diff --git a/docs/source/computational_implementation.rst b/docs/source/computational_implementation.rst index 6ca9eb5a8..30c01e20f 100644 --- a/docs/source/computational_implementation.rst +++ b/docs/source/computational_implementation.rst @@ -505,7 +505,7 @@ The Temoa model code is organized into clear, purpose-driven packages: * ``flows.py`` - Commodity flow balance constraints * ``capacity.py`` - Capacity and activity constraints * ``emissions.py`` - Emission accounting and constraints - * ``reserves.py`` - Reserve margin requirements + * ``reserves.py`` - Planning reserve margin and shared reserve helpers * ``limits.py`` - Various limit constraints (capacity, activity, emissions, etc.) * ``storage.py`` - Energy storage constraints * ``operations.py`` - Baseload and ramping constraints for generators diff --git a/docs/source/database.rst b/docs/source/database.rst index 3f6e7c317..f9a5356cf 100644 --- a/docs/source/database.rst +++ b/docs/source/database.rst @@ -110,18 +110,26 @@ recommend that you populate input tables in the following order: Group Region and Technology Constraints --------------------------------------- -Some constraint tables support summation over groups of regions or technologies. Note that each row in these tables will still only create one constraint, but that constraint will be a summation over the defined group. For example, the ``limit_capacity`` table will limit the total summed capacity of all technologies in the technology group (if used) and over all the regions in the region group (if used). Consider behaviour carefully. For example, the ``limit_annual_capacity_factor`` table will constrain the total summed capacity factor of the group, which would allow for varying capacity factors of processes within that group as long as the limit is met in aggregate. +Some constraint tables support summation over groups of regions or technologies. +Note that each row in these tables will still only create one constraint, but +that constraint will be a summation over the defined group. For example, the +``limit_capacity`` table will limit the total summed capacity of all technologies +in the technology group (if used) and over all the regions in the region group (if used). +Consider behaviour carefully. For example, the ``limit_annual_capacity_factor`` table will +constrain the total summed capacity factor of the group, which would allow for varying +capacity factors of processes within that group as long as the limit is met in aggregate. **Group Regions:** For the supported tables, the ``region`` column can be populated with either a single region (e.g., ``"east"``), a subset of regions delineated with a ``+`` (e.g., ``"east+west"``), or ``"global"`` to indicate summation over all model regions. .. important:: - When grouped or global region constraints are used with exchange technologies, - exchange flows are only counted if the relevant exchange-technology keys are + When ``+`` delineated region summations are used with exchange technologies, + exchange flows are only counted if the relevant exchange-technology region pairs are explicitly included in the region string used by the constraint row. - Exchange-technology keys are directional and use a hyphen to separate the - two regions (e.g., ``east-west`` and ``west-east`` are distinct keys). + Exchange-technology regions are directional and use a hyphen to separate the + two regions (e.g., ``east-west`` and ``west-east`` are distinct keys). ``"global"`` + *does* include all exchange flows by default. For example, to constrain activity across the ``east`` and ``west`` regions including all exchange flows between them, the region string should be: @@ -132,7 +140,13 @@ For the supported tables, the ``region`` column can be populated with either a s If exchange keys are omitted (e.g., using only ``east+west``), flows through exchange technologies between those regions will *not* be included in the - constrained summation. + constraint summation. + + The only exception to this rule is reserve margin constraints, + :code:`planning_reserve_margin` and :code:`operating_reserve_margin` + (:ref:`unit_commitment extension `), + which automatically include all exchange flows into and out of the region + or region group due to their specific logic requiring this behaviour. Supported tables: @@ -146,18 +160,17 @@ Supported tables: * limit_capacity_share * limit_new_capacity_share * limit_emission -* limit_growth_capacity -* limit_growth_new_capacity -* limit_growth_new_capacity_delta -* limit_degrowth_capacity -* limit_degrowth_new_capacity -* limit_degrowth_new_capacity_delta +* planning_reserve_margin +* operating_reserve_margin (unit_commitment extension) **Technology Groups:** -For the supported tables, the following columns accept either technologies or technology groups, over which the constraint is summed. Technology groups are defined in the ``tech_group`` and ``tech_group_member`` tables. +For the supported tables, the following columns accept either technologies or +technology groups, over which the constraint is summed. Technology groups are +defined in the ``tech_group`` and ``tech_group_member`` tables. + +Technology group columns: -* tech * tech_or_group * sub_group * super_group @@ -173,18 +186,14 @@ Supported tables: * limit_activity_share * limit_capacity_share * limit_new_capacity_share -* limit_growth_capacity -* limit_growth_new_capacity -* limit_growth_new_capacity_delta -* limit_degrowth_capacity -* limit_degrowth_new_capacity -* limit_degrowth_new_capacity_delta +* planning_reserve_margin +* operating_reserve_margin (unit_commitment extension) For help getting started, consider using the ``temoa tutorial`` command to generate a template project or inspect the example SQL file at ``temoa/tutorial_assets/utopia.sql``. To begin building your own database file, use -``temoa/db_schema/temoa_schema_v4.sql``, which is a database file with the requisite +``temoa/db_schema/temoa_schema_v4_1.sql``, which is a database file with the requisite structure but no data added. We recommend leaving the database structure intact, and simply adding data to the schema file, or constructing an empty database from the schema file and then using a script or database editor to import data. diff --git a/docs/source/database_schema.mmd b/docs/source/database_schema.mmd index 84f580141..889cc9931 100644 --- a/docs/source/database_schema.mmd +++ b/docs/source/database_schema.mmd @@ -1,12 +1,19 @@ erDiagram -capacity_credit { - INTEGER period PK +planning_reserve_credit { + TEXT reserve_name PK TEXT region PK TEXT tech PK - INTEGER vintage PK REAL credit TEXT notes } +planning_reserve_margin { + TEXT reserve_name PK + TEXT region PK + TEXT tech_or_group PK + TEXT type + REAL margin + TEXT notes +} technology { TEXT tech PK INTEGER annual @@ -16,7 +23,6 @@ technology { INTEGER exchange TEXT flag INTEGER flex - INTEGER reserve INTEGER retire INTEGER seas_stor TEXT sector @@ -539,11 +545,6 @@ output_storage_level { REAL level TEXT sector } -planning_reserve_margin { - TEXT region PK - REAL margin - TEXT notes -} ramp_down_hourly { TEXT region PK TEXT tech PK @@ -556,22 +557,6 @@ ramp_up_hourly { TEXT notes REAL rate } -reserve_capacity_derate { - INTEGER period PK - TEXT region PK - TEXT season PK - TEXT tech PK - INTEGER vintage PK - REAL factor - TEXT notes -} -rps_requirement { - TEXT notes - INTEGER period - TEXT region - REAL requirement - TEXT tech_group -} tech_group { TEXT group_name PK TEXT notes @@ -621,8 +606,8 @@ time_segment_fraction { TEXT notes REAL segment_fraction } -technology one or zero--0+ capacity_credit : has -time_period one or zero--0+ capacity_credit : has +planning_reserve_margin one or zero--0+ planning_reserve_credit : has +technology one or zero--0+ planning_reserve_credit : has technology_type 1--0+ technology : has time_period_type one or zero--0+ time_period : has technology one or zero--0+ capacity_factor_process : has @@ -698,15 +683,9 @@ operator 1--0+ limit_capacity : has time_period one or zero--0+ limit_capacity : has time_period one or zero--0+ limit_capacity_share : has operator 1--0+ limit_capacity_share : has -operator 1--0+ limit_degrowth_capacity : has -operator 1--0+ limit_degrowth_new_capacity : has -operator 1--0+ limit_degrowth_new_capacity_delta : has commodity one or zero--0+ limit_emission : has operator 1--0+ limit_emission : has time_period one or zero--0+ limit_emission : has -operator 1--0+ limit_growth_capacity : has -operator 1--0+ limit_growth_new_capacity : has -operator 1--0+ limit_growth_new_capacity_delta : has time_period one or zero--0+ limit_new_capacity : has operator 1--0+ limit_new_capacity : has operator 1--0+ limit_new_capacity_share : has @@ -797,15 +776,8 @@ sector_label one or zero--0+ output_storage_level : has time_period one or zero--0+ output_storage_level : has season_label one or zero--0+ output_storage_level : has time_of_day one or zero--0+ output_storage_level : has -region one or zero--1 planning_reserve_margin : has technology one or zero--0+ ramp_down_hourly : has technology one or zero--0+ ramp_up_hourly : has -technology one or zero--0+ reserve_capacity_derate : has -time_period one or zero--0+ reserve_capacity_derate : has -season_label one or zero--0+ reserve_capacity_derate : has -time_period 1--0+ rps_requirement : has -tech_group 1--0+ rps_requirement : has -region 1--0+ rps_requirement : has tech_group one or zero--0+ tech_group_member : has technology one or zero--0+ tech_group_member : has time_period one or zero--0+ time_season : has diff --git a/docs/source/extensions/unit_commitment.rst b/docs/source/extensions/unit_commitment.rst index 795ba32a3..b8a200ab0 100644 --- a/docs/source/extensions/unit_commitment.rst +++ b/docs/source/extensions/unit_commitment.rst @@ -6,7 +6,9 @@ Unit Commitment The **unit_commitment** extension adds commitment-level operational constraints to selected technologies: online/started/stopped unit accounting, minimum output floors, maximum output ceilings, and minimum up-time and down-time windows. -It also supports discounted startup costs and startup emissions and input flows. +It also supports discounted startup costs and startup emissions and input flows, +and operating reserve margins credited from current generation, online headroom, +and offline units (see :ref:`uc-operating-reserves`). It is disabled by default and enabled per run through configuration: @@ -48,7 +50,6 @@ constraints automatically become UC-aware for registered technologies with no fu - :code:`capacity_constraint` — output bounded by online capacity - :code:`storage_charge_rate_constraint`, :code:`storage_discharge_rate_constraint`, :code:`storage_throughput_constraint` — storage rates scale with online units -- :code:`reserve_margin_constraint` (dynamic mode only) — reserve contribution from online units only Ramp constraints are the only exception: they require explicit knowledge of started/stopped units to compute the ramp envelope and are therefore fully replaced by @@ -99,6 +100,13 @@ Overview - Input commodity consumed at startup per unit of capacity started. - Added to consumption in :code:`commodity_balance_constraint` and results in :code:`output_flow_in`. + * - :code:`operating_reserve_margin` + - One row per reserve product: region-group, tech-group, margin, sustain hours. + - Adds :code:`operating_reserve_margin_constraint` per product and time slice. + * - :code:`operating_reserve_credit` + - Per-product, per-technology credits for activity, online headroom and + offline units. + - Credited reserve is written to :code:`output_operating_reserve`. Parameters ---------- @@ -186,6 +194,73 @@ capacity started. Startup inputs are summed into the These inputs are **not** considered in network checking. If no other process produces or consumes the input commodity in this region and period, it may be removed from the model and lead to errors. +operating_reserve_margin +~~~~~~~~~~~~~~~~~~~~~~~~ + +:math:`{ORM}_{n, r_g, t_g}` + +Defines each operating reserve product :math:`(n, r_g, t_g)`. Each product applies to +one region-or-group and technology-or-group. The same reserve name :math:`n` may be +repeated over several region-groups and tech-groups (e.g. a regulation reserve held +separately in several regions), in which case they share the credits of that name (see +:ref:`uc-operating-reserve-credit`). Any exchange region (e.g. ``r1-r2``) with exactly +one endpoint in the region group is automatically included in the proxy demand, as for +:code:`planning_reserve_margin`. + +.. csv-table:: + :header: "Column", "Symbol", "Default", "Description" + :widths: 20, 16, 10, 54 + + ":code:`reserve_name`", ":math:`n`", "—", "name of the reserve; primary key with :code:`region` and :code:`tech_or_group`" + ":code:`region`", ":math:`r_g`", "—", "region or region group in which the reserve is held" + ":code:`tech_or_group`", ":math:`t_g`", "—", "technologies feeding the demand; must include every demand-feeding technology, even those with zero credit, because the group also defines the proxy demand" + ":code:`margin`", ":math:`ORM_{n,r_g,t_g}`", "—", "required credited reserve as a fraction of proxy demand (unlike :code:`planning_reserve_margin`, this is not an excess above demand)" + ":code:`sustain_hours`", ":math:`SH_{n,r_g,t_g}`", "0", "hours for which storage must be able to sustain its credited reserve from its state of charge; 0 or empty skips the storage energy constraint for this product" + +.. _uc-operating-reserve-credit: + +operating_reserve_credit +~~~~~~~~~~~~~~~~~~~~~~~~ + +:math:`{AC}_{n,t},\ {ONC}_{n,t},\ {OFC}_{n,t}` + +Per-reserve-name, per-technology credits. **All credits default to 0**, so a technology +in the tech group contributes to the proxy demand but not to the reserve unless a +credit is set. Exchange technologies' :code:`online_credit` must be matched in both +directions of the link (see :ref:`uc-operating-reserves`). Credits are keyed by +reserve name only, so they apply to every region-group and tech-group using that name; +use a different reserve name to give a region different credits. + +.. csv-table:: + :header: "Column", "Symbol", "Default", "Description" + :widths: 20, 16, 10, 54 + + ":code:`reserve_name`", ":math:`n`", "—", "reserve product from :code:`operating_reserve_margin`" + ":code:`tech`", ":math:`t`", "—", "technology name" + ":code:`activity_credit`", ":math:`AC_{n,t}`", "0", "fraction of current net output activity counted as reserve" + ":code:`online_credit`", ":math:`ONC_{n,t}`", "0", "maximum online headroom credit, as a fraction of online installed capacity (installed capacity for non-UC technologies)" + ":code:`offline_credit`", ":math:`OFC_{n,t}`", "0", "fraction of offline installed capacity counted as reserve; UC technologies only" + +.. important:: + + **Online and offline credits are fractions of total installed (nameplate) capacity, not of + maximum available output.** Operational limits are not applied to the credit + automatically, so they should be folded into the credit value where they apply. + For example, the offline credit multiplies the nameplate capacity of offline + units (with capacity factors applied) and does **not** account for + :code:`max_output_fraction`; a unit with :code:`max_output_fraction = 0.9` that + can fully start within the product's response time should have + :code:`offline_credit` of at most 0.9. Similarly, startup times, ramp rates, or + forced outage rates should be reflected in the credit. Online headroom is + also a fraction of total nameplate capacity but takes the lesser of the credit + available and the actual available headroom to maximum output, which already + includes :code:`max_output_fraction` and capacity factors. + +.. note:: + + A process may contribute to several products at once; products are assumed + never to be called on simultaneously, so credits are not shared between them. + Decision Variables ------------------ @@ -201,6 +276,17 @@ to relax them to continuous non-negative reals. ":math:`\textbf{UCST}_{r,p,s,d,t,v}` (:code:`v_uc_started`)", ":math:`\mathbb{Z}_{\ge 0}` when `linearized = 0`; :math:`\mathbb{R}_{\ge 0}` when `linearized = 1`", "number of units that start up during timeslice :math:`(s,d)`" ":math:`\textbf{UCSP}_{r,p,s,d,t,v}` (:code:`v_uc_stopped`)", ":math:`\mathbb{Z}_{\ge 0}` when `linearized = 0`; :math:`\mathbb{R}_{\ge 0}` when `linearized = 1`", "number of units that shut down during timeslice :math:`(s,d)`" +One operating reserve variable is added per :math:`(n, r, p, s, d, t, v)` for +processes with a nonzero :code:`online_credit`. It is indexed by reserve +name rather than by product, so a process that falls in several region-groups or +tech-groups sharing a reserve name contributes the same headroom credit to each: + +.. csv-table:: + :header: "Variable", "Domain", "Description" + :widths: 36, 16, 48 + + ":math:`\textbf{ORH}_{n,r,p,s,d,t,v}` (:code:`v_orm_online_credit`)", ":math:`\mathbb{R}_{\ge 0}`", "online headroom credited to reserve product :math:`n`" + Constraints ----------- @@ -221,7 +307,7 @@ Commitment Transition Output Bounds ~~~~~~~~~~~~~ -The minimum output constraint enforces a floor on generation per online unit. +The minimum output constraint enforces a floor on output per online unit. The maximum output (capacity) constraint is handled by the standard core-model :code:`capacity_constraint` — the extension overrides :func:`~temoa.components.utils.get_available_output` so that available output @@ -258,6 +344,37 @@ start and stop at their minimum viable output level, taken as the larger of thei .. autofunction:: temoa.extensions.unit_commitment.components.commitment.uc_ramp_down_constraint +.. _uc-operating-reserves: + +Operating Reserves +~~~~~~~~~~~~~~~~~~ + +Each reserve product requires credited reserve to exceed the proxy demand of its +region-group and tech-group (see +:func:`~temoa.components.reserves.reserve_margin_proxy_demand`) by its margin in +every time slice. Reserve is credited from current activity, headroom on online +units, and offline unit commitment units that could start. + +Although operating reserves live in the :code:`unit_commitment` extension, the tech +group need not be registered for unit commitment: a non-UC technology is simply +treated as always fully online, so its online headroom credit is unused installed +capacity and it is never eligible for offline credit. + +Exchange technologies count toward the proxy demand (imports add, exports subtract). +Their :code:`online_credit` is constrained equal across both directional process +entries of the link +(:func:`~temoa.extensions.unit_commitment.components.operating_reserves.operating_reserve_online_exchange_symmetry_constraint`). + +.. autofunction:: temoa.extensions.unit_commitment.components.operating_reserves.operating_reserve_margin_constraint + +.. autofunction:: temoa.extensions.unit_commitment.components.operating_reserves.operating_reserve_online_headroom_constraint + +.. autofunction:: temoa.extensions.unit_commitment.components.operating_reserves.operating_reserve_online_headroom_credit_constraint + +.. autofunction:: temoa.extensions.unit_commitment.components.operating_reserves.operating_reserve_storage_energy_constraint + +.. autofunction:: temoa.extensions.unit_commitment.components.operating_reserves.operating_reserve_online_exchange_symmetry_constraint + Objective Contributions ----------------------- @@ -277,6 +394,17 @@ Results are written to the :code:`output_unit_commitment` table with one row per ":code:`start_cap`", "capacity started during the timeslice (:math:`\textbf{UCST} \cdot UC_{r,t}`)" ":code:`stop_cap`", "capacity stopped during the timeslice (:math:`\textbf{UCSP} \cdot UC_{r,t}`)" +Operating reserve credits are written to the :code:`output_operating_reserve` table +with one row per :math:`(scenario, reserve\_name, region, period, season, tod, tech, vintage)`: + +.. csv-table:: + :header: "Column", "Description" + :widths: 22, 78 + + ":code:`activity_credit`", "reserve credited from current generation" + ":code:`online_credit`", "reserve credited from online headroom" + ":code:`offline_credit`", "reserve credited from offline units" + .. note:: **Starts and stops take effect in the following time slice.** The transition diff --git a/docs/source/mathematical_formulation.rst b/docs/source/mathematical_formulation.rst index 8bbd7a21e..18cfcd691 100644 --- a/docs/source/mathematical_formulation.rst +++ b/docs/source/mathematical_formulation.rst @@ -338,19 +338,8 @@ efficiency values. If not specified for a given process, it defaults to 1, meaning the base :code:`efficiency` value applies uniformly. Note that there is no period index: the time-varying efficiency applies to all periods. - .. _capacity_factor_tech: -capacity_credit -~~~~~~~~~~~~~~~ - -:math:`{CC}_{r \in R, p \in P, t \in T, v \in V}` - -The capacity credit represents the fraction of total installed capacity of -a process that can be relied upon during the time slice in which peak -electricity demand occurs. This parameter is used in the 'static' version of -the :math:`reserve_margin` constraint. - capacity_factor_tech ~~~~~~~~~~~~~~~~~~~~ @@ -822,13 +811,50 @@ level to vary. planning_reserve_margin ~~~~~~~~~~~~~~~~~~~~~~~ -:math:`{PRM}_{r \in R}` +:math:`{PRM}_{n, r \in R, t \in T}` + +The required excess of credited capacity above demand, expressed +as a fraction of demand, for planning reserve product :math:`(n, r_g, t_g)` +(``reserve_name``, ``region``, ``tech_or_group``). The same reserve name may be +repeated over several region-groups and tech-groups, in which case they share the +planning reserve credits of that name. For example, a value of 0.2 requires that +credited capacity be at least 120% of demand. Demand is estimated from production +by time slice. Any exchange region (e.g. ``r1-r2``) where exactly one endpoint +connects to the region or group is automatically included in the +reserve calculation; this auto-inclusion is unique to the reserve margin constraints. + +The ``type`` column selects how credited capacity is calculated for each product: + +* ``static`` (default): credit times installed capacity, the same in every time slice + (:eq:`planning_reserve_margin_static`). Credits typically represent the expected + availability of nameplate capacity during peak demand. +* ``dynamic``: credit times the output actually available in each time slice, so + capacity factors and, with the unit commitment extension, online units are applied + automatically (:eq:`planning_reserve_margin_dynamic`). Credits then act as a derate, + e.g. for forced outages. Storage is credited only for its net output in each time + slice. + + +planning_reserve_credit +~~~~~~~~~~~~~~~~~~~~~~~ -The :code:`planning_reserve_margin` parameter specifies the capacity reserve margin -in the electric sector by region. The capacity reserve margin represents the -installed generating capacity — expressed as a share of peak load — that must be -available in reserve to meet contingencies. Temoa estimates peak demand from electricity -production by time slice. +:math:`{PRC}_{n, t \in T}` + +The fraction of a technology's capacity that can be reliably counted toward planning +reserve name :math:`n`. For ``static`` reserves this is a fraction of installed +capacity: a firm, fully dispatchable process (e.g. a gas turbine) typically receives a +credit near 1, while a weather-dependent process (e.g. wind or solar) receives a lower +value. For ``dynamic`` reserves it is a derate on available output, which already +includes capacity factors, so weather-dependent processes may also receive a credit +near 1. Credits are keyed by reserve name only, so they apply to every region-group +and tech-group using that name; use a different reserve name to give a region +different credits. + +.. note:: + + The operating reserve margin, which credits online, offline, and currently + generating units in each time slice, is part of the + :ref:`unit_commitment extension `. ramp_down_hourly @@ -851,18 +877,6 @@ by which a technology can ramp output up per hour. This is used in the :code:`ramp_up_constraint`. -reserve_capacity_derate -~~~~~~~~~~~~~~~~~~~~~~~ - -:math:`{RCD}_{r \in R, s \in S, t \in T^{res}, v \in V}` - -The :code:`reserve_capacity_derate` parameter allows the modeler to derate -the capacity of a reserve technology in specific seasons — for example, to -account for seasonal availability. Values default to 1 (no derate). This -parameter is used in the 'dynamic' version of the :code:`reserve_margin` -constraint. - - .. _segment_fraction: segment_fraction @@ -1313,9 +1327,13 @@ various physical and operational real-world phenomena. .. autofunction:: temoa.components.operations.ramp_down_constraint -.. autofunction:: temoa.components.reserves.reserve_margin_static +.. autofunction:: temoa.components.reserves.planning_reserve_margin_constraint + +.. autofunction:: temoa.components.reserves._planning_reserve_margin_static + +.. autofunction:: temoa.components.reserves._planning_reserve_margin_dynamic -.. autofunction:: temoa.components.reserves.reserve_margin_dynamic +.. autofunction:: temoa.components.reserves.reserve_margin_proxy_demand .. autofunction:: temoa.components.emissions.linked_emissions_tech_constraint diff --git a/docs/source/param_desc_and_tables.rst b/docs/source/param_desc_and_tables.rst index aef95320e..a29e04deb 100644 --- a/docs/source/param_desc_and_tables.rst +++ b/docs/source/param_desc_and_tables.rst @@ -24,12 +24,12 @@ characteristics**. :widths: 15, 20, 25, 40 ":math:`\text{C2A}_{r,t}`", ":code:`capacity_to_activity`", ":code:`capacity_to_activity`", "converts from capacity to activity units" - ":math:`\text{CC}_{r,p,t,v}`", ":code:`capacity_credit`", ":code:`capacity_credit`", "process-specific capacity credit used in the static reserve margin constraint" + ":math:`\text{PRC}_{n,t}`", ":code:`planning_reserve_credit`", ":code:`planning_reserve_credit`", "fraction of installed capacity (static) or available output (dynamic) that can be relied upon for planning reserve name :math:`n` (default 0)" ":math:`\text{CFT}_{r,s,d,t}`", ":code:`capacity_factor_tech`", ":code:`capacity_factor_tech`", "technology-specific capacity factor" ":math:`\text{CFP}_{r,s,d,t,v}`", ":code:`capacity_factor_process`", ":code:`capacity_factor_process`", "process-specific capacity factor; allows capacity factor to change with technology vintage" ":math:`\text{ECAP}_{r,t,v}`", ":code:`existing_capacity`", ":code:`existing_capacity`", "installed capacity that exists prior to first model time period" - ":math:`\text{PRM}_{r}`", ":code:`planning_reserve_margin`", ":code:`planning_reserve_margin`", "planning reserve margin used to ensure sufficient generating capacity" - ":math:`\text{RCD}_{r,s,t,v}`", ":code:`reserve_capacity_derate`", ":code:`reserve_capacity_derate`", "capacity derate factor for dynamic reserve margin constraint" + ":math:`\text{PRM}_{n,r_g,t_g}`", ":code:`planning_reserve_margin`", ":code:`planning_reserve_margin`", "required excess of credited capacity above demand in each time slice for planning reserve product :math:`(n,r_g,t_g)`, as a fraction of demand" + "", ":code:`planning_reserve_margin` (:code:`type`)", ":code:`planning_reserve_type`", "``static`` (default) or ``dynamic`` planning reserve formulation for product :math:`(n,r_g,t_g)`" ":math:`\text{RUH}_{r,t}`", ":code:`ramp_up_hourly`", ":code:`ramp_up_hourly`", "hourly rate at which generation techs can ramp output up" ":math:`\text{RDH}_{r,t}`", ":code:`ramp_down_hourly`", ":code:`ramp_down_hourly`", "hourly rate at which generation techs can ramp output down" @@ -125,7 +125,6 @@ Parameters in the table below relate to the specification of **policy**. :header: "Parameter", "Database Table", "Model Element", "Notes" :widths: 15, 20, 25, 40 - "", ":code:`rps_requirement`", ":code:`renewable_portfolio_standard`", "**[Deprecated]** RPS requirements; use :code:`limit_activity_share` instead" ":math:`\text{LIT}_{r,t,e,t'}`", ":code:`linked_tech`", ":code:`linked_techs`", "dummy techs used to convert CO2 emissions to physical commodity" Parameters in the table below relate to the specification of **construction and diff --git a/docs/source/set_desc_and_tables.rst b/docs/source/set_desc_and_tables.rst index 29818d487..150eb2596 100644 --- a/docs/source/set_desc_and_tables.rst +++ b/docs/source/set_desc_and_tables.rst @@ -51,14 +51,13 @@ number of **technology subsets**. ":math:`\text{T}^b`", ":code:`technology, flag = pb`", ":code:`tech_baseload`", "baseload electric generators, which have constant output across intraday time segments (:math:`{T}^b \subset T`)" ":math:`\text{T}^s`", ":code:`technology, flag = ps`", ":code:`tech_storage`", "all storage technologies (:math:`{T}^s \subset T`)" ":math:`\text{T}^a`", ":code:`technology, annual = 1`", ":code:`tech_annual`", "technologies that produce constant annual output (:math:`{T}^a \subset T`)" - ":math:`\text{T}^{res}`", ":code:`technology, reserve = 1`", ":code:`tech_reserve`", "electric generators contributing to the reserve margin requirement (:math:`{T}^{res} \subset T`)" - ":math:`\text{T}^c`", ":code:`technology, curtail = 1`", ":code:`tech_curtailment`", "technologies with curtailable output and no upstream cost (:math:`{T}^c \subset (T - T^{res})`)" + ":math:`\text{T}^c`", ":code:`technology, curtail = 1`", ":code:`tech_curtailment`", "technologies with curtailable output and no upstream cost (:math:`{T}^c \subset T`)" ":math:`\text{T}^f`", ":code:`technology, flex = 1`", ":code:`tech_flex`", "technologies producing excess commodity flows (:math:`{T}^f \subset T`)" ":math:`\text{T}^x`", ":code:`technology, exchange = 1`", ":code:`tech_exchange`", "technologies used for interregional commodity flows (:math:`{T}^x \subset T`)" ":math:`\text{T}^{ur}`", ":code:`ramp_up_hourly`", ":code:`tech_upramping`", "electric generators with a ramp up hourly rate limit; derived from :code:`ramp_up_hourly` table (:math:`{T}^{ur} \subset T`)" ":math:`\text{T}^{dr}`", ":code:`ramp_down_hourly`", ":code:`tech_downramping`", "electric generators with a ramp down hourly rate limit; derived from :code:`ramp_down_hourly` table (:math:`{T}^{dr} \subset T`)" ":math:`\text{T}^{ret}`", ":code:`technology, retire = 1`", ":code:`tech_retirement`", "technologies allowed to retire before end of life (:math:`{T}^{ret} \subset (T - T^{u})`)" - ":math:`\text{T}^u`", ":code:`technology, unlim_cap = 1`", ":code:`tech_uncap`", "technologies that have no bound on capacity (:math:`{T}^u \subset (T - T^{res})`)" + ":math:`\text{T}^u`", ":code:`technology, unlim_cap = 1`", ":code:`tech_uncap`", "technologies that have no bound on capacity (:math:`{T}^u \subset T`)" ":math:`\text{T}^{ss}`", ":code:`technology, flag = 'ps' AND seas_stor = 1`", ":code:`tech_seasonal_storage`", "seasonal storage technologies; requires both storage flag and seas_stor column (:math:`{T}^{ss} \subset T^s`)" "", ":code:`tech_group`", ":code:`tech_group_names`", "named groups for use in group constraints" "", ":code:`tech_group_member`", ":code:`tech_group_members`", "each technology belonging to each group" diff --git a/temoa/__about__.py b/temoa/__about__.py index 28c809a05..954c4971d 100644 --- a/temoa/__about__.py +++ b/temoa/__about__.py @@ -21,4 +21,7 @@ # db is tested for match on major and >= on minor DB_MAJOR_VERSION = 4 -MIN_DB_MINOR_VERSION = 0 +MIN_DB_MINOR_VERSION = 1 + +# Also needs updating in database.rst +DB_SCHEMA = 'temoa_schema_v4_1.sql' diff --git a/temoa/_internal/table_writer.py b/temoa/_internal/table_writer.py index 240ed43b8..57e0d9209 100644 --- a/temoa/_internal/table_writer.py +++ b/temoa/_internal/table_writer.py @@ -28,6 +28,7 @@ poll_storage_level_results, ) from temoa.core.modes import TemoaMode +from temoa.extensions.framework import get_extension_output_tables if TYPE_CHECKING: from collections.abc import Iterable @@ -376,7 +377,10 @@ def clear_scenario(self) -> None: cur = self.connection.cursor() for table in BASIC_OUTPUT_TABLES: cur.execute(f'DELETE FROM {table} WHERE scenario == ?', (self.config.scenario,)) - for table in OPTIONAL_OUTPUT_TABLES: + for table in ( + *OPTIONAL_OUTPUT_TABLES, + *get_extension_output_tables(self.config.extensions), + ): try: cur.execute(f'DELETE FROM {table} WHERE scenario == ?', (self.config.scenario,)) except sqlite3.OperationalError: @@ -387,7 +391,11 @@ def clear_scenario(self) -> None: def clear_iterative_runs(self) -> None: target = self.config.scenario + '-%' cur = self.connection.cursor() - tables = BASIC_OUTPUT_TABLES + OPTIONAL_OUTPUT_TABLES + tables = ( + *BASIC_OUTPUT_TABLES, + *OPTIONAL_OUTPUT_TABLES, + *get_extension_output_tables(self.config.extensions), + ) for table in tables: try: cur.execute(f'DELETE FROM {table} WHERE scenario like ?', (target,)) @@ -494,6 +502,12 @@ def write_capacity_tables(self, model: TemoaModel, iteration: int | None = None) iteration=iteration, epsilon=self.output_threshold_capacity, ) + uc_puller.write_operating_reserve_results( + model=model, + writer=self, + iteration=iteration, + epsilon=self.output_threshold_capacity, + ) def _insert_capacity_results(self, cap_data: CapData, iteration: int | None) -> None: if self.tech_sectors is None: diff --git a/temoa/_internal/temoa_sequencer.py b/temoa/_internal/temoa_sequencer.py index d781aad1b..48cd8ee67 100644 --- a/temoa/_internal/temoa_sequencer.py +++ b/temoa/_internal/temoa_sequencer.py @@ -145,6 +145,8 @@ def build_model(self) -> TemoaModel: data_portal, silent=self.config.silent, extensions=self.config.extensions, + keep_lp_file=self.config.save_lp_file, + lp_path=self.config.output_path, ) logger.info('Model build process complete.') diff --git a/temoa/cli.py b/temoa/cli.py index 418e7250d..7d52499fb 100644 --- a/temoa/cli.py +++ b/temoa/cli.py @@ -11,11 +11,11 @@ from rich.logging import RichHandler from rich.text import Text -from temoa.__about__ import __version__ +from temoa.__about__ import DB_SCHEMA, __version__ from temoa._internal.temoa_sequencer import TemoaSequencer from temoa.core.config import TemoaConfig from temoa.core.modes import TemoaMode -from temoa.utilities import master_migration +from temoa.utilities import migration_chain from temoa.utilities.run_all_v4_migrations import run_migrations # ============================================================================= @@ -137,7 +137,7 @@ def _cite_callback(value: bool) -> None: def get_default_schema() -> Path: """Get the default path to the v4 schema file, handling both installed and development cases.""" try: - schema_path = resources.files('temoa.db_schema') / 'temoa_schema_v4.sql' + schema_path = resources.files('temoa.db_schema') / DB_SCHEMA if not schema_path.is_file(): raise FileNotFoundError( @@ -149,7 +149,7 @@ def get_default_schema() -> Path: # The fallback for development needs to reflect the current repository structure # assuming `cli.py` is in `temoa/` and `db_schema/` is a sibling of `cli.py` within # `temoa/`. - fallback_path = Path(__file__).parent / 'db_schema' / 'temoa_schema_v4.sql' + fallback_path = Path(__file__).parent / 'db_schema' / DB_SCHEMA if fallback_path.is_file(): logger.warning( 'Using fallback schema path: %s. ' @@ -415,7 +415,7 @@ def migrate( ] = None, schema_path: Annotated[ Path | None, - typer.Option('--schema', '-s', help='Path to v4 schema SQL file.'), + typer.Option('--schema', '-s', help='Path to the (target) schema SQL file.'), ] = None, migration_type: Annotated[ str | None, @@ -431,7 +431,7 @@ def migrate( debug: Annotated[bool, typer.Option('--debug', '-d', help='Enable debug output.')] = False, ) -> None: """ - Migrate a Temoa database file (SQL dump or SQLite DB) or directory from v3 to v4 format. + Migrate a Temoa database file (SQL dump or SQLite DB) or directory to the target version. """ if schema_path is None: schema_path = get_default_schema() @@ -447,7 +447,7 @@ def migrate( 'overwritten after backup.[/yellow]' ) - migration_script = Path(__file__).parent / 'utilities' / 'master_migration.py' + migration_script = Path(__file__).parent / 'utilities' / 'migration_chain.py' if not silent: rich.print(f'[green]Batch migrating directory: {input_path}[/green]') @@ -521,7 +521,7 @@ def migrate( # --- Execute the migration based on type --- if migration_type == 'sql' or (migration_type is None and ext == '.sql'): try: - master_migration.migrate_sql_dump( + migration_chain.migrate_sql_dump( source_path=input_path, schema_path=schema_path, output_path=final_output_file ) if not silent: @@ -534,7 +534,7 @@ def migrate( raise typer.Exit(1) from e elif migration_type == 'db' or (migration_type is None and ext in ['.db', '.sqlite']): try: - master_migration.migrate_database( + migration_chain.migrate_database( source_path=input_path, schema_path=schema_path, output_path=final_output_file ) if not silent: @@ -573,7 +573,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' + schema_resource = resources.files('temoa.db_schema') / DB_SCHEMA # Copy configuration file with config_resource.open('rb') as source: @@ -612,7 +612,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' + fallback_schema = Path(__file__).parent / 'db_schema' / DB_SCHEMA if not fallback_config.exists(): raise FileNotFoundError( diff --git a/temoa/components/capacity.py b/temoa/components/capacity.py index 78b681346..510570e14 100644 --- a/temoa/components/capacity.py +++ b/temoa/components/capacity.py @@ -198,6 +198,7 @@ def regional_exchange_capacity_constraint_indices( (r_to, r_from, p, t, v) for r_from, p, i in model.export_regions for r_to, t, v, _o in model.export_regions[r_from, p, i] + if r_from < r_to } @@ -657,34 +658,34 @@ def create_capacity_and_retirement_sets(model: TemoaModel) -> None: def gather_group_active_processes( - model: TemoaModel, r: Region, p: Period, t: Technology + model: TemoaModel, r_g: Region, p: Period, t_g: Technology ) -> set[tuple[Region, Technology]]: """ A utility to get the valid active processes for a group-region, tech-group pair in period p. Caches the result if its a new call so we don't repeat these O(n2) lookups. """ - if (r, p, t) not in model.group_active_processes: - model.group_active_processes[r, p, t] = { - (_r, _t) - for _r in geography.gather_group_regions(model, r) - for _t in technology.gather_group_techs(model, t) - if (_r, p, _t) in model.process_vintages + if (r_g, p, t_g) not in model.group_active_processes: + model.group_active_processes[r_g, p, t_g] = { + (r, t) + for r in geography.gather_group_regions(model, r_g) + for t in technology.gather_group_techs(model, t_g) + if (r, p, t) in model.process_vintages } - return model.group_active_processes[r, p, t] + return model.group_active_processes[r_g, p, t_g] def gather_group_built_processes( - model: TemoaModel, r: Region, t: Technology, v: Vintage + model: TemoaModel, r_g: Region, t_g: Technology, v: Vintage ) -> set[tuple[Region, Technology]]: """ A utility to get the valid built processes for a group-region, tech-group, vintage index. Caches the result if its a new call so we don't repeat these O(n2) lookups. """ - if (r, t, v) not in model.group_built_processes: - model.group_built_processes[r, t, v] = { - (_r, _t) - for _r in geography.gather_group_regions(model, r) - for _t in technology.gather_group_techs(model, t) - if (_r, _t, v) in model.process_periods + if (r_g, t_g, v) not in model.group_built_processes: + model.group_built_processes[r_g, t_g, v] = { + (r, t) + for r in geography.gather_group_regions(model, r_g) + for t in technology.gather_group_techs(model, t_g) + if (r, t, v) in model.process_periods } - return model.group_built_processes[r, t, v] + return model.group_built_processes[r_g, t_g, v] diff --git a/temoa/components/geography.py b/temoa/components/geography.py index 45e8f788e..892f76974 100644 --- a/temoa/components/geography.py +++ b/temoa/components/geography.py @@ -19,8 +19,6 @@ from pyomo.environ import value if TYPE_CHECKING: - from collections.abc import Iterable - from temoa.core.model import TemoaModel from temoa.types import ExprLike, Period, Region, Technology, Vintage @@ -33,15 +31,13 @@ # ============================================================================ -def gather_group_regions(model: TemoaModel, region: Region) -> Iterable[Region]: - regions: list[Region] +def gather_group_regions(model: TemoaModel, region: Region) -> set[Region]: if region == 'global': - regions = list(model.regions) + return set(model.regional_indices) elif '+' in region: - regions = [cast('Region', r) for r in region.split('+')] + return {cast('Region', r) for r in region.split('+')} else: - regions = [region] - return regions + return {region} # ============================================================================ diff --git a/temoa/components/limits.py b/temoa/components/limits.py index 342b9b4ca..265bbb0cc 100644 --- a/temoa/components/limits.py +++ b/temoa/components/limits.py @@ -160,42 +160,6 @@ def limit_annual_capacity_factor_indices( # ============================================================================ -# @deprecated('Deprecated. Use limit_activityGroupShare instead') # doesn't play well with pyomo -def renewable_portfolio_standard_constraint( - model: TemoaModel, r: Region, p: Period, g: str -) -> ExprLike: - r""" - Allows users to specify the share of electricity generation in a region - coming from RPS-eligible technologies. - """ - # devnote: this formulation leans on the reserve set, which is not necessarily - # the super set we want. We can also generalise this to all groups and so - # it has been deprecated in favour of the limit_activityGroupShare constraint. - - inp = quicksum( - model.v_flow_out[r, p, s, d, S_i, t, v, S_o] - for t in model.tech_group_members[g] - for (_t, v) in model.process_reserve_periods.get((r, p), []) - if _t == t - for s in model.time_season - for d in model.time_of_day - for S_i in model.process_inputs[r, p, t, v] - for S_o in model.process_outputs_by_input[r, p, t, v, S_i] - ) - - total_inp = quicksum( - model.v_flow_out[r, p, s, d, S_i, t, v, S_o] - for (t, v) in model.process_reserve_periods[r, p] - for s in model.time_season - for d in model.time_of_day - for S_i in model.process_inputs[r, p, t, v] - for S_o in model.process_outputs_by_input[r, p, t, v, S_i] - ) - - expr = inp >= (value(model.renewable_portfolio_standard[r, p, g]) * total_inp) - return expr - - def limit_resource_constraint(model: TemoaModel, r: Region, t: Technology, op: str) -> ExprLike: r""" diff --git a/temoa/components/operations.py b/temoa/components/operations.py index 3d6ab7dfc..0df5879eb 100644 --- a/temoa/components/operations.py +++ b/temoa/components/operations.py @@ -175,7 +175,6 @@ def create_operational_vintage_sets(model: TemoaModel) -> None: for r, p, t in model.process_vintages: for v in model.process_vintages[r, p, t]: key_rpt = (r, p, t) - key_rp = (r, p) if t in model.tech_curtailment: model.curtailment_vintages.setdefault(key_rpt, set()).add(v) if t in model.tech_baseload: @@ -186,8 +185,6 @@ def create_operational_vintage_sets(model: TemoaModel) -> None: model.ramp_up_vintages.setdefault(key_rpt, set()).add(v) if t in model.tech_downramping: model.ramp_down_vintages.setdefault(key_rpt, set()).add(v) - if t in model.tech_reserve: - model.process_reserve_periods.setdefault(key_rp, set()).add((t, v)) # A dictionary of whether a storage tech is seasonal, just to speed things up for t in model.tech_storage: diff --git a/temoa/components/reserves.py b/temoa/components/reserves.py index 9b519d89a..7cc9a95c8 100644 --- a/temoa/components/reserves.py +++ b/temoa/components/reserves.py @@ -1,11 +1,19 @@ # temoa/components/reserves.py """ -Defines the reserve margin components of the Temoa model. - -This module is responsible for ensuring the energy system maintains a sufficient -planning reserve margin to ensure reliability. It supports both a 'static' -(based on installed capacity) and a 'dynamic' (based on available generation -in a time slice) formulation for calculating available reserves. +Defines the planning reserve margin and shared reserve helpers of the Temoa model. + +Each planning reserve product (``reserve_name``, region-group, tech-group) requires +credited capacity or available output to exceed a proxy demand in every time slice, +using either the static or dynamic formulation selected by the ``type`` column. +The same reserve name may be repeated over several region-groups and tech-groups, +in which case they share that name's credits. +Reserve margins are the only constraints in Temoa that, given a region group, +automatically pull in exchange processes connecting a region inside the group +to a region outside it -- see `initialize_reserve_groups`. + +The operating reserve margin lives in the unit commitment extension +(`temoa.extensions.unit_commitment.components.operating_reserves`) and reuses the +helpers here. """ from __future__ import annotations @@ -13,14 +21,28 @@ from logging import getLogger from typing import TYPE_CHECKING -from pyomo.environ import Constraint, Expression, value +from pyomo.environ import Constraint, quicksum, value + +from temoa.components import geography +from temoa.components.capacity import gather_group_active_processes +from temoa.types.core_types import ReserveMarginType from .utils import get_available_output, get_variable_efficiency if TYPE_CHECKING: + from pyomo.core import Param + from temoa.core.model import TemoaModel - from temoa.types import ExprLike - from temoa.types.core_types import Period, Region, Season, TimeOfDay + from temoa.types import ExprLike, ReserveProcessesDict + from temoa.types.core_types import ( + Period, + Region, + ReserveName, + Season, + Technology, + TimeOfDay, + Vintage, + ) logger = getLogger(__name__) @@ -29,348 +51,463 @@ # ============================================================================ -def reserve_margin_indices(model: TemoaModel) -> set[tuple[Region, Period, Season, TimeOfDay]]: +def planning_reserve_indices( + model: TemoaModel, +) -> set[tuple[ReserveName, Region, Technology, Period, Season, TimeOfDay]]: return { - (r, p, s, d) - for r in model.planning_reserve_margin.sparse_keys() - for p in model.time_optimize - if (r, p) in model.process_reserve_periods + (prm, r_g, t_g, p, s, d) + for prm, r_g, t_g, p in model.planning_reserve_processes for s in model.time_season for d in model.time_of_day } # ============================================================================ -# HELPER FUNCTIONS FOR CONSTRAINT LOGIC +# INITIALIZATION FUNCTIONS # ============================================================================ -def _available_activity_dynamic( - model: TemoaModel, r: Region, p: Period, s: Season, d: TimeOfDay -) -> Expression: - - # Everything but storage and exchange techs - # Derated available generation - available = sum( - get_available_output(model, r, p, s, d, t, v) - * value(model.reserve_capacity_derate[r, s, t, v]) - for (t, v) in model.process_reserve_periods[r, p] - if t not in model.tech_uncap and t not in model.tech_storage - ) - - # Storage - # Derated net output flow - available += sum( - model.v_flow_out[r, p, s, d, i, t, v, o] * value(model.reserve_capacity_derate[r, s, t, v]) - for (t, v) in model.process_reserve_periods[r, p] - if t in model.tech_storage - for i in model.process_inputs[r, p, t, v] - for o in model.process_outputs_by_input[r, p, t, v, i] - ) - available -= sum( - model.v_flow_in[r, p, s, d, i, t, v, o] * value(model.reserve_capacity_derate[r, s, t, v]) - for (t, v) in model.process_reserve_periods[r, p] - if t in model.tech_storage - for i in model.process_inputs[r, p, t, v] - for o in model.process_outputs_by_input[r, p, t, v, i] +def initialize_reserve_groups( + model: TemoaModel, + margin: Param, + processes: ReserveProcessesDict, +) -> None: + """Map each reserve product in ``margin`` to its groups and contributing processes. + + A single reserve name may apply to several region-group/tech-group pairs + (e.g., the same product defined separately in different regions). + + Resolves the group's base regions via `geography.gather_group_regions`, then + appends any exchange region-pair (`r1-r2`) with exactly one endpoint inside + the group, so exchange processes crossing the group boundary are counted as + contributors. This is the only place in Temoa where a group constraint + auto-includes connected exchange regions; the corresponding import/export + sign handling is applied in `reserve_margin_proxy_demand`. + + Periods with no contributing processes are omitted. + """ + for name, r_g, t_g in margin.sparse_keys(): + # Gather boundary-crossing exchange regions and add to the group + _r_g = r_g + regions = geography.gather_group_regions(model, r_g) + for r1r2 in model.regional_indices: + if r1r2 in regions or '-' not in r1r2: + continue + r1, r2 = r1r2.split('-') + if (r1 in regions) != (r2 in regions): + _r_g += '+' + r1r2 + + # Gather valid processes + has_contributors = False + for p in model.time_optimize: + valid_rtv = { + (r, t, v) + for r, t in gather_group_active_processes(model, _r_g, p, t_g) + for v in model.process_vintages.get((r, p, t), set()) + } + if valid_rtv: + processes[name, r_g, t_g, p] = valid_rtv + has_contributors = True + else: + logger.info('Reserve %s has no contributors in period %s', (name, r_g, t_g), p) + if not has_contributors: + logger.warning('Reserve has no contributors in any period: %s', (name, r_g, t_g)) + + +def initialize_planning_reserve_margins(model: TemoaModel) -> None: + initialize_reserve_groups( + model, + model.planning_reserve_margin, + model.planning_reserve_processes, ) + for (prm, r_g, t_g, p), processes in model.planning_reserve_processes.items(): + if not any(model.planning_reserve_credit[prm, r, t] for r, t, _v in processes): + logger.warning('No non-zero credits for reserve %s', (prm, r_g, t_g, p)) - # The above code does not consider exchange techs, e.g. electricity - # transmission between two distinct regions. - # We take exchange takes into account below. - # Note that a single exchange tech linking regions Ri and Rj is twice - # defined: once for region "Ri-Rj" and once for region "Rj-Ri". - # First, determine the amount of firm capacity each exchange tech - # contributes. - for r1r2 in model.regional_indices: - if '-' not in r1r2: - continue - if ( - r1r2, - p, - ) not in model.process_reserve_periods: # ensure r1r2 is a valid reserve provider in p - continue - r1, r2 = r1r2.split('-') +# ============================================================================ +# HELPER FUNCTIONS FOR CONSTRAINT LOGIC +# ============================================================================ - output = sum( - get_available_output(model, r1r2, p, s, d, t, v) - * value(model.reserve_capacity_derate[r1r2, s, t, v]) - for (t, v) in model.process_reserve_periods[r1r2, p] - ) - # Only consider exchange technologies connecting to this region - if r2 == r: - # Add the firm capacity commitment TO this region - # (this region was guaranteed an import of power) - available += output - elif r1 == r: - # Subtract the firm capacity commitment FROM this region - # (this region guaranteed an export of power) - available -= output +def _into_region(model: TemoaModel, r: Region, t: Technology, regions: set[Region]) -> int: + """ + Returns +1 if not an exchange tech or is an exchange tech importing into the region group. + """ + if t not in model.tech_exchange: + return 1 + r1, r2 = r.split('-') + if r2 in regions and r1 not in regions: + return 1 + return 0 - return available +def _out_of_region(model: TemoaModel, r: Region, t: Technology, regions: set[Region]) -> int: + """ + Returns +1 if and only if is an exchange tech exporting out of the region group. + """ + if t not in model.tech_exchange: + return 0 + r1, r2 = r.split('-') + if r1 in regions and r2 not in regions: + return 1 + return 0 -def _available_activity_static( - model: TemoaModel, r: Region, p: Period, s: Season, d: TimeOfDay -) -> Expression: - available = sum( - value(model.capacity_credit[r, p, t, v]) - * model.v_capacity[r, p, t, v] - * value(model.capacity_to_activity[r, t]) - * value(model.segment_fraction[s, d]) - for (t, v) in model.process_reserve_periods[r, p] - if t not in model.tech_uncap - ) +def reserve_margin_proxy_demand( + model: TemoaModel, + processes: set[tuple[Region, Technology, Vintage]], + r_g: Region, + p: Period, + s: Season, + d: TimeOfDay, +) -> tuple[ExprLike, dict[tuple[Region, Technology, Vintage], ExprLike]]: + r"""In Temoa, demand for a particular commodity (e.g., electricity) may be endogenous to + decisions in the model. So, we estimate demand as the net production of processes + in the reserve group, :math:`\Theta^{res}_{n,r_g,t_g,p}`. This provides the RHS demand for + both reserve constraints. Also returns the net contribution of each process to that + demand, which the operating reserve margin reuses for activity credits. + + The region group :math:`r_g` indicates the regions in which demand is met, and the + tech group :math:`t_g` indicates which technologies supply the demanded commodity. The + technology group should include all technologies that produce, store, or import/export + the commodity of interest but **not** the technologies that demand it downstream. + + .. note:: + In Temoa, we are not reasonably able to disaggregate the **available** output of a + process for individual commodities when that process outputs multiple commodities. As a + result, a reserve margin constraint cannot be applied to a single commodity where supplying + processes output multiple different commodities (e.g., if a co-generation plant outputs both + heat and electricity, the heat will be included in the equations). This can be avoided by + adding an intermediate "dummy" process that throughputs only the output of interest and then + adding this dummy process to the tech group instead of the original process, but this + requires careful cloning of other technoeconomic parameters so the reserve contributions + remain the same. - # The above code does not consider exchange techs, e.g. electricity - # transmission between two distinct regions. - # We take exchange takes into account below. - # Note that a single exchange tech linking regions Ri and Rj is twice - # defined: once for region "Ri-Rj" and once for region "Rj-Ri". + .. math:: + :label: reserve_margin_proxy_demand + + \begin{aligned} + D^{proxy}_{r_g,p,s,d} =& + \sum_{\substack{(r,t,v) \in \Theta^{res} \setminus T^a \\ \uparrow_{r,r_g},\, I, O}} + \mathbf{FO}_{r, p, s, d, i, t, v, o} + && \text{(non-annual production and imports)} \\ + &+ \sum_{\substack{(r,t,v) \in \Theta^{res} \cap T^a \\ \uparrow_{r,r_g},\, I, O}} + \begin{cases} DSD_{r,s,d,o} & o \in C^d \\ SEG_{s,d} & \text{otherwise} + \end{cases} \cdot \mathbf{FOA}_{r, p, i, t, v, o} + && \text{(annual production and imports)} \\ + &- \sum_{(r,t,v) \in \Theta^{res} \cap T^s,\, I, O} + \mathbf{FI}_{r, p, s, d, i, t, v, o} + && \text{(storage inputs)} \\ + &- \sum_{\substack{(r,t,v) \in \Theta^{res} \cap T^x \setminus T^a \\ + \downarrow_{r,r_g},\, I, O}} + \mathbf{FO}_{r, p, s, d, i, t, v, o} / EFF_{r,p,s,d,i,t,v,o} + && \text{(non-annual exports)} \\ + &- \sum_{\substack{(r,t,v) \in \Theta^{res} \cap T^x \cap T^a \\ + \downarrow_{r,r_g},\, I, O}} + \begin{cases} DSD_{r,s,d,o} & o \in C^d \\ SEG_{s,d} & \text{otherwise} + \end{cases} \cdot \mathbf{FOA}_{r, p, i, t, v, o} / EFF_{r,p,i,t,v,o} + && \text{(annual exports)} + \end{aligned} + + where :math:`\uparrow_{r,r_g}` selects non-exchange processes and exchange imports + (:math:`r_2 \in r_g,\ r_1 \notin r_g`), and :math:`\downarrow_{r,r_g}` selects exchange + exports (:math:`r_1 \in r_g,\ r_2 \notin r_g`). + :math:`\Theta^{res} = \Theta^{res}_{n,r_g,t_g,p}` + is the set of all :math:`(r,t,v)` processes contributing to this reserve margin in this period. + """ + regions = geography.gather_group_regions(model, r_g) - # First, determine the amount of firm capacity each exchange tech - # contributes. - for r1r2 in model.regional_indices: - if '-' not in r1r2: - continue - if ( - r1r2, - p, - ) not in model.process_reserve_periods: # ensure r1r2 is a valid reserve provider in p - continue - r1, r2 = r1r2.split('-') + activity_rtv: dict[tuple[Region, Technology, Vintage], ExprLike] = dict.fromkeys(processes, 0) - # Only consider exchange technologies connecting to this region - if r2 == r: - # Add the firm capacity commitment TO this region - # (this region was guaranteed an import of power) - available += sum( - value(model.capacity_credit[r1r2, p, t, v]) - * model.v_capacity[r1r2, p, t, v] - * value(model.capacity_to_activity[r1r2, t]) - * value(model.segment_fraction[s, d]) - for (t, v) in model.process_reserve_periods[r1r2, p] - ) - elif r1 == r: - # Subtract the firm capacity commitment FROM this region - # (this region guaranteed an export of power) - available -= sum( - value(model.capacity_credit[r1r2, p, t, v]) - * model.v_capacity[r1r2, p, t, v] - * value(model.capacity_to_activity[r1r2, t]) - * value(model.segment_fraction[s, d]) - for (t, v) in model.process_reserve_periods[r1r2, p] + for r, t, v in processes: + # Non-annual activity + if t not in model.tech_annual and _into_region(model, r, t, regions): + activity_rtv[r, t, v] += quicksum( + model.v_flow_out[r, p, s, d, i, t, v, o] + for i in model.process_inputs[r, p, t, v] + for o in model.process_outputs_by_input[r, p, t, v, i] ) - return available - - -def _required_available_activity( - model: TemoaModel, r: Region, p: Period, s: Season, d: TimeOfDay -) -> ExprLike: - - # In most Temoa input databases, demand is endogenous, so we use electricity - # generation instead as a proxy for electricity demand. - # Non-annual generation - total_generation = sum( - model.v_flow_out[r, p, s, d, S_i, t, S_v, S_o] - for (t, S_v) in model.process_reserve_periods[r, p] - if t not in model.tech_annual - for S_i in model.process_inputs[r, p, t, S_v] - for S_o in model.process_outputs_by_input[r, p, t, S_v, S_i] - ) - - # Generators might serve demands directly - # Annual generation - total_generation += sum( - ( - value(model.demand_specific_distribution[r, p, s, d, S_o]) - if S_o in model.commodity_demand - else value(model.segment_fraction[s, d]) - ) - * model.v_flow_out_annual[r, p, S_i, t, S_v, S_o] - for (t, S_v) in model.process_reserve_periods[r, p] - if t in model.tech_annual - for S_i in model.process_inputs[r, p, t, S_v] - for S_o in model.process_outputs_by_input[r, p, t, S_v, S_i] - ) + # Annual activity (could also just be a demand tech) + if t in model.tech_annual and _into_region(model, r, t, regions): + activity_rtv[r, t, v] += quicksum( + ( + value(model.demand_specific_distribution[r, p, s, d, o]) + if o in model.commodity_demand + else value(model.segment_fraction[s, d]) + ) + * model.v_flow_out_annual[r, p, i, t, v, o] + for i in model.process_inputs[r, p, t, v] + for o in model.process_outputs_by_input[r, p, t, v, i] + ) - # We must take into account flows into storage technologies. - # Flows into storage technologies need to be subtracted from the - # load calculation. - total_generation -= sum( - model.v_flow_in[r, p, s, d, S_i, t, S_v, S_o] - for (t, S_v) in model.process_reserve_periods[r, p] - if t in model.tech_storage - for S_i in model.process_inputs[r, p, t, S_v] - for S_o in model.process_outputs_by_input[r, p, t, S_v, S_i] - ) + # We must take into account flows into storage technologies. + # Flows into storage technologies need to be subtracted from the + # load calculation. Flow_out already summed above. + if t in model.tech_storage and t not in model.tech_exchange: + activity_rtv[r, t, v] -= quicksum( + model.v_flow_in[r, p, s, d, i, t, v, o] + for i in model.process_inputs[r, p, t, v] + for o in model.process_outputs_by_input[r, p, t, v, i] + ) - # Electricity imports and exports via exchange techs are accounted - # for below: - for r1r2 in model.regional_indices: # ensure the region is of the form r1-r2 - if '-' not in r1r2: - continue - if ( - r1r2, - p, - ) not in model.process_reserve_periods: # ensure r1r2 is a valid reserve provider in p - continue - r1, r2 = r1r2.split('-') - # First, determine the exports, and subtract this value from the - # total generation. - if r1 == r: - total_generation -= sum( - model.v_flow_out[r1r2, p, s, d, S_i, t, S_v, S_o] - / get_variable_efficiency(model, r1r2, p, s, d, S_i, t, S_v, S_o) - for (t, S_v) in model.process_reserve_periods[r1r2, p] - for S_i in model.process_inputs[r1r2, p, t, S_v] - for S_o in model.process_outputs_by_input[r1r2, p, t, S_v, S_i] + # Subtract exchange exports + # Non-annual exports + if t not in model.tech_annual and _out_of_region(model, r, t, regions): + activity_rtv[r, t, v] -= quicksum( + model.v_flow_out[r, p, s, d, i, t, v, o] + / get_variable_efficiency(model, r, p, s, d, i, t, v, o) + for i in model.process_inputs[r, p, t, v] + for o in model.process_outputs_by_input[r, p, t, v, i] ) - # Second, determine the imports, and add this value from the - # total generation. - elif r2 == r: - total_generation += sum( - model.v_flow_out[r1r2, p, s, d, S_i, t, S_v, S_o] - for (t, S_v) in model.process_reserve_periods[r1r2, p] - for S_i in model.process_inputs[r1r2, p, t, S_v] - for S_o in model.process_outputs_by_input[r1r2, p, t, S_v, S_i] + # Annual exports (could feed a demand) + if t in model.tech_annual and _out_of_region(model, r, t, regions): + activity_rtv[r, t, v] -= quicksum( + ( + value(model.demand_specific_distribution[r, p, s, d, o]) + if o in model.commodity_demand + else value(model.segment_fraction[s, d]) + ) + * model.v_flow_out_annual[r, p, i, t, v, o] + / value(model.efficiency[r, i, t, v, o]) + for i in model.process_inputs[r, p, t, v] + for o in model.process_outputs_by_input[r, p, t, v, i] ) - requirement = total_generation * (1 + value(model.planning_reserve_margin[r])) - return requirement + demand = quicksum(activity_rtv.values()) + return demand, activity_rtv # ============================================================================ -# PYOMO CONSTRAINT RULE +# PYOMO CONSTRAINT RULES # ============================================================================ -def reserve_margin_dynamic( - model: TemoaModel, r: Region, p: Period, s: Season, d: TimeOfDay +def planning_reserve_margin_constraint( + model: TemoaModel, + prm: ReserveName, + r_g: Region, + t_g: Technology, + p: Period, + s: Season, + d: TimeOfDay, ) -> Constraint: r""" - A dynamic alternative to the traditional, static reserve margin constraint. Capacity values - are calculated from availability of generation in each hour—like an operating reserve margin—\ - accounting for a capacity derate factor subtracting, for example, forced outage due to icing. - - .. math:: - :label: reserve_margin_dynamic - - &\sum_{t \in T^{res} \setminus T^{x} \setminus T^s,\ V} CFP_{r,s^*,d^*,t,v}\ - \cdot RCD_{r,s^*,t,v}\ - \cdot \mathbf{CAP}_{r,p,t,v} \cdot SEG_{s^*,d^*}\ - \cdot C2A_{r,t} \\ - &+ \sum_{t \in T^{res} \cap T^{x} \setminus T^s,\ V} CFP_{r_i - r, s^*, d^*, t, v}\ - \cdot RCD_{r_i - r, s^*, t, v}\ - \cdot \mathbf{CAP}_{r_i - r,p,t,v} \cdot SEG_{s^*,d^*}\ - \cdot C2A_{r_i - r, t} \\ - &- \sum_{t \in T^{res} \cap T^{x} \setminus T^s,\ V} CFP_{r - r_i, s^*, d^*, t, v}\ - \cdot RCD_{r - r_i, s^*, t, v}\ - \cdot \mathbf{CAP}_{r - r_i,p,t,v}\ - \cdot SEG_{s^*,d^*} \cdot C2A_{r - r_i, t} \\ - &+ \sum_{t \in (T^s \cap T^{res}), V, I, O} \ - \left(\ - \mathbf{FO}_{r,p,s,d,i,t,v,o} - \mathbf{FI}_{r,p,s,d,i,t,v,o}\ - \right)\ - \cdot RCD_{r,s,t,v} \\ - &\geq\ - \left[\ - \sum_{t \in T^{res} \setminus T^{x} \setminus T^a, V, I, O}\ - \mathbf{FO}_{r, p, s, d, i, t, v, o}\ - \right. \\ - &+ \sum_{t \in T^{res} \cap T^a, V, I, O} - \begin{cases} DSD_{r,s,d,o} & \text{if } o \in C^d \\ - SEG_{s,d} & \text{otherwise} \end{cases} - \cdot \mathbf{FOA}_{r, p, i, t, v, o} \\ - &+ \sum_{t \in T^{res} \cap T^{x}, V, I, O} \ - \mathbf{FO}_{r_i - r, p, s, d, i, t, v, o} \\ - &- \sum_{t \in T^{res} \cap T^{x}, V, I, O} \ - \mathbf{FI}_{r - r_i, p, s, d, i, t, v, o} \\ - &- \left. \sum_{t \in T^{res} \cap T^{s}, V, I, O} \ - \mathbf{FI}_{r, p, s, d, i, t, v, o} \right] \cdot (1 + PRM_r) \\ - \\ - &\qquad \qquad \forall \{r, p, s, d\} \in \ - \Theta_{\text{ReserveMargin}} \text{ and } \forall r_i \in R + During each period :math:`p`, the sum of capacity values of all reserve + technologies, weighted by their planning reserve credit, must exceed the + proxy demand of reserve product :math:`n` by :math:`PRM_{n,r_g,t_g}` in every + time slice, where :math:`r_g` and :math:`t_g` are the product's region-group + and tech-group. Several products may be defined on the same groups. + + The credit formulation is selected per reserve product by the :code:`type` column of + :code:`planning_reserve_margin` (:code:`planning_reserve_type` in the model), either + :code:`static` (:func:`~temoa.components.reserves._planning_reserve_margin_static`, + the default) or :code:`dynamic` + (:func:`~temoa.components.reserves._planning_reserve_margin_dynamic`). + Static credits a fraction of installed capacity in every time slice; dynamic credits a + fraction of the output actually available in each time slice. """ - return _available_activity_dynamic(model, r, p, s, d) >= _required_available_activity( - model, r, p, s, d - ) + reserve_type = model.planning_reserve_type[prm, r_g, t_g] + if reserve_type == ReserveMarginType.DYNAMIC: + return _planning_reserve_margin_dynamic(model, prm, r_g, t_g, p, s, d) + elif reserve_type == ReserveMarginType.STATIC: + return _planning_reserve_margin_static(model, prm, r_g, t_g, p, s, d) + else: + msg = ( + f"Unknown planning reserve type '{reserve_type}' for reserve product " + f"'{prm}' in region-group '{r_g}' and tech-group '{t_g}'." + ) + logger.error(msg) + raise ValueError(msg) -def reserve_margin_static( - model: TemoaModel, r: Region, p: Period, s: Season, d: TimeOfDay +def _planning_reserve_margin_static( + model: TemoaModel, + prm: ReserveName, + r_g: Region, + t_g: Technology, + p: Period, + s: Season, + d: TimeOfDay, ) -> Constraint: r""" - During each period :math:`p`, the sum of capacity values of all reserve - technologies :math:`\sum_{t \in T^{res}} \textbf{CAP}_{r,p,t,v}`, which are - defined in the set :math:`\textbf{T}^{res}`, should exceed the peak load by - :math:`PRM`, the regional reserve margin. Note that the reserve - margin is expressed in percentage of the peak load. Generally speaking, in - a database we may not know the peak demand before running the model, therefore, - we write this equation for all the time-slices defined in the database in each region. - Each generator is allowed to contribute its available capacity times a pre-defined - capacity credit, :math:`CC_{r,p,t,v}`. - - For exchange technologies (i.e., inter-regional transmission), reserve contributions - are added to the downstream region but *subtracted* from the upstream region. This is - because, since they are not generating any power, their summed contribution across - regions should be zero. + In the static formulation, during each period :math:`p`, the sum of capacity + values of all reserve technologies, weighted by their planning reserve credit, + must exceed the reserve product's proxy demand by :math:`PRM_{n,r_g,t_g}` in every + time slice. + + This credit represents the expected availability of nameplate capacity + during binding demand conditions and is usually determined from stochastic + modelling of demand/supply scenarios. A credit of 1 indicates the technology is + expected to be able to output its full nameplate capacity at high demand, + while 0 indicates it offers no reliable capacity. Technologies in the tech + group are used to calculate the proxy demand and so must include these zero + credit processes as well. + + **The default credit is 0** if not set (i.e., we assume technologies offer + no reserve by default). + + For exchange technologies (e.g., inter-regional transmission), reserve + contributions are added for import capacity into the region-group but the same + contribution is *subtracted* for export capacity out of it. .. math:: - :label: reserve_margin_static - - &\sum_{t \in T^{res} \setminus T^{x}, V} {CC_{r,p,t,v} - \cdot \textbf{CAP}_{r,p,t,v} \cdot - SEG_{s^*,d^*} \cdot C2A_{r,t} }\\ - &+ \sum_{t \in T^{res} \cap T^{x}, V} {CC_{r_i-r,p,t,v} - \cdot \textbf{CAP}_{r_i-r,p,t,v} \cdot - SEG_{s^*,d^*} \cdot C2A_{r_i-r,t} }\\ - &- \sum_{t \in T^{res} \cap T^{x}, V} {CC_{r-r_i,p,t,v} - \cdot \textbf{CAP}_{r-r_i,p,t,v} \cdot - SEG_{s^*,d^*} \cdot C2A_{r-r_i,t} }\\ - &\geq \left [ \sum_{ t \in T^{res} \setminus T^{x} \setminus T^a,V,I,O } - \textbf{FO}_{r, p, s, d, i, t, v, o}\right.\\ - &+ \sum_{ t \in T^{res} \cap T^a,V,I,O } - \begin{cases} DSD_{r,s,d,o} & \text{if } o \in C^d \\ - SEG_{s,d} & \text{otherwise} \end{cases} - \cdot \textbf{FOA}_{r, p, i, t, v, o}\\ - &+ \sum_{ t \in T^{res} \cap T^{x},V,I,O } \textbf{FO}_{r_i-r, p, s, d, i, t, v, o}\\ - &- \sum_{ t \in T^{res} \cap T^{x},V,I,O } \textbf{FI}_{r-r_i, p, s, d, i, t, v, o}\\ - &- \left.\sum_{ t \in T^{res} \cap T^{s},V,I,O } \textbf{FI}_{r, p, s, d, i, t, v, o} - \right] - \cdot (1 + PRM_r)\\ - - \\ - &\qquad\qquad\forall \{r, p, s, d\} \in \Theta_{\text{ReserveMargin}} \text{and} \forall - r_i \in R + :label: planning_reserve_margin_static + + \begin{aligned} + &\sum_{(r,t,v) \in \Theta^{res} \setminus T^x} + PRC_{n,t} \cdot \mathbf{CAP}_{r,p,t,v} \cdot SEG_{s,d} \cdot C2A_{r,t} + && \text{(production capacity, includes storage)} \\ + &+ \sum_{(r,t,v) \in \Theta^{res} \cap T^x} + \sigma_{r,r_g} \cdot PRC_{n,t} \cdot \mathbf{CAP}_{r,p,t,v} + \cdot SEG_{s,d} \cdot C2A_{r,t} + && \text{(net import capacity)} \\ + &\geq D^{proxy}_{r_g,p,s,d} \cdot (1 + PRM_{n,r_g,t_g}) \\ + &\forall \{n, r_g, t_g, p, s, d\} \in \Theta_{\text{PlanningReserveMargin}} + \end{aligned} + + where :math:`\sigma_{r,r_g} = +1` for an exchange process delivering into + region-group :math:`r_g` and :math:`-1` for one delivering out of it, + :math:`\Theta^{res} = \Theta^{res}_{n,r_g,t_g,p}` is the set of processes contributing to + product :math:`{n,r_g,t_g}` in period :math:`p`, and :math:`D^{proxy}_{n,r_g,t_g,p,s,d}` is the + product's proxy demand defined in :eq:`reserve_margin_proxy_demand`. """ - return _available_activity_static(model, r, p, s, d) >= _required_available_activity( - model, r, p, s, d + processes = model.planning_reserve_processes[prm, r_g, t_g, p] + + available = quicksum( + value(model.planning_reserve_credit[prm, r, t]) + * model.v_capacity[r, p, t, v] + * value(model.capacity_to_activity[r, t]) + * value(model.segment_fraction[s, d]) + for r, t, v in processes + if t not in model.tech_uncap and t not in model.tech_exchange ) + # Add credited imports into the group, subtract credited exports out of it + regions = geography.gather_group_regions(model, r_g) + for r1r2, t, v in processes: + if t not in model.tech_exchange: + continue + + _available = ( + value(model.planning_reserve_credit[prm, r1r2, t]) + * model.v_capacity[r1r2, p, t, v] + * value(model.capacity_to_activity[r1r2, t]) + * value(model.segment_fraction[s, d]) + ) + + r1, r2 = r1r2.split('-') + if r2 in regions and r1 not in regions: + available += _available + elif r1 in regions and r2 not in regions: + available -= _available + + demand, _ = reserve_margin_proxy_demand(model, processes, r_g, p, s, d) + return available >= demand * (1 + value(model.planning_reserve_margin[prm, r_g, t_g])) -def reserve_margin_constraint( + +def _planning_reserve_margin_dynamic( model: TemoaModel, - r: Region, + prm: ReserveName, + r_g: Region, + t_g: Technology, p: Period, s: Season, d: TimeOfDay, -) -> ExprLike: - """Returns the appropriate reserve margin constraint rule.""" - if (not model.tech_reserve) or ( - (r, p) not in model.process_reserve_periods - ): # If reserve set empty or if r,p not in M.processReservePeriod, skip the constraint - return Constraint.Skip - mode = model.reserve_margin_method.first() - if mode == 'dynamic': - return reserve_margin_dynamic(model, r, p, s, d) - elif mode == 'static': - return reserve_margin_static(model, r, p, s, d) - else: - raise ValueError( - f"Invalid reserve margin method: {mode}. Must be either 'dynamic' or 'static'." +) -> Constraint: + r""" + A dynamic alternative to the static planning reserve margin constraint. Capacity values are + calculated from process output availability in each time slice, accounting for capacity + factors, unit commitment (if the extension is enabled), and the planning reserve credit + which may derate contributions for, for example, forced outage rates. A credit of 1 + indicates no derating while a credit of zero indicates zero dependable output. + The tech group :math:`t_g` should include technologies with no credit as these are still + used to calculate the proxy demand for the reserve. + + **The default credit is 0** if not set (i.e., we assume technologies offer + no reserve by default). + + For exchange technologies (e.g., inter-regional transmission), reserve + contributions are added for available imports into the region-group but *subtracted* + for available exports out of it. + + The availability of storage technologies is a non-trivial problem as it depends on state + of charge, which has a temporal dependency (i.e., if we consider a storage technology to + contribute reserve in time t can it also contribute in time t+1?). In this implementation, + we let storage contribute only what it actually outputs (net) in each time slice, as a + conservative but tractable approach (use it or lose it). + + .. math:: + :label: planning_reserve_margin_dynamic + + \begin{aligned} + &\sum_{(r,t,v) \in \Theta^{res} \setminus T^x \setminus T^s} + CFP_{r,s,d,t,v} \cdot PRC_{n,t} \cdot \mathbf{CAP}_{r,p,t,v} + \cdot SEG_{s,d} \cdot C2A_{r,t} + && \text{(firm production)} \\ + &+ \sum_{(r,t,v) \in \Theta^{res} \cap T^s,\, I, O} + \left( \mathbf{FO}_{r,p,s,d,i,t,v,o} - \mathbf{FI}_{r,p,s,d,i,t,v,o} \right) + \cdot PRC_{n,t} + && \text{(net storage output)} \\ + &+ \sum_{(r,t,v) \in \Theta^{res} \cap T^x} + \sigma_{r,r_g} \cdot CFP_{r,s,d,t,v} \cdot PRC_{n,t} + \cdot \mathbf{CAP}_{r,p,t,v} \cdot SEG_{s,d} \cdot C2A_{r,t} + && \text{(net firm imports)} \\ + &\geq D^{proxy}_{r_g,p,s,d} \cdot (1 + PRM_{n,r_g,t_g}) \\ + &\forall \{n, r_g, t_g, p, s, d\} \in \Theta_{\text{PlanningReserveMargin}} + \end{aligned} + + where :math:`\sigma_{r,r_g} = +1` for an exchange process delivering into + region-group :math:`r_g` and :math:`-1` for one delivering out of it, + :math:`\Theta^{res} = \Theta^{res}_{n,r_g,t_g,p}` is the set of processes contributing to + product :math:`{n,r_g,t_g}` in period :math:`p`, and :math:`D^{proxy}_{n,r_g,t_g,p,s,d}` is the + product's proxy demand defined in :eq:`reserve_margin_proxy_demand`. + """ + processes = model.planning_reserve_processes[prm, r_g, t_g, p] + + # Everything but storage and exchange techs + # Derated available generation + available = quicksum( + get_available_output(model, r, p, s, d, t, v) + * value(model.planning_reserve_credit[prm, r, t]) + for (r, t, v) in processes + if not (t in model.tech_uncap or t in model.tech_storage or t in model.tech_exchange) + ) + + # Storage + # Derated net output flow + available += quicksum( + model.v_flow_out[r, p, s, d, i, t, v, o] * value(model.planning_reserve_credit[prm, r, t]) + for (r, t, v) in processes + if t in model.tech_storage and t not in model.tech_exchange + for i in model.process_inputs[r, p, t, v] + for o in model.process_outputs_by_input[r, p, t, v, i] + ) + available -= quicksum( + model.v_flow_in[r, p, s, d, i, t, v, o] * value(model.planning_reserve_credit[prm, r, t]) + for (r, t, v) in processes + if t in model.tech_storage and t not in model.tech_exchange + for i in model.process_inputs[r, p, t, v] + for o in model.process_outputs_by_input[r, p, t, v, i] + ) + + # Exchange technologies + # Add available imports into the group, subtract available exports out of it + regions = geography.gather_group_regions(model, r_g) + for r1r2, t, v in processes: + if t not in model.tech_exchange: + continue + + _available = get_available_output(model, r1r2, p, s, d, t, v) * value( + model.planning_reserve_credit[prm, r1r2, t] ) + + r1, r2 = r1r2.split('-') + if r2 in regions and r1 not in regions: + available += _available + elif r1 in regions and r2 not in regions: + available -= _available + + demand, _ = reserve_margin_proxy_demand(model, processes, r_g, p, s, d) + return available >= demand * (1 + value(model.planning_reserve_margin[prm, r_g, t_g])) diff --git a/temoa/components/technology.py b/temoa/components/technology.py index 9957db979..d7666b4ec 100644 --- a/temoa/components/technology.py +++ b/temoa/components/technology.py @@ -20,8 +20,6 @@ from temoa.components.utils import get_adjusted_existing_capacity if TYPE_CHECKING: - from collections.abc import Iterable - from temoa.core.model import TemoaModel from temoa.types import Period, Region, Technology, Vintage @@ -32,13 +30,11 @@ # ============================================================================ -def gather_group_techs(model: TemoaModel, t_or_g: Technology) -> Iterable[Technology]: +def gather_group_techs(model: TemoaModel, t_or_g: Technology) -> set[Technology]: if t_or_g in model.tech_group_names: - return model.tech_group_members[t_or_g] - elif '+' in t_or_g: - return [cast('Technology', tech) for tech in t_or_g.split('+')] + return set(model.tech_group_members[t_or_g]) else: - return (t_or_g,) + return {t_or_g} # ============================================================================ diff --git a/temoa/core/config.py b/temoa/core/config.py index 173b296b7..212d0c149 100644 --- a/temoa/core/config.py +++ b/temoa/core/config.py @@ -54,7 +54,6 @@ def __init__( save_lp_file: bool = False, time_sequencing: str | None = None, days_per_period: int = 365, - reserve_margin: str | None = None, MGA: dict[str, object] | None = None, SVMGA: dict[str, object] | None = None, myopic: dict[str, object] | None = None, @@ -155,7 +154,6 @@ def __init__( self.save_lp_file = save_lp_file self.time_sequencing = time_sequencing self.days_per_period = days_per_period - self.reserve_margin = reserve_margin self.mga_inputs = MGA self.svmga_inputs = SVMGA @@ -420,7 +418,6 @@ def __repr__(self) -> str: msg += spacer msg += '{:>{}s}: {}\n'.format('Time sequencing', width, self.time_sequencing) msg += '{:>{}s}: {}\n'.format('Days per period', width, self.days_per_period) - msg += '{:>{}s}: {}\n'.format('Planning reserve margin', width, self.reserve_margin) if self.scenario_mode == TemoaMode.MYOPIC and self.myopic_inputs is not None: msg += spacer diff --git a/temoa/core/model.py b/temoa/core/model.py index b52ec1779..0d812fea1 100755 --- a/temoa/core/model.py +++ b/temoa/core/model.py @@ -48,9 +48,9 @@ validate_0to1, validate_efficiency, validate_linked_tech, - validate_reserve_margin, validate_tech_sets, ) +from temoa.types.core_types import ReserveMarginType if TYPE_CHECKING: from temoa import types as t @@ -162,8 +162,8 @@ def __init__( self.retirement_production_processes: t.RetirementProductionProcessesDict = {} self.process_inputs_by_output: t.ProcessInputsByOutputDict = {} self.process_outputs_by_input: t.ProcessOutputsByInputDict = {} - self.process_reserve_periods: t.ProcessReservePeriodsDict = {} self.process_periods: t.ProcessPeriodsDict = {} # {(r, t, v): set(p)} + self.planning_reserve_processes: t.ReserveProcessesDict = {} # {(r, t, v): set(p)} periods in which a process can economically or naturally retire self.retirement_periods: t.RetirementPeriodsDict = {} self.process_vintages: t.ProcessVintagesDict = {} @@ -263,7 +263,6 @@ def __init__( self.tech_demand = Set(within=self.tech_all) # annual storage not supported in Storage constraint or TableWriter, so exclude from domain self.tech_storage = Set(within=self.tech_all) - self.tech_reserve = Set(within=self.tech_all) self.tech_upramping = Set(within=self.tech_all) self.tech_downramping = Set(within=self.tech_all) self.tech_curtailment = Set(within=self.tech_all) @@ -279,7 +278,7 @@ def __init__( self.tech_seasonal_storage = Set(within=self.tech_storage) """storage technologies using the interseasonal storage feature""" - self.tech_uncap = Set(within=self.tech_all - self.tech_reserve) + self.tech_uncap = Set(within=self.tech_all) """techs with unlimited capacity, ALWAYS available within lifespan""" self.tech_exist = Set() @@ -517,13 +516,6 @@ def __init__( validate=validate_0to1, ) - self.renewable_portfolio_standard_constraint_rpg = Set( - within=self.regions * self.time_optimize * self.tech_group_names - ) - self.renewable_portfolio_standard = Param( - self.renewable_portfolio_standard_constraint_rpg, validate=validate_0to1 - ) - # The method below creates a series of helper functions that are used to # perform the sparse matrix of indexing for the parameters, variables, and # equations below. @@ -721,24 +713,24 @@ def __init__( self.linked_techs = Param(self.regional_indices, self.tech_all, self.commodity_emissions) # Define parameters associated with electric sector operation - self.reserve_margin_method = Set() # How contributions to the reserve margin are calculated - self.capacity_credit = Param( + self.planning_reserves = Set() + self.planning_reserve_margin = Param( + self.planning_reserves, self.regional_global_indices, self.tech_or_group + ) + self.planning_reserve_type = Param( + self.planning_reserves, + self.regional_global_indices, + self.tech_or_group, + within=list(ReserveMarginType), + default=ReserveMarginType.STATIC, + ) + self.planning_reserve_credit = Param( + self.planning_reserves, self.regional_indices, - self.time_optimize, - self.tech_reserve, - self.vintage_all, + self.tech_all, default=0, validate=validate_0to1, ) - self.reserve_capacity_derate = Param( - self.regional_indices, - self.time_season, - self.tech_reserve, - self.vintage_all, - default=1, - validate=validate_0to1, - ) - self.planning_reserve_margin = Param(self.regions) self.emission_embodied = Param( self.regions, @@ -982,10 +974,12 @@ def __init__( self.ramp_up_constraint_rpsdtv, rule=operations.ramp_up_constraint ) - self.reserve_margin_rpsd = Set(dimen=4, initialize=reserves.reserve_margin_indices) - self.validate_reserve_margin = BuildAction(rule=validate_reserve_margin) - self.reserve_margin_constraint = Constraint( - self.reserve_margin_rpsd, rule=reserves.reserve_margin_constraint + self.initialize_reserve_margins = BuildAction( + rule=reserves.initialize_planning_reserve_margins + ) + self.planning_reserve_nrtpsd = Set(dimen=6, initialize=reserves.planning_reserve_indices) + self.planning_reserve_margin_constraint = Constraint( + self.planning_reserve_nrtpsd, rule=reserves.planning_reserve_margin_constraint ) self.limit_emission_constraint = Constraint( @@ -1091,11 +1085,6 @@ def __init__( rule=limits.limit_tech_output_split_average_constraint, ) - self.renewable_portfolio_standard_constraint = Constraint( - self.renewable_portfolio_standard_constraint_rpg, - rule=limits.renewable_portfolio_standard_constraint, - ) - self.linked_emissions_tech_constraint_rpsdtve = Set( dimen=7, initialize=emissions.linked_tech_constraint_indices ) diff --git a/temoa/data_io/component_manifest.py b/temoa/data_io/component_manifest.py index 7521b34c8..301efdc8e 100644 --- a/temoa/data_io/component_manifest.py +++ b/temoa/data_io/component_manifest.py @@ -101,15 +101,6 @@ def build_manifest(model: TemoaModel, extension_ids: Sequence[str] | None = None validation_map=(0,), is_period_filtered=False, ), - LoadItem( - component=model.tech_reserve, - table='technology', - columns=['tech'], - where_clause='reserve > 0', - validator_name='viable_techs', - validation_map=(0,), - is_period_filtered=False, - ), LoadItem( component=model.tech_curtailment, table='technology', @@ -499,34 +490,36 @@ def build_manifest(model: TemoaModel, extension_ids: Sequence[str] | None = None is_period_filtered=False, ), LoadItem( - component=model.renewable_portfolio_standard, - table='rps_requirement', - columns=['region', 'period', 'tech_group', 'requirement'], - custom_loader_name='_load_rps_requirement', + component=model.planning_reserves, + table='planning_reserve_margin', + columns=['reserve_name'], + is_period_filtered=False, is_table_required=False, - index_set=model.renewable_portfolio_standard_constraint_rpg, ), LoadItem( - component=model.capacity_credit, - table='capacity_credit', - columns=['region', 'period', 'tech', 'vintage', 'credit'], - validator_name='viable_rtv', - validation_map=(0, 2, 3), + component=model.planning_reserve_credit, + table='planning_reserve_credit', + columns=['reserve_name', 'region', 'tech', 'credit'], + validator_name='viable_rt', + validation_map=(1, 2), + is_period_filtered=False, is_table_required=False, ), LoadItem( - component=model.reserve_capacity_derate, - table='reserve_capacity_derate', - columns=['region', 'season', 'tech', 'vintage', 'factor'], - validator_name='viable_rtv', - validation_map=(0, 2, 3), + component=model.planning_reserve_margin, + table='planning_reserve_margin', + columns=['reserve_name', 'region', 'tech_or_group', 'margin'], + validator_name='viable_rt', + validation_map=(1, 2), is_period_filtered=False, is_table_required=False, ), LoadItem( - component=model.planning_reserve_margin, + component=model.planning_reserve_type, table='planning_reserve_margin', - columns=['region', 'margin'], + columns=['reserve_name', 'region', 'tech_or_group', 'type'], + validator_name='viable_rt', + validation_map=(1, 2), is_period_filtered=False, is_table_required=False, ), diff --git a/temoa/data_io/hybrid_loader.py b/temoa/data_io/hybrid_loader.py index 6f7e26b1c..427c6e92a 100644 --- a/temoa/data_io/hybrid_loader.py +++ b/temoa/data_io/hybrid_loader.py @@ -66,6 +66,7 @@ 'limit_capacity_share': 'region', 'limit_new_capacity_share': 'region', 'limit_resource': 'region', + 'planning_reserve_margin': 'region', } @@ -284,9 +285,6 @@ def create_data_dict(self, myopic_index: MyopicIndex | None = None) -> dict[str, # Load simple config-based or myopic-specific values self._load_component_data(data, model.time_sequencing, [(self.config.time_sequencing,)]) self._load_component_data(data, model.days_per_period, [(self.config.days_per_period,)]) - self._load_component_data( - data, model.reserve_margin_method, [(self.config.reserve_margin,)] - ) if myopic_index: p0_result = cur.execute( "SELECT min(period) FROM time_period WHERE flag == 'f'" @@ -856,22 +854,6 @@ def _load_ramping_up( ) self._load_component_data(data, model.tech_upramping, tech_filtered) - def _load_rps_requirement( - self, - data: dict[str, object], - raw_data: Sequence[tuple[object, ...]], - filtered_data: Sequence[tuple[object, ...]], - ) -> None: - """Handles deprecation warning for renewable_portfolio_standard.""" - model = self.model - self._load_component_data(data, model.renewable_portfolio_standard, filtered_data) - if filtered_data: - logger.warning( - 'The renewable_portfolio_standard constraint is deprecated. Use ' - 'limit_activity_share instead. ' - 'The constraint has been applied but this feature may be removed in the future.' - ) - def _load_limit_tech_input_split( self, data: dict[str, object], diff --git a/temoa/db_schema/temoa_schema_v4_1.sql b/temoa/db_schema/temoa_schema_v4_1.sql new file mode 100644 index 000000000..5df85231c --- /dev/null +++ b/temoa/db_schema/temoa_schema_v4_1.sql @@ -0,0 +1,977 @@ +PRAGMA foreign_keys = OFF; +BEGIN TRANSACTION; + +CREATE TABLE IF NOT EXISTS metadata +( + element TEXT, + value INT, + notes TEXT, + PRIMARY KEY (element) +); +REPLACE INTO metadata +VALUES ('DB_MAJOR', 4, 'DB major version number'); +REPLACE INTO metadata +VALUES ('DB_MINOR', 1, 'DB minor version number'); + +CREATE TABLE IF NOT EXISTS metadata_real +( + element TEXT, + value REAL, + notes TEXT, + + PRIMARY KEY (element) +); +REPLACE INTO metadata_real +VALUES ('global_discount_rate', 0.05, 'Discount Rate for future costs'); +REPLACE INTO metadata_real +VALUES ('default_loan_rate', 0.05, 'Default Loan Rate if not specified in LoanRate table'); + +CREATE TABLE IF NOT EXISTS output_dual_variable +( + scenario TEXT, + constraint_name TEXT, + dual REAL, + PRIMARY KEY (constraint_name, scenario) +); +CREATE TABLE IF NOT EXISTS output_objective +( + scenario TEXT, + objective_name TEXT, + total_system_cost REAL +); +CREATE TABLE IF NOT EXISTS sector_label +( + sector TEXT PRIMARY KEY, + notes TEXT +); +CREATE TABLE IF NOT EXISTS 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) +); +CREATE TABLE IF NOT EXISTS 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) +); +CREATE TABLE IF NOT EXISTS capacity_to_activity +( + region TEXT, + tech TEXT + REFERENCES technology (tech), + c2a REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, tech) +); +CREATE TABLE IF NOT EXISTS commodity +( + name TEXT + PRIMARY KEY, + flag TEXT + REFERENCES commodity_type (label), + description TEXT, + units TEXT +); +CREATE TABLE IF NOT EXISTS commodity_type +( + label TEXT + PRIMARY KEY, + description TEXT +); +REPLACE INTO commodity_type +VALUES ('s', 'source commodity'); +REPLACE INTO commodity_type +VALUES ('a', 'annual commodity'); +REPLACE INTO commodity_type +VALUES ('p', 'physical commodity'); +REPLACE INTO commodity_type +VALUES ('d', 'demand commodity'); +REPLACE INTO commodity_type +VALUES ('e', 'emissions 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'); +CREATE TABLE IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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) +); +CREATE TABLE IF NOT EXISTS 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) +); +CREATE TABLE IF NOT EXISTS 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) +); +CREATE TABLE IF NOT EXISTS 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) +); +CREATE TABLE IF NOT EXISTS 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) +); +CREATE TABLE IF NOT EXISTS 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 IF NOT EXISTS 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) +); +CREATE TABLE IF NOT EXISTS 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 IF NOT EXISTS 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) +); +CREATE TABLE IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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) +); +CREATE TABLE IF NOT EXISTS tech_group +( + group_name TEXT + PRIMARY KEY, + notes TEXT +); +CREATE TABLE IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS lifetime_tech +( + region TEXT, + tech TEXT + REFERENCES technology (tech), + lifetime REAL, + units TEXT, + notes TEXT, + PRIMARY KEY (region, tech) +); +CREATE TABLE IF NOT EXISTS operator +( + operator TEXT PRIMARY KEY, + notes TEXT +); +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_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 IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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) +); +CREATE TABLE IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS limit_seasonal_capacity_factor +( + region TEXT, + 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 IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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) +); +CREATE TABLE IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS 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 IF NOT EXISTS planning_reserve_margin +( + reserve_name TEXT, + region TEXT, + tech_or_group TEXT, + type TEXT DEFAULT 'static', + margin REAL, + notes TEXT, + PRIMARY KEY (reserve_name, region, tech_or_group), + CHECK (margin >= 0), + CHECK (type IN ('static', 'dynamic')) +); +CREATE TABLE IF NOT EXISTS planning_reserve_credit +( + reserve_name TEXT, + region TEXT, + tech TEXT + REFERENCES technology (tech), + credit REAL, + notes TEXT, + PRIMARY KEY (reserve_name, region, tech), + CHECK (credit >= 0 AND credit <= 1) +); +CREATE TABLE IF NOT EXISTS ramp_down_hourly +( + region TEXT, + tech TEXT + REFERENCES technology (tech), + rate REAL, + notes TEXT, + PRIMARY KEY (region, tech) +); +CREATE TABLE IF NOT EXISTS ramp_up_hourly +( + region TEXT, + tech TEXT + REFERENCES technology (tech), + rate REAL, + notes TEXT, + PRIMARY KEY (region, tech) +); +CREATE TABLE IF NOT EXISTS region +( + region TEXT + PRIMARY KEY, + notes TEXT +); +CREATE TABLE IF NOT EXISTS storage_duration +( + region TEXT, + tech TEXT, + duration REAL, + notes TEXT, + PRIMARY KEY (region, tech) +); +CREATE TABLE IF NOT EXISTS 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 IF NOT EXISTS technology_type +( + label TEXT + PRIMARY KEY, + description TEXT +); +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'); +-- CREATE TABLE IF NOT EXISTS time_manual +-- ( +-- season TEXT +-- REFERENCES time_season (season), +-- tod TEXT +-- REFERENCES time_of_day (tod), +-- season_next TEXT +-- REFERENCES time_season (season), +-- tod_next TEXT +-- REFERENCES time_of_day (tod), +-- notes TEXT, +-- PRIMARY KEY (season, tod) +-- ); +CREATE TABLE IF NOT EXISTS time_of_day +( + sequence INTEGER UNIQUE, + tod TEXT + PRIMARY KEY, + hours REAL NOT NULL DEFAULT 1, + notes TEXT, + CHECK (hours > 0) +); +CREATE TABLE IF NOT EXISTS time_period +( + sequence INTEGER UNIQUE, + period INTEGER + PRIMARY KEY, + flag TEXT + REFERENCES time_period_type (label) +); +CREATE TABLE IF NOT EXISTS time_period_type +( + label TEXT + PRIMARY KEY, + description TEXT +); +REPLACE INTO time_period_type +VALUES('e', 'existing vintages'); +REPLACE INTO time_period_type +VALUES('f', 'future'); +CREATE TABLE IF NOT EXISTS 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 IF NOT EXISTS tech_group_member +( + group_name TEXT + REFERENCES tech_group (group_name), + tech TEXT + REFERENCES technology (tech), + PRIMARY KEY (group_name, tech) +); +CREATE TABLE IF NOT EXISTS 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, + 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) +); +CREATE TABLE IF NOT EXISTS output_cost +( + scenario TEXT, + region TEXT, + sector TEXT REFERENCES sector_label (sector), + period INTEGER REFERENCES time_period (period), + tech TEXT, + 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) +); + +CREATE TABLE IF NOT EXISTS 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) +); + +CREATE TABLE IF NOT EXISTS 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 TABLE IF NOT EXISTS 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) +); +-- for efficient searching by rtv: +CREATE INDEX IF NOT EXISTS region_tech_vintage ON myopic_efficiency (region, tech, vintage); + +CREATE TABLE IF NOT EXISTS 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) +); + +COMMIT; +PRAGMA foreign_keys = ON; diff --git a/temoa/extensions/framework.py b/temoa/extensions/framework.py index bf32b3bee..1b1b05746 100644 --- a/temoa/extensions/framework.py +++ b/temoa/extensions/framework.py @@ -25,6 +25,8 @@ class ExtensionSpec: extension_id: str owned_tables: tuple[str, ...] = () + # Result tables with `scenario` and `period` columns; cleared by run/myopic cleanup + output_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 @@ -84,6 +86,13 @@ def resolve_extension_specs(extension_ids: Sequence[str] | None) -> tuple[Extens return tuple(known[ext_id] for ext_id in normalized_ids) +def get_extension_output_tables(extension_ids: Sequence[str] | None) -> tuple[str, ...]: + """Return the output tables declared by the enabled extensions.""" + return tuple( + table for spec in resolve_extension_specs(extension_ids) for table in spec.output_tables + ) + + def apply_model_extension_hooks(model: TemoaModel, specs: Sequence[ExtensionSpec]) -> None: """Attach extension-owned model components to a model instance.""" for spec in specs: diff --git a/temoa/extensions/myopic/myopic_sequencer.py b/temoa/extensions/myopic/myopic_sequencer.py index 8d01c0c04..bf6e638db 100644 --- a/temoa/extensions/myopic/myopic_sequencer.py +++ b/temoa/extensions/myopic/myopic_sequencer.py @@ -19,6 +19,7 @@ from temoa.core.solver_spec import resolve_solver_options from temoa.data_io.hybrid_loader import HybridLoader from temoa.data_processing.db_to_excel import make_excel +from temoa.extensions.framework import get_extension_output_tables from temoa.extensions.myopic.myopic_index import MyopicIndex from temoa.extensions.myopic.myopic_progress_mapper import MyopicProgressMapper from temoa.model_checking.pricing_check import price_checker @@ -635,6 +636,9 @@ def execute_script(self, script_file: Path) -> None: self.cursor.executescript(sql_commands) self.output_con.commit() + def _extension_output_tables(self) -> tuple[str, ...]: + return get_extension_output_tables(self.config.extensions if self.config else None) + def clear_old_results(self) -> None: """ Clear old results from tables @@ -644,7 +648,7 @@ def clear_old_results(self) -> None: assert self.output_con is not None scenario_name = self.config.scenario if self.config else None logger.debug('Deleting old results for scenario name %s', scenario_name) - for table in self.tables_with_scenario_reference: + for table in (*self.tables_with_scenario_reference, *self._extension_output_tables()): try: self.cursor.execute( f'DELETE FROM {table} WHERE scenario = ? OR scenario like ?', @@ -693,7 +697,7 @@ def clear_results_after(self, period: int) -> None: assert self.cursor is not None assert self.output_con is not None - for table in self.tables_with_period: + for table in (*self.tables_with_period, *self._extension_output_tables()): scenario_name = self.config.scenario if self.config else None try: self.cursor.execute( diff --git a/temoa/extensions/unit_commitment/components/commitment.py b/temoa/extensions/unit_commitment/components/commitment.py index 998502517..80916d35e 100644 --- a/temoa/extensions/unit_commitment/components/commitment.py +++ b/temoa/extensions/unit_commitment/components/commitment.py @@ -8,7 +8,7 @@ - min/max output from online units - min up-time and min down-time via cyclic windows - ramp-up and ramp-down constraints that account for online units and started/stopped units - - dynamic reserve margin constraint that accounts for online units and started/stopped units + - operating reserve margin constraint that accounts for online units and started/stopped units """ from __future__ import annotations @@ -236,8 +236,8 @@ def uc_available_output( if (r, t) not in model.uc_unit_capacity: return available_output_base(model, r, p, s, d, t, v) base = ( - model.capacity_to_activity[r, t] - * model.segment_fraction[s, d] + value(model.capacity_to_activity[r, t]) + * value(model.segment_fraction[s, d]) * value(model.uc_max_output_fraction[r, t]) * value(model.uc_unit_capacity[r, t]) * model.v_uc_online[r, p, s, d, t, v] diff --git a/temoa/extensions/unit_commitment/components/operating_reserves.py b/temoa/extensions/unit_commitment/components/operating_reserves.py new file mode 100644 index 000000000..0f8736cf7 --- /dev/null +++ b/temoa/extensions/unit_commitment/components/operating_reserves.py @@ -0,0 +1,539 @@ +""" +Operating reserve margins for the unit commitment extension. + +Each operating reserve product (``reserve_name``) applies to one region-group and +tech-group and requires that credited reserve in every time slice exceeds the +group's proxy demand (see :func:`temoa.components.reserves.reserve_margin_proxy_demand`) +by a margin. Reserve is credited from three sources, each weighted by a per-product, +per-technology credit: + + - current generation (``activity_credit``) + - headroom on online units (``online_credit``) + - offline unit commitment units that could start (``offline_credit``) + +Storage contributions must also be sustainable from the current state of charge +for the product's ``sustain_hours``. + +These products are registered by the unit_commitment extension, but technologies +need not themselves be subject to unit commitment: a non-UC technology is simply +treated as always fully online, so its online headroom is just unused installed +capacity. Exchange technologies' ``online_credit`` is constrained equal and opposite +across the pair's two directional entries (outgoing = -incoming; see +:func:`operating_reserve_online_exchange_symmetry_constraint`), so +:func:`operating_reserve_margin_constraint` only ever sums the incoming entry, which +is already correctly signed for either direction of reserve flow. +A process may contribute to several products at once; products are assumed not to +be called on simultaneously. +""" + +from __future__ import annotations + +from logging import getLogger +from typing import TYPE_CHECKING + +from pyomo.environ import quicksum, value + +from temoa.components import geography +from temoa.components.reserves import initialize_reserve_groups, reserve_margin_proxy_demand +from temoa.components.utils import get_available_output, get_variable_efficiency +from temoa.extensions.unit_commitment.components.commitment import _total_units + +if TYPE_CHECKING: + from pyomo.environ import Expression, NumericValue + + from temoa.extensions.unit_commitment.core.model import UnitCommitmentModel + from temoa.types import ExprLike + from temoa.types.core_types import ( + Period, + Region, + ReserveName, + Season, + Technology, + TimeOfDay, + Vintage, + ) + +logger = getLogger(__name__) + + +# ============================================================================ +# INITIALIZATION +# ============================================================================ + + +def initialize_operating_reserve_margins(model: UnitCommitmentModel) -> None: + initialize_reserve_groups( + model, + model.operating_reserve_margin, + model.operating_reserve_processes, + ) + for (orm, r_g, t_g, p), processes in model.operating_reserve_processes.items(): + if not any( + (orm, r, t) in model.operating_reserve_activity_credit + or (orm, r, t) in model.operating_reserve_online_credit + or (orm, r, t) in model.operating_reserve_offline_credit + for r, t, _v in processes + ): + logger.warning('No credits defined for reserve %s', (orm, r_g, t_g, p)) + + +def has_activity_credit( + model: UnitCommitmentModel, orm: ReserveName, r: Region, t: Technology +) -> bool: + return (orm, r, t) in model.operating_reserve_activity_credit + + +def has_online_credit( + model: UnitCommitmentModel, orm: ReserveName, r: Region, t: Technology +) -> bool: + return (orm, r, t) in model.operating_reserve_online_credit + + +def has_offline_credit( + model: UnitCommitmentModel, orm: ReserveName, r: Region, t: Technology +) -> bool: + # Only unit commitment techs have offline units + uc_tech = (r, t) in model.uc_unit_capacity + has_credit = (orm, r, t) in model.operating_reserve_offline_credit + return uc_tech and has_credit + + +def _sustain_hours( + model: UnitCommitmentModel, orm: ReserveName, r_g: Region, t_g: Technology +) -> float | NumericValue: + if (orm, r_g, t_g) not in model.operating_reserve_sustain_hours: + return 0.0 + return value(model.operating_reserve_sustain_hours[orm, r_g, t_g]) + + +# ============================================================================ +# PYOMO INDEX SET FUNCTIONS +# ============================================================================ + + +def operating_reserve_indices( + model: UnitCommitmentModel, +) -> set[tuple[ReserveName, Region, Technology, Period, Season, TimeOfDay]]: + return { + (orm, r_g, t_g, p, s, d) + for orm, r_g, t_g, p in model.operating_reserve_processes + for s in model.time_season + for d in model.time_of_day + } + + +def operating_reserve_online_indices( + model: UnitCommitmentModel, +) -> set[tuple[ReserveName, Region, Period, Season, TimeOfDay, Technology, Vintage]]: + return { + (orm, r, p, s, d, t, v) + for (orm, _r_g, _t_g, p), processes in model.operating_reserve_processes.items() + for r, t, v in processes + if has_online_credit(model, orm, r, t) + for s in model.time_season + for d in model.time_of_day + } + + +def operating_reserve_storage_indices( + model: UnitCommitmentModel, +) -> set[ + tuple[ReserveName, Region, Technology, Region, Period, Season, TimeOfDay, Technology, Vintage] +]: + return { + (orm, r_g, t_g, r, p, s, d, t, v) + for (orm, r_g, t_g, p), processes in model.operating_reserve_processes.items() + if _sustain_hours(model, orm, r_g, t_g) > 0 + for r, t, v in processes + if t in model.tech_storage + if ( + has_activity_credit(model, orm, r, t) + or has_online_credit(model, orm, r, t) + or has_offline_credit(model, orm, r, t) + ) + for s in model.time_season + for d in model.time_of_day + } + + +def operating_reserve_online_exchange_indices( + model: UnitCommitmentModel, +) -> set[tuple[ReserveName, Region, Region, Period, Season, TimeOfDay, Technology, Vintage]]: + """One entry per credited exchange link (r_e < r_i), not per direction.""" + return { + (orm, r_e, r_i, p, s, d, t, v) + for orm, r, p, s, d, t, v in model.operating_reserve_online_nrpsdtv + if t in model.tech_exchange + for r_e, r_i in (r.split('-'),) + if (orm, r_i + '-' + r_e, p, s, d, t, v) in model.operating_reserve_online_nrpsdtv + if r_e < r_i + } + + +# ============================================================================ +# HELPER EXPRESSIONS +# ============================================================================ + + +def _process_activity( + model: UnitCommitmentModel, + r: Region, + p: Period, + s: Season, + d: TimeOfDay, + t: Technology, + v: Vintage, +) -> ExprLike: + """Output of a process in a time slice, including net of storage charging.""" + if t in model.tech_annual: + return quicksum( + ( + value(model.demand_specific_distribution[r, p, s, d, o]) + if o in model.commodity_demand + else value(model.segment_fraction[s, d]) + ) + * model.v_flow_out_annual[r, p, i, t, v, o] + for i in model.process_inputs[r, p, t, v] + for o in model.process_outputs_by_input[r, p, t, v, i] + ) + + activity = quicksum( + model.v_flow_out[r, p, s, d, i, t, v, o] + for i in model.process_inputs[r, p, t, v] + for o in model.process_outputs_by_input[r, p, t, v, i] + ) + if t in model.tech_storage: + activity -= quicksum( + model.v_flow_in[r, p, s, d, i, t, v, o] + for i in model.process_inputs[r, p, t, v] + for o in model.process_outputs_by_input[r, p, t, v, i] + ) + return activity + + +def offline_credit( + model: UnitCommitmentModel, + orm: ReserveName, + r: Region, + p: Period, + s: Season, + d: TimeOfDay, + t: Technology, + v: Vintage, +) -> Expression: + """Credited output available from offline unit commitment units. + + The credit is a fraction of installed capacity, so it should already account for + ``max_output_fraction``. + """ + capacity_factor = ( + value(model.capacity_factor_process[r, s, d, t, v]) + if model.is_capacity_factor_process[r, t, v] + else value(model.capacity_factor_tech[r, s, d, t]) + ) + offline_units = _total_units(model, r, p, t, v) - model.v_uc_online[r, p, s, d, t, v] + return ( + value(model.operating_reserve_offline_credit[orm, r, t]) + * value(model.capacity_to_activity[r, t]) + * value(model.segment_fraction[s, d]) + * value(model.uc_unit_capacity[r, t]) + * capacity_factor + * offline_units + ) + + +# ============================================================================ +# PYOMO CONSTRAINT RULES +# ============================================================================ + + +def operating_reserve_online_headroom_constraint( + model: UnitCommitmentModel, + orm: ReserveName, + r: Region, + p: Period, + s: Season, + d: TimeOfDay, + t: Technology, + v: Vintage, +) -> ExprLike: + r""" + Online headroom credit cannot exceed the unused available output of the process. + + .. math:: + :label: operating_reserve_online_headroom + + \mathbf{ORH}_{n,r,p,s,d,t,v} \le \mathbf{AVL}_{r,p,s,d,t,v} - \mathbf{ACT}_{r,p,s,d,t,v} + + where :math:`\mathbf{AVL}` is the available output (online units for unit commitment + technologies, installed capacity otherwise, with capacity factors applied) and + :math:`\mathbf{ACT}` is the process's output net of storage charging. + """ + activity = _process_activity(model, r, p, s, d, t, v) + return model.v_orm_online_credit[orm, r, p, s, d, t, v] + activity <= get_available_output( + model, r, p, s, d, t, v + ) + + +def operating_reserve_online_headroom_credit_constraint( + model: UnitCommitmentModel, + orm: ReserveName, + r: Region, + p: Period, + s: Season, + d: TimeOfDay, + t: Technology, + v: Vintage, +) -> ExprLike: + r""" + Online headroom credit cannot exceed the creditable fraction of online capacity. + + .. math:: + :label: operating_reserve_online_headroom_credit + + \mathbf{ORH}_{n,r,p,s,d,t,v} \le ONC_{n,t} \cdot C2A_{r,t} \cdot SEG_{s,d} \cdot + \begin{cases} + UC_{r,t} \cdot \mathbf{UCN}_{r,p,s,d,t,v} & (r,t) \in UC \\ + \mathbf{CAP}_{r,p,t,v} & \text{otherwise} + \end{cases} + """ + online_capacity = ( + value(model.uc_unit_capacity[r, t]) * model.v_uc_online[r, p, s, d, t, v] + if (r, t) in model.uc_unit_capacity + else model.v_capacity[r, p, t, v] + ) + max_credit = ( + value(model.operating_reserve_online_credit[orm, r, t]) + * value(model.capacity_to_activity[r, t]) + * value(model.segment_fraction[s, d]) + * online_capacity + ) + return model.v_orm_online_credit[orm, r, p, s, d, t, v] <= max_credit + + +def operating_reserve_online_exchange_symmetry_constraint( + model: UnitCommitmentModel, + orm: ReserveName, + r_e: Region, + r_i: Region, + p: Period, + s: Season, + d: TimeOfDay, + t: Technology, + v: Vintage, +) -> ExprLike: + r""" + An exchange link's online headroom is physically the same capacity regardless of + direction, so crediting it as incoming headroom on one side must be equivalent to + debiting it as outgoing headroom on the other: the two directional entries are + constrained to be exact negatives of one another. + + This lets :func:`operating_reserve_margin_constraint` add only the *incoming* + entry. Two things follow: + + - The sum is always the side bounded above by + :func:`operating_reserve_online_headroom_constraint` and + :func:`operating_reserve_online_headroom_credit_constraint`, rather than an + unconstrained negative, so there's no risk of the credit running away to + :math:`-\infty`. + - There's no double counting: if the model instead wants to export reserve out of + the group, the incoming entry simply goes negative (its magnitude still capped + by the outgoing side's own headroom constraints via this equality), correctly + reducing the group's credited reserve instead of being added a second time. + + .. math:: + :label: operating_reserve_online_exchange_symmetry + + \mathbf{ORH}_{n,r_e-r_i,p,s,d,t,v} = -\mathbf{ORH}_{n,r_i-r_e,p,s,d,t,v} + """ + return ( + model.v_orm_online_credit[orm, r_e + '-' + r_i, p, s, d, t, v] + == -model.v_orm_online_credit[orm, r_i + '-' + r_e, p, s, d, t, v] + ) + + +def operating_reserve_storage_energy_constraint( + model: UnitCommitmentModel, + orm: ReserveName, + r_g: Region, + t_g: Technology, + r: Region, + p: Period, + s: Season, + d: TimeOfDay, + t: Technology, + v: Vintage, +) -> ExprLike: + r""" + The reserve credited to a storage process, sustained for the product's + :code:`sustain_hours`, plus its net discharge in the time slice must be covered by + its state of charge at the start of the time slice. + + The same formulation works for seasonal storage because the non-sequential + :code:`v_storage_level` is the floor state of charge for all sequential seasons + built on the same non-sequential season. + + .. math:: + :label: operating_reserve_storage_energy + + \left( AC_{n,t} \cdot \mathbf{ACT}_{r,p,s,d,t,v} + \mathbf{ORH}_{n,r,p,s,d,t,v} + + \mathbf{OFF}_{n,r,p,s,d,t,v} \right) \cdot \frac{SH_{n,r_g,t_g}}{HRS_d} + + \sum_{I,O} \left( \mathbf{FO}_{r,p,s,d,i,t,v,o} - EFF \cdot \mathbf{FI}_{r,p,s,d,i,t,v,o} + \right) \le \mathbf{SL}_{r,p,s,d,t,v} + + where :math:`\mathbf{OFF}_{n,r,p,s,d,t,v}` is the offline unit credit term of + :eq:`operating_reserve_margin`. + """ + charge = quicksum( + model.v_flow_in[r, p, s, d, i, t, v, o] + * get_variable_efficiency(model, r, p, s, d, i, t, v, o) + for i in model.process_inputs[r, p, t, v] + for o in model.process_outputs_by_input[r, p, t, v, i] + ) + discharge = quicksum( + model.v_flow_out[r, p, s, d, i, t, v, o] + for i in model.process_inputs[r, p, t, v] + for o in model.process_outputs_by_input[r, p, t, v, i] + ) + + credit = 0.0 + if has_activity_credit(model, orm, r, t): + credit += value(model.operating_reserve_activity_credit[orm, r, t]) * _process_activity( + model, r, p, s, d, t, v + ) + if has_online_credit(model, orm, r, t): + credit += model.v_orm_online_credit[orm, r, p, s, d, t, v] + if has_offline_credit(model, orm, r, t): + credit += offline_credit(model, orm, r, p, s, d, t, v) + + sustained = credit * (_sustain_hours(model, orm, r_g, t_g) / value(model.time_of_day_hours[d])) + + return sustained + discharge - charge <= model.v_storage_level[r, p, s, d, t, v] + + +def operating_reserve_margin_constraint( + model: UnitCommitmentModel, + orm: ReserveName, + r_g: Region, + t_g: Technology, + p: Period, + s: Season, + d: TimeOfDay, +) -> ExprLike: + r""" + Credited reserve from processes in the product's region-group and tech-group must + exceed the group's proxy demand by the product's margin in every time slice. + + Reserve is credited from current generation, headroom on online units, and offline + unit commitment units that could start, each weighted by a per-product, per-technology + credit. **All credits default to 0**, so technologies in the tech group contribute to + the proxy demand but nothing to the reserve unless a credit is set. The tech group must + include all technologies feeding the demand, even those with zero credit. + + Technologies need not be subject to unit commitment: a non-UC technology is treated as + always fully online, so its online headroom is simply unused installed capacity, and it + is never eligible for offline credit. + + Exchange technologies' online headroom credit is constrained equal and opposite across the + link's two directional entries (outgoing = -incoming; see + :func:`operating_reserve_online_exchange_symmetry_constraint`), so only the entry incoming + to the group is summed below -- it is already correctly signed whether the link is + importing (positive) or exporting (negative) reserve. Offline credit has no such symmetry + constraint, so it's still credited for imports and debited for exports with an explicit + sign, as in :func:`~temoa.components.reserves._planning_reserve_margin_static`. + + .. note:: + Unlike the planning reserve margin, :math:`ORM` is the required reserve as a + fraction of proxy demand, not an excess above it (e.g. 0.1 requires reserve equal + to 10% of demand). + + .. math:: + :label: operating_reserve_margin + + \begin{aligned} + &\sum_{(r,t,v) \in \Theta^{res}} + AC_{n,t} \cdot \mathbf{ACT}_{r,p,s,d,t,v} + && \text{(current generation)} \\ + &+ \sum_{(r,t,v) \in \Theta^{res} \setminus T^x} + \mathbf{ORH}_{n,r,p,s,d,t,v} + && \text{(online headroom)} \\ + &+ \sum_{(r,t,v) \in \Theta^{res} \cap UC \setminus T^x} + \mathbf{OFF}_{n,r,p,s,d,t,v} + && \text{(offline units)} \\ + &+ \sum_{\substack{(r_1-r_2,t,v) \in \Theta^{res} \cap T^x \\ + r_2 \in r_g,\ r_1 \notin r_g}} + \mathbf{ORH}_{n,r_1-r_2,p,s,d,t,v} + && \text{(incoming exchange online headroom)} \\ + &+ \sum_{(r,t,v) \in \Theta^{res} \cap T^x} + \sigma_{r,r_g} \cdot \mathbf{OFF}_{n,r,p,s,d,t,v} + && \text{(net exchange offline)} \\ + &\geq D^{proxy}_{r_g,p,s,d} \cdot ORM_{n,r_g,t_g} \\ + &\forall \{n, r_g, t_g, p, s, d\} \in \Theta_{\text{OperatingReserveMargin}} + \end{aligned} + + where :math:`\sigma_{r,r_g} = +1` for an exchange process delivering into region-group + :math:`r_g` and :math:`-1` for one delivering out of it, the incoming-only online headroom + term already carries the correct sign for either direction by construction of + :eq:`operating_reserve_online_exchange_symmetry` (no separate :math:`\sigma` needed), + :math:`\Theta^{res} = + \Theta^{res}_{n,r_g,t_g,p}` is the set of processes + contributing to product :math:`{n,r_g,t_g}` in period :math:`p`, + :math:`D^{proxy}_{r_g,p,s,d}` is the product's proxy demand defined in + :eq:`reserve_margin_proxy_demand`, and + + .. math:: + + \mathbf{OFF}_{n,r,p,s,d,t,v} = OFC_{n,t} \cdot C2A_{r,t} \cdot SEG_{s,d} \cdot UC_{r,t} + \cdot CFP_{r,s,d,t,v} \cdot \left( \frac{\mathbf{CAP}_{r,p,t,v}}{UC_{r,t}} + - \mathbf{UCN}_{r,p,s,d,t,v} \right) + """ + processes = model.operating_reserve_processes[orm, r_g, t_g, p] + demand, activity_rtv = reserve_margin_proxy_demand(model, processes, r_g, p, s, d) + + # Activity credit reuses activity_rtv, which reserve_margin_proxy_demand already signs for + # exchange imports/exports; online and offline credit are not similarly signed, so they're + # computed separately for exchange processes below. + activity_credits = quicksum( + activity_rtv[r, t, v] * value(model.operating_reserve_activity_credit[orm, r, t]) + for r, t, v in processes + if has_activity_credit(model, orm, r, t) + ) + online_credits = quicksum( + model.v_orm_online_credit[orm, r, p, s, d, t, v] + for r, t, v in processes + if t not in model.tech_exchange + if has_online_credit(model, orm, r, t) + ) + offline_credits = quicksum( + offline_credit(model, orm, r, p, s, d, t, v) + for r, t, v in processes + if t not in model.tech_exchange + if has_offline_credit(model, orm, r, t) + ) + + # Credit exchange online/offline reserve for imports into the group, debit it for exports + regions = geography.gather_group_regions(model, r_g) + for r1r2, t, v in processes: + if t not in model.tech_exchange: + continue + + r1, r2 = r1r2.split('-') + if r2 in regions and r1 not in regions: + if has_online_credit(model, orm, r1r2, t): + # Online credits are signed-symmetric for imports/exports. We only want the + # incoming part because the outgoing part is just the same but sign-flipped + # (would just cancel out). + online_credits += model.v_orm_online_credit[orm, r1r2, p, s, d, t, v] + sign = 1 + elif r1 in regions and r2 not in regions: + sign = -1 + else: + continue + + if has_offline_credit(model, orm, r1r2, t): + offline_credits += sign * offline_credit(model, orm, r1r2, p, s, d, t, v) + + reserve = activity_credits + online_credits + offline_credits + + margin = value(model.operating_reserve_margin[orm, r_g, t_g]) + return reserve >= demand * margin diff --git a/temoa/extensions/unit_commitment/core/data_puller.py b/temoa/extensions/unit_commitment/core/data_puller.py index 4c9212733..120c2a7ac 100644 --- a/temoa/extensions/unit_commitment/core/data_puller.py +++ b/temoa/extensions/unit_commitment/core/data_puller.py @@ -8,18 +8,38 @@ from temoa._internal.exchange_tech_cost_ledger import CostType, ExchangeTechCostLedger from temoa.components import costs -from temoa.extensions.unit_commitment.components import startup +from temoa.components.reserves import reserve_margin_proxy_demand +from temoa.core.modes import TemoaMode +from temoa.extensions.unit_commitment.components import operating_reserves, startup from temoa.types.model_types import EI, FI, FlowType if TYPE_CHECKING: from temoa._internal.table_writer import TableWriter from temoa.core.model import TemoaModel from temoa.extensions.unit_commitment.core.model import UnitCommitmentModel - from temoa.types import Commodity, Period, Region, Season, Technology, TimeOfDay, Vintage + from temoa.types import ( + Commodity, + Period, + Region, + Season, + Technology, + TimeOfDay, + Vintage, + ) logger = logging.getLogger(__name__) +def _clear_scenario_rows(writer: TableWriter, table: str, scenario: str) -> None: + """Replace prior rows for this scenario, except in myopic runs where steps accumulate.""" + if writer.config.scenario_mode == TemoaMode.MYOPIC: + return + try: + writer.connection.execute(f'DELETE FROM {table} WHERE scenario == ?', (scenario,)) + except sqlite3.OperationalError: + pass + + class UCI(NamedTuple): """Unit Commitment Index""" @@ -80,17 +100,96 @@ def write_uc_results( 'units': unit_prop.get_capacity_units(uci.t) if unit_prop else None, } records.append(row) - try: - writer.connection.execute( - 'DELETE FROM output_unit_commitment WHERE scenario == ?', (scenario,) - ) - except sqlite3.OperationalError: - pass + _clear_scenario_rows(writer, 'output_unit_commitment', scenario) writer._bulk_insert('output_unit_commitment', records) writer.connection.commit() +class ORI(NamedTuple): + """Operating Reserve Index""" + + orm: str + r: Region + p: Period + s: Season + d: TimeOfDay + t: Technology + v: Vintage + + +def poll_operating_reserve_results( + model: UnitCommitmentModel, +) -> dict[ORI, tuple[float, float, float]]: + """ + Poll the generation, online headroom, and offline credits of each process toward + each operating reserve product in each time slice. + """ + + results: dict[ORI, tuple[float, float, float]] = {} + for orm, r_g, t_g, p, s, d in model.operating_reserve_nrtpsd: + name = f'{orm}_{r_g}_{t_g}' + processes = model.operating_reserve_processes[orm, r_g, t_g, p] + _, activity_rtv = reserve_margin_proxy_demand(model, processes, r_g, p, s, d) + for r, t, v in processes: + if t in model.tech_exchange: + continue + activity = ( + value(activity_rtv[r, t, v]) + * value(model.operating_reserve_activity_credit[orm, r, t]) + if operating_reserves.has_activity_credit(model, orm, r, t) + else 0.0 + ) + online = ( + value(model.v_orm_online_credit[orm, r, p, s, d, t, v]) + if operating_reserves.has_online_credit(model, orm, r, t) + else 0.0 + ) + offline = ( + value(operating_reserves.offline_credit(model, orm, r, p, s, d, t, v)) + if operating_reserves.has_offline_credit(model, orm, r, t) + else 0.0 + ) + results[ORI(name, r, p, s, d, t, v)] = (activity, online, offline) + return results + + +def write_operating_reserve_results( + model: TemoaModel, writer: TableWriter, iteration: int | None, epsilon: float = 1e-5 +) -> None: + if writer.tech_sectors is None: + raise RuntimeError('Missing tech_sectors') + model = cast('UnitCommitmentModel', model) + + results = poll_operating_reserve_results(model) + scenario = writer._get_scenario_name(iteration) + records = [] + + for ori, (activity, online, offline) in results.items(): + if all(abs(v) < epsilon for v in (activity, online, offline)): + continue + records.append( + { + 'scenario': scenario, + 'reserve': ori.orm, + 'region': ori.r, + 'sector': writer.tech_sectors.get(ori.t), + 'period': ori.p, + 'season': ori.s, + 'tod': ori.d, + 'tech': ori.t, + 'vintage': ori.v, + 'activity_credit': activity, + 'online_credit': online, + 'offline_credit': offline, + } + ) + _clear_scenario_rows(writer, 'output_operating_reserve', scenario) + + writer._bulk_insert('output_operating_reserve', records) + writer.connection.commit() + + def poll_startup_input_results( model: TemoaModel, res: dict[FI, dict[FlowType, float]], epsilon: float = 1e-5 ) -> None: diff --git a/temoa/extensions/unit_commitment/core/model.py b/temoa/extensions/unit_commitment/core/model.py index 4482152d1..bd5285eff 100644 --- a/temoa/extensions/unit_commitment/core/model.py +++ b/temoa/extensions/unit_commitment/core/model.py @@ -10,15 +10,17 @@ NonNegativeReals, Param, PositiveReals, + Reals, Set, Var, ) from temoa.components import operations -from temoa.extensions.unit_commitment.components import commitment, startup +from temoa.extensions.unit_commitment.components import commitment, operating_reserves, startup if TYPE_CHECKING: from temoa.core.model import TemoaModel + from temoa.types import ReserveProcessesDict from temoa.types.core_types import Season, TimeOfDay class UnitCommitmentModel(TemoaModel): @@ -26,6 +28,7 @@ class UnitCommitmentModel(TemoaModel): # --- Instantiation helpers --- uc_backslices: dict[tuple[Season, TimeOfDay, int], set[tuple[Season, TimeOfDay]]] + operating_reserve_processes: ReserveProcessesDict # --- UC process parameters (indexed by region, tech) --- uc_unit_capacity: Param @@ -40,22 +43,36 @@ class UnitCommitmentModel(TemoaModel): uc_startup_emissions: Param uc_startup_input: Param + # --- Operating reserve sets and parameters --- + operating_reserves: Set + operating_reserve_margin: Param + operating_reserve_sustain_hours: Param + operating_reserve_activity_credit: Param + operating_reserve_online_credit: Param + operating_reserve_offline_credit: Param + # --- Index sets --- uc_indices_rpsdtv: Set # all (r,p,s,d,t,v) subject to UC default_ramp_up_constraint_rpsdtv: Set default_ramp_down_constraint_rpsdtv: Set uc_ramp_up_constraint_rpsdtv: Set uc_ramp_down_constraint_rpsdtv: Set + operating_reserve_nrtpsd: Set + operating_reserve_online_nrpsdtv: Set + operating_reserve_storage_nrtrpsdtv: Set + operating_reserve_online_exchange_nrrpsdtv: Set # --- Build actions --- uc_initialise: BuildAction uc_apply_integer_domains: BuildAction uc_append_startup_costs: BuildAction + initialize_operating_reserves: BuildAction # --- Decision variables --- v_uc_online: Var v_uc_started: Var v_uc_stopped: Var + v_orm_online_credit: Var # --- Constraints --- uc_online_upper_constraint: Constraint @@ -67,6 +84,11 @@ class UnitCommitmentModel(TemoaModel): uc_min_down_time_constraint: Constraint uc_ramp_up_constraint: Constraint uc_ramp_down_constraint: Constraint + operating_reserve_margin_constraint: Constraint + operating_reserve_online_headroom_constraint: Constraint + operating_reserve_online_headroom_credit_constraint: Constraint + operating_reserve_storage_energy_constraint: Constraint + operating_reserve_online_exchange_symmetry_constraint: Constraint def register_early_components(model: TemoaModel) -> None: @@ -173,3 +195,72 @@ def register_model_components(model: TemoaModel) -> None: # Startup costs to objective function m.uc_append_startup_costs = BuildAction(rule=startup.append_startup_costs) + + _register_operating_reserves(m) + + +def _register_operating_reserves(m: UnitCommitmentModel) -> None: + """Attach operating reserve margin components.""" + m.operating_reserve_processes = {} + + m.operating_reserves = Set() + m.operating_reserve_margin = Param( + m.operating_reserves, + m.regional_global_indices, + m.tech_or_group, + domain=PositiveReals, + ) + m.operating_reserve_sustain_hours = Param( + m.operating_reserves, + m.regional_global_indices, + m.tech_or_group, + domain=NonNegativeReals, + ) + m.operating_reserve_activity_credit = Param( + m.operating_reserves, m.regional_indices, m.tech_all, domain=Reals + ) + m.operating_reserve_online_credit = Param( + m.operating_reserves, m.regional_indices, m.tech_with_capacity, domain=Reals + ) + m.operating_reserve_offline_credit = Param( + m.operating_reserves, m.regional_indices, m.tech_with_capacity, domain=Reals + ) + + m.initialize_operating_reserves = BuildAction( + rule=operating_reserves.initialize_operating_reserve_margins + ) + + m.operating_reserve_nrtpsd = Set( + dimen=6, initialize=operating_reserves.operating_reserve_indices + ) + m.operating_reserve_online_nrpsdtv = Set( + dimen=7, initialize=operating_reserves.operating_reserve_online_indices + ) + m.operating_reserve_storage_nrtrpsdtv = Set( + dimen=9, initialize=operating_reserves.operating_reserve_storage_indices + ) + m.operating_reserve_online_exchange_nrrpsdtv = Set( + dimen=8, initialize=operating_reserves.operating_reserve_online_exchange_indices + ) + + m.v_orm_online_credit = Var(m.operating_reserve_online_nrpsdtv, domain=Reals) + + m.operating_reserve_online_headroom_constraint = Constraint( + m.operating_reserve_online_nrpsdtv, + rule=operating_reserves.operating_reserve_online_headroom_constraint, + ) + m.operating_reserve_online_headroom_credit_constraint = Constraint( + m.operating_reserve_online_nrpsdtv, + rule=operating_reserves.operating_reserve_online_headroom_credit_constraint, + ) + m.operating_reserve_storage_energy_constraint = Constraint( + m.operating_reserve_storage_nrtrpsdtv, + rule=operating_reserves.operating_reserve_storage_energy_constraint, + ) + m.operating_reserve_online_exchange_symmetry_constraint = Constraint( + m.operating_reserve_online_exchange_nrrpsdtv, + rule=operating_reserves.operating_reserve_online_exchange_symmetry_constraint, + ) + m.operating_reserve_margin_constraint = Constraint( + m.operating_reserve_nrtpsd, rule=operating_reserves.operating_reserve_margin_constraint + ) diff --git a/temoa/extensions/unit_commitment/data_manifest.py b/temoa/extensions/unit_commitment/data_manifest.py index e4aafb624..86b8f0470 100644 --- a/temoa/extensions/unit_commitment/data_manifest.py +++ b/temoa/extensions/unit_commitment/data_manifest.py @@ -76,4 +76,61 @@ def build_manifest_items(model: TemoaModel) -> list[LoadItem]: validator_name='viable_rt', validation_map=(0, 2), ), + *_operating_reserve_items(m), + ] + + +def _operating_reserve_items(m: UnitCommitmentModel) -> list[LoadItem]: + margin: dict[str, Any] = { + 'table': 'operating_reserve_margin', + 'validator_name': 'viable_rt', + 'validation_map': (1, 2), + 'is_table_required': False, + 'is_period_filtered': False, + } + credit: dict[str, Any] = { + 'table': 'operating_reserve_credit', + 'validator_name': 'viable_rt', + 'validation_map': (1, 2), + 'is_table_required': False, + 'is_period_filtered': False, + } + return [ + LoadItem( + component=m.operating_reserves, + table='operating_reserve_margin', + columns=['reserve_name'], + is_table_required=False, + is_period_filtered=False, + ), + LoadItem( + component=m.operating_reserve_margin, + columns=['reserve_name', 'region', 'tech_or_group', 'margin'], + where_clause='margin IS NOT NULL and margin != 0', + **margin, + ), + LoadItem( + component=m.operating_reserve_sustain_hours, + columns=['reserve_name', 'region', 'tech_or_group', 'sustain_hours'], + where_clause='sustain_hours IS NOT NULL and sustain_hours != 0', + **margin, + ), + LoadItem( + component=m.operating_reserve_activity_credit, + columns=['reserve_name', 'region', 'tech', 'activity_credit'], + where_clause='activity_credit IS NOT NULL and activity_credit != 0', + **credit, + ), + LoadItem( + component=m.operating_reserve_online_credit, + columns=['reserve_name', 'region', 'tech', 'online_credit'], + where_clause='online_credit IS NOT NULL and online_credit != 0', + **credit, + ), + LoadItem( + component=m.operating_reserve_offline_credit, + columns=['reserve_name', 'region', 'tech', 'offline_credit'], + where_clause='offline_credit IS NOT NULL and offline_credit != 0', + **credit, + ), ] diff --git a/temoa/extensions/unit_commitment/extension.py b/temoa/extensions/unit_commitment/extension.py index 27e2c7e7b..0688e2250 100644 --- a/temoa/extensions/unit_commitment/extension.py +++ b/temoa/extensions/unit_commitment/extension.py @@ -13,9 +13,13 @@ 'unit_commitment_startup_cost', 'unit_commitment_startup_emissions', 'unit_commitment_startup_input', + 'operating_reserve_margin', + 'operating_reserve_credit', 'output_unit_commitment', + 'output_operating_reserve', ), - regional_group_tables={}, + output_tables=('output_unit_commitment', 'output_operating_reserve'), + regional_group_tables={'operating_reserve_margin': 'region'}, register_model_components=register_model_components, build_manifest_items=build_manifest_items, schema_sql_path=str(Path(__file__).parent / 'tables.sql'), diff --git a/temoa/extensions/unit_commitment/tables.sql b/temoa/extensions/unit_commitment/tables.sql index f6d9f3694..a9ae2b037 100644 --- a/temoa/extensions/unit_commitment/tables.sql +++ b/temoa/extensions/unit_commitment/tables.sql @@ -51,6 +51,30 @@ CREATE TABLE IF NOT EXISTS unit_commitment_startup_input CHECK (input_per_cap > 0), PRIMARY KEY (region, input_comm, tech) ); +CREATE TABLE IF NOT EXISTS operating_reserve_margin +( + reserve_name TEXT, + region TEXT, + tech_or_group TEXT, + margin REAL, + sustain_hours REAL, + notes TEXT, + PRIMARY KEY (reserve_name, region, tech_or_group), + CHECK (margin > 0), + CHECK (sustain_hours >= 0) +); +CREATE TABLE IF NOT EXISTS operating_reserve_credit +( + reserve_name TEXT, + region TEXT, + tech TEXT + REFERENCES technology (tech), + activity_credit REAL, + online_credit REAL, + offline_credit REAL, + notes TEXT, + PRIMARY KEY (reserve_name, region, tech) +); CREATE TABLE IF NOT EXISTS output_unit_commitment ( scenario TEXT, @@ -73,3 +97,25 @@ CREATE TABLE IF NOT EXISTS output_unit_commitment units TEXT, PRIMARY KEY (scenario, region, sector, period, season, tod, tech, vintage) ); +CREATE TABLE IF NOT EXISTS output_operating_reserve +( + scenario TEXT, + reserve 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), + tech TEXT + REFERENCES technology (tech), + vintage INTEGER + REFERENCES time_period (period), + activity_credit REAL, + online_credit REAL, + offline_credit REAL, + PRIMARY KEY (scenario, reserve, region, sector, period, season, tod, tech, vintage) +); diff --git a/temoa/model_checking/validators.py b/temoa/model_checking/validators.py index 4db893b28..e84b524ce 100644 --- a/temoa/model_checking/validators.py +++ b/temoa/model_checking/validators.py @@ -39,7 +39,6 @@ 'validate_0to1', 'validate_efficiency', 'validate_linked_tech', - 'validate_reserve_margin', 'validate_tech_sets', ] @@ -337,17 +336,6 @@ def validate_efficiency( return False -def validate_reserve_margin(model: TemoaModel) -> None: - for r in model.planning_reserve_margin.sparse_keys(): - if all((r, p) not in model.process_reserve_periods for p in model.time_optimize): - logger.warning( - 'Planning reserve margin provided but there are no reserve technologies serving ' - 'this ' - 'region: %s', - (r, model.planning_reserve_margin[r]), - ) - - def validate_tech_sets(model: TemoaModel) -> None: """ Check tech sets for any forbidden intersections @@ -361,7 +349,6 @@ def validate_tech_sets(model: TemoaModel) -> None: check_no_intersection(model.tech_annual, model.tech_curtailment), check_no_intersection(model.tech_curtailment, model.tech_flex), check_no_intersection(model.tech_all, model.tech_group_names), - check_no_intersection(model.tech_uncap, model.tech_reserve), ) ): raise ValueError('Technology sets failed to validate. Check log file for details.') diff --git a/temoa/tutorial_assets/config_sample.toml b/temoa/tutorial_assets/config_sample.toml index b262cf598..e87910bf2 100644 --- a/temoa/tutorial_assets/config_sample.toml +++ b/temoa/tutorial_assets/config_sample.toml @@ -143,19 +143,6 @@ time_sequencing = 'seasonal_timeslices' # E.g. 365 if all seasons collectively represent a year, 7 if modelling a single representative week. days_per_period = 365 -# How contributions to the planning reserve margin are calculated -# Options: -# 'static' -# Traditional planning reserve formulation. Contributions are independent of hourly availability: -# capacity value = net capacity * capacity credit -# 'dynamic' -# Contributions are available output including a capacity derate factor (e.g., forced outage rate). -# For most generators, contributions are available (derated) output in each time slice: -# capacity value = net capacity * reserve capacity derate * capacity factor -# For storage, contributions are (derated) actual output in each time slice: -# capacity value = flow out * reserve capacity derate -reserve_margin = 'dynamic' - # ------------------------------------ # SQLITE PERFORMANCE TUNING # ------------------------------------ diff --git a/temoa/tutorial_assets/utopia.sql b/temoa/tutorial_assets/utopia.sql index 1814f34f9..8117d2c40 100644 --- a/temoa/tutorial_assets/utopia.sql +++ b/temoa/tutorial_assets/utopia.sql @@ -415,25 +415,25 @@ 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 "technology" VALUES('IMPDSL1','p','supply','petroleum','',1,0,0,0,0,0,0,' imported diesel'); +REPLACE INTO "technology" VALUES('IMPGSL1','p','supply','petroleum','',1,0,0,0,0,0,0,' imported gasoline'); +REPLACE INTO "technology" VALUES('IMPHCO1','p','supply','coal','',1,0,0,0,0,0,0,' imported coal'); +REPLACE INTO "technology" VALUES('IMPOIL1','p','supply','petroleum','',1,0,0,0,0,0,0,' imported crude oil'); +REPLACE INTO "technology" VALUES('IMPURN1','p','supply','nuclear','',1,0,0,0,0,0,0,' imported uranium'); +REPLACE INTO "technology" VALUES('IMPFEQ','p','supply','petroleum','',1,0,0,0,0,0,0,' imported fossil equivalent'); +REPLACE INTO "technology" VALUES('IMPHYD','p','supply','hydro','',1,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,' coal power plant'); +REPLACE INTO "technology" VALUES('E21','pb','electric','nuclear','',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,' hydro power'); +REPLACE INTO "technology" VALUES('E51','ps','electric','electric','',0,0,0,0,0,0,0,' electric storage'); +REPLACE INTO "technology" VALUES('E70','p','electric','petroleum','',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,' electric residential heating'); +REPLACE INTO "technology" VALUES('RHO','p','residential','petroleum','',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,' residential lighting'); +REPLACE INTO "technology" VALUES('SRE','p','supply','petroleum','',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,' diesel powered vehicles'); +REPLACE INTO "technology" VALUES('TXE','p','transport','electric','',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,' 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'); diff --git a/temoa/types/__init__.py b/temoa/types/__init__.py index 78d4a98ac..77cb42544 100644 --- a/temoa/types/__init__.py +++ b/temoa/types/__init__.py @@ -10,6 +10,8 @@ 'Period', 'Region', 'RegionSet', + 'ReserveMarginType', + 'ReserveName', 'Season', 'SparseIndex', 'Technology', @@ -37,8 +39,7 @@ 'ProcessOutputsByInputDict', 'ProcessOutputsDict', 'ProcessPeriodsDict', - 'ProcessReservePeriodsDict', - 'ProcessTechsDict', + 'ReserveProcessesDict', 'ProcessVintagesDict', 'GroupBuiltProcessesDict', 'GroupActiveProcessesDict', @@ -84,6 +85,8 @@ Period, Region, RegionSet, + ReserveMarginType, + ReserveName, Season, Sector, SparseIndex, @@ -117,11 +120,10 @@ ProcessOutputsByInputDict, ProcessOutputsDict, ProcessPeriodsDict, - ProcessReservePeriodsDict, - ProcessTechsDict, ProcessVintagesDict, RampDownVintagesDict, RampUpVintagesDict, + ReserveProcessesDict, RetirementPeriodsDict, RetirementProductionProcessesDict, SeasonalStorageDict, diff --git a/temoa/types/core_types.py b/temoa/types/core_types.py index bfb91037f..9749b46c4 100644 --- a/temoa/types/core_types.py +++ b/temoa/types/core_types.py @@ -7,6 +7,7 @@ from collections.abc import Callable from dataclasses import dataclass, field +from enum import StrEnum from typing import Any, NewType # Core type aliases for commonly used dimensions @@ -19,6 +20,15 @@ TimeOfDay = NewType('TimeOfDay', str) Commodity = NewType('Commodity', str) Process = NewType('Process', str) +ReserveName = NewType('ReserveName', str) + + +class ReserveMarginType(StrEnum): + """Formulation variant for a planning reserve margin row.""" + + STATIC = 'static' + DYNAMIC = 'dynamic' + # Type aliases for common data structures SparseIndex = ( diff --git a/temoa/types/dict_types.py b/temoa/types/dict_types.py index 380e4f772..b19b24bac 100644 --- a/temoa/types/dict_types.py +++ b/temoa/types/dict_types.py @@ -5,7 +5,16 @@ the Temoa model for various data structures and mappings. """ -from .core_types import Commodity, Period, Region, Season, Technology, TimeOfDay, Vintage +from .core_types import ( + Commodity, + Period, + Region, + ReserveName, + Season, + Technology, + TimeOfDay, + Vintage, +) # Process-related dictionary types ProcessInputsDict = dict[tuple[Region, Period, Technology, Vintage], set[Commodity]] @@ -17,8 +26,9 @@ ProcessOutputsByInputDict = dict[ tuple[Region, Period, Technology, Vintage, Commodity], set[Commodity] ] -ProcessTechsDict = dict[tuple[Region, Period, Commodity], set[Technology]] -ProcessReservePeriodsDict = dict[tuple[Region, Period], set[tuple[Technology, Vintage]]] +ReserveProcessesDict = dict[ + tuple[ReserveName, Region, Technology, Period], set[tuple[Region, Technology, Vintage]] +] ProcessPeriodsDict = dict[tuple[Region, Technology, Vintage], set[Period]] RetirementPeriodsDict = dict[tuple[Region, Technology, Vintage], set[Period]] ProcessVintagesDict = dict[tuple[Region, Period, Technology], set[Vintage]] diff --git a/temoa/types/model_types.py b/temoa/types/model_types.py index 108a70f62..491ebb249 100644 --- a/temoa/types/model_types.py +++ b/temoa/types/model_types.py @@ -105,7 +105,6 @@ class TemoaModelProtocol(Protocol): tech_all: Set tech_production: Set tech_storage: Set - tech_reserve: Set tech_exchange: Set # Commodity sets @@ -176,7 +175,6 @@ class TemoaModel(AbstractModel): tech_baseload: Set tech_annual: Set tech_storage: Set - tech_reserve: Set tech_exchange: Set tech_uncap: Set tech_with_capacity: Set diff --git a/temoa/utilities/migrate_v4_to_v4_1.py b/temoa/utilities/migrate_v4_to_v4_1.py new file mode 100644 index 000000000..6142b1d1c --- /dev/null +++ b/temoa/utilities/migrate_v4_to_v4_1.py @@ -0,0 +1,339 @@ +#!/usr/bin/env python3 +""" +migrate_v4_to_v4_1.py + +Migrates a Temoa v4 database (SQLite or SQL dump) to v4.1 schema format. + +Key changes from v4 to v4.1: + - planning_reserve_margin -> planning_reserve_margin (reserve_name = region; + tech_or_group from reserve-flagged techs) + - capacity_credit, + reserve_capacity_derate -> planning_reserve_credit (keyed by reserve_name and tech; + AVG credit/factor over period, season, vintage and the + reserve's regions) + - rps_requirement -> limit_activity_share (tech_group=sub_group, reserve=super_group) + - DB_MINOR bumped: 0 -> 1 +""" + +from __future__ import annotations + +import argparse +import os +import sqlite3 +import tempfile +from pathlib import Path + + +def get_table_cols(conn: sqlite3.Connection, table: str) -> list[str]: + return [r[1] for r in conn.execute(f'PRAGMA table_info({table})').fetchall()] + + +def _migrate_planning_reserve_credit( + con_old: sqlite3.Connection, con_new: sqlite3.Connection, reserve_names: list[str] +) -> int: + """Migrate capacity_credit and reserve_capacity_derate -> planning_reserve_credit. + + A credit row applies to a reserve if its region is one of the reserve's regions or + an exchange pair with exactly one endpoint among them. Both sources are averaged + together per (reserve_name, region, tech), since planning_reserve_credit has no + period or season dimension. + """ + rows: list[tuple[str, str, float]] = [] + try: + rows += con_old.execute('SELECT region, tech, credit FROM capacity_credit').fetchall() + except sqlite3.OperationalError: + pass + try: + rows += con_old.execute( + 'SELECT region, tech, factor FROM reserve_capacity_derate' + ).fetchall() + except sqlite3.OperationalError: + pass + if not rows: + return 0 + if not reserve_names: + print( + f'WARNING: Dropping {len(rows)} row(s) from capacity_credit/reserve_capacity_derate; ' + 'no planning reserve was migrated to attach them to. Populate ' + 'planning_reserve_credit manually.' + ) + return 0 + print( + 'WARNING: planning_reserve_credit is now keyed by (reserve_name, region, tech); using ' + 'the average capacity_credit/reserve_capacity_derate value over period, season, and ' + 'vintage for each reserve/region/tech' + ) + + migrated: list[tuple[str, str, str, float]] = [] + for name in reserve_names: + regions = set(name.split('+')) + credits: dict[tuple[str, str], list[float]] = {} + for region, tech, credit in rows: + ends = region.split('-') + in_reserve = ( + region in regions + if len(ends) == 1 + else (ends[0] in regions) != (ends[1] in regions) + ) + if in_reserve: + credits.setdefault((region, tech), []).append(credit) + migrated.extend( + (name, region, tech, sum(c) / len(c)) for (region, tech), c in credits.items() + ) + + con_new.executemany( + 'INSERT OR REPLACE INTO planning_reserve_credit (reserve_name, region, tech, credit) ' + 'VALUES (?, ?, ?, ?)', + migrated, + ) + print(f'Migrated {len(migrated)} rows: capacity_credit -> planning_reserve_credit') + return len(migrated) + + +RESERVE_GROUP_NAME = 'migrated_reserve_techs' + + +def _build_reserve_tech_group( + con_old: sqlite3.Connection, con_new: sqlite3.Connection +) -> list[str]: + """Create a tech_group from techs with reserve=1; return the list of reserve tech names.""" + try: + reserve_techs = [ + r[0] + for r in con_old.execute('SELECT tech FROM technology WHERE reserve > 0').fetchall() + ] + except sqlite3.OperationalError: + return [] + if not reserve_techs: + return [] + con_new.execute( + 'INSERT OR IGNORE INTO tech_group (group_name) VALUES (?)', (RESERVE_GROUP_NAME,) + ) + con_new.executemany( + 'INSERT OR IGNORE INTO tech_group_member (group_name, tech) VALUES (?, ?)', + [(RESERVE_GROUP_NAME, t) for t in reserve_techs], + ) + print(f'Built reserve tech group "{RESERVE_GROUP_NAME}" with {len(reserve_techs)} member(s)') + return reserve_techs + + +def _migrate_planning_reserve_margin( + con_old: sqlite3.Connection, con_new: sqlite3.Connection, reserve_group_built: bool +) -> list[str]: + """Migrate planning_reserve_margin, naming each reserve after its region. + + Returns the migrated reserve names. + """ + try: + rows = con_old.execute( + 'SELECT region, margin, notes FROM planning_reserve_margin' + ).fetchall() + except sqlite3.OperationalError: + return [] + if not rows: + return [] + if not reserve_group_built: + print( + f'WARNING: planning_reserve_margin has {len(rows)} row(s) but no reserve-flagged ' + 'techs found; skipping migration. Populate planning_reserve_margin manually.' + ) + return [] + migrated = [ + (region, region, RESERVE_GROUP_NAME, margin, notes) for region, margin, notes in rows + ] + con_new.executemany( + 'INSERT OR REPLACE INTO planning_reserve_margin ' + '(reserve_name, region, tech_or_group, margin, notes) VALUES (?, ?, ?, ?, ?)', + migrated, + ) + print( + f'Migrated {len(migrated)} rows: planning_reserve_margin' + f' (reserve_name=region, tech_or_group={RESERVE_GROUP_NAME!r})' + ) + return [row[0] for row in migrated] + + +def _migrate_rps_requirement( + con_old: sqlite3.Connection, con_new: sqlite3.Connection, reserve_group_built: bool +) -> int: + """Migrate rps_requirement -> limit_activity_share. + + sub_group = tech_group (the RPS-eligible group) + super_group = RESERVE_GROUP_NAME (all reserve-flagged techs) + operator = 'ge' (must meet minimum share) + """ + try: + rows = con_old.execute( + 'SELECT region, period, tech_group, requirement, notes FROM rps_requirement' + ).fetchall() + except sqlite3.OperationalError: + return 0 + if not rows: + return 0 + if not reserve_group_built: + print( + 'WARNING: rps_requirement has rows but no reserve-flagged techs found to use as ' + 'super_group; skipping migration. Populate limit_activity_share manually.' + ) + return 0 + migrated = [ + (region, period, sub_group, RESERVE_GROUP_NAME, 'ge', requirement, notes) + for region, period, sub_group, requirement, notes in rows + ] + con_new.executemany( + 'INSERT OR REPLACE INTO limit_activity_share ' + '(region, period, sub_group, super_group, operator, share, notes) ' + 'VALUES (?, ?, ?, ?, ?, ?, ?)', + migrated, + ) + print(f'Migrated {len(migrated)} rows: rps_requirement -> limit_activity_share') + return len(migrated) + + +def _migrate_common_tables(con_old: sqlite3.Connection, con_new: sqlite3.Connection) -> int: + """Copy all tables that exist in both schemas, skipping custom-handled ones.""" + skip = { + 'capacity_credit', + 'reserve_capacity_derate', + 'rps_requirement', + 'planning_reserve_margin', + 'metadata', + 'operator', + 'commodity_type', + } + old_tables = { + r[0] + for r in con_old.execute("SELECT name FROM sqlite_master WHERE type='table'").fetchall() + } + new_tables = { + r[0] + for r in con_new.execute("SELECT name FROM sqlite_master WHERE type='table'").fetchall() + } + total = 0 + for table in sorted(old_tables & new_tables): + if table.startswith('sqlite_') or table in skip: + continue + old_cols = set(get_table_cols(con_old, table)) + new_cols = get_table_cols(con_new, table) + shared = [c for c in new_cols if c in old_cols] + if not shared: + continue + col_list = ', '.join(shared) + rows = con_old.execute(f'SELECT {col_list} FROM {table}').fetchall() + if not rows: + continue + placeholders = ', '.join(['?'] * len(shared)) + con_new.executemany( + f'INSERT OR REPLACE INTO {table} ({col_list}) VALUES ({placeholders})', rows + ) + print(f'Copied {len(rows)} rows: {table}') + total += len(rows) + return total + + +def execute_v4_to_v4_1_migration(con_old: sqlite3.Connection, con_new: sqlite3.Connection) -> None: + """Run all v4 -> v4.1 migration steps.""" + total = 0 + print('--- Migrating common tables ---') + total += _migrate_common_tables(con_old, con_new) + + print('--- Migrating restructured tables ---') + reserve_techs = _build_reserve_tech_group(con_old, con_new) + reserve_group_built = len(reserve_techs) > 0 + reserve_names = _migrate_planning_reserve_margin(con_old, con_new, reserve_group_built) + total += len(reserve_names) + total += _migrate_planning_reserve_credit(con_old, con_new, reserve_names) + total += _migrate_rps_requirement(con_old, con_new, reserve_group_built) + + con_new.execute("INSERT OR REPLACE INTO metadata VALUES ('DB_MAJOR', 4, 'DB major version')") + con_new.execute("INSERT OR REPLACE INTO metadata VALUES ('DB_MINOR', 1, 'DB minor version')") + print(f'Total rows successfully copied: {total}') + + +def migrate_database(source_path: Path, schema_path: Path, output_path: Path) -> None: + if not source_path.is_file(): + raise FileNotFoundError(f'Input database not found: {source_path}') + if not schema_path.is_file(): + raise FileNotFoundError(f'Schema file not found: {schema_path}') + + fd, temp_str = tempfile.mkstemp( + suffix='.sqlite', prefix='temp_v4_1_migration_', dir=output_path.parent + ) + os.close(fd) + temp_path = Path(temp_str) + + con_old = sqlite3.connect(source_path) + con_new = sqlite3.connect(temp_path) + try: + con_new.executescript(schema_path.read_text(encoding='utf-8')) + con_new.execute('PRAGMA foreign_keys = 0;') + execute_v4_to_v4_1_migration(con_old, con_new) + con_new.commit() + con_new.execute('PRAGMA foreign_keys = 1;') + con_old.close() + con_new.close() + os.replace(temp_path, output_path) + except Exception: + if temp_path.exists(): + os.remove(temp_path) + raise + finally: + con_old.close() + con_new.close() + + +def migrate_sql_dump(source_path: Path, schema_path: Path, output_path: Path) -> None: + if not source_path.is_file(): + raise FileNotFoundError(f'Input SQL dump not found: {source_path}') + if not schema_path.is_file(): + raise FileNotFoundError(f'Schema file not found: {schema_path}') + + con_old = sqlite3.connect(':memory:') + con_new = sqlite3.connect(':memory:') + temp_path: Path | None = None + + try: + con_old.executescript(source_path.read_text(encoding='utf-8')) + con_new.executescript(schema_path.read_text(encoding='utf-8')) + + con_new.execute('PRAGMA foreign_keys = 0;') + execute_v4_to_v4_1_migration(con_old, con_new) + con_new.commit() + con_new.execute('PRAGMA foreign_keys = 1;') + + fd, temp_str = tempfile.mkstemp( + suffix='.sql', prefix='temp_v4_1_sql_', dir=output_path.parent + ) + temp_path = Path(temp_str) + with os.fdopen(fd, 'w', encoding='utf-8') as f: + for line in con_new.iterdump(): + f.write(line + '\n') + f.flush() + os.fsync(f.fileno()) + os.replace(temp_path, output_path) + except Exception: + if temp_path is not None and temp_path.exists(): + os.remove(temp_path) + raise + finally: + con_old.close() + con_new.close() + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Migrate Temoa database from v4 to v4.1') + parser.add_argument('--input', '-i', required=True, help='Input DB or SQL file') + parser.add_argument('--schema', '-s', required=True, help='Path to v4.1 schema SQL') + parser.add_argument('--output', '-o', required=True, help='Output DB or SQL file') + parser.add_argument('--type', choices=['db', 'sql'], required=True, help='Migration type') + args = parser.parse_args() + + input_path = Path(args.input) + schema_path = Path(args.schema) + output_path = Path(args.output) + + if args.type == 'db': + migrate_database(input_path, schema_path, output_path) + else: + migrate_sql_dump(input_path, schema_path, output_path) + print('Migration complete.') diff --git a/temoa/utilities/migration_chain.py b/temoa/utilities/migration_chain.py new file mode 100644 index 000000000..bc5b257de --- /dev/null +++ b/temoa/utilities/migration_chain.py @@ -0,0 +1,193 @@ +#!/usr/bin/env python3 +""" +migration_chain.py + +Version-aware migration to the current Temoa schema (v4.1). The source version is read +from its metadata and only the required steps are applied: + + v3.x -> v4.0 (master_migration) -> v4.1 (migrate_v4_to_v4_1) + v4.0 -> v4.1 (migrate_v4_to_v4_1) + v4.1 -> unchanged + +Intermediate databases are held in memory; the output is only written once every step succeeded. +""" + +from __future__ import annotations + +import argparse +import os +import sqlite3 +import tempfile +from pathlib import Path + +from temoa.__about__ import DB_MAJOR_VERSION, MIN_DB_MINOR_VERSION +from temoa.utilities.master_migration import execute_v3_to_v4_migration +from temoa.utilities.migrate_v4_to_v4_1 import execute_v4_to_v4_1_migration + +LATEST_VERSION = (DB_MAJOR_VERSION, MIN_DB_MINOR_VERSION) +# Historical v4.0 schema used as the intermediate target when migrating from v3 +V4_SCHEMA_NAME = 'temoa_schema_v4.sql' + + +def detect_version(con: sqlite3.Connection) -> tuple[int, int]: + """Return (major, minor) from the metadata table; databases without a version are v3.""" + + def _read(element: str) -> int | None: + try: + row = con.execute('SELECT value FROM metadata WHERE element = ?', (element,)).fetchone() + except sqlite3.OperationalError: + return None + return int(row[0]) if row else None + + major = _read('DB_MAJOR') + if major is None: + return 3, 0 + return major, _read('DB_MINOR') or 0 + + +def _new_db(schema_path: Path) -> sqlite3.Connection: + con = sqlite3.connect(':memory:') + con.executescript(schema_path.read_text(encoding='utf-8')) + con.execute('PRAGMA foreign_keys = 0;') + return con + + +def migrate_connection( + con_src: sqlite3.Connection, schema_path: Path, v4_schema_path: Path +) -> sqlite3.Connection: + """Migrate an open source database to v4.1, returning an in-memory result connection. + + If the source is already current, it is returned as-is. + """ + version = detect_version(con_src) + print(f'Detected source database version: {version[0]}.{version[1]}') + if version > LATEST_VERSION: + raise ValueError( + f'Source database version {version[0]}.{version[1]} is newer than the supported ' + f'{LATEST_VERSION[0]}.{LATEST_VERSION[1]}.' + ) + if version == LATEST_VERSION: + print('Database is already at the latest version; no migration needed.') + return con_src + + current = con_src + if version[0] < 4: + if not v4_schema_path.is_file(): + raise FileNotFoundError(f'v4.0 schema file not found: {v4_schema_path}') + print('=== Step: v3 -> v4.0 ===') + con_v4 = _new_db(v4_schema_path) + execute_v3_to_v4_migration(current, con_v4) + con_v4.commit() + current = con_v4 + + print('=== Step: v4.0 -> v4.1 ===') + con_v41 = _new_db(schema_path) + execute_v4_to_v4_1_migration(current, con_v41) + con_v41.commit() + if current is not con_src: + current.close() + return con_v41 + + +def _resolve_v4_schema(schema_path: Path, v4_schema_path: Path | None) -> Path: + return v4_schema_path if v4_schema_path is not None else schema_path.parent / V4_SCHEMA_NAME + + +def migrate_database( + source_path: Path, + schema_path: Path, + output_path: Path, + v4_schema_path: Path | None = None, +) -> None: + if not source_path.is_file(): + raise FileNotFoundError(f'Input database not found: {source_path}') + if not schema_path.is_file(): + raise FileNotFoundError(f'Schema file not found: {schema_path}') + + fd, temp_str = tempfile.mkstemp( + suffix='.sqlite', prefix='temp_migration_', dir=output_path.parent + ) + os.close(fd) + temp_path = Path(temp_str) + + con_src = sqlite3.connect(source_path) + con_out: sqlite3.Connection | None = None + try: + con_out = migrate_connection( + con_src, schema_path, _resolve_v4_schema(schema_path, v4_schema_path) + ) + con_dest = sqlite3.connect(temp_path) + try: + con_out.backup(con_dest) + con_dest.execute('VACUUM;') + finally: + con_dest.close() + con_src.close() + if con_out is not con_src: + con_out.close() + os.replace(temp_path, output_path) + except Exception: + con_src.close() + if con_out is not None: + con_out.close() + if temp_path.exists(): + os.remove(temp_path) + raise + + +def migrate_sql_dump( + source_path: Path, + schema_path: Path, + output_path: Path, + v4_schema_path: Path | None = None, +) -> None: + if not source_path.is_file(): + raise FileNotFoundError(f'Input SQL dump not found: {source_path}') + if not schema_path.is_file(): + raise FileNotFoundError(f'Schema file not found: {schema_path}') + + con_src = sqlite3.connect(':memory:') + con_out: sqlite3.Connection | None = None + temp_path: Path | None = None + try: + con_src.executescript(source_path.read_text(encoding='utf-8')) + con_out = migrate_connection( + con_src, schema_path, _resolve_v4_schema(schema_path, v4_schema_path) + ) + fd, temp_str = tempfile.mkstemp( + suffix='.sql', prefix='temp_sql_export_', dir=output_path.parent + ) + temp_path = Path(temp_str) + with os.fdopen(fd, 'w', encoding='utf-8') as f: + for line in con_out.iterdump(): + f.write(line + '\n') + f.flush() + os.fsync(f.fileno()) + os.replace(temp_path, output_path) + except Exception: + if temp_path is not None and temp_path.exists(): + os.remove(temp_path) + raise + finally: + con_src.close() + if con_out is not None and con_out is not con_src: + con_out.close() + + +if __name__ == '__main__': + parser = argparse.ArgumentParser(description='Migrate a Temoa database (v3 or v4) to v4.1') + parser.add_argument('--input', '-i', required=True, help='Input DB or SQL file') + parser.add_argument('--schema', '-s', required=True, help='Path to v4.1 schema SQL') + parser.add_argument( + '--v4-schema', + help=f'Path to v4.0 schema SQL (default: {V4_SCHEMA_NAME} next to --schema)', + ) + parser.add_argument('--output', '-o', required=True, help='Output DB or SQL file') + parser.add_argument('--type', choices=['db', 'sql'], required=True, help='Migration type') + args = parser.parse_args() + + v4_schema = Path(args.v4_schema) if args.v4_schema else None + if args.type == 'db': + migrate_database(Path(args.input), Path(args.schema), Path(args.output), v4_schema) + else: + migrate_sql_dump(Path(args.input), Path(args.schema), Path(args.output), v4_schema) diff --git a/tests/conftest.py b/tests/conftest.py index 7cb63eb9a..5e2588b03 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -7,6 +7,7 @@ from _pytest.config import Config from pyomo.opt import SolverResults +from temoa.__about__ import DB_SCHEMA from temoa._internal.temoa_sequencer import TemoaSequencer from temoa.core.config import TemoaConfig from temoa.core.model import TemoaModel @@ -37,7 +38,7 @@ # Central paths TEST_DATA_PATH = Path(__file__).parent / 'testing_data' TEST_OUTPUT_PATH = Path(__file__).parent / 'testing_outputs' -SCHEMA_PATH = Path(__file__).parent.parent / 'temoa' / 'db_schema' / 'temoa_schema_v4.sql' +SCHEMA_PATH = Path(__file__).parent.parent / 'temoa' / 'db_schema' / DB_SCHEMA def _build_test_db( @@ -101,6 +102,7 @@ def refresh_databases() -> None: # Feature tests (separate for temporal consistency) ('emissions.sql', 'emissions.sqlite'), ('materials.sql', 'materials.sqlite'), + ('reserve_margins.sql', 'reserve_margins.sqlite'), ('simple_linked_tech.sql', 'simple_linked_tech.sqlite'), ('storageville.sql', 'storageville.sqlite'), ('test_week.sql', 'test_week.sqlite'), diff --git a/tests/legacy_test_values.py b/tests/legacy_test_values.py index 3fb7d2e13..840a5e42f 100644 --- a/tests/legacy_test_values.py +++ b/tests/legacy_test_values.py @@ -29,7 +29,8 @@ class ExpectedVals(Enum): # increased 2025/08/19 after making annual demands optional # increased by 10 after removing period index from storagefrac (more constraints) # increased by 48 after tying v_storage_level[d_last] to v_storage_init - ExpectedVals.CONSTR_COUNT: 2868, + # decreased by 3 after removing redundant regional_exchange_capacity_constraints + ExpectedVals.CONSTR_COUNT: 2865, # reduced by 6 when reworking storageinit. # increased after making annualretirement derived var # reduced 2025/07/21 after removing existing vintage v_new_capacity indices @@ -77,7 +78,8 @@ class ExpectedVals(Enum): # increased by 2 after tying v_storage_level[d_last] to v_storage_init # reduced by 10 after dropping DAC for single-tech demands # reduced by 8 after disabling season ramp for seasonal_timeslices - ExpectedVals.CONSTR_COUNT: 224, + # decreased by 1 after removing redundant regional_exchange_capacity_constraints + ExpectedVals.CONSTR_COUNT: 223, # reduced 2025/07/25 by 18 after annualising demands # increased 2025/08/19 after making annual demands optional # increased by 2 after adding v_storage_init variable diff --git a/tests/test_migration_chain.py b/tests/test_migration_chain.py new file mode 100644 index 000000000..466e6ea1a --- /dev/null +++ b/tests/test_migration_chain.py @@ -0,0 +1,62 @@ +import contextlib +import sqlite3 +from pathlib import Path + +from temoa.utilities import migration_chain + +REPO_ROOT = Path(__file__).parents[1] +SCHEMA_DIR = REPO_ROOT / 'temoa' / 'db_schema' +SCHEMA_V4 = SCHEMA_DIR / 'temoa_schema_v4.sql' +SCHEMA_V4_1 = SCHEMA_DIR / 'temoa_schema_v4_1.sql' +MOCK_V3 = REPO_ROOT / 'tests' / 'testing_data' / 'migration_v3_mock.sql' +SCHEMA_V3 = SCHEMA_DIR / 'temoa_schema_v3.sql' + + +def _make_v3_db(path: Path) -> Path: + with contextlib.closing(sqlite3.connect(path)) as conn: + conn.execute('PRAGMA foreign_keys = OFF') + conn.executescript(SCHEMA_V3.read_text()) + conn.executescript(MOCK_V3.read_text()) + return path + + +MOCK_V4 = REPO_ROOT / 'tests' / 'testing_data' / 'migration_v4_mock.sql' + + +def _version(conn: sqlite3.Connection) -> tuple[int, int]: + return migration_chain.detect_version(conn) + + +def test_chain_v3_sql_to_v4_1(tmp_path: Path) -> None: + sql_src = tmp_path / 'v3.sql' + with contextlib.closing(sqlite3.connect(_make_v3_db(tmp_path / 'v3_src.sqlite'))) as conn: + sql_src.write_text('\n'.join(conn.iterdump())) + out = tmp_path / 'out.sql' + migration_chain.migrate_sql_dump(sql_src, SCHEMA_V4_1, out) + with contextlib.closing(sqlite3.connect(':memory:')) as conn: + conn.executescript(out.read_text()) + assert _version(conn) == (4, 1) + assert conn.execute('SELECT COUNT(*) FROM efficiency').fetchone()[0] > 0 + + +def test_chain_v3_db_to_v4_1(tmp_path: Path) -> None: + src = _make_v3_db(tmp_path / 'v3.sqlite') + out = tmp_path / 'out.sqlite' + migration_chain.migrate_database(src, SCHEMA_V4_1, out) + with contextlib.closing(sqlite3.connect(out)) as conn: + assert _version(conn) == (4, 1) + + +def test_chain_v4_db_to_v4_1_and_idempotent(tmp_path: Path) -> None: + src = tmp_path / 'v4.sqlite' + with contextlib.closing(sqlite3.connect(src)) as conn: + conn.execute('PRAGMA foreign_keys = OFF') + conn.executescript(SCHEMA_V4.read_text()) + conn.executescript(MOCK_V4.read_text()) + out = tmp_path / 'v4_1.sqlite' + migration_chain.migrate_database(src, SCHEMA_V4_1, out) + again = tmp_path / 'again.sqlite' + migration_chain.migrate_database(out, SCHEMA_V4_1, again) + for path in (out, again): + with contextlib.closing(sqlite3.connect(path)) as conn: + assert _version(conn) == (4, 1) diff --git a/tests/test_reserve_margins.py b/tests/test_reserve_margins.py new file mode 100644 index 000000000..2b986af12 --- /dev/null +++ b/tests/test_reserve_margins.py @@ -0,0 +1,184 @@ +from __future__ import annotations + +import contextlib +import logging +import sqlite3 +from pathlib import Path +from typing import TYPE_CHECKING, cast + +if TYPE_CHECKING: + from pyomo.core.base.constraint import ConstraintData + + from temoa.extensions.unit_commitment.core.model import UnitCommitmentModel + + type ReserveRun = tuple[UnitCommitmentModel, Path] + +import pytest + +from temoa._internal.temoa_sequencer import TemoaSequencer +from temoa.core.config import TemoaConfig +from temoa.core.modes import TemoaMode +from tests.utilities.compare_lp import LpDiff, compare_lp_files + +logger = logging.getLogger(__name__) + +TEST_CONFIG = Path(__file__).parent / 'testing_configs' / 'config_reserve_margins.toml' +CACHED_LP = Path(__file__).parent / 'testing_data' / 'reserve_margins.lp' + + +# --------------------------------------------------------------------------- +# Fixture +# --------------------------------------------------------------------------- + + +@pytest.fixture(scope='module') +def reserve_run(tmp_path_factory: pytest.TempPathFactory) -> ReserveRun: + """Build, solve, and return (model, lp_path) for the reserve_margins scenario.""" + tmp = tmp_path_factory.mktemp('reserve_margins') + config = TemoaConfig.build_config( + config_file=TEST_CONFIG, + output_path=tmp, + silent=True, + ) + config.save_lp_file = True + + seq = TemoaSequencer(config=config, mode_override=TemoaMode.BUILD_ONLY) + instance = seq.build_model() + + lp_files = list(tmp.glob('*.lp')) + assert lp_files, 'No LP file was written to the output directory' + return cast('UnitCommitmentModel', instance), lp_files[0] + + +def test_planning_ab_group_includes_exchange(reserve_run: ReserveRun) -> None: + model, _ = reserve_run + exchange_regions = { + r + for prm, r_g, t_g, p in model.planning_reserve_processes + if prm == 'cap_AB' + for r, _t, _v in model.planning_reserve_processes[prm, r_g, t_g, p] + if '-' in r + } + assert all(r in exchange_regions for r in ['A-C', 'C-A', 'B-C', 'C-B']), ( + 'Exchange regions A-C / C-A / B-C / C-B not auto-included in planning reserve group A+B' + ) + + +def test_single_region_a_includes_exchange(reserve_run: ReserveRun) -> None: + model, _ = reserve_run + exchange_regions = { + r + for orm, r_g, t_g, p in model.operating_reserve_processes + if orm == 'spin_A' + for r, _t, _v in model.operating_reserve_processes[orm, r_g, t_g, p] + if '-' in r + } + assert all(r in exchange_regions for r in ['A-C', 'C-A', 'B-A', 'A-B']), ( + 'Exchange regions A-C / C-A / B-A / A-B not auto-included in operating reserve group A' + ) + + +def test_stacked_planning_reserves(reserve_run: ReserveRun) -> None: + model, _ = reserve_run + con = model.planning_reserve_margin_constraint + stacked = [ + (r_g, t_g, p, s, d) + for prm, r_g, t_g, p, s, d in model.planning_reserve_nrtpsd + if prm == 'cap_A' + ] + assert stacked + for r_g, t_g, p, s, d in stacked: + base = cast('ConstraintData', con['cap_A', r_g, t_g, p, s, d]) + derate = cast('ConstraintData', con['cap_A_derate', r_g, t_g, p, s, d]) + assert str(base.body) != str(derate.body), 'Stacked reserves should use their own data' + + +def test_online_headroom_only_for_credited_non_exchange(reserve_run: ReserveRun) -> None: + model, _ = reserve_run + credited = {(orm, t) for orm, r, p, s, d, t, v in model.operating_reserve_online_nrpsdtv} + assert credited == { + ('spin_A', 'NGCC'), + ('spin_A', 'SOLPV'), + ('spin_A', 'E_BATT'), + ('spin_A', 'E_LDES'), + ('spin_A', 'E_TRANS'), + ('reg_B', 'NGCC'), + ('reg_B', 'E_BATT'), + ('reg_B', 'E_TRANS'), + ('spin_AB', 'NGCC'), + ('spin_AB', 'SOLPV'), + ('spin_AB', 'E_BATT'), + ('spin_AB', 'E_LDES'), + ('spin_AB', 'E_TRANS'), + }, 'Online headroom should be indexed for every tech (incl. exchange) with a nonzero credit' + + +def test_storage_energy_requires_sustain_hours(reserve_run: ReserveRun) -> None: + model, _ = reserve_run + products = { + (orm, t) for orm, r_g, t_g, r, p, s, d, t, v in model.operating_reserve_storage_nrtrpsdtv + } + assert products == { + ('spin_A', 'E_BATT'), + ('spin_A', 'E_LDES'), + ('spin_AB', 'E_BATT'), + ('spin_AB', 'E_LDES'), + } + + +def test_offline_credit_only_for_uc_techs(reserve_run: ReserveRun) -> None: + model, _ = reserve_run + for orm, r_g, t_g, p, s, d in model.operating_reserve_nrtpsd: + con = cast( + 'ConstraintData', model.operating_reserve_margin_constraint[orm, r_g, t_g, p, s, d] + ) + body = str(con.body) + assert ('v_uc_online' in body) == (orm == 'spin_AB'), ( + f'Offline UC credit should only appear in spin_AB, found mismatch in {orm}' + ) + + +def test_single_tech_region_a_not_includes_exchange(reserve_run: ReserveRun) -> None: + model, _ = reserve_run + exchange_regions = { + r + for prm, r_g, t_g, p in model.planning_reserve_processes + if prm == 'cap_A' + for r, t, v in model.planning_reserve_processes[prm, r_g, t_g, p] + if '-' in r + } + assert not exchange_regions, ( + 'Single-region planning margin on A should ' + f'not include exchange regions: {exchange_regions}' + ) + + +def test_lp_matches(reserve_run: ReserveRun) -> None: + _, lp_path = reserve_run + + if not CACHED_LP.exists(): + import shutil + + shutil.copy(lp_path, CACHED_LP) + pytest.skip( + f'No cached LP found — saved current output as new cache: {CACHED_LP}. ' + 'Re-run the test to validate against it.' + ) + + diff: LpDiff = compare_lp_files(CACHED_LP, lp_path) + assert diff.is_identical, f'LP file differs from cached ({CACHED_LP.name}):\n{diff.summary()}' + + +def test_output_operating_reserve(tmp_path: Path) -> None: + config = TemoaConfig.build_config(config_file=TEST_CONFIG, output_path=tmp_path, silent=True) + TemoaSequencer(config=config).start() + + with contextlib.closing(sqlite3.connect(config.output_database)) as con: + products = { + row[0] + for row in con.execute( + 'SELECT reserve FROM output_operating_reserve WHERE scenario = ?', + (config.scenario,), + ) + } + assert products == {'spin_A_A_elec_A', 'reg_B_B_elec_B', 'spin_AB_A+B_elec_AB'} diff --git a/tests/test_v4_1_migration.py b/tests/test_v4_1_migration.py new file mode 100644 index 000000000..d651796b5 --- /dev/null +++ b/tests/test_v4_1_migration.py @@ -0,0 +1,181 @@ +import contextlib +import sqlite3 +import subprocess +import sys +from pathlib import Path + +import pytest + +from temoa.utilities.migrate_v4_to_v4_1 import migrate_database, migrate_sql_dump + +REPO_ROOT = Path(__file__).parents[1] +UTILITIES_DIR = REPO_ROOT / 'temoa' / 'utilities' +SCHEMA_V4 = REPO_ROOT / 'temoa' / 'db_schema' / 'temoa_schema_v4.sql' +SCHEMA_V4_1 = REPO_ROOT / 'temoa' / 'db_schema' / 'temoa_schema_v4_1.sql' +MOCK_DATA_V4 = REPO_ROOT / 'tests' / 'testing_data' / 'migration_v4_mock.sql' +MIGRATION_SCRIPT = UTILITIES_DIR / 'migrate_v4_to_v4_1.py' + + +def _make_v4_db(tmp_path: Path) -> Path: + """Create a v4 SQLite database populated with mock data.""" + db = tmp_path / 'test_v4.sqlite' + with contextlib.closing(sqlite3.connect(db)) as conn: + conn.execute('PRAGMA foreign_keys = OFF') + conn.executescript(SCHEMA_V4.read_text()) + conn.executescript(MOCK_DATA_V4.read_text()) + conn.execute('PRAGMA foreign_keys = ON') + return db + + +def _verify_migrated_db(conn: sqlite3.Connection) -> None: + # Metadata version updated + major = conn.execute("SELECT value FROM metadata WHERE element='DB_MAJOR'").fetchone()[0] + minor = conn.execute("SELECT value FROM metadata WHERE element='DB_MINOR'").fetchone()[0] + assert major == 4 + assert minor == 1 + + # planning_reserve_credit: capacity_credit and reserve_capacity_derate averaged together + # per (reserve_name, tech) + credits = { + (r[0], r[1]): r[2] + for r in conn.execute( + 'SELECT reserve_name, tech, credit FROM planning_reserve_credit' + ).fetchall() + } + # GasTurbine: capacity_credit 0.85 (2030), 0.80 (2040); reserve_capacity_derate 0.95 (summer) + # -> AVG = (0.85 + 0.80 + 0.95) / 3 + assert ('R1', 'GasTurbine') in credits + assert credits[('R1', 'GasTurbine')] == pytest.approx((0.85 + 0.80 + 0.95) / 3) + # WindFarm: capacity_credit 0.25; reserve_capacity_derate 0.20 (summer), 0.10 (winter) + # -> AVG = (0.25 + 0.20 + 0.10) / 3 + assert credits[('R1', 'WindFarm')] == pytest.approx((0.25 + 0.20 + 0.10) / 3) + + # Removed v4 tables must not be present + tables = { + r[0] for r in conn.execute("SELECT name FROM sqlite_master WHERE type='table'").fetchall() + } + assert 'capacity_credit' not in tables + assert 'reserve_capacity_derate' not in tables + assert 'operating_reserve_derate' not in tables + assert 'rps_requirement' not in tables + + # planning_reserve_margin: migrated using reserve tech group as tech_or_group + from temoa.utilities.migrate_v4_to_v4_1 import RESERVE_GROUP_NAME + + margins = conn.execute( + 'SELECT reserve_name, region, tech_or_group, margin FROM planning_reserve_margin' + ).fetchall() + assert len(margins) == 1 + assert margins[0] == ('R1', 'R1', RESERVE_GROUP_NAME, pytest.approx(0.15)) + + # reserve tech group must exist with GasTurbine and WindFarm (reserve=1), not CoalPlant + members = { + r[0] + for r in conn.execute( + 'SELECT tech FROM tech_group_member WHERE group_name = ?', (RESERVE_GROUP_NAME,) + ).fetchall() + } + assert 'GasTurbine' in members + assert 'WindFarm' in members + assert 'CoalPlant' not in members + + # rps_requirement: migrated to limit_activity_share, one row per period + activity_shares = { + (r[0], r[1], r[2]): r[4] + for r in conn.execute( + 'SELECT region, period, sub_group, super_group, share FROM limit_activity_share' + ).fetchall() + } + assert ('R1', 2030, 'renewables') in activity_shares + assert activity_shares[('R1', 2030, 'renewables')] == pytest.approx(0.30) + assert activity_shares[('R1', 2040, 'renewables')] == pytest.approx(0.40) + + # Common table data preserved + efficiencies = conn.execute('SELECT region, tech, vintage FROM efficiency').fetchall() + assert len(efficiencies) == 3 + + +def test_v4_1_migration_db(tmp_path: Path) -> None: + """Test SQLite DB migration from v4 to v4.1.""" + db_v4 = _make_v4_db(tmp_path) + db_v4_1 = tmp_path / 'test_v4_1.sqlite' + + subprocess.run( + [ + sys.executable, + str(MIGRATION_SCRIPT), + '--type', + 'db', + '--input', + str(db_v4), + '--schema', + str(SCHEMA_V4_1), + '--output', + str(db_v4_1), + ], + check=True, + ) + + with contextlib.closing(sqlite3.connect(db_v4_1)) as conn: + _verify_migrated_db(conn) + + +def test_v4_1_migration_sql(tmp_path: Path) -> None: + """Test SQL dump migration from v4 to v4.1.""" + db_v4 = _make_v4_db(tmp_path) + + sql_v4 = tmp_path / 'test_v4.sql' + with open(sql_v4, 'w') as f: + with contextlib.closing(sqlite3.connect(db_v4)) as conn: + for line in conn.iterdump(): + f.write(line + '\n') + + sql_v4_1 = tmp_path / 'test_v4_1.sql' + subprocess.run( + [ + sys.executable, + str(MIGRATION_SCRIPT), + '--type', + 'sql', + '--input', + str(sql_v4), + '--schema', + str(SCHEMA_V4_1), + '--output', + str(sql_v4_1), + ], + check=True, + ) + + with contextlib.closing(sqlite3.connect(':memory:')) as conn: + conn.executescript(sql_v4_1.read_text()) + _verify_migrated_db(conn) + + +def test_v4_1_migration_db_inthread(tmp_path: Path) -> None: + """In-process variant of test_v4_1_migration_db for coverage.""" + db_v4 = _make_v4_db(tmp_path) + db_v4_1 = tmp_path / 'test_v4_1.sqlite' + + migrate_database(db_v4, SCHEMA_V4_1, db_v4_1) + + with contextlib.closing(sqlite3.connect(db_v4_1)) as conn: + _verify_migrated_db(conn) + + +def test_v4_1_migration_sql_inthread(tmp_path: Path) -> None: + """In-process variant of test_v4_1_migration_sql for coverage.""" + db_v4 = _make_v4_db(tmp_path) + + sql_v4 = tmp_path / 'test_v4.sql' + with open(sql_v4, 'w') as f: + with contextlib.closing(sqlite3.connect(db_v4)) as conn: + for line in conn.iterdump(): + f.write(line + '\n') + + sql_v4_1 = tmp_path / 'test_v4_1.sql' + migrate_sql_dump(sql_v4, SCHEMA_V4_1, sql_v4_1) + + with contextlib.closing(sqlite3.connect(':memory:')) as conn: + conn.executescript(sql_v4_1.read_text()) + _verify_migrated_db(conn) diff --git a/tests/testing_configs/config_annualised_demand.toml b/tests/testing_configs/config_annualised_demand.toml index 198a7982f..847b1de38 100644 --- a/tests/testing_configs/config_annualised_demand.toml +++ b/tests/testing_configs/config_annualised_demand.toml @@ -9,7 +9,6 @@ save_duals = false save_lp_file = false time_sequencing = "representative_periods" days_per_period = 365 -reserve_margin = "static" [MGA] cost_epsilon = 0.03 diff --git a/tests/testing_configs/config_emissions.toml b/tests/testing_configs/config_emissions.toml index a3ec86a4b..b63e2c38a 100644 --- a/tests/testing_configs/config_emissions.toml +++ b/tests/testing_configs/config_emissions.toml @@ -9,7 +9,6 @@ save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" days_per_period = 365 -reserve_margin = "static" [MGA] slack = 0.1 diff --git a/tests/testing_configs/config_link_test.toml b/tests/testing_configs/config_link_test.toml index 88192e4f4..93356f666 100644 --- a/tests/testing_configs/config_link_test.toml +++ b/tests/testing_configs/config_link_test.toml @@ -12,7 +12,6 @@ save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" days_per_period = 365 -reserve_margin = "static" [MGA] slack = 0.1 diff --git a/tests/testing_configs/config_materials.toml b/tests/testing_configs/config_materials.toml index 3eae4926f..6567dd309 100644 --- a/tests/testing_configs/config_materials.toml +++ b/tests/testing_configs/config_materials.toml @@ -9,7 +9,6 @@ save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" days_per_period = 365 -reserve_margin = "static" [MGA] slack = 0.1 diff --git a/tests/testing_configs/config_mediumville.toml b/tests/testing_configs/config_mediumville.toml index 935abdbaa..e6d214edd 100644 --- a/tests/testing_configs/config_mediumville.toml +++ b/tests/testing_configs/config_mediumville.toml @@ -9,7 +9,6 @@ save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" days_per_period = 365 -reserve_margin = "static" [MGA] slack = 0.1 diff --git a/tests/testing_configs/config_myopic_capacities.toml b/tests/testing_configs/config_myopic_capacities.toml index 77b49abde..5787108dd 100644 --- a/tests/testing_configs/config_myopic_capacities.toml +++ b/tests/testing_configs/config_myopic_capacities.toml @@ -10,7 +10,6 @@ save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" days_per_period = 365 -reserve_margin = "static" [MGA] slack = 0.1 diff --git a/tests/testing_configs/config_reserve_margins.toml b/tests/testing_configs/config_reserve_margins.toml new file mode 100644 index 000000000..f794eac59 --- /dev/null +++ b/tests/testing_configs/config_reserve_margins.toml @@ -0,0 +1,12 @@ +scenario = "reserve_margins" +scenario_mode = "perfect_foresight" +extensions = ["unit_commitment"] +input_database = "tests/testing_outputs/reserve_margins.sqlite" +output_database = "tests/testing_outputs/reserve_margins.sqlite" +neos = false +solver_name = "appsi_highs" +save_excel = false +save_duals = false +save_lp_file = true +time_sequencing = "seasonal_timeslices" +days_per_period = 365 diff --git a/tests/testing_configs/config_seasonal_storage.toml b/tests/testing_configs/config_seasonal_storage.toml index 927446558..5c61a78a8 100644 --- a/tests/testing_configs/config_seasonal_storage.toml +++ b/tests/testing_configs/config_seasonal_storage.toml @@ -9,7 +9,6 @@ save_duals = false save_lp_file = false time_sequencing = "representative_periods" days_per_period = 365 -reserve_margin = "static" [MGA] cost_epsilon = 0.03 diff --git a/tests/testing_configs/config_storageville.toml b/tests/testing_configs/config_storageville.toml index 79a2585d0..a8216a6aa 100644 --- a/tests/testing_configs/config_storageville.toml +++ b/tests/testing_configs/config_storageville.toml @@ -9,7 +9,6 @@ save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" days_per_period = 365 -reserve_margin = "static" [MGA] slack = 0.1 diff --git a/tests/testing_configs/config_survival_curve.toml b/tests/testing_configs/config_survival_curve.toml index fa28822a1..6796bb64d 100644 --- a/tests/testing_configs/config_survival_curve.toml +++ b/tests/testing_configs/config_survival_curve.toml @@ -9,7 +9,6 @@ save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" days_per_period = 365 -reserve_margin = "static" [MGA] cost_epsilon = 0.03 diff --git a/tests/testing_configs/config_test_system.toml b/tests/testing_configs/config_test_system.toml index 25acdfe59..7b5072a97 100644 --- a/tests/testing_configs/config_test_system.toml +++ b/tests/testing_configs/config_test_system.toml @@ -9,7 +9,6 @@ save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" days_per_period = 365 -reserve_margin = "static" [MGA] slack = 0.1 diff --git a/tests/testing_configs/config_test_week.toml b/tests/testing_configs/config_test_week.toml index 484272eae..7e7a1face 100644 --- a/tests/testing_configs/config_test_week.toml +++ b/tests/testing_configs/config_test_week.toml @@ -9,7 +9,6 @@ save_excel = false save_duals = false save_lp_file = false days_per_period = 7 -reserve_margin = "static" [MGA] slack = 0.1 diff --git a/tests/testing_configs/config_utopia.toml b/tests/testing_configs/config_utopia.toml index 1e7080c4a..ec7d69f3b 100644 --- a/tests/testing_configs/config_utopia.toml +++ b/tests/testing_configs/config_utopia.toml @@ -9,7 +9,6 @@ save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" days_per_period = 365 -reserve_margin = "static" [MGA] cost_epsilon = 0.03 diff --git a/tests/testing_configs/config_utopia_gv.toml b/tests/testing_configs/config_utopia_gv.toml index cc5d93a5e..deb7bfdfa 100644 --- a/tests/testing_configs/config_utopia_gv.toml +++ b/tests/testing_configs/config_utopia_gv.toml @@ -9,7 +9,6 @@ save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" days_per_period = 365 -reserve_margin = "static" graphviz_output = true [MGA] diff --git a/tests/testing_configs/config_utopia_mc.toml b/tests/testing_configs/config_utopia_mc.toml index 40f8993dc..3eae138be 100644 --- a/tests/testing_configs/config_utopia_mc.toml +++ b/tests/testing_configs/config_utopia_mc.toml @@ -11,7 +11,6 @@ solver_name = "appsi_highs" time_sequencing = 'seasonal_timeslices' days_per_period = 365 -reserve_margin = 'static' [monte_carlo] run_settings = "tests/testing_data/mc_settings_utopia.csv" diff --git a/tests/testing_configs/config_utopia_myopic.toml b/tests/testing_configs/config_utopia_myopic.toml index 2744e9809..4077dafc7 100644 --- a/tests/testing_configs/config_utopia_myopic.toml +++ b/tests/testing_configs/config_utopia_myopic.toml @@ -9,7 +9,6 @@ save_duals = false save_lp_file = false time_sequencing = "seasonal_timeslices" days_per_period = 365 -reserve_margin = "static" [MGA] slack = 0.1 diff --git a/tests/testing_data/annualised_demand.sql b/tests/testing_data/annualised_demand.sql index 76d910927..f2407ac4c 100644 --- a/tests/testing_data/annualised_demand.sql +++ b/tests/testing_data/annualised_demand.sql @@ -32,16 +32,16 @@ REPLACE INTO "limit_activity" VALUES('region',2000,'non_annual','le',0.5,NULL,NU REPLACE INTO "loan_lifetime_process" VALUES('region', 'annual', 2000, 1.0, NULL, NULL); REPLACE INTO "loan_lifetime_process" VALUES('region', 'non_annual', 2000, 1.0, NULL, NULL); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); -REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); +REPLACE INTO "metadata" VALUES('DB_MINOR',1,''); REPLACE INTO "metadata_real" VALUES('global_discount_rate',0.05,'Discount Rate for future costs'); REPLACE INTO "metadata_real" VALUES('default_loan_rate',0.05,'Default Loan Rate if not specified in loan_rate table'); REPLACE INTO "operator" VALUES('e','equal to'); REPLACE INTO "operator" VALUES('le','less than or equal to'); REPLACE INTO "operator" VALUES('ge','greater than or equal to'); REPLACE INTO "region" VALUES('region',NULL); -REPLACE INTO "technology" VALUES('annual','p','energy',NULL,NULL,0,1,0,0,0,0,0,0,NULL); -REPLACE INTO "technology" VALUES('import','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); -REPLACE INTO "technology" VALUES('non_annual','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('annual','p','energy',NULL,NULL,0,1,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('import','p','energy',NULL,NULL,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('non_annual','p','energy',NULL,NULL,0,0,0,0,0,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'); diff --git a/tests/testing_data/emissions.sql b/tests/testing_data/emissions.sql index 0aaa11b02..1d2bcc6c6 100644 --- a/tests/testing_data/emissions.sql +++ b/tests/testing_data/emissions.sql @@ -68,21 +68,21 @@ REPLACE INTO "limit_capacity" VALUES('Testregion',2000,'TechCurtailment','ge',1. REPLACE INTO "limit_capacity" VALUES('Testregion',2000,'TechOrdinary','le',1.0,NULL,NULL); REPLACE INTO "limit_capacity" VALUES('Testregion',2000,'TechCurtailment','le',1.0,NULL,NULL); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); -REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); +REPLACE INTO "metadata" VALUES('DB_MINOR',1,''); REPLACE INTO "metadata_real" VALUES('global_discount_rate',0.05,'Discount Rate for future costs'); REPLACE INTO "metadata_real" VALUES('default_loan_rate',0.05,'Default Loan Rate if not specified in loan_rate table'); REPLACE INTO "operator" VALUES('e','equal to'); REPLACE INTO "operator" VALUES('le','less than or equal to'); REPLACE INTO "operator" VALUES('ge','greater than or equal to'); REPLACE INTO "region" VALUES('Testregion',NULL); -REPLACE INTO "technology" VALUES('TechAnnual','p','energy',NULL,NULL,0,1,0,0,0,0,0,0,NULL); -REPLACE INTO "technology" VALUES('TechFlex','p','energy',NULL,NULL,0,0,0,0,0,1,0,0,NULL); -REPLACE INTO "technology" VALUES('TechOrdinary','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); -REPLACE INTO "technology" VALUES('TechCurtailment','p','energy',NULL,NULL,0,0,0,1,0,0,0,0,NULL); -REPLACE INTO "technology" VALUES('TechFlexNull','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); -REPLACE INTO "technology" VALUES('TechAnnualFlex','p','energy',NULL,NULL,0,1,0,0,0,1,0,0,NULL); -REPLACE INTO "technology" VALUES('TechEmbodied','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); -REPLACE INTO "technology" VALUES('TechEndOfLife','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('TechAnnual','p','energy',NULL,NULL,0,1,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('TechFlex','p','energy',NULL,NULL,0,0,0,0,1,0,0,NULL); +REPLACE INTO "technology" VALUES('TechOrdinary','p','energy',NULL,NULL,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('TechCurtailment','p','energy',NULL,NULL,0,0,1,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('TechFlexNull','p','energy',NULL,NULL,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('TechAnnualFlex','p','energy',NULL,NULL,0,1,0,0,1,0,0,NULL); +REPLACE INTO "technology" VALUES('TechEmbodied','p','energy',NULL,NULL,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('TechEndOfLife','p','energy',NULL,NULL,0,0,0,0,0,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'); diff --git a/tests/testing_data/materials.sql b/tests/testing_data/materials.sql index 95f24b4fa..b9631c9f7 100644 --- a/tests/testing_data/materials.sql +++ b/tests/testing_data/materials.sql @@ -330,7 +330,7 @@ REPLACE INTO "limit_tech_input_split_annual" VALUES('regionB',2010,'diesel','CAR REPLACE INTO "limit_tech_input_split_annual" VALUES('regionB',2020,'electricity','CAR_PHEV','le',0.2,''); REPLACE INTO "limit_tech_input_split_annual" VALUES('regionB',2020,'diesel','CAR_PHEV','le',0.8,NULL); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); -REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); +REPLACE INTO "metadata" VALUES('DB_MINOR',1,''); REPLACE INTO "metadata_real" VALUES('global_discount_rate',0.05,'Discount Rate for future costs'); REPLACE INTO "metadata_real" VALUES('default_loan_rate',0.05,'Default Loan Rate if not specified in loan_rate table'); REPLACE INTO "operator" VALUES('e','equal to'); @@ -345,25 +345,25 @@ REPLACE INTO "sector_label" VALUES('residential',NULL); REPLACE INTO "sector_label" VALUES('fuels',NULL); REPLACE INTO "storage_duration" VALUES('regionA','BATT_GRID',2.0,'2 hours energy storage'); REPLACE INTO "storage_duration" VALUES('regionB','BATT_GRID',2.0,'2 hours energy storage'); -REPLACE INTO "technology" VALUES('IMPORT_LI','p','materials',NULL,NULL,1,1,0,0,0,0,0,0,'lithium importer'); -REPLACE INTO "technology" VALUES('IMPORT_CO','p','materials',NULL,NULL,1,1,0,0,0,0,0,0,'cobalt importer'); -REPLACE INTO "technology" VALUES('IMPORT_P','p','materials',NULL,NULL,1,1,0,0,0,0,0,0,'phosphorous importer'); -REPLACE INTO "technology" VALUES('CAR_BEV','p','transportation',NULL,NULL,0,0,0,0,0,0,0,0,'car - battery electric'); -REPLACE INTO "technology" VALUES('CAR_PHEV','p','transportation',NULL,NULL,0,0,0,0,0,0,0,0,'car - plug in hybrid'); -REPLACE INTO "technology" VALUES('CAR_ICE','p','transportation',NULL,NULL,0,0,0,0,0,0,0,0,'car - internal combustion'); -REPLACE INTO "technology" VALUES('RECYCLE_NMC','p','materials',NULL,NULL,0,1,0,0,0,0,0,0,'nmc battery recycler'); -REPLACE INTO "technology" VALUES('RECYCLE_LFP','p','materials',NULL,NULL,0,1,0,0,0,0,0,0,'lfp battery recycler'); -REPLACE INTO "technology" VALUES('MANUFAC_NMC','p','materials',NULL,NULL,0,1,0,0,0,0,0,0,'nmc battery manufacturing'); -REPLACE INTO "technology" VALUES('MANUFAC_LFP','p','materials',NULL,NULL,0,1,0,0,0,0,0,0,'lfp battery manufacturing'); -REPLACE INTO "technology" VALUES('IMPORT_NI','p','materials',NULL,NULL,1,1,0,0,0,0,0,0,'nickel importer'); -REPLACE INTO "technology" VALUES('DOMESTIC_NI','p','materials',NULL,NULL,1,1,0,0,0,0,0,0,'domestic nickel production'); -REPLACE INTO "technology" VALUES('GEN_DSL','p','electricity',NULL,NULL,0,0,0,0,0,0,0,0,'diesel generators'); -REPLACE INTO "technology" VALUES('SOL_PV','p','electricity',NULL,NULL,0,0,0,1,0,0,0,0,'solar panels'); -REPLACE INTO "technology" VALUES('BATT_GRID','ps','electricity',NULL,NULL,0,0,0,0,0,0,0,0,'grid battery storage'); -REPLACE INTO "technology" VALUES('FURNACE','p','residential',NULL,NULL,1,0,0,0,0,0,0,0,'diesel furnace heater'); -REPLACE INTO "technology" VALUES('HEATPUMP','p','residential',NULL,NULL,1,0,0,0,0,0,0,0,'heat pump'); -REPLACE INTO "technology" VALUES('IMPORT_DSL','p','fuels',NULL,NULL,1,1,0,0,0,0,0,0,'diesel importer'); -REPLACE INTO "technology" VALUES('ELEC_INTERTIE','p','electricity',NULL,NULL,0,0,0,0,0,0,1,0,'dummy tech to make landfill feasible'); +REPLACE INTO "technology" VALUES('IMPORT_LI','p','materials',NULL,NULL,1,1,0,0,0,0,0,'lithium importer'); +REPLACE INTO "technology" VALUES('IMPORT_CO','p','materials',NULL,NULL,1,1,0,0,0,0,0,'cobalt importer'); +REPLACE INTO "technology" VALUES('IMPORT_P','p','materials',NULL,NULL,1,1,0,0,0,0,0,'phosphorous importer'); +REPLACE INTO "technology" VALUES('CAR_BEV','p','transportation',NULL,NULL,0,0,0,0,0,0,0,'car - battery electric'); +REPLACE INTO "technology" VALUES('CAR_PHEV','p','transportation',NULL,NULL,0,0,0,0,0,0,0,'car - plug in hybrid'); +REPLACE INTO "technology" VALUES('CAR_ICE','p','transportation',NULL,NULL,0,0,0,0,0,0,0,'car - internal combustion'); +REPLACE INTO "technology" VALUES('RECYCLE_NMC','p','materials',NULL,NULL,0,1,0,0,0,0,0,'nmc battery recycler'); +REPLACE INTO "technology" VALUES('RECYCLE_LFP','p','materials',NULL,NULL,0,1,0,0,0,0,0,'lfp battery recycler'); +REPLACE INTO "technology" VALUES('MANUFAC_NMC','p','materials',NULL,NULL,0,1,0,0,0,0,0,'nmc battery manufacturing'); +REPLACE INTO "technology" VALUES('MANUFAC_LFP','p','materials',NULL,NULL,0,1,0,0,0,0,0,'lfp battery manufacturing'); +REPLACE INTO "technology" VALUES('IMPORT_NI','p','materials',NULL,NULL,1,1,0,0,0,0,0,'nickel importer'); +REPLACE INTO "technology" VALUES('DOMESTIC_NI','p','materials',NULL,NULL,1,1,0,0,0,0,0,'domestic nickel production'); +REPLACE INTO "technology" VALUES('GEN_DSL','p','electricity',NULL,NULL,0,0,0,0,0,0,0,'diesel generators'); +REPLACE INTO "technology" VALUES('SOL_PV','p','electricity',NULL,NULL,0,0,1,0,0,0,0,'solar panels'); +REPLACE INTO "technology" VALUES('BATT_GRID','ps','electricity',NULL,NULL,0,0,0,0,0,0,0,'grid battery storage'); +REPLACE INTO "technology" VALUES('FURNACE','p','residential',NULL,NULL,1,0,0,0,0,0,0,'diesel furnace heater'); +REPLACE INTO "technology" VALUES('HEATPUMP','p','residential',NULL,NULL,1,0,0,0,0,0,0,'heat pump'); +REPLACE INTO "technology" VALUES('IMPORT_DSL','p','fuels',NULL,NULL,1,1,0,0,0,0,0,'diesel importer'); +REPLACE INTO "technology" VALUES('ELEC_INTERTIE','p','electricity',NULL,NULL,0,0,0,0,0,1,0,'dummy tech to make landfill feasible'); 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'); diff --git a/tests/testing_data/mediumville.sql b/tests/testing_data/mediumville.sql index 2f253a8ce..26a6bc913 100644 --- a/tests/testing_data/mediumville.sql +++ b/tests/testing_data/mediumville.sql @@ -1,4 +1,4 @@ -REPLACE INTO "capacity_credit" VALUES('A',2025,'EF',2025,0.6,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('prm_A','A','EF',0.6,NULL); REPLACE INTO "capacity_factor_process" VALUES('A','s2','d1','EFL',2025,0.8,NULL); REPLACE INTO "capacity_factor_process" VALUES('A','s1','d2','EFL',2025,0.9,NULL); REPLACE INTO "capacity_factor_tech" VALUES('A','s1','d1','EF',0.8,NULL); @@ -108,6 +108,7 @@ REPLACE INTO "limit_activity" VALUES('B',2025,'EH','le',10000.0,'stuff',NULL); REPLACE INTO "limit_activity" VALUES('A',2025,'EF','le',10000.0,'stuff',NULL); REPLACE INTO "limit_activity" VALUES('A',2025,'A_tech_grp_1','ge',0.05,'',NULL); REPLACE INTO "limit_activity" VALUES('A',2025,'A_tech_grp_1','le',10000.0,'',NULL); +REPLACE INTO "limit_activity_share" VALUES('B',2025,'EF','RPS_common','ge',0.3,NULL); REPLACE INTO "limit_capacity" VALUES('A',2025,'EH','ge',0.1,'',''); REPLACE INTO "limit_capacity" VALUES('B',2025,'batt','ge',0.1,'',''); REPLACE INTO "limit_capacity" VALUES('A',2025,'EH','le',20000.0,'',''); @@ -140,20 +141,19 @@ REPLACE INTO "loan_lifetime_process" VALUES('B', 'GeoThermal', 2025, 10.0, NULL, REPLACE INTO "loan_lifetime_process" VALUES('A-B', 'FGF_pipe', 2025, 10.0, NULL, NULL); REPLACE INTO "loan_lifetime_process" VALUES('B-A', 'FGF_pipe', 2025, 10.0, NULL, NULL); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); -REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); +REPLACE INTO "metadata" VALUES('DB_MINOR',1,''); 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',4.2000000000000004e-01,''); 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 "planning_reserve_margin" VALUES('A',0.05,NULL); +REPLACE INTO "planning_reserve_margin" VALUES('prm_A','A','EF','static',0.05,NULL); REPLACE INTO "ramp_down_hourly" VALUES('A','EH',0.05,NULL); REPLACE INTO "ramp_down_hourly" VALUES('B','EH',0.05,NULL); REPLACE INTO "ramp_up_hourly" VALUES('B','EH',0.05,NULL); REPLACE INTO "ramp_up_hourly" VALUES('A','EH',0.05,NULL); REPLACE INTO "region" VALUES('A','main region'); REPLACE INTO "region" VALUES('B','just a 2nd region'); -REPLACE INTO "rps_requirement" VALUES('B',2025,'RPS_common',0.3,NULL); REPLACE INTO "sector_label" VALUES('supply',NULL); REPLACE INTO "sector_label" VALUES('electric',NULL); REPLACE INTO "sector_label" VALUES('transport',NULL); @@ -166,16 +166,16 @@ REPLACE INTO "tech_group" VALUES('A_tech_grp_1','converted from old db'); REPLACE INTO "tech_group_member" VALUES('RPS_common','EF'); REPLACE INTO "tech_group_member" VALUES('A_tech_grp_1','EH'); REPLACE INTO "tech_group_member" VALUES('A_tech_grp_1','EF'); -REPLACE INTO "technology" VALUES('well','p','supply','water','',0,0,0,0,0,0,0,0,'plain old water'); -REPLACE INTO "technology" VALUES('bulbs','p','residential','electric','',0,0,0,0,0,0,0,0,'residential lighting'); -REPLACE INTO "technology" VALUES('EH','pb','electric','hydro','',0,0,0,1,1,0,0,0,'hydro power electric plant'); -REPLACE INTO "technology" VALUES('batt','ps','electric','electric','',0,0,0,0,0,0,0,0,'big battery'); -REPLACE INTO "technology" VALUES('EF','p','electric','electric','',0,0,1,0,0,0,0,0,'fusion plant'); -REPLACE INTO "technology" VALUES('EFL','p','electric','electric','',0,0,0,0,0,1,0,0,'linked (to Fusion) producer'); -REPLACE INTO "technology" VALUES('heater','p','residential','electric','',0,0,0,0,0,0,0,0,'heater'); -REPLACE INTO "technology" VALUES('FGF_pipe','p','transport',NULL,'',0,0,0,0,0,0,1,0,'transportation line A->B'); -REPLACE INTO "technology" VALUES('GeoThermal','p','residential','hydro','',0,1,0,0,0,0,0,0,'geothermal hot water source'); -REPLACE INTO "technology" VALUES('GeoHeater','p','residential','hydro','',0,0,0,0,0,0,0,0,'geothermal heater from geo hyd'); +REPLACE INTO "technology" VALUES('well','p','supply','water','',0,0,0,0,0,0,0,'plain old water'); +REPLACE INTO "technology" VALUES('bulbs','p','residential','electric','',0,0,0,0,0,0,0,'residential lighting'); +REPLACE INTO "technology" VALUES('EH','pb','electric','hydro','',0,0,1,1,0,0,0,'hydro power electric plant'); +REPLACE INTO "technology" VALUES('batt','ps','electric','electric','',0,0,0,0,0,0,0,'big battery'); +REPLACE INTO "technology" VALUES('EF','p','electric','electric','',0,0,0,0,0,0,0,'fusion plant'); +REPLACE INTO "technology" VALUES('EFL','p','electric','electric','',0,0,0,0,1,0,0,'linked (to Fusion) producer'); +REPLACE INTO "technology" VALUES('heater','p','residential','electric','',0,0,0,0,0,0,0,'heater'); +REPLACE INTO "technology" VALUES('FGF_pipe','p','transport',NULL,'',0,0,0,0,0,1,0,'transportation line A->B'); +REPLACE INTO "technology" VALUES('GeoThermal','p','residential','hydro','',0,1,0,0,0,0,0,'geothermal hot water source'); +REPLACE INTO "technology" VALUES('GeoHeater','p','residential','hydro','',0,0,0,0,0,0,0,'geothermal heater from geo hyd'); 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'); diff --git a/tests/testing_data/mediumville_sets.json b/tests/testing_data/mediumville_sets.json index 3aca6a682..2d3676958 100644 --- a/tests/testing_data/mediumville_sets.json +++ b/tests/testing_data/mediumville_sets.json @@ -31,10 +31,10 @@ "flow_in_storage_rpsditvo": "ff680754a218ee843941e77bd07cbc5e5afd74e2b7b29a76ea86621624e8c0fd", "flow_var_annual_rpitvo": "6f5c569787fbf1e0a4076011f75fcd50a840bac85bb57b026f4fc5682739f888", "flow_var_rpsditvo": "e8c35c3b7b1f0c0e10e6f53e94d0c6b8a884c0dd048675cbeb9e7df33794161b", - "lifetime_tech_rt": "6786f2e9acdccce907ebad50d2ea70481bff72a749253e78168d29b480b07f65", "lifetime_process_rtv": "212639322f29aa7687eb9962fb9d74ef60961d720a2a753e2af53473b9e1648f", + "lifetime_tech_rt": "6786f2e9acdccce907ebad50d2ea70481bff72a749253e78168d29b480b07f65", "limit_activity_constraint_rpt": "90461349933d0b32167abdca242233004b66212b57ed57213dce6f6818203963", - "limit_activity_share_constraint_rpgg": "(empty)", + "limit_activity_share_constraint_rpgg": "0df34850f785baf3f30a829f838bb853edd65e1969b3df81885a2ef40c130495", "limit_annual_capacity_factor_constraint_rptvo": "(empty)", "limit_annual_capacity_factor_constraint_rtvo": "(empty)", "limit_capacity_constraint_rpt": "118826dabd14af75ae09adbd5bdbba750528b3d59907cbfba3690223ffc7def7", @@ -58,16 +58,15 @@ "new_capacity_var_rtv": "212639322f29aa7687eb9962fb9d74ef60961d720a2a753e2af53473b9e1648f", "operator": "74d830836f1399fb336a0432dde7d7bd36cffa3ff76b1c42d7945350cfb9bf91", "ordered_season_sequential": "(empty)", + "planning_reserve_nrtpsd": "2e7d381ec4fe519b7073ff597c1ff94d78c22f439643c3167f6a65f203a24322", + "planning_reserves": "6354fba2bc272aa5b1d6c6855d3d1da49e7d3967c8982c2b32463326597457b3", "process_life_frac_rptv": "fdb177f119430de12c8b1083c9275e3a256f45f859d6b6819a84bff5c8e92184", "ramp_down_constraint_rpsdtv": "d766f05fa377b69768214641fda5d15617b697a43e64c863fe53503f11db4a89", "ramp_up_constraint_rpsdtv": "d766f05fa377b69768214641fda5d15617b697a43e64c863fe53503f11db4a89", - "regional_exchange_capacity_constraint_rrptv": "cf641ca7d7b664fda48e76f03b37c3b81aaa130ce821f919e6a8ac4860dad100", + "regional_exchange_capacity_constraint_rrptv": "06d563ada57aa6284fd48464d44cb37bc79f51681bfb8274c0d176c42f9398d1", "regional_global_indices": "a4bd2969735cb437072971a2fa02a2d8fbb20a707a1bdfa695b92922daeb5d10", "regional_indices": "6d8dc3bc6dc8cd485bcf2a59d752df20974b0fd78cc623e3a51e705a01edeea4", "regions": "f2314439597c11e286fd3c2fdf8eb70d3739e136f83e9533249ce3ecc43ece3e", - "renewable_portfolio_standard_constraint_rpg": "ab39415b5df1f906b11f06034cbfca390f7332b6a17adae60a71a74d7b421f67", - "reserve_margin_method": "7869283c0d14273f720716309207a8f0c24606d03c679d6b68e656ed8d86241d", - "reserve_margin_rpsd": "9bd91053e57055456e04648c00d8e581addc9aa503cf31cf44c7a439c6f4fe0f", "retired_capacity_var_rptv": "(empty)", "seasonal_storage_constraints_rpsdtv": "(empty)", "seasonal_storage_level_rpstv": "(empty)", @@ -87,7 +86,6 @@ "tech_group_names": "6b923047f11d1c00a828b0f02aed79e853d81fd35ffd4667fbdc828ce356e515", "tech_or_group": "4899ca300eb8ed5ba168b1f2ee669cacd36d041f493fb3dd00218d6764598cf9", "tech_production": "24f75b6f705a36033456d02638e7c50667908c45c474151fb8490666d928c63f", - "tech_reserve": "b28d0fd7ec11abdd0e645c2a9d83b05c08ecadcfb944d4a7bbd844ff4b83bfbf", "tech_retirement": "ddcf6ff7665c2a8acc4dff1b43655fae1b5a265135cbee18cec638df4e954346", "tech_seasonal_storage": "(empty)", "tech_storage": "e4e91128cadba8c633bf98029cf6666adc3959c63967c6f396028b78e2e9f0cf", diff --git a/tests/testing_data/migration_v4_mock.sql b/tests/testing_data/migration_v4_mock.sql new file mode 100644 index 000000000..01ed01526 --- /dev/null +++ b/tests/testing_data/migration_v4_mock.sql @@ -0,0 +1,56 @@ +-- Mock data for v4 -> v4.1 migration testing +PRAGMA foreign_keys = OFF; +INSERT OR IGNORE INTO commodity_type (label, description) VALUES ('p', 'physical'); +INSERT OR IGNORE INTO commodity_type (label, description) VALUES ('e', 'emissions'); +INSERT OR IGNORE INTO sector_label (sector) VALUES ('electric'); + +INSERT INTO commodity (name, flag) VALUES ('FuelIn', 'p'); +INSERT INTO commodity (name, flag) VALUES ('EnergyOut', 'p'); + +INSERT INTO time_period (period, flag) VALUES (2020, 'e'); +INSERT INTO time_period (period, flag) VALUES (2030, 'f'); +INSERT INTO time_period (period, flag) VALUES (2040, 'f'); + +INSERT INTO time_season (season, segment_fraction) VALUES ('summer', 0.6); +INSERT INTO time_season (season, segment_fraction) VALUES ('winter', 0.4); + +INSERT INTO time_of_day (tod, hours) VALUES ('day', 14.4); +INSERT INTO time_of_day (tod, hours) VALUES ('night', 9.6); + +INSERT OR IGNORE INTO technology_type (label, description) VALUES ('p', 'production'); +INSERT INTO technology (tech, flag, reserve) VALUES ('GasTurbine', 'p', 1); +INSERT INTO technology (tech, flag, reserve) VALUES ('WindFarm', 'p', 1); +INSERT INTO technology (tech, flag, reserve) VALUES ('CoalPlant', 'p', 0); + +INSERT INTO efficiency (region, input_comm, tech, vintage, output_comm, efficiency) + VALUES ('R1', 'FuelIn', 'GasTurbine', 2030, 'EnergyOut', 0.4); +INSERT INTO efficiency (region, input_comm, tech, vintage, output_comm, efficiency) + VALUES ('R1', 'FuelIn', 'WindFarm', 2030, 'EnergyOut', 1.0); +INSERT INTO efficiency (region, input_comm, tech, vintage, output_comm, efficiency) + VALUES ('R1', 'FuelIn', 'CoalPlant', 2030, 'EnergyOut', 0.35); + +-- capacity_credit will migrate to planning_reserve_credit (dropping period, vintage) +INSERT INTO capacity_credit (region, period, tech, vintage, credit) + VALUES ('R1', 2030, 'GasTurbine', 2030, 0.85); +INSERT INTO capacity_credit (region, period, tech, vintage, credit) + VALUES ('R1', 2040, 'GasTurbine', 2030, 0.80); +INSERT INTO capacity_credit (region, period, tech, vintage, credit) + VALUES ('R1', 2030, 'WindFarm', 2030, 0.25); + +-- reserve_capacity_derate migrates to planning_reserve_credit too, averaged in with capacity_credit +INSERT INTO reserve_capacity_derate (region, season, tech, vintage, factor) + VALUES ('R1', 'summer', 'GasTurbine', 2030, 0.95); +INSERT INTO reserve_capacity_derate (region, season, tech, vintage, factor) + VALUES ('R1', 'summer', 'WindFarm', 2030, 0.20); +INSERT INTO reserve_capacity_derate (region, season, tech, vintage, factor) + VALUES ('R1', 'winter', 'WindFarm', 2030, 0.10); + +-- planning_reserve_margin will migrate using reserve-flagged tech group as tech_or_group +INSERT INTO planning_reserve_margin (region, margin) VALUES ('R1', 0.15); + +-- rps_requirement will migrate to limit_activity_share +INSERT INTO tech_group (group_name) VALUES ('renewables'); +INSERT INTO rps_requirement (region, period, tech_group, requirement) + VALUES ('R1', 2030, 'renewables', 0.30); +INSERT INTO rps_requirement (region, period, tech_group, requirement) + VALUES ('R1', 2040, 'renewables', 0.40); diff --git a/tests/testing_data/myopic_capacities.sql b/tests/testing_data/myopic_capacities.sql index ca11c4158..d9f03b2e9 100644 --- a/tests/testing_data/myopic_capacities.sql +++ b/tests/testing_data/myopic_capacities.sql @@ -1,5 +1,5 @@ REPLACE INTO metadata VALUES('DB_MAJOR',4,''); -REPLACE INTO metadata VALUES('DB_MINOR',0,''); +REPLACE INTO metadata VALUES('DB_MINOR',1,''); 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); @@ -234,18 +234,18 @@ 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); REPLACE INTO commodity VALUES('demand_dc','d',NULL,NULL); REPLACE INTO commodity VALUES('demand_dnc','d',NULL,NULL); -REPLACE INTO technology VALUES('tech_discrete_cap','p','energy',NULL,NULL,0,0,0,0,1,0,0,0,NULL); -REPLACE INTO technology VALUES('tech_dc_dummy','p','energy',NULL,NULL,1,0,0,0,0,0,0,0,NULL); -REPLACE INTO technology VALUES('tech_discrete_new_cap','p','energy',NULL,NULL,0,0,0,0,1,0,0,0,NULL); -REPLACE INTO technology VALUES('tech_dnc_dummy','p','energy',NULL,NULL,1,0,0,0,0,0,0,0,NULL); +REPLACE INTO technology VALUES('tech_ancient','p','energy',NULL,NULL,0,0,0,1,0,0,0,NULL); +REPLACE INTO technology VALUES('tech_old','p','energy',NULL,NULL,0,0,0,1,0,0,0,NULL); +REPLACE INTO technology VALUES('tech_current','p','energy',NULL,NULL,0,0,0,1,0,0,0,NULL); +REPLACE INTO technology VALUES('tech_future','p','energy',NULL,NULL,0,0,0,1,0,0,0,NULL); +REPLACE INTO technology VALUES('tech_retire','p','energy',NULL,NULL,0,0,0,1,0,0,0,NULL); +REPLACE INTO technology VALUES('tech_discrete_cap','p','energy',NULL,NULL,0,0,0,1,0,0,0,NULL); +REPLACE INTO technology VALUES('tech_dc_dummy','p','energy',NULL,NULL,1,0,0,0,0,0,0,NULL); +REPLACE INTO technology VALUES('tech_discrete_new_cap','p','energy',NULL,NULL,0,0,0,1,0,0,0,NULL); +REPLACE INTO technology VALUES('tech_dnc_dummy','p','energy',NULL,NULL,1,0,0,0,0,0,0,NULL); REPLACE INTO lifetime_tech VALUES('region','tech_discrete_cap',35.0,NULL,NULL); REPLACE INTO lifetime_tech VALUES('region','tech_dc_dummy',35.0,NULL,NULL); REPLACE INTO lifetime_tech VALUES('region','tech_discrete_new_cap',5.0,NULL,NULL); diff --git a/tests/testing_data/reserve_margins.lp b/tests/testing_data/reserve_margins.lp new file mode 100644 index 000000000..11e0220ed --- /dev/null +++ b/tests/testing_data/reserve_margins.lp @@ -0,0 +1,11212 @@ +\* Source Pyomo model name=unknown *\ + +min +total_cost: ++0.0 ONE_VAR_CONSTANT + +s.t. + +c_u_capacity_constraint(B_2025_summer_day_NGCC_2015)_: ++1 v_flow_out(B_2025_summer_day_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2025_NGCC_2015) +<= 0 + +c_u_capacity_constraint(B_2025_winter_day_NGCC_2020)_: ++1 v_flow_out(B_2025_winter_day_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2025_NGCC_2020) +<= 0 + +c_u_capacity_constraint(B_2025_summer_night_NGCC_2015)_: ++1 v_flow_out(B_2025_summer_night_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2025_NGCC_2015) +<= 0 + +c_u_capacity_constraint(B_A_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(B_A_2025_winter_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(B_2025_summer_night_HEAT_SYS_2020)_: ++1 v_flow_out(B_2025_summer_night_ELC_HEAT_SYS_2020_HEAT) +-0.25 v_capacity(B_2025_HEAT_SYS_2020) +<= 0 + +c_u_capacity_constraint(C_2020_winter_night_HEAT_ANN_2020)_: +-0.25 v_capacity(C_2020_HEAT_ANN_2020) +<= -0.25 + +c_u_capacity_constraint(C_A_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(C_A_2020_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2020_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(B_2025_summer_day_HEAT_SYS_2020)_: ++1 v_flow_out(B_2025_summer_day_ELC_HEAT_SYS_2020_HEAT) +-0.25 v_capacity(B_2025_HEAT_SYS_2020) +<= 0 + +c_u_capacity_constraint(B_2025_winter_day_HEAT_SYS_2025)_: ++1 v_flow_out(B_2025_winter_day_ELC_HEAT_SYS_2025_HEAT) +-0.25 v_capacity(B_2025_HEAT_SYS_2025) +<= 0 + +c_u_capacity_constraint(C_A_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(C_A_2020_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2020_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(C_B_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(C_B_2025_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2025_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2020_summer_night_NGCC_2020)_: ++1 v_flow_out(A_2020_summer_night_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2020_summer_night_NGCC_2020) +<= 0 + +c_u_capacity_constraint(A_B_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(A_B_2025_summer_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2025_summer_night_E_TRANS_2015) +<= 0 + +c_e_capacity_constraint(A_2020_summer_day_SOLPV_2015)_: +-1 v_flow_out(A_2020_summer_day_ethos_SOLPV_2015_ELC) ++1.3139999999999998 v_capacity(A_2020_SOLPV_2015) +-1 v_curtailment(A_2020_summer_day_ethos_SOLPV_2015_ELC) += 0 + +c_u_capacity_constraint(B_2025_winter_night_NGCC_2020)_: ++1 v_flow_out(B_2025_winter_night_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2025_NGCC_2020) +<= 0 + +c_u_capacity_constraint(A_C_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(A_C_2020_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2020_E_TRANS_2015) +<= 0 + +c_e_capacity_constraint(A_2020_winter_night_SOLPV_2020)_: +-1 v_flow_out(A_2020_winter_night_ethos_SOLPV_2020_ELC) +-1 v_curtailment(A_2020_winter_night_ethos_SOLPV_2020_ELC) += 0.0 + +c_e_capacity_constraint(A_2025_winter_day_SOLPV_2015)_: +-1 v_flow_out(A_2025_winter_day_ethos_SOLPV_2015_ELC) ++0.6569999999999999 v_capacity(A_2025_SOLPV_2015) +-1 v_curtailment(A_2025_winter_day_ethos_SOLPV_2015_ELC) += 0 + +c_u_capacity_constraint(A_2025_summer_night_NGCC_2020)_: ++1 v_flow_out(A_2025_summer_night_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2025_summer_night_NGCC_2020) +<= 0 + +c_e_capacity_constraint(A_2025_summer_day_SOLPV_2025)_: +-1 v_flow_out(A_2025_summer_day_ethos_SOLPV_2025_ELC) ++1.3139999999999998 v_capacity(A_2025_SOLPV_2025) +-1 v_curtailment(A_2025_summer_day_ethos_SOLPV_2025_ELC) += 0 + +c_u_capacity_constraint(A_2025_winter_day_HEAT_SYS_2025)_: ++1 v_flow_out(A_2025_winter_day_ELC_HEAT_SYS_2025_HEAT) +-0.25 v_capacity(A_2025_HEAT_SYS_2025) +<= 0 + +c_u_capacity_constraint(A_C_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(A_C_2020_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2020_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2025_winter_night_NGCC_2020)_: ++1 v_flow_out(A_2025_winter_night_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2025_winter_night_NGCC_2020) +<= 0 + +c_u_capacity_constraint(C_B_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(C_B_2020_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2020_E_TRANS_2015) +<= 0 + +c_e_capacity_constraint(A_2025_winter_night_SOLPV_2015)_: +-1 v_flow_out(A_2025_winter_night_ethos_SOLPV_2015_ELC) +-1 v_curtailment(A_2025_winter_night_ethos_SOLPV_2015_ELC) += 0.0 + +c_u_capacity_constraint(C_2025_winter_night_HEAT_ANN_2020)_: +-0.25 v_capacity(C_2025_HEAT_ANN_2020) +<= -0.275 + +c_u_capacity_constraint(C_2020_winter_day_HEAT_ANN_2020)_: +-0.25 v_capacity(C_2020_HEAT_ANN_2020) +<= -0.25 + +c_u_capacity_constraint(B_2025_winter_day_NGCC_2015)_: ++1 v_flow_out(B_2025_winter_day_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2025_NGCC_2015) +<= 0 + +c_u_capacity_constraint(C_A_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(C_A_2020_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2020_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(B_2025_winter_night_HEAT_SYS_2020)_: ++1 v_flow_out(B_2025_winter_night_ELC_HEAT_SYS_2020_HEAT) +-0.25 v_capacity(B_2025_HEAT_SYS_2020) +<= 0 + +c_u_capacity_constraint(A_B_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(A_B_2025_summer_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2025_winter_day_NGCC_2025)_: ++1 v_flow_out(A_2025_winter_day_NG_NGCC_2025_ELC) +-0.219 v_uc_online(A_2025_winter_day_NGCC_2025) +<= 0 + +c_u_capacity_constraint(B_2025_winter_day_HEAT_SYS_2020)_: ++1 v_flow_out(B_2025_winter_day_ELC_HEAT_SYS_2020_HEAT) +-0.25 v_capacity(B_2025_HEAT_SYS_2020) +<= 0 + +c_u_capacity_constraint(C_B_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(C_B_2020_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2020_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2020_summer_night_NGCC_2015)_: ++1 v_flow_out(A_2020_summer_night_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2020_summer_night_NGCC_2015) +<= 0 + +c_u_capacity_constraint(B_2020_summer_day_NGCC_2020)_: ++1 v_flow_out(B_2020_summer_day_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2020_NGCC_2020) +<= 0 + +c_u_capacity_constraint(B_2025_winter_night_NGCC_2015)_: ++1 v_flow_out(B_2025_winter_night_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2025_NGCC_2015) +<= 0 + +c_e_capacity_constraint(A_2020_winter_night_SOLPV_2015)_: +-1 v_flow_out(A_2020_winter_night_ethos_SOLPV_2015_ELC) +-1 v_curtailment(A_2020_winter_night_ethos_SOLPV_2015_ELC) += 0.0 + +c_u_capacity_constraint(A_B_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(A_B_2020_winter_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2020_summer_day_HEAT_SYS_2020)_: +-0.25 v_capacity(A_2020_HEAT_SYS_2020) +<= -1.25 + +c_u_capacity_constraint(A_2025_summer_night_NGCC_2015)_: ++1 v_flow_out(A_2025_summer_night_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2025_summer_night_NGCC_2015) +<= 0 + +c_e_capacity_constraint(A_2025_summer_day_SOLPV_2020)_: +-1 v_flow_out(A_2025_summer_day_ethos_SOLPV_2020_ELC) ++1.3139999999999998 v_capacity(A_2025_SOLPV_2020) +-1 v_curtailment(A_2025_summer_day_ethos_SOLPV_2020_ELC) += 0 + +c_u_capacity_constraint(B_2020_winter_day_NGCC_2020)_: ++1 v_flow_out(B_2020_winter_day_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2020_NGCC_2020) +<= 0 + +c_u_capacity_constraint(B_2020_winter_night_NGCC_2020)_: ++1 v_flow_out(B_2020_winter_night_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2020_NGCC_2020) +<= 0 + +c_u_capacity_constraint(A_2025_winter_day_HEAT_SYS_2020)_: ++1 v_flow_out(A_2025_winter_day_ELC_HEAT_SYS_2020_HEAT) +-0.25 v_capacity(A_2025_HEAT_SYS_2020) +<= 0 + +c_u_capacity_constraint(B_A_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(B_A_2020_winter_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_C_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(A_C_2025_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2025_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2025_winter_night_NGCC_2015)_: ++1 v_flow_out(A_2025_winter_night_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2025_winter_night_NGCC_2015) +<= 0 + +c_e_capacity_constraint(A_2020_winter_day_SOLPV_2020)_: +-1 v_flow_out(A_2020_winter_day_ethos_SOLPV_2020_ELC) ++0.6569999999999999 v_capacity(A_2020_SOLPV_2020) +-1 v_curtailment(A_2020_winter_day_ethos_SOLPV_2020_ELC) += 0 + +c_u_capacity_constraint(B_C_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(B_C_2025_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2025_E_TRANS_2015) +<= 0 + +c_e_capacity_constraint(A_2020_summer_night_SOLPV_2015)_: +-1 v_flow_out(A_2020_summer_night_ethos_SOLPV_2015_ELC) +-1 v_curtailment(A_2020_summer_night_ethos_SOLPV_2015_ELC) += 0.0 + +c_u_capacity_constraint(A_B_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(A_B_2020_summer_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(C_2025_summer_night_HEAT_ANN_2020)_: +-0.25 v_capacity(C_2025_HEAT_ANN_2020) +<= -0.275 + +c_u_capacity_constraint(A_2020_summer_day_NGCC_2020)_: ++1 v_flow_out(A_2020_summer_day_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2020_summer_day_NGCC_2020) +<= 0 + +c_u_capacity_constraint(A_2025_winter_day_NGCC_2020)_: ++1 v_flow_out(A_2025_winter_day_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2025_winter_day_NGCC_2020) +<= 0 + +c_e_capacity_constraint(A_2025_summer_night_SOLPV_2015)_: +-1 v_flow_out(A_2025_summer_night_ethos_SOLPV_2015_ELC) +-1 v_curtailment(A_2025_summer_night_ethos_SOLPV_2015_ELC) += 0.0 + +c_u_capacity_constraint(B_2020_summer_day_NGCC_2015)_: ++1 v_flow_out(B_2020_summer_day_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2020_NGCC_2015) +<= 0 + +c_u_capacity_constraint(A_2025_summer_night_HEAT_SYS_2025)_: ++1 v_flow_out(A_2025_summer_night_ELC_HEAT_SYS_2025_HEAT) +-0.25 v_capacity(A_2025_HEAT_SYS_2025) +<= 0 + +c_u_capacity_constraint(B_2020_summer_night_HEAT_SYS_2020)_: +-0.25 v_capacity(B_2020_HEAT_SYS_2020) +<= -0.75 + +c_u_capacity_constraint(C_A_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(C_A_2020_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2020_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(B_2020_winter_day_NGCC_2015)_: ++1 v_flow_out(B_2020_winter_day_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2020_NGCC_2015) +<= 0 + +c_u_capacity_constraint(B_2025_summer_day_NGCC_2025)_: ++1 v_flow_out(B_2025_summer_day_NG_NGCC_2025_ELC) +-2.19 v_capacity(B_2025_NGCC_2025) +<= 0 + +c_e_capacity_constraint(A_2025_summer_day_SOLPV_2015)_: +-1 v_flow_out(A_2025_summer_day_ethos_SOLPV_2015_ELC) ++1.3139999999999998 v_capacity(A_2025_SOLPV_2015) +-1 v_curtailment(A_2025_summer_day_ethos_SOLPV_2015_ELC) += 0 + +c_u_capacity_constraint(A_C_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(A_C_2020_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2020_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2025_winter_night_HEAT_SYS_2025)_: ++1 v_flow_out(A_2025_winter_night_ELC_HEAT_SYS_2025_HEAT) +-0.25 v_capacity(A_2025_HEAT_SYS_2025) +<= 0 + +c_u_capacity_constraint(B_2020_winter_night_HEAT_SYS_2020)_: +-0.25 v_capacity(B_2020_HEAT_SYS_2020) +<= -0.75 + +c_u_capacity_constraint(A_2020_winter_day_NGCC_2020)_: ++1 v_flow_out(A_2020_winter_day_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2020_winter_day_NGCC_2020) +<= 0 + +c_e_capacity_constraint(A_2020_winter_day_SOLPV_2015)_: +-1 v_flow_out(A_2020_winter_day_ethos_SOLPV_2015_ELC) ++0.6569999999999999 v_capacity(A_2020_SOLPV_2015) +-1 v_curtailment(A_2020_winter_day_ethos_SOLPV_2015_ELC) += 0 + +c_u_capacity_constraint(B_2020_winter_day_HEAT_SYS_2020)_: +-0.25 v_capacity(B_2020_HEAT_SYS_2020) +<= -0.75 + +c_u_capacity_constraint(B_2020_summer_night_NGCC_2020)_: ++1 v_flow_out(B_2020_summer_night_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2020_NGCC_2020) +<= 0 + +c_u_capacity_constraint(B_C_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(B_C_2020_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2020_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(C_B_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(C_B_2025_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2025_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2020_summer_day_NGCC_2015)_: ++1 v_flow_out(A_2020_summer_day_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2020_summer_day_NGCC_2015) +<= 0 + +c_u_capacity_constraint(A_2020_winter_night_NGCC_2020)_: ++1 v_flow_out(A_2020_winter_night_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2020_winter_night_NGCC_2020) +<= 0 + +c_u_capacity_constraint(A_2020_summer_night_HEAT_SYS_2020)_: +-0.25 v_capacity(A_2020_HEAT_SYS_2020) +<= -1.25 + +c_u_capacity_constraint(C_A_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(C_A_2025_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2025_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2025_winter_day_NGCC_2015)_: ++1 v_flow_out(A_2025_winter_day_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2025_winter_day_NGCC_2015) +<= 0 + +c_u_capacity_constraint(B_C_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(B_C_2025_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2025_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2025_summer_day_NGCC_2025)_: ++1 v_flow_out(A_2025_summer_day_NG_NGCC_2025_ELC) +-0.219 v_uc_online(A_2025_summer_day_NGCC_2025) +<= 0 + +c_u_capacity_constraint(A_2025_summer_night_HEAT_SYS_2020)_: ++1 v_flow_out(A_2025_summer_night_ELC_HEAT_SYS_2020_HEAT) +-0.25 v_capacity(A_2025_HEAT_SYS_2020) +<= 0 + +c_u_capacity_constraint(C_2025_summer_day_HEAT_ANN_2020)_: +-0.25 v_capacity(C_2025_HEAT_ANN_2020) +<= -0.275 + +c_u_capacity_constraint(B_2025_summer_day_NGCC_2020)_: ++1 v_flow_out(B_2025_summer_day_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2025_NGCC_2020) +<= 0 + +c_u_capacity_constraint(C_B_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(C_B_2020_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2020_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2025_winter_night_HEAT_SYS_2020)_: ++1 v_flow_out(A_2025_winter_night_ELC_HEAT_SYS_2020_HEAT) +-0.25 v_capacity(A_2025_HEAT_SYS_2020) +<= 0 + +c_u_capacity_constraint(B_A_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(B_A_2020_summer_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2020_winter_day_NGCC_2015)_: ++1 v_flow_out(A_2020_winter_day_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2020_winter_day_NGCC_2015) +<= 0 + +c_u_capacity_constraint(B_A_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(B_A_2025_summer_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(C_A_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(C_A_2025_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2025_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(B_C_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(B_C_2020_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2020_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_B_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(A_B_2025_winter_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(B_2020_summer_night_NGCC_2015)_: ++1 v_flow_out(B_2020_summer_night_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2020_NGCC_2015) +<= 0 + +c_u_capacity_constraint(B_A_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(B_A_2020_winter_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(B_2020_summer_day_HEAT_SYS_2020)_: +-0.25 v_capacity(B_2020_HEAT_SYS_2020) +<= -0.75 + +c_u_capacity_constraint(B_2020_winter_night_NGCC_2015)_: ++1 v_flow_out(B_2020_winter_night_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2020_NGCC_2015) +<= 0 + +c_u_capacity_constraint(B_2025_summer_night_NGCC_2025)_: ++1 v_flow_out(B_2025_summer_night_NG_NGCC_2025_ELC) +-2.19 v_capacity(B_2025_NGCC_2025) +<= 0 + +c_u_capacity_constraint(A_C_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(A_C_2025_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2025_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2020_winter_night_HEAT_SYS_2020)_: +-0.25 v_capacity(A_2020_HEAT_SYS_2020) +<= -1.25 + +c_u_capacity_constraint(A_C_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(A_C_2025_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2025_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2025_summer_day_NGCC_2020)_: ++1 v_flow_out(A_2025_summer_day_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2025_summer_day_NGCC_2020) +<= 0 + +c_u_capacity_constraint(A_2025_summer_day_HEAT_SYS_2025)_: ++1 v_flow_out(A_2025_summer_day_ELC_HEAT_SYS_2025_HEAT) +-0.25 v_capacity(A_2025_HEAT_SYS_2025) +<= 0 + +c_u_capacity_constraint(A_B_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(A_B_2020_summer_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_C_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(A_C_2025_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2025_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(B_C_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(B_C_2025_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2025_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(C_A_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(C_A_2025_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2025_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(C_2020_summer_night_HEAT_ANN_2020)_: +-0.25 v_capacity(C_2020_HEAT_ANN_2020) +<= -0.25 + +c_e_capacity_constraint(A_2025_winter_day_SOLPV_2025)_: +-1 v_flow_out(A_2025_winter_day_ethos_SOLPV_2025_ELC) ++0.6569999999999999 v_capacity(A_2025_SOLPV_2025) +-1 v_curtailment(A_2025_winter_day_ethos_SOLPV_2025_ELC) += 0 + +c_u_capacity_constraint(C_2025_winter_day_HEAT_ANN_2020)_: +-0.25 v_capacity(C_2025_HEAT_ANN_2020) +<= -0.275 + +c_e_capacity_constraint(A_2025_summer_night_SOLPV_2025)_: +-1 v_flow_out(A_2025_summer_night_ethos_SOLPV_2025_ELC) +-1 v_curtailment(A_2025_summer_night_ethos_SOLPV_2025_ELC) += 0.0 + +c_u_capacity_constraint(B_2025_winter_night_HEAT_SYS_2025)_: ++1 v_flow_out(B_2025_winter_night_ELC_HEAT_SYS_2025_HEAT) +-0.25 v_capacity(B_2025_HEAT_SYS_2025) +<= 0 + +c_e_capacity_constraint(A_2025_winter_night_SOLPV_2025)_: +-1 v_flow_out(A_2025_winter_night_ethos_SOLPV_2025_ELC) +-1 v_curtailment(A_2025_winter_night_ethos_SOLPV_2025_ELC) += 0.0 + +c_u_capacity_constraint(C_B_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(C_B_2025_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2025_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(B_C_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(B_C_2020_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2020_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(B_2025_summer_night_NGCC_2020)_: ++1 v_flow_out(B_2025_summer_night_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2025_NGCC_2020) +<= 0 + +c_u_capacity_constraint(B_2025_winter_day_NGCC_2025)_: ++1 v_flow_out(B_2025_winter_day_NG_NGCC_2025_ELC) +-2.19 v_capacity(B_2025_NGCC_2025) +<= 0 + +c_u_capacity_constraint(B_C_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(B_C_2025_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2025_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(C_B_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(C_B_2025_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2025_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2025_summer_day_NGCC_2015)_: ++1 v_flow_out(A_2025_summer_day_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2025_summer_day_NGCC_2015) +<= 0 + +c_u_capacity_constraint(B_2025_summer_night_HEAT_SYS_2025)_: ++1 v_flow_out(B_2025_summer_night_ELC_HEAT_SYS_2025_HEAT) +-0.25 v_capacity(B_2025_HEAT_SYS_2025) +<= 0 + +c_u_capacity_constraint(A_B_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(A_B_2025_winter_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(B_A_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(B_A_2025_winter_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2025_summer_day_HEAT_SYS_2020)_: ++1 v_flow_out(A_2025_summer_day_ELC_HEAT_SYS_2020_HEAT) +-0.25 v_capacity(A_2025_HEAT_SYS_2020) +<= 0 + +c_u_capacity_constraint(B_2025_summer_day_HEAT_SYS_2025)_: ++1 v_flow_out(B_2025_summer_day_ELC_HEAT_SYS_2025_HEAT) +-0.25 v_capacity(B_2025_HEAT_SYS_2025) +<= 0 + +c_u_capacity_constraint(A_B_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(A_B_2020_winter_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_C_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(A_C_2020_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2020_E_TRANS_2015) +<= 0 + +c_e_capacity_constraint(A_2020_summer_day_SOLPV_2020)_: +-1 v_flow_out(A_2020_summer_day_ethos_SOLPV_2020_ELC) ++1.3139999999999998 v_capacity(A_2020_SOLPV_2020) +-1 v_curtailment(A_2020_summer_day_ethos_SOLPV_2020_ELC) += 0 + +c_e_capacity_constraint(A_2020_summer_night_SOLPV_2020)_: +-1 v_flow_out(A_2020_summer_night_ethos_SOLPV_2020_ELC) +-1 v_curtailment(A_2020_summer_night_ethos_SOLPV_2020_ELC) += 0.0 + +c_u_capacity_constraint(A_2020_winter_day_HEAT_SYS_2020)_: +-0.25 v_capacity(A_2020_HEAT_SYS_2020) +<= -1.25 + +c_u_capacity_constraint(C_A_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(C_A_2025_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2025_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(B_2025_winter_night_NGCC_2025)_: ++1 v_flow_out(B_2025_winter_night_NG_NGCC_2025_ELC) +-2.19 v_capacity(B_2025_NGCC_2025) +<= 0 + +c_e_capacity_constraint(A_2025_winter_day_SOLPV_2020)_: +-1 v_flow_out(A_2025_winter_day_ethos_SOLPV_2020_ELC) ++0.6569999999999999 v_capacity(A_2025_SOLPV_2020) +-1 v_curtailment(A_2025_winter_day_ethos_SOLPV_2020_ELC) += 0 + +c_u_capacity_constraint(A_2020_winter_night_NGCC_2015)_: ++1 v_flow_out(A_2020_winter_night_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2020_winter_night_NGCC_2015) +<= 0 + +c_u_capacity_constraint(A_2025_summer_night_NGCC_2025)_: ++1 v_flow_out(A_2025_summer_night_NG_NGCC_2025_ELC) +-0.219 v_uc_online(A_2025_summer_night_NGCC_2025) +<= 0 + +c_u_capacity_constraint(C_B_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(C_B_2020_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2020_E_TRANS_2015) +<= 0 + +c_e_capacity_constraint(A_2025_summer_night_SOLPV_2020)_: +-1 v_flow_out(A_2025_summer_night_ethos_SOLPV_2020_ELC) +-1 v_curtailment(A_2025_summer_night_ethos_SOLPV_2020_ELC) += 0.0 + +c_u_capacity_constraint(B_C_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(B_C_2020_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2020_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(B_A_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(B_A_2025_summer_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(B_A_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(B_A_2020_summer_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_capacity_constraint(A_2025_winter_night_NGCC_2025)_: ++1 v_flow_out(A_2025_winter_night_NG_NGCC_2025_ELC) +-0.219 v_uc_online(A_2025_winter_night_NGCC_2025) +<= 0 + +c_e_capacity_constraint(A_2025_winter_night_SOLPV_2020)_: +-1 v_flow_out(A_2025_winter_night_ethos_SOLPV_2020_ELC) +-1 v_curtailment(A_2025_winter_night_ethos_SOLPV_2020_ELC) += 0.0 + +c_u_capacity_constraint(C_2020_summer_day_HEAT_ANN_2020)_: +-0.25 v_capacity(C_2020_HEAT_ANN_2020) +<= -0.25 + +c_u_capacity_annual_constraint(C_2025_ANN_IMP_2020)_: +-1 v_capacity(C_2025_ANN_IMP_2020) ++1 v_flow_out_annual(C_2025_ethos_ANN_IMP_2020_ELC_C) +<= 0 + +c_u_capacity_annual_constraint(C_2020_ANN_IMP_2020)_: +-1 v_capacity(C_2020_ANN_IMP_2020) ++1 v_flow_out_annual(C_2020_ethos_ANN_IMP_2020_ELC_C) +<= 0 + +c_e_capacity_available_by_period_and_tech_constraint(A_2020_E_LDES)_: +-1 v_capacity(A_2020_E_LDES_2020) ++1 v_capacity_available_by_period_and_tech(A_2020_E_LDES) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(A_2020_SOLPV)_: +-1 v_capacity(A_2020_SOLPV_2015) +-1 v_capacity(A_2020_SOLPV_2020) ++1 v_capacity_available_by_period_and_tech(A_2020_SOLPV) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(C_B_2025_E_TRANS)_: +-1 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_capacity_available_by_period_and_tech(C_B_2025_E_TRANS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(B_2025_NGCC)_: +-1 v_capacity(B_2025_NGCC_2020) +-1 v_capacity(B_2025_NGCC_2025) +-1 v_capacity(B_2025_NGCC_2015) ++1 v_capacity_available_by_period_and_tech(B_2025_NGCC) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(C_A_2020_E_TRANS)_: +-1 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_capacity_available_by_period_and_tech(C_A_2020_E_TRANS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(A_B_2025_E_TRANS)_: +-1 v_capacity(A_B_2025_E_TRANS_2015) ++1 v_capacity_available_by_period_and_tech(A_B_2025_E_TRANS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(A_2020_HEAT_SYS)_: +-1 v_capacity(A_2020_HEAT_SYS_2020) ++1 v_capacity_available_by_period_and_tech(A_2020_HEAT_SYS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(B_2025_E_BATT)_: +-1 v_capacity(B_2025_E_BATT_2025) +-1 v_capacity(B_2025_E_BATT_2020) ++1 v_capacity_available_by_period_and_tech(B_2025_E_BATT) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(C_2020_ANN_IMP)_: +-1 v_capacity(C_2020_ANN_IMP_2020) ++1 v_capacity_available_by_period_and_tech(C_2020_ANN_IMP) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(C_B_2020_E_TRANS)_: +-1 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_capacity_available_by_period_and_tech(C_B_2020_E_TRANS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(B_2020_NGCC)_: +-1 v_capacity(B_2020_NGCC_2015) +-1 v_capacity(B_2020_NGCC_2020) ++1 v_capacity_available_by_period_and_tech(B_2020_NGCC) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(B_2025_E_LDES)_: +-1 v_capacity(B_2025_E_LDES_2020) +-1 v_capacity(B_2025_E_LDES_2025) ++1 v_capacity_available_by_period_and_tech(B_2025_E_LDES) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(A_C_2025_E_TRANS)_: +-1 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_capacity_available_by_period_and_tech(A_C_2025_E_TRANS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(A_B_2020_E_TRANS)_: +-1 v_capacity(A_B_2020_E_TRANS_2015) ++1 v_capacity_available_by_period_and_tech(A_B_2020_E_TRANS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(B_2020_E_BATT)_: +-1 v_capacity(B_2020_E_BATT_2020) ++1 v_capacity_available_by_period_and_tech(B_2020_E_BATT) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(B_2025_HEAT_SYS)_: +-1 v_capacity(B_2025_HEAT_SYS_2025) +-1 v_capacity(B_2025_HEAT_SYS_2020) ++1 v_capacity_available_by_period_and_tech(B_2025_HEAT_SYS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(A_2025_NGCC)_: +-1 v_capacity(A_2025_NGCC_2025) +-1 v_capacity(A_2025_NGCC_2015) +-1 v_capacity(A_2025_NGCC_2020) ++1 v_capacity_available_by_period_and_tech(A_2025_NGCC) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(B_C_2025_E_TRANS)_: +-1 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_capacity_available_by_period_and_tech(B_C_2025_E_TRANS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(B_A_2025_E_TRANS)_: +-1 v_capacity(B_A_2025_E_TRANS_2015) ++1 v_capacity_available_by_period_and_tech(B_A_2025_E_TRANS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(A_2025_E_BATT)_: +-1 v_capacity(A_2025_E_BATT_2025) +-1 v_capacity(A_2025_E_BATT_2020) ++1 v_capacity_available_by_period_and_tech(A_2025_E_BATT) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(B_2020_E_LDES)_: +-1 v_capacity(B_2020_E_LDES_2020) ++1 v_capacity_available_by_period_and_tech(B_2020_E_LDES) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(A_C_2020_E_TRANS)_: +-1 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_capacity_available_by_period_and_tech(A_C_2020_E_TRANS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(C_2025_HEAT_ANN)_: +-1 v_capacity(C_2025_HEAT_ANN_2020) ++1 v_capacity_available_by_period_and_tech(C_2025_HEAT_ANN) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(B_2020_HEAT_SYS)_: +-1 v_capacity(B_2020_HEAT_SYS_2020) ++1 v_capacity_available_by_period_and_tech(B_2020_HEAT_SYS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(A_2025_E_LDES)_: +-1 v_capacity(A_2025_E_LDES_2020) +-1 v_capacity(A_2025_E_LDES_2025) ++1 v_capacity_available_by_period_and_tech(A_2025_E_LDES) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(A_2025_SOLPV)_: +-1 v_capacity(A_2025_SOLPV_2020) +-1 v_capacity(A_2025_SOLPV_2025) +-1 v_capacity(A_2025_SOLPV_2015) ++1 v_capacity_available_by_period_and_tech(A_2025_SOLPV) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(A_2020_NGCC)_: +-1 v_capacity(A_2020_NGCC_2015) +-1 v_capacity(A_2020_NGCC_2020) ++1 v_capacity_available_by_period_and_tech(A_2020_NGCC) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(B_C_2020_E_TRANS)_: +-1 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_capacity_available_by_period_and_tech(B_C_2020_E_TRANS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(B_A_2020_E_TRANS)_: +-1 v_capacity(B_A_2020_E_TRANS_2015) ++1 v_capacity_available_by_period_and_tech(B_A_2020_E_TRANS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(C_A_2025_E_TRANS)_: +-1 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_capacity_available_by_period_and_tech(C_A_2025_E_TRANS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(A_2020_E_BATT)_: +-1 v_capacity(A_2020_E_BATT_2020) ++1 v_capacity_available_by_period_and_tech(A_2020_E_BATT) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(A_2025_HEAT_SYS)_: +-1 v_capacity(A_2025_HEAT_SYS_2025) +-1 v_capacity(A_2025_HEAT_SYS_2020) ++1 v_capacity_available_by_period_and_tech(A_2025_HEAT_SYS) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(C_2020_HEAT_ANN)_: +-1 v_capacity(C_2020_HEAT_ANN_2020) ++1 v_capacity_available_by_period_and_tech(C_2020_HEAT_ANN) += 0 + +c_e_capacity_available_by_period_and_tech_constraint(C_2025_ANN_IMP)_: +-1 v_capacity(C_2025_ANN_IMP_2020) ++1 v_capacity_available_by_period_and_tech(C_2025_ANN_IMP) += 0 + +c_e_adjusted_capacity_constraint(A_2025_E_BATT_2025)_: ++1 v_capacity(A_2025_E_BATT_2025) +-1 v_new_capacity(A_E_BATT_2025) += 0 + +c_e_adjusted_capacity_constraint(B_2020_E_LDES_2020)_: ++1 v_capacity(B_2020_E_LDES_2020) +-1 v_new_capacity(B_E_LDES_2020) += 0 + +c_e_adjusted_capacity_constraint(B_C_2020_E_TRANS_2015)_: ++1 v_capacity(B_C_2020_E_TRANS_2015) += 1.0 + +c_e_adjusted_capacity_constraint(A_2020_NGCC_2015)_: ++1 v_capacity(A_2020_NGCC_2015) += 0.5 + +c_e_adjusted_capacity_constraint(A_2025_HEAT_SYS_2025)_: ++1 v_capacity(A_2025_HEAT_SYS_2025) +-1 v_new_capacity(A_HEAT_SYS_2025) += 0 + +c_e_adjusted_capacity_constraint(A_2020_E_BATT_2020)_: ++1 v_capacity(A_2020_E_BATT_2020) +-1 v_new_capacity(A_E_BATT_2020) += 0 + +c_e_adjusted_capacity_constraint(B_2025_NGCC_2020)_: ++1 v_capacity(B_2025_NGCC_2020) +-1 v_new_capacity(B_NGCC_2020) += 0 + +c_e_adjusted_capacity_constraint(A_C_2025_E_TRANS_2015)_: ++1 v_capacity(A_C_2025_E_TRANS_2015) += 1.0 + +c_e_adjusted_capacity_constraint(C_2025_HEAT_ANN_2020)_: ++1 v_capacity(C_2025_HEAT_ANN_2020) +-1 v_new_capacity(C_HEAT_ANN_2020) += 0 + +c_e_adjusted_capacity_constraint(C_2025_ANN_IMP_2020)_: ++1 v_capacity(C_2025_ANN_IMP_2020) +-1 v_new_capacity(C_ANN_IMP_2020) += 0 + +c_e_adjusted_capacity_constraint(A_2025_NGCC_2025)_: ++1 v_capacity(A_2025_NGCC_2025) +-1 v_new_capacity(A_NGCC_2025) += 0 + +c_e_adjusted_capacity_constraint(C_B_2020_E_TRANS_2015)_: ++1 v_capacity(C_B_2020_E_TRANS_2015) += 1.0 + +c_e_adjusted_capacity_constraint(A_2025_SOLPV_2020)_: ++1 v_capacity(A_2025_SOLPV_2020) +-1 v_new_capacity(A_SOLPV_2020) += 0 + +c_e_adjusted_capacity_constraint(B_2025_E_BATT_2025)_: ++1 v_capacity(B_2025_E_BATT_2025) +-1 v_new_capacity(B_E_BATT_2025) += 0 + +c_e_adjusted_capacity_constraint(A_2020_HEAT_SYS_2020)_: ++1 v_capacity(A_2020_HEAT_SYS_2020) +-1 v_new_capacity(A_HEAT_SYS_2020) += 0 + +c_e_adjusted_capacity_constraint(B_2025_HEAT_SYS_2025)_: ++1 v_capacity(B_2025_HEAT_SYS_2025) +-1 v_new_capacity(B_HEAT_SYS_2025) += 0 + +c_e_adjusted_capacity_constraint(A_2025_E_LDES_2020)_: ++1 v_capacity(A_2025_E_LDES_2020) +-1 v_new_capacity(A_E_LDES_2020) += 0 + +c_e_adjusted_capacity_constraint(B_2020_E_BATT_2020)_: ++1 v_capacity(B_2020_E_BATT_2020) +-1 v_new_capacity(B_E_BATT_2020) += 0 + +c_e_adjusted_capacity_constraint(B_2020_NGCC_2015)_: ++1 v_capacity(B_2020_NGCC_2015) += 0.3 + +c_e_adjusted_capacity_constraint(C_A_2025_E_TRANS_2015)_: ++1 v_capacity(C_A_2025_E_TRANS_2015) += 1.0 + +c_e_adjusted_capacity_constraint(A_B_2025_E_TRANS_2015)_: ++1 v_capacity(A_B_2025_E_TRANS_2015) += 1.0 + +c_e_adjusted_capacity_constraint(B_A_2020_E_TRANS_2015)_: ++1 v_capacity(B_A_2020_E_TRANS_2015) += 1.0 + +c_e_adjusted_capacity_constraint(A_2020_NGCC_2020)_: ++1 v_capacity(A_2020_NGCC_2020) +-1 v_new_capacity(A_NGCC_2020) += 0 + +c_e_adjusted_capacity_constraint(B_2025_E_LDES_2020)_: ++1 v_capacity(B_2025_E_LDES_2020) +-1 v_new_capacity(B_E_LDES_2020) += 0 + +c_e_adjusted_capacity_constraint(A_2020_SOLPV_2015)_: ++1 v_capacity(A_2020_SOLPV_2015) += 0.2 + +c_e_adjusted_capacity_constraint(A_2025_NGCC_2015)_: ++1 v_capacity(A_2025_NGCC_2015) += 0.5 + +c_e_adjusted_capacity_constraint(B_2025_NGCC_2025)_: ++1 v_capacity(B_2025_NGCC_2025) +-1 v_new_capacity(B_NGCC_2025) += 0 + +c_e_adjusted_capacity_constraint(B_2020_HEAT_SYS_2020)_: ++1 v_capacity(B_2020_HEAT_SYS_2020) +-1 v_new_capacity(B_HEAT_SYS_2020) += 0 + +c_e_adjusted_capacity_constraint(C_2020_HEAT_ANN_2020)_: ++1 v_capacity(C_2020_HEAT_ANN_2020) +-1 v_new_capacity(C_HEAT_ANN_2020) += 0 + +c_e_adjusted_capacity_constraint(A_C_2020_E_TRANS_2015)_: ++1 v_capacity(A_C_2020_E_TRANS_2015) += 1.0 + +c_e_adjusted_capacity_constraint(A_2025_SOLPV_2025)_: ++1 v_capacity(A_2025_SOLPV_2025) +-1 v_new_capacity(A_SOLPV_2025) += 0 + +c_e_adjusted_capacity_constraint(B_C_2025_E_TRANS_2015)_: ++1 v_capacity(B_C_2025_E_TRANS_2015) += 1.0 + +c_e_adjusted_capacity_constraint(A_2025_E_BATT_2020)_: ++1 v_capacity(A_2025_E_BATT_2020) +-1 v_new_capacity(A_E_BATT_2020) += 0 + +c_e_adjusted_capacity_constraint(A_2025_E_LDES_2025)_: ++1 v_capacity(A_2025_E_LDES_2025) +-1 v_new_capacity(A_E_LDES_2025) += 0 + +c_e_adjusted_capacity_constraint(A_2025_HEAT_SYS_2020)_: ++1 v_capacity(A_2025_HEAT_SYS_2020) +-1 v_new_capacity(A_HEAT_SYS_2020) += 0 + +c_e_adjusted_capacity_constraint(B_2020_NGCC_2020)_: ++1 v_capacity(B_2020_NGCC_2020) +-1 v_new_capacity(B_NGCC_2020) += 0 + +c_e_adjusted_capacity_constraint(A_2020_E_LDES_2020)_: ++1 v_capacity(A_2020_E_LDES_2020) +-1 v_new_capacity(A_E_LDES_2020) += 0 + +c_e_adjusted_capacity_constraint(B_2025_NGCC_2015)_: ++1 v_capacity(B_2025_NGCC_2015) += 0.3 + +c_e_adjusted_capacity_constraint(C_2020_ANN_IMP_2020)_: ++1 v_capacity(C_2020_ANN_IMP_2020) +-1 v_new_capacity(C_ANN_IMP_2020) += 0 + +c_e_adjusted_capacity_constraint(A_B_2020_E_TRANS_2015)_: ++1 v_capacity(A_B_2020_E_TRANS_2015) += 1.0 + +c_e_adjusted_capacity_constraint(A_2020_SOLPV_2020)_: ++1 v_capacity(A_2020_SOLPV_2020) +-1 v_new_capacity(A_SOLPV_2020) += 0 + +c_e_adjusted_capacity_constraint(B_2025_E_LDES_2025)_: ++1 v_capacity(B_2025_E_LDES_2025) +-1 v_new_capacity(B_E_LDES_2025) += 0 + +c_e_adjusted_capacity_constraint(B_A_2025_E_TRANS_2015)_: ++1 v_capacity(B_A_2025_E_TRANS_2015) += 1.0 + +c_e_adjusted_capacity_constraint(C_B_2025_E_TRANS_2015)_: ++1 v_capacity(C_B_2025_E_TRANS_2015) += 1.0 + +c_e_adjusted_capacity_constraint(A_2025_NGCC_2020)_: ++1 v_capacity(A_2025_NGCC_2020) +-1 v_new_capacity(A_NGCC_2020) += 0 + +c_e_adjusted_capacity_constraint(A_2025_SOLPV_2015)_: ++1 v_capacity(A_2025_SOLPV_2015) += 0.2 + +c_e_adjusted_capacity_constraint(C_A_2020_E_TRANS_2015)_: ++1 v_capacity(C_A_2020_E_TRANS_2015) += 1.0 + +c_e_adjusted_capacity_constraint(B_2025_E_BATT_2020)_: ++1 v_capacity(B_2025_E_BATT_2020) +-1 v_new_capacity(B_E_BATT_2020) += 0 + +c_e_adjusted_capacity_constraint(B_2025_HEAT_SYS_2020)_: ++1 v_capacity(B_2025_HEAT_SYS_2020) +-1 v_new_capacity(B_HEAT_SYS_2020) += 0 + +c_e_demand_constraint(A_2025_HEAT)_: ++1 v_flow_out_annual(A_2025_ELC_HEAT_SYS_2025_HEAT) ++1 v_flow_out_annual(A_2025_ELC_HEAT_SYS_2020_HEAT) += 5.5 + +c_e_demand_constraint(B_2025_HEAT)_: ++1 v_flow_out_annual(B_2025_ELC_HEAT_SYS_2025_HEAT) ++1 v_flow_out_annual(B_2025_ELC_HEAT_SYS_2020_HEAT) += 3.3 + +c_e_demand_activity_constraint(A_2025_winter_day_HEAT_SYS_2025_HEAT)_: +-1 v_flow_out(A_2025_winter_day_ELC_HEAT_SYS_2025_HEAT) ++0.25 v_flow_out_annual(A_2025_ELC_HEAT_SYS_2025_HEAT) += 0 + +c_e_demand_activity_constraint(A_2025_winter_day_HEAT_SYS_2020_HEAT)_: +-1 v_flow_out(A_2025_winter_day_ELC_HEAT_SYS_2020_HEAT) ++0.25 v_flow_out_annual(A_2025_ELC_HEAT_SYS_2020_HEAT) += 0 + +c_e_demand_activity_constraint(B_2025_summer_night_HEAT_SYS_2020_HEAT)_: +-1 v_flow_out(B_2025_summer_night_ELC_HEAT_SYS_2020_HEAT) ++0.25 v_flow_out_annual(B_2025_ELC_HEAT_SYS_2020_HEAT) += 0 + +c_e_demand_activity_constraint(B_2025_summer_night_HEAT_SYS_2025_HEAT)_: +-1 v_flow_out(B_2025_summer_night_ELC_HEAT_SYS_2025_HEAT) ++0.25 v_flow_out_annual(B_2025_ELC_HEAT_SYS_2025_HEAT) += 0 + +c_e_demand_activity_constraint(A_2025_summer_day_HEAT_SYS_2025_HEAT)_: +-1 v_flow_out(A_2025_summer_day_ELC_HEAT_SYS_2025_HEAT) ++0.25 v_flow_out_annual(A_2025_ELC_HEAT_SYS_2025_HEAT) += 0 + +c_e_demand_activity_constraint(A_2025_summer_day_HEAT_SYS_2020_HEAT)_: +-1 v_flow_out(A_2025_summer_day_ELC_HEAT_SYS_2020_HEAT) ++0.25 v_flow_out_annual(A_2025_ELC_HEAT_SYS_2020_HEAT) += 0 + +c_e_demand_activity_constraint(A_2025_summer_night_HEAT_SYS_2020_HEAT)_: +-1 v_flow_out(A_2025_summer_night_ELC_HEAT_SYS_2020_HEAT) ++0.25 v_flow_out_annual(A_2025_ELC_HEAT_SYS_2020_HEAT) += 0 + +c_e_demand_activity_constraint(A_2025_summer_night_HEAT_SYS_2025_HEAT)_: +-1 v_flow_out(A_2025_summer_night_ELC_HEAT_SYS_2025_HEAT) ++0.25 v_flow_out_annual(A_2025_ELC_HEAT_SYS_2025_HEAT) += 0 + +c_e_demand_activity_constraint(B_2025_winter_day_HEAT_SYS_2025_HEAT)_: +-1 v_flow_out(B_2025_winter_day_ELC_HEAT_SYS_2025_HEAT) ++0.25 v_flow_out_annual(B_2025_ELC_HEAT_SYS_2025_HEAT) += 0 + +c_e_demand_activity_constraint(B_2025_winter_day_HEAT_SYS_2020_HEAT)_: +-1 v_flow_out(B_2025_winter_day_ELC_HEAT_SYS_2020_HEAT) ++0.25 v_flow_out_annual(B_2025_ELC_HEAT_SYS_2020_HEAT) += 0 + +c_e_demand_activity_constraint(B_2025_summer_day_HEAT_SYS_2020_HEAT)_: +-1 v_flow_out(B_2025_summer_day_ELC_HEAT_SYS_2020_HEAT) ++0.25 v_flow_out_annual(B_2025_ELC_HEAT_SYS_2020_HEAT) += 0 + +c_e_demand_activity_constraint(B_2025_winter_night_HEAT_SYS_2025_HEAT)_: +-1 v_flow_out(B_2025_winter_night_ELC_HEAT_SYS_2025_HEAT) ++0.25 v_flow_out_annual(B_2025_ELC_HEAT_SYS_2025_HEAT) += 0 + +c_e_demand_activity_constraint(B_2025_winter_night_HEAT_SYS_2020_HEAT)_: +-1 v_flow_out(B_2025_winter_night_ELC_HEAT_SYS_2020_HEAT) ++0.25 v_flow_out_annual(B_2025_ELC_HEAT_SYS_2020_HEAT) += 0 + +c_e_demand_activity_constraint(A_2025_winter_night_HEAT_SYS_2025_HEAT)_: +-1 v_flow_out(A_2025_winter_night_ELC_HEAT_SYS_2025_HEAT) ++0.25 v_flow_out_annual(A_2025_ELC_HEAT_SYS_2025_HEAT) += 0 + +c_e_demand_activity_constraint(A_2025_winter_night_HEAT_SYS_2020_HEAT)_: +-1 v_flow_out(A_2025_winter_night_ELC_HEAT_SYS_2020_HEAT) ++0.25 v_flow_out_annual(A_2025_ELC_HEAT_SYS_2020_HEAT) += 0 + +c_e_demand_activity_constraint(B_2025_summer_day_HEAT_SYS_2025_HEAT)_: +-1 v_flow_out(B_2025_summer_day_ELC_HEAT_SYS_2025_HEAT) ++0.25 v_flow_out_annual(B_2025_ELC_HEAT_SYS_2025_HEAT) += 0 + +c_e_commodity_balance_constraint(C_2025_summer_day_ELC)_: ++1 v_flow_out(B_C_2025_summer_day_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(C_A_2025_summer_day_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(C_B_2025_summer_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_C_2025_summer_day_ELC_E_TRANS_2015_ELC) += 0 + +c_e_commodity_balance_constraint(C_2020_winter_day_ELC)_: +-1.0526315789473684 v_flow_out(C_A_2020_winter_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_C_2020_winter_day_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(C_B_2020_winter_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_C_2020_winter_day_ELC_E_TRANS_2015_ELC) += 0 + +c_e_commodity_balance_constraint(B_2020_summer_night_NG)_: +-1.8181818181818181 v_flow_out(B_2020_summer_night_NG_NGCC_2020_ELC) ++1 v_flow_out(B_2020_summer_night_ethos_IMP_NG_2020_NG) +-1.8181818181818181 v_flow_out(B_2020_summer_night_NG_NGCC_2015_ELC) += 0 + +c_e_commodity_balance_constraint(B_2020_winter_night_ELC)_: ++1 v_flow_out(A_B_2020_winter_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2020_winter_night_NG_NGCC_2015_ELC) ++1 v_flow_out(B_2020_winter_night_ELC_E_BATT_2020_ELC) +-1.0526315789473684 v_flow_out(B_C_2020_winter_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2020_winter_night_ELC_E_LDES_2020_ELC) ++1 v_flow_out(C_B_2020_winter_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2020_winter_night_NG_NGCC_2020_ELC) +-1.0526315789473684 v_flow_out(B_A_2020_winter_night_ELC_E_TRANS_2015_ELC) +-1 v_flow_in(B_2020_winter_night_ELC_E_BATT_2020_ELC) +-1 v_flow_in(B_2020_winter_night_ELC_E_LDES_2020_ELC) += 0.75 + +c_e_commodity_balance_constraint(A_2025_summer_night_ELC)_: ++1 v_flow_out(A_2025_summer_night_ethos_SOLPV_2020_ELC) +-1.0526315789473684 v_flow_out(A_B_2025_summer_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2025_summer_night_NG_NGCC_2025_ELC) ++1 v_flow_out(A_2025_summer_night_ethos_SOLPV_2025_ELC) ++1 v_flow_out(A_2025_summer_night_NG_NGCC_2015_ELC) +-1 v_flow_out(A_2025_summer_night_ELC_HEAT_SYS_2020_HEAT) ++1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2020_ELC) ++1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2020_ELC) ++1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2025_ELC) ++1 v_flow_out(A_2025_summer_night_ethos_SOLPV_2015_ELC) ++1 v_flow_out(A_2025_summer_night_NG_NGCC_2020_ELC) ++1 v_flow_out(B_A_2025_summer_night_ELC_E_TRANS_2015_ELC) +-1 v_flow_out(A_2025_summer_night_ELC_HEAT_SYS_2025_HEAT) ++1 v_flow_out(C_A_2025_summer_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2025_ELC) +-1.0526315789473684 v_flow_out(A_C_2025_summer_night_ELC_E_TRANS_2015_ELC) +-1 v_flow_in(A_2025_summer_night_ELC_E_BATT_2025_ELC) +-1 v_flow_in(A_2025_summer_night_ELC_E_LDES_2025_ELC) +-1 v_flow_in(A_2025_summer_night_ELC_E_BATT_2020_ELC) +-1 v_flow_in(A_2025_summer_night_ELC_E_LDES_2020_ELC) += 0 + +c_e_commodity_balance_constraint(B_2025_winter_night_ELC)_: ++1 v_flow_out(A_B_2025_winter_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(C_B_2025_winter_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2025_winter_night_NG_NGCC_2025_ELC) ++1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2020_ELC) ++1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2020_ELC) ++1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2025_ELC) +-1 v_flow_out(B_2025_winter_night_ELC_HEAT_SYS_2020_HEAT) ++1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2025_ELC) ++1 v_flow_out(B_2025_winter_night_NG_NGCC_2015_ELC) +-1.0526315789473684 v_flow_out(B_A_2025_winter_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2025_winter_night_NG_NGCC_2020_ELC) +-1.0526315789473684 v_flow_out(B_C_2025_winter_night_ELC_E_TRANS_2015_ELC) +-1 v_flow_out(B_2025_winter_night_ELC_HEAT_SYS_2025_HEAT) +-1 v_flow_in(B_2025_winter_night_ELC_E_LDES_2025_ELC) +-1 v_flow_in(B_2025_winter_night_ELC_E_LDES_2020_ELC) +-1 v_flow_in(B_2025_winter_night_ELC_E_BATT_2025_ELC) +-1 v_flow_in(B_2025_winter_night_ELC_E_BATT_2020_ELC) += 0 + +c_e_commodity_balance_constraint(C_2025_winter_day_ELC)_: ++1 v_flow_out(A_C_2025_winter_day_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(C_A_2025_winter_day_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(C_B_2025_winter_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_C_2025_winter_day_ELC_E_TRANS_2015_ELC) += 0 + +c_e_commodity_balance_constraint(B_2025_summer_day_NG)_: +-1.8181818181818181 v_flow_out(B_2025_summer_day_NG_NGCC_2025_ELC) +-1.8181818181818181 v_flow_out(B_2025_summer_day_NG_NGCC_2015_ELC) ++1 v_flow_out(B_2025_summer_day_ethos_IMP_NG_2020_NG) +-1.8181818181818181 v_flow_out(B_2025_summer_day_NG_NGCC_2020_ELC) += 0 + +c_e_commodity_balance_constraint(B_2020_summer_day_ELC)_: ++1 v_flow_out(B_2020_summer_day_NG_NGCC_2020_ELC) ++1 v_flow_out(C_B_2020_summer_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2020_summer_day_ELC_E_LDES_2020_ELC) +-1.0526315789473684 v_flow_out(B_C_2020_summer_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2020_summer_day_ELC_E_BATT_2020_ELC) ++1 v_flow_out(B_2020_summer_day_NG_NGCC_2015_ELC) +-1.0526315789473684 v_flow_out(B_A_2020_summer_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_B_2020_summer_day_ELC_E_TRANS_2015_ELC) +-1 v_flow_in(B_2020_summer_day_ELC_E_LDES_2020_ELC) +-1 v_flow_in(B_2020_summer_day_ELC_E_BATT_2020_ELC) += 0.75 + +c_e_commodity_balance_constraint(A_2020_winter_night_ELC)_: ++1 v_flow_out(C_A_2020_winter_night_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(A_B_2020_winter_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2020_winter_night_ethos_SOLPV_2020_ELC) ++1 v_flow_out(A_2020_winter_night_ELC_E_BATT_2020_ELC) ++1 v_flow_out(A_2020_winter_night_NG_NGCC_2020_ELC) +-1.0526315789473684 v_flow_out(A_C_2020_winter_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2020_winter_night_ELC_E_LDES_2020_ELC) ++1 v_flow_out(A_2020_winter_night_NG_NGCC_2015_ELC) ++1 v_flow_out(A_2020_winter_night_ethos_SOLPV_2015_ELC) ++1 v_flow_out(B_A_2020_winter_night_ELC_E_TRANS_2015_ELC) +-1 v_flow_in(A_2020_winter_night_ELC_E_BATT_2020_ELC) +-1 v_flow_in(A_2020_winter_night_ELC_E_LDES_2020_ELC) += 1.25 + +c_e_commodity_balance_constraint(A_2025_winter_night_NG)_: +-1.8181818181818181 v_flow_out(A_2025_winter_night_NG_NGCC_2015_ELC) +-1.8181818181818181 v_flow_out(A_2025_winter_night_NG_NGCC_2020_ELC) ++1 v_flow_out(A_2025_winter_night_ethos_IMP_NG_2020_NG) +-1.8181818181818181 v_flow_out(A_2025_winter_night_NG_NGCC_2025_ELC) += 0 + +c_e_commodity_balance_constraint(B_2020_winter_day_NG)_: ++1 v_flow_out(B_2020_winter_day_ethos_IMP_NG_2020_NG) +-1.8181818181818181 v_flow_out(B_2020_winter_day_NG_NGCC_2015_ELC) +-1.8181818181818181 v_flow_out(B_2020_winter_day_NG_NGCC_2020_ELC) += 0 + +c_e_commodity_balance_constraint(A_2025_winter_day_ELC)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2025_ELC) ++1 v_flow_out(B_A_2025_winter_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2025_winter_day_NG_NGCC_2020_ELC) ++1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2025_ELC) +-1 v_flow_out(A_2025_winter_day_ELC_HEAT_SYS_2020_HEAT) ++1 v_flow_out(A_2025_winter_day_NG_NGCC_2025_ELC) +-1.0526315789473684 v_flow_out(A_C_2025_winter_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2025_winter_day_ethos_SOLPV_2025_ELC) ++1 v_flow_out(C_A_2025_winter_day_ELC_E_TRANS_2015_ELC) +-1 v_flow_out(A_2025_winter_day_ELC_HEAT_SYS_2025_HEAT) ++1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2020_ELC) ++1 v_flow_out(A_2025_winter_day_NG_NGCC_2015_ELC) +-1.0526315789473684 v_flow_out(A_B_2025_winter_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2025_winter_day_ethos_SOLPV_2015_ELC) ++1 v_flow_out(A_2025_winter_day_ethos_SOLPV_2020_ELC) ++1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2020_ELC) +-1 v_flow_in(A_2025_winter_day_ELC_E_LDES_2025_ELC) +-1 v_flow_in(A_2025_winter_day_ELC_E_BATT_2025_ELC) +-1 v_flow_in(A_2025_winter_day_ELC_E_LDES_2020_ELC) +-1 v_flow_in(A_2025_winter_day_ELC_E_BATT_2020_ELC) += 0 + +c_e_commodity_balance_constraint(B_2025_winter_day_NG)_: +-1.8181818181818181 v_flow_out(B_2025_winter_day_NG_NGCC_2015_ELC) ++1 v_flow_out(B_2025_winter_day_ethos_IMP_NG_2020_NG) +-1.8181818181818181 v_flow_out(B_2025_winter_day_NG_NGCC_2020_ELC) +-1.8181818181818181 v_flow_out(B_2025_winter_day_NG_NGCC_2025_ELC) += 0 + +c_e_commodity_balance_constraint(A_2020_summer_night_NG)_: +-1.8181818181818181 v_flow_out(A_2020_summer_night_NG_NGCC_2015_ELC) ++1 v_flow_out(A_2020_summer_night_ethos_IMP_NG_2020_NG) +-1.8181818181818181 v_flow_out(A_2020_summer_night_NG_NGCC_2020_ELC) += 0 + +c_e_commodity_balance_constraint(C_2025_summer_night_ELC)_: +-1.0526315789473684 v_flow_out(C_B_2025_summer_night_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(C_A_2025_summer_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_C_2025_summer_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_C_2025_summer_night_ELC_E_TRANS_2015_ELC) += 0 + +c_e_commodity_balance_constraint(A_2020_summer_day_ELC)_: ++1 v_flow_out(A_2020_summer_day_NG_NGCC_2015_ELC) ++1 v_flow_out(A_2020_summer_day_ethos_SOLPV_2020_ELC) ++1 v_flow_out(A_2020_summer_day_NG_NGCC_2020_ELC) ++1 v_flow_out(A_2020_summer_day_ethos_SOLPV_2015_ELC) +-1.0526315789473684 v_flow_out(A_C_2020_summer_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2020_summer_day_ELC_E_BATT_2020_ELC) ++1 v_flow_out(A_2020_summer_day_ELC_E_LDES_2020_ELC) ++1 v_flow_out(B_A_2020_summer_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(C_A_2020_summer_day_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(A_B_2020_summer_day_ELC_E_TRANS_2015_ELC) +-1 v_flow_in(A_2020_summer_day_ELC_E_LDES_2020_ELC) +-1 v_flow_in(A_2020_summer_day_ELC_E_BATT_2020_ELC) += 1.25 + +c_e_commodity_balance_constraint(A_2025_summer_day_NG)_: +-1.8181818181818181 v_flow_out(A_2025_summer_day_NG_NGCC_2015_ELC) +-1.8181818181818181 v_flow_out(A_2025_summer_day_NG_NGCC_2020_ELC) ++1 v_flow_out(A_2025_summer_day_ethos_IMP_NG_2020_NG) +-1.8181818181818181 v_flow_out(A_2025_summer_day_NG_NGCC_2025_ELC) += 0 + +c_e_commodity_balance_constraint(A_2020_winter_day_NG)_: +-1.8181818181818181 v_flow_out(A_2020_winter_day_NG_NGCC_2020_ELC) ++1 v_flow_out(A_2020_winter_day_ethos_IMP_NG_2020_NG) +-1.8181818181818181 v_flow_out(A_2020_winter_day_NG_NGCC_2015_ELC) += 0 + +c_e_commodity_balance_constraint(B_2020_summer_night_ELC)_: +-1.0526315789473684 v_flow_out(B_A_2020_summer_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_B_2020_summer_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2020_summer_night_NG_NGCC_2020_ELC) ++1 v_flow_out(B_2020_summer_night_ELC_E_LDES_2020_ELC) +-1.0526315789473684 v_flow_out(B_C_2020_summer_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(C_B_2020_summer_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2020_summer_night_ELC_E_BATT_2020_ELC) ++1 v_flow_out(B_2020_summer_night_NG_NGCC_2015_ELC) +-1 v_flow_in(B_2020_summer_night_ELC_E_BATT_2020_ELC) +-1 v_flow_in(B_2020_summer_night_ELC_E_LDES_2020_ELC) += 0.75 + +c_e_commodity_balance_constraint(B_2025_summer_night_NG)_: +-1.8181818181818181 v_flow_out(B_2025_summer_night_NG_NGCC_2015_ELC) +-1.8181818181818181 v_flow_out(B_2025_summer_night_NG_NGCC_2020_ELC) +-1.8181818181818181 v_flow_out(B_2025_summer_night_NG_NGCC_2025_ELC) ++1 v_flow_out(B_2025_summer_night_ethos_IMP_NG_2020_NG) += 0 + +c_e_commodity_balance_constraint(C_2020_winter_night_ELC)_: +-1.0526315789473684 v_flow_out(C_A_2020_winter_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_C_2020_winter_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_C_2020_winter_night_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(C_B_2020_winter_night_ELC_E_TRANS_2015_ELC) += 0 + +c_e_commodity_balance_constraint(C_2020_summer_day_ELC)_: +-1.0526315789473684 v_flow_out(C_B_2020_summer_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_C_2020_summer_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_C_2020_summer_day_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(C_A_2020_summer_day_ELC_E_TRANS_2015_ELC) += 0 + +c_e_commodity_balance_constraint(C_2025_winter_night_ELC)_: +-1.0526315789473684 v_flow_out(C_B_2025_winter_night_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(C_A_2025_winter_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_C_2025_winter_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_C_2025_winter_night_ELC_E_TRANS_2015_ELC) += 0 + +c_e_commodity_balance_constraint(B_2020_winter_night_NG)_: +-1.8181818181818181 v_flow_out(B_2020_winter_night_NG_NGCC_2015_ELC) ++1 v_flow_out(B_2020_winter_night_ethos_IMP_NG_2020_NG) +-1.8181818181818181 v_flow_out(B_2020_winter_night_NG_NGCC_2020_ELC) += 0 + +c_e_commodity_balance_constraint(A_2025_summer_night_NG)_: +-1.8181818181818181 v_flow_out(A_2025_summer_night_NG_NGCC_2025_ELC) +-1.8181818181818181 v_flow_out(A_2025_summer_night_NG_NGCC_2015_ELC) ++1 v_flow_out(A_2025_summer_night_ethos_IMP_NG_2020_NG) +-1.8181818181818181 v_flow_out(A_2025_summer_night_NG_NGCC_2020_ELC) += 0 + +c_e_commodity_balance_constraint(A_2025_winter_night_ELC)_: ++1 v_flow_out(A_2025_winter_night_ethos_SOLPV_2025_ELC) ++1 v_flow_out(A_2025_winter_night_NG_NGCC_2015_ELC) ++1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2020_ELC) ++1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2020_ELC) +-1.0526315789473684 v_flow_out(A_B_2025_winter_night_ELC_E_TRANS_2015_ELC) +-1 v_flow_out(A_2025_winter_night_ELC_HEAT_SYS_2025_HEAT) ++1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2025_ELC) +-1 v_flow_out(A_2025_winter_night_ELC_HEAT_SYS_2020_HEAT) ++1 v_flow_out(A_2025_winter_night_ethos_SOLPV_2015_ELC) ++1 v_flow_out(A_2025_winter_night_NG_NGCC_2020_ELC) ++1 v_flow_out(A_2025_winter_night_ethos_SOLPV_2020_ELC) ++1 v_flow_out(C_A_2025_winter_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2025_ELC) ++1 v_flow_out(B_A_2025_winter_night_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(A_C_2025_winter_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2025_winter_night_NG_NGCC_2025_ELC) +-1 v_flow_in(A_2025_winter_night_ELC_E_BATT_2025_ELC) +-1 v_flow_in(A_2025_winter_night_ELC_E_LDES_2020_ELC) +-1 v_flow_in(A_2025_winter_night_ELC_E_BATT_2020_ELC) +-1 v_flow_in(A_2025_winter_night_ELC_E_LDES_2025_ELC) += 0 + +c_e_commodity_balance_constraint(B_2025_summer_day_ELC)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2020_ELC) ++1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2020_ELC) ++1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2025_ELC) +-1 v_flow_out(B_2025_summer_day_ELC_HEAT_SYS_2025_HEAT) ++1 v_flow_out(B_2025_summer_day_NG_NGCC_2025_ELC) ++1 v_flow_out(A_B_2025_summer_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2025_ELC) ++1 v_flow_out(B_2025_summer_day_NG_NGCC_2015_ELC) +-1.0526315789473684 v_flow_out(B_A_2025_summer_day_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(B_C_2025_summer_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(C_B_2025_summer_day_ELC_E_TRANS_2015_ELC) +-1 v_flow_out(B_2025_summer_day_ELC_HEAT_SYS_2020_HEAT) ++1 v_flow_out(B_2025_summer_day_NG_NGCC_2020_ELC) +-1 v_flow_in(B_2025_summer_day_ELC_E_BATT_2025_ELC) +-1 v_flow_in(B_2025_summer_day_ELC_E_LDES_2025_ELC) +-1 v_flow_in(B_2025_summer_day_ELC_E_BATT_2020_ELC) +-1 v_flow_in(B_2025_summer_day_ELC_E_LDES_2020_ELC) += 0 + +c_e_commodity_balance_constraint(B_2025_winter_night_NG)_: +-1.8181818181818181 v_flow_out(B_2025_winter_night_NG_NGCC_2025_ELC) ++1 v_flow_out(B_2025_winter_night_ethos_IMP_NG_2020_NG) +-1.8181818181818181 v_flow_out(B_2025_winter_night_NG_NGCC_2015_ELC) +-1.8181818181818181 v_flow_out(B_2025_winter_night_NG_NGCC_2020_ELC) += 0 + +c_e_commodity_balance_constraint(B_2020_summer_day_NG)_: +-1.8181818181818181 v_flow_out(B_2020_summer_day_NG_NGCC_2020_ELC) +-1.8181818181818181 v_flow_out(B_2020_summer_day_NG_NGCC_2015_ELC) ++1 v_flow_out(B_2020_summer_day_ethos_IMP_NG_2020_NG) += 0 + +c_e_commodity_balance_constraint(B_2020_winter_day_ELC)_: ++1 v_flow_out(C_B_2020_winter_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_B_2020_winter_day_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(B_C_2020_winter_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2020_winter_day_ELC_E_LDES_2020_ELC) ++1 v_flow_out(B_2020_winter_day_NG_NGCC_2015_ELC) ++1 v_flow_out(B_2020_winter_day_ELC_E_BATT_2020_ELC) +-1.0526315789473684 v_flow_out(B_A_2020_winter_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2020_winter_day_NG_NGCC_2020_ELC) +-1 v_flow_in(B_2020_winter_day_ELC_E_LDES_2020_ELC) +-1 v_flow_in(B_2020_winter_day_ELC_E_BATT_2020_ELC) += 0.75 + +c_e_commodity_balance_constraint(B_2025_winter_day_ELC)_: ++1 v_flow_out(B_2025_winter_day_NG_NGCC_2015_ELC) +-1.0526315789473684 v_flow_out(B_A_2025_winter_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2025_ELC) +-1 v_flow_out(B_2025_winter_day_ELC_HEAT_SYS_2025_HEAT) ++1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2025_ELC) ++1 v_flow_out(B_2025_winter_day_NG_NGCC_2020_ELC) ++1 v_flow_out(A_B_2025_winter_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(C_B_2025_winter_day_ELC_E_TRANS_2015_ELC) +-1 v_flow_out(B_2025_winter_day_ELC_HEAT_SYS_2020_HEAT) +-1.0526315789473684 v_flow_out(B_C_2025_winter_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2025_winter_day_NG_NGCC_2025_ELC) ++1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2020_ELC) ++1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2020_ELC) +-1 v_flow_in(B_2025_winter_day_ELC_E_BATT_2025_ELC) +-1 v_flow_in(B_2025_winter_day_ELC_E_LDES_2025_ELC) +-1 v_flow_in(B_2025_winter_day_ELC_E_BATT_2020_ELC) +-1 v_flow_in(B_2025_winter_day_ELC_E_LDES_2020_ELC) += 0 + +c_e_commodity_balance_constraint(A_2020_summer_night_ELC)_: ++1 v_flow_out(A_2020_summer_night_ethos_SOLPV_2020_ELC) ++1 v_flow_out(B_A_2020_summer_night_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(A_B_2020_summer_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2020_summer_night_NG_NGCC_2015_ELC) ++1 v_flow_out(A_2020_summer_night_ELC_E_BATT_2020_ELC) ++1 v_flow_out(A_2020_summer_night_NG_NGCC_2020_ELC) +-1.0526315789473684 v_flow_out(A_C_2020_summer_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2020_summer_night_ELC_E_LDES_2020_ELC) ++1 v_flow_out(A_2020_summer_night_ethos_SOLPV_2015_ELC) ++1 v_flow_out(C_A_2020_summer_night_ELC_E_TRANS_2015_ELC) +-1 v_flow_in(A_2020_summer_night_ELC_E_BATT_2020_ELC) +-1 v_flow_in(A_2020_summer_night_ELC_E_LDES_2020_ELC) += 1.25 + +c_e_commodity_balance_constraint(A_2020_winter_night_NG)_: ++1 v_flow_out(A_2020_winter_night_ethos_IMP_NG_2020_NG) +-1.8181818181818181 v_flow_out(A_2020_winter_night_NG_NGCC_2020_ELC) +-1.8181818181818181 v_flow_out(A_2020_winter_night_NG_NGCC_2015_ELC) += 0 + +c_e_commodity_balance_constraint(A_2020_winter_day_ELC)_: ++1 v_flow_out(C_A_2020_winter_day_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(A_C_2020_winter_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2020_winter_day_ethos_SOLPV_2020_ELC) +-1.0526315789473684 v_flow_out(A_B_2020_winter_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2020_winter_day_NG_NGCC_2020_ELC) ++1 v_flow_out(A_2020_winter_day_ELC_E_BATT_2020_ELC) ++1 v_flow_out(A_2020_winter_day_ethos_SOLPV_2015_ELC) ++1 v_flow_out(A_2020_winter_day_ELC_E_LDES_2020_ELC) ++1 v_flow_out(B_A_2020_winter_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2020_winter_day_NG_NGCC_2015_ELC) +-1 v_flow_in(A_2020_winter_day_ELC_E_LDES_2020_ELC) +-1 v_flow_in(A_2020_winter_day_ELC_E_BATT_2020_ELC) += 1.25 + +c_e_commodity_balance_constraint(A_2025_winter_day_NG)_: +-1.8181818181818181 v_flow_out(A_2025_winter_day_NG_NGCC_2020_ELC) +-1.8181818181818181 v_flow_out(A_2025_winter_day_NG_NGCC_2025_ELC) ++1 v_flow_out(A_2025_winter_day_ethos_IMP_NG_2020_NG) +-1.8181818181818181 v_flow_out(A_2025_winter_day_NG_NGCC_2015_ELC) += 0 + +c_e_commodity_balance_constraint(A_2025_summer_day_ELC)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2020_ELC) +-1 v_flow_out(A_2025_summer_day_ELC_HEAT_SYS_2025_HEAT) ++1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2025_ELC) ++1 v_flow_out(A_2025_summer_day_ethos_SOLPV_2020_ELC) ++1 v_flow_out(A_2025_summer_day_ethos_SOLPV_2025_ELC) ++1 v_flow_out(A_2025_summer_day_NG_NGCC_2015_ELC) +-1.0526315789473684 v_flow_out(A_B_2025_summer_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2025_ELC) ++1 v_flow_out(A_2025_summer_day_NG_NGCC_2020_ELC) +-1 v_flow_out(A_2025_summer_day_ELC_HEAT_SYS_2020_HEAT) ++1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2020_ELC) ++1 v_flow_out(B_A_2025_summer_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2025_summer_day_ethos_SOLPV_2015_ELC) ++1 v_flow_out(C_A_2025_summer_day_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(A_2025_summer_day_NG_NGCC_2025_ELC) +-1.0526315789473684 v_flow_out(A_C_2025_summer_day_ELC_E_TRANS_2015_ELC) +-1 v_flow_in(A_2025_summer_day_ELC_E_BATT_2020_ELC) +-1 v_flow_in(A_2025_summer_day_ELC_E_LDES_2025_ELC) +-1 v_flow_in(A_2025_summer_day_ELC_E_LDES_2020_ELC) +-1 v_flow_in(A_2025_summer_day_ELC_E_BATT_2025_ELC) += 0 + +c_e_commodity_balance_constraint(C_2020_summer_night_ELC)_: ++1 v_flow_out(A_C_2020_summer_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_C_2020_summer_night_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(C_B_2020_summer_night_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(C_A_2020_summer_night_ELC_E_TRANS_2015_ELC) += 0 + +c_e_commodity_balance_constraint(A_2020_summer_day_NG)_: +-1.8181818181818181 v_flow_out(A_2020_summer_day_NG_NGCC_2015_ELC) +-1.8181818181818181 v_flow_out(A_2020_summer_day_NG_NGCC_2020_ELC) ++1 v_flow_out(A_2020_summer_day_ethos_IMP_NG_2020_NG) += 0 + +c_e_commodity_balance_constraint(B_2025_summer_night_ELC)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2020_ELC) ++1 v_flow_out(A_B_2025_summer_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2025_summer_night_NG_NGCC_2015_ELC) ++1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2025_ELC) +-1 v_flow_out(B_2025_summer_night_ELC_HEAT_SYS_2025_HEAT) ++1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2020_ELC) ++1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2025_ELC) ++1 v_flow_out(C_B_2025_summer_night_ELC_E_TRANS_2015_ELC) +-1.0526315789473684 v_flow_out(B_A_2025_summer_night_ELC_E_TRANS_2015_ELC) ++1 v_flow_out(B_2025_summer_night_NG_NGCC_2020_ELC) ++1 v_flow_out(B_2025_summer_night_NG_NGCC_2025_ELC) +-1 v_flow_out(B_2025_summer_night_ELC_HEAT_SYS_2020_HEAT) +-1.0526315789473684 v_flow_out(B_C_2025_summer_night_ELC_E_TRANS_2015_ELC) +-1 v_flow_in(B_2025_summer_night_ELC_E_BATT_2020_ELC) +-1 v_flow_in(B_2025_summer_night_ELC_E_LDES_2020_ELC) +-1 v_flow_in(B_2025_summer_night_ELC_E_BATT_2025_ELC) +-1 v_flow_in(B_2025_summer_night_ELC_E_LDES_2025_ELC) += 0 + +c_e_annual_commodity_balance_constraint(C_2025_ELC_C)_: ++1 v_flow_out_annual(C_2025_ethos_ANN_IMP_2020_ELC_C) += 1.1 + +c_e_annual_commodity_balance_constraint(C_2020_ELC_C)_: ++1 v_flow_out_annual(C_2020_ethos_ANN_IMP_2020_ELC_C) += 1.0 + +c_e_regional_exchange_capacity_constraint(C_B_2020_E_TRANS_2015)_: +-1 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_capacity(C_B_2020_E_TRANS_2015) += 0 + +c_e_regional_exchange_capacity_constraint(B_A_2020_E_TRANS_2015)_: ++1 v_capacity(B_A_2020_E_TRANS_2015) +-1 v_capacity(A_B_2020_E_TRANS_2015) += 0 + +c_e_regional_exchange_capacity_constraint(C_B_2025_E_TRANS_2015)_: +-1 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_capacity(C_B_2025_E_TRANS_2015) += 0 + +c_e_regional_exchange_capacity_constraint(C_A_2025_E_TRANS_2015)_: +-1 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_capacity(C_A_2025_E_TRANS_2015) += 0 + +c_e_regional_exchange_capacity_constraint(C_A_2020_E_TRANS_2015)_: +-1 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_capacity(C_A_2020_E_TRANS_2015) += 0 + +c_e_regional_exchange_capacity_constraint(B_A_2025_E_TRANS_2015)_: +-1 v_capacity(A_B_2025_E_TRANS_2015) ++1 v_capacity(B_A_2025_E_TRANS_2015) += 0 + +c_e_storage_energy_constraint(A_2020_summer_day_E_BATT_2020)_: +-1 v_flow_out(A_2020_summer_day_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(A_2020_summer_day_ELC_E_BATT_2020_ELC) ++1 v_storage_level(A_2020_summer_day_E_BATT_2020) +-1 v_storage_level(A_2020_summer_night_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(A_2025_summer_day_E_LDES_2020)_: +-1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(A_2025_summer_day_ELC_E_LDES_2020_ELC) ++1 v_storage_level(A_2025_summer_day_E_LDES_2020) +-1 v_storage_level(A_2025_summer_night_E_LDES_2020) += 0 + +c_e_storage_energy_constraint(B_2025_summer_day_E_LDES_2025)_: +-1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2025_ELC) ++0.95 v_flow_in(B_2025_summer_day_ELC_E_LDES_2025_ELC) ++1 v_storage_level(B_2025_summer_day_E_LDES_2025) +-1 v_storage_level(B_2025_summer_night_E_LDES_2025) += 0 + +c_e_storage_energy_constraint(B_2025_summer_night_E_BATT_2020)_: +-1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(B_2025_summer_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(B_2025_summer_day_E_BATT_2020) ++1 v_storage_init(B_2025_summer_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(A_2025_summer_night_E_BATT_2020)_: +-1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(A_2025_summer_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2025_summer_day_E_BATT_2020) ++1 v_storage_init(A_2025_summer_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(A_2025_winter_day_E_BATT_2020)_: +-1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(A_2025_winter_day_ELC_E_BATT_2020_ELC) ++1 v_storage_level(A_2025_winter_day_E_BATT_2020) +-1 v_storage_level(A_2025_winter_night_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(B_2025_winter_night_E_BATT_2025)_: +-1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2025_ELC) ++0.85 v_flow_in(B_2025_winter_night_ELC_E_BATT_2025_ELC) +-1 v_storage_level(B_2025_winter_day_E_BATT_2025) ++1 v_storage_init(B_2025_winter_E_BATT_2025) += 0 + +c_e_storage_energy_constraint(B_2025_summer_day_E_BATT_2020)_: +-1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(B_2025_summer_day_ELC_E_BATT_2020_ELC) +-1 v_storage_level(B_2025_summer_night_E_BATT_2020) ++1 v_storage_level(B_2025_summer_day_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(A_2025_winter_night_E_BATT_2020)_: +-1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(A_2025_winter_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2025_winter_day_E_BATT_2020) ++1 v_storage_init(A_2025_winter_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(B_2020_summer_day_E_LDES_2020)_: +-1 v_flow_out(B_2020_summer_day_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(B_2020_summer_day_ELC_E_LDES_2020_ELC) ++1 v_storage_level(B_2020_summer_day_E_LDES_2020) +-1 v_storage_level(B_2020_summer_night_E_LDES_2020) += 0 + +c_e_storage_energy_constraint(A_2020_winter_day_E_LDES_2020)_: +-1 v_flow_out(A_2020_winter_day_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(A_2020_winter_day_ELC_E_LDES_2020_ELC) ++1 v_storage_level(A_2020_winter_day_E_LDES_2020) +-1 v_storage_level(A_2020_winter_night_E_LDES_2020) += 0 + +c_e_storage_energy_constraint(B_2020_winter_day_E_LDES_2020)_: +-1 v_flow_out(B_2020_winter_day_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(B_2020_winter_day_ELC_E_LDES_2020_ELC) +-1 v_storage_level(B_2020_winter_night_E_LDES_2020) ++1 v_storage_level(B_2020_winter_day_E_LDES_2020) += 0 + +c_e_storage_energy_constraint(B_2025_winter_day_E_LDES_2020)_: +-1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(B_2025_winter_day_ELC_E_LDES_2020_ELC) ++1 v_storage_level(B_2025_winter_day_E_LDES_2020) +-1 v_storage_level(B_2025_winter_night_E_LDES_2020) += 0 + +c_e_storage_energy_constraint(A_2025_summer_day_E_LDES_2025)_: +-1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2025_ELC) ++0.95 v_flow_in(A_2025_summer_day_ELC_E_LDES_2025_ELC) +-1 v_storage_level(A_2025_summer_night_E_LDES_2025) ++1 v_storage_level(A_2025_summer_day_E_LDES_2025) += 0 + +c_e_storage_energy_constraint(B_2025_summer_night_E_BATT_2025)_: +-1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2025_ELC) ++0.85 v_flow_in(B_2025_summer_night_ELC_E_BATT_2025_ELC) +-1 v_storage_level(B_2025_summer_day_E_BATT_2025) ++1 v_storage_init(B_2025_summer_E_BATT_2025) += 0 + +c_e_storage_energy_constraint(A_2025_summer_night_E_BATT_2025)_: +-1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2025_ELC) ++0.85 v_flow_in(A_2025_summer_night_ELC_E_BATT_2025_ELC) +-1 v_storage_level(A_2025_summer_day_E_BATT_2025) ++1 v_storage_init(A_2025_summer_E_BATT_2025) += 0 + +c_e_storage_energy_constraint(A_2025_winter_day_E_BATT_2025)_: +-1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2025_ELC) ++0.85 v_flow_in(A_2025_winter_day_ELC_E_BATT_2025_ELC) ++1 v_storage_level(A_2025_winter_day_E_BATT_2025) +-1 v_storage_level(A_2025_winter_night_E_BATT_2025) += 0 + +c_e_storage_energy_constraint(A_2025_summer_day_E_BATT_2020)_: +-1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(A_2025_summer_day_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2025_summer_night_E_BATT_2020) ++1 v_storage_level(A_2025_summer_day_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(B_2025_summer_day_E_BATT_2025)_: +-1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2025_ELC) ++0.85 v_flow_in(B_2025_summer_day_ELC_E_BATT_2025_ELC) +-1 v_storage_level(B_2025_summer_night_E_BATT_2025) ++1 v_storage_level(B_2025_summer_day_E_BATT_2025) += 0 + +c_e_storage_energy_constraint(B_2025_winter_day_E_BATT_2020)_: +-1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(B_2025_winter_day_ELC_E_BATT_2020_ELC) ++1 v_storage_level(B_2025_winter_day_E_BATT_2020) +-1 v_storage_level(B_2025_winter_night_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(B_2020_summer_day_E_BATT_2020)_: +-1 v_flow_out(B_2020_summer_day_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(B_2020_summer_day_ELC_E_BATT_2020_ELC) ++1 v_storage_level(B_2020_summer_day_E_BATT_2020) +-1 v_storage_level(B_2020_summer_night_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(A_2025_winter_night_E_BATT_2025)_: +-1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2025_ELC) ++0.85 v_flow_in(A_2025_winter_night_ELC_E_BATT_2025_ELC) +-1 v_storage_level(A_2025_winter_day_E_BATT_2025) ++1 v_storage_init(A_2025_winter_E_BATT_2025) += 0 + +c_e_storage_energy_constraint(B_2020_summer_night_E_BATT_2020)_: +-1 v_flow_out(B_2020_summer_night_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(B_2020_summer_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(B_2020_summer_day_E_BATT_2020) ++1 v_storage_init(B_2020_summer_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(A_2020_winter_day_E_BATT_2020)_: +-1 v_flow_out(A_2020_winter_day_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(A_2020_winter_day_ELC_E_BATT_2020_ELC) ++1 v_storage_level(A_2020_winter_day_E_BATT_2020) +-1 v_storage_level(A_2020_winter_night_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(A_2025_winter_day_E_LDES_2020)_: +-1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(A_2025_winter_day_ELC_E_LDES_2020_ELC) ++1 v_storage_level(A_2025_winter_day_E_LDES_2020) +-1 v_storage_level(A_2025_winter_night_E_LDES_2020) += 0 + +c_e_storage_energy_constraint(B_2025_summer_day_E_LDES_2020)_: +-1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(B_2025_summer_day_ELC_E_LDES_2020_ELC) +-1 v_storage_level(B_2025_summer_night_E_LDES_2020) ++1 v_storage_level(B_2025_summer_day_E_LDES_2020) += 0 + +c_e_storage_energy_constraint(B_2025_winter_day_E_LDES_2025)_: +-1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2025_ELC) ++0.95 v_flow_in(B_2025_winter_day_ELC_E_LDES_2025_ELC) ++1 v_storage_level(B_2025_winter_day_E_LDES_2025) +-1 v_storage_level(B_2025_winter_night_E_LDES_2025) += 0 + +c_e_storage_energy_constraint(B_2020_winter_day_E_BATT_2020)_: +-1 v_flow_out(B_2020_winter_day_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(B_2020_winter_day_ELC_E_BATT_2020_ELC) ++1 v_storage_level(B_2020_winter_day_E_BATT_2020) +-1 v_storage_level(B_2020_winter_night_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(A_2020_summer_day_E_LDES_2020)_: +-1 v_flow_out(A_2020_summer_day_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(A_2020_summer_day_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2020_summer_night_E_LDES_2020) ++1 v_storage_level(A_2020_summer_day_E_LDES_2020) += 0 + +c_e_storage_energy_constraint(B_2020_winter_night_E_BATT_2020)_: +-1 v_flow_out(B_2020_winter_night_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(B_2020_winter_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(B_2020_winter_day_E_BATT_2020) ++1 v_storage_init(B_2020_winter_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(A_2020_winter_night_E_BATT_2020)_: +-1 v_flow_out(A_2020_winter_night_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(A_2020_winter_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2020_winter_day_E_BATT_2020) ++1 v_storage_init(A_2020_winter_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(B_2025_winter_night_E_BATT_2020)_: +-1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(B_2025_winter_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(B_2025_winter_day_E_BATT_2020) ++1 v_storage_init(B_2025_winter_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(A_2025_summer_day_E_BATT_2025)_: +-1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2025_ELC) ++0.85 v_flow_in(A_2025_summer_day_ELC_E_BATT_2025_ELC) +-1 v_storage_level(A_2025_summer_night_E_BATT_2025) ++1 v_storage_level(A_2025_summer_day_E_BATT_2025) += 0 + +c_e_storage_energy_constraint(B_2025_winter_day_E_BATT_2025)_: +-1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2025_ELC) ++0.85 v_flow_in(B_2025_winter_day_ELC_E_BATT_2025_ELC) +-1 v_storage_level(B_2025_winter_night_E_BATT_2025) ++1 v_storage_level(B_2025_winter_day_E_BATT_2025) += 0 + +c_e_storage_energy_constraint(A_2020_summer_night_E_BATT_2020)_: +-1 v_flow_out(A_2020_summer_night_ELC_E_BATT_2020_ELC) ++0.85 v_flow_in(A_2020_summer_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2020_summer_day_E_BATT_2020) ++1 v_storage_init(A_2020_summer_E_BATT_2020) += 0 + +c_e_storage_energy_constraint(A_2025_winter_day_E_LDES_2025)_: +-1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2025_ELC) ++0.95 v_flow_in(A_2025_winter_day_ELC_E_LDES_2025_ELC) +-1 v_storage_level(A_2025_winter_night_E_LDES_2025) ++1 v_storage_level(A_2025_winter_day_E_LDES_2025) += 0 + +c_e_storage_level_last_tod_constraint(B_2025_winter_E_BATT_2025)_: ++1 v_storage_level(B_2025_winter_night_E_BATT_2025) +-1 v_storage_init(B_2025_winter_E_BATT_2025) += 0 + +c_e_storage_level_last_tod_constraint(A_2025_summer_E_BATT_2020)_: ++1 v_storage_level(A_2025_summer_night_E_BATT_2020) +-1 v_storage_init(A_2025_summer_E_BATT_2020) += 0 + +c_e_storage_level_last_tod_constraint(B_2025_summer_E_BATT_2025)_: ++1 v_storage_level(B_2025_summer_night_E_BATT_2025) +-1 v_storage_init(B_2025_summer_E_BATT_2025) += 0 + +c_e_storage_level_last_tod_constraint(A_2025_summer_E_BATT_2025)_: ++1 v_storage_level(A_2025_summer_night_E_BATT_2025) +-1 v_storage_init(A_2025_summer_E_BATT_2025) += 0 + +c_e_storage_level_last_tod_constraint(B_2020_summer_E_BATT_2020)_: ++1 v_storage_level(B_2020_summer_night_E_BATT_2020) +-1 v_storage_init(B_2020_summer_E_BATT_2020) += 0 + +c_e_storage_level_last_tod_constraint(B_2020_winter_E_BATT_2020)_: ++1 v_storage_level(B_2020_winter_night_E_BATT_2020) +-1 v_storage_init(B_2020_winter_E_BATT_2020) += 0 + +c_e_storage_level_last_tod_constraint(A_2020_winter_E_BATT_2020)_: ++1 v_storage_level(A_2020_winter_night_E_BATT_2020) +-1 v_storage_init(A_2020_winter_E_BATT_2020) += 0 + +c_e_storage_level_last_tod_constraint(A_2025_winter_E_BATT_2020)_: ++1 v_storage_level(A_2025_winter_night_E_BATT_2020) +-1 v_storage_init(A_2025_winter_E_BATT_2020) += 0 + +c_e_storage_level_last_tod_constraint(B_2025_winter_E_BATT_2020)_: ++1 v_storage_level(B_2025_winter_night_E_BATT_2020) +-1 v_storage_init(B_2025_winter_E_BATT_2020) += 0 + +c_e_storage_level_last_tod_constraint(B_2025_summer_E_BATT_2020)_: ++1 v_storage_level(B_2025_summer_night_E_BATT_2020) +-1 v_storage_init(B_2025_summer_E_BATT_2020) += 0 + +c_e_storage_level_last_tod_constraint(A_2020_summer_E_BATT_2020)_: ++1 v_storage_level(A_2020_summer_night_E_BATT_2020) +-1 v_storage_init(A_2020_summer_E_BATT_2020) += 0 + +c_e_storage_level_last_tod_constraint(A_2025_winter_E_BATT_2025)_: ++1 v_storage_level(A_2025_winter_night_E_BATT_2025) +-1 v_storage_init(A_2025_winter_E_BATT_2025) += 0 + +c_u_storage_energy_upper_bound_constraint(A_2020_summer_day_E_BATT_2020)_: +-0.73 v_capacity(A_2020_E_BATT_2020) ++1 v_storage_level(A_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_storage_energy_upper_bound_constraint(B_2025_summer_night_E_BATT_2020)_: +-0.73 v_capacity(B_2025_E_BATT_2020) ++1 v_storage_level(B_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_storage_energy_upper_bound_constraint(A_2025_summer_night_E_BATT_2020)_: +-0.73 v_capacity(A_2025_E_BATT_2020) ++1 v_storage_level(A_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_storage_energy_upper_bound_constraint(A_2025_winter_day_E_BATT_2020)_: +-0.73 v_capacity(A_2025_E_BATT_2020) ++1 v_storage_level(A_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_storage_energy_upper_bound_constraint(B_2025_winter_night_E_BATT_2025)_: +-0.73 v_capacity(B_2025_E_BATT_2025) ++1 v_storage_level(B_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_storage_energy_upper_bound_constraint(B_2025_summer_day_E_BATT_2020)_: +-0.73 v_capacity(B_2025_E_BATT_2020) ++1 v_storage_level(B_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_storage_energy_upper_bound_constraint(A_2025_winter_night_E_BATT_2020)_: +-0.73 v_capacity(A_2025_E_BATT_2020) ++1 v_storage_level(A_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_storage_energy_upper_bound_constraint(B_2025_summer_night_E_BATT_2025)_: +-0.73 v_capacity(B_2025_E_BATT_2025) ++1 v_storage_level(B_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_storage_energy_upper_bound_constraint(A_2025_summer_night_E_BATT_2025)_: +-0.73 v_capacity(A_2025_E_BATT_2025) ++1 v_storage_level(A_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_storage_energy_upper_bound_constraint(A_2025_winter_day_E_BATT_2025)_: +-0.73 v_capacity(A_2025_E_BATT_2025) ++1 v_storage_level(A_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_storage_energy_upper_bound_constraint(A_2025_summer_day_E_BATT_2020)_: +-0.73 v_capacity(A_2025_E_BATT_2020) ++1 v_storage_level(A_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_storage_energy_upper_bound_constraint(B_2025_summer_day_E_BATT_2025)_: +-0.73 v_capacity(B_2025_E_BATT_2025) ++1 v_storage_level(B_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_storage_energy_upper_bound_constraint(B_2025_winter_day_E_BATT_2020)_: +-0.73 v_capacity(B_2025_E_BATT_2020) ++1 v_storage_level(B_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_storage_energy_upper_bound_constraint(B_2020_summer_day_E_BATT_2020)_: +-0.73 v_capacity(B_2020_E_BATT_2020) ++1 v_storage_level(B_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_storage_energy_upper_bound_constraint(A_2025_winter_night_E_BATT_2025)_: +-0.73 v_capacity(A_2025_E_BATT_2025) ++1 v_storage_level(A_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_storage_energy_upper_bound_constraint(B_2020_summer_night_E_BATT_2020)_: +-0.73 v_capacity(B_2020_E_BATT_2020) ++1 v_storage_level(B_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_storage_energy_upper_bound_constraint(A_2020_winter_day_E_BATT_2020)_: +-0.73 v_capacity(A_2020_E_BATT_2020) ++1 v_storage_level(A_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_storage_energy_upper_bound_constraint(B_2020_winter_day_E_BATT_2020)_: +-0.73 v_capacity(B_2020_E_BATT_2020) ++1 v_storage_level(B_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_storage_energy_upper_bound_constraint(B_2020_winter_night_E_BATT_2020)_: +-0.73 v_capacity(B_2020_E_BATT_2020) ++1 v_storage_level(B_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_storage_energy_upper_bound_constraint(A_2020_winter_night_E_BATT_2020)_: +-0.73 v_capacity(A_2020_E_BATT_2020) ++1 v_storage_level(A_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_storage_energy_upper_bound_constraint(B_2025_winter_night_E_BATT_2020)_: +-0.73 v_capacity(B_2025_E_BATT_2020) ++1 v_storage_level(B_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_storage_energy_upper_bound_constraint(A_2025_summer_day_E_BATT_2025)_: +-0.73 v_capacity(A_2025_E_BATT_2025) ++1 v_storage_level(A_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_storage_energy_upper_bound_constraint(B_2025_winter_day_E_BATT_2025)_: +-0.73 v_capacity(B_2025_E_BATT_2025) ++1 v_storage_level(B_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_storage_energy_upper_bound_constraint(A_2020_summer_night_E_BATT_2020)_: +-0.73 v_capacity(A_2020_E_BATT_2020) ++1 v_storage_level(A_2020_summer_night_E_BATT_2020) +<= 0 + +c_e_seasonal_storage_energy_constraint(A_2025_summer_E_LDES_2020)_: +-1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(A_2025_summer_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2025_winter_day_E_LDES_2020) ++1 v_storage_level(A_2025_summer_night_E_LDES_2020) ++1 v_seasonal_storage_level(A_2025_summer_E_LDES_2020) +-1 v_seasonal_storage_level(A_2025_winter_E_LDES_2020) += 0 + +c_e_seasonal_storage_energy_constraint(A_2020_summer_E_LDES_2020)_: +-1 v_flow_out(A_2020_summer_night_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(A_2020_summer_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2020_winter_day_E_LDES_2020) ++1 v_storage_level(A_2020_summer_night_E_LDES_2020) ++1 v_seasonal_storage_level(A_2020_summer_E_LDES_2020) +-1 v_seasonal_storage_level(A_2020_winter_E_LDES_2020) += 0 + +c_e_seasonal_storage_energy_constraint(B_2020_summer_E_LDES_2020)_: +-1 v_flow_out(B_2020_summer_night_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(B_2020_summer_night_ELC_E_LDES_2020_ELC) ++1 v_storage_level(B_2020_summer_night_E_LDES_2020) +-1 v_storage_level(B_2020_winter_day_E_LDES_2020) ++1 v_seasonal_storage_level(B_2020_summer_E_LDES_2020) +-1 v_seasonal_storage_level(B_2020_winter_E_LDES_2020) += 0 + +c_e_seasonal_storage_energy_constraint(A_2025_winter_E_LDES_2020)_: +-1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(A_2025_winter_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2025_summer_day_E_LDES_2020) ++1 v_storage_level(A_2025_winter_night_E_LDES_2020) +-1 v_seasonal_storage_level(A_2025_summer_E_LDES_2020) ++1 v_seasonal_storage_level(A_2025_winter_E_LDES_2020) += 0 + +c_e_seasonal_storage_energy_constraint(B_2025_winter_E_LDES_2020)_: +-1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(B_2025_winter_night_ELC_E_LDES_2020_ELC) ++1 v_storage_level(B_2025_winter_night_E_LDES_2020) +-1 v_storage_level(B_2025_summer_day_E_LDES_2020) ++1 v_seasonal_storage_level(B_2025_winter_E_LDES_2020) +-1 v_seasonal_storage_level(B_2025_summer_E_LDES_2020) += 0 + +c_e_seasonal_storage_energy_constraint(B_2025_summer_E_LDES_2025)_: +-1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2025_ELC) ++0.95 v_flow_in(B_2025_summer_night_ELC_E_LDES_2025_ELC) +-1 v_storage_level(B_2025_winter_day_E_LDES_2025) ++1 v_storage_level(B_2025_summer_night_E_LDES_2025) ++1 v_seasonal_storage_level(B_2025_summer_E_LDES_2025) +-1 v_seasonal_storage_level(B_2025_winter_E_LDES_2025) += 0 + +c_e_seasonal_storage_energy_constraint(B_2020_winter_E_LDES_2020)_: +-1 v_flow_out(B_2020_winter_night_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(B_2020_winter_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(B_2020_summer_day_E_LDES_2020) ++1 v_storage_level(B_2020_winter_night_E_LDES_2020) +-1 v_seasonal_storage_level(B_2020_summer_E_LDES_2020) ++1 v_seasonal_storage_level(B_2020_winter_E_LDES_2020) += 0 + +c_e_seasonal_storage_energy_constraint(A_2025_summer_E_LDES_2025)_: +-1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2025_ELC) ++0.95 v_flow_in(A_2025_summer_night_ELC_E_LDES_2025_ELC) ++1 v_storage_level(A_2025_summer_night_E_LDES_2025) +-1 v_storage_level(A_2025_winter_day_E_LDES_2025) ++1 v_seasonal_storage_level(A_2025_summer_E_LDES_2025) +-1 v_seasonal_storage_level(A_2025_winter_E_LDES_2025) += 0 + +c_e_seasonal_storage_energy_constraint(A_2020_winter_E_LDES_2020)_: +-1 v_flow_out(A_2020_winter_night_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(A_2020_winter_night_ELC_E_LDES_2020_ELC) ++1 v_storage_level(A_2020_winter_night_E_LDES_2020) +-1 v_storage_level(A_2020_summer_day_E_LDES_2020) +-1 v_seasonal_storage_level(A_2020_summer_E_LDES_2020) ++1 v_seasonal_storage_level(A_2020_winter_E_LDES_2020) += 0 + +c_e_seasonal_storage_energy_constraint(A_2025_winter_E_LDES_2025)_: +-1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2025_ELC) ++0.95 v_flow_in(A_2025_winter_night_ELC_E_LDES_2025_ELC) ++1 v_storage_level(A_2025_winter_night_E_LDES_2025) +-1 v_storage_level(A_2025_summer_day_E_LDES_2025) +-1 v_seasonal_storage_level(A_2025_summer_E_LDES_2025) ++1 v_seasonal_storage_level(A_2025_winter_E_LDES_2025) += 0 + +c_e_seasonal_storage_energy_constraint(B_2025_winter_E_LDES_2025)_: +-1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2025_ELC) ++0.95 v_flow_in(B_2025_winter_night_ELC_E_LDES_2025_ELC) +-1 v_storage_level(B_2025_summer_day_E_LDES_2025) ++1 v_storage_level(B_2025_winter_night_E_LDES_2025) +-1 v_seasonal_storage_level(B_2025_summer_E_LDES_2025) ++1 v_seasonal_storage_level(B_2025_winter_E_LDES_2025) += 0 + +c_e_seasonal_storage_energy_constraint(B_2025_summer_E_LDES_2020)_: +-1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2020_ELC) ++0.95 v_flow_in(B_2025_summer_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(B_2025_winter_day_E_LDES_2020) ++1 v_storage_level(B_2025_summer_night_E_LDES_2020) +-1 v_seasonal_storage_level(B_2025_winter_E_LDES_2020) ++1 v_seasonal_storage_level(B_2025_summer_E_LDES_2020) += 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(A_2025_summer_day_E_LDES_2020)_: +-0.39999999999999997 v_capacity(A_2025_E_LDES_2020) ++1 v_storage_level(A_2025_summer_day_E_LDES_2020) ++1 v_seasonal_storage_level(A_2025_summer_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(B_2025_summer_day_E_LDES_2025)_: +-0.39999999999999997 v_capacity(B_2025_E_LDES_2025) ++1 v_storage_level(B_2025_summer_day_E_LDES_2025) ++1 v_seasonal_storage_level(B_2025_summer_E_LDES_2025) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(A_2025_summer_night_E_LDES_2025)_: +-0.39999999999999997 v_capacity(A_2025_E_LDES_2025) ++1 v_storage_level(A_2025_summer_night_E_LDES_2025) ++1 v_seasonal_storage_level(A_2025_summer_E_LDES_2025) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(B_2020_summer_day_E_LDES_2020)_: +-0.39999999999999997 v_capacity(B_2020_E_LDES_2020) ++1 v_storage_level(B_2020_summer_day_E_LDES_2020) ++1 v_seasonal_storage_level(B_2020_summer_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(B_2020_winter_night_E_LDES_2020)_: +-0.39999999999999997 v_capacity(B_2020_E_LDES_2020) ++1 v_storage_level(B_2020_winter_night_E_LDES_2020) ++1 v_seasonal_storage_level(B_2020_winter_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(A_2025_winter_night_E_LDES_2025)_: +-0.39999999999999997 v_capacity(A_2025_E_LDES_2025) ++1 v_storage_level(A_2025_winter_night_E_LDES_2025) ++1 v_seasonal_storage_level(A_2025_winter_E_LDES_2025) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(B_2020_summer_night_E_LDES_2020)_: +-0.39999999999999997 v_capacity(B_2020_E_LDES_2020) ++1 v_storage_level(B_2020_summer_night_E_LDES_2020) ++1 v_seasonal_storage_level(B_2020_summer_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(A_2020_winter_day_E_LDES_2020)_: +-0.39999999999999997 v_capacity(A_2020_E_LDES_2020) ++1 v_storage_level(A_2020_winter_day_E_LDES_2020) ++1 v_seasonal_storage_level(A_2020_winter_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(B_2020_winter_day_E_LDES_2020)_: +-0.39999999999999997 v_capacity(B_2020_E_LDES_2020) ++1 v_storage_level(B_2020_winter_day_E_LDES_2020) ++1 v_seasonal_storage_level(B_2020_winter_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(B_2025_winter_day_E_LDES_2020)_: +-0.39999999999999997 v_capacity(B_2025_E_LDES_2020) ++1 v_storage_level(B_2025_winter_day_E_LDES_2020) ++1 v_seasonal_storage_level(B_2025_winter_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(A_2025_summer_day_E_LDES_2025)_: +-0.39999999999999997 v_capacity(A_2025_E_LDES_2025) ++1 v_storage_level(A_2025_summer_day_E_LDES_2025) ++1 v_seasonal_storage_level(A_2025_summer_E_LDES_2025) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(A_2020_winter_night_E_LDES_2020)_: +-0.39999999999999997 v_capacity(A_2020_E_LDES_2020) ++1 v_storage_level(A_2020_winter_night_E_LDES_2020) ++1 v_seasonal_storage_level(A_2020_winter_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(A_2025_winter_day_E_LDES_2025)_: +-0.39999999999999997 v_capacity(A_2025_E_LDES_2025) ++1 v_storage_level(A_2025_winter_day_E_LDES_2025) ++1 v_seasonal_storage_level(A_2025_winter_E_LDES_2025) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(B_2025_winter_night_E_LDES_2020)_: +-0.39999999999999997 v_capacity(B_2025_E_LDES_2020) ++1 v_storage_level(B_2025_winter_night_E_LDES_2020) ++1 v_seasonal_storage_level(B_2025_winter_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(A_2020_summer_night_E_LDES_2020)_: +-0.39999999999999997 v_capacity(A_2020_E_LDES_2020) ++1 v_storage_level(A_2020_summer_night_E_LDES_2020) ++1 v_seasonal_storage_level(A_2020_summer_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(B_2025_summer_night_E_LDES_2020)_: +-0.39999999999999997 v_capacity(B_2025_E_LDES_2020) ++1 v_storage_level(B_2025_summer_night_E_LDES_2020) ++1 v_seasonal_storage_level(B_2025_summer_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(A_2025_winter_day_E_LDES_2020)_: +-0.39999999999999997 v_capacity(A_2025_E_LDES_2020) ++1 v_storage_level(A_2025_winter_day_E_LDES_2020) ++1 v_seasonal_storage_level(A_2025_winter_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(B_2025_summer_day_E_LDES_2020)_: +-0.39999999999999997 v_capacity(B_2025_E_LDES_2020) ++1 v_storage_level(B_2025_summer_day_E_LDES_2020) ++1 v_seasonal_storage_level(B_2025_summer_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(B_2025_winter_day_E_LDES_2025)_: +-0.39999999999999997 v_capacity(B_2025_E_LDES_2025) ++1 v_storage_level(B_2025_winter_day_E_LDES_2025) ++1 v_seasonal_storage_level(B_2025_winter_E_LDES_2025) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(A_2020_summer_day_E_LDES_2020)_: +-0.39999999999999997 v_capacity(A_2020_E_LDES_2020) ++1 v_storage_level(A_2020_summer_day_E_LDES_2020) ++1 v_seasonal_storage_level(A_2020_summer_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(A_2025_summer_night_E_LDES_2020)_: +-0.39999999999999997 v_capacity(A_2025_E_LDES_2020) ++1 v_storage_level(A_2025_summer_night_E_LDES_2020) ++1 v_seasonal_storage_level(A_2025_summer_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(B_2025_winter_night_E_LDES_2025)_: +-0.39999999999999997 v_capacity(B_2025_E_LDES_2025) ++1 v_storage_level(B_2025_winter_night_E_LDES_2025) ++1 v_seasonal_storage_level(B_2025_winter_E_LDES_2025) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(A_2025_winter_night_E_LDES_2020)_: +-0.39999999999999997 v_capacity(A_2025_E_LDES_2020) ++1 v_storage_level(A_2025_winter_night_E_LDES_2020) ++1 v_seasonal_storage_level(A_2025_winter_E_LDES_2020) +<= 0 + +c_u_seasonal_storage_energy_upper_bound_constraint(B_2025_summer_night_E_LDES_2025)_: +-0.39999999999999997 v_capacity(B_2025_E_LDES_2025) ++1 v_storage_level(B_2025_summer_night_E_LDES_2025) ++1 v_seasonal_storage_level(B_2025_summer_E_LDES_2025) +<= 0 + +c_u_storage_charge_rate_constraint(A_2020_summer_day_E_BATT_2020)_: +-2.19 v_capacity(A_2020_E_BATT_2020) ++0.85 v_flow_in(A_2020_summer_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_summer_day_E_LDES_2020)_: +-2.19 v_capacity(A_2025_E_LDES_2020) ++0.95 v_flow_in(A_2025_summer_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_summer_day_E_LDES_2025)_: +-0.0438 v_uc_online(B_2025_summer_day_E_LDES_2025) ++0.95 v_flow_in(B_2025_summer_day_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_summer_night_E_BATT_2020)_: +-0.1095 v_uc_online(B_2025_summer_night_E_BATT_2020) ++0.85 v_flow_in(B_2025_summer_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_summer_night_E_BATT_2020)_: +-2.19 v_capacity(A_2025_E_BATT_2020) ++0.85 v_flow_in(A_2025_summer_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_summer_night_E_LDES_2025)_: +-2.19 v_capacity(A_2025_E_LDES_2025) ++0.95 v_flow_in(A_2025_summer_night_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_winter_day_E_BATT_2020)_: +-2.19 v_capacity(A_2025_E_BATT_2020) ++0.85 v_flow_in(A_2025_winter_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_winter_night_E_BATT_2025)_: +-0.1095 v_uc_online(B_2025_winter_night_E_BATT_2025) ++0.85 v_flow_in(B_2025_winter_night_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_summer_day_E_BATT_2020)_: +-0.1095 v_uc_online(B_2025_summer_day_E_BATT_2020) ++0.85 v_flow_in(B_2025_summer_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_winter_night_E_BATT_2020)_: +-2.19 v_capacity(A_2025_E_BATT_2020) ++0.85 v_flow_in(A_2025_winter_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2020_summer_day_E_LDES_2020)_: +-0.0438 v_uc_online(B_2020_summer_day_E_LDES_2020) ++0.95 v_flow_in(B_2020_summer_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_winter_night_E_LDES_2025)_: +-2.19 v_capacity(A_2025_E_LDES_2025) ++0.95 v_flow_in(A_2025_winter_night_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2020_winter_night_E_LDES_2020)_: +-0.0438 v_uc_online(B_2020_winter_night_E_LDES_2020) ++0.95 v_flow_in(B_2020_winter_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2020_winter_day_E_LDES_2020)_: +-2.19 v_capacity(A_2020_E_LDES_2020) ++0.95 v_flow_in(A_2020_winter_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2020_summer_night_E_LDES_2020)_: +-0.0438 v_uc_online(B_2020_summer_night_E_LDES_2020) ++0.95 v_flow_in(B_2020_summer_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2020_winter_day_E_LDES_2020)_: +-0.0438 v_uc_online(B_2020_winter_day_E_LDES_2020) ++0.95 v_flow_in(B_2020_winter_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_winter_day_E_LDES_2020)_: +-0.0438 v_uc_online(B_2025_winter_day_E_LDES_2020) ++0.95 v_flow_in(B_2025_winter_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_summer_day_E_LDES_2025)_: +-2.19 v_capacity(A_2025_E_LDES_2025) ++0.95 v_flow_in(A_2025_summer_day_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2020_winter_night_E_LDES_2020)_: +-2.19 v_capacity(A_2020_E_LDES_2020) ++0.95 v_flow_in(A_2020_winter_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_summer_night_E_BATT_2025)_: +-0.1095 v_uc_online(B_2025_summer_night_E_BATT_2025) ++0.85 v_flow_in(B_2025_summer_night_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_summer_night_E_BATT_2025)_: +-2.19 v_capacity(A_2025_E_BATT_2025) ++0.85 v_flow_in(A_2025_summer_night_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_winter_day_E_BATT_2025)_: +-2.19 v_capacity(A_2025_E_BATT_2025) ++0.85 v_flow_in(A_2025_winter_day_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_winter_night_E_LDES_2020)_: +-0.0438 v_uc_online(B_2025_winter_night_E_LDES_2020) ++0.95 v_flow_in(B_2025_winter_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_summer_day_E_BATT_2020)_: +-2.19 v_capacity(A_2025_E_BATT_2020) ++0.85 v_flow_in(A_2025_summer_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_summer_day_E_BATT_2025)_: +-0.1095 v_uc_online(B_2025_summer_day_E_BATT_2025) ++0.85 v_flow_in(B_2025_summer_day_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_winter_day_E_BATT_2020)_: +-0.1095 v_uc_online(B_2025_winter_day_E_BATT_2020) ++0.85 v_flow_in(B_2025_winter_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2020_summer_day_E_BATT_2020)_: +-0.1095 v_uc_online(B_2020_summer_day_E_BATT_2020) ++0.85 v_flow_in(B_2020_summer_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_winter_night_E_BATT_2025)_: +-2.19 v_capacity(A_2025_E_BATT_2025) ++0.85 v_flow_in(A_2025_winter_night_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2020_summer_night_E_LDES_2020)_: +-2.19 v_capacity(A_2020_E_LDES_2020) ++0.95 v_flow_in(A_2020_summer_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2020_summer_night_E_BATT_2020)_: +-0.1095 v_uc_online(B_2020_summer_night_E_BATT_2020) ++0.85 v_flow_in(B_2020_summer_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_summer_night_E_LDES_2020)_: +-0.0438 v_uc_online(B_2025_summer_night_E_LDES_2020) ++0.95 v_flow_in(B_2025_summer_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2020_winter_day_E_BATT_2020)_: +-2.19 v_capacity(A_2020_E_BATT_2020) ++0.85 v_flow_in(A_2020_winter_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_winter_day_E_LDES_2020)_: +-2.19 v_capacity(A_2025_E_LDES_2020) ++0.95 v_flow_in(A_2025_winter_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_summer_day_E_LDES_2020)_: +-0.0438 v_uc_online(B_2025_summer_day_E_LDES_2020) ++0.95 v_flow_in(B_2025_summer_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_winter_day_E_LDES_2025)_: +-0.0438 v_uc_online(B_2025_winter_day_E_LDES_2025) ++0.95 v_flow_in(B_2025_winter_day_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2020_winter_day_E_BATT_2020)_: +-0.1095 v_uc_online(B_2020_winter_day_E_BATT_2020) ++0.85 v_flow_in(B_2020_winter_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2020_summer_day_E_LDES_2020)_: +-2.19 v_capacity(A_2020_E_LDES_2020) ++0.95 v_flow_in(A_2020_summer_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_summer_night_E_LDES_2020)_: +-2.19 v_capacity(A_2025_E_LDES_2020) ++0.95 v_flow_in(A_2025_summer_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_summer_night_E_LDES_2025)_: +-0.0438 v_uc_online(B_2025_summer_night_E_LDES_2025) ++0.95 v_flow_in(B_2025_summer_night_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2020_winter_night_E_BATT_2020)_: +-0.1095 v_uc_online(B_2020_winter_night_E_BATT_2020) ++0.85 v_flow_in(B_2020_winter_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2020_winter_night_E_BATT_2020)_: +-2.19 v_capacity(A_2020_E_BATT_2020) ++0.85 v_flow_in(A_2020_winter_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_winter_night_E_BATT_2020)_: +-0.1095 v_uc_online(B_2025_winter_night_E_BATT_2020) ++0.85 v_flow_in(B_2025_winter_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_winter_night_E_LDES_2025)_: +-0.0438 v_uc_online(B_2025_winter_night_E_LDES_2025) ++0.95 v_flow_in(B_2025_winter_night_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_summer_day_E_BATT_2025)_: +-2.19 v_capacity(A_2025_E_BATT_2025) ++0.85 v_flow_in(A_2025_summer_day_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(B_2025_winter_day_E_BATT_2025)_: +-0.1095 v_uc_online(B_2025_winter_day_E_BATT_2025) ++0.85 v_flow_in(B_2025_winter_day_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_winter_night_E_LDES_2020)_: +-2.19 v_capacity(A_2025_E_LDES_2020) ++0.95 v_flow_in(A_2025_winter_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2020_summer_night_E_BATT_2020)_: +-2.19 v_capacity(A_2020_E_BATT_2020) ++0.85 v_flow_in(A_2020_summer_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_charge_rate_constraint(A_2025_winter_day_E_LDES_2025)_: +-2.19 v_capacity(A_2025_E_LDES_2025) ++0.95 v_flow_in(A_2025_winter_day_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2020_summer_day_E_BATT_2020)_: ++1 v_flow_out(A_2020_summer_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_summer_day_E_LDES_2020)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_summer_day_E_LDES_2025)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2025_ELC) +-0.0438 v_uc_online(B_2025_summer_day_E_LDES_2025) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_summer_night_E_BATT_2020)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_summer_night_E_BATT_2020)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_summer_night_E_LDES_2025)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_winter_day_E_BATT_2020)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_winter_night_E_BATT_2025)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_summer_day_E_BATT_2020)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_winter_night_E_BATT_2020)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2020_summer_day_E_LDES_2020)_: ++1 v_flow_out(B_2020_summer_day_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2020_summer_day_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_winter_night_E_LDES_2025)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2020_winter_night_E_LDES_2020)_: ++1 v_flow_out(B_2020_winter_night_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2020_winter_night_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2020_winter_day_E_LDES_2020)_: ++1 v_flow_out(A_2020_winter_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2020_summer_night_E_LDES_2020)_: ++1 v_flow_out(B_2020_summer_night_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2020_summer_night_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2020_winter_day_E_LDES_2020)_: ++1 v_flow_out(B_2020_winter_day_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2020_winter_day_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_winter_day_E_LDES_2020)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2025_winter_day_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_summer_day_E_LDES_2025)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2020_winter_night_E_LDES_2020)_: ++1 v_flow_out(A_2020_winter_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_summer_night_E_BATT_2025)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_summer_night_E_BATT_2025)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_winter_day_E_BATT_2025)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_winter_night_E_LDES_2020)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2025_winter_night_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_summer_day_E_BATT_2020)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_summer_day_E_BATT_2025)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_winter_day_E_BATT_2020)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2020_summer_day_E_BATT_2020)_: ++1 v_flow_out(B_2020_summer_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_winter_night_E_BATT_2025)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2020_summer_night_E_LDES_2020)_: ++1 v_flow_out(A_2020_summer_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2020_summer_night_E_BATT_2020)_: ++1 v_flow_out(B_2020_summer_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_summer_night_E_LDES_2020)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2025_summer_night_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2020_winter_day_E_BATT_2020)_: ++1 v_flow_out(A_2020_winter_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_winter_day_E_LDES_2020)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_summer_day_E_LDES_2020)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2025_summer_day_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_winter_day_E_LDES_2025)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2025_ELC) +-0.0438 v_uc_online(B_2025_winter_day_E_LDES_2025) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2020_winter_day_E_BATT_2020)_: ++1 v_flow_out(B_2020_winter_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2020_summer_day_E_LDES_2020)_: ++1 v_flow_out(A_2020_summer_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_summer_night_E_LDES_2020)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_summer_night_E_LDES_2025)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2025_ELC) +-0.0438 v_uc_online(B_2025_summer_night_E_LDES_2025) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2020_winter_night_E_BATT_2020)_: ++1 v_flow_out(B_2020_winter_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2020_winter_night_E_BATT_2020)_: ++1 v_flow_out(A_2020_winter_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_winter_night_E_BATT_2020)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_winter_night_E_LDES_2025)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2025_ELC) +-0.0438 v_uc_online(B_2025_winter_night_E_LDES_2025) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_summer_day_E_BATT_2025)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) +<= 0 + +c_u_storage_discharge_rate_constraint(B_2025_winter_day_E_BATT_2025)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_winter_night_E_LDES_2020)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2020_summer_night_E_BATT_2020)_: ++1 v_flow_out(A_2020_summer_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) +<= 0 + +c_u_storage_discharge_rate_constraint(A_2025_winter_day_E_LDES_2025)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) +<= 0 + +c_u_storage_throughput_constraint(A_2020_summer_day_E_BATT_2020)_: ++1 v_flow_out(A_2020_summer_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) ++0.85 v_flow_in(A_2020_summer_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_summer_day_E_LDES_2020)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) ++0.95 v_flow_in(A_2025_summer_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_summer_day_E_LDES_2025)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2025_ELC) +-0.0438 v_uc_online(B_2025_summer_day_E_LDES_2025) ++0.95 v_flow_in(B_2025_summer_day_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_summer_night_E_BATT_2020)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_summer_night_E_BATT_2020) ++0.85 v_flow_in(B_2025_summer_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_summer_night_E_BATT_2020)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) ++0.85 v_flow_in(A_2025_summer_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_summer_night_E_LDES_2025)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) ++0.95 v_flow_in(A_2025_summer_night_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_winter_day_E_BATT_2020)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) ++0.85 v_flow_in(A_2025_winter_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_winter_night_E_BATT_2025)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_winter_night_E_BATT_2025) ++0.85 v_flow_in(B_2025_winter_night_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_summer_day_E_BATT_2020)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_summer_day_E_BATT_2020) ++0.85 v_flow_in(B_2025_summer_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_winter_night_E_BATT_2020)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) ++0.85 v_flow_in(A_2025_winter_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2020_summer_day_E_LDES_2020)_: ++1 v_flow_out(B_2020_summer_day_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2020_summer_day_E_LDES_2020) ++0.95 v_flow_in(B_2020_summer_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_winter_night_E_LDES_2025)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) ++0.95 v_flow_in(A_2025_winter_night_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2020_winter_night_E_LDES_2020)_: ++1 v_flow_out(B_2020_winter_night_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2020_winter_night_E_LDES_2020) ++0.95 v_flow_in(B_2020_winter_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2020_winter_day_E_LDES_2020)_: ++1 v_flow_out(A_2020_winter_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) ++0.95 v_flow_in(A_2020_winter_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2020_summer_night_E_LDES_2020)_: ++1 v_flow_out(B_2020_summer_night_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2020_summer_night_E_LDES_2020) ++0.95 v_flow_in(B_2020_summer_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2020_winter_day_E_LDES_2020)_: ++1 v_flow_out(B_2020_winter_day_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2020_winter_day_E_LDES_2020) ++0.95 v_flow_in(B_2020_winter_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_winter_day_E_LDES_2020)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2025_winter_day_E_LDES_2020) ++0.95 v_flow_in(B_2025_winter_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_summer_day_E_LDES_2025)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) ++0.95 v_flow_in(A_2025_summer_day_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2020_winter_night_E_LDES_2020)_: ++1 v_flow_out(A_2020_winter_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) ++0.95 v_flow_in(A_2020_winter_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_summer_night_E_BATT_2025)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_summer_night_E_BATT_2025) ++0.85 v_flow_in(B_2025_summer_night_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_summer_night_E_BATT_2025)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) ++0.85 v_flow_in(A_2025_summer_night_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_winter_day_E_BATT_2025)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) ++0.85 v_flow_in(A_2025_winter_day_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_winter_night_E_LDES_2020)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2025_winter_night_E_LDES_2020) ++0.95 v_flow_in(B_2025_winter_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_summer_day_E_BATT_2020)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) ++0.85 v_flow_in(A_2025_summer_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_summer_day_E_BATT_2025)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_summer_day_E_BATT_2025) ++0.85 v_flow_in(B_2025_summer_day_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_winter_day_E_BATT_2020)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_winter_day_E_BATT_2020) ++0.85 v_flow_in(B_2025_winter_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2020_summer_day_E_BATT_2020)_: ++1 v_flow_out(B_2020_summer_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_summer_day_E_BATT_2020) ++0.85 v_flow_in(B_2020_summer_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_winter_night_E_BATT_2025)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) ++0.85 v_flow_in(A_2025_winter_night_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2020_summer_night_E_LDES_2020)_: ++1 v_flow_out(A_2020_summer_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) ++0.95 v_flow_in(A_2020_summer_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2020_summer_night_E_BATT_2020)_: ++1 v_flow_out(B_2020_summer_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_summer_night_E_BATT_2020) ++0.85 v_flow_in(B_2020_summer_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_summer_night_E_LDES_2020)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2025_summer_night_E_LDES_2020) ++0.95 v_flow_in(B_2025_summer_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2020_winter_day_E_BATT_2020)_: ++1 v_flow_out(A_2020_winter_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) ++0.85 v_flow_in(A_2020_winter_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_winter_day_E_LDES_2020)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) ++0.95 v_flow_in(A_2025_winter_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_summer_day_E_LDES_2020)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2025_summer_day_E_LDES_2020) ++0.95 v_flow_in(B_2025_summer_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_winter_day_E_LDES_2025)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2025_ELC) +-0.0438 v_uc_online(B_2025_winter_day_E_LDES_2025) ++0.95 v_flow_in(B_2025_winter_day_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2020_winter_day_E_BATT_2020)_: ++1 v_flow_out(B_2020_winter_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_winter_day_E_BATT_2020) ++0.85 v_flow_in(B_2020_winter_day_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2020_summer_day_E_LDES_2020)_: ++1 v_flow_out(A_2020_summer_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) ++0.95 v_flow_in(A_2020_summer_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_summer_night_E_LDES_2020)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) ++0.95 v_flow_in(A_2025_summer_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_summer_night_E_LDES_2025)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2025_ELC) +-0.0438 v_uc_online(B_2025_summer_night_E_LDES_2025) ++0.95 v_flow_in(B_2025_summer_night_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2020_winter_night_E_BATT_2020)_: ++1 v_flow_out(B_2020_winter_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_winter_night_E_BATT_2020) ++0.85 v_flow_in(B_2020_winter_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2020_winter_night_E_BATT_2020)_: ++1 v_flow_out(A_2020_winter_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) ++0.85 v_flow_in(A_2020_winter_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_winter_night_E_BATT_2020)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_winter_night_E_BATT_2020) ++0.85 v_flow_in(B_2025_winter_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_winter_night_E_LDES_2025)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2025_ELC) +-0.0438 v_uc_online(B_2025_winter_night_E_LDES_2025) ++0.95 v_flow_in(B_2025_winter_night_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_summer_day_E_BATT_2025)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) ++0.85 v_flow_in(A_2025_summer_day_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_throughput_constraint(B_2025_winter_day_E_BATT_2025)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_winter_day_E_BATT_2025) ++0.85 v_flow_in(B_2025_winter_day_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_winter_night_E_LDES_2020)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) ++0.95 v_flow_in(A_2025_winter_night_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2020_summer_night_E_BATT_2020)_: ++1 v_flow_out(A_2020_summer_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) ++0.85 v_flow_in(A_2020_summer_night_ELC_E_BATT_2020_ELC) +<= 0 + +c_u_storage_throughput_constraint(A_2025_winter_day_E_LDES_2025)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) ++0.95 v_flow_in(A_2025_winter_day_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_A_derate_A_NGCC_2020_winter_night)_: ++1.05 v_flow_out(A_2020_winter_night_NG_NGCC_2020_ELC) ++1.05 v_flow_out(A_2020_winter_night_NG_NGCC_2015_ELC) +-1.752 v_capacity(A_2020_NGCC_2015) +-1.752 v_capacity(A_2020_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_A_A_NGCC_2025_summer_night)_: ++1.15 v_flow_out(A_2025_summer_night_NG_NGCC_2025_ELC) ++1.15 v_flow_out(A_2025_summer_night_NG_NGCC_2015_ELC) ++1.15 v_flow_out(A_2025_summer_night_NG_NGCC_2020_ELC) +-2.19 v_capacity(A_2025_NGCC_2025) +-2.19 v_capacity(A_2025_NGCC_2015) +-2.19 v_capacity(A_2025_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_AB_A_B_elec_AB_2020_winter_night)_: ++1.1 v_flow_out(C_A_2020_winter_night_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(A_2020_winter_night_ethos_SOLPV_2020_ELC) ++1.1 v_flow_out(A_2020_winter_night_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(B_2020_winter_night_NG_NGCC_2015_ELC) ++1.1 v_flow_out(B_2020_winter_night_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(A_2020_winter_night_NG_NGCC_2020_ELC) +-1.1578947368421053 v_flow_out(A_C_2020_winter_night_ELC_E_TRANS_2015_ELC) +-1.1578947368421053 v_flow_out(B_C_2020_winter_night_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(A_2020_winter_night_ELC_E_LDES_2020_ELC) ++1.1 v_flow_out(A_2020_winter_night_NG_NGCC_2015_ELC) ++1.1 v_flow_out(B_2020_winter_night_ELC_E_LDES_2020_ELC) ++1.1 v_flow_out(C_B_2020_winter_night_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(A_2020_winter_night_ethos_SOLPV_2015_ELC) ++1.1 v_flow_out(B_2020_winter_night_NG_NGCC_2020_ELC) +-1.095 v_capacity(B_2020_E_LDES_2020) ++1.752 v_capacity(B_C_2020_E_TRANS_2015) +-2.19 v_capacity(A_2020_NGCC_2015) +-1.971 v_capacity(A_2020_E_BATT_2020) +-1.9272 v_capacity(C_B_2020_E_TRANS_2015) +-1.971 v_capacity(B_2020_E_BATT_2020) +-2.19 v_capacity(B_2020_NGCC_2015) +-2.19 v_capacity(A_2020_NGCC_2020) +-0.32849999999999996 v_capacity(A_2020_SOLPV_2015) ++1.8615 v_capacity(A_C_2020_E_TRANS_2015) +-2.19 v_capacity(B_2020_NGCC_2020) +-1.095 v_capacity(A_2020_E_LDES_2020) +-0.32849999999999996 v_capacity(A_2020_SOLPV_2020) +-2.0805 v_capacity(C_A_2020_E_TRANS_2015) +-1.1 v_flow_in(A_2020_winter_night_ELC_E_BATT_2020_ELC) +-1.1 v_flow_in(A_2020_winter_night_ELC_E_LDES_2020_ELC) +-1.1 v_flow_in(B_2020_winter_night_ELC_E_BATT_2020_ELC) +-1.1 v_flow_in(B_2020_winter_night_ELC_E_LDES_2020_ELC) +<= -2.2 + +c_u_planning_reserve_margin_constraint(cap_C_C_elec_C_ann_2020_winter_night)_: +-0.25 v_capacity(C_2020_ANN_IMP_2020) ++0.3 v_flow_out_annual(C_2020_ethos_ANN_IMP_2020_ELC_C) +<= -0.3 + +c_u_planning_reserve_margin_constraint(cap_A_A_NGCC_2020_winter_day)_: ++1.15 v_flow_out(A_2020_winter_day_NG_NGCC_2020_ELC) ++1.15 v_flow_out(A_2020_winter_day_NG_NGCC_2015_ELC) +-2.19 v_capacity(A_2020_NGCC_2015) +-2.19 v_capacity(A_2020_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_C_C_elec_C_ann_2020_summer_day)_: +-0.25 v_capacity(C_2020_ANN_IMP_2020) ++0.3 v_flow_out_annual(C_2020_ethos_ANN_IMP_2020_ELC_C) +<= -0.3 + +c_u_planning_reserve_margin_constraint(cap_AB_A_B_elec_AB_2020_summer_day)_: ++1.1 v_flow_out(A_2020_summer_day_NG_NGCC_2015_ELC) ++1.1 v_flow_out(A_2020_summer_day_ethos_SOLPV_2020_ELC) ++1.1 v_flow_out(B_2020_summer_day_NG_NGCC_2020_ELC) ++1.1 v_flow_out(C_B_2020_summer_day_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(A_2020_summer_day_NG_NGCC_2020_ELC) ++1.1 v_flow_out(B_2020_summer_day_ELC_E_LDES_2020_ELC) +-1.1578947368421053 v_flow_out(B_C_2020_summer_day_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(B_2020_summer_day_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(A_2020_summer_day_ethos_SOLPV_2015_ELC) +-1.1578947368421053 v_flow_out(A_C_2020_summer_day_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(A_2020_summer_day_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(A_2020_summer_day_ELC_E_LDES_2020_ELC) ++1.1 v_flow_out(B_2020_summer_day_NG_NGCC_2015_ELC) ++1.1 v_flow_out(C_A_2020_summer_day_ELC_E_TRANS_2015_ELC) +-1.095 v_capacity(B_2020_E_LDES_2020) ++1.752 v_capacity(B_C_2020_E_TRANS_2015) +-2.19 v_capacity(A_2020_NGCC_2015) +-1.971 v_capacity(A_2020_E_BATT_2020) +-1.9272 v_capacity(C_B_2020_E_TRANS_2015) +-1.971 v_capacity(B_2020_E_BATT_2020) +-2.19 v_capacity(B_2020_NGCC_2015) +-2.19 v_capacity(A_2020_NGCC_2020) +-0.32849999999999996 v_capacity(A_2020_SOLPV_2015) ++1.8615 v_capacity(A_C_2020_E_TRANS_2015) +-2.19 v_capacity(B_2020_NGCC_2020) +-1.095 v_capacity(A_2020_E_LDES_2020) +-0.32849999999999996 v_capacity(A_2020_SOLPV_2020) +-2.0805 v_capacity(C_A_2020_E_TRANS_2015) +-1.1 v_flow_in(A_2020_summer_day_ELC_E_LDES_2020_ELC) +-1.1 v_flow_in(B_2020_summer_day_ELC_E_LDES_2020_ELC) +-1.1 v_flow_in(B_2020_summer_day_ELC_E_BATT_2020_ELC) +-1.1 v_flow_in(A_2020_summer_day_ELC_E_BATT_2020_ELC) +<= -2.2 + +c_u_planning_reserve_margin_constraint(cap_A_derate_A_NGCC_2025_winter_day)_: ++1.05 v_flow_out(A_2025_winter_day_NG_NGCC_2020_ELC) ++1.05 v_flow_out(A_2025_winter_day_NG_NGCC_2025_ELC) ++1.05 v_flow_out(A_2025_winter_day_NG_NGCC_2015_ELC) +-1.752 v_capacity(A_2025_NGCC_2025) +-1.752 v_capacity(A_2025_NGCC_2015) +-1.752 v_capacity(A_2025_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_A_derate_A_NGCC_2020_winter_day)_: ++1.05 v_flow_out(A_2020_winter_day_NG_NGCC_2020_ELC) ++1.05 v_flow_out(A_2020_winter_day_NG_NGCC_2015_ELC) +-1.752 v_capacity(A_2020_NGCC_2015) +-1.752 v_capacity(A_2020_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_AB_A_B_elec_AB_2025_summer_night)_: ++1.1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(A_2025_summer_night_ethos_SOLPV_2020_ELC) ++1.1 v_flow_out(A_2025_summer_night_NG_NGCC_2025_ELC) ++1.1 v_flow_out(A_2025_summer_night_ethos_SOLPV_2025_ELC) ++1.1 v_flow_out(B_2025_summer_night_NG_NGCC_2015_ELC) ++1.1 v_flow_out(A_2025_summer_night_NG_NGCC_2015_ELC) ++1.1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2025_ELC) ++1.1 v_flow_out(A_2025_summer_night_ELC_HEAT_SYS_2020_HEAT) ++1.1 v_flow_out(B_2025_summer_night_ELC_HEAT_SYS_2025_HEAT) ++1.1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2020_ELC) ++1.1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2020_ELC) ++1.1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2025_ELC) ++1.1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2025_ELC) ++1.1 v_flow_out(A_2025_summer_night_ethos_SOLPV_2015_ELC) ++1.1 v_flow_out(C_B_2025_summer_night_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(A_2025_summer_night_NG_NGCC_2020_ELC) ++1.1 v_flow_out(B_2025_summer_night_NG_NGCC_2020_ELC) ++1.1 v_flow_out(A_2025_summer_night_ELC_HEAT_SYS_2025_HEAT) ++1.1 v_flow_out(B_2025_summer_night_NG_NGCC_2025_ELC) ++1.1 v_flow_out(C_A_2025_summer_night_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2025_ELC) ++1.1 v_flow_out(B_2025_summer_night_ELC_HEAT_SYS_2020_HEAT) +-1.1578947368421053 v_flow_out(A_C_2025_summer_night_ELC_E_TRANS_2015_ELC) +-1.1578947368421053 v_flow_out(B_C_2025_summer_night_ELC_E_TRANS_2015_ELC) +-1.971 v_capacity(A_2025_E_BATT_2025) +-2.19 v_capacity(B_2025_NGCC_2020) ++1.8615 v_capacity(A_C_2025_E_TRANS_2015) +-2.19 v_capacity(A_2025_NGCC_2025) +-0.32849999999999996 v_capacity(A_2025_SOLPV_2020) +-1.971 v_capacity(B_2025_E_BATT_2025) +-1.095 v_capacity(A_2025_E_LDES_2020) +-2.0805 v_capacity(C_A_2025_E_TRANS_2015) +-1.095 v_capacity(B_2025_E_LDES_2020) +-2.19 v_capacity(A_2025_NGCC_2015) +-2.19 v_capacity(B_2025_NGCC_2025) +-0.32849999999999996 v_capacity(A_2025_SOLPV_2025) ++1.752 v_capacity(B_C_2025_E_TRANS_2015) +-1.971 v_capacity(A_2025_E_BATT_2020) +-1.095 v_capacity(A_2025_E_LDES_2025) +-2.19 v_capacity(B_2025_NGCC_2015) +-1.095 v_capacity(B_2025_E_LDES_2025) +-1.9272 v_capacity(C_B_2025_E_TRANS_2015) +-2.19 v_capacity(A_2025_NGCC_2020) +-0.32849999999999996 v_capacity(A_2025_SOLPV_2015) +-1.971 v_capacity(B_2025_E_BATT_2020) +-1.1 v_flow_in(B_2025_summer_night_ELC_E_BATT_2020_ELC) +-1.1 v_flow_in(A_2025_summer_night_ELC_E_BATT_2025_ELC) +-1.1 v_flow_in(B_2025_summer_night_ELC_E_LDES_2020_ELC) +-1.1 v_flow_in(A_2025_summer_night_ELC_E_LDES_2025_ELC) +-1.1 v_flow_in(A_2025_summer_night_ELC_E_BATT_2020_ELC) +-1.1 v_flow_in(A_2025_summer_night_ELC_E_LDES_2020_ELC) +-1.1 v_flow_in(B_2025_summer_night_ELC_E_BATT_2025_ELC) +-1.1 v_flow_in(B_2025_summer_night_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_A_A_NGCC_2025_summer_day)_: ++1.15 v_flow_out(A_2025_summer_day_NG_NGCC_2015_ELC) ++1.15 v_flow_out(A_2025_summer_day_NG_NGCC_2020_ELC) ++1.15 v_flow_out(A_2025_summer_day_NG_NGCC_2025_ELC) +-2.19 v_capacity(A_2025_NGCC_2025) +-2.19 v_capacity(A_2025_NGCC_2015) +-2.19 v_capacity(A_2025_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_C_C_elec_C_ann_2025_summer_night)_: +-0.25 v_capacity(C_2025_ANN_IMP_2020) ++0.3 v_flow_out_annual(C_2025_ethos_ANN_IMP_2020_ELC_C) +<= -0.33 + +c_u_planning_reserve_margin_constraint(cap_AB_A_B_elec_AB_2020_winter_day)_: ++1.1 v_flow_out(C_A_2020_winter_day_ELC_E_TRANS_2015_ELC) +-1.1578947368421053 v_flow_out(A_C_2020_winter_day_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(A_2020_winter_day_ethos_SOLPV_2020_ELC) ++1.1 v_flow_out(C_B_2020_winter_day_ELC_E_TRANS_2015_ELC) +-1.1578947368421053 v_flow_out(B_C_2020_winter_day_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(B_2020_winter_day_ELC_E_LDES_2020_ELC) ++1.1 v_flow_out(B_2020_winter_day_NG_NGCC_2015_ELC) ++1.1 v_flow_out(A_2020_winter_day_NG_NGCC_2020_ELC) ++1.1 v_flow_out(A_2020_winter_day_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(A_2020_winter_day_ethos_SOLPV_2015_ELC) ++1.1 v_flow_out(B_2020_winter_day_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(A_2020_winter_day_ELC_E_LDES_2020_ELC) ++1.1 v_flow_out(B_2020_winter_day_NG_NGCC_2020_ELC) ++1.1 v_flow_out(A_2020_winter_day_NG_NGCC_2015_ELC) +-1.095 v_capacity(B_2020_E_LDES_2020) ++1.752 v_capacity(B_C_2020_E_TRANS_2015) +-2.19 v_capacity(A_2020_NGCC_2015) +-1.971 v_capacity(A_2020_E_BATT_2020) +-1.9272 v_capacity(C_B_2020_E_TRANS_2015) +-1.971 v_capacity(B_2020_E_BATT_2020) +-2.19 v_capacity(B_2020_NGCC_2015) +-2.19 v_capacity(A_2020_NGCC_2020) +-0.32849999999999996 v_capacity(A_2020_SOLPV_2015) ++1.8615 v_capacity(A_C_2020_E_TRANS_2015) +-2.19 v_capacity(B_2020_NGCC_2020) +-1.095 v_capacity(A_2020_E_LDES_2020) +-0.32849999999999996 v_capacity(A_2020_SOLPV_2020) +-2.0805 v_capacity(C_A_2020_E_TRANS_2015) +-1.1 v_flow_in(A_2020_winter_day_ELC_E_LDES_2020_ELC) +-1.1 v_flow_in(B_2020_winter_day_ELC_E_LDES_2020_ELC) +-1.1 v_flow_in(A_2020_winter_day_ELC_E_BATT_2020_ELC) +-1.1 v_flow_in(B_2020_winter_day_ELC_E_BATT_2020_ELC) +<= -2.2 + +c_u_planning_reserve_margin_constraint(cap_A_A_NGCC_2025_winter_night)_: ++1.15 v_flow_out(A_2025_winter_night_NG_NGCC_2015_ELC) ++1.15 v_flow_out(A_2025_winter_night_NG_NGCC_2020_ELC) ++1.15 v_flow_out(A_2025_winter_night_NG_NGCC_2025_ELC) +-2.19 v_capacity(A_2025_NGCC_2025) +-2.19 v_capacity(A_2025_NGCC_2015) +-2.19 v_capacity(A_2025_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_A_derate_A_NGCC_2025_winter_night)_: ++1.05 v_flow_out(A_2025_winter_night_NG_NGCC_2015_ELC) ++1.05 v_flow_out(A_2025_winter_night_NG_NGCC_2020_ELC) ++1.05 v_flow_out(A_2025_winter_night_NG_NGCC_2025_ELC) +-1.752 v_capacity(A_2025_NGCC_2025) +-1.752 v_capacity(A_2025_NGCC_2015) +-1.752 v_capacity(A_2025_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_C_C_elec_C_ann_2020_winter_day)_: +-0.25 v_capacity(C_2020_ANN_IMP_2020) ++0.3 v_flow_out_annual(C_2020_ethos_ANN_IMP_2020_ELC_C) +<= -0.3 + +c_u_planning_reserve_margin_constraint(cap_AB_A_B_elec_AB_2025_winter_night)_: ++1.1 v_flow_out(A_2025_winter_night_ethos_SOLPV_2025_ELC) ++1.1 v_flow_out(A_2025_winter_night_NG_NGCC_2015_ELC) ++1.1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2020_ELC) ++1.1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(A_2025_winter_night_ELC_HEAT_SYS_2025_HEAT) ++1.1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2025_ELC) ++1.1 v_flow_out(C_B_2025_winter_night_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(B_2025_winter_night_NG_NGCC_2025_ELC) ++1.1 v_flow_out(A_2025_winter_night_ELC_HEAT_SYS_2020_HEAT) ++1.1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2020_ELC) ++1.1 v_flow_out(A_2025_winter_night_ethos_SOLPV_2015_ELC) ++1.1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(A_2025_winter_night_NG_NGCC_2020_ELC) ++1.1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2025_ELC) ++1.1 v_flow_out(B_2025_winter_night_ELC_HEAT_SYS_2020_HEAT) ++1.1 v_flow_out(A_2025_winter_night_ethos_SOLPV_2020_ELC) ++1.1 v_flow_out(C_A_2025_winter_night_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2025_ELC) ++1.1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2025_ELC) ++1.1 v_flow_out(B_2025_winter_night_NG_NGCC_2015_ELC) +-1.1578947368421053 v_flow_out(A_C_2025_winter_night_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(B_2025_winter_night_NG_NGCC_2020_ELC) +-1.1578947368421053 v_flow_out(B_C_2025_winter_night_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(A_2025_winter_night_NG_NGCC_2025_ELC) ++1.1 v_flow_out(B_2025_winter_night_ELC_HEAT_SYS_2025_HEAT) +-1.971 v_capacity(A_2025_E_BATT_2025) +-2.19 v_capacity(B_2025_NGCC_2020) ++1.8615 v_capacity(A_C_2025_E_TRANS_2015) +-2.19 v_capacity(A_2025_NGCC_2025) +-0.32849999999999996 v_capacity(A_2025_SOLPV_2020) +-1.971 v_capacity(B_2025_E_BATT_2025) +-1.095 v_capacity(A_2025_E_LDES_2020) +-2.0805 v_capacity(C_A_2025_E_TRANS_2015) +-1.095 v_capacity(B_2025_E_LDES_2020) +-2.19 v_capacity(A_2025_NGCC_2015) +-2.19 v_capacity(B_2025_NGCC_2025) +-0.32849999999999996 v_capacity(A_2025_SOLPV_2025) ++1.752 v_capacity(B_C_2025_E_TRANS_2015) +-1.971 v_capacity(A_2025_E_BATT_2020) +-1.095 v_capacity(A_2025_E_LDES_2025) +-2.19 v_capacity(B_2025_NGCC_2015) +-1.095 v_capacity(B_2025_E_LDES_2025) +-1.9272 v_capacity(C_B_2025_E_TRANS_2015) +-2.19 v_capacity(A_2025_NGCC_2020) +-0.32849999999999996 v_capacity(A_2025_SOLPV_2015) +-1.971 v_capacity(B_2025_E_BATT_2020) +-1.1 v_flow_in(B_2025_winter_night_ELC_E_LDES_2025_ELC) +-1.1 v_flow_in(A_2025_winter_night_ELC_E_BATT_2025_ELC) +-1.1 v_flow_in(A_2025_winter_night_ELC_E_LDES_2020_ELC) +-1.1 v_flow_in(B_2025_winter_night_ELC_E_LDES_2020_ELC) +-1.1 v_flow_in(A_2025_winter_night_ELC_E_BATT_2020_ELC) +-1.1 v_flow_in(B_2025_winter_night_ELC_E_BATT_2025_ELC) +-1.1 v_flow_in(B_2025_winter_night_ELC_E_BATT_2020_ELC) +-1.1 v_flow_in(A_2025_winter_night_ELC_E_LDES_2025_ELC) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_A_derate_A_NGCC_2025_summer_night)_: ++1.05 v_flow_out(A_2025_summer_night_NG_NGCC_2025_ELC) ++1.05 v_flow_out(A_2025_summer_night_NG_NGCC_2015_ELC) ++1.05 v_flow_out(A_2025_summer_night_NG_NGCC_2020_ELC) +-1.752 v_capacity(A_2025_NGCC_2025) +-1.752 v_capacity(A_2025_NGCC_2015) +-1.752 v_capacity(A_2025_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_C_C_elec_C_ann_2025_winter_night)_: +-0.25 v_capacity(C_2025_ANN_IMP_2020) ++0.3 v_flow_out_annual(C_2025_ethos_ANN_IMP_2020_ELC_C) +<= -0.33 + +c_u_planning_reserve_margin_constraint(cap_C_C_elec_C_ann_2025_summer_day)_: +-0.25 v_capacity(C_2025_ANN_IMP_2020) ++0.3 v_flow_out_annual(C_2025_ethos_ANN_IMP_2020_ELC_C) +<= -0.33 + +c_u_planning_reserve_margin_constraint(cap_A_A_NGCC_2020_summer_night)_: ++1.15 v_flow_out(A_2020_summer_night_NG_NGCC_2015_ELC) ++1.15 v_flow_out(A_2020_summer_night_NG_NGCC_2020_ELC) +-2.19 v_capacity(A_2020_NGCC_2015) +-2.19 v_capacity(A_2020_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_A_derate_A_NGCC_2020_summer_night)_: ++1.05 v_flow_out(A_2020_summer_night_NG_NGCC_2015_ELC) ++1.05 v_flow_out(A_2020_summer_night_NG_NGCC_2020_ELC) +-1.752 v_capacity(A_2020_NGCC_2015) +-1.752 v_capacity(A_2020_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_AB_A_B_elec_AB_2025_summer_day)_: ++1.1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(A_2025_summer_day_ELC_HEAT_SYS_2025_HEAT) ++1.1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2025_ELC) ++1.1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(A_2025_summer_day_ethos_SOLPV_2020_ELC) ++1.1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2020_ELC) ++1.1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2025_ELC) ++1.1 v_flow_out(A_2025_summer_day_ethos_SOLPV_2025_ELC) ++1.1 v_flow_out(A_2025_summer_day_NG_NGCC_2015_ELC) ++1.1 v_flow_out(B_2025_summer_day_ELC_HEAT_SYS_2025_HEAT) ++1.1 v_flow_out(B_2025_summer_day_NG_NGCC_2025_ELC) ++1.1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2025_ELC) ++1.1 v_flow_out(A_2025_summer_day_NG_NGCC_2020_ELC) ++1.1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2025_ELC) ++1.1 v_flow_out(B_2025_summer_day_NG_NGCC_2015_ELC) ++1.1 v_flow_out(A_2025_summer_day_ELC_HEAT_SYS_2020_HEAT) ++1.1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2020_ELC) ++1.1 v_flow_out(A_2025_summer_day_ethos_SOLPV_2015_ELC) +-1.1578947368421053 v_flow_out(B_C_2025_summer_day_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(C_A_2025_summer_day_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(C_B_2025_summer_day_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(A_2025_summer_day_NG_NGCC_2025_ELC) ++1.1 v_flow_out(B_2025_summer_day_ELC_HEAT_SYS_2020_HEAT) +-1.1578947368421053 v_flow_out(A_C_2025_summer_day_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(B_2025_summer_day_NG_NGCC_2020_ELC) +-1.971 v_capacity(A_2025_E_BATT_2025) +-2.19 v_capacity(B_2025_NGCC_2020) ++1.8615 v_capacity(A_C_2025_E_TRANS_2015) +-2.19 v_capacity(A_2025_NGCC_2025) +-0.32849999999999996 v_capacity(A_2025_SOLPV_2020) +-1.971 v_capacity(B_2025_E_BATT_2025) +-1.095 v_capacity(A_2025_E_LDES_2020) +-2.0805 v_capacity(C_A_2025_E_TRANS_2015) +-1.095 v_capacity(B_2025_E_LDES_2020) +-2.19 v_capacity(A_2025_NGCC_2015) +-2.19 v_capacity(B_2025_NGCC_2025) +-0.32849999999999996 v_capacity(A_2025_SOLPV_2025) ++1.752 v_capacity(B_C_2025_E_TRANS_2015) +-1.971 v_capacity(A_2025_E_BATT_2020) +-1.095 v_capacity(A_2025_E_LDES_2025) +-2.19 v_capacity(B_2025_NGCC_2015) +-1.095 v_capacity(B_2025_E_LDES_2025) +-1.9272 v_capacity(C_B_2025_E_TRANS_2015) +-2.19 v_capacity(A_2025_NGCC_2020) +-0.32849999999999996 v_capacity(A_2025_SOLPV_2015) +-1.971 v_capacity(B_2025_E_BATT_2020) +-1.1 v_flow_in(B_2025_summer_day_ELC_E_BATT_2025_ELC) +-1.1 v_flow_in(A_2025_summer_day_ELC_E_BATT_2020_ELC) +-1.1 v_flow_in(B_2025_summer_day_ELC_E_LDES_2025_ELC) +-1.1 v_flow_in(A_2025_summer_day_ELC_E_LDES_2025_ELC) +-1.1 v_flow_in(B_2025_summer_day_ELC_E_BATT_2020_ELC) +-1.1 v_flow_in(A_2025_summer_day_ELC_E_LDES_2020_ELC) +-1.1 v_flow_in(B_2025_summer_day_ELC_E_LDES_2020_ELC) +-1.1 v_flow_in(A_2025_summer_day_ELC_E_BATT_2025_ELC) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_A_A_NGCC_2025_winter_day)_: ++1.15 v_flow_out(A_2025_winter_day_NG_NGCC_2020_ELC) ++1.15 v_flow_out(A_2025_winter_day_NG_NGCC_2025_ELC) ++1.15 v_flow_out(A_2025_winter_day_NG_NGCC_2015_ELC) +-2.19 v_capacity(A_2025_NGCC_2025) +-2.19 v_capacity(A_2025_NGCC_2015) +-2.19 v_capacity(A_2025_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_AB_A_B_elec_AB_2025_winter_day)_: ++1.1 v_flow_out(B_2025_winter_day_NG_NGCC_2015_ELC) ++1.1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2025_ELC) ++1.1 v_flow_out(A_2025_winter_day_NG_NGCC_2020_ELC) ++1.1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2025_ELC) ++1.1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2025_ELC) ++1.1 v_flow_out(A_2025_winter_day_ELC_HEAT_SYS_2020_HEAT) ++1.1 v_flow_out(A_2025_winter_day_NG_NGCC_2025_ELC) ++1.1 v_flow_out(B_2025_winter_day_ELC_HEAT_SYS_2025_HEAT) +-1.1578947368421053 v_flow_out(A_C_2025_winter_day_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(A_2025_winter_day_ethos_SOLPV_2025_ELC) ++1.1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2025_ELC) ++1.1 v_flow_out(B_2025_winter_day_NG_NGCC_2020_ELC) ++1.1 v_flow_out(C_A_2025_winter_day_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(A_2025_winter_day_ELC_HEAT_SYS_2025_HEAT) ++1.1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2020_ELC) ++1.1 v_flow_out(A_2025_winter_day_NG_NGCC_2015_ELC) ++1.1 v_flow_out(C_B_2025_winter_day_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(A_2025_winter_day_ethos_SOLPV_2015_ELC) ++1.1 v_flow_out(B_2025_winter_day_ELC_HEAT_SYS_2020_HEAT) +-1.1578947368421053 v_flow_out(B_C_2025_winter_day_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(B_2025_winter_day_NG_NGCC_2025_ELC) ++1.1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(A_2025_winter_day_ethos_SOLPV_2020_ELC) ++1.1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2020_ELC) +-1.971 v_capacity(A_2025_E_BATT_2025) +-2.19 v_capacity(B_2025_NGCC_2020) ++1.8615 v_capacity(A_C_2025_E_TRANS_2015) +-2.19 v_capacity(A_2025_NGCC_2025) +-0.32849999999999996 v_capacity(A_2025_SOLPV_2020) +-1.971 v_capacity(B_2025_E_BATT_2025) +-1.095 v_capacity(A_2025_E_LDES_2020) +-2.0805 v_capacity(C_A_2025_E_TRANS_2015) +-1.095 v_capacity(B_2025_E_LDES_2020) +-2.19 v_capacity(A_2025_NGCC_2015) +-2.19 v_capacity(B_2025_NGCC_2025) +-0.32849999999999996 v_capacity(A_2025_SOLPV_2025) ++1.752 v_capacity(B_C_2025_E_TRANS_2015) +-1.971 v_capacity(A_2025_E_BATT_2020) +-1.095 v_capacity(A_2025_E_LDES_2025) +-2.19 v_capacity(B_2025_NGCC_2015) +-1.095 v_capacity(B_2025_E_LDES_2025) +-1.9272 v_capacity(C_B_2025_E_TRANS_2015) +-2.19 v_capacity(A_2025_NGCC_2020) +-0.32849999999999996 v_capacity(A_2025_SOLPV_2015) +-1.971 v_capacity(B_2025_E_BATT_2020) +-1.1 v_flow_in(A_2025_winter_day_ELC_E_LDES_2025_ELC) +-1.1 v_flow_in(B_2025_winter_day_ELC_E_BATT_2025_ELC) +-1.1 v_flow_in(A_2025_winter_day_ELC_E_BATT_2025_ELC) +-1.1 v_flow_in(A_2025_winter_day_ELC_E_LDES_2020_ELC) +-1.1 v_flow_in(B_2025_winter_day_ELC_E_LDES_2025_ELC) +-1.1 v_flow_in(B_2025_winter_day_ELC_E_BATT_2020_ELC) +-1.1 v_flow_in(A_2025_winter_day_ELC_E_BATT_2020_ELC) +-1.1 v_flow_in(B_2025_winter_day_ELC_E_LDES_2020_ELC) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_A_derate_A_NGCC_2025_summer_day)_: ++1.05 v_flow_out(A_2025_summer_day_NG_NGCC_2015_ELC) ++1.05 v_flow_out(A_2025_summer_day_NG_NGCC_2020_ELC) ++1.05 v_flow_out(A_2025_summer_day_NG_NGCC_2025_ELC) +-1.752 v_capacity(A_2025_NGCC_2025) +-1.752 v_capacity(A_2025_NGCC_2015) +-1.752 v_capacity(A_2025_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_C_C_elec_C_ann_2025_winter_day)_: +-0.25 v_capacity(C_2025_ANN_IMP_2020) ++0.3 v_flow_out_annual(C_2025_ethos_ANN_IMP_2020_ELC_C) +<= -0.33 + +c_u_planning_reserve_margin_constraint(cap_A_A_NGCC_2020_winter_night)_: ++1.15 v_flow_out(A_2020_winter_night_NG_NGCC_2020_ELC) ++1.15 v_flow_out(A_2020_winter_night_NG_NGCC_2015_ELC) +-2.19 v_capacity(A_2020_NGCC_2015) +-2.19 v_capacity(A_2020_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_AB_A_B_elec_AB_2020_summer_night)_: ++1.1 v_flow_out(A_2020_summer_night_ethos_SOLPV_2020_ELC) ++1.1 v_flow_out(B_2020_summer_night_NG_NGCC_2020_ELC) ++1.1 v_flow_out(A_2020_summer_night_NG_NGCC_2015_ELC) ++1.1 v_flow_out(A_2020_summer_night_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(B_2020_summer_night_ELC_E_LDES_2020_ELC) ++1.1 v_flow_out(A_2020_summer_night_NG_NGCC_2020_ELC) +-1.1578947368421053 v_flow_out(A_C_2020_summer_night_ELC_E_TRANS_2015_ELC) +-1.1578947368421053 v_flow_out(B_C_2020_summer_night_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(A_2020_summer_night_ELC_E_LDES_2020_ELC) ++1.1 v_flow_out(C_B_2020_summer_night_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(B_2020_summer_night_ELC_E_BATT_2020_ELC) ++1.1 v_flow_out(A_2020_summer_night_ethos_SOLPV_2015_ELC) ++1.1 v_flow_out(C_A_2020_summer_night_ELC_E_TRANS_2015_ELC) ++1.1 v_flow_out(B_2020_summer_night_NG_NGCC_2015_ELC) +-1.095 v_capacity(B_2020_E_LDES_2020) ++1.752 v_capacity(B_C_2020_E_TRANS_2015) +-2.19 v_capacity(A_2020_NGCC_2015) +-1.971 v_capacity(A_2020_E_BATT_2020) +-1.9272 v_capacity(C_B_2020_E_TRANS_2015) +-1.971 v_capacity(B_2020_E_BATT_2020) +-2.19 v_capacity(B_2020_NGCC_2015) +-2.19 v_capacity(A_2020_NGCC_2020) +-0.32849999999999996 v_capacity(A_2020_SOLPV_2015) ++1.8615 v_capacity(A_C_2020_E_TRANS_2015) +-2.19 v_capacity(B_2020_NGCC_2020) +-1.095 v_capacity(A_2020_E_LDES_2020) +-0.32849999999999996 v_capacity(A_2020_SOLPV_2020) +-2.0805 v_capacity(C_A_2020_E_TRANS_2015) +-1.1 v_flow_in(B_2020_summer_night_ELC_E_BATT_2020_ELC) +-1.1 v_flow_in(A_2020_summer_night_ELC_E_BATT_2020_ELC) +-1.1 v_flow_in(B_2020_summer_night_ELC_E_LDES_2020_ELC) +-1.1 v_flow_in(A_2020_summer_night_ELC_E_LDES_2020_ELC) +<= -2.2 + +c_u_planning_reserve_margin_constraint(cap_A_A_NGCC_2020_summer_day)_: ++1.15 v_flow_out(A_2020_summer_day_NG_NGCC_2015_ELC) ++1.15 v_flow_out(A_2020_summer_day_NG_NGCC_2020_ELC) +-2.19 v_capacity(A_2020_NGCC_2015) +-2.19 v_capacity(A_2020_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_A_derate_A_NGCC_2020_summer_day)_: ++1.05 v_flow_out(A_2020_summer_day_NG_NGCC_2015_ELC) ++1.05 v_flow_out(A_2020_summer_day_NG_NGCC_2020_ELC) +-1.752 v_capacity(A_2020_NGCC_2015) +-1.752 v_capacity(A_2020_NGCC_2020) +<= 0 + +c_u_planning_reserve_margin_constraint(cap_C_C_elec_C_ann_2020_summer_night)_: +-0.25 v_capacity(C_2020_ANN_IMP_2020) ++0.3 v_flow_out_annual(C_2020_ethos_ANN_IMP_2020_ELC_C) +<= -0.3 + +c_u_uc_online_upper_constraint(A_B_2020_winter_day_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2020_E_TRANS_2015) ++1 v_uc_online(A_B_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(A_2020_summer_day_NGCC_2015)_: +-10.0 v_capacity(A_2020_NGCC_2015) ++1 v_uc_online(A_2020_summer_day_NGCC_2015) +<= 0 + +c_u_uc_online_upper_constraint(A_2025_summer_night_NGCC_2015)_: +-10.0 v_capacity(A_2025_NGCC_2015) ++1 v_uc_online(A_2025_summer_night_NGCC_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_summer_day_E_LDES_2025)_: +-50.0 v_capacity(B_2025_E_LDES_2025) ++1 v_uc_online(B_2025_summer_day_E_LDES_2025) +<= 0 + +c_u_uc_online_upper_constraint(B_A_2025_winter_day_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2025_E_TRANS_2015) ++1 v_uc_online(B_A_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(A_2020_winter_night_NGCC_2020)_: +-10.0 v_capacity(A_2020_NGCC_2020) ++1 v_uc_online(A_2020_winter_night_NGCC_2020) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_summer_night_E_BATT_2020)_: +-20.0 v_capacity(B_2025_E_BATT_2020) ++1 v_uc_online(B_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_uc_online_upper_constraint(A_2025_winter_day_NGCC_2015)_: +-10.0 v_capacity(A_2025_NGCC_2015) ++1 v_uc_online(A_2025_winter_day_NGCC_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_winter_night_E_BATT_2025)_: +-20.0 v_capacity(B_2025_E_BATT_2025) ++1 v_uc_online(B_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_summer_day_E_BATT_2020)_: +-20.0 v_capacity(B_2025_E_BATT_2020) ++1 v_uc_online(B_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_uc_online_upper_constraint(A_2025_summer_day_NGCC_2025)_: +-10.0 v_capacity(A_2025_NGCC_2025) ++1 v_uc_online(A_2025_summer_day_NGCC_2025) +<= 0 + +c_u_uc_online_upper_constraint(A_2025_winter_night_NGCC_2015)_: +-10.0 v_capacity(A_2025_NGCC_2015) ++1 v_uc_online(A_2025_winter_night_NGCC_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_A_2020_winter_night_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2020_E_TRANS_2015) ++1 v_uc_online(B_A_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_2020_summer_day_E_LDES_2020)_: +-50.0 v_capacity(B_2020_E_LDES_2020) ++1 v_uc_online(B_2020_summer_day_E_LDES_2020) +<= 0 + +c_u_uc_online_upper_constraint(A_2020_summer_night_NGCC_2020)_: +-10.0 v_capacity(A_2020_NGCC_2020) ++1 v_uc_online(A_2020_summer_night_NGCC_2020) +<= 0 + +c_u_uc_online_upper_constraint(B_2020_winter_night_E_LDES_2020)_: +-50.0 v_capacity(B_2020_E_LDES_2020) ++1 v_uc_online(B_2020_winter_night_E_LDES_2020) +<= 0 + +c_u_uc_online_upper_constraint(A_B_2025_summer_night_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2025_E_TRANS_2015) ++1 v_uc_online(A_B_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_2020_summer_night_E_LDES_2020)_: +-50.0 v_capacity(B_2020_E_LDES_2020) ++1 v_uc_online(B_2020_summer_night_E_LDES_2020) +<= 0 + +c_u_uc_online_upper_constraint(A_B_2020_summer_day_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2020_E_TRANS_2015) ++1 v_uc_online(A_B_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_2020_winter_day_E_LDES_2020)_: +-50.0 v_capacity(B_2020_E_LDES_2020) ++1 v_uc_online(B_2020_winter_day_E_LDES_2020) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_winter_day_E_LDES_2020)_: +-50.0 v_capacity(B_2025_E_LDES_2020) ++1 v_uc_online(B_2025_winter_day_E_LDES_2020) +<= 0 + +c_u_uc_online_upper_constraint(A_2020_summer_day_NGCC_2020)_: +-10.0 v_capacity(A_2020_NGCC_2020) ++1 v_uc_online(A_2020_summer_day_NGCC_2020) +<= 0 + +c_u_uc_online_upper_constraint(A_2025_summer_night_NGCC_2020)_: +-10.0 v_capacity(A_2025_NGCC_2020) ++1 v_uc_online(A_2025_summer_night_NGCC_2020) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_summer_night_E_BATT_2025)_: +-20.0 v_capacity(B_2025_E_BATT_2025) ++1 v_uc_online(B_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_uc_online_upper_constraint(B_A_2020_summer_day_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2020_E_TRANS_2015) ++1 v_uc_online(B_A_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(A_2025_winter_day_NGCC_2020)_: +-10.0 v_capacity(A_2025_NGCC_2020) ++1 v_uc_online(A_2025_winter_day_NGCC_2020) +<= 0 + +c_u_uc_online_upper_constraint(A_2025_summer_day_NGCC_2015)_: +-10.0 v_capacity(A_2025_NGCC_2015) ++1 v_uc_online(A_2025_summer_day_NGCC_2015) +<= 0 + +c_u_uc_online_upper_constraint(A_2020_winter_day_NGCC_2015)_: +-10.0 v_capacity(A_2020_NGCC_2015) ++1 v_uc_online(A_2020_winter_day_NGCC_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_winter_night_E_LDES_2020)_: +-50.0 v_capacity(B_2025_E_LDES_2020) ++1 v_uc_online(B_2025_winter_night_E_LDES_2020) +<= 0 + +c_u_uc_online_upper_constraint(A_B_2025_winter_day_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2025_E_TRANS_2015) ++1 v_uc_online(A_B_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_A_2025_summer_night_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2025_E_TRANS_2015) ++1 v_uc_online(B_A_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_A_2025_winter_night_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2025_E_TRANS_2015) ++1 v_uc_online(B_A_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_2020_summer_day_E_BATT_2020)_: +-20.0 v_capacity(B_2020_E_BATT_2020) ++1 v_uc_online(B_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_summer_day_E_BATT_2025)_: +-20.0 v_capacity(B_2025_E_BATT_2025) ++1 v_uc_online(B_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_winter_day_E_BATT_2020)_: +-20.0 v_capacity(B_2025_E_BATT_2020) ++1 v_uc_online(B_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_uc_online_upper_constraint(A_2025_winter_night_NGCC_2020)_: +-10.0 v_capacity(A_2025_NGCC_2020) ++1 v_uc_online(A_2025_winter_night_NGCC_2020) +<= 0 + +c_u_uc_online_upper_constraint(A_B_2020_winter_night_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2020_E_TRANS_2015) ++1 v_uc_online(A_B_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_2020_summer_night_E_BATT_2020)_: +-20.0 v_capacity(B_2020_E_BATT_2020) ++1 v_uc_online(B_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_summer_night_E_LDES_2020)_: +-50.0 v_capacity(B_2025_E_LDES_2020) ++1 v_uc_online(B_2025_summer_night_E_LDES_2020) +<= 0 + +c_u_uc_online_upper_constraint(A_B_2025_winter_night_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2025_E_TRANS_2015) ++1 v_uc_online(A_B_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_A_2020_winter_day_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2020_E_TRANS_2015) ++1 v_uc_online(B_A_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_summer_day_E_LDES_2020)_: +-50.0 v_capacity(B_2025_E_LDES_2020) ++1 v_uc_online(B_2025_summer_day_E_LDES_2020) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_winter_day_E_LDES_2025)_: +-50.0 v_capacity(B_2025_E_LDES_2025) ++1 v_uc_online(B_2025_winter_day_E_LDES_2025) +<= 0 + +c_u_uc_online_upper_constraint(B_2020_winter_day_E_BATT_2020)_: +-20.0 v_capacity(B_2020_E_BATT_2020) ++1 v_uc_online(B_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_uc_online_upper_constraint(B_2020_winter_night_E_BATT_2020)_: +-20.0 v_capacity(B_2020_E_BATT_2020) ++1 v_uc_online(B_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_uc_online_upper_constraint(A_2020_winter_night_NGCC_2015)_: +-10.0 v_capacity(A_2020_NGCC_2015) ++1 v_uc_online(A_2020_winter_night_NGCC_2015) +<= 0 + +c_u_uc_online_upper_constraint(A_2025_summer_night_NGCC_2025)_: +-10.0 v_capacity(A_2025_NGCC_2025) ++1 v_uc_online(A_2025_summer_night_NGCC_2025) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_winter_night_E_BATT_2020)_: +-20.0 v_capacity(B_2025_E_BATT_2020) ++1 v_uc_online(B_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_winter_night_E_LDES_2025)_: +-50.0 v_capacity(B_2025_E_LDES_2025) ++1 v_uc_online(B_2025_winter_night_E_LDES_2025) +<= 0 + +c_u_uc_online_upper_constraint(A_B_2025_summer_day_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2025_E_TRANS_2015) ++1 v_uc_online(A_B_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(A_2020_winter_day_NGCC_2020)_: +-10.0 v_capacity(A_2020_NGCC_2020) ++1 v_uc_online(A_2020_winter_day_NGCC_2020) +<= 0 + +c_u_uc_online_upper_constraint(A_2025_winter_day_NGCC_2025)_: +-10.0 v_capacity(A_2025_NGCC_2025) ++1 v_uc_online(A_2025_winter_day_NGCC_2025) +<= 0 + +c_u_uc_online_upper_constraint(A_2025_summer_day_NGCC_2020)_: +-10.0 v_capacity(A_2025_NGCC_2020) ++1 v_uc_online(A_2025_summer_day_NGCC_2020) +<= 0 + +c_u_uc_online_upper_constraint(A_2020_summer_night_NGCC_2015)_: +-10.0 v_capacity(A_2020_NGCC_2015) ++1 v_uc_online(A_2020_summer_night_NGCC_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_A_2020_summer_night_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2020_E_TRANS_2015) ++1 v_uc_online(B_A_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_winter_day_E_BATT_2025)_: +-20.0 v_capacity(B_2025_E_BATT_2025) ++1 v_uc_online(B_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_uc_online_upper_constraint(A_B_2020_summer_night_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2020_E_TRANS_2015) ++1 v_uc_online(A_B_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(B_A_2025_summer_day_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2025_E_TRANS_2015) ++1 v_uc_online(B_A_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_online_upper_constraint(A_2025_winter_night_NGCC_2025)_: +-10.0 v_capacity(A_2025_NGCC_2025) ++1 v_uc_online(A_2025_winter_night_NGCC_2025) +<= 0 + +c_u_uc_online_upper_constraint(B_2025_summer_night_E_LDES_2025)_: +-50.0 v_capacity(B_2025_E_LDES_2025) ++1 v_uc_online(B_2025_summer_night_E_LDES_2025) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_B_2020_winter_day_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2020_E_TRANS_2015) ++1 v_uc_online(A_B_2020_winter_day_E_TRANS_2015) ++1 v_uc_started(A_B_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2020_summer_day_NGCC_2015)_: +-10.0 v_capacity(A_2020_NGCC_2015) ++1 v_uc_online(A_2020_summer_day_NGCC_2015) ++1 v_uc_started(A_2020_summer_day_NGCC_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2025_summer_night_NGCC_2015)_: +-10.0 v_capacity(A_2025_NGCC_2015) ++1 v_uc_online(A_2025_summer_night_NGCC_2015) ++1 v_uc_started(A_2025_summer_night_NGCC_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_summer_day_E_LDES_2025)_: +-50.0 v_capacity(B_2025_E_LDES_2025) ++1 v_uc_online(B_2025_summer_day_E_LDES_2025) ++1 v_uc_started(B_2025_summer_day_E_LDES_2025) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_A_2025_winter_day_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2025_E_TRANS_2015) ++1 v_uc_online(B_A_2025_winter_day_E_TRANS_2015) ++1 v_uc_started(B_A_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2020_winter_night_NGCC_2020)_: +-10.0 v_capacity(A_2020_NGCC_2020) ++1 v_uc_online(A_2020_winter_night_NGCC_2020) ++1 v_uc_started(A_2020_winter_night_NGCC_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_summer_night_E_BATT_2020)_: +-20.0 v_capacity(B_2025_E_BATT_2020) ++1 v_uc_online(B_2025_summer_night_E_BATT_2020) ++1 v_uc_started(B_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2025_winter_day_NGCC_2015)_: +-10.0 v_capacity(A_2025_NGCC_2015) ++1 v_uc_online(A_2025_winter_day_NGCC_2015) ++1 v_uc_started(A_2025_winter_day_NGCC_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_winter_night_E_BATT_2025)_: +-20.0 v_capacity(B_2025_E_BATT_2025) ++1 v_uc_online(B_2025_winter_night_E_BATT_2025) ++1 v_uc_started(B_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_summer_day_E_BATT_2020)_: +-20.0 v_capacity(B_2025_E_BATT_2020) ++1 v_uc_online(B_2025_summer_day_E_BATT_2020) ++1 v_uc_started(B_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2025_summer_day_NGCC_2025)_: +-10.0 v_capacity(A_2025_NGCC_2025) ++1 v_uc_online(A_2025_summer_day_NGCC_2025) ++1 v_uc_started(A_2025_summer_day_NGCC_2025) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2025_winter_night_NGCC_2015)_: +-10.0 v_capacity(A_2025_NGCC_2015) ++1 v_uc_online(A_2025_winter_night_NGCC_2015) ++1 v_uc_started(A_2025_winter_night_NGCC_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_A_2020_winter_night_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2020_E_TRANS_2015) ++1 v_uc_online(B_A_2020_winter_night_E_TRANS_2015) ++1 v_uc_started(B_A_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2020_summer_day_E_LDES_2020)_: +-50.0 v_capacity(B_2020_E_LDES_2020) ++1 v_uc_online(B_2020_summer_day_E_LDES_2020) ++1 v_uc_started(B_2020_summer_day_E_LDES_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2020_summer_night_NGCC_2020)_: +-10.0 v_capacity(A_2020_NGCC_2020) ++1 v_uc_online(A_2020_summer_night_NGCC_2020) ++1 v_uc_started(A_2020_summer_night_NGCC_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2020_winter_night_E_LDES_2020)_: +-50.0 v_capacity(B_2020_E_LDES_2020) ++1 v_uc_online(B_2020_winter_night_E_LDES_2020) ++1 v_uc_started(B_2020_winter_night_E_LDES_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_B_2025_summer_night_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2025_E_TRANS_2015) ++1 v_uc_online(A_B_2025_summer_night_E_TRANS_2015) ++1 v_uc_started(A_B_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2020_summer_night_E_LDES_2020)_: +-50.0 v_capacity(B_2020_E_LDES_2020) ++1 v_uc_online(B_2020_summer_night_E_LDES_2020) ++1 v_uc_started(B_2020_summer_night_E_LDES_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_B_2020_summer_day_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2020_E_TRANS_2015) ++1 v_uc_online(A_B_2020_summer_day_E_TRANS_2015) ++1 v_uc_started(A_B_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2020_winter_day_E_LDES_2020)_: +-50.0 v_capacity(B_2020_E_LDES_2020) ++1 v_uc_online(B_2020_winter_day_E_LDES_2020) ++1 v_uc_started(B_2020_winter_day_E_LDES_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_winter_day_E_LDES_2020)_: +-50.0 v_capacity(B_2025_E_LDES_2020) ++1 v_uc_online(B_2025_winter_day_E_LDES_2020) ++1 v_uc_started(B_2025_winter_day_E_LDES_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2020_summer_day_NGCC_2020)_: +-10.0 v_capacity(A_2020_NGCC_2020) ++1 v_uc_online(A_2020_summer_day_NGCC_2020) ++1 v_uc_started(A_2020_summer_day_NGCC_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2025_summer_night_NGCC_2020)_: +-10.0 v_capacity(A_2025_NGCC_2020) ++1 v_uc_online(A_2025_summer_night_NGCC_2020) ++1 v_uc_started(A_2025_summer_night_NGCC_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_summer_night_E_BATT_2025)_: +-20.0 v_capacity(B_2025_E_BATT_2025) ++1 v_uc_online(B_2025_summer_night_E_BATT_2025) ++1 v_uc_started(B_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_A_2020_summer_day_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2020_E_TRANS_2015) ++1 v_uc_online(B_A_2020_summer_day_E_TRANS_2015) ++1 v_uc_started(B_A_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2025_winter_day_NGCC_2020)_: +-10.0 v_capacity(A_2025_NGCC_2020) ++1 v_uc_online(A_2025_winter_day_NGCC_2020) ++1 v_uc_started(A_2025_winter_day_NGCC_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2025_summer_day_NGCC_2015)_: +-10.0 v_capacity(A_2025_NGCC_2015) ++1 v_uc_online(A_2025_summer_day_NGCC_2015) ++1 v_uc_started(A_2025_summer_day_NGCC_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2020_winter_day_NGCC_2015)_: +-10.0 v_capacity(A_2020_NGCC_2015) ++1 v_uc_online(A_2020_winter_day_NGCC_2015) ++1 v_uc_started(A_2020_winter_day_NGCC_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_winter_night_E_LDES_2020)_: +-50.0 v_capacity(B_2025_E_LDES_2020) ++1 v_uc_online(B_2025_winter_night_E_LDES_2020) ++1 v_uc_started(B_2025_winter_night_E_LDES_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_B_2025_winter_day_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2025_E_TRANS_2015) ++1 v_uc_online(A_B_2025_winter_day_E_TRANS_2015) ++1 v_uc_started(A_B_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_A_2025_summer_night_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2025_E_TRANS_2015) ++1 v_uc_online(B_A_2025_summer_night_E_TRANS_2015) ++1 v_uc_started(B_A_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_A_2025_winter_night_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2025_E_TRANS_2015) ++1 v_uc_online(B_A_2025_winter_night_E_TRANS_2015) ++1 v_uc_started(B_A_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2020_summer_day_E_BATT_2020)_: +-20.0 v_capacity(B_2020_E_BATT_2020) ++1 v_uc_online(B_2020_summer_day_E_BATT_2020) ++1 v_uc_started(B_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_summer_day_E_BATT_2025)_: +-20.0 v_capacity(B_2025_E_BATT_2025) ++1 v_uc_online(B_2025_summer_day_E_BATT_2025) ++1 v_uc_started(B_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_winter_day_E_BATT_2020)_: +-20.0 v_capacity(B_2025_E_BATT_2020) ++1 v_uc_online(B_2025_winter_day_E_BATT_2020) ++1 v_uc_started(B_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2025_winter_night_NGCC_2020)_: +-10.0 v_capacity(A_2025_NGCC_2020) ++1 v_uc_online(A_2025_winter_night_NGCC_2020) ++1 v_uc_started(A_2025_winter_night_NGCC_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_B_2020_winter_night_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2020_E_TRANS_2015) ++1 v_uc_online(A_B_2020_winter_night_E_TRANS_2015) ++1 v_uc_started(A_B_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2020_summer_night_E_BATT_2020)_: +-20.0 v_capacity(B_2020_E_BATT_2020) ++1 v_uc_online(B_2020_summer_night_E_BATT_2020) ++1 v_uc_started(B_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_summer_night_E_LDES_2020)_: +-50.0 v_capacity(B_2025_E_LDES_2020) ++1 v_uc_online(B_2025_summer_night_E_LDES_2020) ++1 v_uc_started(B_2025_summer_night_E_LDES_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_B_2025_winter_night_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2025_E_TRANS_2015) ++1 v_uc_online(A_B_2025_winter_night_E_TRANS_2015) ++1 v_uc_started(A_B_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_A_2020_winter_day_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2020_E_TRANS_2015) ++1 v_uc_online(B_A_2020_winter_day_E_TRANS_2015) ++1 v_uc_started(B_A_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_summer_day_E_LDES_2020)_: +-50.0 v_capacity(B_2025_E_LDES_2020) ++1 v_uc_online(B_2025_summer_day_E_LDES_2020) ++1 v_uc_started(B_2025_summer_day_E_LDES_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_winter_day_E_LDES_2025)_: +-50.0 v_capacity(B_2025_E_LDES_2025) ++1 v_uc_online(B_2025_winter_day_E_LDES_2025) ++1 v_uc_started(B_2025_winter_day_E_LDES_2025) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2020_winter_day_E_BATT_2020)_: +-20.0 v_capacity(B_2020_E_BATT_2020) ++1 v_uc_online(B_2020_winter_day_E_BATT_2020) ++1 v_uc_started(B_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2020_winter_night_E_BATT_2020)_: +-20.0 v_capacity(B_2020_E_BATT_2020) ++1 v_uc_online(B_2020_winter_night_E_BATT_2020) ++1 v_uc_started(B_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2020_winter_night_NGCC_2015)_: +-10.0 v_capacity(A_2020_NGCC_2015) ++1 v_uc_online(A_2020_winter_night_NGCC_2015) ++1 v_uc_started(A_2020_winter_night_NGCC_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2025_summer_night_NGCC_2025)_: +-10.0 v_capacity(A_2025_NGCC_2025) ++1 v_uc_online(A_2025_summer_night_NGCC_2025) ++1 v_uc_started(A_2025_summer_night_NGCC_2025) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_winter_night_E_BATT_2020)_: +-20.0 v_capacity(B_2025_E_BATT_2020) ++1 v_uc_online(B_2025_winter_night_E_BATT_2020) ++1 v_uc_started(B_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_winter_night_E_LDES_2025)_: +-50.0 v_capacity(B_2025_E_LDES_2025) ++1 v_uc_online(B_2025_winter_night_E_LDES_2025) ++1 v_uc_started(B_2025_winter_night_E_LDES_2025) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_B_2025_summer_day_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2025_E_TRANS_2015) ++1 v_uc_online(A_B_2025_summer_day_E_TRANS_2015) ++1 v_uc_started(A_B_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2020_winter_day_NGCC_2020)_: +-10.0 v_capacity(A_2020_NGCC_2020) ++1 v_uc_online(A_2020_winter_day_NGCC_2020) ++1 v_uc_started(A_2020_winter_day_NGCC_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2025_winter_day_NGCC_2025)_: +-10.0 v_capacity(A_2025_NGCC_2025) ++1 v_uc_online(A_2025_winter_day_NGCC_2025) ++1 v_uc_started(A_2025_winter_day_NGCC_2025) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2025_summer_day_NGCC_2020)_: +-10.0 v_capacity(A_2025_NGCC_2020) ++1 v_uc_online(A_2025_summer_day_NGCC_2020) ++1 v_uc_started(A_2025_summer_day_NGCC_2020) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2020_summer_night_NGCC_2015)_: +-10.0 v_capacity(A_2020_NGCC_2015) ++1 v_uc_online(A_2020_summer_night_NGCC_2015) ++1 v_uc_started(A_2020_summer_night_NGCC_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_A_2020_summer_night_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2020_E_TRANS_2015) ++1 v_uc_online(B_A_2020_summer_night_E_TRANS_2015) ++1 v_uc_started(B_A_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_winter_day_E_BATT_2025)_: +-20.0 v_capacity(B_2025_E_BATT_2025) ++1 v_uc_online(B_2025_winter_day_E_BATT_2025) ++1 v_uc_started(B_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_B_2020_summer_night_E_TRANS_2015)_: +-5.0 v_capacity(A_B_2020_E_TRANS_2015) ++1 v_uc_online(A_B_2020_summer_night_E_TRANS_2015) ++1 v_uc_started(A_B_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_A_2025_summer_day_E_TRANS_2015)_: +-5.0 v_capacity(B_A_2025_E_TRANS_2015) ++1 v_uc_online(B_A_2025_summer_day_E_TRANS_2015) ++1 v_uc_started(B_A_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_started_upper_tightening_constraint(A_2025_winter_night_NGCC_2025)_: +-10.0 v_capacity(A_2025_NGCC_2025) ++1 v_uc_online(A_2025_winter_night_NGCC_2025) ++1 v_uc_started(A_2025_winter_night_NGCC_2025) +<= 0 + +c_u_uc_started_upper_tightening_constraint(B_2025_summer_night_E_LDES_2025)_: +-50.0 v_capacity(B_2025_E_LDES_2025) ++1 v_uc_online(B_2025_summer_night_E_LDES_2025) ++1 v_uc_started(B_2025_summer_night_E_LDES_2025) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_B_2020_winter_day_E_TRANS_2015)_: +-1 v_uc_online(A_B_2020_winter_day_E_TRANS_2015) ++1 v_uc_stopped(A_B_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2020_summer_day_NGCC_2015)_: +-1 v_uc_online(A_2020_summer_day_NGCC_2015) ++1 v_uc_stopped(A_2020_summer_day_NGCC_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2025_summer_night_NGCC_2015)_: +-1 v_uc_online(A_2025_summer_night_NGCC_2015) ++1 v_uc_stopped(A_2025_summer_night_NGCC_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_summer_day_E_LDES_2025)_: +-1 v_uc_online(B_2025_summer_day_E_LDES_2025) ++1 v_uc_stopped(B_2025_summer_day_E_LDES_2025) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_A_2025_winter_day_E_TRANS_2015)_: +-1 v_uc_online(B_A_2025_winter_day_E_TRANS_2015) ++1 v_uc_stopped(B_A_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2020_winter_night_NGCC_2020)_: +-1 v_uc_online(A_2020_winter_night_NGCC_2020) ++1 v_uc_stopped(A_2020_winter_night_NGCC_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_summer_night_E_BATT_2020)_: +-1 v_uc_online(B_2025_summer_night_E_BATT_2020) ++1 v_uc_stopped(B_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2025_winter_day_NGCC_2015)_: +-1 v_uc_online(A_2025_winter_day_NGCC_2015) ++1 v_uc_stopped(A_2025_winter_day_NGCC_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_winter_night_E_BATT_2025)_: +-1 v_uc_online(B_2025_winter_night_E_BATT_2025) ++1 v_uc_stopped(B_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_summer_day_E_BATT_2020)_: +-1 v_uc_online(B_2025_summer_day_E_BATT_2020) ++1 v_uc_stopped(B_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2025_summer_day_NGCC_2025)_: +-1 v_uc_online(A_2025_summer_day_NGCC_2025) ++1 v_uc_stopped(A_2025_summer_day_NGCC_2025) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2025_winter_night_NGCC_2015)_: +-1 v_uc_online(A_2025_winter_night_NGCC_2015) ++1 v_uc_stopped(A_2025_winter_night_NGCC_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_A_2020_winter_night_E_TRANS_2015)_: +-1 v_uc_online(B_A_2020_winter_night_E_TRANS_2015) ++1 v_uc_stopped(B_A_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2020_summer_day_E_LDES_2020)_: +-1 v_uc_online(B_2020_summer_day_E_LDES_2020) ++1 v_uc_stopped(B_2020_summer_day_E_LDES_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2020_summer_night_NGCC_2020)_: +-1 v_uc_online(A_2020_summer_night_NGCC_2020) ++1 v_uc_stopped(A_2020_summer_night_NGCC_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2020_winter_night_E_LDES_2020)_: +-1 v_uc_online(B_2020_winter_night_E_LDES_2020) ++1 v_uc_stopped(B_2020_winter_night_E_LDES_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_B_2025_summer_night_E_TRANS_2015)_: +-1 v_uc_online(A_B_2025_summer_night_E_TRANS_2015) ++1 v_uc_stopped(A_B_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2020_summer_night_E_LDES_2020)_: +-1 v_uc_online(B_2020_summer_night_E_LDES_2020) ++1 v_uc_stopped(B_2020_summer_night_E_LDES_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_B_2020_summer_day_E_TRANS_2015)_: +-1 v_uc_online(A_B_2020_summer_day_E_TRANS_2015) ++1 v_uc_stopped(A_B_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2020_winter_day_E_LDES_2020)_: +-1 v_uc_online(B_2020_winter_day_E_LDES_2020) ++1 v_uc_stopped(B_2020_winter_day_E_LDES_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_winter_day_E_LDES_2020)_: +-1 v_uc_online(B_2025_winter_day_E_LDES_2020) ++1 v_uc_stopped(B_2025_winter_day_E_LDES_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2020_summer_day_NGCC_2020)_: +-1 v_uc_online(A_2020_summer_day_NGCC_2020) ++1 v_uc_stopped(A_2020_summer_day_NGCC_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2025_summer_night_NGCC_2020)_: +-1 v_uc_online(A_2025_summer_night_NGCC_2020) ++1 v_uc_stopped(A_2025_summer_night_NGCC_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_summer_night_E_BATT_2025)_: +-1 v_uc_online(B_2025_summer_night_E_BATT_2025) ++1 v_uc_stopped(B_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_A_2020_summer_day_E_TRANS_2015)_: +-1 v_uc_online(B_A_2020_summer_day_E_TRANS_2015) ++1 v_uc_stopped(B_A_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2025_winter_day_NGCC_2020)_: +-1 v_uc_online(A_2025_winter_day_NGCC_2020) ++1 v_uc_stopped(A_2025_winter_day_NGCC_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2025_summer_day_NGCC_2015)_: +-1 v_uc_online(A_2025_summer_day_NGCC_2015) ++1 v_uc_stopped(A_2025_summer_day_NGCC_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2020_winter_day_NGCC_2015)_: +-1 v_uc_online(A_2020_winter_day_NGCC_2015) ++1 v_uc_stopped(A_2020_winter_day_NGCC_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_winter_night_E_LDES_2020)_: +-1 v_uc_online(B_2025_winter_night_E_LDES_2020) ++1 v_uc_stopped(B_2025_winter_night_E_LDES_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_B_2025_winter_day_E_TRANS_2015)_: +-1 v_uc_online(A_B_2025_winter_day_E_TRANS_2015) ++1 v_uc_stopped(A_B_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_A_2025_summer_night_E_TRANS_2015)_: +-1 v_uc_online(B_A_2025_summer_night_E_TRANS_2015) ++1 v_uc_stopped(B_A_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_A_2025_winter_night_E_TRANS_2015)_: +-1 v_uc_online(B_A_2025_winter_night_E_TRANS_2015) ++1 v_uc_stopped(B_A_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2020_summer_day_E_BATT_2020)_: +-1 v_uc_online(B_2020_summer_day_E_BATT_2020) ++1 v_uc_stopped(B_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_summer_day_E_BATT_2025)_: +-1 v_uc_online(B_2025_summer_day_E_BATT_2025) ++1 v_uc_stopped(B_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_winter_day_E_BATT_2020)_: +-1 v_uc_online(B_2025_winter_day_E_BATT_2020) ++1 v_uc_stopped(B_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2025_winter_night_NGCC_2020)_: +-1 v_uc_online(A_2025_winter_night_NGCC_2020) ++1 v_uc_stopped(A_2025_winter_night_NGCC_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_B_2020_winter_night_E_TRANS_2015)_: +-1 v_uc_online(A_B_2020_winter_night_E_TRANS_2015) ++1 v_uc_stopped(A_B_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2020_summer_night_E_BATT_2020)_: +-1 v_uc_online(B_2020_summer_night_E_BATT_2020) ++1 v_uc_stopped(B_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_summer_night_E_LDES_2020)_: +-1 v_uc_online(B_2025_summer_night_E_LDES_2020) ++1 v_uc_stopped(B_2025_summer_night_E_LDES_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_B_2025_winter_night_E_TRANS_2015)_: +-1 v_uc_online(A_B_2025_winter_night_E_TRANS_2015) ++1 v_uc_stopped(A_B_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_A_2020_winter_day_E_TRANS_2015)_: +-1 v_uc_online(B_A_2020_winter_day_E_TRANS_2015) ++1 v_uc_stopped(B_A_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_summer_day_E_LDES_2020)_: +-1 v_uc_online(B_2025_summer_day_E_LDES_2020) ++1 v_uc_stopped(B_2025_summer_day_E_LDES_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_winter_day_E_LDES_2025)_: +-1 v_uc_online(B_2025_winter_day_E_LDES_2025) ++1 v_uc_stopped(B_2025_winter_day_E_LDES_2025) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2020_winter_day_E_BATT_2020)_: +-1 v_uc_online(B_2020_winter_day_E_BATT_2020) ++1 v_uc_stopped(B_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2020_winter_night_E_BATT_2020)_: +-1 v_uc_online(B_2020_winter_night_E_BATT_2020) ++1 v_uc_stopped(B_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2020_winter_night_NGCC_2015)_: +-1 v_uc_online(A_2020_winter_night_NGCC_2015) ++1 v_uc_stopped(A_2020_winter_night_NGCC_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2025_summer_night_NGCC_2025)_: +-1 v_uc_online(A_2025_summer_night_NGCC_2025) ++1 v_uc_stopped(A_2025_summer_night_NGCC_2025) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_winter_night_E_BATT_2020)_: +-1 v_uc_online(B_2025_winter_night_E_BATT_2020) ++1 v_uc_stopped(B_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_winter_night_E_LDES_2025)_: +-1 v_uc_online(B_2025_winter_night_E_LDES_2025) ++1 v_uc_stopped(B_2025_winter_night_E_LDES_2025) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_B_2025_summer_day_E_TRANS_2015)_: +-1 v_uc_online(A_B_2025_summer_day_E_TRANS_2015) ++1 v_uc_stopped(A_B_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2020_winter_day_NGCC_2020)_: +-1 v_uc_online(A_2020_winter_day_NGCC_2020) ++1 v_uc_stopped(A_2020_winter_day_NGCC_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2025_winter_day_NGCC_2025)_: +-1 v_uc_online(A_2025_winter_day_NGCC_2025) ++1 v_uc_stopped(A_2025_winter_day_NGCC_2025) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2025_summer_day_NGCC_2020)_: +-1 v_uc_online(A_2025_summer_day_NGCC_2020) ++1 v_uc_stopped(A_2025_summer_day_NGCC_2020) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2020_summer_night_NGCC_2015)_: +-1 v_uc_online(A_2020_summer_night_NGCC_2015) ++1 v_uc_stopped(A_2020_summer_night_NGCC_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_A_2020_summer_night_E_TRANS_2015)_: +-1 v_uc_online(B_A_2020_summer_night_E_TRANS_2015) ++1 v_uc_stopped(B_A_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_winter_day_E_BATT_2025)_: +-1 v_uc_online(B_2025_winter_day_E_BATT_2025) ++1 v_uc_stopped(B_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_B_2020_summer_night_E_TRANS_2015)_: +-1 v_uc_online(A_B_2020_summer_night_E_TRANS_2015) ++1 v_uc_stopped(A_B_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_A_2025_summer_day_E_TRANS_2015)_: +-1 v_uc_online(B_A_2025_summer_day_E_TRANS_2015) ++1 v_uc_stopped(B_A_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(A_2025_winter_night_NGCC_2025)_: +-1 v_uc_online(A_2025_winter_night_NGCC_2025) ++1 v_uc_stopped(A_2025_winter_night_NGCC_2025) +<= 0 + +c_u_uc_stopped_upper_tightening_constraint(B_2025_summer_night_E_LDES_2025)_: +-1 v_uc_online(B_2025_summer_night_E_LDES_2025) ++1 v_uc_stopped(B_2025_summer_night_E_LDES_2025) +<= 0 + +c_e_uc_transition_constraint(A_B_2020_winter_day_E_TRANS_2015)_: +-1 v_uc_online(A_B_2020_winter_day_E_TRANS_2015) ++1 v_uc_online(A_B_2020_winter_night_E_TRANS_2015) +-1 v_uc_started(A_B_2020_winter_day_E_TRANS_2015) ++1 v_uc_stopped(A_B_2020_winter_day_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(A_2020_summer_day_NGCC_2015)_: +-1 v_uc_online(A_2020_summer_day_NGCC_2015) ++1 v_uc_online(A_2020_summer_night_NGCC_2015) +-1 v_uc_started(A_2020_summer_day_NGCC_2015) ++1 v_uc_stopped(A_2020_summer_day_NGCC_2015) += 0 + +c_e_uc_transition_constraint(A_2025_summer_night_NGCC_2015)_: +-1 v_uc_online(A_2025_summer_night_NGCC_2015) ++1 v_uc_online(A_2025_summer_day_NGCC_2015) +-1 v_uc_started(A_2025_summer_night_NGCC_2015) ++1 v_uc_stopped(A_2025_summer_night_NGCC_2015) += 0 + +c_e_uc_transition_constraint(B_2025_summer_day_E_LDES_2025)_: +-1 v_uc_online(B_2025_summer_day_E_LDES_2025) ++1 v_uc_online(B_2025_summer_night_E_LDES_2025) +-1 v_uc_started(B_2025_summer_day_E_LDES_2025) ++1 v_uc_stopped(B_2025_summer_day_E_LDES_2025) += 0 + +c_e_uc_transition_constraint(B_A_2025_winter_day_E_TRANS_2015)_: +-1 v_uc_online(B_A_2025_winter_day_E_TRANS_2015) ++1 v_uc_online(B_A_2025_winter_night_E_TRANS_2015) +-1 v_uc_started(B_A_2025_winter_day_E_TRANS_2015) ++1 v_uc_stopped(B_A_2025_winter_day_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(A_2020_winter_night_NGCC_2020)_: +-1 v_uc_online(A_2020_winter_night_NGCC_2020) ++1 v_uc_online(A_2020_winter_day_NGCC_2020) +-1 v_uc_started(A_2020_winter_night_NGCC_2020) ++1 v_uc_stopped(A_2020_winter_night_NGCC_2020) += 0 + +c_e_uc_transition_constraint(B_2025_summer_night_E_BATT_2020)_: +-1 v_uc_online(B_2025_summer_night_E_BATT_2020) ++1 v_uc_online(B_2025_summer_day_E_BATT_2020) +-1 v_uc_started(B_2025_summer_night_E_BATT_2020) ++1 v_uc_stopped(B_2025_summer_night_E_BATT_2020) += 0 + +c_e_uc_transition_constraint(A_2025_winter_day_NGCC_2015)_: +-1 v_uc_online(A_2025_winter_day_NGCC_2015) ++1 v_uc_online(A_2025_winter_night_NGCC_2015) +-1 v_uc_started(A_2025_winter_day_NGCC_2015) ++1 v_uc_stopped(A_2025_winter_day_NGCC_2015) += 0 + +c_e_uc_transition_constraint(B_2025_winter_night_E_BATT_2025)_: +-1 v_uc_online(B_2025_winter_night_E_BATT_2025) ++1 v_uc_online(B_2025_winter_day_E_BATT_2025) +-1 v_uc_started(B_2025_winter_night_E_BATT_2025) ++1 v_uc_stopped(B_2025_winter_night_E_BATT_2025) += 0 + +c_e_uc_transition_constraint(B_2025_summer_day_E_BATT_2020)_: ++1 v_uc_online(B_2025_summer_night_E_BATT_2020) +-1 v_uc_online(B_2025_summer_day_E_BATT_2020) +-1 v_uc_started(B_2025_summer_day_E_BATT_2020) ++1 v_uc_stopped(B_2025_summer_day_E_BATT_2020) += 0 + +c_e_uc_transition_constraint(A_2025_summer_day_NGCC_2025)_: +-1 v_uc_online(A_2025_summer_day_NGCC_2025) ++1 v_uc_online(A_2025_summer_night_NGCC_2025) +-1 v_uc_started(A_2025_summer_day_NGCC_2025) ++1 v_uc_stopped(A_2025_summer_day_NGCC_2025) += 0 + +c_e_uc_transition_constraint(A_2025_winter_night_NGCC_2015)_: ++1 v_uc_online(A_2025_winter_day_NGCC_2015) +-1 v_uc_online(A_2025_winter_night_NGCC_2015) +-1 v_uc_started(A_2025_winter_night_NGCC_2015) ++1 v_uc_stopped(A_2025_winter_night_NGCC_2015) += 0 + +c_e_uc_transition_constraint(B_A_2020_winter_night_E_TRANS_2015)_: +-1 v_uc_online(B_A_2020_winter_night_E_TRANS_2015) ++1 v_uc_online(B_A_2020_winter_day_E_TRANS_2015) +-1 v_uc_started(B_A_2020_winter_night_E_TRANS_2015) ++1 v_uc_stopped(B_A_2020_winter_night_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(B_2020_summer_day_E_LDES_2020)_: +-1 v_uc_online(B_2020_summer_day_E_LDES_2020) ++1 v_uc_online(B_2020_summer_night_E_LDES_2020) +-1 v_uc_started(B_2020_summer_day_E_LDES_2020) ++1 v_uc_stopped(B_2020_summer_day_E_LDES_2020) += 0 + +c_e_uc_transition_constraint(A_2020_summer_night_NGCC_2020)_: +-1 v_uc_online(A_2020_summer_night_NGCC_2020) ++1 v_uc_online(A_2020_summer_day_NGCC_2020) +-1 v_uc_started(A_2020_summer_night_NGCC_2020) ++1 v_uc_stopped(A_2020_summer_night_NGCC_2020) += 0 + +c_e_uc_transition_constraint(B_2020_winter_night_E_LDES_2020)_: +-1 v_uc_online(B_2020_winter_night_E_LDES_2020) ++1 v_uc_online(B_2020_winter_day_E_LDES_2020) +-1 v_uc_started(B_2020_winter_night_E_LDES_2020) ++1 v_uc_stopped(B_2020_winter_night_E_LDES_2020) += 0 + +c_e_uc_transition_constraint(A_B_2025_summer_night_E_TRANS_2015)_: +-1 v_uc_online(A_B_2025_summer_night_E_TRANS_2015) ++1 v_uc_online(A_B_2025_summer_day_E_TRANS_2015) +-1 v_uc_started(A_B_2025_summer_night_E_TRANS_2015) ++1 v_uc_stopped(A_B_2025_summer_night_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(B_2020_summer_night_E_LDES_2020)_: ++1 v_uc_online(B_2020_summer_day_E_LDES_2020) +-1 v_uc_online(B_2020_summer_night_E_LDES_2020) +-1 v_uc_started(B_2020_summer_night_E_LDES_2020) ++1 v_uc_stopped(B_2020_summer_night_E_LDES_2020) += 0 + +c_e_uc_transition_constraint(A_B_2020_summer_day_E_TRANS_2015)_: +-1 v_uc_online(A_B_2020_summer_day_E_TRANS_2015) ++1 v_uc_online(A_B_2020_summer_night_E_TRANS_2015) +-1 v_uc_started(A_B_2020_summer_day_E_TRANS_2015) ++1 v_uc_stopped(A_B_2020_summer_day_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(B_2020_winter_day_E_LDES_2020)_: ++1 v_uc_online(B_2020_winter_night_E_LDES_2020) +-1 v_uc_online(B_2020_winter_day_E_LDES_2020) +-1 v_uc_started(B_2020_winter_day_E_LDES_2020) ++1 v_uc_stopped(B_2020_winter_day_E_LDES_2020) += 0 + +c_e_uc_transition_constraint(B_2025_winter_day_E_LDES_2020)_: +-1 v_uc_online(B_2025_winter_day_E_LDES_2020) ++1 v_uc_online(B_2025_winter_night_E_LDES_2020) +-1 v_uc_started(B_2025_winter_day_E_LDES_2020) ++1 v_uc_stopped(B_2025_winter_day_E_LDES_2020) += 0 + +c_e_uc_transition_constraint(A_2020_summer_day_NGCC_2020)_: ++1 v_uc_online(A_2020_summer_night_NGCC_2020) +-1 v_uc_online(A_2020_summer_day_NGCC_2020) +-1 v_uc_started(A_2020_summer_day_NGCC_2020) ++1 v_uc_stopped(A_2020_summer_day_NGCC_2020) += 0 + +c_e_uc_transition_constraint(A_2025_summer_night_NGCC_2020)_: +-1 v_uc_online(A_2025_summer_night_NGCC_2020) ++1 v_uc_online(A_2025_summer_day_NGCC_2020) +-1 v_uc_started(A_2025_summer_night_NGCC_2020) ++1 v_uc_stopped(A_2025_summer_night_NGCC_2020) += 0 + +c_e_uc_transition_constraint(B_2025_summer_night_E_BATT_2025)_: +-1 v_uc_online(B_2025_summer_night_E_BATT_2025) ++1 v_uc_online(B_2025_summer_day_E_BATT_2025) +-1 v_uc_started(B_2025_summer_night_E_BATT_2025) ++1 v_uc_stopped(B_2025_summer_night_E_BATT_2025) += 0 + +c_e_uc_transition_constraint(B_A_2020_summer_day_E_TRANS_2015)_: +-1 v_uc_online(B_A_2020_summer_day_E_TRANS_2015) ++1 v_uc_online(B_A_2020_summer_night_E_TRANS_2015) +-1 v_uc_started(B_A_2020_summer_day_E_TRANS_2015) ++1 v_uc_stopped(B_A_2020_summer_day_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(A_2025_winter_day_NGCC_2020)_: +-1 v_uc_online(A_2025_winter_day_NGCC_2020) ++1 v_uc_online(A_2025_winter_night_NGCC_2020) +-1 v_uc_started(A_2025_winter_day_NGCC_2020) ++1 v_uc_stopped(A_2025_winter_day_NGCC_2020) += 0 + +c_e_uc_transition_constraint(A_2025_summer_day_NGCC_2015)_: ++1 v_uc_online(A_2025_summer_night_NGCC_2015) +-1 v_uc_online(A_2025_summer_day_NGCC_2015) +-1 v_uc_started(A_2025_summer_day_NGCC_2015) ++1 v_uc_stopped(A_2025_summer_day_NGCC_2015) += 0 + +c_e_uc_transition_constraint(A_2020_winter_day_NGCC_2015)_: +-1 v_uc_online(A_2020_winter_day_NGCC_2015) ++1 v_uc_online(A_2020_winter_night_NGCC_2015) +-1 v_uc_started(A_2020_winter_day_NGCC_2015) ++1 v_uc_stopped(A_2020_winter_day_NGCC_2015) += 0 + +c_e_uc_transition_constraint(B_2025_winter_night_E_LDES_2020)_: ++1 v_uc_online(B_2025_winter_day_E_LDES_2020) +-1 v_uc_online(B_2025_winter_night_E_LDES_2020) +-1 v_uc_started(B_2025_winter_night_E_LDES_2020) ++1 v_uc_stopped(B_2025_winter_night_E_LDES_2020) += 0 + +c_e_uc_transition_constraint(A_B_2025_winter_day_E_TRANS_2015)_: +-1 v_uc_online(A_B_2025_winter_day_E_TRANS_2015) ++1 v_uc_online(A_B_2025_winter_night_E_TRANS_2015) +-1 v_uc_started(A_B_2025_winter_day_E_TRANS_2015) ++1 v_uc_stopped(A_B_2025_winter_day_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(B_A_2025_summer_night_E_TRANS_2015)_: +-1 v_uc_online(B_A_2025_summer_night_E_TRANS_2015) ++1 v_uc_online(B_A_2025_summer_day_E_TRANS_2015) +-1 v_uc_started(B_A_2025_summer_night_E_TRANS_2015) ++1 v_uc_stopped(B_A_2025_summer_night_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(B_A_2025_winter_night_E_TRANS_2015)_: ++1 v_uc_online(B_A_2025_winter_day_E_TRANS_2015) +-1 v_uc_online(B_A_2025_winter_night_E_TRANS_2015) +-1 v_uc_started(B_A_2025_winter_night_E_TRANS_2015) ++1 v_uc_stopped(B_A_2025_winter_night_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(B_2020_summer_day_E_BATT_2020)_: +-1 v_uc_online(B_2020_summer_day_E_BATT_2020) ++1 v_uc_online(B_2020_summer_night_E_BATT_2020) +-1 v_uc_started(B_2020_summer_day_E_BATT_2020) ++1 v_uc_stopped(B_2020_summer_day_E_BATT_2020) += 0 + +c_e_uc_transition_constraint(B_2025_summer_day_E_BATT_2025)_: ++1 v_uc_online(B_2025_summer_night_E_BATT_2025) +-1 v_uc_online(B_2025_summer_day_E_BATT_2025) +-1 v_uc_started(B_2025_summer_day_E_BATT_2025) ++1 v_uc_stopped(B_2025_summer_day_E_BATT_2025) += 0 + +c_e_uc_transition_constraint(B_2025_winter_day_E_BATT_2020)_: +-1 v_uc_online(B_2025_winter_day_E_BATT_2020) ++1 v_uc_online(B_2025_winter_night_E_BATT_2020) +-1 v_uc_started(B_2025_winter_day_E_BATT_2020) ++1 v_uc_stopped(B_2025_winter_day_E_BATT_2020) += 0 + +c_e_uc_transition_constraint(A_2025_winter_night_NGCC_2020)_: ++1 v_uc_online(A_2025_winter_day_NGCC_2020) +-1 v_uc_online(A_2025_winter_night_NGCC_2020) +-1 v_uc_started(A_2025_winter_night_NGCC_2020) ++1 v_uc_stopped(A_2025_winter_night_NGCC_2020) += 0 + +c_e_uc_transition_constraint(A_B_2020_winter_night_E_TRANS_2015)_: ++1 v_uc_online(A_B_2020_winter_day_E_TRANS_2015) +-1 v_uc_online(A_B_2020_winter_night_E_TRANS_2015) +-1 v_uc_started(A_B_2020_winter_night_E_TRANS_2015) ++1 v_uc_stopped(A_B_2020_winter_night_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(B_2020_summer_night_E_BATT_2020)_: ++1 v_uc_online(B_2020_summer_day_E_BATT_2020) +-1 v_uc_online(B_2020_summer_night_E_BATT_2020) +-1 v_uc_started(B_2020_summer_night_E_BATT_2020) ++1 v_uc_stopped(B_2020_summer_night_E_BATT_2020) += 0 + +c_e_uc_transition_constraint(B_2025_summer_night_E_LDES_2020)_: +-1 v_uc_online(B_2025_summer_night_E_LDES_2020) ++1 v_uc_online(B_2025_summer_day_E_LDES_2020) +-1 v_uc_started(B_2025_summer_night_E_LDES_2020) ++1 v_uc_stopped(B_2025_summer_night_E_LDES_2020) += 0 + +c_e_uc_transition_constraint(A_B_2025_winter_night_E_TRANS_2015)_: ++1 v_uc_online(A_B_2025_winter_day_E_TRANS_2015) +-1 v_uc_online(A_B_2025_winter_night_E_TRANS_2015) +-1 v_uc_started(A_B_2025_winter_night_E_TRANS_2015) ++1 v_uc_stopped(A_B_2025_winter_night_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(B_A_2020_winter_day_E_TRANS_2015)_: ++1 v_uc_online(B_A_2020_winter_night_E_TRANS_2015) +-1 v_uc_online(B_A_2020_winter_day_E_TRANS_2015) +-1 v_uc_started(B_A_2020_winter_day_E_TRANS_2015) ++1 v_uc_stopped(B_A_2020_winter_day_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(B_2025_summer_day_E_LDES_2020)_: ++1 v_uc_online(B_2025_summer_night_E_LDES_2020) +-1 v_uc_online(B_2025_summer_day_E_LDES_2020) +-1 v_uc_started(B_2025_summer_day_E_LDES_2020) ++1 v_uc_stopped(B_2025_summer_day_E_LDES_2020) += 0 + +c_e_uc_transition_constraint(B_2025_winter_day_E_LDES_2025)_: +-1 v_uc_online(B_2025_winter_day_E_LDES_2025) ++1 v_uc_online(B_2025_winter_night_E_LDES_2025) +-1 v_uc_started(B_2025_winter_day_E_LDES_2025) ++1 v_uc_stopped(B_2025_winter_day_E_LDES_2025) += 0 + +c_e_uc_transition_constraint(B_2020_winter_day_E_BATT_2020)_: +-1 v_uc_online(B_2020_winter_day_E_BATT_2020) ++1 v_uc_online(B_2020_winter_night_E_BATT_2020) +-1 v_uc_started(B_2020_winter_day_E_BATT_2020) ++1 v_uc_stopped(B_2020_winter_day_E_BATT_2020) += 0 + +c_e_uc_transition_constraint(B_2020_winter_night_E_BATT_2020)_: ++1 v_uc_online(B_2020_winter_day_E_BATT_2020) +-1 v_uc_online(B_2020_winter_night_E_BATT_2020) +-1 v_uc_started(B_2020_winter_night_E_BATT_2020) ++1 v_uc_stopped(B_2020_winter_night_E_BATT_2020) += 0 + +c_e_uc_transition_constraint(A_2020_winter_night_NGCC_2015)_: ++1 v_uc_online(A_2020_winter_day_NGCC_2015) +-1 v_uc_online(A_2020_winter_night_NGCC_2015) +-1 v_uc_started(A_2020_winter_night_NGCC_2015) ++1 v_uc_stopped(A_2020_winter_night_NGCC_2015) += 0 + +c_e_uc_transition_constraint(A_2025_summer_night_NGCC_2025)_: ++1 v_uc_online(A_2025_summer_day_NGCC_2025) +-1 v_uc_online(A_2025_summer_night_NGCC_2025) +-1 v_uc_started(A_2025_summer_night_NGCC_2025) ++1 v_uc_stopped(A_2025_summer_night_NGCC_2025) += 0 + +c_e_uc_transition_constraint(B_2025_winter_night_E_BATT_2020)_: ++1 v_uc_online(B_2025_winter_day_E_BATT_2020) +-1 v_uc_online(B_2025_winter_night_E_BATT_2020) +-1 v_uc_started(B_2025_winter_night_E_BATT_2020) ++1 v_uc_stopped(B_2025_winter_night_E_BATT_2020) += 0 + +c_e_uc_transition_constraint(B_2025_winter_night_E_LDES_2025)_: ++1 v_uc_online(B_2025_winter_day_E_LDES_2025) +-1 v_uc_online(B_2025_winter_night_E_LDES_2025) +-1 v_uc_started(B_2025_winter_night_E_LDES_2025) ++1 v_uc_stopped(B_2025_winter_night_E_LDES_2025) += 0 + +c_e_uc_transition_constraint(A_B_2025_summer_day_E_TRANS_2015)_: ++1 v_uc_online(A_B_2025_summer_night_E_TRANS_2015) +-1 v_uc_online(A_B_2025_summer_day_E_TRANS_2015) +-1 v_uc_started(A_B_2025_summer_day_E_TRANS_2015) ++1 v_uc_stopped(A_B_2025_summer_day_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(A_2020_winter_day_NGCC_2020)_: ++1 v_uc_online(A_2020_winter_night_NGCC_2020) +-1 v_uc_online(A_2020_winter_day_NGCC_2020) +-1 v_uc_started(A_2020_winter_day_NGCC_2020) ++1 v_uc_stopped(A_2020_winter_day_NGCC_2020) += 0 + +c_e_uc_transition_constraint(A_2025_winter_day_NGCC_2025)_: +-1 v_uc_online(A_2025_winter_day_NGCC_2025) ++1 v_uc_online(A_2025_winter_night_NGCC_2025) +-1 v_uc_started(A_2025_winter_day_NGCC_2025) ++1 v_uc_stopped(A_2025_winter_day_NGCC_2025) += 0 + +c_e_uc_transition_constraint(A_2025_summer_day_NGCC_2020)_: ++1 v_uc_online(A_2025_summer_night_NGCC_2020) +-1 v_uc_online(A_2025_summer_day_NGCC_2020) +-1 v_uc_started(A_2025_summer_day_NGCC_2020) ++1 v_uc_stopped(A_2025_summer_day_NGCC_2020) += 0 + +c_e_uc_transition_constraint(A_2020_summer_night_NGCC_2015)_: ++1 v_uc_online(A_2020_summer_day_NGCC_2015) +-1 v_uc_online(A_2020_summer_night_NGCC_2015) +-1 v_uc_started(A_2020_summer_night_NGCC_2015) ++1 v_uc_stopped(A_2020_summer_night_NGCC_2015) += 0 + +c_e_uc_transition_constraint(B_A_2020_summer_night_E_TRANS_2015)_: ++1 v_uc_online(B_A_2020_summer_day_E_TRANS_2015) +-1 v_uc_online(B_A_2020_summer_night_E_TRANS_2015) +-1 v_uc_started(B_A_2020_summer_night_E_TRANS_2015) ++1 v_uc_stopped(B_A_2020_summer_night_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(B_2025_winter_day_E_BATT_2025)_: ++1 v_uc_online(B_2025_winter_night_E_BATT_2025) +-1 v_uc_online(B_2025_winter_day_E_BATT_2025) +-1 v_uc_started(B_2025_winter_day_E_BATT_2025) ++1 v_uc_stopped(B_2025_winter_day_E_BATT_2025) += 0 + +c_e_uc_transition_constraint(A_B_2020_summer_night_E_TRANS_2015)_: ++1 v_uc_online(A_B_2020_summer_day_E_TRANS_2015) +-1 v_uc_online(A_B_2020_summer_night_E_TRANS_2015) +-1 v_uc_started(A_B_2020_summer_night_E_TRANS_2015) ++1 v_uc_stopped(A_B_2020_summer_night_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(B_A_2025_summer_day_E_TRANS_2015)_: ++1 v_uc_online(B_A_2025_summer_night_E_TRANS_2015) +-1 v_uc_online(B_A_2025_summer_day_E_TRANS_2015) +-1 v_uc_started(B_A_2025_summer_day_E_TRANS_2015) ++1 v_uc_stopped(B_A_2025_summer_day_E_TRANS_2015) += 0 + +c_e_uc_transition_constraint(A_2025_winter_night_NGCC_2025)_: ++1 v_uc_online(A_2025_winter_day_NGCC_2025) +-1 v_uc_online(A_2025_winter_night_NGCC_2025) +-1 v_uc_started(A_2025_winter_night_NGCC_2025) ++1 v_uc_stopped(A_2025_winter_night_NGCC_2025) += 0 + +c_e_uc_transition_constraint(B_2025_summer_night_E_LDES_2025)_: ++1 v_uc_online(B_2025_summer_day_E_LDES_2025) +-1 v_uc_online(B_2025_summer_night_E_LDES_2025) +-1 v_uc_started(B_2025_summer_night_E_LDES_2025) ++1 v_uc_stopped(B_2025_summer_night_E_LDES_2025) += 0 + +c_u_uc_min_output_constraint(A_B_2020_winter_day_E_TRANS_2015)_: +-1 v_flow_out(A_B_2020_winter_day_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(A_B_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(A_2020_summer_day_NGCC_2015)_: +-1 v_flow_out(A_2020_summer_day_NG_NGCC_2015_ELC) ++0.0657 v_uc_online(A_2020_summer_day_NGCC_2015) +<= 0 + +c_u_uc_min_output_constraint(A_2025_summer_night_NGCC_2015)_: +-1 v_flow_out(A_2025_summer_night_NG_NGCC_2015_ELC) ++0.0657 v_uc_online(A_2025_summer_night_NGCC_2015) +<= 0 + +c_u_uc_min_output_constraint(B_2025_summer_day_E_LDES_2025)_: +-1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2025_ELC) ++0.013139999999999999 v_uc_online(B_2025_summer_day_E_LDES_2025) +<= 0 + +c_u_uc_min_output_constraint(B_A_2025_winter_day_E_TRANS_2015)_: +-1 v_flow_out(B_A_2025_winter_day_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(B_A_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(A_2020_winter_night_NGCC_2020)_: +-1 v_flow_out(A_2020_winter_night_NG_NGCC_2020_ELC) ++0.0657 v_uc_online(A_2020_winter_night_NGCC_2020) +<= 0 + +c_u_uc_min_output_constraint(B_2025_summer_night_E_BATT_2020)_: +-1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2020_ELC) ++0.03285 v_uc_online(B_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_uc_min_output_constraint(A_2025_winter_day_NGCC_2015)_: +-1 v_flow_out(A_2025_winter_day_NG_NGCC_2015_ELC) ++0.0657 v_uc_online(A_2025_winter_day_NGCC_2015) +<= 0 + +c_u_uc_min_output_constraint(B_2025_winter_night_E_BATT_2025)_: +-1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2025_ELC) ++0.03285 v_uc_online(B_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_uc_min_output_constraint(B_2025_summer_day_E_BATT_2020)_: +-1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2020_ELC) ++0.03285 v_uc_online(B_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_uc_min_output_constraint(A_2025_summer_day_NGCC_2025)_: +-1 v_flow_out(A_2025_summer_day_NG_NGCC_2025_ELC) ++0.0657 v_uc_online(A_2025_summer_day_NGCC_2025) +<= 0 + +c_u_uc_min_output_constraint(A_2025_winter_night_NGCC_2015)_: +-1 v_flow_out(A_2025_winter_night_NG_NGCC_2015_ELC) ++0.0657 v_uc_online(A_2025_winter_night_NGCC_2015) +<= 0 + +c_u_uc_min_output_constraint(B_A_2020_winter_night_E_TRANS_2015)_: +-1 v_flow_out(B_A_2020_winter_night_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(B_A_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(B_2020_summer_day_E_LDES_2020)_: +-1 v_flow_out(B_2020_summer_day_ELC_E_LDES_2020_ELC) ++0.013139999999999999 v_uc_online(B_2020_summer_day_E_LDES_2020) +<= 0 + +c_u_uc_min_output_constraint(A_2020_summer_night_NGCC_2020)_: +-1 v_flow_out(A_2020_summer_night_NG_NGCC_2020_ELC) ++0.0657 v_uc_online(A_2020_summer_night_NGCC_2020) +<= 0 + +c_u_uc_min_output_constraint(B_2020_winter_night_E_LDES_2020)_: +-1 v_flow_out(B_2020_winter_night_ELC_E_LDES_2020_ELC) ++0.013139999999999999 v_uc_online(B_2020_winter_night_E_LDES_2020) +<= 0 + +c_u_uc_min_output_constraint(A_B_2025_summer_night_E_TRANS_2015)_: +-1 v_flow_out(A_B_2025_summer_night_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(A_B_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(B_2020_summer_night_E_LDES_2020)_: +-1 v_flow_out(B_2020_summer_night_ELC_E_LDES_2020_ELC) ++0.013139999999999999 v_uc_online(B_2020_summer_night_E_LDES_2020) +<= 0 + +c_u_uc_min_output_constraint(A_B_2020_summer_day_E_TRANS_2015)_: +-1 v_flow_out(A_B_2020_summer_day_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(A_B_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(B_2020_winter_day_E_LDES_2020)_: +-1 v_flow_out(B_2020_winter_day_ELC_E_LDES_2020_ELC) ++0.013139999999999999 v_uc_online(B_2020_winter_day_E_LDES_2020) +<= 0 + +c_u_uc_min_output_constraint(B_2025_winter_day_E_LDES_2020)_: +-1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2020_ELC) ++0.013139999999999999 v_uc_online(B_2025_winter_day_E_LDES_2020) +<= 0 + +c_u_uc_min_output_constraint(A_2020_summer_day_NGCC_2020)_: +-1 v_flow_out(A_2020_summer_day_NG_NGCC_2020_ELC) ++0.0657 v_uc_online(A_2020_summer_day_NGCC_2020) +<= 0 + +c_u_uc_min_output_constraint(A_2025_summer_night_NGCC_2020)_: +-1 v_flow_out(A_2025_summer_night_NG_NGCC_2020_ELC) ++0.0657 v_uc_online(A_2025_summer_night_NGCC_2020) +<= 0 + +c_u_uc_min_output_constraint(B_2025_summer_night_E_BATT_2025)_: +-1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2025_ELC) ++0.03285 v_uc_online(B_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_uc_min_output_constraint(B_A_2020_summer_day_E_TRANS_2015)_: +-1 v_flow_out(B_A_2020_summer_day_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(B_A_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(A_2025_winter_day_NGCC_2020)_: +-1 v_flow_out(A_2025_winter_day_NG_NGCC_2020_ELC) ++0.0657 v_uc_online(A_2025_winter_day_NGCC_2020) +<= 0 + +c_u_uc_min_output_constraint(A_2025_summer_day_NGCC_2015)_: +-1 v_flow_out(A_2025_summer_day_NG_NGCC_2015_ELC) ++0.0657 v_uc_online(A_2025_summer_day_NGCC_2015) +<= 0 + +c_u_uc_min_output_constraint(A_2020_winter_day_NGCC_2015)_: +-1 v_flow_out(A_2020_winter_day_NG_NGCC_2015_ELC) ++0.0657 v_uc_online(A_2020_winter_day_NGCC_2015) +<= 0 + +c_u_uc_min_output_constraint(B_2025_winter_night_E_LDES_2020)_: +-1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2020_ELC) ++0.013139999999999999 v_uc_online(B_2025_winter_night_E_LDES_2020) +<= 0 + +c_u_uc_min_output_constraint(A_B_2025_winter_day_E_TRANS_2015)_: +-1 v_flow_out(A_B_2025_winter_day_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(A_B_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(B_A_2025_summer_night_E_TRANS_2015)_: +-1 v_flow_out(B_A_2025_summer_night_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(B_A_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(B_A_2025_winter_night_E_TRANS_2015)_: +-1 v_flow_out(B_A_2025_winter_night_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(B_A_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(B_2020_summer_day_E_BATT_2020)_: +-1 v_flow_out(B_2020_summer_day_ELC_E_BATT_2020_ELC) ++0.03285 v_uc_online(B_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_uc_min_output_constraint(B_2025_summer_day_E_BATT_2025)_: +-1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2025_ELC) ++0.03285 v_uc_online(B_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_uc_min_output_constraint(B_2025_winter_day_E_BATT_2020)_: +-1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2020_ELC) ++0.03285 v_uc_online(B_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_uc_min_output_constraint(A_2025_winter_night_NGCC_2020)_: +-1 v_flow_out(A_2025_winter_night_NG_NGCC_2020_ELC) ++0.0657 v_uc_online(A_2025_winter_night_NGCC_2020) +<= 0 + +c_u_uc_min_output_constraint(A_B_2020_winter_night_E_TRANS_2015)_: +-1 v_flow_out(A_B_2020_winter_night_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(A_B_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(B_2020_summer_night_E_BATT_2020)_: +-1 v_flow_out(B_2020_summer_night_ELC_E_BATT_2020_ELC) ++0.03285 v_uc_online(B_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_uc_min_output_constraint(B_2025_summer_night_E_LDES_2020)_: +-1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2020_ELC) ++0.013139999999999999 v_uc_online(B_2025_summer_night_E_LDES_2020) +<= 0 + +c_u_uc_min_output_constraint(A_B_2025_winter_night_E_TRANS_2015)_: +-1 v_flow_out(A_B_2025_winter_night_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(A_B_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(B_A_2020_winter_day_E_TRANS_2015)_: +-1 v_flow_out(B_A_2020_winter_day_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(B_A_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(B_2025_summer_day_E_LDES_2020)_: +-1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2020_ELC) ++0.013139999999999999 v_uc_online(B_2025_summer_day_E_LDES_2020) +<= 0 + +c_u_uc_min_output_constraint(B_2025_winter_day_E_LDES_2025)_: +-1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2025_ELC) ++0.013139999999999999 v_uc_online(B_2025_winter_day_E_LDES_2025) +<= 0 + +c_u_uc_min_output_constraint(B_2020_winter_day_E_BATT_2020)_: +-1 v_flow_out(B_2020_winter_day_ELC_E_BATT_2020_ELC) ++0.03285 v_uc_online(B_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_uc_min_output_constraint(B_2020_winter_night_E_BATT_2020)_: +-1 v_flow_out(B_2020_winter_night_ELC_E_BATT_2020_ELC) ++0.03285 v_uc_online(B_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_uc_min_output_constraint(A_2020_winter_night_NGCC_2015)_: +-1 v_flow_out(A_2020_winter_night_NG_NGCC_2015_ELC) ++0.0657 v_uc_online(A_2020_winter_night_NGCC_2015) +<= 0 + +c_u_uc_min_output_constraint(A_2025_summer_night_NGCC_2025)_: +-1 v_flow_out(A_2025_summer_night_NG_NGCC_2025_ELC) ++0.0657 v_uc_online(A_2025_summer_night_NGCC_2025) +<= 0 + +c_u_uc_min_output_constraint(B_2025_winter_night_E_BATT_2020)_: +-1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2020_ELC) ++0.03285 v_uc_online(B_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_uc_min_output_constraint(B_2025_winter_night_E_LDES_2025)_: +-1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2025_ELC) ++0.013139999999999999 v_uc_online(B_2025_winter_night_E_LDES_2025) +<= 0 + +c_u_uc_min_output_constraint(A_B_2025_summer_day_E_TRANS_2015)_: +-1 v_flow_out(A_B_2025_summer_day_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(A_B_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(A_2020_winter_day_NGCC_2020)_: +-1 v_flow_out(A_2020_winter_day_NG_NGCC_2020_ELC) ++0.0657 v_uc_online(A_2020_winter_day_NGCC_2020) +<= 0 + +c_u_uc_min_output_constraint(A_2025_winter_day_NGCC_2025)_: +-1 v_flow_out(A_2025_winter_day_NG_NGCC_2025_ELC) ++0.0657 v_uc_online(A_2025_winter_day_NGCC_2025) +<= 0 + +c_u_uc_min_output_constraint(A_2025_summer_day_NGCC_2020)_: +-1 v_flow_out(A_2025_summer_day_NG_NGCC_2020_ELC) ++0.0657 v_uc_online(A_2025_summer_day_NGCC_2020) +<= 0 + +c_u_uc_min_output_constraint(A_2020_summer_night_NGCC_2015)_: +-1 v_flow_out(A_2020_summer_night_NG_NGCC_2015_ELC) ++0.0657 v_uc_online(A_2020_summer_night_NGCC_2015) +<= 0 + +c_u_uc_min_output_constraint(B_A_2020_summer_night_E_TRANS_2015)_: +-1 v_flow_out(B_A_2020_summer_night_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(B_A_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(B_2025_winter_day_E_BATT_2025)_: +-1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2025_ELC) ++0.03285 v_uc_online(B_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_uc_min_output_constraint(A_B_2020_summer_night_E_TRANS_2015)_: +-1 v_flow_out(A_B_2020_summer_night_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(A_B_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(B_A_2025_summer_day_E_TRANS_2015)_: +-1 v_flow_out(B_A_2025_summer_day_ELC_E_TRANS_2015_ELC) ++0.1314 v_uc_online(B_A_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_uc_min_output_constraint(A_2025_winter_night_NGCC_2025)_: +-1 v_flow_out(A_2025_winter_night_NG_NGCC_2025_ELC) ++0.0657 v_uc_online(A_2025_winter_night_NGCC_2025) +<= 0 + +c_u_uc_min_output_constraint(B_2025_summer_night_E_LDES_2025)_: +-1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2025_ELC) ++0.013139999999999999 v_uc_online(B_2025_summer_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_winter_day_SOLPV_2020)_: ++1 v_flow_out(A_2020_winter_day_ethos_SOLPV_2020_ELC) +-0.6569999999999999 v_capacity(A_2020_SOLPV_2020) ++1 v_orm_online_credit(spin_A_A_2020_winter_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_B_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(C_B_2020_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_night_E_LDES_2020)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) +-1 v_flow_in(A_2025_winter_night_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_winter_night_E_LDES_2020)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2025_winter_night_E_LDES_2020) +-1 v_flow_in(B_2025_winter_night_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_C_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(B_C_2020_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_winter_night_SOLPV_2015)_: ++1 v_flow_out(A_2020_winter_night_ethos_SOLPV_2015_ELC) ++1 v_orm_online_credit(spin_A_A_2020_winter_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2020_summer_night_E_BATT_2020)_: ++1 v_flow_out(B_2020_summer_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_summer_night_E_BATT_2020) +-1 v_flow_in(B_2020_summer_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(reg_B_B_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_summer_night_E_BATT_2025)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_summer_night_E_BATT_2025) +-1 v_flow_in(B_2025_summer_night_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(reg_B_B_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_summer_night_NGCC_2020)_: ++1 v_flow_out(B_2025_summer_night_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2025_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_summer_day_E_BATT_2020)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_summer_day_E_BATT_2020) +-1 v_flow_in(B_2025_summer_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_C_A_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(C_A_2025_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_night_E_BATT_2025)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) +-1 v_flow_in(A_2025_summer_night_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_summer_day_E_LDES_2025)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2025_ELC) +-0.0438 v_uc_online(B_2025_summer_day_E_LDES_2025) +-1 v_flow_in(B_2025_summer_day_ELC_E_LDES_2025_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_summer_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_B_A_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(B_A_2025_winter_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2025_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_B_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(C_B_2025_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_winter_day_NGCC_2020)_: ++1 v_flow_out(B_2025_winter_day_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2025_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_A_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(C_A_2020_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_night_E_BATT_2020)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) +-1 v_flow_in(A_2025_summer_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_day_E_BATT_2025)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) +-1 v_flow_in(A_2025_summer_day_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_B_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(C_B_2020_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_winter_night_NGCC_2020)_: ++1 v_flow_out(A_2020_winter_night_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2020_winter_night_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2020_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2020_winter_night_NGCC_2020)_: ++1 v_flow_out(B_2020_winter_night_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2020_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_winter_day_E_BATT_2020)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_winter_day_E_BATT_2020) +-1 v_flow_in(B_2025_winter_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_winter_night_SOLPV_2015)_: ++1 v_flow_out(A_2020_winter_night_ethos_SOLPV_2015_ELC) ++1 v_orm_online_credit(spin_AB_A_2020_winter_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_winter_day_E_LDES_2025)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2025_ELC) +-0.0438 v_uc_online(B_2025_winter_day_E_LDES_2025) +-1 v_flow_in(B_2025_winter_day_ELC_E_LDES_2025_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_winter_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_night_E_BATT_2025)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) +-1 v_flow_in(A_2025_winter_night_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_night_NGCC_2020)_: ++1 v_flow_out(A_2025_winter_night_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2025_winter_night_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2020_winter_day_E_BATT_2020)_: ++1 v_flow_out(B_2020_winter_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_winter_day_E_BATT_2020) +-1 v_flow_in(B_2020_winter_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(reg_B_B_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_A_B_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(A_B_2025_summer_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2025_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_C_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(A_C_2025_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_C_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(A_C_2025_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_summer_day_NGCC_2025)_: ++1 v_flow_out(B_2025_summer_day_NG_NGCC_2025_ELC) +-2.19 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(reg_B_B_2025_summer_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_winter_day_E_BATT_2020)_: ++1 v_flow_out(A_2020_winter_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) +-1 v_flow_in(A_2020_winter_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_day_SOLPV_2020)_: ++1 v_flow_out(A_2025_winter_day_ethos_SOLPV_2020_ELC) +-0.6569999999999999 v_capacity(A_2025_SOLPV_2020) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_summer_night_NGCC_2015)_: ++1 v_flow_out(B_2020_summer_night_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2020_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_winter_night_E_LDES_2020)_: ++1 v_flow_out(B_2020_winter_night_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2020_winter_night_E_LDES_2020) +-1 v_flow_in(B_2020_winter_night_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2020_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_C_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(B_C_2025_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_night_NGCC_2020)_: ++1 v_flow_out(A_2025_summer_night_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2025_summer_night_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_summer_day_NGCC_2020)_: ++1 v_flow_out(A_2020_summer_day_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2020_summer_day_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2020_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_night_NGCC_2025)_: ++1 v_flow_out(A_2025_summer_night_NG_NGCC_2025_ELC) +-0.219 v_uc_online(A_2025_summer_night_NGCC_2025) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_night_SOLPV_2015)_: ++1 v_flow_out(A_2025_summer_night_ethos_SOLPV_2015_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_summer_day_SOLPV_2015)_: ++1 v_flow_out(A_2020_summer_day_ethos_SOLPV_2015_ELC) +-1.3139999999999998 v_capacity(A_2020_SOLPV_2015) ++1 v_orm_online_credit(spin_A_A_2020_summer_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_winter_night_E_LDES_2020)_: ++1 v_flow_out(A_2020_winter_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) +-1 v_flow_in(A_2020_winter_night_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2020_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_day_SOLPV_2025)_: ++1 v_flow_out(A_2025_winter_day_ethos_SOLPV_2025_ELC) +-0.6569999999999999 v_capacity(A_2025_SOLPV_2025) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_C_A_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(C_A_2020_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_day_SOLPV_2020)_: ++1 v_flow_out(A_2025_summer_day_ethos_SOLPV_2020_ELC) +-1.3139999999999998 v_capacity(A_2025_SOLPV_2020) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_night_SOLPV_2020)_: ++1 v_flow_out(A_2025_summer_night_ethos_SOLPV_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_B_A_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(B_A_2020_winter_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2020_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_summer_day_E_BATT_2020)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_summer_day_E_BATT_2020) +-1 v_flow_in(B_2025_summer_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(reg_B_B_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_winter_day_NGCC_2015)_: ++1 v_flow_out(B_2020_winter_day_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2020_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_B_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(C_B_2025_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_C_B_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(C_B_2020_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_night_NGCC_2015)_: ++1 v_flow_out(A_2025_winter_night_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2025_winter_night_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_summer_night_E_BATT_2020)_: ++1 v_flow_out(A_2020_summer_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) +-1 v_flow_in(A_2020_summer_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_C_B_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(C_B_2025_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_winter_day_NGCC_2020)_: ++1 v_flow_out(B_2025_winter_day_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2025_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2020_summer_night_NGCC_2020)_: ++1 v_flow_out(B_2020_summer_night_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2020_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_day_SOLPV_2025)_: ++1 v_flow_out(A_2025_summer_day_ethos_SOLPV_2025_ELC) +-1.3139999999999998 v_capacity(A_2025_SOLPV_2025) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_winter_day_SOLPV_2015)_: ++1 v_flow_out(A_2020_winter_day_ethos_SOLPV_2015_ELC) +-0.6569999999999999 v_capacity(A_2020_SOLPV_2015) ++1 v_orm_online_credit(spin_A_A_2020_winter_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2020_summer_day_E_BATT_2020)_: ++1 v_flow_out(B_2020_summer_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_summer_day_E_BATT_2020) +-1 v_flow_in(B_2020_summer_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(reg_B_B_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_A_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(B_A_2025_winter_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2025_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_summer_night_E_BATT_2020)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_summer_night_E_BATT_2020) +-1 v_flow_in(B_2025_summer_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(reg_B_B_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_summer_night_NGCC_2015)_: ++1 v_flow_out(B_2025_summer_night_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2025_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_winter_night_E_BATT_2025)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_winter_night_E_BATT_2025) +-1 v_flow_in(B_2025_winter_night_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(reg_B_B_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_night_E_BATT_2020)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) +-1 v_flow_in(A_2025_summer_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_C_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(A_C_2020_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_summer_day_E_LDES_2020)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2025_summer_day_E_LDES_2020) +-1 v_flow_in(B_2025_summer_day_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_night_NGCC_2025)_: ++1 v_flow_out(A_2025_summer_night_NG_NGCC_2025_ELC) +-0.219 v_uc_online(A_2025_summer_night_NGCC_2025) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_winter_day_NGCC_2015)_: ++1 v_flow_out(B_2025_winter_day_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2025_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_C_A_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(C_A_2020_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_summer_day_E_LDES_2020)_: ++1 v_flow_out(A_2020_summer_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) +-1 v_flow_in(A_2020_summer_day_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2020_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_C_A_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(C_A_2025_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_day_E_BATT_2020)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) +-1 v_flow_in(A_2025_summer_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_day_E_BATT_2025)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) +-1 v_flow_in(A_2025_winter_day_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_B_A_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(B_A_2025_summer_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2025_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_winter_night_NGCC_2015)_: ++1 v_flow_out(A_2020_winter_night_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2020_winter_night_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2020_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2020_winter_night_NGCC_2015)_: ++1 v_flow_out(B_2020_winter_night_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2020_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_summer_night_E_BATT_2025)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_summer_night_E_BATT_2025) +-1 v_flow_in(B_2025_summer_night_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_winter_day_E_LDES_2020)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2025_winter_day_E_LDES_2020) +-1 v_flow_in(B_2025_winter_day_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_night_E_BATT_2020)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) +-1 v_flow_in(A_2025_winter_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_night_NGCC_2015)_: ++1 v_flow_out(A_2025_winter_night_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2025_winter_night_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_night_E_LDES_2025)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) +-1 v_flow_in(A_2025_winter_night_ELC_E_LDES_2025_ELC) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_C_B_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(C_B_2020_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_C_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(B_C_2020_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_A_B_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(A_B_2020_summer_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2020_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_B_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(C_B_2020_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_summer_day_NGCC_2020)_: ++1 v_flow_out(B_2025_summer_day_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2025_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_day_E_BATT_2025)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) +-1 v_flow_in(A_2025_summer_day_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_winter_day_E_LDES_2020)_: ++1 v_flow_out(A_2020_winter_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) +-1 v_flow_in(A_2020_winter_day_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2020_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_day_SOLPV_2015)_: ++1 v_flow_out(A_2025_winter_day_ethos_SOLPV_2015_ELC) +-0.6569999999999999 v_capacity(A_2025_SOLPV_2015) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_night_NGCC_2015)_: ++1 v_flow_out(A_2025_summer_night_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2025_summer_night_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_summer_day_NGCC_2015)_: ++1 v_flow_out(A_2020_summer_day_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2020_summer_day_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2020_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_night_NGCC_2020)_: ++1 v_flow_out(A_2025_summer_night_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2025_summer_night_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_B_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(A_B_2025_winter_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2025_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_C_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(B_C_2025_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_day_SOLPV_2015)_: ++1 v_flow_out(A_2025_summer_day_ethos_SOLPV_2015_ELC) +-1.3139999999999998 v_capacity(A_2025_SOLPV_2015) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_day_SOLPV_2020)_: ++1 v_flow_out(A_2025_winter_day_ethos_SOLPV_2020_ELC) +-0.6569999999999999 v_capacity(A_2025_SOLPV_2020) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_C_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(B_C_2020_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_A_B_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(A_B_2020_winter_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2020_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_winter_night_NGCC_2025)_: ++1 v_flow_out(B_2025_winter_night_NG_NGCC_2025_ELC) +-2.19 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(reg_B_B_2025_winter_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_winter_night_E_BATT_2020)_: ++1 v_flow_out(A_2020_winter_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) +-1 v_flow_in(A_2020_winter_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_A_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(B_A_2025_summer_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2025_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_day_E_BATT_2025)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) +-1 v_flow_in(A_2025_winter_day_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_summer_day_NGCC_2020)_: ++1 v_flow_out(B_2020_summer_day_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2020_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_night_SOLPV_2015)_: ++1 v_flow_out(A_2025_winter_night_ethos_SOLPV_2015_ELC) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_C_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(A_C_2020_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_winter_day_NGCC_2015)_: ++1 v_flow_out(B_2025_winter_day_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2025_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2020_summer_night_NGCC_2015)_: ++1 v_flow_out(B_2020_summer_night_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2020_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_day_SOLPV_2020)_: ++1 v_flow_out(A_2025_summer_day_ethos_SOLPV_2020_ELC) +-1.3139999999999998 v_capacity(A_2025_SOLPV_2020) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_summer_day_E_BATT_2020)_: ++1 v_flow_out(A_2020_summer_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) +-1 v_flow_in(A_2020_summer_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_night_E_LDES_2025)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) +-1 v_flow_in(A_2025_summer_night_ELC_E_LDES_2025_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_summer_night_NGCC_2025)_: ++1 v_flow_out(B_2025_summer_night_NG_NGCC_2025_ELC) +-2.19 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(spin_AB_B_2025_summer_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_night_SOLPV_2025)_: ++1 v_flow_out(A_2025_winter_night_ethos_SOLPV_2025_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_summer_night_SOLPV_2020)_: ++1 v_flow_out(A_2020_summer_night_ethos_SOLPV_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2020_summer_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_C_B_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(C_B_2025_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_summer_night_E_LDES_2020)_: ++1 v_flow_out(A_2020_summer_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) +-1 v_flow_in(A_2020_summer_night_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2020_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_C_A_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(C_A_2025_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_winter_night_E_BATT_2020)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_winter_night_E_BATT_2020) +-1 v_flow_in(B_2025_winter_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(reg_B_B_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_B_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(A_B_2020_summer_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2020_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_C_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(A_C_2020_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_winter_night_NGCC_2015)_: ++1 v_flow_out(B_2025_winter_night_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2025_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_A_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(B_A_2020_winter_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2020_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_C_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(B_C_2020_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_day_E_BATT_2020)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) +-1 v_flow_in(A_2025_winter_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_day_NGCC_2025)_: ++1 v_flow_out(A_2025_winter_day_NG_NGCC_2025_ELC) +-0.219 v_uc_online(A_2025_winter_day_NGCC_2025) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_A_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(B_A_2025_winter_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2025_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_summer_night_E_BATT_2020)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_summer_night_E_BATT_2020) +-1 v_flow_in(B_2025_summer_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_night_E_LDES_2020)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) +-1 v_flow_in(A_2025_winter_night_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_B_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(A_B_2020_winter_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2020_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_B_A_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(B_A_2025_winter_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2025_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_day_NGCC_2025)_: ++1 v_flow_out(A_2025_summer_day_NG_NGCC_2025_ELC) +-0.219 v_uc_online(A_2025_summer_day_NGCC_2025) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_B_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(C_B_2025_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_summer_day_NGCC_2015)_: ++1 v_flow_out(B_2025_summer_day_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2025_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_day_E_BATT_2020)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) +-1 v_flow_in(A_2025_summer_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_summer_night_E_BATT_2020)_: ++1 v_flow_out(A_2020_summer_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) +-1 v_flow_in(A_2020_summer_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_C_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(A_C_2020_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2020_winter_day_NGCC_2020)_: ++1 v_flow_out(B_2020_winter_day_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2020_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_winter_night_NGCC_2020)_: ++1 v_flow_out(B_2025_winter_night_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2025_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_night_NGCC_2015)_: ++1 v_flow_out(A_2025_summer_night_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2025_summer_night_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_day_E_LDES_2025)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) +-1 v_flow_in(A_2025_summer_day_ELC_E_LDES_2025_ELC) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_winter_day_NGCC_2020)_: ++1 v_flow_out(A_2020_winter_day_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2020_winter_day_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2020_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_day_SOLPV_2015)_: ++1 v_flow_out(A_2025_winter_day_ethos_SOLPV_2015_ELC) +-0.6569999999999999 v_capacity(A_2025_SOLPV_2015) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_day_E_BATT_2020)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) +-1 v_flow_in(A_2025_winter_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_summer_day_NGCC_2015)_: ++1 v_flow_out(B_2020_summer_day_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2020_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_day_E_LDES_2025)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) +-1 v_flow_in(A_2025_winter_day_ELC_E_LDES_2025_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_day_SOLPV_2015)_: ++1 v_flow_out(A_2025_summer_day_ethos_SOLPV_2015_ELC) +-1.3139999999999998 v_capacity(A_2025_SOLPV_2015) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_winter_day_E_LDES_2020)_: ++1 v_flow_out(A_2020_winter_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) +-1 v_flow_in(A_2020_winter_day_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2020_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_summer_night_NGCC_2020)_: ++1 v_flow_out(B_2025_summer_night_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2025_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_night_E_LDES_2020)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) +-1 v_flow_in(A_2025_summer_night_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_B_A_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(B_A_2020_summer_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2020_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_winter_night_NGCC_2020)_: ++1 v_flow_out(B_2020_winter_night_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2020_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_summer_night_NGCC_2020)_: ++1 v_flow_out(A_2020_summer_night_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2020_summer_night_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2020_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_night_SOLPV_2020)_: ++1 v_flow_out(A_2025_winter_night_ethos_SOLPV_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_summer_night_SOLPV_2015)_: ++1 v_flow_out(A_2020_summer_night_ethos_SOLPV_2015_ELC) ++1 v_orm_online_credit(spin_AB_A_2020_summer_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_C_B_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(C_B_2025_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_summer_day_E_BATT_2020)_: ++1 v_flow_out(B_2020_summer_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_summer_day_E_BATT_2020) +-1 v_flow_in(B_2020_summer_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_A_B_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(A_B_2020_winter_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2020_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2020_summer_day_NGCC_2020)_: ++1 v_flow_out(B_2020_summer_day_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2020_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_summer_night_E_LDES_2020)_: ++1 v_flow_out(B_2020_summer_night_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2020_summer_night_E_LDES_2020) +-1 v_flow_in(B_2020_summer_night_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2020_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_A_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(C_A_2025_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_day_NGCC_2020)_: ++1 v_flow_out(A_2025_winter_day_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2025_winter_day_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_night_SOLPV_2015)_: ++1 v_flow_out(A_2025_summer_night_ethos_SOLPV_2015_ELC) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_winter_day_E_BATT_2020)_: ++1 v_flow_out(A_2020_winter_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) +-1 v_flow_in(A_2020_winter_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_C_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(B_C_2025_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_C_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(A_C_2025_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_day_NGCC_2020)_: ++1 v_flow_out(A_2025_summer_day_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2025_summer_day_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_day_NGCC_2025)_: ++1 v_flow_out(A_2025_winter_day_NG_NGCC_2025_ELC) +-0.219 v_uc_online(A_2025_winter_day_NGCC_2025) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_C_A_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(C_A_2025_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_C_A_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(C_A_2020_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_C_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(A_C_2020_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_A_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(B_A_2020_summer_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2020_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2020_winter_day_NGCC_2015)_: ++1 v_flow_out(B_2020_winter_day_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2020_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_A_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(C_A_2025_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_day_E_LDES_2020)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) +-1 v_flow_in(A_2025_summer_day_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_day_E_LDES_2025)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) +-1 v_flow_in(A_2025_winter_day_ELC_E_LDES_2025_ELC) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_day_NGCC_2025)_: ++1 v_flow_out(A_2025_summer_day_NG_NGCC_2025_ELC) +-0.219 v_uc_online(A_2025_summer_day_NGCC_2025) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_winter_day_NGCC_2015)_: ++1 v_flow_out(A_2020_winter_day_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2020_winter_day_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2020_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_C_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(B_C_2025_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_winter_night_SOLPV_2020)_: ++1 v_flow_out(A_2020_winter_night_ethos_SOLPV_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2020_winter_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_summer_night_E_BATT_2020)_: ++1 v_flow_out(B_2020_summer_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_summer_night_E_BATT_2020) +-1 v_flow_in(B_2020_summer_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_summer_night_SOLPV_2020)_: ++1 v_flow_out(A_2020_summer_night_ethos_SOLPV_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2020_summer_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_C_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(B_C_2025_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_day_E_LDES_2020)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) +-1 v_flow_in(A_2025_winter_day_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_winter_day_E_BATT_2020)_: ++1 v_flow_out(B_2020_winter_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_winter_day_E_BATT_2020) +-1 v_flow_in(B_2020_winter_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_B_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(A_B_2025_summer_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2025_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_winter_day_NGCC_2025)_: ++1 v_flow_out(B_2025_winter_day_NG_NGCC_2025_ELC) +-2.19 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(reg_B_B_2025_winter_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_summer_day_NGCC_2020)_: ++1 v_flow_out(A_2020_summer_day_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2020_summer_day_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2020_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_C_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(A_C_2025_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_summer_night_NGCC_2015)_: ++1 v_flow_out(B_2025_summer_night_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2025_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_A_B_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(A_B_2025_winter_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2025_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_summer_night_NGCC_2015)_: ++1 v_flow_out(A_2020_summer_night_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2020_summer_night_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2020_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_winter_night_E_LDES_2020)_: ++1 v_flow_out(A_2020_winter_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) +-1 v_flow_in(A_2020_winter_night_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2020_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_night_SOLPV_2015)_: ++1 v_flow_out(A_2025_winter_night_ethos_SOLPV_2015_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_night_NGCC_2025)_: ++1 v_flow_out(A_2025_winter_night_NG_NGCC_2025_ELC) +-0.219 v_uc_online(A_2025_winter_night_NGCC_2025) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2020_summer_day_NGCC_2015)_: ++1 v_flow_out(B_2020_summer_day_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2020_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_summer_day_NGCC_2025)_: ++1 v_flow_out(B_2025_summer_day_NG_NGCC_2025_ELC) +-2.19 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(spin_AB_B_2025_summer_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_day_E_LDES_2025)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) +-1 v_flow_in(A_2025_summer_day_ELC_E_LDES_2025_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_winter_day_NGCC_2020)_: ++1 v_flow_out(A_2020_winter_day_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2020_winter_day_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2020_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_summer_night_E_LDES_2025)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2025_ELC) +-0.0438 v_uc_online(B_2025_summer_night_E_LDES_2025) +-1 v_flow_in(B_2025_summer_night_ELC_E_LDES_2025_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_summer_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_winter_night_E_BATT_2020)_: ++1 v_flow_out(B_2020_winter_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_winter_night_E_BATT_2020) +-1 v_flow_in(B_2020_winter_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_summer_day_SOLPV_2020)_: ++1 v_flow_out(A_2020_summer_day_ethos_SOLPV_2020_ELC) +-1.3139999999999998 v_capacity(A_2020_SOLPV_2020) ++1 v_orm_online_credit(spin_AB_A_2020_summer_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_night_E_BATT_2025)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) +-1 v_flow_in(A_2025_winter_night_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_C_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(A_C_2025_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_summer_day_E_LDES_2020)_: ++1 v_flow_out(A_2020_summer_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) +-1 v_flow_in(A_2020_summer_day_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2020_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_night_E_LDES_2025)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) +-1 v_flow_in(A_2025_summer_night_ELC_E_LDES_2025_ELC) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_day_SOLPV_2025)_: ++1 v_flow_out(A_2025_summer_day_ethos_SOLPV_2025_ELC) +-1.3139999999999998 v_capacity(A_2025_SOLPV_2025) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_C_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(B_C_2020_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_C_B_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(C_B_2020_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_C_B_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(C_B_2025_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_C_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(B_C_2020_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_winter_day_NGCC_2020)_: ++1 v_flow_out(B_2020_winter_day_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2020_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_B_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(A_B_2020_summer_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2020_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_day_NGCC_2015)_: ++1 v_flow_out(A_2025_summer_day_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2025_summer_day_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_day_NGCC_2020)_: ++1 v_flow_out(A_2025_winter_day_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2025_winter_day_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_A_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(B_A_2020_summer_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2020_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_night_SOLPV_2025)_: ++1 v_flow_out(A_2025_winter_night_ethos_SOLPV_2025_ELC) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2020_winter_night_E_BATT_2020)_: ++1 v_flow_out(B_2020_winter_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2020_winter_night_E_BATT_2020) +-1 v_flow_in(B_2020_winter_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(reg_B_B_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_A_B_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(A_B_2025_summer_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2025_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_C_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(B_C_2020_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_C_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(A_C_2025_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_winter_day_SOLPV_2020)_: ++1 v_flow_out(A_2020_winter_day_ethos_SOLPV_2020_ELC) +-0.6569999999999999 v_capacity(A_2020_SOLPV_2020) ++1 v_orm_online_credit(spin_AB_A_2020_winter_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_day_NGCC_2020)_: ++1 v_flow_out(A_2025_summer_day_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2025_summer_day_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_day_E_LDES_2020)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) +-1 v_flow_in(A_2025_winter_day_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_summer_night_NGCC_2020)_: ++1 v_flow_out(A_2020_summer_night_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2020_summer_night_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2020_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_A_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(B_A_2020_winter_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2020_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_summer_night_SOLPV_2015)_: ++1 v_flow_out(A_2020_summer_night_ethos_SOLPV_2015_ELC) ++1 v_orm_online_credit(spin_A_A_2020_summer_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_C_A_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(C_A_2020_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_C_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(A_C_2025_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_winter_night_NGCC_2025)_: ++1 v_flow_out(B_2025_winter_night_NG_NGCC_2025_ELC) +-2.19 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(spin_AB_B_2025_winter_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_B_A_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(B_A_2020_winter_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2020_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_winter_day_E_LDES_2020)_: ++1 v_flow_out(B_2020_winter_day_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2020_winter_day_E_LDES_2020) +-1 v_flow_in(B_2020_winter_day_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2020_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_summer_day_NGCC_2015)_: ++1 v_flow_out(A_2020_summer_day_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2020_summer_day_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2020_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_B_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(A_B_2020_winter_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2020_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_winter_night_NGCC_2020)_: ++1 v_flow_out(A_2020_winter_night_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2020_winter_night_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2020_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_night_SOLPV_2025)_: ++1 v_flow_out(A_2025_summer_night_ethos_SOLPV_2025_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_A_B_2020_summer_night_E_TRANS_2015)_: ++1 v_flow_out(A_B_2020_summer_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2020_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_night_NGCC_2025)_: ++1 v_flow_out(A_2025_winter_night_NG_NGCC_2025_ELC) +-0.219 v_uc_online(A_2025_winter_night_NGCC_2025) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_C_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(B_C_2025_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_B_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(C_B_2025_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_summer_day_NGCC_2020)_: ++1 v_flow_out(B_2025_summer_day_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2025_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_winter_day_E_BATT_2025)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_winter_day_E_BATT_2025) +-1 v_flow_in(B_2025_winter_day_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(reg_B_B_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_summer_day_E_BATT_2020)_: ++1 v_flow_out(A_2020_summer_day_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) +-1 v_flow_in(A_2020_summer_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_B_A_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(B_A_2020_summer_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2020_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_winter_day_NGCC_2015)_: ++1 v_flow_out(A_2020_winter_day_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2020_winter_day_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2020_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_day_E_LDES_2020)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) +-1 v_flow_in(A_2025_summer_day_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_summer_night_E_LDES_2020)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2025_summer_night_E_LDES_2020) +-1 v_flow_in(B_2025_summer_night_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_C_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(B_C_2025_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_summer_day_SOLPV_2015)_: ++1 v_flow_out(A_2020_summer_day_ethos_SOLPV_2015_ELC) +-1.3139999999999998 v_capacity(A_2020_SOLPV_2015) ++1 v_orm_online_credit(spin_AB_A_2020_summer_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_winter_night_E_BATT_2020)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_winter_night_E_BATT_2020) +-1 v_flow_in(B_2025_winter_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_winter_night_NGCC_2015)_: ++1 v_flow_out(B_2025_winter_night_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2025_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_summer_night_E_LDES_2020)_: ++1 v_flow_out(A_2020_summer_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2020_E_LDES_2020) +-1 v_flow_in(A_2020_summer_night_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2020_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_night_E_LDES_2020)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2020_ELC) +-2.19 v_capacity(A_2025_E_LDES_2020) +-1 v_flow_in(A_2025_summer_night_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_winter_night_E_LDES_2025)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2025_ELC) +-0.0438 v_uc_online(B_2025_winter_night_E_LDES_2025) +-1 v_flow_in(B_2025_winter_night_ELC_E_LDES_2025_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_winter_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_night_E_LDES_2025)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2025_ELC) +-2.19 v_capacity(A_2025_E_LDES_2025) +-1 v_flow_in(A_2025_winter_night_ELC_E_LDES_2025_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_night_E_BATT_2020)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2025_E_BATT_2020) +-1 v_flow_in(A_2025_winter_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_A_B_2025_winter_day_E_TRANS_2015)_: ++1 v_flow_out(A_B_2025_winter_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2025_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_C_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(A_C_2020_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_A_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(C_A_2025_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_summer_night_NGCC_2025)_: ++1 v_flow_out(B_2025_summer_night_NG_NGCC_2025_ELC) +-2.19 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(reg_B_B_2025_summer_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_summer_day_E_BATT_2025)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_summer_day_E_BATT_2025) +-1 v_flow_in(B_2025_summer_day_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_day_NGCC_2015)_: ++1 v_flow_out(A_2025_winter_day_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2025_winter_day_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_winter_night_SOLPV_2020)_: ++1 v_flow_out(A_2025_winter_night_ethos_SOLPV_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_summer_day_E_LDES_2020)_: ++1 v_flow_out(B_2020_summer_day_ELC_E_LDES_2020_ELC) +-0.0438 v_uc_online(B_2020_summer_day_E_LDES_2020) +-1 v_flow_in(B_2020_summer_day_ELC_E_LDES_2020_ELC) ++1 v_orm_online_credit(spin_AB_B_2020_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_B_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(C_B_2020_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_A_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(C_A_2025_summer_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_night_E_BATT_2025)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2025_ELC) +-2.19 v_capacity(A_2025_E_BATT_2025) +-1 v_flow_in(A_2025_summer_night_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_winter_day_SOLPV_2015)_: ++1 v_flow_out(A_2020_winter_day_ethos_SOLPV_2015_ELC) +-0.6569999999999999 v_capacity(A_2020_SOLPV_2015) ++1 v_orm_online_credit(spin_AB_A_2020_winter_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_winter_night_NGCC_2015)_: ++1 v_flow_out(B_2020_winter_night_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2020_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_A_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(C_A_2020_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_day_NGCC_2015)_: ++1 v_flow_out(A_2025_summer_day_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2025_summer_day_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_winter_day_E_BATT_2025)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_winter_day_E_BATT_2025) +-1 v_flow_in(B_2025_winter_day_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_C_B_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(C_B_2020_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_summer_night_NGCC_2015)_: ++1 v_flow_out(A_2020_summer_night_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2020_summer_night_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2020_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_B_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(A_B_2025_winter_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2025_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_C_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(B_C_2020_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_C_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(B_C_2025_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2020_winter_night_SOLPV_2020)_: ++1 v_flow_out(A_2020_winter_night_ethos_SOLPV_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2020_winter_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_C_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(A_C_2020_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_winter_night_E_BATT_2025)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_winter_night_E_BATT_2025) +-1 v_flow_in(B_2025_winter_night_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(spin_AB_B_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_winter_night_NGCC_2020)_: ++1 v_flow_out(B_2025_winter_night_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2025_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_C_2025_winter_night_E_TRANS_2015)_: ++1 v_flow_out(A_C_2025_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_day_SOLPV_2025)_: ++1 v_flow_out(A_2025_winter_day_ethos_SOLPV_2025_ELC) +-0.6569999999999999 v_capacity(A_2025_SOLPV_2025) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_A_2025_summer_night_E_TRANS_2015)_: ++1 v_flow_out(B_A_2025_summer_night_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2025_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2020_summer_night_NGCC_2020)_: ++1 v_flow_out(B_2020_summer_night_NG_NGCC_2020_ELC) +-2.19 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2020_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_C_2020_winter_day_E_TRANS_2015)_: ++1 v_flow_out(A_C_2020_winter_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_winter_night_E_BATT_2020)_: ++1 v_flow_out(A_2020_winter_night_ELC_E_BATT_2020_ELC) +-2.19 v_capacity(A_2020_E_BATT_2020) +-1 v_flow_in(A_2020_winter_night_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(spin_A_A_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_winter_night_NGCC_2015)_: ++1 v_flow_out(A_2020_winter_night_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2020_winter_night_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2020_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2020_summer_day_SOLPV_2020)_: ++1 v_flow_out(A_2020_summer_day_ethos_SOLPV_2020_ELC) +-1.3139999999999998 v_capacity(A_2020_SOLPV_2020) ++1 v_orm_online_credit(spin_A_A_2020_summer_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_B_A_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(B_A_2025_summer_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(B_A_2025_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_2025_summer_night_SOLPV_2025)_: ++1 v_flow_out(A_2025_summer_night_ethos_SOLPV_2025_ELC) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_summer_day_E_BATT_2025)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2025_ELC) +-0.1095 v_uc_online(B_2025_summer_day_E_BATT_2025) +-1 v_flow_in(B_2025_summer_day_ELC_E_BATT_2025_ELC) ++1 v_orm_online_credit(reg_B_B_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_A_2020_winter_night_E_TRANS_2015)_: ++1 v_flow_out(C_A_2020_winter_night_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_summer_night_SOLPV_2020)_: ++1 v_flow_out(A_2025_summer_night_ethos_SOLPV_2020_ELC) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_day_NGCC_2015)_: ++1 v_flow_out(A_2025_winter_day_NG_NGCC_2015_ELC) +-0.219 v_uc_online(A_2025_winter_day_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_A_A_B_2025_summer_day_E_TRANS_2015)_: ++1 v_flow_out(A_B_2025_summer_day_ELC_E_TRANS_2015_ELC) +-0.438 v_uc_online(A_B_2025_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_A_2025_winter_night_NGCC_2020)_: ++1 v_flow_out(A_2025_winter_night_NG_NGCC_2020_ELC) +-0.219 v_uc_online(A_2025_winter_night_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_summer_day_NGCC_2015)_: ++1 v_flow_out(B_2025_summer_day_NG_NGCC_2015_ELC) +-2.19 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2025_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(reg_B_B_2025_winter_day_E_BATT_2020)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2020_ELC) +-0.1095 v_uc_online(B_2025_winter_day_E_BATT_2020) +-1 v_flow_in(B_2025_winter_day_ELC_E_BATT_2020_ELC) ++1 v_orm_online_credit(reg_B_B_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_C_A_2020_summer_day_E_TRANS_2015)_: ++1 v_flow_out(C_A_2020_summer_day_ELC_E_TRANS_2015_ELC) +-2.19 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_constraint(spin_AB_B_2025_winter_day_NGCC_2025)_: ++1 v_flow_out(B_2025_winter_day_NG_NGCC_2025_ELC) +-2.19 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(spin_AB_B_2025_winter_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_winter_day_SOLPV_2020)_: +-0.1095 v_capacity(A_2020_SOLPV_2020) ++1 v_orm_online_credit(spin_A_A_2020_winter_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_B_2020_winter_day_E_TRANS_2015)_: +-1.1607 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_night_E_LDES_2020)_: +-0.876 v_capacity(A_2025_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_winter_night_E_LDES_2020)_: +-0.01752 v_uc_online(B_2025_winter_night_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_B_2025_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_C_2020_summer_night_E_TRANS_2015)_: +-0.5256 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_winter_night_SOLPV_2015)_: +-0.1095 v_capacity(A_2020_SOLPV_2015) ++1 v_orm_online_credit(spin_A_A_2020_winter_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2020_summer_night_E_BATT_2020)_: +-0.043800000000000006 v_uc_online(B_2020_summer_night_E_BATT_2020) ++1 v_orm_online_credit(reg_B_B_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_summer_night_E_BATT_2025)_: +-0.043800000000000006 v_uc_online(B_2025_summer_night_E_BATT_2025) ++1 v_orm_online_credit(reg_B_B_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_summer_night_NGCC_2020)_: +-0.438 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2025_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_summer_day_E_BATT_2020)_: +-0.05475 v_uc_online(B_2025_summer_day_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_B_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_C_A_2025_summer_day_E_TRANS_2015)_: +-0.8321999999999999 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_night_E_BATT_2025)_: +-2.19 v_capacity(A_2025_E_BATT_2025) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_summer_day_E_LDES_2025)_: +-0.01752 v_uc_online(B_2025_summer_day_E_LDES_2025) ++1 v_orm_online_credit(spin_AB_B_2025_summer_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_B_A_2025_winter_day_E_TRANS_2015)_: +-0.15768000000000001 v_uc_online(B_A_2025_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_B_2025_summer_night_E_TRANS_2015)_: +-1.1607 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_winter_day_NGCC_2020)_: +-0.438 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2025_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_A_2020_summer_night_E_TRANS_2015)_: +-1.2483 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_night_E_BATT_2020)_: +-1.095 v_capacity(A_2025_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_day_E_BATT_2025)_: +-2.19 v_capacity(A_2025_E_BATT_2025) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_B_2020_winter_night_E_TRANS_2015)_: +-1.1607 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_winter_night_NGCC_2020)_: +-0.0657 v_uc_online(A_2020_winter_night_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2020_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2020_winter_night_NGCC_2020)_: +-0.438 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2020_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_winter_day_E_BATT_2020)_: +-0.05475 v_uc_online(B_2025_winter_day_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_B_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_winter_night_SOLPV_2015)_: +-0.1095 v_capacity(A_2020_SOLPV_2015) ++1 v_orm_online_credit(spin_AB_A_2020_winter_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_winter_day_E_LDES_2025)_: +-0.01752 v_uc_online(B_2025_winter_day_E_LDES_2025) ++1 v_orm_online_credit(spin_AB_B_2025_winter_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_night_E_BATT_2025)_: +-2.19 v_capacity(A_2025_E_BATT_2025) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_night_NGCC_2020)_: +-0.1095 v_uc_online(A_2025_winter_night_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2020_winter_day_E_BATT_2020)_: +-0.043800000000000006 v_uc_online(B_2020_winter_day_E_BATT_2020) ++1 v_orm_online_credit(reg_B_B_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_A_B_2025_summer_day_E_TRANS_2015)_: +-0.1314 v_uc_online(A_B_2025_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_C_2025_winter_day_E_TRANS_2015)_: +-1.1169 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_C_2025_winter_day_E_TRANS_2015)_: +-0.7446 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_summer_day_NGCC_2025)_: +-0.438 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(reg_B_B_2025_summer_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_winter_day_E_BATT_2020)_: +-2.19 v_capacity(A_2020_E_BATT_2020) ++1 v_orm_online_credit(spin_A_A_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_day_SOLPV_2020)_: +-0.1095 v_capacity(A_2025_SOLPV_2020) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_summer_night_NGCC_2015)_: +-0.6569999999999999 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2020_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_winter_night_E_LDES_2020)_: +-0.01752 v_uc_online(B_2020_winter_night_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_B_2020_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_C_2025_winter_night_E_TRANS_2015)_: +-1.0512 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_night_NGCC_2020)_: +-0.0657 v_uc_online(A_2025_summer_night_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_summer_day_NGCC_2020)_: +-0.1095 v_uc_online(A_2020_summer_day_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2020_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_night_NGCC_2025)_: +-0.1095 v_uc_online(A_2025_summer_night_NGCC_2025) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_night_SOLPV_2015)_: +-0.1095 v_capacity(A_2025_SOLPV_2015) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_summer_day_SOLPV_2015)_: +-0.1095 v_capacity(A_2020_SOLPV_2015) ++1 v_orm_online_credit(spin_A_A_2020_summer_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_winter_night_E_LDES_2020)_: +-1.3139999999999998 v_capacity(A_2020_E_LDES_2020) ++1 v_orm_online_credit(spin_A_A_2020_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_day_SOLPV_2025)_: +-0.1095 v_capacity(A_2025_SOLPV_2025) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_C_A_2020_summer_day_E_TRANS_2015)_: +-0.8321999999999999 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_day_SOLPV_2020)_: +-0.1095 v_capacity(A_2025_SOLPV_2020) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_night_SOLPV_2020)_: +-0.1095 v_capacity(A_2025_SOLPV_2020) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_B_A_2020_winter_day_E_TRANS_2015)_: +-0.15768000000000001 v_uc_online(B_A_2020_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_summer_day_E_BATT_2020)_: +-0.043800000000000006 v_uc_online(B_2025_summer_day_E_BATT_2020) ++1 v_orm_online_credit(reg_B_B_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_winter_day_NGCC_2015)_: +-0.6569999999999999 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2020_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_B_2025_winter_night_E_TRANS_2015)_: +-1.1607 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_C_B_2020_summer_day_E_TRANS_2015)_: +-0.5694 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_night_NGCC_2015)_: +-0.0657 v_uc_online(A_2025_winter_night_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_summer_night_E_BATT_2020)_: +-1.095 v_capacity(A_2020_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_A_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_C_B_2025_summer_night_E_TRANS_2015)_: +-0.5694 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_winter_day_NGCC_2020)_: +-0.6569999999999999 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2025_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2020_summer_night_NGCC_2020)_: +-0.438 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2020_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_day_SOLPV_2025)_: +-0.1095 v_capacity(A_2025_SOLPV_2025) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_winter_day_SOLPV_2015)_: +-0.1095 v_capacity(A_2020_SOLPV_2015) ++1 v_orm_online_credit(spin_A_A_2020_winter_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2020_summer_day_E_BATT_2020)_: +-0.043800000000000006 v_uc_online(B_2020_summer_day_E_BATT_2020) ++1 v_orm_online_credit(reg_B_B_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_A_2025_winter_night_E_TRANS_2015)_: +-0.11826000000000002 v_uc_online(B_A_2025_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_summer_night_E_BATT_2020)_: +-0.043800000000000006 v_uc_online(B_2025_summer_night_E_BATT_2020) ++1 v_orm_online_credit(reg_B_B_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_summer_night_NGCC_2015)_: +-0.438 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2025_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_winter_night_E_BATT_2025)_: +-0.043800000000000006 v_uc_online(B_2025_winter_night_E_BATT_2025) ++1 v_orm_online_credit(reg_B_B_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_night_E_BATT_2020)_: +-2.19 v_capacity(A_2025_E_BATT_2020) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_C_2020_summer_night_E_TRANS_2015)_: +-1.1169 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_summer_day_E_LDES_2020)_: +-0.01752 v_uc_online(B_2025_summer_day_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_B_2025_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_night_NGCC_2025)_: +-0.0657 v_uc_online(A_2025_summer_night_NGCC_2025) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_winter_day_NGCC_2015)_: +-0.438 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2025_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_C_A_2020_winter_day_E_TRANS_2015)_: +-0.8321999999999999 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_summer_day_E_LDES_2020)_: +-0.876 v_capacity(A_2020_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_A_2020_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_C_A_2025_winter_night_E_TRANS_2015)_: +-0.8321999999999999 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_day_E_BATT_2020)_: +-2.19 v_capacity(A_2025_E_BATT_2020) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_day_E_BATT_2025)_: +-2.19 v_capacity(A_2025_E_BATT_2025) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_B_A_2025_summer_night_E_TRANS_2015)_: +-0.15768000000000001 v_uc_online(B_A_2025_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_winter_night_NGCC_2015)_: +-0.0657 v_uc_online(A_2020_winter_night_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2020_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2020_winter_night_NGCC_2015)_: +-0.438 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2020_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_summer_night_E_BATT_2025)_: +-0.05475 v_uc_online(B_2025_summer_night_E_BATT_2025) ++1 v_orm_online_credit(spin_AB_B_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_winter_day_E_LDES_2020)_: +-0.01752 v_uc_online(B_2025_winter_day_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_B_2025_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_night_E_BATT_2020)_: +-2.19 v_capacity(A_2025_E_BATT_2020) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_night_NGCC_2015)_: +-0.1095 v_uc_online(A_2025_winter_night_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_night_E_LDES_2025)_: +-1.3139999999999998 v_capacity(A_2025_E_LDES_2025) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_C_B_2020_summer_night_E_TRANS_2015)_: +-0.5694 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_C_2020_summer_day_E_TRANS_2015)_: +-0.5256 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_A_B_2020_summer_day_E_TRANS_2015)_: +-0.1314 v_uc_online(A_B_2020_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_B_2020_summer_night_E_TRANS_2015)_: +-1.1607 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_summer_day_NGCC_2020)_: +-0.438 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2025_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_day_E_BATT_2025)_: +-1.095 v_capacity(A_2025_E_BATT_2025) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_winter_day_E_LDES_2020)_: +-0.876 v_capacity(A_2020_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_A_2020_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_day_SOLPV_2015)_: +-0.1095 v_capacity(A_2025_SOLPV_2015) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_night_NGCC_2015)_: +-0.0657 v_uc_online(A_2025_summer_night_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_summer_day_NGCC_2015)_: +-0.1095 v_uc_online(A_2020_summer_day_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2020_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_night_NGCC_2020)_: +-0.1095 v_uc_online(A_2025_summer_night_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_B_2025_winter_day_E_TRANS_2015)_: +-0.17520000000000002 v_uc_online(A_B_2025_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_C_2025_winter_day_E_TRANS_2015)_: +-0.5256 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_day_SOLPV_2015)_: +-0.1095 v_capacity(A_2025_SOLPV_2015) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_day_SOLPV_2020)_: +-0.1095 v_capacity(A_2025_SOLPV_2020) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_C_2020_winter_night_E_TRANS_2015)_: +-0.5256 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_A_B_2020_winter_night_E_TRANS_2015)_: +-0.1314 v_uc_online(A_B_2020_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_winter_night_NGCC_2025)_: +-0.438 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(reg_B_B_2025_winter_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_winter_night_E_BATT_2020)_: +-1.095 v_capacity(A_2020_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_A_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_A_2025_summer_day_E_TRANS_2015)_: +-0.11826000000000002 v_uc_online(B_A_2025_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_day_E_BATT_2025)_: +-1.095 v_capacity(A_2025_E_BATT_2025) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_summer_day_NGCC_2020)_: +-0.6569999999999999 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2020_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_night_SOLPV_2015)_: +-0.1095 v_capacity(A_2025_SOLPV_2015) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_C_2020_winter_night_E_TRANS_2015)_: +-1.1169 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_winter_day_NGCC_2015)_: +-0.6569999999999999 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2025_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2020_summer_night_NGCC_2015)_: +-0.438 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2020_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_day_SOLPV_2020)_: +-0.1095 v_capacity(A_2025_SOLPV_2020) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_summer_day_E_BATT_2020)_: +-2.19 v_capacity(A_2020_E_BATT_2020) ++1 v_orm_online_credit(spin_A_A_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_night_E_LDES_2025)_: +-0.876 v_capacity(A_2025_E_LDES_2025) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_summer_night_NGCC_2025)_: +-0.6569999999999999 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(spin_AB_B_2025_summer_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_night_SOLPV_2025)_: +-0.1095 v_capacity(A_2025_SOLPV_2025) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_summer_night_SOLPV_2020)_: +-0.1095 v_capacity(A_2020_SOLPV_2020) ++1 v_orm_online_credit(spin_AB_A_2020_summer_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_C_B_2025_winter_day_E_TRANS_2015)_: +-0.5694 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_summer_night_E_LDES_2020)_: +-1.3139999999999998 v_capacity(A_2020_E_LDES_2020) ++1 v_orm_online_credit(spin_A_A_2020_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_C_A_2025_summer_night_E_TRANS_2015)_: +-0.8321999999999999 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_winter_night_E_BATT_2020)_: +-0.043800000000000006 v_uc_online(B_2025_winter_night_E_BATT_2020) ++1 v_orm_online_credit(reg_B_B_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_B_2020_summer_day_E_TRANS_2015)_: +-0.17520000000000002 v_uc_online(A_B_2020_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_C_2020_summer_day_E_TRANS_2015)_: +-0.7446 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_winter_night_NGCC_2015)_: +-0.6569999999999999 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2025_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_A_2020_winter_night_E_TRANS_2015)_: +-0.11826000000000002 v_uc_online(B_A_2020_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_C_2020_winter_night_E_TRANS_2015)_: +-1.0512 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_day_E_BATT_2020)_: +-2.19 v_capacity(A_2025_E_BATT_2020) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_day_NGCC_2025)_: +-0.0657 v_uc_online(A_2025_winter_day_NGCC_2025) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_A_2025_winter_day_E_TRANS_2015)_: +-0.11826000000000002 v_uc_online(B_A_2025_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_summer_night_E_BATT_2020)_: +-0.05475 v_uc_online(B_2025_summer_night_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_B_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_night_E_LDES_2020)_: +-1.3139999999999998 v_capacity(A_2025_E_LDES_2020) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_B_2020_winter_day_E_TRANS_2015)_: +-0.17520000000000002 v_uc_online(A_B_2020_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_B_A_2025_winter_night_E_TRANS_2015)_: +-0.15768000000000001 v_uc_online(B_A_2025_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_day_NGCC_2025)_: +-0.1095 v_uc_online(A_2025_summer_day_NGCC_2025) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_B_2025_summer_day_E_TRANS_2015)_: +-1.1607 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_summer_day_NGCC_2015)_: +-0.438 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2025_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_day_E_BATT_2020)_: +-1.095 v_capacity(A_2025_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_summer_night_E_BATT_2020)_: +-2.19 v_capacity(A_2020_E_BATT_2020) ++1 v_orm_online_credit(spin_A_A_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_C_2020_summer_night_E_TRANS_2015)_: +-0.7446 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2020_winter_day_NGCC_2020)_: +-0.438 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2020_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_winter_night_NGCC_2020)_: +-0.438 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2025_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_night_NGCC_2015)_: +-0.1095 v_uc_online(A_2025_summer_night_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_day_E_LDES_2025)_: +-1.3139999999999998 v_capacity(A_2025_E_LDES_2025) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_winter_day_NGCC_2020)_: +-0.1095 v_uc_online(A_2020_winter_day_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2020_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_day_SOLPV_2015)_: +-0.1095 v_capacity(A_2025_SOLPV_2015) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_day_E_BATT_2020)_: +-1.095 v_capacity(A_2025_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_summer_day_NGCC_2015)_: +-0.6569999999999999 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2020_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_day_E_LDES_2025)_: +-0.876 v_capacity(A_2025_E_LDES_2025) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_day_SOLPV_2015)_: +-0.1095 v_capacity(A_2025_SOLPV_2015) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_winter_day_E_LDES_2020)_: +-1.3139999999999998 v_capacity(A_2020_E_LDES_2020) ++1 v_orm_online_credit(spin_A_A_2020_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_summer_night_NGCC_2020)_: +-0.6569999999999999 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2025_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_night_E_LDES_2020)_: +-0.876 v_capacity(A_2025_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_B_A_2020_summer_night_E_TRANS_2015)_: +-0.15768000000000001 v_uc_online(B_A_2020_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_winter_night_NGCC_2020)_: +-0.6569999999999999 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2020_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_summer_night_NGCC_2020)_: +-0.0657 v_uc_online(A_2020_summer_night_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2020_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_night_SOLPV_2020)_: +-0.1095 v_capacity(A_2025_SOLPV_2020) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_summer_night_SOLPV_2015)_: +-0.1095 v_capacity(A_2020_SOLPV_2015) ++1 v_orm_online_credit(spin_AB_A_2020_summer_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_C_B_2025_summer_day_E_TRANS_2015)_: +-0.5694 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_summer_day_E_BATT_2020)_: +-0.05475 v_uc_online(B_2020_summer_day_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_B_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_A_B_2020_winter_day_E_TRANS_2015)_: +-0.1314 v_uc_online(A_B_2020_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2020_summer_day_NGCC_2020)_: +-0.438 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(reg_B_B_2020_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_summer_night_E_LDES_2020)_: +-0.01752 v_uc_online(B_2020_summer_night_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_B_2020_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_A_2025_winter_day_E_TRANS_2015)_: +-1.2483 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_day_NGCC_2020)_: +-0.0657 v_uc_online(A_2025_winter_day_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_night_SOLPV_2015)_: +-0.1095 v_capacity(A_2025_SOLPV_2015) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_winter_day_E_BATT_2020)_: +-1.095 v_capacity(A_2020_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_A_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_C_2025_summer_day_E_TRANS_2015)_: +-1.0512 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_C_2025_summer_night_E_TRANS_2015)_: +-1.1169 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_day_NGCC_2020)_: +-0.1095 v_uc_online(A_2025_summer_day_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_day_NGCC_2025)_: +-0.1095 v_uc_online(A_2025_winter_day_NGCC_2025) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_C_A_2025_winter_day_E_TRANS_2015)_: +-0.8321999999999999 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_C_A_2020_winter_night_E_TRANS_2015)_: +-0.8321999999999999 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_C_2020_winter_night_E_TRANS_2015)_: +-0.7446 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_A_2020_summer_night_E_TRANS_2015)_: +-0.11826000000000002 v_uc_online(B_A_2020_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2020_winter_day_NGCC_2015)_: +-0.438 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2020_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_A_2025_winter_night_E_TRANS_2015)_: +-1.2483 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_day_E_LDES_2020)_: +-1.3139999999999998 v_capacity(A_2025_E_LDES_2020) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_day_E_LDES_2025)_: +-1.3139999999999998 v_capacity(A_2025_E_LDES_2025) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_day_NGCC_2025)_: +-0.0657 v_uc_online(A_2025_summer_day_NGCC_2025) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_winter_day_NGCC_2015)_: +-0.1095 v_uc_online(A_2020_winter_day_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2020_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_C_2025_summer_night_E_TRANS_2015)_: +-0.5256 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_winter_night_SOLPV_2020)_: +-0.1095 v_capacity(A_2020_SOLPV_2020) ++1 v_orm_online_credit(spin_A_A_2020_winter_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_summer_night_E_BATT_2020)_: +-0.05475 v_uc_online(B_2020_summer_night_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_B_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_summer_night_SOLPV_2020)_: +-0.1095 v_capacity(A_2020_SOLPV_2020) ++1 v_orm_online_credit(spin_A_A_2020_summer_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_C_2025_summer_night_E_TRANS_2015)_: +-1.0512 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_day_E_LDES_2020)_: +-0.876 v_capacity(A_2025_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_winter_day_E_BATT_2020)_: +-0.05475 v_uc_online(B_2020_winter_day_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_B_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_B_2025_summer_night_E_TRANS_2015)_: +-0.17520000000000002 v_uc_online(A_B_2025_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_winter_day_NGCC_2025)_: +-0.438 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(reg_B_B_2025_winter_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_summer_day_NGCC_2020)_: +-0.0657 v_uc_online(A_2020_summer_day_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2020_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_C_2025_summer_day_E_TRANS_2015)_: +-0.7446 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_summer_night_NGCC_2015)_: +-0.6569999999999999 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2025_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_A_B_2025_winter_night_E_TRANS_2015)_: +-0.1314 v_uc_online(A_B_2025_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_summer_night_NGCC_2015)_: +-0.0657 v_uc_online(A_2020_summer_night_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2020_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_winter_night_E_LDES_2020)_: +-0.876 v_capacity(A_2020_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_A_2020_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_night_SOLPV_2015)_: +-0.1095 v_capacity(A_2025_SOLPV_2015) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_night_NGCC_2025)_: +-0.1095 v_uc_online(A_2025_winter_night_NGCC_2025) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2020_summer_day_NGCC_2015)_: +-0.438 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2020_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_summer_day_NGCC_2025)_: +-0.6569999999999999 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(spin_AB_B_2025_summer_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_day_E_LDES_2025)_: +-0.876 v_capacity(A_2025_E_LDES_2025) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_winter_day_NGCC_2020)_: +-0.0657 v_uc_online(A_2020_winter_day_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2020_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_summer_night_E_LDES_2025)_: +-0.01752 v_uc_online(B_2025_summer_night_E_LDES_2025) ++1 v_orm_online_credit(spin_AB_B_2025_summer_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_winter_night_E_BATT_2020)_: +-0.05475 v_uc_online(B_2020_winter_night_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_B_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_summer_day_SOLPV_2020)_: +-0.1095 v_capacity(A_2020_SOLPV_2020) ++1 v_orm_online_credit(spin_AB_A_2020_summer_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_night_E_BATT_2025)_: +-1.095 v_capacity(A_2025_E_BATT_2025) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_C_2025_summer_night_E_TRANS_2015)_: +-0.7446 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_summer_day_E_LDES_2020)_: +-1.3139999999999998 v_capacity(A_2020_E_LDES_2020) ++1 v_orm_online_credit(spin_A_A_2020_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_night_E_LDES_2025)_: +-1.3139999999999998 v_capacity(A_2025_E_LDES_2025) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_day_SOLPV_2025)_: +-0.1095 v_capacity(A_2025_SOLPV_2025) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_C_2020_winter_day_E_TRANS_2015)_: +-0.5256 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_C_B_2020_winter_night_E_TRANS_2015)_: +-0.5694 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_C_B_2025_winter_night_E_TRANS_2015)_: +-0.5694 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_C_2020_summer_night_E_TRANS_2015)_: +-1.0512 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_winter_day_NGCC_2020)_: +-0.6569999999999999 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2020_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_B_2020_summer_night_E_TRANS_2015)_: +-0.17520000000000002 v_uc_online(A_B_2020_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_day_NGCC_2015)_: +-0.1095 v_uc_online(A_2025_summer_day_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2025_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_day_NGCC_2020)_: +-0.1095 v_uc_online(A_2025_winter_day_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_A_2020_summer_day_E_TRANS_2015)_: +-0.11826000000000002 v_uc_online(B_A_2020_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_night_SOLPV_2025)_: +-0.1095 v_capacity(A_2025_SOLPV_2025) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2020_winter_night_E_BATT_2020)_: +-0.043800000000000006 v_uc_online(B_2020_winter_night_E_BATT_2020) ++1 v_orm_online_credit(reg_B_B_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_A_B_2025_summer_night_E_TRANS_2015)_: +-0.1314 v_uc_online(A_B_2025_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_C_2020_winter_day_E_TRANS_2015)_: +-1.0512 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_C_2025_winter_night_E_TRANS_2015)_: +-0.7446 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_winter_day_SOLPV_2020)_: +-0.1095 v_capacity(A_2020_SOLPV_2020) ++1 v_orm_online_credit(spin_AB_A_2020_winter_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_day_NGCC_2020)_: +-0.0657 v_uc_online(A_2025_summer_day_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_day_E_LDES_2020)_: +-1.3139999999999998 v_capacity(A_2025_E_LDES_2020) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_summer_night_NGCC_2020)_: +-0.1095 v_uc_online(A_2020_summer_night_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2020_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_A_2020_winter_day_E_TRANS_2015)_: +-0.11826000000000002 v_uc_online(B_A_2020_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_summer_night_SOLPV_2015)_: +-0.1095 v_capacity(A_2020_SOLPV_2015) ++1 v_orm_online_credit(spin_A_A_2020_summer_night_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_C_A_2020_summer_night_E_TRANS_2015)_: +-0.8321999999999999 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_C_2025_summer_day_E_TRANS_2015)_: +-1.1169 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_winter_night_NGCC_2025)_: +-0.6569999999999999 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(spin_AB_B_2025_winter_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_B_A_2020_winter_night_E_TRANS_2015)_: +-0.15768000000000001 v_uc_online(B_A_2020_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_winter_day_E_LDES_2020)_: +-0.01752 v_uc_online(B_2020_winter_day_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_B_2020_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_summer_day_NGCC_2015)_: +-0.0657 v_uc_online(A_2020_summer_day_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2020_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_B_2020_winter_night_E_TRANS_2015)_: +-0.17520000000000002 v_uc_online(A_B_2020_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_winter_night_NGCC_2020)_: +-0.1095 v_uc_online(A_2020_winter_night_NGCC_2020) ++1 v_orm_online_credit(spin_A_A_2020_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_night_SOLPV_2025)_: +-0.1095 v_capacity(A_2025_SOLPV_2025) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_A_B_2020_summer_night_E_TRANS_2015)_: +-0.1314 v_uc_online(A_B_2020_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_night_NGCC_2025)_: +-0.0657 v_uc_online(A_2025_winter_night_NGCC_2025) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_C_2025_summer_day_E_TRANS_2015)_: +-0.5256 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_B_2025_winter_day_E_TRANS_2015)_: +-1.1607 v_capacity(C_B_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_summer_day_NGCC_2020)_: +-0.6569999999999999 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2025_summer_day_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_winter_day_E_BATT_2025)_: +-0.043800000000000006 v_uc_online(B_2025_winter_day_E_BATT_2025) ++1 v_orm_online_credit(reg_B_B_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_summer_day_E_BATT_2020)_: +-1.095 v_capacity(A_2020_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_A_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_B_A_2020_summer_day_E_TRANS_2015)_: +-0.15768000000000001 v_uc_online(B_A_2020_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_winter_day_NGCC_2015)_: +-0.0657 v_uc_online(A_2020_winter_day_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2020_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_day_E_LDES_2020)_: +-0.876 v_capacity(A_2025_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_summer_night_E_LDES_2020)_: +-0.01752 v_uc_online(B_2025_summer_night_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_B_2025_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_C_2025_winter_day_E_TRANS_2015)_: +-1.0512 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_summer_day_SOLPV_2015)_: +-0.1095 v_capacity(A_2020_SOLPV_2015) ++1 v_orm_online_credit(spin_AB_A_2020_summer_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_winter_night_E_BATT_2020)_: +-0.05475 v_uc_online(B_2025_winter_night_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_B_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_winter_night_NGCC_2015)_: +-0.438 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(reg_B_B_2025_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_summer_night_E_LDES_2020)_: +-0.876 v_capacity(A_2020_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_A_2020_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_night_E_LDES_2020)_: +-1.3139999999999998 v_capacity(A_2025_E_LDES_2020) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_winter_night_E_LDES_2025)_: +-0.01752 v_uc_online(B_2025_winter_night_E_LDES_2025) ++1 v_orm_online_credit(spin_AB_B_2025_winter_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_night_E_LDES_2025)_: +-0.876 v_capacity(A_2025_E_LDES_2025) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_night_E_BATT_2020)_: +-1.095 v_capacity(A_2025_E_BATT_2020) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_A_B_2025_winter_day_E_TRANS_2015)_: +-0.1314 v_uc_online(A_B_2025_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2025_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_C_2020_summer_day_E_TRANS_2015)_: +-1.1169 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_A_2025_summer_day_E_TRANS_2015)_: +-1.2483 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_summer_night_NGCC_2025)_: +-0.438 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(reg_B_B_2025_summer_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_summer_day_E_BATT_2025)_: +-0.05475 v_uc_online(B_2025_summer_day_E_BATT_2025) ++1 v_orm_online_credit(spin_AB_B_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_day_NGCC_2015)_: +-0.1095 v_uc_online(A_2025_winter_day_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2025_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_winter_night_SOLPV_2020)_: +-0.1095 v_capacity(A_2025_SOLPV_2020) ++1 v_orm_online_credit(spin_A_A_2025_winter_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_summer_day_E_LDES_2020)_: +-0.01752 v_uc_online(B_2020_summer_day_E_LDES_2020) ++1 v_orm_online_credit(spin_AB_B_2020_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_B_2020_summer_day_E_TRANS_2015)_: +-1.1607 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_A_2025_summer_night_E_TRANS_2015)_: +-1.2483 v_capacity(C_A_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_night_E_BATT_2025)_: +-1.095 v_capacity(A_2025_E_BATT_2025) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_winter_day_SOLPV_2015)_: +-0.1095 v_capacity(A_2020_SOLPV_2015) ++1 v_orm_online_credit(spin_AB_A_2020_winter_day_SOLPV_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_winter_night_NGCC_2015)_: +-0.6569999999999999 v_capacity(B_2020_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2020_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_A_2020_winter_day_E_TRANS_2015)_: +-1.2483 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_day_NGCC_2015)_: +-0.0657 v_uc_online(A_2025_summer_day_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2025_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_winter_day_E_BATT_2025)_: +-0.05475 v_uc_online(B_2025_winter_day_E_BATT_2025) ++1 v_orm_online_credit(spin_AB_B_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_C_B_2020_winter_day_E_TRANS_2015)_: +-0.5694 v_capacity(C_B_2020_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_summer_night_NGCC_2015)_: +-0.1095 v_uc_online(A_2020_summer_night_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2020_summer_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_B_2025_winter_night_E_TRANS_2015)_: +-0.17520000000000002 v_uc_online(A_B_2025_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_C_2020_summer_day_E_TRANS_2015)_: +-1.0512 v_capacity(B_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_C_2025_winter_night_E_TRANS_2015)_: +-0.5256 v_capacity(B_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2020_winter_night_SOLPV_2020)_: +-0.1095 v_capacity(A_2020_SOLPV_2020) ++1 v_orm_online_credit(spin_AB_A_2020_winter_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_C_2020_winter_day_E_TRANS_2015)_: +-0.7446 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_winter_night_E_BATT_2025)_: +-0.05475 v_uc_online(B_2025_winter_night_E_BATT_2025) ++1 v_orm_online_credit(spin_AB_B_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_winter_night_NGCC_2020)_: +-0.6569999999999999 v_capacity(B_2025_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2025_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_C_2025_winter_night_E_TRANS_2015)_: +-1.1169 v_capacity(A_C_2025_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2025_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_day_SOLPV_2025)_: +-0.1095 v_capacity(A_2025_SOLPV_2025) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_A_2025_summer_night_E_TRANS_2015)_: +-0.11826000000000002 v_uc_online(B_A_2025_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2025_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2020_summer_night_NGCC_2020)_: +-0.6569999999999999 v_capacity(B_2020_NGCC_2020) ++1 v_orm_online_credit(spin_AB_B_2020_summer_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_C_2020_winter_day_E_TRANS_2015)_: +-1.1169 v_capacity(A_C_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2020_winter_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_winter_night_E_BATT_2020)_: +-2.19 v_capacity(A_2020_E_BATT_2020) ++1 v_orm_online_credit(spin_A_A_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_winter_night_NGCC_2015)_: +-0.1095 v_uc_online(A_2020_winter_night_NGCC_2015) ++1 v_orm_online_credit(spin_A_A_2020_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2020_summer_day_SOLPV_2020)_: +-0.1095 v_capacity(A_2020_SOLPV_2020) ++1 v_orm_online_credit(spin_A_A_2020_summer_day_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_B_A_2025_summer_day_E_TRANS_2015)_: +-0.15768000000000001 v_uc_online(B_A_2025_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_2025_summer_night_SOLPV_2025)_: +-0.1095 v_capacity(A_2025_SOLPV_2025) ++1 v_orm_online_credit(spin_A_A_2025_summer_night_SOLPV_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_summer_day_E_BATT_2025)_: +-0.043800000000000006 v_uc_online(B_2025_summer_day_E_BATT_2025) ++1 v_orm_online_credit(reg_B_B_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_A_2020_winter_night_E_TRANS_2015)_: +-1.2483 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2020_winter_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_summer_night_SOLPV_2020)_: +-0.1095 v_capacity(A_2025_SOLPV_2020) ++1 v_orm_online_credit(spin_AB_A_2025_summer_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_day_NGCC_2015)_: +-0.0657 v_uc_online(A_2025_winter_day_NGCC_2015) ++1 v_orm_online_credit(spin_AB_A_2025_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_A_A_B_2025_summer_day_E_TRANS_2015)_: +-0.17520000000000002 v_uc_online(A_B_2025_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_A_2025_winter_night_NGCC_2020)_: +-0.0657 v_uc_online(A_2025_winter_night_NGCC_2020) ++1 v_orm_online_credit(spin_AB_A_2025_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_summer_day_NGCC_2015)_: +-0.6569999999999999 v_capacity(B_2025_NGCC_2015) ++1 v_orm_online_credit(spin_AB_B_2025_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(reg_B_B_2025_winter_day_E_BATT_2020)_: +-0.043800000000000006 v_uc_online(B_2025_winter_day_E_BATT_2020) ++1 v_orm_online_credit(reg_B_B_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_C_A_2020_summer_day_E_TRANS_2015)_: +-1.2483 v_capacity(C_A_2020_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2020_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_online_headroom_credit_constraint(spin_AB_B_2025_winter_day_NGCC_2025)_: +-0.6569999999999999 v_capacity(B_2025_NGCC_2025) ++1 v_orm_online_credit(spin_AB_B_2025_winter_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_summer_night_E_LDES_2020)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2025_summer_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2025_summer_night_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_winter_night_E_LDES_2020)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2025_winter_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2025_winter_night_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2020_winter_night_E_LDES_2020)_: ++1 v_flow_out(A_2020_winter_night_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2020_winter_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2020_winter_night_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2020_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_winter_night_E_LDES_2025)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2025_ELC) +-0.95 v_flow_in(A_2025_winter_night_ELC_E_LDES_2025_ELC) +-1 v_storage_level(A_2025_winter_night_E_LDES_2025) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_winter_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2020_summer_day_E_BATT_2020)_: ++1 v_flow_out(B_2020_summer_day_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(B_2020_summer_day_ELC_E_BATT_2020_ELC) +-1 v_storage_level(B_2020_summer_day_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_summer_day_E_BATT_2020)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2025_summer_day_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2025_summer_day_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_summer_day_E_LDES_2025)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2025_ELC) +-0.95 v_flow_in(A_2025_summer_day_ELC_E_LDES_2025_ELC) +-1 v_storage_level(A_2025_summer_day_E_LDES_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_summer_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_winter_day_E_BATT_2025)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2025_ELC) +-0.85 v_flow_in(B_2025_winter_day_ELC_E_BATT_2025_ELC) +-1 v_storage_level(B_2025_winter_day_E_BATT_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_winter_day_E_LDES_2020)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2025_winter_day_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2025_winter_day_E_LDES_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_winter_night_E_BATT_2020)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2025_winter_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2025_winter_night_E_BATT_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2020_summer_night_E_BATT_2020)_: ++1 v_flow_out(B_2020_summer_night_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(B_2020_summer_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(B_2020_summer_night_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_summer_night_E_BATT_2025)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2025_ELC) +-0.85 v_flow_in(B_2025_summer_night_ELC_E_BATT_2025_ELC) +-1 v_storage_level(B_2025_summer_night_E_BATT_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2020_winter_night_E_BATT_2020)_: ++1 v_flow_out(A_2020_winter_night_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2020_winter_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2020_winter_night_E_BATT_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_summer_night_E_BATT_2020)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2025_summer_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2025_summer_night_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_summer_day_E_LDES_2020)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2020_ELC) ++0.10949999999999999 v_capacity(B_2025_E_LDES_2020) +-0.0021899999999999997 v_uc_online(B_2025_summer_day_E_LDES_2020) +-0.95 v_flow_in(B_2025_summer_day_ELC_E_LDES_2020_ELC) +-1 v_storage_level(B_2025_summer_day_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_summer_night_E_BATT_2025)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2025_ELC) +-0.85 v_flow_in(A_2025_summer_night_ELC_E_BATT_2025_ELC) +-1 v_storage_level(A_2025_summer_night_E_BATT_2025) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_winter_night_E_LDES_2025)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2025_ELC) ++0.10949999999999999 v_capacity(B_2025_E_LDES_2025) +-0.0021899999999999997 v_uc_online(B_2025_winter_night_E_LDES_2025) +-0.95 v_flow_in(B_2025_winter_night_ELC_E_LDES_2025_ELC) +-1 v_storage_level(B_2025_winter_night_E_LDES_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_winter_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_winter_day_E_BATT_2025)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2025_ELC) +-0.85 v_flow_in(A_2025_winter_day_ELC_E_BATT_2025_ELC) +-1 v_storage_level(A_2025_winter_day_E_BATT_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_winter_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_summer_day_E_BATT_2020)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2025_summer_day_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2025_summer_day_E_BATT_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_summer_day_E_LDES_2025)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2025_ELC) +-0.95 v_flow_in(A_2025_summer_day_ELC_E_LDES_2025_ELC) +-1 v_storage_level(A_2025_summer_day_E_LDES_2025) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_summer_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2020_summer_day_E_LDES_2020)_: ++1 v_flow_out(A_2020_summer_day_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2020_summer_day_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2020_summer_day_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2020_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_winter_night_E_BATT_2020)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(B_2025_winter_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(B_2025_winter_night_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_winter_night_E_BATT_2020)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2025_winter_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2025_winter_night_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_summer_night_E_LDES_2025)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2025_ELC) +-0.95 v_flow_in(A_2025_summer_night_ELC_E_LDES_2025_ELC) +-1 v_storage_level(A_2025_summer_night_E_LDES_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_summer_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2020_summer_night_E_BATT_2020)_: ++1 v_flow_out(A_2020_summer_night_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2020_summer_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2020_summer_night_E_BATT_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_summer_night_E_LDES_2020)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2025_summer_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2025_summer_night_E_LDES_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_winter_night_E_LDES_2025)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2025_ELC) +-0.95 v_flow_in(A_2025_winter_night_ELC_E_LDES_2025_ELC) +-1 v_storage_level(A_2025_winter_night_E_LDES_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_winter_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2020_winter_day_E_BATT_2020)_: ++1 v_flow_out(B_2020_winter_day_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(B_2020_winter_day_ELC_E_BATT_2020_ELC) +-1 v_storage_level(B_2020_winter_day_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_winter_day_E_LDES_2020)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2025_winter_day_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2025_winter_day_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2020_summer_night_E_LDES_2020)_: ++1 v_flow_out(A_2020_summer_night_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2020_summer_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2020_summer_night_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2020_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2020_winter_day_E_LDES_2020)_: ++1 v_flow_out(A_2020_winter_day_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2020_winter_day_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2020_winter_day_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2020_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_winter_day_E_LDES_2025)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2025_ELC) +-0.95 v_flow_in(A_2025_winter_day_ELC_E_LDES_2025_ELC) +-1 v_storage_level(A_2025_winter_day_E_LDES_2025) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_winter_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_summer_day_E_BATT_2025)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2025_ELC) +-0.85 v_flow_in(A_2025_summer_day_ELC_E_BATT_2025_ELC) +-1 v_storage_level(A_2025_summer_day_E_BATT_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_summer_night_E_LDES_2020)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2020_ELC) ++0.10949999999999999 v_capacity(B_2025_E_LDES_2020) +-0.0021899999999999997 v_uc_online(B_2025_summer_night_E_LDES_2020) +-0.95 v_flow_in(B_2025_summer_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(B_2025_summer_night_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2020_summer_day_E_LDES_2020)_: ++1 v_flow_out(A_2020_summer_day_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2020_summer_day_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2020_summer_day_E_LDES_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2020_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2020_winter_night_E_LDES_2020)_: ++1 v_flow_out(B_2020_winter_night_ELC_E_LDES_2020_ELC) ++0.10949999999999999 v_capacity(B_2020_E_LDES_2020) +-0.0021899999999999997 v_uc_online(B_2020_winter_night_E_LDES_2020) +-0.95 v_flow_in(B_2020_winter_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(B_2020_winter_night_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2020_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2020_winter_night_E_BATT_2020)_: ++1 v_flow_out(A_2020_winter_night_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2020_winter_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2020_winter_night_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_winter_night_E_BATT_2025)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2025_ELC) +-0.85 v_flow_in(A_2025_winter_night_ELC_E_BATT_2025_ELC) +-1 v_storage_level(A_2025_winter_night_E_BATT_2025) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_winter_day_E_LDES_2020)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2020_ELC) ++0.10949999999999999 v_capacity(B_2025_E_LDES_2020) +-0.0021899999999999997 v_uc_online(B_2025_winter_day_E_LDES_2020) +-0.95 v_flow_in(B_2025_winter_day_ELC_E_LDES_2020_ELC) +-1 v_storage_level(B_2025_winter_day_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_summer_day_E_BATT_2020)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(B_2025_summer_day_ELC_E_BATT_2020_ELC) +-1 v_storage_level(B_2025_summer_day_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_summer_night_E_BATT_2025)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2025_ELC) +-0.85 v_flow_in(A_2025_summer_night_ELC_E_BATT_2025_ELC) +-1 v_storage_level(A_2025_summer_night_E_BATT_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_summer_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_winter_day_E_BATT_2020)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2025_winter_day_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2025_winter_day_E_BATT_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_summer_day_E_LDES_2025)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_LDES_2025_ELC) ++0.10949999999999999 v_capacity(B_2025_E_LDES_2025) +-0.0021899999999999997 v_uc_online(B_2025_summer_day_E_LDES_2025) +-0.95 v_flow_in(B_2025_summer_day_ELC_E_LDES_2025_ELC) +-1 v_storage_level(B_2025_summer_day_E_LDES_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_summer_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2020_winter_day_E_LDES_2020)_: ++1 v_flow_out(A_2020_winter_day_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2020_winter_day_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2020_winter_day_E_LDES_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2020_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_summer_day_E_BATT_2025)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2025_ELC) +-0.85 v_flow_in(A_2025_summer_day_ELC_E_BATT_2025_ELC) +-1 v_storage_level(A_2025_summer_day_E_BATT_2025) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2020_winter_day_E_BATT_2020)_: ++1 v_flow_out(A_2020_winter_day_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2020_winter_day_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2020_winter_day_E_BATT_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_winter_night_E_LDES_2020)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2025_winter_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2025_winter_night_E_LDES_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2020_winter_night_E_LDES_2020)_: ++1 v_flow_out(A_2020_winter_night_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2020_winter_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2020_winter_night_E_LDES_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2020_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2020_summer_day_E_LDES_2020)_: ++1 v_flow_out(B_2020_summer_day_ELC_E_LDES_2020_ELC) ++0.10949999999999999 v_capacity(B_2020_E_LDES_2020) +-0.0021899999999999997 v_uc_online(B_2020_summer_day_E_LDES_2020) +-0.95 v_flow_in(B_2020_summer_day_ELC_E_LDES_2020_ELC) +-1 v_storage_level(B_2020_summer_day_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2020_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_winter_night_E_BATT_2025)_: ++1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2025_ELC) +-0.85 v_flow_in(A_2025_winter_night_ELC_E_BATT_2025_ELC) +-1 v_storage_level(A_2025_winter_night_E_BATT_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2020_summer_day_E_BATT_2020)_: ++1 v_flow_out(A_2020_summer_day_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2020_summer_day_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2020_summer_day_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_summer_night_E_LDES_2025)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2025_ELC) +-0.95 v_flow_in(A_2025_summer_night_ELC_E_LDES_2025_ELC) +-1 v_storage_level(A_2025_summer_night_E_LDES_2025) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_summer_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_summer_day_E_LDES_2020)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2025_summer_day_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2025_summer_day_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_winter_day_E_BATT_2020)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(B_2025_winter_day_ELC_E_BATT_2020_ELC) +-1 v_storage_level(B_2025_winter_day_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_winter_night_E_BATT_2025)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2025_ELC) +-0.85 v_flow_in(B_2025_winter_night_ELC_E_BATT_2025_ELC) +-1 v_storage_level(B_2025_winter_night_E_BATT_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_winter_night_E_BATT_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_winter_day_E_LDES_2025)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2025_ELC) +-0.95 v_flow_in(A_2025_winter_day_ELC_E_LDES_2025_ELC) +-1 v_storage_level(A_2025_winter_day_E_LDES_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_winter_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2020_summer_day_E_BATT_2020)_: ++1 v_flow_out(A_2020_summer_day_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2020_summer_day_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2020_summer_day_E_BATT_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2020_summer_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_summer_night_E_BATT_2020)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(B_2025_summer_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(B_2025_summer_night_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2020_summer_night_E_LDES_2020)_: ++1 v_flow_out(B_2020_summer_night_ELC_E_LDES_2020_ELC) ++0.10949999999999999 v_capacity(B_2020_E_LDES_2020) +-0.0021899999999999997 v_uc_online(B_2020_summer_night_E_LDES_2020) +-0.95 v_flow_in(B_2020_summer_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(B_2020_summer_night_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2020_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_summer_night_E_LDES_2025)_: ++1 v_flow_out(B_2025_summer_night_ELC_E_LDES_2025_ELC) ++0.10949999999999999 v_capacity(B_2025_E_LDES_2025) +-0.0021899999999999997 v_uc_online(B_2025_summer_night_E_LDES_2025) +-0.95 v_flow_in(B_2025_summer_night_ELC_E_LDES_2025_ELC) +-1 v_storage_level(B_2025_summer_night_E_LDES_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_summer_night_E_LDES_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2020_summer_night_E_BATT_2020)_: ++1 v_flow_out(A_2020_summer_night_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2020_summer_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2020_summer_night_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2020_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2020_winter_night_E_BATT_2020)_: ++1 v_flow_out(B_2020_winter_night_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(B_2020_winter_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(B_2020_winter_night_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_summer_night_E_BATT_2020)_: ++1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2025_summer_night_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2025_summer_night_E_BATT_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_summer_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_winter_night_E_LDES_2020)_: ++1 v_flow_out(B_2025_winter_night_ELC_E_LDES_2020_ELC) ++0.10949999999999999 v_capacity(B_2025_E_LDES_2020) +-0.0021899999999999997 v_uc_online(B_2025_winter_night_E_LDES_2020) +-0.95 v_flow_in(B_2025_winter_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(B_2025_winter_night_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_winter_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_summer_day_E_BATT_2025)_: ++1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2025_ELC) +-0.85 v_flow_in(B_2025_summer_day_ELC_E_BATT_2025_ELC) +-1 v_storage_level(B_2025_summer_day_E_BATT_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2020_summer_night_E_LDES_2020)_: ++1 v_flow_out(A_2020_summer_night_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2020_summer_night_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2020_summer_night_E_LDES_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2020_summer_night_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2025_winter_day_E_BATT_2020)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2025_winter_day_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2025_winter_day_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2020_winter_day_E_LDES_2020)_: ++1 v_flow_out(B_2020_winter_day_ELC_E_LDES_2020_ELC) ++0.10949999999999999 v_capacity(B_2020_E_LDES_2020) +-0.0021899999999999997 v_uc_online(B_2020_winter_day_E_LDES_2020) +-0.95 v_flow_in(B_2020_winter_day_ELC_E_LDES_2020_ELC) +-1 v_storage_level(B_2020_winter_day_E_LDES_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2020_winter_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_B_2025_winter_day_E_LDES_2025)_: ++1 v_flow_out(B_2025_winter_day_ELC_E_LDES_2025_ELC) ++0.10949999999999999 v_capacity(B_2025_E_LDES_2025) +-0.0021899999999999997 v_uc_online(B_2025_winter_day_E_LDES_2025) +-0.95 v_flow_in(B_2025_winter_day_ELC_E_LDES_2025_ELC) +-1 v_storage_level(B_2025_winter_day_E_LDES_2025) ++0.16666666666666666 v_orm_online_credit(spin_AB_B_2025_winter_day_E_LDES_2025) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_AB_A_B_elec_AB_A_2020_winter_day_E_BATT_2020)_: ++1 v_flow_out(A_2020_winter_day_ELC_E_BATT_2020_ELC) +-0.85 v_flow_in(A_2020_winter_day_ELC_E_BATT_2020_ELC) +-1 v_storage_level(A_2020_winter_day_E_BATT_2020) ++0.16666666666666666 v_orm_online_credit(spin_AB_A_2020_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_summer_day_E_LDES_2020)_: ++1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2020_ELC) +-0.95 v_flow_in(A_2025_summer_day_ELC_E_LDES_2020_ELC) +-1 v_storage_level(A_2025_summer_day_E_LDES_2020) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_summer_day_E_LDES_2020) +<= 0 + +c_u_operating_reserve_storage_energy_constraint(spin_A_A_elec_A_A_2025_winter_day_E_BATT_2025)_: ++1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2025_ELC) +-0.85 v_flow_in(A_2025_winter_day_ELC_E_BATT_2025_ELC) +-1 v_storage_level(A_2025_winter_day_E_BATT_2025) ++0.08333333333333333 v_orm_online_credit(spin_A_A_2025_winter_day_E_BATT_2025) +<= 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_A_B_2025_summer_night_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_A_B_2025_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2025_summer_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_C_2025_winter_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_A_C_2025_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2025_winter_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_B_C_2025_winter_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_C_B_2025_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2025_winter_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_B_C_2020_winter_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_C_B_2020_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2020_winter_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_B_C_2025_summer_day_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_C_B_2025_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2025_summer_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_B_2020_winter_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_B_A_2020_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2020_winter_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_B_C_2020_winter_day_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_B_C_2020_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2020_winter_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_C_2020_summer_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_A_C_2020_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_C_A_2020_summer_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_B_2025_winter_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_B_A_2025_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2025_winter_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_A_B_2020_winter_day_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_A_B_2020_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2020_winter_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_B_C_2025_summer_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_C_B_2025_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2025_summer_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_A_C_2020_winter_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_A_C_2020_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2020_winter_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_B_C_2020_winter_night_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_B_C_2020_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2020_winter_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_B_C_2025_winter_day_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_B_C_2025_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2025_winter_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_A_C_2025_winter_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_A_C_2025_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2025_winter_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_A_C_2025_summer_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_A_C_2025_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2025_summer_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_B_C_2025_winter_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_B_C_2025_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_B_2025_winter_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_B_2025_summer_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_B_A_2025_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2025_summer_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_A_C_2020_summer_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_C_A_2020_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2020_summer_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_B_2020_summer_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_A_B_2020_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_B_A_2020_summer_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_A_B_2025_summer_day_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_A_B_2025_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2025_summer_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_B_2025_summer_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_B_A_2025_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2025_summer_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_B_C_2020_winter_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_C_B_2020_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2020_winter_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_C_2025_summer_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_C_A_2025_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2025_summer_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_B_C_2020_summer_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_C_B_2020_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2020_summer_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_C_2025_winter_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_C_A_2025_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2025_winter_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_B_C_2025_winter_night_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_C_B_2025_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2025_winter_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_A_C_2025_winter_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_C_A_2025_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2025_winter_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_B_2020_winter_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_B_A_2020_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2020_winter_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_B_C_2020_summer_night_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_B_C_2020_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_C_B_2020_summer_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_B_C_2020_summer_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_C_B_2020_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2020_summer_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_A_B_2020_winter_night_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_A_B_2020_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2020_winter_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_A_B_2025_winter_day_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_B_A_2025_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2025_winter_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_B_2025_winter_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_B_A_2025_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2025_winter_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_C_2020_summer_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_C_A_2020_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2020_summer_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_A_C_2020_winter_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_C_A_2020_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_A_C_2020_winter_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_B_C_2025_summer_night_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_C_B_2025_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2025_summer_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_C_2020_winter_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_C_A_2020_winter_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2020_winter_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_A_B_2020_summer_day_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_A_B_2020_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_A_2020_summer_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_A_B_2025_winter_night_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_B_A_2025_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2025_winter_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_A_C_2025_summer_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_A_C_2025_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2025_summer_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_C_2025_summer_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_C_A_2025_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2025_summer_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_C_2020_winter_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_C_A_2020_winter_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_C_2020_winter_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_A_B_2020_summer_night_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_B_A_2020_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_A_B_2020_summer_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_B_C_2025_summer_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_C_B_2025_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_B_C_2025_summer_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_AB_A_C_2020_summer_day_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_AB_A_C_2020_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(spin_AB_C_A_2020_summer_day_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(spin_A_A_B_2020_summer_night_E_TRANS_2015)_: ++1 v_orm_online_credit(spin_A_B_A_2020_summer_night_E_TRANS_2015) ++1 v_orm_online_credit(spin_A_A_B_2020_summer_night_E_TRANS_2015) += 0 + +c_e_operating_reserve_online_exchange_symmetry_constraint(reg_B_B_C_2020_summer_day_E_TRANS_2015)_: ++1 v_orm_online_credit(reg_B_C_B_2020_summer_day_E_TRANS_2015) ++1 v_orm_online_credit(reg_B_B_C_2020_summer_day_E_TRANS_2015) += 0 + +c_u_operating_reserve_margin_constraint(reg_B_B_elec_B_2025_summer_night)_: ++0.1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2020_ELC) ++0.1 v_flow_out(A_B_2025_summer_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(B_2025_summer_night_NG_NGCC_2015_ELC) ++0.1 v_flow_out(B_2025_summer_night_ELC_E_BATT_2025_ELC) ++0.1 v_flow_out(C_B_2025_summer_night_ELC_E_TRANS_2015_ELC) +-0.10526315789473684 v_flow_out(B_A_2025_summer_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(B_2025_summer_night_NG_NGCC_2020_ELC) ++0.1 v_flow_out(B_2025_summer_night_NG_NGCC_2025_ELC) +-0.10526315789473684 v_flow_out(B_C_2025_summer_night_ELC_E_TRANS_2015_ELC) +-0.1 v_flow_in(B_2025_summer_night_ELC_E_BATT_2020_ELC) +-0.1 v_flow_in(B_2025_summer_night_ELC_E_BATT_2025_ELC) +-1 v_orm_online_credit(reg_B_B_2025_summer_night_E_BATT_2025) +-1 v_orm_online_credit(reg_B_B_2025_summer_night_NGCC_2020) +-1 v_orm_online_credit(reg_B_C_B_2025_summer_night_E_TRANS_2015) +-1 v_orm_online_credit(reg_B_B_2025_summer_night_E_BATT_2020) +-1 v_orm_online_credit(reg_B_B_2025_summer_night_NGCC_2015) +-1 v_orm_online_credit(reg_B_A_B_2025_summer_night_E_TRANS_2015) +-1 v_orm_online_credit(reg_B_B_2025_summer_night_NGCC_2025) +<= 0 + +c_u_operating_reserve_margin_constraint(reg_B_B_elec_B_2025_winter_night)_: ++0.1 v_flow_out(A_B_2025_winter_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(C_B_2025_winter_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(B_2025_winter_night_NG_NGCC_2025_ELC) ++0.1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2020_ELC) ++0.1 v_flow_out(B_2025_winter_night_ELC_E_BATT_2025_ELC) ++0.1 v_flow_out(B_2025_winter_night_NG_NGCC_2015_ELC) +-0.10526315789473684 v_flow_out(B_A_2025_winter_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(B_2025_winter_night_NG_NGCC_2020_ELC) +-0.10526315789473684 v_flow_out(B_C_2025_winter_night_ELC_E_TRANS_2015_ELC) +-0.1 v_flow_in(B_2025_winter_night_ELC_E_BATT_2025_ELC) +-0.1 v_flow_in(B_2025_winter_night_ELC_E_BATT_2020_ELC) +-1 v_orm_online_credit(reg_B_B_2025_winter_night_E_BATT_2025) +-1 v_orm_online_credit(reg_B_B_2025_winter_night_NGCC_2025) +-1 v_orm_online_credit(reg_B_B_2025_winter_night_E_BATT_2020) +-1 v_orm_online_credit(reg_B_B_2025_winter_night_NGCC_2020) +-1 v_orm_online_credit(reg_B_A_B_2025_winter_night_E_TRANS_2015) +-1 v_orm_online_credit(reg_B_C_B_2025_winter_night_E_TRANS_2015) +-1 v_orm_online_credit(reg_B_B_2025_winter_night_NGCC_2015) +<= 0 + +c_u_operating_reserve_margin_constraint(spin_AB_A_B_elec_AB_2025_winter_day)_: +-0.020000000000000004 v_flow_out(B_2025_winter_day_NG_NGCC_2015_ELC) ++0.08 v_flow_out(A_2025_winter_day_ELC_E_LDES_2025_ELC) +-0.020000000000000004 v_flow_out(A_2025_winter_day_NG_NGCC_2020_ELC) ++0.08 v_flow_out(B_2025_winter_day_ELC_E_BATT_2025_ELC) ++0.08 v_flow_out(A_2025_winter_day_ELC_E_BATT_2025_ELC) ++0.08 v_flow_out(A_2025_winter_day_ELC_HEAT_SYS_2020_HEAT) +-0.020000000000000004 v_flow_out(A_2025_winter_day_NG_NGCC_2025_ELC) ++0.08 v_flow_out(B_2025_winter_day_ELC_HEAT_SYS_2025_HEAT) +-0.08421052631578947 v_flow_out(A_C_2025_winter_day_ELC_E_TRANS_2015_ELC) ++0.18 v_flow_out(A_2025_winter_day_ethos_SOLPV_2025_ELC) ++0.08 v_flow_out(B_2025_winter_day_ELC_E_LDES_2025_ELC) +-0.020000000000000004 v_flow_out(B_2025_winter_day_NG_NGCC_2020_ELC) ++0.08 v_flow_out(C_A_2025_winter_day_ELC_E_TRANS_2015_ELC) ++0.08 v_flow_out(A_2025_winter_day_ELC_HEAT_SYS_2025_HEAT) ++0.08 v_flow_out(A_2025_winter_day_ELC_E_LDES_2020_ELC) +-0.020000000000000004 v_flow_out(A_2025_winter_day_NG_NGCC_2015_ELC) ++0.08 v_flow_out(C_B_2025_winter_day_ELC_E_TRANS_2015_ELC) ++0.18 v_flow_out(A_2025_winter_day_ethos_SOLPV_2015_ELC) ++0.08 v_flow_out(B_2025_winter_day_ELC_HEAT_SYS_2020_HEAT) +-0.08421052631578947 v_flow_out(B_C_2025_winter_day_ELC_E_TRANS_2015_ELC) +-0.020000000000000004 v_flow_out(B_2025_winter_day_NG_NGCC_2025_ELC) ++0.08 v_flow_out(B_2025_winter_day_ELC_E_BATT_2020_ELC) ++0.18 v_flow_out(A_2025_winter_day_ethos_SOLPV_2020_ELC) ++0.08 v_flow_out(A_2025_winter_day_ELC_E_BATT_2020_ELC) ++0.08 v_flow_out(B_2025_winter_day_ELC_E_LDES_2020_ELC) +-1.095 v_capacity(A_2025_NGCC_2025) +-0.6569999999999999 v_capacity(B_2025_E_LDES_2020) +-1.095 v_capacity(A_2025_NGCC_2015) +-0.6569999999999999 v_capacity(B_2025_E_LDES_2025) +-1.095 v_capacity(A_2025_NGCC_2020) ++0.1095 v_uc_online(A_2025_winter_day_NGCC_2015) ++0.013139999999999999 v_uc_online(B_2025_winter_day_E_LDES_2020) ++0.1095 v_uc_online(A_2025_winter_day_NGCC_2020) ++0.013139999999999999 v_uc_online(B_2025_winter_day_E_LDES_2025) ++0.1095 v_uc_online(A_2025_winter_day_NGCC_2025) +-0.08 v_flow_in(A_2025_winter_day_ELC_E_LDES_2025_ELC) +-0.08 v_flow_in(B_2025_winter_day_ELC_E_BATT_2025_ELC) +-0.08 v_flow_in(A_2025_winter_day_ELC_E_BATT_2025_ELC) +-0.08 v_flow_in(A_2025_winter_day_ELC_E_LDES_2020_ELC) +-0.08 v_flow_in(B_2025_winter_day_ELC_E_LDES_2025_ELC) +-0.08 v_flow_in(B_2025_winter_day_ELC_E_BATT_2020_ELC) +-0.08 v_flow_in(A_2025_winter_day_ELC_E_BATT_2020_ELC) +-0.08 v_flow_in(B_2025_winter_day_ELC_E_LDES_2020_ELC) +-1 v_orm_online_credit(spin_AB_B_2025_winter_day_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_B_2025_winter_day_E_LDES_2025) +-1 v_orm_online_credit(spin_AB_A_2025_winter_day_SOLPV_2020) +-1 v_orm_online_credit(spin_AB_B_2025_winter_day_NGCC_2020) +-1 v_orm_online_credit(spin_AB_B_2025_winter_day_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_A_2025_winter_day_SOLPV_2015) +-1 v_orm_online_credit(spin_AB_A_2025_winter_day_E_BATT_2025) +-1 v_orm_online_credit(spin_AB_B_2025_winter_day_NGCC_2015) +-1 v_orm_online_credit(spin_AB_A_2025_winter_day_NGCC_2025) +-1 v_orm_online_credit(spin_AB_A_2025_winter_day_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_A_2025_winter_day_E_LDES_2025) +-1 v_orm_online_credit(spin_AB_C_A_2025_winter_day_E_TRANS_2015) +-1 v_orm_online_credit(spin_AB_A_2025_winter_day_NGCC_2020) +-1 v_orm_online_credit(spin_AB_A_2025_winter_day_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_C_B_2025_winter_day_E_TRANS_2015) +-1 v_orm_online_credit(spin_AB_B_2025_winter_day_E_BATT_2025) +-1 v_orm_online_credit(spin_AB_A_2025_winter_day_SOLPV_2025) +-1 v_orm_online_credit(spin_AB_A_2025_winter_day_NGCC_2015) +-1 v_orm_online_credit(spin_AB_B_2025_winter_day_NGCC_2025) +<= 0 + +c_u_operating_reserve_margin_constraint(spin_AB_A_B_elec_AB_2020_summer_night)_: ++0.18 v_flow_out(A_2020_summer_night_ethos_SOLPV_2020_ELC) +-0.020000000000000004 v_flow_out(B_2020_summer_night_NG_NGCC_2020_ELC) +-0.020000000000000004 v_flow_out(A_2020_summer_night_NG_NGCC_2015_ELC) ++0.08 v_flow_out(A_2020_summer_night_ELC_E_BATT_2020_ELC) ++0.08 v_flow_out(B_2020_summer_night_ELC_E_LDES_2020_ELC) +-0.020000000000000004 v_flow_out(A_2020_summer_night_NG_NGCC_2020_ELC) +-0.08421052631578947 v_flow_out(A_C_2020_summer_night_ELC_E_TRANS_2015_ELC) +-0.08421052631578947 v_flow_out(B_C_2020_summer_night_ELC_E_TRANS_2015_ELC) ++0.08 v_flow_out(A_2020_summer_night_ELC_E_LDES_2020_ELC) ++0.08 v_flow_out(C_B_2020_summer_night_ELC_E_TRANS_2015_ELC) ++0.08 v_flow_out(B_2020_summer_night_ELC_E_BATT_2020_ELC) ++0.18 v_flow_out(A_2020_summer_night_ethos_SOLPV_2015_ELC) ++0.08 v_flow_out(C_A_2020_summer_night_ELC_E_TRANS_2015_ELC) +-0.020000000000000004 v_flow_out(B_2020_summer_night_NG_NGCC_2015_ELC) +-0.6569999999999999 v_capacity(B_2020_E_LDES_2020) +-1.095 v_capacity(A_2020_NGCC_2015) +-1.095 v_capacity(A_2020_NGCC_2020) ++0.1095 v_uc_online(A_2020_summer_night_NGCC_2020) ++0.013139999999999999 v_uc_online(B_2020_summer_night_E_LDES_2020) ++0.1095 v_uc_online(A_2020_summer_night_NGCC_2015) +-0.08 v_flow_in(B_2020_summer_night_ELC_E_BATT_2020_ELC) +-0.08 v_flow_in(A_2020_summer_night_ELC_E_BATT_2020_ELC) +-0.08 v_flow_in(B_2020_summer_night_ELC_E_LDES_2020_ELC) +-0.08 v_flow_in(A_2020_summer_night_ELC_E_LDES_2020_ELC) +-1 v_orm_online_credit(spin_AB_C_A_2020_summer_night_E_TRANS_2015) +-1 v_orm_online_credit(spin_AB_B_2020_summer_night_NGCC_2015) +-1 v_orm_online_credit(spin_AB_A_2020_summer_night_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_C_B_2020_summer_night_E_TRANS_2015) +-1 v_orm_online_credit(spin_AB_A_2020_summer_night_SOLPV_2020) +-1 v_orm_online_credit(spin_AB_A_2020_summer_night_NGCC_2020) +-1 v_orm_online_credit(spin_AB_A_2020_summer_night_SOLPV_2015) +-1 v_orm_online_credit(spin_AB_B_2020_summer_night_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_B_2020_summer_night_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_A_2020_summer_night_NGCC_2015) +-1 v_orm_online_credit(spin_AB_A_2020_summer_night_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_B_2020_summer_night_NGCC_2020) +<= -0.16 + +c_u_operating_reserve_margin_constraint(spin_A_A_elec_A_2020_summer_day)_: ++0.1 v_flow_out(A_2020_summer_day_NG_NGCC_2015_ELC) ++0.2 v_flow_out(A_2020_summer_day_ethos_SOLPV_2020_ELC) ++0.1 v_flow_out(A_2020_summer_day_NG_NGCC_2020_ELC) ++0.2 v_flow_out(A_2020_summer_day_ethos_SOLPV_2015_ELC) +-0.10526315789473684 v_flow_out(A_C_2020_summer_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2020_summer_day_ELC_E_BATT_2020_ELC) ++0.1 v_flow_out(A_2020_summer_day_ELC_E_LDES_2020_ELC) ++0.1 v_flow_out(B_A_2020_summer_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(C_A_2020_summer_day_ELC_E_TRANS_2015_ELC) +-0.10526315789473684 v_flow_out(A_B_2020_summer_day_ELC_E_TRANS_2015_ELC) +-0.1 v_flow_in(A_2020_summer_day_ELC_E_LDES_2020_ELC) +-0.1 v_flow_in(A_2020_summer_day_ELC_E_BATT_2020_ELC) +-1 v_orm_online_credit(spin_A_A_2020_summer_day_NGCC_2020) +-1 v_orm_online_credit(spin_A_A_2020_summer_day_SOLPV_2015) +-1 v_orm_online_credit(spin_A_C_A_2020_summer_day_E_TRANS_2015) +-1 v_orm_online_credit(spin_A_A_2020_summer_day_NGCC_2015) +-1 v_orm_online_credit(spin_A_A_2020_summer_day_E_BATT_2020) +-1 v_orm_online_credit(spin_A_A_2020_summer_day_E_LDES_2020) +-1 v_orm_online_credit(spin_A_B_A_2020_summer_day_E_TRANS_2015) +-1 v_orm_online_credit(spin_A_A_2020_summer_day_SOLPV_2020) +<= -0.125 + +c_u_operating_reserve_margin_constraint(spin_AB_A_B_elec_AB_2020_winter_night)_: ++0.08 v_flow_out(C_A_2020_winter_night_ELC_E_TRANS_2015_ELC) ++0.18 v_flow_out(A_2020_winter_night_ethos_SOLPV_2020_ELC) ++0.08 v_flow_out(A_2020_winter_night_ELC_E_BATT_2020_ELC) +-0.020000000000000004 v_flow_out(B_2020_winter_night_NG_NGCC_2015_ELC) ++0.08 v_flow_out(B_2020_winter_night_ELC_E_BATT_2020_ELC) +-0.020000000000000004 v_flow_out(A_2020_winter_night_NG_NGCC_2020_ELC) +-0.08421052631578947 v_flow_out(A_C_2020_winter_night_ELC_E_TRANS_2015_ELC) +-0.08421052631578947 v_flow_out(B_C_2020_winter_night_ELC_E_TRANS_2015_ELC) ++0.08 v_flow_out(A_2020_winter_night_ELC_E_LDES_2020_ELC) +-0.020000000000000004 v_flow_out(A_2020_winter_night_NG_NGCC_2015_ELC) ++0.08 v_flow_out(B_2020_winter_night_ELC_E_LDES_2020_ELC) ++0.08 v_flow_out(C_B_2020_winter_night_ELC_E_TRANS_2015_ELC) ++0.18 v_flow_out(A_2020_winter_night_ethos_SOLPV_2015_ELC) +-0.020000000000000004 v_flow_out(B_2020_winter_night_NG_NGCC_2020_ELC) +-0.6569999999999999 v_capacity(B_2020_E_LDES_2020) +-1.095 v_capacity(A_2020_NGCC_2015) +-1.095 v_capacity(A_2020_NGCC_2020) ++0.1095 v_uc_online(A_2020_winter_night_NGCC_2020) ++0.013139999999999999 v_uc_online(B_2020_winter_night_E_LDES_2020) ++0.1095 v_uc_online(A_2020_winter_night_NGCC_2015) +-0.08 v_flow_in(A_2020_winter_night_ELC_E_BATT_2020_ELC) +-0.08 v_flow_in(A_2020_winter_night_ELC_E_LDES_2020_ELC) +-0.08 v_flow_in(B_2020_winter_night_ELC_E_BATT_2020_ELC) +-0.08 v_flow_in(B_2020_winter_night_ELC_E_LDES_2020_ELC) +-1 v_orm_online_credit(spin_AB_C_B_2020_winter_night_E_TRANS_2015) +-1 v_orm_online_credit(spin_AB_A_2020_winter_night_NGCC_2020) +-1 v_orm_online_credit(spin_AB_A_2020_winter_night_SOLPV_2015) +-1 v_orm_online_credit(spin_AB_B_2020_winter_night_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_A_2020_winter_night_NGCC_2015) +-1 v_orm_online_credit(spin_AB_A_2020_winter_night_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_B_2020_winter_night_NGCC_2020) +-1 v_orm_online_credit(spin_AB_A_2020_winter_night_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_B_2020_winter_night_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_B_2020_winter_night_NGCC_2015) +-1 v_orm_online_credit(spin_AB_A_2020_winter_night_SOLPV_2020) +-1 v_orm_online_credit(spin_AB_C_A_2020_winter_night_E_TRANS_2015) +<= -0.16 + +c_u_operating_reserve_margin_constraint(spin_A_A_elec_A_2020_winter_day)_: ++0.1 v_flow_out(C_A_2020_winter_day_ELC_E_TRANS_2015_ELC) +-0.10526315789473684 v_flow_out(A_C_2020_winter_day_ELC_E_TRANS_2015_ELC) ++0.2 v_flow_out(A_2020_winter_day_ethos_SOLPV_2020_ELC) +-0.10526315789473684 v_flow_out(A_B_2020_winter_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2020_winter_day_NG_NGCC_2020_ELC) ++0.1 v_flow_out(A_2020_winter_day_ELC_E_BATT_2020_ELC) ++0.2 v_flow_out(A_2020_winter_day_ethos_SOLPV_2015_ELC) ++0.1 v_flow_out(A_2020_winter_day_ELC_E_LDES_2020_ELC) ++0.1 v_flow_out(B_A_2020_winter_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2020_winter_day_NG_NGCC_2015_ELC) +-0.1 v_flow_in(A_2020_winter_day_ELC_E_LDES_2020_ELC) +-0.1 v_flow_in(A_2020_winter_day_ELC_E_BATT_2020_ELC) +-1 v_orm_online_credit(spin_A_A_2020_winter_day_SOLPV_2020) +-1 v_orm_online_credit(spin_A_A_2020_winter_day_E_BATT_2020) +-1 v_orm_online_credit(spin_A_B_A_2020_winter_day_E_TRANS_2015) +-1 v_orm_online_credit(spin_A_A_2020_winter_day_SOLPV_2015) +-1 v_orm_online_credit(spin_A_C_A_2020_winter_day_E_TRANS_2015) +-1 v_orm_online_credit(spin_A_A_2020_winter_day_NGCC_2020) +-1 v_orm_online_credit(spin_A_A_2020_winter_day_E_LDES_2020) +-1 v_orm_online_credit(spin_A_A_2020_winter_day_NGCC_2015) +<= -0.125 + +c_u_operating_reserve_margin_constraint(spin_A_A_elec_A_2025_summer_night)_: ++0.2 v_flow_out(A_2025_summer_night_ethos_SOLPV_2020_ELC) +-0.10526315789473684 v_flow_out(A_B_2025_summer_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2025_summer_night_NG_NGCC_2025_ELC) ++0.2 v_flow_out(A_2025_summer_night_ethos_SOLPV_2025_ELC) ++0.1 v_flow_out(A_2025_summer_night_NG_NGCC_2015_ELC) ++0.1 v_flow_out(A_2025_summer_night_ELC_HEAT_SYS_2020_HEAT) ++0.1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2020_ELC) ++0.1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2020_ELC) ++0.1 v_flow_out(A_2025_summer_night_ELC_E_BATT_2025_ELC) ++0.2 v_flow_out(A_2025_summer_night_ethos_SOLPV_2015_ELC) ++0.1 v_flow_out(A_2025_summer_night_NG_NGCC_2020_ELC) ++0.1 v_flow_out(B_A_2025_summer_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2025_summer_night_ELC_HEAT_SYS_2025_HEAT) ++0.1 v_flow_out(C_A_2025_summer_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2025_summer_night_ELC_E_LDES_2025_ELC) +-0.10526315789473684 v_flow_out(A_C_2025_summer_night_ELC_E_TRANS_2015_ELC) +-0.1 v_flow_in(A_2025_summer_night_ELC_E_BATT_2025_ELC) +-0.1 v_flow_in(A_2025_summer_night_ELC_E_LDES_2025_ELC) +-0.1 v_flow_in(A_2025_summer_night_ELC_E_BATT_2020_ELC) +-0.1 v_flow_in(A_2025_summer_night_ELC_E_LDES_2020_ELC) +-1 v_orm_online_credit(spin_A_A_2025_summer_night_E_BATT_2025) +-1 v_orm_online_credit(spin_A_A_2025_summer_night_NGCC_2025) +-1 v_orm_online_credit(spin_A_A_2025_summer_night_SOLPV_2020) +-1 v_orm_online_credit(spin_A_A_2025_summer_night_E_BATT_2020) +-1 v_orm_online_credit(spin_A_B_A_2025_summer_night_E_TRANS_2015) +-1 v_orm_online_credit(spin_A_A_2025_summer_night_NGCC_2020) +-1 v_orm_online_credit(spin_A_C_A_2025_summer_night_E_TRANS_2015) +-1 v_orm_online_credit(spin_A_A_2025_summer_night_NGCC_2015) +-1 v_orm_online_credit(spin_A_A_2025_summer_night_SOLPV_2015) +-1 v_orm_online_credit(spin_A_A_2025_summer_night_E_LDES_2025) +-1 v_orm_online_credit(spin_A_A_2025_summer_night_E_LDES_2020) +-1 v_orm_online_credit(spin_A_A_2025_summer_night_SOLPV_2025) +<= 0 + +c_u_operating_reserve_margin_constraint(reg_B_B_elec_B_2025_summer_day)_: ++0.1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2020_ELC) ++0.1 v_flow_out(B_2025_summer_day_NG_NGCC_2025_ELC) ++0.1 v_flow_out(A_B_2025_summer_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(B_2025_summer_day_ELC_E_BATT_2025_ELC) ++0.1 v_flow_out(B_2025_summer_day_NG_NGCC_2015_ELC) +-0.10526315789473684 v_flow_out(B_A_2025_summer_day_ELC_E_TRANS_2015_ELC) +-0.10526315789473684 v_flow_out(B_C_2025_summer_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(C_B_2025_summer_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(B_2025_summer_day_NG_NGCC_2020_ELC) +-0.1 v_flow_in(B_2025_summer_day_ELC_E_BATT_2025_ELC) +-0.1 v_flow_in(B_2025_summer_day_ELC_E_BATT_2020_ELC) +-1 v_orm_online_credit(reg_B_A_B_2025_summer_day_E_TRANS_2015) +-1 v_orm_online_credit(reg_B_B_2025_summer_day_NGCC_2025) +-1 v_orm_online_credit(reg_B_B_2025_summer_day_E_BATT_2020) +-1 v_orm_online_credit(reg_B_B_2025_summer_day_NGCC_2020) +-1 v_orm_online_credit(reg_B_B_2025_summer_day_NGCC_2015) +-1 v_orm_online_credit(reg_B_C_B_2025_summer_day_E_TRANS_2015) +-1 v_orm_online_credit(reg_B_B_2025_summer_day_E_BATT_2025) +<= 0 + +c_u_operating_reserve_margin_constraint(reg_B_B_elec_B_2025_winter_day)_: ++0.1 v_flow_out(B_2025_winter_day_NG_NGCC_2015_ELC) +-0.10526315789473684 v_flow_out(B_A_2025_winter_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2025_ELC) ++0.1 v_flow_out(B_2025_winter_day_NG_NGCC_2020_ELC) ++0.1 v_flow_out(A_B_2025_winter_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(C_B_2025_winter_day_ELC_E_TRANS_2015_ELC) +-0.10526315789473684 v_flow_out(B_C_2025_winter_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(B_2025_winter_day_NG_NGCC_2025_ELC) ++0.1 v_flow_out(B_2025_winter_day_ELC_E_BATT_2020_ELC) +-0.1 v_flow_in(B_2025_winter_day_ELC_E_BATT_2025_ELC) +-0.1 v_flow_in(B_2025_winter_day_ELC_E_BATT_2020_ELC) +-1 v_orm_online_credit(reg_B_B_2025_winter_day_NGCC_2020) +-1 v_orm_online_credit(reg_B_B_2025_winter_day_NGCC_2015) +-1 v_orm_online_credit(reg_B_C_B_2025_winter_day_E_TRANS_2015) +-1 v_orm_online_credit(reg_B_B_2025_winter_day_NGCC_2025) +-1 v_orm_online_credit(reg_B_B_2025_winter_day_E_BATT_2025) +-1 v_orm_online_credit(reg_B_A_B_2025_winter_day_E_TRANS_2015) +-1 v_orm_online_credit(reg_B_B_2025_winter_day_E_BATT_2020) +<= 0 + +c_u_operating_reserve_margin_constraint(spin_AB_A_B_elec_AB_2020_summer_day)_: +-0.020000000000000004 v_flow_out(A_2020_summer_day_NG_NGCC_2015_ELC) ++0.18 v_flow_out(A_2020_summer_day_ethos_SOLPV_2020_ELC) +-0.020000000000000004 v_flow_out(B_2020_summer_day_NG_NGCC_2020_ELC) ++0.08 v_flow_out(C_B_2020_summer_day_ELC_E_TRANS_2015_ELC) +-0.020000000000000004 v_flow_out(A_2020_summer_day_NG_NGCC_2020_ELC) ++0.08 v_flow_out(B_2020_summer_day_ELC_E_LDES_2020_ELC) +-0.08421052631578947 v_flow_out(B_C_2020_summer_day_ELC_E_TRANS_2015_ELC) ++0.08 v_flow_out(B_2020_summer_day_ELC_E_BATT_2020_ELC) ++0.18 v_flow_out(A_2020_summer_day_ethos_SOLPV_2015_ELC) +-0.08421052631578947 v_flow_out(A_C_2020_summer_day_ELC_E_TRANS_2015_ELC) ++0.08 v_flow_out(A_2020_summer_day_ELC_E_BATT_2020_ELC) ++0.08 v_flow_out(A_2020_summer_day_ELC_E_LDES_2020_ELC) +-0.020000000000000004 v_flow_out(B_2020_summer_day_NG_NGCC_2015_ELC) ++0.08 v_flow_out(C_A_2020_summer_day_ELC_E_TRANS_2015_ELC) +-0.6569999999999999 v_capacity(B_2020_E_LDES_2020) +-1.095 v_capacity(A_2020_NGCC_2015) +-1.095 v_capacity(A_2020_NGCC_2020) ++0.1095 v_uc_online(A_2020_summer_day_NGCC_2015) ++0.013139999999999999 v_uc_online(B_2020_summer_day_E_LDES_2020) ++0.1095 v_uc_online(A_2020_summer_day_NGCC_2020) +-0.08 v_flow_in(A_2020_summer_day_ELC_E_LDES_2020_ELC) +-0.08 v_flow_in(B_2020_summer_day_ELC_E_LDES_2020_ELC) +-0.08 v_flow_in(B_2020_summer_day_ELC_E_BATT_2020_ELC) +-0.08 v_flow_in(A_2020_summer_day_ELC_E_BATT_2020_ELC) +-1 v_orm_online_credit(spin_AB_A_2020_summer_day_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_B_2020_summer_day_NGCC_2020) +-1 v_orm_online_credit(spin_AB_B_2020_summer_day_NGCC_2015) +-1 v_orm_online_credit(spin_AB_B_2020_summer_day_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_A_2020_summer_day_NGCC_2020) +-1 v_orm_online_credit(spin_AB_A_2020_summer_day_SOLPV_2020) +-1 v_orm_online_credit(spin_AB_A_2020_summer_day_NGCC_2015) +-1 v_orm_online_credit(spin_AB_A_2020_summer_day_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_A_2020_summer_day_SOLPV_2015) +-1 v_orm_online_credit(spin_AB_B_2020_summer_day_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_C_B_2020_summer_day_E_TRANS_2015) +-1 v_orm_online_credit(spin_AB_C_A_2020_summer_day_E_TRANS_2015) +<= -0.16 + +c_u_operating_reserve_margin_constraint(reg_B_B_elec_B_2020_summer_night)_: +-0.10526315789473684 v_flow_out(B_A_2020_summer_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_B_2020_summer_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(B_2020_summer_night_NG_NGCC_2020_ELC) +-0.10526315789473684 v_flow_out(B_C_2020_summer_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(C_B_2020_summer_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(B_2020_summer_night_ELC_E_BATT_2020_ELC) ++0.1 v_flow_out(B_2020_summer_night_NG_NGCC_2015_ELC) +-0.1 v_flow_in(B_2020_summer_night_ELC_E_BATT_2020_ELC) +-1 v_orm_online_credit(reg_B_B_2020_summer_night_E_BATT_2020) +-1 v_orm_online_credit(reg_B_B_2020_summer_night_NGCC_2020) +-1 v_orm_online_credit(reg_B_C_B_2020_summer_night_E_TRANS_2015) +-1 v_orm_online_credit(reg_B_B_2020_summer_night_NGCC_2015) +-1 v_orm_online_credit(reg_B_A_B_2020_summer_night_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_margin_constraint(spin_AB_A_B_elec_AB_2020_winter_day)_: ++0.08 v_flow_out(C_A_2020_winter_day_ELC_E_TRANS_2015_ELC) +-0.08421052631578947 v_flow_out(A_C_2020_winter_day_ELC_E_TRANS_2015_ELC) ++0.18 v_flow_out(A_2020_winter_day_ethos_SOLPV_2020_ELC) ++0.08 v_flow_out(C_B_2020_winter_day_ELC_E_TRANS_2015_ELC) +-0.08421052631578947 v_flow_out(B_C_2020_winter_day_ELC_E_TRANS_2015_ELC) ++0.08 v_flow_out(B_2020_winter_day_ELC_E_LDES_2020_ELC) +-0.020000000000000004 v_flow_out(B_2020_winter_day_NG_NGCC_2015_ELC) +-0.020000000000000004 v_flow_out(A_2020_winter_day_NG_NGCC_2020_ELC) ++0.08 v_flow_out(A_2020_winter_day_ELC_E_BATT_2020_ELC) ++0.18 v_flow_out(A_2020_winter_day_ethos_SOLPV_2015_ELC) ++0.08 v_flow_out(B_2020_winter_day_ELC_E_BATT_2020_ELC) ++0.08 v_flow_out(A_2020_winter_day_ELC_E_LDES_2020_ELC) +-0.020000000000000004 v_flow_out(B_2020_winter_day_NG_NGCC_2020_ELC) +-0.020000000000000004 v_flow_out(A_2020_winter_day_NG_NGCC_2015_ELC) +-0.6569999999999999 v_capacity(B_2020_E_LDES_2020) +-1.095 v_capacity(A_2020_NGCC_2015) +-1.095 v_capacity(A_2020_NGCC_2020) ++0.013139999999999999 v_uc_online(B_2020_winter_day_E_LDES_2020) ++0.1095 v_uc_online(A_2020_winter_day_NGCC_2015) ++0.1095 v_uc_online(A_2020_winter_day_NGCC_2020) +-0.08 v_flow_in(A_2020_winter_day_ELC_E_LDES_2020_ELC) +-0.08 v_flow_in(B_2020_winter_day_ELC_E_LDES_2020_ELC) +-0.08 v_flow_in(A_2020_winter_day_ELC_E_BATT_2020_ELC) +-0.08 v_flow_in(B_2020_winter_day_ELC_E_BATT_2020_ELC) +-1 v_orm_online_credit(spin_AB_C_B_2020_winter_day_E_TRANS_2015) +-1 v_orm_online_credit(spin_AB_B_2020_winter_day_NGCC_2015) +-1 v_orm_online_credit(spin_AB_A_2020_winter_day_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_A_2020_winter_day_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_B_2020_winter_day_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_A_2020_winter_day_NGCC_2020) +-1 v_orm_online_credit(spin_AB_B_2020_winter_day_NGCC_2020) +-1 v_orm_online_credit(spin_AB_A_2020_winter_day_SOLPV_2020) +-1 v_orm_online_credit(spin_AB_B_2020_winter_day_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_A_2020_winter_day_NGCC_2015) +-1 v_orm_online_credit(spin_AB_A_2020_winter_day_SOLPV_2015) +-1 v_orm_online_credit(spin_AB_C_A_2020_winter_day_E_TRANS_2015) +<= -0.16 + +c_u_operating_reserve_margin_constraint(spin_A_A_elec_A_2025_winter_night)_: ++0.2 v_flow_out(A_2025_winter_night_ethos_SOLPV_2025_ELC) ++0.1 v_flow_out(A_2025_winter_night_NG_NGCC_2015_ELC) ++0.1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2020_ELC) ++0.1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2020_ELC) +-0.10526315789473684 v_flow_out(A_B_2025_winter_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2025_winter_night_ELC_HEAT_SYS_2025_HEAT) ++0.1 v_flow_out(A_2025_winter_night_ELC_E_LDES_2025_ELC) ++0.1 v_flow_out(A_2025_winter_night_ELC_HEAT_SYS_2020_HEAT) ++0.2 v_flow_out(A_2025_winter_night_ethos_SOLPV_2015_ELC) ++0.1 v_flow_out(A_2025_winter_night_NG_NGCC_2020_ELC) ++0.2 v_flow_out(A_2025_winter_night_ethos_SOLPV_2020_ELC) ++0.1 v_flow_out(C_A_2025_winter_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2025_winter_night_ELC_E_BATT_2025_ELC) ++0.1 v_flow_out(B_A_2025_winter_night_ELC_E_TRANS_2015_ELC) +-0.10526315789473684 v_flow_out(A_C_2025_winter_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2025_winter_night_NG_NGCC_2025_ELC) +-0.1 v_flow_in(A_2025_winter_night_ELC_E_BATT_2025_ELC) +-0.1 v_flow_in(A_2025_winter_night_ELC_E_LDES_2020_ELC) +-0.1 v_flow_in(A_2025_winter_night_ELC_E_BATT_2020_ELC) +-0.1 v_flow_in(A_2025_winter_night_ELC_E_LDES_2025_ELC) +-1 v_orm_online_credit(spin_A_A_2025_winter_night_E_BATT_2025) +-1 v_orm_online_credit(spin_A_A_2025_winter_night_NGCC_2020) +-1 v_orm_online_credit(spin_A_C_A_2025_winter_night_E_TRANS_2015) +-1 v_orm_online_credit(spin_A_A_2025_winter_night_E_BATT_2020) +-1 v_orm_online_credit(spin_A_A_2025_winter_night_NGCC_2015) +-1 v_orm_online_credit(spin_A_A_2025_winter_night_E_LDES_2025) +-1 v_orm_online_credit(spin_A_A_2025_winter_night_SOLPV_2015) +-1 v_orm_online_credit(spin_A_A_2025_winter_night_E_LDES_2020) +-1 v_orm_online_credit(spin_A_B_A_2025_winter_night_E_TRANS_2015) +-1 v_orm_online_credit(spin_A_A_2025_winter_night_NGCC_2025) +-1 v_orm_online_credit(spin_A_A_2025_winter_night_SOLPV_2025) +-1 v_orm_online_credit(spin_A_A_2025_winter_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_margin_constraint(spin_AB_A_B_elec_AB_2025_summer_night)_: ++0.08 v_flow_out(B_2025_summer_night_ELC_E_BATT_2020_ELC) ++0.18 v_flow_out(A_2025_summer_night_ethos_SOLPV_2020_ELC) +-0.020000000000000004 v_flow_out(A_2025_summer_night_NG_NGCC_2025_ELC) ++0.18 v_flow_out(A_2025_summer_night_ethos_SOLPV_2025_ELC) +-0.020000000000000004 v_flow_out(B_2025_summer_night_NG_NGCC_2015_ELC) +-0.020000000000000004 v_flow_out(A_2025_summer_night_NG_NGCC_2015_ELC) ++0.08 v_flow_out(B_2025_summer_night_ELC_E_LDES_2025_ELC) ++0.08 v_flow_out(A_2025_summer_night_ELC_HEAT_SYS_2020_HEAT) ++0.08 v_flow_out(B_2025_summer_night_ELC_HEAT_SYS_2025_HEAT) ++0.08 v_flow_out(B_2025_summer_night_ELC_E_LDES_2020_ELC) ++0.08 v_flow_out(A_2025_summer_night_ELC_E_BATT_2020_ELC) ++0.08 v_flow_out(A_2025_summer_night_ELC_E_LDES_2020_ELC) ++0.08 v_flow_out(B_2025_summer_night_ELC_E_BATT_2025_ELC) ++0.08 v_flow_out(A_2025_summer_night_ELC_E_BATT_2025_ELC) ++0.18 v_flow_out(A_2025_summer_night_ethos_SOLPV_2015_ELC) ++0.08 v_flow_out(C_B_2025_summer_night_ELC_E_TRANS_2015_ELC) +-0.020000000000000004 v_flow_out(A_2025_summer_night_NG_NGCC_2020_ELC) +-0.020000000000000004 v_flow_out(B_2025_summer_night_NG_NGCC_2020_ELC) ++0.08 v_flow_out(A_2025_summer_night_ELC_HEAT_SYS_2025_HEAT) +-0.020000000000000004 v_flow_out(B_2025_summer_night_NG_NGCC_2025_ELC) ++0.08 v_flow_out(C_A_2025_summer_night_ELC_E_TRANS_2015_ELC) ++0.08 v_flow_out(A_2025_summer_night_ELC_E_LDES_2025_ELC) ++0.08 v_flow_out(B_2025_summer_night_ELC_HEAT_SYS_2020_HEAT) +-0.08421052631578947 v_flow_out(A_C_2025_summer_night_ELC_E_TRANS_2015_ELC) +-0.08421052631578947 v_flow_out(B_C_2025_summer_night_ELC_E_TRANS_2015_ELC) +-1.095 v_capacity(A_2025_NGCC_2025) +-0.6569999999999999 v_capacity(B_2025_E_LDES_2020) +-1.095 v_capacity(A_2025_NGCC_2015) +-0.6569999999999999 v_capacity(B_2025_E_LDES_2025) +-1.095 v_capacity(A_2025_NGCC_2020) ++0.1095 v_uc_online(A_2025_summer_night_NGCC_2015) ++0.1095 v_uc_online(A_2025_summer_night_NGCC_2020) ++0.013139999999999999 v_uc_online(B_2025_summer_night_E_LDES_2020) ++0.1095 v_uc_online(A_2025_summer_night_NGCC_2025) ++0.013139999999999999 v_uc_online(B_2025_summer_night_E_LDES_2025) +-0.08 v_flow_in(B_2025_summer_night_ELC_E_BATT_2020_ELC) +-0.08 v_flow_in(A_2025_summer_night_ELC_E_BATT_2025_ELC) +-0.08 v_flow_in(B_2025_summer_night_ELC_E_LDES_2020_ELC) +-0.08 v_flow_in(A_2025_summer_night_ELC_E_LDES_2025_ELC) +-0.08 v_flow_in(A_2025_summer_night_ELC_E_BATT_2020_ELC) +-0.08 v_flow_in(A_2025_summer_night_ELC_E_LDES_2020_ELC) +-0.08 v_flow_in(B_2025_summer_night_ELC_E_BATT_2025_ELC) +-0.08 v_flow_in(B_2025_summer_night_ELC_E_LDES_2025_ELC) +-1 v_orm_online_credit(spin_AB_C_B_2025_summer_night_E_TRANS_2015) +-1 v_orm_online_credit(spin_AB_A_2025_summer_night_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_A_2025_summer_night_NGCC_2020) +-1 v_orm_online_credit(spin_AB_A_2025_summer_night_SOLPV_2015) +-1 v_orm_online_credit(spin_AB_A_2025_summer_night_NGCC_2025) +-1 v_orm_online_credit(spin_AB_B_2025_summer_night_E_BATT_2025) +-1 v_orm_online_credit(spin_AB_A_2025_summer_night_NGCC_2015) +-1 v_orm_online_credit(spin_AB_A_2025_summer_night_E_LDES_2025) +-1 v_orm_online_credit(spin_AB_B_2025_summer_night_NGCC_2025) +-1 v_orm_online_credit(spin_AB_B_2025_summer_night_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_B_2025_summer_night_NGCC_2020) +-1 v_orm_online_credit(spin_AB_A_2025_summer_night_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_B_2025_summer_night_NGCC_2015) +-1 v_orm_online_credit(spin_AB_B_2025_summer_night_E_LDES_2025) +-1 v_orm_online_credit(spin_AB_A_2025_summer_night_SOLPV_2025) +-1 v_orm_online_credit(spin_AB_B_2025_summer_night_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_C_A_2025_summer_night_E_TRANS_2015) +-1 v_orm_online_credit(spin_AB_A_2025_summer_night_E_BATT_2025) +-1 v_orm_online_credit(spin_AB_A_2025_summer_night_SOLPV_2020) +<= 0 + +c_u_operating_reserve_margin_constraint(spin_A_A_elec_A_2025_summer_day)_: ++0.1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2020_ELC) ++0.1 v_flow_out(A_2025_summer_day_ELC_HEAT_SYS_2025_HEAT) ++0.1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2025_ELC) ++0.2 v_flow_out(A_2025_summer_day_ethos_SOLPV_2020_ELC) ++0.2 v_flow_out(A_2025_summer_day_ethos_SOLPV_2025_ELC) ++0.1 v_flow_out(A_2025_summer_day_NG_NGCC_2015_ELC) +-0.10526315789473684 v_flow_out(A_B_2025_summer_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2025_summer_day_ELC_E_BATT_2025_ELC) ++0.1 v_flow_out(A_2025_summer_day_NG_NGCC_2020_ELC) ++0.1 v_flow_out(A_2025_summer_day_ELC_HEAT_SYS_2020_HEAT) ++0.1 v_flow_out(A_2025_summer_day_ELC_E_LDES_2020_ELC) ++0.1 v_flow_out(B_A_2025_summer_day_ELC_E_TRANS_2015_ELC) ++0.2 v_flow_out(A_2025_summer_day_ethos_SOLPV_2015_ELC) ++0.1 v_flow_out(C_A_2025_summer_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2025_summer_day_NG_NGCC_2025_ELC) +-0.10526315789473684 v_flow_out(A_C_2025_summer_day_ELC_E_TRANS_2015_ELC) +-0.1 v_flow_in(A_2025_summer_day_ELC_E_BATT_2020_ELC) +-0.1 v_flow_in(A_2025_summer_day_ELC_E_LDES_2025_ELC) +-0.1 v_flow_in(A_2025_summer_day_ELC_E_LDES_2020_ELC) +-0.1 v_flow_in(A_2025_summer_day_ELC_E_BATT_2025_ELC) +-1 v_orm_online_credit(spin_A_C_A_2025_summer_day_E_TRANS_2015) +-1 v_orm_online_credit(spin_A_A_2025_summer_day_E_BATT_2025) +-1 v_orm_online_credit(spin_A_A_2025_summer_day_SOLPV_2020) +-1 v_orm_online_credit(spin_A_A_2025_summer_day_E_BATT_2020) +-1 v_orm_online_credit(spin_A_A_2025_summer_day_SOLPV_2015) +-1 v_orm_online_credit(spin_A_A_2025_summer_day_NGCC_2025) +-1 v_orm_online_credit(spin_A_A_2025_summer_day_E_LDES_2025) +-1 v_orm_online_credit(spin_A_A_2025_summer_day_NGCC_2020) +-1 v_orm_online_credit(spin_A_A_2025_summer_day_E_LDES_2020) +-1 v_orm_online_credit(spin_A_A_2025_summer_day_SOLPV_2025) +-1 v_orm_online_credit(spin_A_A_2025_summer_day_NGCC_2015) +-1 v_orm_online_credit(spin_A_B_A_2025_summer_day_E_TRANS_2015) +<= 0 + +c_u_operating_reserve_margin_constraint(reg_B_B_elec_B_2020_winter_night)_: ++0.1 v_flow_out(A_B_2020_winter_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(B_2020_winter_night_NG_NGCC_2015_ELC) ++0.1 v_flow_out(B_2020_winter_night_ELC_E_BATT_2020_ELC) +-0.10526315789473684 v_flow_out(B_C_2020_winter_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(C_B_2020_winter_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(B_2020_winter_night_NG_NGCC_2020_ELC) +-0.10526315789473684 v_flow_out(B_A_2020_winter_night_ELC_E_TRANS_2015_ELC) +-0.1 v_flow_in(B_2020_winter_night_ELC_E_BATT_2020_ELC) +-1 v_orm_online_credit(reg_B_B_2020_winter_night_NGCC_2020) +-1 v_orm_online_credit(reg_B_B_2020_winter_night_NGCC_2015) +-1 v_orm_online_credit(reg_B_A_B_2020_winter_night_E_TRANS_2015) +-1 v_orm_online_credit(reg_B_C_B_2020_winter_night_E_TRANS_2015) +-1 v_orm_online_credit(reg_B_B_2020_winter_night_E_BATT_2020) +<= 0 + +c_u_operating_reserve_margin_constraint(reg_B_B_elec_B_2020_summer_day)_: ++0.1 v_flow_out(B_2020_summer_day_NG_NGCC_2020_ELC) ++0.1 v_flow_out(C_B_2020_summer_day_ELC_E_TRANS_2015_ELC) +-0.10526315789473684 v_flow_out(B_C_2020_summer_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(B_2020_summer_day_ELC_E_BATT_2020_ELC) ++0.1 v_flow_out(B_2020_summer_day_NG_NGCC_2015_ELC) +-0.10526315789473684 v_flow_out(B_A_2020_summer_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_B_2020_summer_day_ELC_E_TRANS_2015_ELC) +-0.1 v_flow_in(B_2020_summer_day_ELC_E_BATT_2020_ELC) +-1 v_orm_online_credit(reg_B_C_B_2020_summer_day_E_TRANS_2015) +-1 v_orm_online_credit(reg_B_B_2020_summer_day_E_BATT_2020) +-1 v_orm_online_credit(reg_B_A_B_2020_summer_day_E_TRANS_2015) +-1 v_orm_online_credit(reg_B_B_2020_summer_day_NGCC_2020) +-1 v_orm_online_credit(reg_B_B_2020_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_margin_constraint(spin_AB_A_B_elec_AB_2025_winter_night)_: ++0.18 v_flow_out(A_2025_winter_night_ethos_SOLPV_2025_ELC) +-0.020000000000000004 v_flow_out(A_2025_winter_night_NG_NGCC_2015_ELC) ++0.08 v_flow_out(A_2025_winter_night_ELC_E_LDES_2020_ELC) ++0.08 v_flow_out(A_2025_winter_night_ELC_E_BATT_2020_ELC) ++0.08 v_flow_out(A_2025_winter_night_ELC_HEAT_SYS_2025_HEAT) ++0.08 v_flow_out(A_2025_winter_night_ELC_E_LDES_2025_ELC) ++0.08 v_flow_out(C_B_2025_winter_night_ELC_E_TRANS_2015_ELC) +-0.020000000000000004 v_flow_out(B_2025_winter_night_NG_NGCC_2025_ELC) ++0.08 v_flow_out(A_2025_winter_night_ELC_HEAT_SYS_2020_HEAT) ++0.08 v_flow_out(B_2025_winter_night_ELC_E_LDES_2020_ELC) ++0.18 v_flow_out(A_2025_winter_night_ethos_SOLPV_2015_ELC) ++0.08 v_flow_out(B_2025_winter_night_ELC_E_BATT_2020_ELC) +-0.020000000000000004 v_flow_out(A_2025_winter_night_NG_NGCC_2020_ELC) ++0.08 v_flow_out(B_2025_winter_night_ELC_E_LDES_2025_ELC) ++0.08 v_flow_out(B_2025_winter_night_ELC_HEAT_SYS_2020_HEAT) ++0.18 v_flow_out(A_2025_winter_night_ethos_SOLPV_2020_ELC) ++0.08 v_flow_out(C_A_2025_winter_night_ELC_E_TRANS_2015_ELC) ++0.08 v_flow_out(A_2025_winter_night_ELC_E_BATT_2025_ELC) ++0.08 v_flow_out(B_2025_winter_night_ELC_E_BATT_2025_ELC) +-0.020000000000000004 v_flow_out(B_2025_winter_night_NG_NGCC_2015_ELC) +-0.08421052631578947 v_flow_out(A_C_2025_winter_night_ELC_E_TRANS_2015_ELC) +-0.020000000000000004 v_flow_out(B_2025_winter_night_NG_NGCC_2020_ELC) +-0.08421052631578947 v_flow_out(B_C_2025_winter_night_ELC_E_TRANS_2015_ELC) +-0.020000000000000004 v_flow_out(A_2025_winter_night_NG_NGCC_2025_ELC) ++0.08 v_flow_out(B_2025_winter_night_ELC_HEAT_SYS_2025_HEAT) +-1.095 v_capacity(A_2025_NGCC_2025) +-0.6569999999999999 v_capacity(B_2025_E_LDES_2020) +-1.095 v_capacity(A_2025_NGCC_2015) +-0.6569999999999999 v_capacity(B_2025_E_LDES_2025) +-1.095 v_capacity(A_2025_NGCC_2020) ++0.1095 v_uc_online(A_2025_winter_night_NGCC_2015) ++0.013139999999999999 v_uc_online(B_2025_winter_night_E_LDES_2020) ++0.1095 v_uc_online(A_2025_winter_night_NGCC_2020) ++0.013139999999999999 v_uc_online(B_2025_winter_night_E_LDES_2025) ++0.1095 v_uc_online(A_2025_winter_night_NGCC_2025) +-0.08 v_flow_in(B_2025_winter_night_ELC_E_LDES_2025_ELC) +-0.08 v_flow_in(A_2025_winter_night_ELC_E_BATT_2025_ELC) +-0.08 v_flow_in(A_2025_winter_night_ELC_E_LDES_2020_ELC) +-0.08 v_flow_in(B_2025_winter_night_ELC_E_LDES_2020_ELC) +-0.08 v_flow_in(A_2025_winter_night_ELC_E_BATT_2020_ELC) +-0.08 v_flow_in(B_2025_winter_night_ELC_E_BATT_2025_ELC) +-0.08 v_flow_in(B_2025_winter_night_ELC_E_BATT_2020_ELC) +-0.08 v_flow_in(A_2025_winter_night_ELC_E_LDES_2025_ELC) +-1 v_orm_online_credit(spin_AB_A_2025_winter_night_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_B_2025_winter_night_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_C_B_2025_winter_night_E_TRANS_2015) +-1 v_orm_online_credit(spin_AB_A_2025_winter_night_NGCC_2015) +-1 v_orm_online_credit(spin_AB_A_2025_winter_night_SOLPV_2025) +-1 v_orm_online_credit(spin_AB_B_2025_winter_night_NGCC_2015) +-1 v_orm_online_credit(spin_AB_A_2025_winter_night_SOLPV_2020) +-1 v_orm_online_credit(spin_AB_C_A_2025_winter_night_E_TRANS_2015) +-1 v_orm_online_credit(spin_AB_A_2025_winter_night_SOLPV_2015) +-1 v_orm_online_credit(spin_AB_A_2025_winter_night_E_BATT_2025) +-1 v_orm_online_credit(spin_AB_B_2025_winter_night_NGCC_2025) +-1 v_orm_online_credit(spin_AB_A_2025_winter_night_NGCC_2025) +-1 v_orm_online_credit(spin_AB_B_2025_winter_night_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_B_2025_winter_night_E_LDES_2025) +-1 v_orm_online_credit(spin_AB_A_2025_winter_night_E_LDES_2025) +-1 v_orm_online_credit(spin_AB_A_2025_winter_night_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_B_2025_winter_night_E_BATT_2025) +-1 v_orm_online_credit(spin_AB_B_2025_winter_night_NGCC_2020) +-1 v_orm_online_credit(spin_AB_A_2025_winter_night_NGCC_2020) +<= 0 + +c_u_operating_reserve_margin_constraint(spin_A_A_elec_A_2025_winter_day)_: ++0.1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2025_ELC) ++0.1 v_flow_out(B_A_2025_winter_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2025_winter_day_NG_NGCC_2020_ELC) ++0.1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2025_ELC) ++0.1 v_flow_out(A_2025_winter_day_ELC_HEAT_SYS_2020_HEAT) ++0.1 v_flow_out(A_2025_winter_day_NG_NGCC_2025_ELC) +-0.10526315789473684 v_flow_out(A_C_2025_winter_day_ELC_E_TRANS_2015_ELC) ++0.2 v_flow_out(A_2025_winter_day_ethos_SOLPV_2025_ELC) ++0.1 v_flow_out(C_A_2025_winter_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2025_winter_day_ELC_HEAT_SYS_2025_HEAT) ++0.1 v_flow_out(A_2025_winter_day_ELC_E_LDES_2020_ELC) ++0.1 v_flow_out(A_2025_winter_day_NG_NGCC_2015_ELC) +-0.10526315789473684 v_flow_out(A_B_2025_winter_day_ELC_E_TRANS_2015_ELC) ++0.2 v_flow_out(A_2025_winter_day_ethos_SOLPV_2015_ELC) ++0.2 v_flow_out(A_2025_winter_day_ethos_SOLPV_2020_ELC) ++0.1 v_flow_out(A_2025_winter_day_ELC_E_BATT_2020_ELC) +-0.1 v_flow_in(A_2025_winter_day_ELC_E_LDES_2025_ELC) +-0.1 v_flow_in(A_2025_winter_day_ELC_E_BATT_2025_ELC) +-0.1 v_flow_in(A_2025_winter_day_ELC_E_LDES_2020_ELC) +-0.1 v_flow_in(A_2025_winter_day_ELC_E_BATT_2020_ELC) +-1 v_orm_online_credit(spin_A_B_A_2025_winter_day_E_TRANS_2015) +-1 v_orm_online_credit(spin_A_A_2025_winter_day_SOLPV_2025) +-1 v_orm_online_credit(spin_A_A_2025_winter_day_E_BATT_2025) +-1 v_orm_online_credit(spin_A_A_2025_winter_day_SOLPV_2020) +-1 v_orm_online_credit(spin_A_A_2025_winter_day_E_BATT_2020) +-1 v_orm_online_credit(spin_A_A_2025_winter_day_SOLPV_2015) +-1 v_orm_online_credit(spin_A_A_2025_winter_day_NGCC_2025) +-1 v_orm_online_credit(spin_A_C_A_2025_winter_day_E_TRANS_2015) +-1 v_orm_online_credit(spin_A_A_2025_winter_day_E_LDES_2025) +-1 v_orm_online_credit(spin_A_A_2025_winter_day_NGCC_2020) +-1 v_orm_online_credit(spin_A_A_2025_winter_day_E_LDES_2020) +-1 v_orm_online_credit(spin_A_A_2025_winter_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_margin_constraint(spin_AB_A_B_elec_AB_2025_summer_day)_: ++0.08 v_flow_out(A_2025_summer_day_ELC_E_BATT_2020_ELC) ++0.08 v_flow_out(A_2025_summer_day_ELC_HEAT_SYS_2025_HEAT) ++0.08 v_flow_out(A_2025_summer_day_ELC_E_LDES_2025_ELC) ++0.08 v_flow_out(B_2025_summer_day_ELC_E_BATT_2020_ELC) ++0.18 v_flow_out(A_2025_summer_day_ethos_SOLPV_2020_ELC) ++0.08 v_flow_out(B_2025_summer_day_ELC_E_LDES_2020_ELC) ++0.08 v_flow_out(B_2025_summer_day_ELC_E_LDES_2025_ELC) ++0.18 v_flow_out(A_2025_summer_day_ethos_SOLPV_2025_ELC) +-0.020000000000000004 v_flow_out(A_2025_summer_day_NG_NGCC_2015_ELC) ++0.08 v_flow_out(B_2025_summer_day_ELC_HEAT_SYS_2025_HEAT) +-0.020000000000000004 v_flow_out(B_2025_summer_day_NG_NGCC_2025_ELC) ++0.08 v_flow_out(A_2025_summer_day_ELC_E_BATT_2025_ELC) +-0.020000000000000004 v_flow_out(A_2025_summer_day_NG_NGCC_2020_ELC) ++0.08 v_flow_out(B_2025_summer_day_ELC_E_BATT_2025_ELC) +-0.020000000000000004 v_flow_out(B_2025_summer_day_NG_NGCC_2015_ELC) ++0.08 v_flow_out(A_2025_summer_day_ELC_HEAT_SYS_2020_HEAT) ++0.08 v_flow_out(A_2025_summer_day_ELC_E_LDES_2020_ELC) ++0.18 v_flow_out(A_2025_summer_day_ethos_SOLPV_2015_ELC) +-0.08421052631578947 v_flow_out(B_C_2025_summer_day_ELC_E_TRANS_2015_ELC) ++0.08 v_flow_out(C_A_2025_summer_day_ELC_E_TRANS_2015_ELC) ++0.08 v_flow_out(C_B_2025_summer_day_ELC_E_TRANS_2015_ELC) +-0.020000000000000004 v_flow_out(A_2025_summer_day_NG_NGCC_2025_ELC) ++0.08 v_flow_out(B_2025_summer_day_ELC_HEAT_SYS_2020_HEAT) +-0.08421052631578947 v_flow_out(A_C_2025_summer_day_ELC_E_TRANS_2015_ELC) +-0.020000000000000004 v_flow_out(B_2025_summer_day_NG_NGCC_2020_ELC) +-1.095 v_capacity(A_2025_NGCC_2025) +-0.6569999999999999 v_capacity(B_2025_E_LDES_2020) +-1.095 v_capacity(A_2025_NGCC_2015) +-0.6569999999999999 v_capacity(B_2025_E_LDES_2025) +-1.095 v_capacity(A_2025_NGCC_2020) ++0.013139999999999999 v_uc_online(B_2025_summer_day_E_LDES_2025) ++0.1095 v_uc_online(A_2025_summer_day_NGCC_2025) ++0.1095 v_uc_online(A_2025_summer_day_NGCC_2015) ++0.013139999999999999 v_uc_online(B_2025_summer_day_E_LDES_2020) ++0.1095 v_uc_online(A_2025_summer_day_NGCC_2020) +-0.08 v_flow_in(B_2025_summer_day_ELC_E_BATT_2025_ELC) +-0.08 v_flow_in(A_2025_summer_day_ELC_E_BATT_2020_ELC) +-0.08 v_flow_in(B_2025_summer_day_ELC_E_LDES_2025_ELC) +-0.08 v_flow_in(A_2025_summer_day_ELC_E_LDES_2025_ELC) +-0.08 v_flow_in(B_2025_summer_day_ELC_E_BATT_2020_ELC) +-0.08 v_flow_in(A_2025_summer_day_ELC_E_LDES_2020_ELC) +-0.08 v_flow_in(B_2025_summer_day_ELC_E_LDES_2020_ELC) +-0.08 v_flow_in(A_2025_summer_day_ELC_E_BATT_2025_ELC) +-1 v_orm_online_credit(spin_AB_B_2025_summer_day_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_B_2025_summer_day_E_LDES_2025) +-1 v_orm_online_credit(spin_AB_A_2025_summer_day_SOLPV_2025) +-1 v_orm_online_credit(spin_AB_B_2025_summer_day_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_A_2025_summer_day_E_BATT_2025) +-1 v_orm_online_credit(spin_AB_A_2025_summer_day_SOLPV_2020) +-1 v_orm_online_credit(spin_AB_C_B_2025_summer_day_E_TRANS_2015) +-1 v_orm_online_credit(spin_AB_A_2025_summer_day_E_BATT_2020) +-1 v_orm_online_credit(spin_AB_A_2025_summer_day_SOLPV_2015) +-1 v_orm_online_credit(spin_AB_A_2025_summer_day_NGCC_2025) +-1 v_orm_online_credit(spin_AB_B_2025_summer_day_NGCC_2025) +-1 v_orm_online_credit(spin_AB_A_2025_summer_day_E_LDES_2025) +-1 v_orm_online_credit(spin_AB_A_2025_summer_day_NGCC_2020) +-1 v_orm_online_credit(spin_AB_B_2025_summer_day_NGCC_2020) +-1 v_orm_online_credit(spin_AB_A_2025_summer_day_E_LDES_2020) +-1 v_orm_online_credit(spin_AB_C_A_2025_summer_day_E_TRANS_2015) +-1 v_orm_online_credit(spin_AB_B_2025_summer_day_E_BATT_2025) +-1 v_orm_online_credit(spin_AB_A_2025_summer_day_NGCC_2015) +-1 v_orm_online_credit(spin_AB_B_2025_summer_day_NGCC_2015) +<= 0 + +c_u_operating_reserve_margin_constraint(spin_A_A_elec_A_2020_summer_night)_: ++0.2 v_flow_out(A_2020_summer_night_ethos_SOLPV_2020_ELC) ++0.1 v_flow_out(B_A_2020_summer_night_ELC_E_TRANS_2015_ELC) +-0.10526315789473684 v_flow_out(A_B_2020_summer_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2020_summer_night_NG_NGCC_2015_ELC) ++0.1 v_flow_out(A_2020_summer_night_ELC_E_BATT_2020_ELC) ++0.1 v_flow_out(A_2020_summer_night_NG_NGCC_2020_ELC) +-0.10526315789473684 v_flow_out(A_C_2020_summer_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2020_summer_night_ELC_E_LDES_2020_ELC) ++0.2 v_flow_out(A_2020_summer_night_ethos_SOLPV_2015_ELC) ++0.1 v_flow_out(C_A_2020_summer_night_ELC_E_TRANS_2015_ELC) +-0.1 v_flow_in(A_2020_summer_night_ELC_E_BATT_2020_ELC) +-0.1 v_flow_in(A_2020_summer_night_ELC_E_LDES_2020_ELC) +-1 v_orm_online_credit(spin_A_A_2020_summer_night_E_LDES_2020) +-1 v_orm_online_credit(spin_A_A_2020_summer_night_E_BATT_2020) +-1 v_orm_online_credit(spin_A_B_A_2020_summer_night_E_TRANS_2015) +-1 v_orm_online_credit(spin_A_A_2020_summer_night_SOLPV_2020) +-1 v_orm_online_credit(spin_A_A_2020_summer_night_NGCC_2020) +-1 v_orm_online_credit(spin_A_A_2020_summer_night_SOLPV_2015) +-1 v_orm_online_credit(spin_A_C_A_2020_summer_night_E_TRANS_2015) +-1 v_orm_online_credit(spin_A_A_2020_summer_night_NGCC_2015) +<= -0.125 + +c_u_operating_reserve_margin_constraint(spin_A_A_elec_A_2020_winter_night)_: ++0.1 v_flow_out(C_A_2020_winter_night_ELC_E_TRANS_2015_ELC) +-0.10526315789473684 v_flow_out(A_B_2020_winter_night_ELC_E_TRANS_2015_ELC) ++0.2 v_flow_out(A_2020_winter_night_ethos_SOLPV_2020_ELC) ++0.1 v_flow_out(A_2020_winter_night_ELC_E_BATT_2020_ELC) ++0.1 v_flow_out(A_2020_winter_night_NG_NGCC_2020_ELC) +-0.10526315789473684 v_flow_out(A_C_2020_winter_night_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_2020_winter_night_ELC_E_LDES_2020_ELC) ++0.1 v_flow_out(A_2020_winter_night_NG_NGCC_2015_ELC) ++0.2 v_flow_out(A_2020_winter_night_ethos_SOLPV_2015_ELC) ++0.1 v_flow_out(B_A_2020_winter_night_ELC_E_TRANS_2015_ELC) +-0.1 v_flow_in(A_2020_winter_night_ELC_E_BATT_2020_ELC) +-0.1 v_flow_in(A_2020_winter_night_ELC_E_LDES_2020_ELC) +-1 v_orm_online_credit(spin_A_A_2020_winter_night_SOLPV_2015) +-1 v_orm_online_credit(spin_A_A_2020_winter_night_E_LDES_2020) +-1 v_orm_online_credit(spin_A_C_A_2020_winter_night_E_TRANS_2015) +-1 v_orm_online_credit(spin_A_A_2020_winter_night_SOLPV_2020) +-1 v_orm_online_credit(spin_A_B_A_2020_winter_night_E_TRANS_2015) +-1 v_orm_online_credit(spin_A_A_2020_winter_night_NGCC_2020) +-1 v_orm_online_credit(spin_A_A_2020_winter_night_E_BATT_2020) +-1 v_orm_online_credit(spin_A_A_2020_winter_night_NGCC_2015) +<= -0.125 + +c_u_operating_reserve_margin_constraint(reg_B_B_elec_B_2020_winter_day)_: ++0.1 v_flow_out(C_B_2020_winter_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(A_B_2020_winter_day_ELC_E_TRANS_2015_ELC) +-0.10526315789473684 v_flow_out(B_C_2020_winter_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(B_2020_winter_day_NG_NGCC_2015_ELC) ++0.1 v_flow_out(B_2020_winter_day_ELC_E_BATT_2020_ELC) +-0.10526315789473684 v_flow_out(B_A_2020_winter_day_ELC_E_TRANS_2015_ELC) ++0.1 v_flow_out(B_2020_winter_day_NG_NGCC_2020_ELC) +-0.1 v_flow_in(B_2020_winter_day_ELC_E_BATT_2020_ELC) +-1 v_orm_online_credit(reg_B_B_2020_winter_day_E_BATT_2020) +-1 v_orm_online_credit(reg_B_B_2020_winter_day_NGCC_2020) +-1 v_orm_online_credit(reg_B_A_B_2020_winter_day_E_TRANS_2015) +-1 v_orm_online_credit(reg_B_B_2020_winter_day_NGCC_2015) +-1 v_orm_online_credit(reg_B_C_B_2020_winter_day_E_TRANS_2015) +<= 0 + +bounds + 1 <= ONE_VAR_CONSTANT <= 1 + 0 <= v_flow_out(A_2025_winter_night_ethos_SOLPV_2025_ELC) <= +inf + 0 <= v_flow_out(C_A_2020_winter_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_night_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(C_A_2020_winter_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(A_C_2020_winter_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_day_ELC_HEAT_SYS_2025_HEAT) <= +inf + 0 <= v_flow_out(B_2025_winter_day_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(A_2020_winter_day_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_day_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_day_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_out(C_B_2020_winter_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2020_summer_night_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_flow_out(A_2020_summer_day_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_night_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_flow_out(A_B_2025_summer_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_out(B_A_2025_winter_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_day_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(B_2020_winter_day_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(B_2025_winter_day_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_day_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_night_NG_NGCC_2025_ELC) <= +inf + 0 <= v_flow_out(A_2020_summer_day_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_day_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_day_ELC_HEAT_SYS_2020_HEAT) <= +inf + 0 <= v_flow_out(A_2025_winter_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(A_B_2020_winter_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_B_2020_winter_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2020_winter_night_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_flow_out(A_B_2025_winter_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_night_ELC_HEAT_SYS_2025_HEAT) <= +inf + 0 <= v_flow_out(B_C_2020_winter_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_A_2020_summer_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_night_ethos_SOLPV_2025_ELC) <= +inf + 0 <= v_flow_out(B_2020_summer_day_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_night_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_night_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_night_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_out(C_B_2020_summer_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_day_NG_NGCC_2025_ELC) <= +inf + 0 <= v_flow_out(B_2025_winter_day_ELC_HEAT_SYS_2025_HEAT) <= +inf + 0 <= v_flow_out(B_2025_summer_night_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_night_ELC_HEAT_SYS_2020_HEAT) <= +inf + 0 <= v_flow_out(C_B_2025_winter_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_B_2020_summer_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2025_winter_night_NG_NGCC_2025_ELC) <= +inf + 0 <= v_flow_out(A_2020_winter_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_day_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_night_ELC_HEAT_SYS_2020_HEAT) <= +inf + 0 <= v_flow_out(A_2025_summer_night_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(A_C_2025_winter_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_night_ELC_HEAT_SYS_2025_HEAT) <= +inf + 0 <= v_flow_out(A_2025_summer_day_ethos_SOLPV_2025_ELC) <= +inf + 0 <= v_flow_out(B_2020_winter_night_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_day_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_day_ELC_HEAT_SYS_2025_HEAT) <= +inf + 0 <= v_flow_out(B_2020_winter_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_out(B_2025_winter_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_day_NG_NGCC_2025_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_day_ethos_SOLPV_2025_ELC) <= +inf + 0 <= v_flow_out(B_2020_summer_night_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(A_B_2025_summer_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2020_winter_day_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(A_2020_winter_night_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(A_2020_winter_day_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(B_2020_winter_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_night_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_flow_out(A_2020_winter_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(B_2025_winter_day_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_out(B_2025_winter_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_day_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_night_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_night_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_out(B_2025_winter_day_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(B_2025_winter_day_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_day_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(A_2020_summer_day_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_day_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_out(A_2020_winter_night_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(A_2020_summer_night_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(B_2020_summer_night_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(A_C_2020_winter_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_day_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(B_2025_winter_night_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_night_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_out(B_C_2020_winter_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2025_winter_night_ELC_HEAT_SYS_2020_HEAT) <= +inf + 0 <= v_flow_out(C_A_2025_winter_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2020_summer_night_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(A_2025_winter_night_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_day_ELC_HEAT_SYS_2025_HEAT) <= +inf + 0 <= v_flow_out(C_A_2025_winter_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2020_summer_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_night_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_day_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(A_2025_summer_day_ELC_HEAT_SYS_2020_HEAT) <= +inf + 0 <= v_flow_out(A_2020_winter_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_out(A_2020_summer_day_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(B_2025_winter_night_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(A_2020_winter_day_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_out(A_2020_winter_night_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_night_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_flow_out(B_C_2020_summer_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(C_B_2025_summer_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2020_summer_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(B_2025_winter_night_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_out(B_2020_summer_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_out(A_2020_summer_night_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_day_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(B_2020_summer_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(B_A_2025_summer_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_day_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_night_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(B_2020_winter_night_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(B_A_2025_summer_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2020_summer_day_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_night_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(A_C_2020_summer_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_C_2020_summer_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2025_winter_night_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_night_ELC_HEAT_SYS_2025_HEAT) <= +inf + 0 <= v_flow_out(A_2020_summer_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(B_C_2020_summer_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_B_2025_winter_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(C_B_2025_winter_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2020_winter_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_out(B_2020_winter_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_day_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(A_2020_summer_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_out(C_B_2020_summer_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_A_2025_winter_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_day_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(C_B_2020_winter_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2020_winter_night_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_night_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(A_2025_winter_day_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_flow_out(A_2020_winter_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_out(A_2020_summer_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_out(B_A_2020_winter_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2020_winter_night_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(B_A_2020_winter_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2020_summer_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(A_C_2025_winter_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2020_summer_day_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(B_C_2025_summer_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2020_summer_day_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(B_A_2020_summer_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2025_winter_day_ELC_HEAT_SYS_2020_HEAT) <= +inf + 0 <= v_flow_out(B_2025_summer_night_NG_NGCC_2025_ELC) <= +inf + 0 <= v_flow_out(B_2025_winter_night_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(C_A_2025_summer_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2020_summer_night_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_flow_out(C_A_2020_summer_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_C_2025_winter_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_B_2020_summer_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2020_winter_day_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(C_A_2025_summer_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(C_A_2020_summer_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_C_2025_winter_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_night_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_night_ELC_HEAT_SYS_2020_HEAT) <= +inf + 0 <= v_flow_out(A_2025_winter_night_NG_NGCC_2025_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_night_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(C_B_2025_summer_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2025_winter_day_NG_NGCC_2025_ELC) <= +inf + 0 <= v_flow_out(A_2025_summer_day_NG_NGCC_2025_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_day_ELC_HEAT_SYS_2020_HEAT) <= +inf + 0 <= v_flow_out(A_C_2025_summer_day_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2020_winter_day_ethos_IMP_NG_2020_NG) <= +inf + 0 <= v_flow_out(A_C_2025_summer_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(B_2025_winter_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(B_2025_summer_day_NG_NGCC_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_day_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_flow_out(A_2025_winter_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_out(B_2020_summer_night_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(B_C_2025_summer_night_ELC_E_TRANS_2015_ELC) <= +inf + 0 <= v_flow_out(A_2020_winter_day_NG_NGCC_2015_ELC) <= +inf + 0 <= v_flow_out(B_2025_winter_night_ELC_HEAT_SYS_2025_HEAT) <= +inf + 0 <= v_flow_out(B_2025_winter_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_capacity(A_2025_E_BATT_2025) <= +inf + 0 <= v_capacity(B_2020_E_LDES_2020) <= +inf + 0 <= v_capacity(B_C_2020_E_TRANS_2015) <= +inf + 0 <= v_capacity(A_2020_NGCC_2015) <= +inf + 0 <= v_capacity(A_2025_HEAT_SYS_2025) <= +inf + 0 <= v_capacity(A_2020_E_BATT_2020) <= +inf + 0 <= v_capacity(B_2025_NGCC_2020) <= +inf + 0 <= v_capacity(A_C_2025_E_TRANS_2015) <= +inf + 0 <= v_capacity(C_2025_HEAT_ANN_2020) <= +inf + 0 <= v_capacity(C_2025_ANN_IMP_2020) <= +inf + 0 <= v_capacity(A_2025_NGCC_2025) <= +inf + 0 <= v_capacity(C_B_2020_E_TRANS_2015) <= +inf + 0 <= v_capacity(A_2025_SOLPV_2020) <= +inf + 0 <= v_capacity(B_2025_E_BATT_2025) <= +inf + 0 <= v_capacity(A_2020_HEAT_SYS_2020) <= +inf + 0 <= v_capacity(B_2025_HEAT_SYS_2025) <= +inf + 0 <= v_capacity(A_2025_E_LDES_2020) <= +inf + 0 <= v_capacity(B_2020_E_BATT_2020) <= +inf + 0 <= v_capacity(B_2020_NGCC_2015) <= +inf + 0 <= v_capacity(C_A_2025_E_TRANS_2015) <= +inf + 0 <= v_capacity(A_B_2025_E_TRANS_2015) <= +inf + 0 <= v_capacity(B_A_2020_E_TRANS_2015) <= +inf + 0 <= v_capacity(A_2020_NGCC_2020) <= +inf + 0 <= v_capacity(B_2025_E_LDES_2020) <= +inf + 0 <= v_capacity(A_2020_SOLPV_2015) <= +inf + 0 <= v_capacity(A_2025_NGCC_2015) <= +inf + 0 <= v_capacity(B_2025_NGCC_2025) <= +inf + 0 <= v_capacity(B_2020_HEAT_SYS_2020) <= +inf + 0 <= v_capacity(C_2020_HEAT_ANN_2020) <= +inf + 0 <= v_capacity(A_C_2020_E_TRANS_2015) <= +inf + 0 <= v_capacity(A_2025_SOLPV_2025) <= +inf + 0 <= v_capacity(B_C_2025_E_TRANS_2015) <= +inf + 0 <= v_capacity(A_2025_E_BATT_2020) <= +inf + 0 <= v_capacity(A_2025_E_LDES_2025) <= +inf + 0 <= v_capacity(A_2025_HEAT_SYS_2020) <= +inf + 0 <= v_capacity(B_2020_NGCC_2020) <= +inf + 0 <= v_capacity(A_2020_E_LDES_2020) <= +inf + 0 <= v_capacity(B_2025_NGCC_2015) <= +inf + 0 <= v_capacity(C_2020_ANN_IMP_2020) <= +inf + 0 <= v_capacity(A_B_2020_E_TRANS_2015) <= +inf + 0 <= v_capacity(A_2020_SOLPV_2020) <= +inf + 0 <= v_capacity(B_2025_E_LDES_2025) <= +inf + 0 <= v_capacity(B_A_2025_E_TRANS_2015) <= +inf + 0 <= v_capacity(C_B_2025_E_TRANS_2015) <= +inf + 0 <= v_capacity(A_2025_NGCC_2020) <= +inf + 0 <= v_capacity(A_2025_SOLPV_2015) <= +inf + 0 <= v_capacity(C_A_2020_E_TRANS_2015) <= +inf + 0 <= v_capacity(B_2025_E_BATT_2020) <= +inf + 0 <= v_capacity(B_2025_HEAT_SYS_2020) <= +inf + 0 <= v_uc_online(A_B_2020_winter_day_E_TRANS_2015) <= +inf + 0 <= v_uc_online(A_2020_summer_day_NGCC_2015) <= +inf + 0 <= v_uc_online(A_2025_summer_night_NGCC_2015) <= +inf + 0 <= v_uc_online(B_2025_summer_day_E_LDES_2025) <= +inf + 0 <= v_uc_online(B_A_2025_winter_day_E_TRANS_2015) <= +inf + 0 <= v_uc_online(A_2020_winter_night_NGCC_2020) <= +inf + 0 <= v_uc_online(B_2025_summer_night_E_BATT_2020) <= +inf + 0 <= v_uc_online(A_2025_winter_day_NGCC_2015) <= +inf + 0 <= v_uc_online(B_2025_winter_night_E_BATT_2025) <= +inf + 0 <= v_uc_online(B_2025_summer_day_E_BATT_2020) <= +inf + 0 <= v_uc_online(A_2025_summer_day_NGCC_2025) <= +inf + 0 <= v_uc_online(A_2025_winter_night_NGCC_2015) <= +inf + 0 <= v_uc_online(B_A_2020_winter_night_E_TRANS_2015) <= +inf + 0 <= v_uc_online(B_2020_summer_day_E_LDES_2020) <= +inf + 0 <= v_uc_online(A_2020_summer_night_NGCC_2020) <= +inf + 0 <= v_uc_online(B_2020_winter_night_E_LDES_2020) <= +inf + 0 <= v_uc_online(A_B_2025_summer_night_E_TRANS_2015) <= +inf + 0 <= v_uc_online(B_2020_summer_night_E_LDES_2020) <= +inf + 0 <= v_uc_online(A_B_2020_summer_day_E_TRANS_2015) <= +inf + 0 <= v_uc_online(B_2020_winter_day_E_LDES_2020) <= +inf + 0 <= v_uc_online(B_2025_winter_day_E_LDES_2020) <= +inf + 0 <= v_uc_online(A_2020_summer_day_NGCC_2020) <= +inf + 0 <= v_uc_online(A_2025_summer_night_NGCC_2020) <= +inf + 0 <= v_uc_online(B_2025_summer_night_E_BATT_2025) <= +inf + 0 <= v_uc_online(B_A_2020_summer_day_E_TRANS_2015) <= +inf + 0 <= v_uc_online(A_2025_winter_day_NGCC_2020) <= +inf + 0 <= v_uc_online(A_2025_summer_day_NGCC_2015) <= +inf + 0 <= v_uc_online(A_2020_winter_day_NGCC_2015) <= +inf + 0 <= v_uc_online(B_2025_winter_night_E_LDES_2020) <= +inf + 0 <= v_uc_online(A_B_2025_winter_day_E_TRANS_2015) <= +inf + 0 <= v_uc_online(B_A_2025_summer_night_E_TRANS_2015) <= +inf + 0 <= v_uc_online(B_A_2025_winter_night_E_TRANS_2015) <= +inf + 0 <= v_uc_online(B_2020_summer_day_E_BATT_2020) <= +inf + 0 <= v_uc_online(B_2025_summer_day_E_BATT_2025) <= +inf + 0 <= v_uc_online(B_2025_winter_day_E_BATT_2020) <= +inf + 0 <= v_uc_online(A_2025_winter_night_NGCC_2020) <= +inf + 0 <= v_uc_online(A_B_2020_winter_night_E_TRANS_2015) <= +inf + 0 <= v_uc_online(B_2020_summer_night_E_BATT_2020) <= +inf + 0 <= v_uc_online(B_2025_summer_night_E_LDES_2020) <= +inf + 0 <= v_uc_online(A_B_2025_winter_night_E_TRANS_2015) <= +inf + 0 <= v_uc_online(B_A_2020_winter_day_E_TRANS_2015) <= +inf + 0 <= v_uc_online(B_2025_summer_day_E_LDES_2020) <= +inf + 0 <= v_uc_online(B_2025_winter_day_E_LDES_2025) <= +inf + 0 <= v_uc_online(B_2020_winter_day_E_BATT_2020) <= +inf + 0 <= v_uc_online(B_2020_winter_night_E_BATT_2020) <= +inf + 0 <= v_uc_online(A_2020_winter_night_NGCC_2015) <= +inf + 0 <= v_uc_online(A_2025_summer_night_NGCC_2025) <= +inf + 0 <= v_uc_online(B_2025_winter_night_E_BATT_2020) <= +inf + 0 <= v_uc_online(B_2025_winter_night_E_LDES_2025) <= +inf + 0 <= v_uc_online(A_B_2025_summer_day_E_TRANS_2015) <= +inf + 0 <= v_uc_online(A_2020_winter_day_NGCC_2020) <= +inf + 0 <= v_uc_online(A_2025_winter_day_NGCC_2025) <= +inf + 0 <= v_uc_online(A_2025_summer_day_NGCC_2020) <= +inf + 0 <= v_uc_online(A_2020_summer_night_NGCC_2015) <= +inf + 0 <= v_uc_online(B_A_2020_summer_night_E_TRANS_2015) <= +inf + 0 <= v_uc_online(B_2025_winter_day_E_BATT_2025) <= +inf + 0 <= v_uc_online(A_B_2020_summer_night_E_TRANS_2015) <= +inf + 0 <= v_uc_online(B_A_2025_summer_day_E_TRANS_2015) <= +inf + 0 <= v_uc_online(A_2025_winter_night_NGCC_2025) <= +inf + 0 <= v_uc_online(B_2025_summer_night_E_LDES_2025) <= +inf + 0 <= v_curtailment(A_2025_winter_night_ethos_SOLPV_2025_ELC) <= +inf + 0 <= v_curtailment(A_2020_winter_day_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_curtailment(A_2020_summer_night_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_curtailment(A_2025_winter_night_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_curtailment(A_2025_summer_night_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_curtailment(A_2025_summer_day_ethos_SOLPV_2025_ELC) <= +inf + 0 <= v_curtailment(A_2020_summer_night_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_curtailment(A_2025_summer_day_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_curtailment(A_2020_summer_day_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_curtailment(A_2020_winter_day_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_curtailment(A_2025_summer_night_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_curtailment(A_2025_winter_day_ethos_SOLPV_2025_ELC) <= +inf + 0 <= v_curtailment(A_2025_summer_day_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_curtailment(A_2025_winter_night_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_curtailment(A_2020_summer_day_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_curtailment(A_2020_winter_night_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_curtailment(A_2025_winter_day_ethos_SOLPV_2020_ELC) <= +inf + 0 <= v_curtailment(A_2025_summer_night_ethos_SOLPV_2025_ELC) <= +inf + 0 <= v_curtailment(A_2020_winter_night_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_curtailment(A_2025_winter_day_ethos_SOLPV_2015_ELC) <= +inf + 0 <= v_flow_out_annual(B_2025_ELC_HEAT_SYS_2025_HEAT) <= +inf + 0 <= v_flow_out_annual(B_2025_ELC_HEAT_SYS_2020_HEAT) <= +inf + 0 <= v_flow_out_annual(C_2025_ethos_ANN_IMP_2020_ELC_C) <= +inf + 0 <= v_flow_out_annual(C_2020_ethos_ANN_IMP_2020_ELC_C) <= +inf + 0 <= v_flow_out_annual(A_2025_ELC_HEAT_SYS_2025_HEAT) <= +inf + 0 <= v_flow_out_annual(A_2025_ELC_HEAT_SYS_2020_HEAT) <= +inf + 0 <= v_capacity_available_by_period_and_tech(A_2020_E_LDES) <= +inf + 0 <= v_capacity_available_by_period_and_tech(A_2020_SOLPV) <= +inf + 0 <= v_capacity_available_by_period_and_tech(C_B_2025_E_TRANS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(B_2025_NGCC) <= +inf + 0 <= v_capacity_available_by_period_and_tech(C_A_2020_E_TRANS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(A_B_2025_E_TRANS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(A_2020_HEAT_SYS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(B_2025_E_BATT) <= +inf + 0 <= v_capacity_available_by_period_and_tech(C_2020_ANN_IMP) <= +inf + 0 <= v_capacity_available_by_period_and_tech(C_B_2020_E_TRANS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(B_2020_NGCC) <= +inf + 0 <= v_capacity_available_by_period_and_tech(B_2025_E_LDES) <= +inf + 0 <= v_capacity_available_by_period_and_tech(A_C_2025_E_TRANS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(A_B_2020_E_TRANS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(B_2020_E_BATT) <= +inf + 0 <= v_capacity_available_by_period_and_tech(B_2025_HEAT_SYS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(A_2025_NGCC) <= +inf + 0 <= v_capacity_available_by_period_and_tech(B_C_2025_E_TRANS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(B_A_2025_E_TRANS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(A_2025_E_BATT) <= +inf + 0 <= v_capacity_available_by_period_and_tech(B_2020_E_LDES) <= +inf + 0 <= v_capacity_available_by_period_and_tech(A_C_2020_E_TRANS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(C_2025_HEAT_ANN) <= +inf + 0 <= v_capacity_available_by_period_and_tech(B_2020_HEAT_SYS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(A_2025_E_LDES) <= +inf + 0 <= v_capacity_available_by_period_and_tech(A_2025_SOLPV) <= +inf + 0 <= v_capacity_available_by_period_and_tech(A_2020_NGCC) <= +inf + 0 <= v_capacity_available_by_period_and_tech(B_C_2020_E_TRANS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(B_A_2020_E_TRANS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(C_A_2025_E_TRANS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(A_2020_E_BATT) <= +inf + 0 <= v_capacity_available_by_period_and_tech(A_2025_HEAT_SYS) <= +inf + 0 <= v_capacity_available_by_period_and_tech(C_2020_HEAT_ANN) <= +inf + 0 <= v_capacity_available_by_period_and_tech(C_2025_ANN_IMP) <= +inf + 0 <= v_new_capacity(A_NGCC_2020) <= +inf + 0 <= v_new_capacity(A_E_BATT_2025) <= +inf + 0 <= v_new_capacity(A_HEAT_SYS_2025) <= +inf + 0 <= v_new_capacity(B_E_BATT_2020) <= +inf + 0 <= v_new_capacity(B_E_LDES_2025) <= +inf + 0 <= v_new_capacity(A_E_LDES_2020) <= +inf + 0 <= v_new_capacity(A_NGCC_2025) <= +inf + 0 <= v_new_capacity(A_SOLPV_2020) <= +inf + 0 <= v_new_capacity(B_HEAT_SYS_2020) <= +inf + 0 <= v_new_capacity(B_E_BATT_2025) <= +inf + 0 <= v_new_capacity(B_NGCC_2020) <= +inf + 0 <= v_new_capacity(A_E_LDES_2025) <= +inf + 0 <= v_new_capacity(A_SOLPV_2025) <= +inf + 0 <= v_new_capacity(B_HEAT_SYS_2025) <= +inf + 0 <= v_new_capacity(A_E_BATT_2020) <= +inf + 0 <= v_new_capacity(A_HEAT_SYS_2020) <= +inf + 0 <= v_new_capacity(B_E_LDES_2020) <= +inf + 0 <= v_new_capacity(B_NGCC_2025) <= +inf + 0 <= v_new_capacity(C_HEAT_ANN_2020) <= +inf + 0 <= v_new_capacity(C_ANN_IMP_2020) <= +inf + 0 <= v_flow_in(A_2020_winter_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_in(B_2025_summer_day_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_in(A_2020_summer_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_in(A_2025_summer_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(B_2025_summer_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(A_2020_winter_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(B_2025_winter_night_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_in(B_2020_summer_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(A_2025_summer_night_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_in(B_2025_summer_day_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_in(A_2025_winter_day_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_in(A_2025_summer_day_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_in(B_2025_summer_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(B_2020_summer_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_in(A_2025_winter_night_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_in(A_2025_winter_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_in(B_2025_winter_day_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_in(A_2020_winter_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_in(B_2025_summer_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_in(A_2025_winter_day_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_in(B_2020_winter_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_in(A_2025_winter_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_in(A_2025_summer_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_in(A_2025_summer_night_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_in(B_2025_winter_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_in(A_2025_summer_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(B_2025_summer_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_in(A_2020_summer_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(A_2025_winter_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(B_2025_winter_night_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_in(B_2020_summer_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_in(B_2020_summer_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(B_2020_winter_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(A_2020_winter_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(B_2025_winter_day_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_in(B_2025_winter_night_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(A_2025_summer_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_in(A_2020_summer_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(A_2025_summer_day_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_in(B_2025_winter_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(B_2020_winter_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_in(B_2025_summer_night_ELC_E_BATT_2025_ELC) <= +inf + 0 <= v_flow_in(A_2025_winter_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(B_2020_winter_day_ELC_E_BATT_2020_ELC) <= +inf + 0 <= v_flow_in(A_2020_summer_night_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_flow_in(A_2025_winter_night_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_in(B_2025_summer_night_ELC_E_LDES_2025_ELC) <= +inf + 0 <= v_flow_in(B_2025_winter_day_ELC_E_LDES_2020_ELC) <= +inf + 0 <= v_storage_level(A_2020_summer_day_E_BATT_2020) <= +inf + 0 <= v_storage_level(A_2025_summer_day_E_LDES_2020) <= +inf + 0 <= v_storage_level(B_2025_summer_day_E_LDES_2025) <= +inf + 0 <= v_storage_level(B_2025_summer_night_E_BATT_2020) <= +inf + 0 <= v_storage_level(A_2025_summer_night_E_BATT_2020) <= +inf + 0 <= v_storage_level(A_2025_summer_night_E_LDES_2025) <= +inf + 0 <= v_storage_level(A_2025_winter_day_E_BATT_2020) <= +inf + 0 <= v_storage_level(B_2025_winter_night_E_BATT_2025) <= +inf + 0 <= v_storage_level(B_2025_summer_day_E_BATT_2020) <= +inf + 0 <= v_storage_level(A_2025_winter_night_E_BATT_2020) <= +inf + 0 <= v_storage_level(B_2020_summer_day_E_LDES_2020) <= +inf + 0 <= v_storage_level(A_2025_winter_night_E_LDES_2025) <= +inf + 0 <= v_storage_level(B_2020_winter_night_E_LDES_2020) <= +inf + 0 <= v_storage_level(A_2020_winter_day_E_LDES_2020) <= +inf + 0 <= v_storage_level(B_2020_summer_night_E_LDES_2020) <= +inf + 0 <= v_storage_level(B_2020_winter_day_E_LDES_2020) <= +inf + 0 <= v_storage_level(B_2025_winter_day_E_LDES_2020) <= +inf + 0 <= v_storage_level(A_2025_summer_day_E_LDES_2025) <= +inf + 0 <= v_storage_level(A_2020_winter_night_E_LDES_2020) <= +inf + 0 <= v_storage_level(B_2025_summer_night_E_BATT_2025) <= +inf + 0 <= v_storage_level(A_2025_summer_night_E_BATT_2025) <= +inf + 0 <= v_storage_level(A_2025_winter_day_E_BATT_2025) <= +inf + 0 <= v_storage_level(B_2025_winter_night_E_LDES_2020) <= +inf + 0 <= v_storage_level(A_2025_summer_day_E_BATT_2020) <= +inf + 0 <= v_storage_level(B_2025_summer_day_E_BATT_2025) <= +inf + 0 <= v_storage_level(B_2025_winter_day_E_BATT_2020) <= +inf + 0 <= v_storage_level(B_2020_summer_day_E_BATT_2020) <= +inf + 0 <= v_storage_level(A_2025_winter_night_E_BATT_2025) <= +inf + 0 <= v_storage_level(A_2020_summer_night_E_LDES_2020) <= +inf + 0 <= v_storage_level(B_2020_summer_night_E_BATT_2020) <= +inf + 0 <= v_storage_level(B_2025_summer_night_E_LDES_2020) <= +inf + 0 <= v_storage_level(A_2020_winter_day_E_BATT_2020) <= +inf + 0 <= v_storage_level(A_2025_winter_day_E_LDES_2020) <= +inf + 0 <= v_storage_level(B_2025_summer_day_E_LDES_2020) <= +inf + 0 <= v_storage_level(B_2025_winter_day_E_LDES_2025) <= +inf + 0 <= v_storage_level(B_2020_winter_day_E_BATT_2020) <= +inf + 0 <= v_storage_level(A_2020_summer_day_E_LDES_2020) <= +inf + 0 <= v_storage_level(A_2025_summer_night_E_LDES_2020) <= +inf + 0 <= v_storage_level(B_2025_summer_night_E_LDES_2025) <= +inf + 0 <= v_storage_level(B_2020_winter_night_E_BATT_2020) <= +inf + 0 <= v_storage_level(A_2020_winter_night_E_BATT_2020) <= +inf + 0 <= v_storage_level(B_2025_winter_night_E_BATT_2020) <= +inf + 0 <= v_storage_level(B_2025_winter_night_E_LDES_2025) <= +inf + 0 <= v_storage_level(A_2025_summer_day_E_BATT_2025) <= +inf + 0 <= v_storage_level(B_2025_winter_day_E_BATT_2025) <= +inf + 0 <= v_storage_level(A_2025_winter_night_E_LDES_2020) <= +inf + 0 <= v_storage_level(A_2020_summer_night_E_BATT_2020) <= +inf + 0 <= v_storage_level(A_2025_winter_day_E_LDES_2025) <= +inf + 0 <= v_storage_init(B_2025_winter_E_BATT_2025) <= +inf + 0 <= v_storage_init(A_2025_summer_E_BATT_2020) <= +inf + 0 <= v_storage_init(B_2025_summer_E_BATT_2025) <= +inf + 0 <= v_storage_init(A_2025_summer_E_BATT_2025) <= +inf + 0 <= v_storage_init(B_2020_summer_E_BATT_2020) <= +inf + 0 <= v_storage_init(B_2020_winter_E_BATT_2020) <= +inf + 0 <= v_storage_init(A_2020_winter_E_BATT_2020) <= +inf + 0 <= v_storage_init(A_2025_winter_E_BATT_2020) <= +inf + 0 <= v_storage_init(B_2025_winter_E_BATT_2020) <= +inf + 0 <= v_storage_init(B_2025_summer_E_BATT_2020) <= +inf + 0 <= v_storage_init(A_2020_summer_E_BATT_2020) <= +inf + 0 <= v_storage_init(A_2025_winter_E_BATT_2025) <= +inf + 0 <= v_seasonal_storage_level(A_2025_summer_E_LDES_2020) <= +inf + 0 <= v_seasonal_storage_level(A_2020_summer_E_LDES_2020) <= +inf + 0 <= v_seasonal_storage_level(B_2020_summer_E_LDES_2020) <= +inf + 0 <= v_seasonal_storage_level(A_2025_winter_E_LDES_2020) <= +inf + 0 <= v_seasonal_storage_level(B_2025_winter_E_LDES_2020) <= +inf + 0 <= v_seasonal_storage_level(B_2025_summer_E_LDES_2025) <= +inf + 0 <= v_seasonal_storage_level(B_2020_winter_E_LDES_2020) <= +inf + 0 <= v_seasonal_storage_level(A_2025_summer_E_LDES_2025) <= +inf + 0 <= v_seasonal_storage_level(A_2020_winter_E_LDES_2020) <= +inf + 0 <= v_seasonal_storage_level(A_2025_winter_E_LDES_2025) <= +inf + 0 <= v_seasonal_storage_level(B_2025_winter_E_LDES_2025) <= +inf + 0 <= v_seasonal_storage_level(B_2025_summer_E_LDES_2020) <= +inf + 0 <= v_uc_started(A_B_2020_winter_day_E_TRANS_2015) <= +inf + 0 <= v_uc_started(A_2020_summer_day_NGCC_2015) <= +inf + 0 <= v_uc_started(A_2025_summer_night_NGCC_2015) <= +inf + 0 <= v_uc_started(B_2025_summer_day_E_LDES_2025) <= +inf + 0 <= v_uc_started(B_A_2025_winter_day_E_TRANS_2015) <= +inf + 0 <= v_uc_started(A_2020_winter_night_NGCC_2020) <= +inf + 0 <= v_uc_started(B_2025_summer_night_E_BATT_2020) <= +inf + 0 <= v_uc_started(A_2025_winter_day_NGCC_2015) <= +inf + 0 <= v_uc_started(B_2025_winter_night_E_BATT_2025) <= +inf + 0 <= v_uc_started(B_2025_summer_day_E_BATT_2020) <= +inf + 0 <= v_uc_started(A_2025_summer_day_NGCC_2025) <= +inf + 0 <= v_uc_started(A_2025_winter_night_NGCC_2015) <= +inf + 0 <= v_uc_started(B_A_2020_winter_night_E_TRANS_2015) <= +inf + 0 <= v_uc_started(B_2020_summer_day_E_LDES_2020) <= +inf + 0 <= v_uc_started(A_2020_summer_night_NGCC_2020) <= +inf + 0 <= v_uc_started(B_2020_winter_night_E_LDES_2020) <= +inf + 0 <= v_uc_started(A_B_2025_summer_night_E_TRANS_2015) <= +inf + 0 <= v_uc_started(B_2020_summer_night_E_LDES_2020) <= +inf + 0 <= v_uc_started(A_B_2020_summer_day_E_TRANS_2015) <= +inf + 0 <= v_uc_started(B_2020_winter_day_E_LDES_2020) <= +inf + 0 <= v_uc_started(B_2025_winter_day_E_LDES_2020) <= +inf + 0 <= v_uc_started(A_2020_summer_day_NGCC_2020) <= +inf + 0 <= v_uc_started(A_2025_summer_night_NGCC_2020) <= +inf + 0 <= v_uc_started(B_2025_summer_night_E_BATT_2025) <= +inf + 0 <= v_uc_started(B_A_2020_summer_day_E_TRANS_2015) <= +inf + 0 <= v_uc_started(A_2025_winter_day_NGCC_2020) <= +inf + 0 <= v_uc_started(A_2025_summer_day_NGCC_2015) <= +inf + 0 <= v_uc_started(A_2020_winter_day_NGCC_2015) <= +inf + 0 <= v_uc_started(B_2025_winter_night_E_LDES_2020) <= +inf + 0 <= v_uc_started(A_B_2025_winter_day_E_TRANS_2015) <= +inf + 0 <= v_uc_started(B_A_2025_summer_night_E_TRANS_2015) <= +inf + 0 <= v_uc_started(B_A_2025_winter_night_E_TRANS_2015) <= +inf + 0 <= v_uc_started(B_2020_summer_day_E_BATT_2020) <= +inf + 0 <= v_uc_started(B_2025_summer_day_E_BATT_2025) <= +inf + 0 <= v_uc_started(B_2025_winter_day_E_BATT_2020) <= +inf + 0 <= v_uc_started(A_2025_winter_night_NGCC_2020) <= +inf + 0 <= v_uc_started(A_B_2020_winter_night_E_TRANS_2015) <= +inf + 0 <= v_uc_started(B_2020_summer_night_E_BATT_2020) <= +inf + 0 <= v_uc_started(B_2025_summer_night_E_LDES_2020) <= +inf + 0 <= v_uc_started(A_B_2025_winter_night_E_TRANS_2015) <= +inf + 0 <= v_uc_started(B_A_2020_winter_day_E_TRANS_2015) <= +inf + 0 <= v_uc_started(B_2025_summer_day_E_LDES_2020) <= +inf + 0 <= v_uc_started(B_2025_winter_day_E_LDES_2025) <= +inf + 0 <= v_uc_started(B_2020_winter_day_E_BATT_2020) <= +inf + 0 <= v_uc_started(B_2020_winter_night_E_BATT_2020) <= +inf + 0 <= v_uc_started(A_2020_winter_night_NGCC_2015) <= +inf + 0 <= v_uc_started(A_2025_summer_night_NGCC_2025) <= +inf + 0 <= v_uc_started(B_2025_winter_night_E_BATT_2020) <= +inf + 0 <= v_uc_started(B_2025_winter_night_E_LDES_2025) <= +inf + 0 <= v_uc_started(A_B_2025_summer_day_E_TRANS_2015) <= +inf + 0 <= v_uc_started(A_2020_winter_day_NGCC_2020) <= +inf + 0 <= v_uc_started(A_2025_winter_day_NGCC_2025) <= +inf + 0 <= v_uc_started(A_2025_summer_day_NGCC_2020) <= +inf + 0 <= v_uc_started(A_2020_summer_night_NGCC_2015) <= +inf + 0 <= v_uc_started(B_A_2020_summer_night_E_TRANS_2015) <= +inf + 0 <= v_uc_started(B_2025_winter_day_E_BATT_2025) <= +inf + 0 <= v_uc_started(A_B_2020_summer_night_E_TRANS_2015) <= +inf + 0 <= v_uc_started(B_A_2025_summer_day_E_TRANS_2015) <= +inf + 0 <= v_uc_started(A_2025_winter_night_NGCC_2025) <= +inf + 0 <= v_uc_started(B_2025_summer_night_E_LDES_2025) <= +inf + 0 <= v_uc_stopped(A_B_2020_winter_day_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(A_2020_summer_day_NGCC_2015) <= +inf + 0 <= v_uc_stopped(A_2025_summer_night_NGCC_2015) <= +inf + 0 <= v_uc_stopped(B_2025_summer_day_E_LDES_2025) <= +inf + 0 <= v_uc_stopped(B_A_2025_winter_day_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(A_2020_winter_night_NGCC_2020) <= +inf + 0 <= v_uc_stopped(B_2025_summer_night_E_BATT_2020) <= +inf + 0 <= v_uc_stopped(A_2025_winter_day_NGCC_2015) <= +inf + 0 <= v_uc_stopped(B_2025_winter_night_E_BATT_2025) <= +inf + 0 <= v_uc_stopped(B_2025_summer_day_E_BATT_2020) <= +inf + 0 <= v_uc_stopped(A_2025_summer_day_NGCC_2025) <= +inf + 0 <= v_uc_stopped(A_2025_winter_night_NGCC_2015) <= +inf + 0 <= v_uc_stopped(B_A_2020_winter_night_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(B_2020_summer_day_E_LDES_2020) <= +inf + 0 <= v_uc_stopped(A_2020_summer_night_NGCC_2020) <= +inf + 0 <= v_uc_stopped(B_2020_winter_night_E_LDES_2020) <= +inf + 0 <= v_uc_stopped(A_B_2025_summer_night_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(B_2020_summer_night_E_LDES_2020) <= +inf + 0 <= v_uc_stopped(A_B_2020_summer_day_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(B_2020_winter_day_E_LDES_2020) <= +inf + 0 <= v_uc_stopped(B_2025_winter_day_E_LDES_2020) <= +inf + 0 <= v_uc_stopped(A_2020_summer_day_NGCC_2020) <= +inf + 0 <= v_uc_stopped(A_2025_summer_night_NGCC_2020) <= +inf + 0 <= v_uc_stopped(B_2025_summer_night_E_BATT_2025) <= +inf + 0 <= v_uc_stopped(B_A_2020_summer_day_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(A_2025_winter_day_NGCC_2020) <= +inf + 0 <= v_uc_stopped(A_2025_summer_day_NGCC_2015) <= +inf + 0 <= v_uc_stopped(A_2020_winter_day_NGCC_2015) <= +inf + 0 <= v_uc_stopped(B_2025_winter_night_E_LDES_2020) <= +inf + 0 <= v_uc_stopped(A_B_2025_winter_day_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(B_A_2025_summer_night_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(B_A_2025_winter_night_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(B_2020_summer_day_E_BATT_2020) <= +inf + 0 <= v_uc_stopped(B_2025_summer_day_E_BATT_2025) <= +inf + 0 <= v_uc_stopped(B_2025_winter_day_E_BATT_2020) <= +inf + 0 <= v_uc_stopped(A_2025_winter_night_NGCC_2020) <= +inf + 0 <= v_uc_stopped(A_B_2020_winter_night_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(B_2020_summer_night_E_BATT_2020) <= +inf + 0 <= v_uc_stopped(B_2025_summer_night_E_LDES_2020) <= +inf + 0 <= v_uc_stopped(A_B_2025_winter_night_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(B_A_2020_winter_day_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(B_2025_summer_day_E_LDES_2020) <= +inf + 0 <= v_uc_stopped(B_2025_winter_day_E_LDES_2025) <= +inf + 0 <= v_uc_stopped(B_2020_winter_day_E_BATT_2020) <= +inf + 0 <= v_uc_stopped(B_2020_winter_night_E_BATT_2020) <= +inf + 0 <= v_uc_stopped(A_2020_winter_night_NGCC_2015) <= +inf + 0 <= v_uc_stopped(A_2025_summer_night_NGCC_2025) <= +inf + 0 <= v_uc_stopped(B_2025_winter_night_E_BATT_2020) <= +inf + 0 <= v_uc_stopped(B_2025_winter_night_E_LDES_2025) <= +inf + 0 <= v_uc_stopped(A_B_2025_summer_day_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(A_2020_winter_day_NGCC_2020) <= +inf + 0 <= v_uc_stopped(A_2025_winter_day_NGCC_2025) <= +inf + 0 <= v_uc_stopped(A_2025_summer_day_NGCC_2020) <= +inf + 0 <= v_uc_stopped(A_2020_summer_night_NGCC_2015) <= +inf + 0 <= v_uc_stopped(B_A_2020_summer_night_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(B_2025_winter_day_E_BATT_2025) <= +inf + 0 <= v_uc_stopped(A_B_2020_summer_night_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(B_A_2025_summer_day_E_TRANS_2015) <= +inf + 0 <= v_uc_stopped(A_2025_winter_night_NGCC_2025) <= +inf + 0 <= v_uc_stopped(B_2025_summer_night_E_LDES_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_winter_day_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_B_2020_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_night_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_winter_night_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_B_C_2020_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_winter_night_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2020_summer_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_summer_night_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_summer_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_summer_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_C_A_2025_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_night_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_summer_day_E_LDES_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_B_A_2025_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_B_2025_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_winter_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_A_2020_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_day_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_B_2020_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_winter_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2020_winter_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_winter_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_winter_night_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_winter_day_E_LDES_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_night_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2020_winter_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_A_B_2025_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_C_2025_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_C_2025_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_summer_day_NGCC_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_winter_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_day_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_summer_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_winter_night_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_C_2025_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_summer_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_night_NGCC_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_night_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_summer_day_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_winter_night_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_day_SOLPV_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_C_A_2020_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_day_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_night_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_B_A_2020_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_summer_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_winter_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_B_2025_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_C_B_2020_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_summer_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_C_B_2025_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_winter_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2020_summer_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_day_SOLPV_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_winter_day_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2020_summer_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_B_A_2025_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_summer_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_summer_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_winter_night_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_C_2020_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_summer_day_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_night_NGCC_2025) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_winter_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_C_A_2020_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_summer_day_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_C_A_2025_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_day_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_B_A_2025_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_winter_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2020_winter_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_summer_night_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_winter_day_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_night_E_LDES_2025) <= +inf + -inf <= v_orm_online_credit(reg_B_C_B_2020_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_C_2020_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_A_B_2020_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_B_2020_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_summer_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_day_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_winter_day_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_day_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_summer_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_B_2025_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_C_2025_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_day_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_day_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_B_C_2020_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_A_B_2020_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_winter_night_NGCC_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_winter_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_B_A_2025_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_day_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_summer_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_night_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_C_2020_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_winter_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2020_summer_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_day_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_summer_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_night_E_LDES_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_summer_night_NGCC_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_night_SOLPV_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_summer_night_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_C_B_2025_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_summer_night_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_C_A_2025_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_winter_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_B_2020_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_C_2020_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_winter_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_A_2020_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_C_2020_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_day_NGCC_2025) <= +inf + -inf <= v_orm_online_credit(reg_B_B_A_2025_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_summer_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_night_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_B_2020_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_B_A_2025_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_day_NGCC_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_B_2025_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_summer_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_summer_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_C_2020_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2020_winter_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_winter_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_day_E_LDES_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_winter_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_day_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_summer_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_day_E_LDES_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_day_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_winter_day_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_summer_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_night_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_B_A_2020_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_winter_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_summer_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_night_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_summer_night_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_C_B_2025_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_summer_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_A_B_2020_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2020_summer_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_summer_night_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_A_2025_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_night_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_winter_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_C_2025_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_C_2025_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_day_NGCC_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_C_A_2025_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_C_A_2020_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_C_2020_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_A_2020_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2020_winter_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_A_2025_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_day_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_day_E_LDES_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_day_NGCC_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_winter_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_C_2025_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_winter_night_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_summer_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_summer_night_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_C_2025_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_day_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_winter_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_B_2025_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_winter_day_NGCC_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_summer_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_C_2025_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_summer_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_A_B_2025_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_summer_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_winter_night_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_night_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_night_NGCC_2025) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2020_summer_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_summer_day_NGCC_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_day_E_LDES_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_winter_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_summer_night_E_LDES_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_winter_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_summer_day_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_night_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_A_C_2025_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_summer_day_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_night_E_LDES_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_day_SOLPV_2025) <= +inf + -inf <= v_orm_online_credit(reg_B_B_C_2020_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_C_B_2020_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_C_B_2025_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_C_2020_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_winter_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_B_2020_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_B_A_2020_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_night_SOLPV_2025) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2020_winter_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_A_B_2025_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_C_2020_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_C_2025_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_winter_day_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_day_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_summer_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_B_A_2020_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_summer_night_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_C_A_2020_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_C_2025_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_winter_night_NGCC_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_B_A_2020_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_winter_day_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_summer_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_B_2020_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_winter_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_night_SOLPV_2025) <= +inf + -inf <= v_orm_online_credit(reg_B_A_B_2020_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_night_NGCC_2025) <= +inf + -inf <= v_orm_online_credit(reg_B_B_C_2025_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_B_2025_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_summer_day_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_winter_day_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_summer_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_B_A_2020_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_winter_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_day_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_summer_night_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_C_2025_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_summer_day_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_winter_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_winter_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_summer_night_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_night_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_winter_night_E_LDES_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_night_E_LDES_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(reg_B_A_B_2025_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_C_2020_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_A_2025_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_summer_night_NGCC_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_summer_day_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_winter_night_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_summer_day_E_LDES_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_B_2020_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_A_2025_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_night_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_winter_day_SOLPV_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_winter_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_A_2020_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_winter_day_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(reg_B_C_B_2020_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_summer_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_B_2025_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_C_2020_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_C_2025_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2020_winter_night_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_C_2020_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_winter_night_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_winter_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_C_2025_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_day_SOLPV_2025) <= +inf + -inf <= v_orm_online_credit(reg_B_B_A_2025_summer_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2020_summer_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_C_2020_winter_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_winter_night_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_winter_night_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2020_summer_day_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(spin_A_B_A_2025_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_2025_summer_night_SOLPV_2025) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_summer_day_E_BATT_2025) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_A_2020_winter_night_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_summer_night_SOLPV_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(spin_A_A_B_2025_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_A_2025_winter_night_NGCC_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_summer_day_NGCC_2015) <= +inf + -inf <= v_orm_online_credit(reg_B_B_2025_winter_day_E_BATT_2020) <= +inf + -inf <= v_orm_online_credit(spin_AB_C_A_2020_summer_day_E_TRANS_2015) <= +inf + -inf <= v_orm_online_credit(spin_AB_B_2025_winter_day_NGCC_2025) <= +inf +end diff --git a/tests/testing_data/reserve_margins.sql b/tests/testing_data/reserve_margins.sql new file mode 100644 index 000000000..e4cb14ecd --- /dev/null +++ b/tests/testing_data/reserve_margins.sql @@ -0,0 +1,218 @@ +REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); +REPLACE INTO "metadata" VALUES('DB_MINOR',1,''); +REPLACE INTO "metadata_real" VALUES('global_discount_rate',0.05,''); +REPLACE INTO "metadata_real" VALUES('default_loan_rate',0.05,''); +REPLACE INTO "time_period" VALUES(0,2015,'e'); +REPLACE INTO "time_period" VALUES(1,2020,'f'); +REPLACE INTO "time_period" VALUES(2,2025,'f'); +REPLACE INTO "time_period" VALUES(3,2030,'f'); +REPLACE INTO "time_period_type" VALUES('e','existing'); +REPLACE INTO "time_period_type" VALUES('f','future'); +REPLACE INTO "time_season" VALUES(0,'summer',0.5,NULL); +REPLACE INTO "time_season" VALUES(1,'winter',0.5,NULL); +REPLACE INTO "time_of_day" VALUES(0,'day',12,NULL); +REPLACE INTO "time_of_day" VALUES(1,'night',12,NULL); +REPLACE INTO "region" VALUES('A',NULL); +REPLACE INTO "region" VALUES('B',NULL); +REPLACE INTO "region" VALUES('C',NULL); +REPLACE INTO "commodity_type" VALUES('s','source'); +REPLACE INTO "commodity_type" VALUES('a','annual'); +REPLACE INTO "commodity_type" VALUES('p','physical'); +REPLACE INTO "commodity_type" VALUES('d','demand'); +REPLACE INTO "commodity_type" VALUES('e','emissions'); +REPLACE INTO "commodity_type" VALUES('w','waste'); +REPLACE INTO "commodity_type" VALUES('wa','waste annual'); +REPLACE INTO "commodity_type" VALUES('wp','waste physical'); +REPLACE INTO "commodity" VALUES('ethos','s',NULL,NULL); +REPLACE INTO "commodity" VALUES('NG','p',NULL,NULL); +REPLACE INTO "commodity" VALUES('ELC','p',NULL,NULL); +REPLACE INTO "commodity" VALUES('ELC_C','a',NULL,NULL); +REPLACE INTO "commodity" VALUES('HEAT','d',NULL,NULL); +REPLACE INTO "commodity" VALUES('HEAT_C','d',NULL,NULL); +REPLACE INTO "technology_type" VALUES('p','production'); +REPLACE INTO "technology_type" VALUES('pb','baseload production'); +REPLACE INTO "technology_type" VALUES('ps','storage production'); +REPLACE INTO "technology" VALUES('NGCC','p',NULL,NULL,NULL,0,0,0,0,0,0,0,'combined-cycle gas'); +REPLACE INTO "technology" VALUES('SOLPV','p',NULL,NULL,NULL,0,0,1,0,0,0,0,'solar photovoltaic'); +REPLACE INTO "technology" VALUES('E_BATT','ps',NULL,NULL,NULL,0,0,0,0,0,0,0,'grid battery'); +REPLACE INTO "technology" VALUES('ANN_IMP','p',NULL,NULL,NULL,0,1,0,0,0,0,0,'capacitated annual import'); +REPLACE INTO "technology" VALUES('HEAT_SYS','p',NULL,NULL,NULL,0,0,0,0,0,0,0,'electric heater'); +REPLACE INTO "technology" VALUES('HEAT_ANN','p',NULL,NULL,NULL,0,1,0,0,0,0,0,'annual electric heater'); +REPLACE INTO "technology" VALUES('IMP_NG','p',NULL,NULL,NULL,1,0,0,0,0,0,0,'unlimited NG import'); +REPLACE INTO "technology" VALUES('E_TRANS','p',NULL,NULL,NULL,0,0,0,0,0,1,0,'interregional transmission'); +REPLACE INTO "technology" VALUES('E_LDES','ps',NULL,NULL,NULL,0,0,0,0,0,0,1,'seasonal/long-duration storage'); +REPLACE INTO "tech_group" VALUES('elec_A','generators + storage + load in A'); +REPLACE INTO "tech_group" VALUES('elec_AB','generators + storage + exchange + load across A and B'); +REPLACE INTO "tech_group" VALUES('elec_B','generators + storage + exchange + load in B'); +REPLACE INTO "tech_group" VALUES('elec_C_ann','annual import + load in C'); +REPLACE INTO "tech_group_member" VALUES('elec_A','NGCC'); +REPLACE INTO "tech_group_member" VALUES('elec_A','SOLPV'); +REPLACE INTO "tech_group_member" VALUES('elec_A','E_BATT'); +REPLACE INTO "tech_group_member" VALUES('elec_A','E_LDES'); +REPLACE INTO "tech_group_member" VALUES('elec_A','HEAT_SYS'); +REPLACE INTO "tech_group_member" VALUES('elec_A','E_TRANS'); +REPLACE INTO "tech_group_member" VALUES('elec_AB','NGCC'); +REPLACE INTO "tech_group_member" VALUES('elec_AB','SOLPV'); +REPLACE INTO "tech_group_member" VALUES('elec_AB','E_BATT'); +REPLACE INTO "tech_group_member" VALUES('elec_AB','E_LDES'); +REPLACE INTO "tech_group_member" VALUES('elec_AB','HEAT_SYS'); +REPLACE INTO "tech_group_member" VALUES('elec_AB','E_TRANS'); +REPLACE INTO "tech_group_member" VALUES('elec_B','NGCC'); +REPLACE INTO "tech_group_member" VALUES('elec_B','E_BATT'); +REPLACE INTO "tech_group_member" VALUES('elec_B','E_TRANS'); +REPLACE INTO "tech_group_member" VALUES('elec_C_ann','ANN_IMP'); +REPLACE INTO "tech_group_member" VALUES('elec_C_ann','HEAT_ANN'); +REPLACE INTO "efficiency" VALUES('A','ethos','IMP_NG',2020,'NG',1.0,NULL,NULL); +REPLACE INTO "efficiency" VALUES('A','NG','NGCC',2015,'ELC',0.55,NULL,NULL); +REPLACE INTO "efficiency" VALUES('A','NG','NGCC',2020,'ELC',0.55,NULL,NULL); +REPLACE INTO "efficiency" VALUES('A','NG','NGCC',2025,'ELC',0.55,NULL,NULL); +REPLACE INTO "efficiency" VALUES('A','ethos','SOLPV',2015,'ELC',1.0,NULL,NULL); +REPLACE INTO "efficiency" VALUES('A','ethos','SOLPV',2020,'ELC',1.0,NULL,NULL); +REPLACE INTO "efficiency" VALUES('A','ethos','SOLPV',2025,'ELC',1.0,NULL,NULL); +REPLACE INTO "efficiency" VALUES('A','ELC','E_BATT',2020,'ELC',0.85,NULL,NULL); +REPLACE INTO "efficiency" VALUES('A','ELC','E_BATT',2025,'ELC',0.85,NULL,NULL); +REPLACE INTO "efficiency" VALUES('A','ELC','E_LDES',2020,'ELC',0.95,NULL,NULL); +REPLACE INTO "efficiency" VALUES('A','ELC','E_LDES',2025,'ELC',0.95,NULL,NULL); +REPLACE INTO "efficiency" VALUES('A','ELC','HEAT_SYS',2020,'HEAT',1.0,NULL,NULL); +REPLACE INTO "efficiency" VALUES('A','ELC','HEAT_SYS',2025,'HEAT',1.0,NULL,NULL); +REPLACE INTO "efficiency" VALUES('B','ethos','IMP_NG',2020,'NG',1.0,NULL,NULL); +REPLACE INTO "efficiency" VALUES('B','NG','NGCC',2015,'ELC',0.55,NULL,NULL); +REPLACE INTO "efficiency" VALUES('B','NG','NGCC',2020,'ELC',0.55,NULL,NULL); +REPLACE INTO "efficiency" VALUES('B','NG','NGCC',2025,'ELC',0.55,NULL,NULL); +REPLACE INTO "efficiency" VALUES('B','ELC','E_BATT',2020,'ELC',0.85,NULL,NULL); +REPLACE INTO "efficiency" VALUES('B','ELC','E_BATT',2025,'ELC',0.85,NULL,NULL); +REPLACE INTO "efficiency" VALUES('B','ELC','E_LDES',2020,'ELC',0.95,NULL,NULL); +REPLACE INTO "efficiency" VALUES('B','ELC','E_LDES',2025,'ELC',0.95,NULL,NULL); +REPLACE INTO "efficiency" VALUES('B','ELC','HEAT_SYS',2020,'HEAT',1.0,NULL,NULL); +REPLACE INTO "efficiency" VALUES('B','ELC','HEAT_SYS',2025,'HEAT',1.0,NULL,NULL); +REPLACE INTO "efficiency" VALUES('C','ethos','ANN_IMP',2020,'ELC_C',1.0,NULL,NULL); +REPLACE INTO "efficiency" VALUES('C','ELC_C','HEAT_ANN',2020,'HEAT_C',1.0,NULL,NULL); +REPLACE INTO "efficiency" VALUES('A-B','ELC','E_TRANS',2015,'ELC',0.95,NULL,NULL); +REPLACE INTO "efficiency" VALUES('B-A','ELC','E_TRANS',2015,'ELC',0.95,NULL,NULL); +REPLACE INTO "efficiency" VALUES('A-C','ELC','E_TRANS',2015,'ELC',0.95,NULL,NULL); +REPLACE INTO "efficiency" VALUES('C-A','ELC','E_TRANS',2015,'ELC',0.95,NULL,NULL); +REPLACE INTO "efficiency" VALUES('B-C','ELC','E_TRANS',2015,'ELC',0.95,NULL,NULL); +REPLACE INTO "efficiency" VALUES('C-B','ELC','E_TRANS',2015,'ELC',0.95,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('A','IMP_NG',1.0,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('A','NGCC',8.76,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('A','SOLPV',8.76,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('A','E_BATT',8.76,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('A','E_LDES',8.76,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('A','HEAT_SYS',1.0,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('B','IMP_NG',1.0,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('B','NGCC',8.76,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('B','E_BATT',8.76,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('B','E_LDES',8.76,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('B','HEAT_SYS',1.0,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('C','ANN_IMP',1.0,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('C','HEAT_ANN',1.0,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('A-B','E_TRANS',8.76,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('B-A','E_TRANS',8.76,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('A-C','E_TRANS',8.76,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('C-A','E_TRANS',8.76,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('B-C','E_TRANS',8.76,NULL,NULL); +REPLACE INTO "capacity_to_activity" VALUES('C-B','E_TRANS',8.76,NULL,NULL); +REPLACE INTO "storage_duration" VALUES('A','E_BATT',4.0,NULL); +REPLACE INTO "storage_duration" VALUES('B','E_BATT',4.0,NULL); +REPLACE INTO "storage_duration" VALUES('A','E_LDES',400.0,NULL); +REPLACE INTO "storage_duration" VALUES('B','E_LDES',400.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('A','summer','day','SOLPV',0.6,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('A','summer','night','SOLPV',0.0,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('A','winter','day','SOLPV',0.3,NULL); +REPLACE INTO "capacity_factor_tech" VALUES('A','winter','night','SOLPV',0.0,NULL); +REPLACE INTO "existing_capacity" VALUES('A','NGCC',2015,0.5,'GW',NULL); +REPLACE INTO "existing_capacity" VALUES('A','SOLPV',2015,0.2,'GW',NULL); +REPLACE INTO "existing_capacity" VALUES('B','NGCC',2015,0.3,'GW',NULL); +REPLACE INTO "existing_capacity" VALUES('A-B','E_TRANS',2015,1.0,'GW',NULL); +REPLACE INTO "existing_capacity" VALUES('B-A','E_TRANS',2015,1.0,'GW',NULL); +REPLACE INTO "existing_capacity" VALUES('A-C','E_TRANS',2015,1.0,'GW',NULL); +REPLACE INTO "existing_capacity" VALUES('C-A','E_TRANS',2015,1.0,'GW',NULL); +REPLACE INTO "existing_capacity" VALUES('B-C','E_TRANS',2015,1.0,'GW',NULL); +REPLACE INTO "existing_capacity" VALUES('C-B','E_TRANS',2015,1.0,'GW',NULL); +REPLACE INTO "lifetime_tech" VALUES('A','IMP_NG',100.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('A','NGCC',30.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('A','SOLPV',25.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('A','E_BATT',15.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('A','E_LDES',25.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('A','HEAT_SYS',20.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('B','IMP_NG',100.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('B','NGCC',30.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('B','E_BATT',15.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('B','E_LDES',25.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('B','HEAT_SYS',20.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('C','ANN_IMP',100.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('C','HEAT_ANN',20.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('A-B','E_TRANS',50.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('B-A','E_TRANS',50.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('C-A','E_TRANS',50.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('A-C','E_TRANS',50.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('B-C','E_TRANS',50.0,NULL,NULL); +REPLACE INTO "lifetime_tech" VALUES('C-B','E_TRANS',50.0,NULL,NULL); +REPLACE INTO "demand" VALUES('A',2020,'HEAT',5.0,NULL,NULL); +REPLACE INTO "demand" VALUES('A',2025,'HEAT',5.5,NULL,NULL); +REPLACE INTO "demand" VALUES('B',2020,'HEAT',3.0,NULL,NULL); +REPLACE INTO "demand" VALUES('B',2025,'HEAT',3.3,NULL,NULL); +REPLACE INTO "demand" VALUES('C',2020,'HEAT_C',1.0,NULL,NULL); +REPLACE INTO "demand" VALUES('C',2025,'HEAT_C',1.1,NULL,NULL); +REPLACE INTO "planning_reserve_margin" VALUES('cap_A','A','NGCC','static',0.15,NULL); +REPLACE INTO "planning_reserve_margin" VALUES('cap_A_derate','A','NGCC','static',0.05,NULL); +REPLACE INTO "planning_reserve_margin" VALUES('cap_AB','A+B','elec_AB','static',0.10,NULL); +REPLACE INTO "planning_reserve_margin" VALUES('cap_C','C','elec_C_ann','static',0.20,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_A','A','NGCC',1.0,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_A_derate','A','NGCC',0.8,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_AB','A','NGCC',1.0,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_AB','B','NGCC',1.0,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_AB','A','SOLPV',0.15,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_AB','A','E_BATT',0.9,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_AB','B','E_BATT',0.9,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_AB','A','HEAT_SYS',0.0,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_AB','B','HEAT_SYS',0.0,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_AB','A-B','E_TRANS',1.0,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_AB','B-A','E_TRANS',0.9,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_AB','A-C','E_TRANS',0.85,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_AB','C-A','E_TRANS',0.95,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_AB','B-C','E_TRANS',0.8,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_AB','C-B','E_TRANS',0.88,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_AB','A','E_LDES',0.5,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_AB','B','E_LDES',0.5,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_C','A-C','E_TRANS',0.85,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_C','C-A','E_TRANS',0.95,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_C','B-C','E_TRANS',0.8,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_C','C-B','E_TRANS',0.88,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_C','C','ANN_IMP',1.0,NULL); +REPLACE INTO "planning_reserve_credit" VALUES('cap_C','C','HEAT_ANN',0.0,NULL); +REPLACE INTO "unit_commitment" VALUES('A','NGCC',0.1,0.3,1.0,0,0,1,NULL,NULL); +REPLACE INTO "unit_commitment" VALUES('B','E_BATT',0.05,0.3,1.0,0,0,1,NULL,NULL); +REPLACE INTO "unit_commitment" VALUES('B','E_LDES',0.02,0.3,1.0,0,0,1,NULL,NULL); +REPLACE INTO "unit_commitment" VALUES('A-B','E_TRANS',0.2,0.3,1.0,0,0,1,NULL,NULL); +REPLACE INTO "unit_commitment" VALUES('B-A','E_TRANS',0.2,0.3,1.0,0,0,1,NULL,NULL); +REPLACE INTO "operating_reserve_margin" VALUES('spin_A','A','elec_A',0.10,1.0,NULL); +REPLACE INTO "operating_reserve_margin" VALUES('reg_B','B','elec_B',0.10,NULL,NULL); +REPLACE INTO "operating_reserve_margin" VALUES('spin_AB','A+B','elec_AB',0.08,2.0,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_A','A','NGCC',0.0,0.5,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_A','A','SOLPV',-0.1,0.05,0.2,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_A','A','E_BATT',0.0,1.0,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_A','A-B','E_TRANS',0.0,0.4,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_A','B-A','E_TRANS',0.0,0.36,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_A','A-C','E_TRANS',0.0,0.34,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_A','C-A','E_TRANS',0.0,0.38,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_A','A','E_LDES',0.0,0.6,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('reg_B','B','NGCC',0.0,0.2,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('reg_B','B','E_BATT',0.0,0.4,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('reg_B','A-B','E_TRANS',0.0,0.3,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('reg_B','B-A','E_TRANS',0.0,0.27,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('reg_B','B-C','E_TRANS',0.0,0.24,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('reg_B','C-B','E_TRANS',0.0,0.26,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_AB','A','NGCC',0.1,0.3,0.5,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_AB','B','NGCC',0.1,0.3,0.5,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_AB','A','SOLPV',-0.1,0.05,0.2,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_AB','A','E_BATT',0.0,0.5,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_AB','B','E_BATT',0.0,0.5,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_AB','A-B','E_TRANS',0.0,0.6,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_AB','B-A','E_TRANS',0.0,0.54,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_AB','A-C','E_TRANS',0.0,0.51,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_AB','C-A','E_TRANS',0.0,0.57,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_AB','B-C','E_TRANS',0.0,0.48,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_AB','C-B','E_TRANS',0.0,0.53,NULL,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_AB','A','E_LDES',0.0,0.4,0.3,NULL); +REPLACE INTO "operating_reserve_credit" VALUES('spin_AB','B','E_LDES',0.0,0.4,0.3,NULL); diff --git a/tests/testing_data/seasonal_storage.sql b/tests/testing_data/seasonal_storage.sql index 19b394b39..55ba285d2 100644 --- a/tests/testing_data/seasonal_storage.sql +++ b/tests/testing_data/seasonal_storage.sql @@ -43,7 +43,7 @@ REPLACE INTO "efficiency" VALUES('region', 'electricity', 'demand', 2000, 'deman REPLACE INTO "limit_storage_level_fraction" VALUES('region','winter','b','seas_stor','e',0.5,NULL); REPLACE INTO "limit_storage_level_fraction" VALUES('region','charge','b','dly_stor','e',0.5,NULL); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); -REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); +REPLACE INTO "metadata" VALUES('DB_MINOR',1,''); REPLACE INTO "metadata_real" VALUES('global_discount_rate',0.05,'Discount Rate for future costs'); REPLACE INTO "metadata_real" VALUES('default_loan_rate',0.05,'Default Loan Rate if not specified in loan_rate table'); REPLACE INTO "operator" VALUES('e','equal to'); @@ -53,10 +53,10 @@ REPLACE INTO "region" VALUES('region',NULL); REPLACE INTO "sector_label" VALUES('electricity',NULL); REPLACE INTO "storage_duration" VALUES('region','dly_stor',4.0,NULL); REPLACE INTO "storage_duration" VALUES('region','seas_stor',8760.0,NULL); -REPLACE INTO "technology" VALUES('generator','p','electricity',NULL,NULL,0,0,0,0,0,0,0,0,NULL); -REPLACE INTO "technology" VALUES('dly_stor','ps','electricity',NULL,NULL,0,0,0,0,0,0,0,0,NULL); -REPLACE INTO "technology" VALUES('seas_stor','ps','electricity',NULL,NULL,0,0,0,0,0,0,0,1,NULL); -REPLACE INTO "technology" VALUES('demand','p','electricity',NULL,NULL,0,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('generator','p','electricity',NULL,NULL,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('dly_stor','ps','electricity',NULL,NULL,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('seas_stor','ps','electricity',NULL,NULL,0,0,0,0,0,0,1,NULL); +REPLACE INTO "technology" VALUES('demand','p','electricity',NULL,NULL,0,0,0,0,0,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'); diff --git a/tests/testing_data/simple_linked_tech.sql b/tests/testing_data/simple_linked_tech.sql index 25760ebc9..34e502b49 100644 --- a/tests/testing_data/simple_linked_tech.sql +++ b/tests/testing_data/simple_linked_tech.sql @@ -28,7 +28,7 @@ REPLACE INTO "lifetime_tech" VALUES('linkville', 'CCS', 100.0, NULL, ''); REPLACE INTO "lifetime_tech" VALUES('linkville', 'PLANT', 100.0, NULL, ''); REPLACE INTO "linked_tech" VALUES('linkville','PLANT','CO2','CCS',NULL); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); -REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); +REPLACE INTO "metadata" VALUES('DB_MINOR',1,''); 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 "operator" VALUES('e','equal to'); @@ -41,10 +41,10 @@ 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('PLANT','p','supply',NULL,NULL,0,0,0,0,0,0,0,0,NULL); -REPLACE INTO "technology" VALUES('CCS','p','supply',NULL,NULL,0,0,0,0,0,0,0,0,NULL); -REPLACE INTO "technology" VALUES('MINE','p','supply',NULL,NULL,0,0,0,0,0,0,0,0,NULL); -REPLACE INTO "technology" VALUES('FAKE_SOURCE','p','supply',NULL,NULL,1,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('PLANT','p','supply',NULL,NULL,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('CCS','p','supply',NULL,NULL,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('MINE','p','supply',NULL,NULL,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('FAKE_SOURCE','p','supply',NULL,NULL,1,0,0,0,0,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'); diff --git a/tests/testing_data/storageville.sql b/tests/testing_data/storageville.sql index e643378ba..3d33f461f 100644 --- a/tests/testing_data/storageville.sql +++ b/tests/testing_data/storageville.sql @@ -42,7 +42,7 @@ REPLACE INTO "limit_capacity" VALUES('electricville',2025,'EH','le',200.0,'','') REPLACE INTO "limit_capacity" VALUES('electricville',2025,'batt','le',100.0,'',''); REPLACE INTO "limit_storage_level_fraction" VALUES('electricville','s1','d1','batt','e',0.5,NULL); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); -REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); +REPLACE INTO "metadata" VALUES('DB_MINOR',1,''); 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 "operator" VALUES('e','equal to'); @@ -56,10 +56,10 @@ REPLACE INTO "sector_label" VALUES('commercial',NULL); REPLACE INTO "sector_label" VALUES('residential',NULL); REPLACE INTO "sector_label" VALUES('industrial',NULL); REPLACE INTO "storage_duration" VALUES('electricville','batt',10.0,NULL); -REPLACE INTO "technology" VALUES('well','p','supply','water','',0,0,0,0,0,0,0,0,'plain old water'); -REPLACE INTO "technology" VALUES('bulbs','p','residential','electric','',0,0,0,0,0,0,0,0,' residential lighting'); -REPLACE INTO "technology" VALUES('EH','pb','electric','hydro','',0,0,0,0,0,0,0,0,'hydro power electric plant'); -REPLACE INTO "technology" VALUES('batt','ps','electric','electric','',0,0,0,0,0,0,0,0,'big battery'); +REPLACE INTO "technology" VALUES('well','p','supply','water','',0,0,0,0,0,0,0,'plain old water'); +REPLACE INTO "technology" VALUES('bulbs','p','residential','electric','',0,0,0,0,0,0,0,' residential lighting'); +REPLACE INTO "technology" VALUES('EH','pb','electric','hydro','',0,0,0,0,0,0,0,'hydro power electric plant'); +REPLACE INTO "technology" VALUES('batt','ps','electric','electric','',0,0,0,0,0,0,0,'big battery'); 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'); diff --git a/tests/testing_data/survival_curve.sql b/tests/testing_data/survival_curve.sql index a0f32dc16..864d9de38 100644 --- a/tests/testing_data/survival_curve.sql +++ b/tests/testing_data/survival_curve.sql @@ -143,17 +143,17 @@ REPLACE INTO "lifetime_tech" VALUES('region', 'tech_old', 35.0, NULL, NULL); REPLACE INTO "lifetime_tech" VALUES('region', 'tech_current', 35.0, NULL, NULL); REPLACE INTO "lifetime_tech" VALUES('region', 'tech_future', 35.0, NULL, NULL); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); -REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); +REPLACE INTO "metadata" VALUES('DB_MINOR',1,''); REPLACE INTO "metadata_real" VALUES('global_discount_rate',0.05,'Discount Rate for future costs'); REPLACE INTO "metadata_real" VALUES('default_loan_rate',0.05,'Default Loan Rate if not specified in loan_rate table'); REPLACE INTO "operator" VALUES('e','equal to'); REPLACE INTO "operator" VALUES('le','less than or equal to'); REPLACE INTO "operator" VALUES('ge','greater than or equal to'); REPLACE INTO "region" VALUES('region',NULL); -REPLACE INTO "technology" VALUES('tech_ancient','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); -REPLACE INTO "technology" VALUES('tech_old','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); -REPLACE INTO "technology" VALUES('tech_current','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); -REPLACE INTO "technology" VALUES('tech_future','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('tech_ancient','p','energy',NULL,NULL,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('tech_old','p','energy',NULL,NULL,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('tech_current','p','energy',NULL,NULL,0,0,0,0,0,0,0,NULL); +REPLACE INTO "technology" VALUES('tech_future','p','energy',NULL,NULL,0,0,0,0,0,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'); diff --git a/tests/testing_data/test_system.sql b/tests/testing_data/test_system.sql index a50226c85..7bf6bbbd9 100644 --- a/tests/testing_data/test_system.sql +++ b/tests/testing_data/test_system.sql @@ -438,7 +438,7 @@ REPLACE INTO "limit_tech_output_split" VALUES('R2',2025,'S_OILREF','DSL','ge',0. REPLACE INTO "limit_tech_output_split" VALUES('R2',2030,'S_OILREF','GSL','ge',0.72,''); REPLACE INTO "limit_tech_output_split" VALUES('R2',2030,'S_OILREF','DSL','ge',0.08,''); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); -REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); +REPLACE INTO "metadata" VALUES('DB_MINOR',1,''); 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 "operator" VALUES('e','equal to'); @@ -454,22 +454,22 @@ REPLACE INTO "sector_label" VALUES('residential',NULL); REPLACE INTO "sector_label" VALUES('industrial',NULL); REPLACE INTO "storage_duration" VALUES('R1','E_BATT',8.0,'8-hour duration specified as fraction of a day'); REPLACE INTO "storage_duration" VALUES('R2','E_BATT',8.0,'8-hour duration specified as fraction of a day'); -REPLACE INTO "technology" VALUES('S_IMPETH','p','supply','','',1,0,0,0,0,0,0,0,' imported ethanol'); -REPLACE INTO "technology" VALUES('S_IMPOIL','p','supply','','',1,0,0,0,0,0,0,0,' imported crude oil'); -REPLACE INTO "technology" VALUES('S_IMPNG','p','supply','','',1,0,0,0,0,0,0,0,' imported natural gas'); -REPLACE INTO "technology" VALUES('S_IMPURN','p','supply','','',1,0,0,0,0,0,0,0,' imported uranium'); -REPLACE INTO "technology" VALUES('S_OILREF','p','supply','','',0,0,0,1,0,0,0,0,' crude oil refinery'); -REPLACE INTO "technology" VALUES('E_NGCC','p','electric','','',0,0,0,0,0,0,0,0,' natural gas combined-cycle'); -REPLACE INTO "technology" VALUES('E_SOLPV','p','electric','','',0,0,0,0,0,0,0,0,' solar photovoltaic'); -REPLACE INTO "technology" VALUES('E_BATT','ps','electric','','',0,0,0,0,0,0,0,0,' lithium-ion battery'); -REPLACE INTO "technology" VALUES('E_NUCLEAR','pb','electric','','',0,0,0,0,0,0,0,0,' nuclear power plant'); -REPLACE INTO "technology" VALUES('T_BLND','p','transport','','',0,0,0,0,0,0,0,0,'ethanol - gasoline blending process'); -REPLACE INTO "technology" VALUES('T_DSL','p','transport','','',0,0,0,0,0,0,0,0,'diesel vehicle'); -REPLACE INTO "technology" VALUES('T_GSL','p','transport','','',0,0,0,0,0,0,0,0,'gasoline vehicle'); -REPLACE INTO "technology" VALUES('T_EV','p','transport','','',0,0,0,0,0,0,0,0,'electric vehicle'); -REPLACE INTO "technology" VALUES('R_EH','p','residential','','',0,0,0,0,0,0,0,0,' electric residential heating'); -REPLACE INTO "technology" VALUES('R_NGH','p','residential','','',0,0,0,0,0,0,0,0,' natural gas residential heating'); -REPLACE INTO "technology" VALUES('E_TRANS','p','electric','','',0,0,0,0,0,0,1,0,'electric transmission'); +REPLACE INTO "technology" VALUES('S_IMPETH','p','supply','','',1,0,0,0,0,0,0,' imported ethanol'); +REPLACE INTO "technology" VALUES('S_IMPOIL','p','supply','','',1,0,0,0,0,0,0,' imported crude oil'); +REPLACE INTO "technology" VALUES('S_IMPNG','p','supply','','',1,0,0,0,0,0,0,' imported natural gas'); +REPLACE INTO "technology" VALUES('S_IMPURN','p','supply','','',1,0,0,0,0,0,0,' imported uranium'); +REPLACE INTO "technology" VALUES('S_OILREF','p','supply','','',0,0,1,0,0,0,0,' crude oil refinery'); +REPLACE INTO "technology" VALUES('E_NGCC','p','electric','','',0,0,0,0,0,0,0,' natural gas combined-cycle'); +REPLACE INTO "technology" VALUES('E_SOLPV','p','electric','','',0,0,0,0,0,0,0,' solar photovoltaic'); +REPLACE INTO "technology" VALUES('E_BATT','ps','electric','','',0,0,0,0,0,0,0,' lithium-ion battery'); +REPLACE INTO "technology" VALUES('E_NUCLEAR','pb','electric','','',0,0,0,0,0,0,0,' nuclear power plant'); +REPLACE INTO "technology" VALUES('T_BLND','p','transport','','',0,0,0,0,0,0,0,'ethanol - gasoline blending process'); +REPLACE INTO "technology" VALUES('T_DSL','p','transport','','',0,0,0,0,0,0,0,'diesel vehicle'); +REPLACE INTO "technology" VALUES('T_GSL','p','transport','','',0,0,0,0,0,0,0,'gasoline vehicle'); +REPLACE INTO "technology" VALUES('T_EV','p','transport','','',0,0,0,0,0,0,0,'electric vehicle'); +REPLACE INTO "technology" VALUES('R_EH','p','residential','','',0,0,0,0,0,0,0,' electric residential heating'); +REPLACE INTO "technology" VALUES('R_NGH','p','residential','','',0,0,0,0,0,0,0,' natural gas residential heating'); +REPLACE INTO "technology" VALUES('E_TRANS','p','electric','','',0,0,0,0,0,1,0,'electric transmission'); 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'); diff --git a/tests/testing_data/test_system_sets.json b/tests/testing_data/test_system_sets.json index 40e5b7ab4..c2f6df1b3 100644 --- a/tests/testing_data/test_system_sets.json +++ b/tests/testing_data/test_system_sets.json @@ -31,8 +31,8 @@ "flow_in_storage_rpsditvo": "8c97fbeacbca1a772ba04f63d0a82f7703500f83c0dc602114b17c64ad4d2e28", "flow_var_annual_rpitvo": "f98f5f41c5cba8ce2a894734abbc5e90310b695bee3c24c52acd8b4800c5ab85", "flow_var_rpsditvo": "784d98e451a8dcf0122f475c2e229162d99e403bdea85f7c608a3d86e850db44", - "lifetime_tech_rt": "984cc175a7aa58e77bb626e3237ca9bf625f5d9b15250870bef1cddc5f57f642", "lifetime_process_rtv": "5033502364848a3a3f295f1b3d051531ecd5c1e5f8bbaecd61afcd18181225ab", + "lifetime_tech_rt": "984cc175a7aa58e77bb626e3237ca9bf625f5d9b15250870bef1cddc5f57f642", "limit_activity_constraint_rpt": "2561103e7e6dd3dee3ba5832290ab5e933f4af08661dff4f2e661b6f4ffefc86", "limit_activity_share_constraint_rpgg": "(empty)", "limit_annual_capacity_factor_constraint_rptvo": "(empty)", @@ -58,16 +58,15 @@ "new_capacity_var_rtv": "bc0ec9e7f812410cb2af924cbc99a31c6e99cd95fc2de26193daad38f33cc132", "operator": "74d830836f1399fb336a0432dde7d7bd36cffa3ff76b1c42d7945350cfb9bf91", "ordered_season_sequential": "(empty)", + "planning_reserve_nrtpsd": "(empty)", + "planning_reserves": "(empty)", "process_life_frac_rptv": "d1b75ede9f90899b1c1cbc56489bf9d12c52abc6c0466eb5fe4dccaf6f3be800", "ramp_down_constraint_rpsdtv": "(empty)", "ramp_up_constraint_rpsdtv": "(empty)", - "regional_exchange_capacity_constraint_rrptv": "ae0671daa1263140faff22e3d2610c1fbab942d4e814892a50471adfa1bcc740", + "regional_exchange_capacity_constraint_rrptv": "6717d388890a9a64b2e3861c2bf99a62603dd8a7df0af12dab3ad905a0cce0eb", "regional_global_indices": "92fa6c5d5745d765d6e16ad1bca7e1fc72f4377273be7cfbfde626ca1967d81b", "regional_indices": "f74187f92c4fdb3c12d5610304c7ac9696001433150bdaa9ff20793fb6365b32", "regions": "0ddd05d695b255ac719dfa85de1e900a3036d547ffc7261c9c9ca2c81bfda029", - "renewable_portfolio_standard_constraint_rpg": "(empty)", - "reserve_margin_method": "7869283c0d14273f720716309207a8f0c24606d03c679d6b68e656ed8d86241d", - "reserve_margin_rpsd": "(empty)", "retired_capacity_var_rptv": "(empty)", "seasonal_storage_constraints_rpsdtv": "(empty)", "seasonal_storage_level_rpstv": "(empty)", @@ -87,7 +86,6 @@ "tech_group_names": "(empty)", "tech_or_group": "85a3645929dbeaf6b7eb17e8085c8923ef86949eaa3fb4fd81724dcdcf38fd30", "tech_production": "85a3645929dbeaf6b7eb17e8085c8923ef86949eaa3fb4fd81724dcdcf38fd30", - "tech_reserve": "(empty)", "tech_retirement": "(empty)", "tech_seasonal_storage": "(empty)", "tech_storage": "7109b89425e6707adc8a5e571bf70fc64475d2d76471e5afe93110fd86bbcec8", diff --git a/tests/testing_data/test_week.sql b/tests/testing_data/test_week.sql index a0384dc26..d22900ef6 100644 --- a/tests/testing_data/test_week.sql +++ b/tests/testing_data/test_week.sql @@ -1,5 +1,5 @@ REPLACE INTO metadata VALUES('DB_MAJOR',4,'DB major version number'); -REPLACE INTO metadata VALUES('DB_MINOR',0,'DB minor version number'); +REPLACE INTO metadata VALUES('DB_MINOR',1,'DB minor version number'); 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 LoanRate table'); REPLACE INTO sector_label VALUES('energy',NULL); @@ -90,11 +90,12 @@ REPLACE INTO time_of_day VALUES(24,'h24',1.0,NULL); REPLACE INTO time_period VALUES(0,0,'f'); REPLACE INTO time_period VALUES(1,1,'f'); REPLACE INTO time_period_type VALUES('e','existing vintages'); -REPLACE INTO time_period_type VALUES('f','future');REPLACE INTO technology VALUES('uc_cheap','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); -REPLACE INTO technology VALUES('uc_expensive','p','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); -REPLACE INTO technology VALUES('demand_sink','p','energy',NULL,NULL,1,0,0,0,0,0,0,0,NULL); -REPLACE INTO technology VALUES('daily_storage','ps','energy',NULL,NULL,0,0,0,0,0,0,0,0,NULL); -REPLACE INTO technology VALUES('seasonal_storage','ps','energy',NULL,NULL,0,0,0,0,0,0,0,1,NULL); +REPLACE INTO time_period_type VALUES('f','future'); +REPLACE INTO technology VALUES('uc_cheap','p','energy',NULL,NULL,0,0,0,0,0,0,0,NULL); +REPLACE INTO technology VALUES('uc_expensive','p','energy',NULL,NULL,0,0,0,0,0,0,0,NULL); +REPLACE INTO technology VALUES('demand_sink','p','energy',NULL,NULL,1,0,0,0,0,0,0,NULL); +REPLACE INTO technology VALUES('daily_storage','ps','energy',NULL,NULL,0,0,0,0,0,0,0,NULL); +REPLACE INTO technology VALUES('seasonal_storage','ps','energy',NULL,NULL,0,0,0,0,0,0,1,NULL); REPLACE INTO time_season VALUES(1,'d01',0.1428571428571428493,'1/7'); REPLACE INTO time_season VALUES(2,'d02',0.1428571428571428493,'1/7'); REPLACE INTO time_season VALUES(3,'d03',0.1428571428571428493,'1/7'); diff --git a/tests/testing_data/utopia_data.sql b/tests/testing_data/utopia_data.sql index d0f131cb3..66afeaefe 100644 --- a/tests/testing_data/utopia_data.sql +++ b/tests/testing_data/utopia_data.sql @@ -414,7 +414,7 @@ REPLACE INTO "limit_tech_output_split" VALUES('utopia',1990,'SRE','GSL','ge',0.3 REPLACE INTO "limit_tech_output_split" VALUES('utopia',2000,'SRE','GSL','ge',0.3,''); REPLACE INTO "limit_tech_output_split" VALUES('utopia',2010,'SRE','GSL','ge',0.3,''); REPLACE INTO "metadata" VALUES('DB_MAJOR',4,''); -REPLACE INTO "metadata" VALUES('DB_MINOR',0,''); +REPLACE INTO "metadata" VALUES('DB_MINOR',1,''); 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 "operator" VALUES('e','equal to'); @@ -427,25 +427,25 @@ 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 "technology" VALUES('IMPDSL1','p','supply','petroleum','',1,0,0,0,0,0,0,' imported diesel'); +REPLACE INTO "technology" VALUES('IMPGSL1','p','supply','petroleum','',1,0,0,0,0,0,0,' imported gasoline'); +REPLACE INTO "technology" VALUES('IMPHCO1','p','supply','coal','',1,0,0,0,0,0,0,' imported coal'); +REPLACE INTO "technology" VALUES('IMPOIL1','p','supply','petroleum','',1,0,0,0,0,0,0,' imported crude oil'); +REPLACE INTO "technology" VALUES('IMPURN1','p','supply','nuclear','',1,0,0,0,0,0,0,' imported uranium'); +REPLACE INTO "technology" VALUES('IMPFEQ','p','supply','petroleum','',1,0,0,0,0,0,0,' imported fossil equivalent'); +REPLACE INTO "technology" VALUES('IMPHYD','p','supply','hydro','',1,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,' coal power plant'); +REPLACE INTO "technology" VALUES('E21','pb','electric','nuclear','',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,' hydro power'); +REPLACE INTO "technology" VALUES('E51','ps','electric','electric','',0,0,0,0,0,0,0,' electric storage'); +REPLACE INTO "technology" VALUES('E70','p','electric','petroleum','',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,' electric residential heating'); +REPLACE INTO "technology" VALUES('RHO','p','residential','petroleum','',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,' residential lighting'); +REPLACE INTO "technology" VALUES('SRE','p','supply','petroleum','',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,' diesel powered vehicles'); +REPLACE INTO "technology" VALUES('TXE','p','transport','electric','',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,' gasoline powered vehicles'); 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'); diff --git a/tests/testing_data/utopia_sets.json b/tests/testing_data/utopia_sets.json index dded63032..9ee611654 100644 --- a/tests/testing_data/utopia_sets.json +++ b/tests/testing_data/utopia_sets.json @@ -31,8 +31,8 @@ "flow_in_storage_rpsditvo": "99eb864a26adcb6633c95462649bca3ef7096f67682702915d7769b54b5de386", "flow_var_annual_rpitvo": "4053866a304af0a6b9a1d293ddaf358dfee5b170dcb01d41e6bc52437908a98a", "flow_var_rpsditvo": "350739a59b14969da094cf1c95524134b9c9acd0989710456a8dcc6596d0a401", - "lifetime_tech_rt": "7b3703e1f021594993a54c55427a599ed03fc512cf34826b7a7670eb93edfb9a", "lifetime_process_rtv": "2cfc288b15f25957dfc70f6396d97ad655ecbed91c5a11582329749f1fb3dbd7", + "lifetime_tech_rt": "7b3703e1f021594993a54c55427a599ed03fc512cf34826b7a7670eb93edfb9a", "limit_activity_constraint_rpt": "(empty)", "limit_activity_share_constraint_rpgg": "(empty)", "limit_annual_capacity_factor_constraint_rptvo": "(empty)", @@ -58,6 +58,8 @@ "new_capacity_var_rtv": "d4f1cc8b432075001befddab648d54d1f82a29099236948845393a193b6add5b", "operator": "74d830836f1399fb336a0432dde7d7bd36cffa3ff76b1c42d7945350cfb9bf91", "ordered_season_sequential": "(empty)", + "planning_reserve_nrtpsd": "(empty)", + "planning_reserves": "(empty)", "process_life_frac_rptv": "63d17957ee2bebf664ffa6a39cea5e16ec65ad07db1df24dcea6b15bb9ebf589", "ramp_down_constraint_rpsdtv": "(empty)", "ramp_up_constraint_rpsdtv": "(empty)", @@ -65,9 +67,6 @@ "regional_global_indices": "ce00905893c23bc59c15dcf61d7e261c2e97ab1fc298ed0e0ccb1344f1cace37", "regional_indices": "ce00905893c23bc59c15dcf61d7e261c2e97ab1fc298ed0e0ccb1344f1cace37", "regions": "ce00905893c23bc59c15dcf61d7e261c2e97ab1fc298ed0e0ccb1344f1cace37", - "renewable_portfolio_standard_constraint_rpg": "(empty)", - "reserve_margin_method": "7869283c0d14273f720716309207a8f0c24606d03c679d6b68e656ed8d86241d", - "reserve_margin_rpsd": "(empty)", "retired_capacity_var_rptv": "(empty)", "seasonal_storage_constraints_rpsdtv": "(empty)", "seasonal_storage_level_rpstv": "(empty)", @@ -87,7 +86,6 @@ "tech_group_names": "(empty)", "tech_or_group": "5c321f60e5d16e60c5063b83d59ac9e184ab78e7fc469e41b21fd8aea83f600c", "tech_production": "5c321f60e5d16e60c5063b83d59ac9e184ab78e7fc469e41b21fd8aea83f600c", - "tech_reserve": "(empty)", "tech_retirement": "(empty)", "tech_seasonal_storage": "(empty)", "tech_storage": "245737c06f3e838e63da08a47a7d2a8605340ea5cad86397e1bb66461a574358", diff --git a/tests/utilities/compare_lp.py b/tests/utilities/compare_lp.py new file mode 100644 index 000000000..5090a7f57 --- /dev/null +++ b/tests/utilities/compare_lp.py @@ -0,0 +1,276 @@ +""" +Lightweight LP comparison helper, extracted from compare_lp.py. + +Parses two LP files and returns a structured diff, without writing reports +to disk. Intended for use by the reserve margin regression test. +""" + +from __future__ import annotations + +import re +from collections import defaultdict +from dataclasses import dataclass, field +from typing import TYPE_CHECKING, Any + +if TYPE_CHECKING: + from collections.abc import Generator + from pathlib import Path + +_CAMEL_RE = re.compile(r'([a-z0-9])([A-Z])') +_TERM_RE = re.compile(r'^([+\-]?\s*\d*\.?\d+(?:[eE][+\-]?\d+)?)\s+(\S+)$') +_RELATION_RE = re.compile(r'^([<>=]=?)\s*([\d.eE+\-]+)$') + + +def _camel_to_snake(s: str) -> str: + return _CAMEL_RE.sub(r'\1_\2', s).lower() + + +def _norm(token: str) -> str: + paren = token.find('(') + if paren == -1: + return _camel_to_snake(token) + return _camel_to_snake(token[:paren]) + token[paren:] + + +def _needs_normalization(path: Path, sample: int = 2000) -> bool: + checked = 0 + with path.open(encoding='utf-8', errors='replace') as fh: + for raw in fh: + s = raw.strip() + if not s or s.startswith('\\') or s.startswith('*'): + continue + line = re.sub(r'^([+\-])\s+', r'\1', s) + m = _TERM_RE.match(line) + token = None + if m: + token = m.group(2) + elif s.endswith(':') and not s.startswith(('+', '-')): + token = s.rstrip(':').rstrip('_') + if token: + paren = token.find('(') + name = token[:paren] if paren != -1 else token + if _CAMEL_RE.search(name): + return True + checked += 1 + if checked >= sample: + break + return False + + +def _stream(path: Path, normalize: bool) -> Generator[tuple[Any, ...]]: + tok = _norm if normalize else (lambda t: t) + section = 'preamble' + obj_name = None + obj_terms: list[tuple[float, str]] = [] + con_label: str | None = None + con_terms: list[tuple[float, str]] = [] + con_rel: str | None = None + con_rhs: float | None = None + + def _flush() -> tuple[str, str, list[tuple[float, str]], str | None, float | None] | None: + nonlocal con_label, con_terms, con_rel, con_rhs + result: tuple[str, str, list[tuple[float, str]], str | None, float | None] | None = None + if con_label is not None and con_rel is not None: + result = ('con', con_label, list(con_terms), con_rel, con_rhs) + con_label = None + con_terms = [] + con_rel = None + con_rhs = None + return result + + with path.open(encoding='utf-8', errors='replace') as fh: + for raw in fh: + s = raw.strip() + if not s: + continue + lower = s.lower() + + if lower in ('s.t.', 'subject to', 'st'): + if section == 'objective' and obj_terms: + yield ('obj', obj_name, obj_terms) + section = 'constraints' + continue + + if lower in ('bounds', 'generals', 'general', 'binary', 'binaries', 'end'): + r = _flush() + if r: + yield r + if section == 'objective' and obj_terms: + yield ('obj', obj_name, obj_terms) + yield ('bounds_start',) + section = 'done' + continue + + if section == 'done' or s.startswith('\\') or s.startswith('*'): + continue + + if section == 'preamble': + if lower in ('min', 'max'): + section = 'objective' + continue + + if section == 'objective': + if s.endswith(':') and not s.startswith(('+', '-')): + obj_name = tok(s.rstrip(':')) + continue + line = re.sub(r'^([+\-])\s+', r'\1', s) + m = _TERM_RE.match(line) + if m: + obj_terms.append((float(m.group(1).replace(' ', '')), tok(m.group(2)))) + continue + + if section == 'constraints': + if s.endswith(':') and not s.startswith(('+', '-')): + r = _flush() + if r: + yield r + con_label = tok(s.rstrip(':').rstrip('_')) + continue + m = _RELATION_RE.match(s) + if m: + con_rel, con_rhs = m.group(1), float(m.group(2)) + continue + line = re.sub(r'^([+\-])\s+', r'\1', s) + m = _TERM_RE.match(line) + if m: + con_terms.append((float(m.group(1).replace(' ', '')), tok(m.group(2)))) + + r = _flush() + if r: + yield r + if section == 'objective' and obj_terms: + yield ('obj', obj_name, obj_terms) + + +def _to_dict(terms: list[tuple[float, str]]) -> dict[str, float]: + d: dict[str, float] = defaultdict(float) + for c, v in terms: + d[v] += c + return dict(d) + + +@dataclass +class ConstraintDiff: + label: str + relation_changed: tuple[str, str] | None = None # (rel1, rel2) + rhs_changed: tuple[float, float] | None = None # (rhs1, rhs2) + terms_added: dict[str, float] = field(default_factory=dict) + terms_removed: dict[str, float] = field(default_factory=dict) + terms_changed: dict[str, tuple[float, float]] = field(default_factory=dict) + + def __bool__(self) -> bool: + return bool( + self.relation_changed + or self.rhs_changed + or self.terms_added + or self.terms_removed + or self.terms_changed + ) + + +@dataclass +class LpDiff: + only_in_a: list[str] = field(default_factory=list) + only_in_b: list[str] = field(default_factory=list) + changed: list[ConstraintDiff] = field(default_factory=list) + obj_diff: list[str] = field(default_factory=list) # human-readable lines + + @property + def is_identical(self) -> bool: + return not (self.only_in_a or self.only_in_b or self.changed or self.obj_diff) + + def summary(self) -> str: + lines = [ + f'only in A : {len(self.only_in_a)}', + f'only in B : {len(self.only_in_b)}', + f'changed : {len(self.changed)}', + f'obj diffs : {len(self.obj_diff)}', + ] + if self.only_in_a: + lines.append(' A-only (first 10): ' + ', '.join(self.only_in_a[:10])) + if self.only_in_b: + lines.append(' B-only (first 10): ' + ', '.join(self.only_in_b[:10])) + for cd in self.changed[:5]: + lines.append(f' changed: {cd.label}') + if cd.relation_changed: + lines.append(f' relation: {cd.relation_changed[0]} → {cd.relation_changed[1]}') + if cd.rhs_changed: + lines.append(f' rhs: {cd.rhs_changed[0]:+g} → {cd.rhs_changed[1]:+g}') + for v, (c1, c2) in list(cd.terms_changed.items())[:3]: + lines.append(f' coeff {v}: {c1:+g} → {c2:+g}') + return '\n'.join(lines) + + +def compare_lp_files(path_a: Path, path_b: Path, rtol: float = 1e-6) -> LpDiff: + """ + Compare two LP files and return a structured diff. + + Auto-detects CamelCase vs snake_case naming and normalises both sides + when either file uses CamelCase, so mixed-format comparisons work correctly. + """ + apply_norm = _needs_normalization(path_a) or _needs_normalization(path_b) + + # Load file A into memory + cons_a: dict[str, tuple[dict[str, float], str, float]] = {} + obj_a: tuple[str | None, dict[str, float]] | None = None + for block in _stream(path_a, apply_norm): + if block[0] == 'obj': + obj_a = (block[1], _to_dict(block[2])) + elif block[0] == 'con': + _, label, terms, rel, rhs = block + cons_a[label] = (_to_dict(terms), rel, rhs) + elif block[0] == 'bounds_start': + break + + diff = LpDiff() + seen: set[str] = set() + obj_b: tuple[str | None, dict[str, float]] | None = None + + for block in _stream(path_b, apply_norm): + if block[0] == 'obj': + obj_b = (block[1], _to_dict(block[2])) + elif block[0] == 'con': + _, label, terms, rel, rhs = block + td = _to_dict(terms) + if label not in cons_a: + diff.only_in_b.append(label) + else: + seen.add(label) + td_a, rel_a, rhs_a = cons_a[label] + cd = ConstraintDiff(label=label) + if rel_a != rel: + cd.relation_changed = (rel_a, rel) + if abs(rhs_a - rhs) > rtol * max(abs(rhs_a), abs(rhs), 1e-15): + cd.rhs_changed = (rhs_a, rhs) + all_vars = sorted(set(td_a) | set(td)) + for v in all_vars: + c1, c2 = td_a.get(v), td.get(v) + if c1 is None: + cd.terms_added[v] = c2 # type: ignore[assignment] + elif c2 is None: + cd.terms_removed[v] = c1 + else: + tol = rtol * max(abs(c1), abs(c2), 1e-15) + if abs(c1 - c2) > tol: + cd.terms_changed[v] = (c1, c2) + if cd: + diff.changed.append(cd) + elif block[0] == 'bounds_start': + break + + diff.only_in_a = [lbl for lbl in cons_a if lbl not in seen] + + if obj_a and obj_b: + all_vars = sorted(set(obj_a[1]) | set(obj_b[1])) + for v in all_vars: + c1, c2 = obj_a[1].get(v), obj_b[1].get(v) + if c1 is None: + diff.obj_diff.append(f'ADDED {v} coeff={c2:+g}') + elif c2 is None: + diff.obj_diff.append(f'REMOVED {v} coeff={c1:+g}') + else: + tol = rtol * max(abs(c1), abs(c2), 1e-15) + if abs(c1 - c2) > tol: + diff.obj_diff.append(f'CHANGED {v} {c1:+g} → {c2:+g}') + + return diff