diff --git a/previews/PR662/.documenter-siteinfo.json b/previews/PR662/.documenter-siteinfo.json
index 91f7e82c09..86f5dbbb3f 100644
--- a/previews/PR662/.documenter-siteinfo.json
+++ b/previews/PR662/.documenter-siteinfo.json
@@ -1 +1 @@
-{"documenter":{"julia_version":"1.10.2","generation_timestamp":"2024-03-20T22:59:13","documenter_version":"1.3.0"}}
\ No newline at end of file
+{"documenter":{"julia_version":"1.10.2","generation_timestamp":"2024-03-20T23:09:17","documenter_version":"1.3.0"}}
\ No newline at end of file
diff --git a/previews/PR662/Getting_Started/commercial_solvers/index.html b/previews/PR662/Getting_Started/commercial_solvers/index.html
index 54e6764777..3d4f64fa25 100644
--- a/previews/PR662/Getting_Started/commercial_solvers/index.html
+++ b/previews/PR662/Getting_Started/commercial_solvers/index.html
@@ -1,5 +1,5 @@
-
If you want to use the commercial solvers Gurobi or CPLEX:
Make sure you have a valid license and the actual solvers for either of Gurobi or CPLEX installed on your machine
Add Gurobi or CPLEX to the Julia Project.
$ julia --project=/home/youruser/GenX
julia> <press close-bracket ] to access the package manager>
(GenX) pkg> add Gurobi
@@ -7,4 +7,4 @@
(GenX) pkg> add CPLEX
Edit the Run.jl file to use the commercial solver. For example, to use Gurobi, you can add the following lines to the Run.jl file:
using Gurobi
using GenX
-run_genx_case!(dirname(@__FILE__), Gurobi.Optimizer)
Warning
Note that if you have not already installed the required Julia packages or you do not have a valid Gurobi license on your host machine, you will receive an error message and Run.jl will not run to completion.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
Note that if you have not already installed the required Julia packages or you do not have a valid Gurobi license on your host machine, you will receive an error message and Run.jl will not run to completion.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
This section describes how to run GenX with the examples provided in the repository and with user-defined cases. To have a deeper understanding of how to structure the input files and the settings, please refer to the User Guide.
GenX repository contains several examples to get you started with GenX. These examples are located in the example_systems folder of the repository and are designed to be easy to run and to demonstrate the main features of GenX.
The following instructions assume that you have already installed GenX and its dependencies. If you haven't, please follow the instructions in the Installation Guide.
To run an example, follow these steps:
Open a terminal and run Julia with an environment containing GenX;
Run the Run.jl file located in the example folder.
For example, to run the 1_three_zones example, you can use the following commands:
This section describes how to run GenX with the examples provided in the repository and with user-defined cases. To have a deeper understanding of how to structure the input files and the settings, please refer to the User Guide.
GenX repository contains several examples to get you started with GenX. These examples are located in the example_systems folder of the repository and are designed to be easy to run and to demonstrate the main features of GenX.
The following instructions assume that you have already installed GenX and its dependencies. If you haven't, please follow the instructions in the Installation Guide.
To run an example, follow these steps:
Open a terminal and run Julia with an environment containing GenX;
Run the Run.jl file located in the example folder.
For example, to run the 1_three_zones example, you can use the following commands:
$ julia
julia> <press close-bracket ] to access the package manager>
(@v1.9) pkg> activate /path/to/env
julia> using GenX
@@ -43,4 +43,4 @@
using Gurobi
run_genx_case!(dirname(@__FILE__), Gurobi.Optimizer)
To run the case, open a terminal and run the following command:
$ julia --project="/path/to/env"
-julia> include("/path/to/MyCase/Run.jl")
where /path/to/env is the path to the environment with GenX installed, and /path/to/MyCase is the path to the folder of the MyCase case. Alternatively, you can run the case directly from the terminal using the following command:
$ julia --project="/path/to/env" /path/to/MyCase/Run.jl
The entry point for running a GenX case is the run_genx_case!("path/to/case") function, where path/to/case is the path to the case directory that contains the .csv files with the inputs for GenX and the settings folder with the configuration files.
The following are the main steps performed in this function:
Establish path to environment setup files and GenX source files.
Read in model settings genx_settings.yml from the example directory.
Configure solver settings.
Load the model inputs from the example directory and perform time-domain clustering if required.
Generate a GenX model instance.
Solve the model.
Write the output files to a specified directory.
After the script runs to completion, results will be written to a folder called results, located in the current working directory.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+julia> include("/path/to/MyCase/Run.jl")
where /path/to/env is the path to the environment with GenX installed, and /path/to/MyCase is the path to the folder of the MyCase case. Alternatively, you can run the case directly from the terminal using the following command:
$ julia --project="/path/to/env" /path/to/MyCase/Run.jl
The entry point for running a GenX case is the run_genx_case!("path/to/case") function, where path/to/case is the path to the case directory that contains the .csv files with the inputs for GenX and the settings folder with the configuration files.
The following are the main steps performed in this function:
Establish path to environment setup files and GenX source files.
Read in model settings genx_settings.yml from the example directory.
Configure solver settings.
Load the model inputs from the example directory and perform time-domain clustering if required.
Generate a GenX model instance.
Solve the model.
Write the output files to a specified directory.
After the script runs to completion, results will be written to a folder called results, located in the current working directory.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
GenX allows for the simultaneous co-optimization of several interlinked power system decision layers, described below:
Capacity expansion planning (e.g., investment and retirement decisions for a full range of centralized and distributed generation, storage, and demand-side resources)
Hourly dispatch of generation, storage, and demand-side resources,
Unit commitment decisions and operational constraints for thermal generators,
Commitment of generation, storage, and demand-side capacity to meet system operating reserves requirements,
Commitment of generation, storage, and demand-side capacity to meet capacity reserve requirements,
Transmission network power flows (including losses) and network expansion decisions, and
Several optional policy constraints
Depending on the dimensionality of the problem, it may not be possible to model all decision layers at the highest possible resolution of detail, so the GenX model is designed to be highly configurable, allowing the user to specify the level of detail or abstraction along each of these layers or to omit one or more layers from consideration entirely.
For example, while investment and dispatch decisions (Layers 1 and 2) are a consistent feature of the model under all configurations, the user has several options with regards to representing the operational constraints on various thermal power plants (e.g., coal, gas, nuclear, and biomass generators). Unit commitment (e.g., start-up and shut-down) decisions Morales-España et al., 2013 (Layer 3) can be modeled at the individual power plant level (as per De Sisternes Jimenez, 2014); by using an efficient clustering of similar or identical units (as per Palmintier, 2011, Palmintier, 2013, Palmintier, 2014); by using a linear relaxation (or convex hull) of the integer unit commitment constraints set; or ignoring unit commitment decisions entirely and treating generator output as fully continuous. Furthermore, different levels of resolution can be selected for each individual resource type, as desired (e.g., larger thermal units can be represented with integer unit commitment decisions while smaller units can be treated as fully continuous). In such a manner, the model can be configured to represent operating constraints on thermal generators at a level of resolution that achieves a desired balance between abstraction error and computational tractability and provides sufficient accuracy to generate insights for the problem at hand.
The model can also be configured to consider commitment of capacity to supply frequency regulation (symmetric up and down) and operating reserves (up) needed by system operators to robustly resolve short-term uncertainty in demand and renewable energy forecasts and power plant or transmission network failures (Layer 4). Alternatively, reserve commitments can be ignored if desired.
Additionally, the model can approximate resource adequacy requirements through capacity reserve margin requirements at the zonal and/or system level (Layer 5). In this way, the model can approximate varying structure of capacity markets seen in deregulated electricity markets in the U.S. and other regions.
The model also allows for transmission networks to be represented at several levels of detail (Layer 6) including at a zonal level with transport constraints on power flows between zones (as per Mai et al., 2013, Johnston et al., 2013, Hirth, 2017); or as a single zone problem where transmission constraints and flows are ignored. (A DC optimal power flow formulation is in development.) In cases where a nodal or zonal transmission model is employed, network capacity expansion decisions can be modeled or ignored, and transmission losses can be represented either as a linear function of power flows or a piecewise linear approximation of a quadratic function of power flows between nodes or zones (as per Zhang et al., 2013, Fitiwi et al., 2016), with the number of segments in the piecewise approximation specified by the user as desired. In a multi-zonal or nodal configuration, GenX can therefore consider siting generators in different locations, including balancing tradeoffs between access to different renewable resource quality, siting restrictions, and impacts on network congestions, power flows and losses.
GenX also allows the user to specify several optional public policy constraints, such as CO2 emissions limits, minimum energy share requirements (such as renewable portfolio standard or clean energy standard policies), and minimum technology capacity requirements (e.g. technology deployment mandates).
Finally, the model is usually configured to consider a full year of operating decisions at an hourly resolution, but as this is often not tractable when considering large-scale problems with high resolution in other dimensions, GenX is also designed to model a number of subperiods – typically multiday periods of chronologically sequential hourly operating decisions – that can be selected via appropriate statistical clustering methods to represent a full year of operations (De Sisternes Jimenez and Webster, 2013, De Sisternes Jimenez, 2014, Poncelet et al., 2016, Nahmmacher et al., 2016, Blanford et al., 2016, Merrick, 2016, Mallapragada et al., 2018). GenX ships with a built-in time-domain reduction package that uses k-means or k-medoids to cluster raw time series data for demand (load) profiles and resource capacity factor profiles into representative periods during the input processing stage of the model. This method can also consider extreme points in the time series to capture noteworthy periods or periods with notably poor fits.
With appropriate configuration of the model, GenX thus allows the user to tractably consider several interlinking decision layers in a single, monolithic optimization problem that would otherwise have been necessary to solve in different separated stages or models. The following figure reflects the range of configurations currently possible along the three key dimensions of chronological detail, operational detail, and network detail.
Figure. Range of configurations currently implemented in GenX along three key dimensions of model resolution
The model can be configured to consider a single future planning year or multiple planning stages (or investment periods) in sequence.
In single-stage planning mode, the model formulation is static, in the sense that its objective is not to determine when investments should take place over time, but rather to produce a snapshot of the minimum-cost generation capacity mix to meet demand at least cost under some pre-specified future conditions.
The user can formulate and solve a deterministic multi-stage planning problem with perfect foresight i.e. demand, cost, and policy assumptions about all stages are known and exploited to determine the least-cost investment trajectory for the entire period. The solution of this multi-stage problem relies on exploiting the decomposable nature of the multi-stage problem via the implementation of the dual dynamic programming algorithm, described in Lara et al. 2018 here.
The user can formulate a sequential, myopic multi-stage planning problem, where the model solves a sequence of single-stage investment planning problems wherein investment decisions in each stage are individually optimized to meet demand given assumptions for the current planning stage and with investment decisions from previous stages treated as inputs for the current stage. We refer to this as "myopic" (or shortsighted) mode since the solution does not account for information about future stages in determining investments for a given stage. This version is generally more computationally efficient than the deterministic multi-stage expansion with perfect foresight mode.
More information on the two sequential, multi-stage planning modes can be found in the section on Multi-stage under the Model function reference tab.
From a centralized planning perspective, the GenX model can help to determine the investments needed to supply future electricity demand at minimum cost, as is common in least-cost utility planning or integrated resource planning processes. In the context of liberalized markets, the model can be used by regulators and policy makers for indicative energy planning or policy analysis in order to establish a long-term vision of efficient market and policy outcomes. The model can also be used for techno-economic assessment of emerging electricity generation, storage, and demand-side resources and to enumerate the effect of parametric uncertainty (e.g., technology costs, fuel costs, demand, policy decisions) on the system-wide value or role of different resources.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
GenX allows for the simultaneous co-optimization of several interlinked power system decision layers, described below:
Capacity expansion planning (e.g., investment and retirement decisions for a full range of centralized and distributed generation, storage, and demand-side resources)
Hourly dispatch of generation, storage, and demand-side resources,
Unit commitment decisions and operational constraints for thermal generators,
Commitment of generation, storage, and demand-side capacity to meet system operating reserves requirements,
Commitment of generation, storage, and demand-side capacity to meet capacity reserve requirements,
Transmission network power flows (including losses) and network expansion decisions, and
Several optional policy constraints
Depending on the dimensionality of the problem, it may not be possible to model all decision layers at the highest possible resolution of detail, so the GenX model is designed to be highly configurable, allowing the user to specify the level of detail or abstraction along each of these layers or to omit one or more layers from consideration entirely.
For example, while investment and dispatch decisions (Layers 1 and 2) are a consistent feature of the model under all configurations, the user has several options with regards to representing the operational constraints on various thermal power plants (e.g., coal, gas, nuclear, and biomass generators). Unit commitment (e.g., start-up and shut-down) decisions Morales-España et al., 2013 (Layer 3) can be modeled at the individual power plant level (as per De Sisternes Jimenez, 2014); by using an efficient clustering of similar or identical units (as per Palmintier, 2011, Palmintier, 2013, Palmintier, 2014); by using a linear relaxation (or convex hull) of the integer unit commitment constraints set; or ignoring unit commitment decisions entirely and treating generator output as fully continuous. Furthermore, different levels of resolution can be selected for each individual resource type, as desired (e.g., larger thermal units can be represented with integer unit commitment decisions while smaller units can be treated as fully continuous). In such a manner, the model can be configured to represent operating constraints on thermal generators at a level of resolution that achieves a desired balance between abstraction error and computational tractability and provides sufficient accuracy to generate insights for the problem at hand.
The model can also be configured to consider commitment of capacity to supply frequency regulation (symmetric up and down) and operating reserves (up) needed by system operators to robustly resolve short-term uncertainty in demand and renewable energy forecasts and power plant or transmission network failures (Layer 4). Alternatively, reserve commitments can be ignored if desired.
Additionally, the model can approximate resource adequacy requirements through capacity reserve margin requirements at the zonal and/or system level (Layer 5). In this way, the model can approximate varying structure of capacity markets seen in deregulated electricity markets in the U.S. and other regions.
The model also allows for transmission networks to be represented at several levels of detail (Layer 6) including at a zonal level with transport constraints on power flows between zones (as per Mai et al., 2013, Johnston et al., 2013, Hirth, 2017); or as a single zone problem where transmission constraints and flows are ignored. (A DC optimal power flow formulation is in development.) In cases where a nodal or zonal transmission model is employed, network capacity expansion decisions can be modeled or ignored, and transmission losses can be represented either as a linear function of power flows or a piecewise linear approximation of a quadratic function of power flows between nodes or zones (as per Zhang et al., 2013, Fitiwi et al., 2016), with the number of segments in the piecewise approximation specified by the user as desired. In a multi-zonal or nodal configuration, GenX can therefore consider siting generators in different locations, including balancing tradeoffs between access to different renewable resource quality, siting restrictions, and impacts on network congestions, power flows and losses.
GenX also allows the user to specify several optional public policy constraints, such as CO2 emissions limits, minimum energy share requirements (such as renewable portfolio standard or clean energy standard policies), and minimum technology capacity requirements (e.g. technology deployment mandates).
Finally, the model is usually configured to consider a full year of operating decisions at an hourly resolution, but as this is often not tractable when considering large-scale problems with high resolution in other dimensions, GenX is also designed to model a number of subperiods – typically multiday periods of chronologically sequential hourly operating decisions – that can be selected via appropriate statistical clustering methods to represent a full year of operations (De Sisternes Jimenez and Webster, 2013, De Sisternes Jimenez, 2014, Poncelet et al., 2016, Nahmmacher et al., 2016, Blanford et al., 2016, Merrick, 2016, Mallapragada et al., 2018). GenX ships with a built-in time-domain reduction package that uses k-means or k-medoids to cluster raw time series data for demand (load) profiles and resource capacity factor profiles into representative periods during the input processing stage of the model. This method can also consider extreme points in the time series to capture noteworthy periods or periods with notably poor fits.
With appropriate configuration of the model, GenX thus allows the user to tractably consider several interlinking decision layers in a single, monolithic optimization problem that would otherwise have been necessary to solve in different separated stages or models. The following figure reflects the range of configurations currently possible along the three key dimensions of chronological detail, operational detail, and network detail.
Figure. Range of configurations currently implemented in GenX along three key dimensions of model resolution
The model can be configured to consider a single future planning year or multiple planning stages (or investment periods) in sequence.
In single-stage planning mode, the model formulation is static, in the sense that its objective is not to determine when investments should take place over time, but rather to produce a snapshot of the minimum-cost generation capacity mix to meet demand at least cost under some pre-specified future conditions.
The user can formulate and solve a deterministic multi-stage planning problem with perfect foresight i.e. demand, cost, and policy assumptions about all stages are known and exploited to determine the least-cost investment trajectory for the entire period. The solution of this multi-stage problem relies on exploiting the decomposable nature of the multi-stage problem via the implementation of the dual dynamic programming algorithm, described in Lara et al. 2018 here.
The user can formulate a sequential, myopic multi-stage planning problem, where the model solves a sequence of single-stage investment planning problems wherein investment decisions in each stage are individually optimized to meet demand given assumptions for the current planning stage and with investment decisions from previous stages treated as inputs for the current stage. We refer to this as "myopic" (or shortsighted) mode since the solution does not account for information about future stages in determining investments for a given stage. This version is generally more computationally efficient than the deterministic multi-stage expansion with perfect foresight mode.
More information on the two sequential, multi-stage planning modes can be found in the section on Multi-stage under the Model function reference tab.
From a centralized planning perspective, the GenX model can help to determine the investments needed to supply future electricity demand at minimum cost, as is common in least-cost utility planning or integrated resource planning processes. In the context of liberalized markets, the model can be used by regulators and policy makers for indicative energy planning or policy analysis in order to establish a long-term vision of efficient market and policy outcomes. The model can also be used for techno-economic assessment of emerging electricity generation, storage, and demand-side resources and to enumerate the effect of parametric uncertainty (e.g., technology costs, fuel costs, demand, policy decisions) on the system-wide value or role of different resources.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
where $t$ denotes an time step and $\mathcal{T}$ is the set of time steps over which grid operations are modeled
$\mathcal{T}^{interior} \subseteq \mathcal{T}^{}$
where $\mathcal{T}^{interior}$ is the set of interior timesteps in the data series
$\mathcal{T}^{start} \subseteq \mathcal{T}$
where $\mathcal{T}^{start}$ is the set of initial timesteps in the data series. $\mathcal{T}^{start}={1}$ when representing entire year as a single contiguous period; $\mathcal{T}^{start}=\{\left(m-1\right) \times \tau^{period}+1 | m \in \mathcal{M}\}$, which corresponds to the first time step of each representative period $m \in \mathcal{M}$
$n \in \mathcal{N}$
where $n$ corresponds to a contiguous time period and $\mathcal{N}$ corresponds to the set of contiguous periods of length $\tau^{period}$ that make up the input time series (e.g. demand, variable renewable energy availability) to the model
$\mathcal{N}^{rep} \subseteq \mathcal{N}$
where $\mathcal{N}^{rep}$ corresponds to the set of representative time periods that are selected from the set of contiguous periods, $\mathcal{M}$
$m \in \mathcal{M}$
where $m$ corresponds to a representative time period and $\mathcal{M}$ corresponds to the set of representative time periods indexed as per their chronological ocurrence in the set of contiguous periods spanning the input time series data, i.e. $\mathcal{N}$
$z \in \mathcal{Z}$
where $z$ denotes a zone and $\mathcal{Z}$ is the set of zones in the network
$l \in \mathcal{L}$
where $l$ denotes a line and $\mathcal{L}$ is the set of transmission lines in the network
$y \in \mathcal{G}$
where $y$ denotes a technology and $\mathcal{G}$ is the set of available technologies
$\mathcal{H} \subseteq \mathcal{G}$
where $\mathcal{H}$ is the subset of thermal resources
$\mathcal{VRE} \subseteq \mathcal{G}$
where $\mathcal{VRE}$ is the subset of curtailable Variable Renewable Energy (VRE) resources
$\overline{\mathcal{VRE}}^{y,z}$
set of VRE resource bins for VRE technology type $y \in \mathcal{VRE}$ in zone $z$
$\mathcal{CE} \subseteq \mathcal{G}$
where $\mathcal{CE}$ is the subset of resources qualifying for the clean energy standard policy constraint
$\mathcal{UC} \subseteq \mathcal{H}$
where $\mathcal{UC}$ is the subset of thermal resources subject to unit commitment constraints
$s \in \mathcal{S}$
where $s$ denotes a segment and $\mathcal{S}$ is the set of consumers segments for price-responsive demand curtailment
$\mathcal{O} \subseteq \mathcal{G}$
where $\mathcal{O}$ is the subset of storage resources excluding heat storage and hydro storage
$o \in \mathcal{O}$
where $o$ denotes a storage technology in a set $\mathcal{O}$
$\mathcal{O}^{sym} \subseteq \mathcal{O}$
where $\mathcal{O}^{sym}$ corresponds to the set of energy storage technologies with equal (or symmetric) charge and discharge power capacities
$\mathcal{O}^{asym} \subseteq \mathcal{O}$
where $\mathcal{O}^{asym}$ corresponds to the set of energy storage technologies with independently sized (or asymmetric) charge and discharge power capacities
$\mathcal{O}^{LDES} \subseteq \mathcal{O}$
where $\mathcal{O}^{LDES}$ corresponds to the set of long-duration energy storage technologies for which inter-period energy exchange is permitted when using representative periods to model annual grid operations
$\mathcal{VS} \subseteq \mathcal{G}$
where $\mathcal{VS}$ is the subset of co-located VRE and storage resources
$\mathcal{VS}^{pv} \subseteq \mathcal{VS}$
where $\mathcal{VS}^{pv}$ corresponds to the set of co-located VRE and storage resources with a solar PV component
$\mathcal{VS}^{wind} \subseteq \mathcal{VS}$
where $\mathcal{VS}^{wind}$ corresponds to the set of co-located VRE and storage resources with a wind component
$\mathcal{VS}^{inv} \subseteq \mathcal{VS}$
where $\mathcal{VS}^{inv}$ corresponds to the set of co-located VRE and storage resources with an inverter component
$\mathcal{VS}^{stor} \subseteq \mathcal{VS}$
where $\mathcal{VS}^{stor}$ corresponds to the set of co-located VRE and storage resources with a storage component
$\mathcal{VS}^{sym, dc} \subseteq \mathcal{VS}$
where $\mathcal{VS}^{sym, dc}$ corresponds to the set of co-located VRE and storage resources with a storage DC component with equal (or symmetric) charge and discharge power capacities
$\mathcal{VS}^{sym, ac} \subseteq \mathcal{VS}$
where $\mathcal{VS}^{sym, ac}$ corresponds to the set of co-located VRE and storage resources with a storage AC component with equal (or symmetric) charge and discharge power capacities
where $\mathcal{VS}^{asym, dc, dis}$ corresponds to the set of co-located VRE and storage resources with a storage DC component with independently sized (or asymmetric) discharge power capabilities
where $\mathcal{VS}^{asym, dc, cha}$ corresponds to the set of co-located VRE and storage resources with a storage DC component with independently sized (or asymmetric) charge power capabilities
where $\mathcal{VS}^{asym, ac, dis}$ corresponds to the set of co-located VRE and storage with a storage AC component with independently sized (or asymmetric) discharge power capabilities
where $\mathcal{VS}^{asym, ac, cha}$ corresponds to the set of co-located VRE and storage resources with a storage AC component with independently sized (or asymmetric) charge power capabilities
$\mathcal{VS}^{LDES} \subseteq \mathcal{VS}$
where $\mathcal{VS}^{LDES}$ corresponds to the set of co-located VRE and storage resources with a long-duration energy storage component for which inter-period energy exchange is permitted when using representative periods to model annual grid operations
$\mathcal{W} \subseteq \mathcal{G}$
where $\mathcal{W}$ set of hydroelectric generators with water storage reservoirs
$\mathcal{W}^{nocap} \subseteq \mathcal{W}$
where $\mathcal{W}^{nocap}$ is a subset of set of $ \mathcal{W}$ and represents resources with unknown reservoir capacity
$\mathcal{W}^{cap} \subseteq \mathcal{W}$
where $\mathcal{W}^{cap}$ is a subset of set of $ \mathcal{W}$ and represents resources with known reservoir capacity
$\mathcal{MR} \subseteq \mathcal{G}$
where $\mathcal{MR}$ set of must-run resources
$\mathcal{DF} \subseteq \mathcal{G}$
where $\mathcal{DF}$ set of flexible demand resources
$\mathcal{ELECTROLYZER} \subseteq \mathcal{G}$
where $\mathcal{ELECTROLYZER}$ set of electrolyzer resources (optional set)
$\mathcal{G}_p^{ESR} \subseteq \mathcal{G}$
where $\mathcal{G}_p^{ESR}$ is a subset of $\mathcal{G}$ that is eligible for Energy Share Requirement (ESR) policy constraint $p$
$p \in \mathcal{P}$
where $p$ denotes a instance in the policy set $\mathcal{P}$
Installed capacity in terms of the number of units (each unit, being of size $\overline{\Omega}_{y,z}^{size}$) of resource $y$ in zone $z$ [Dimensionless] (Note that for co-located VRE and storage resources, this value represents the installed capacity of the grid connection in [MW AC])
$\Omega^{energy}_{y,z} \in \mathbb{R}_+$
Installed energy capacity of resource $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [MWh] (Note that for co-located VRE and storage resources, this value represents the installed capacity of the storage component in MWh)
$\Omega^{charge}_{y,z} \in \mathbb{R}_+$
Installed charging power capacity of resource $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O}^{asym}$ [MW]
$\Omega^{pv}_{y,z} \in \mathbb{R}_+$
Installed solar PV capacity of resource $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [MW DC]
$\Omega^{wind}_{y,z} \in \mathbb{R}_+$
Installed wind capacity of resource $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [MW AC]
$\Omega^{inv}_{y,z} \in \mathbb{R}_+$
Installed inverter capacity of resource $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [MW AC]
$\Omega^{dc,dis}_{y,z} \in \mathbb{R}_+$
Installed storage DC discharge capacity of resource $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [MW DC]
$\Omega^{dc,cha}_{y,z} \in \mathbb{R}_+$
Installed storage DC charge capacity of resource $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [MW DC]
$\Omega^{ac,dis}_{y,z} \in \mathbb{R}_+$
Installed storage AC discharge capacity of resource $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [MW AC]
$\Omega^{ac,cha}_{y,z} \in \mathbb{R}_+$
Installed storage AC charge capacity of resource $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC charge component, $y \in \mathcal{VS}^{asym,ac,cha}$ [MW AC]
$\Delta_{y,z} \in \mathbb{R}_+$
Retired capacity of technology $y$ from existing capacity in zone $z$ [MW] (Note that for co-located VRE and storage resources, this value represents the retired capacity of the grid connection in MW AC)
$\Delta^{energy}_{y,z} \in \mathbb{R}_+$
Retired energy capacity of technology $y$ from existing capacity in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [MWh] (Note that for co-located VRE and storage resources, this value represents the retired capacity of the storage component in MWh)
$\Delta^{charge}_{y,z} \in \mathbb{R}_+$
Retired charging capacity of technology $y$ from existing capacity in zone $z$ - only applicable for storage resources, $y \in \mathcal{O}^{asym}$[MW]
$\Delta^{pv}_{y,z} \in \mathbb{R}_+$
Retired solar PV capacity of technology $y$ from existing capacity in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [MW DC]
$\Delta^{wind}_{y,z} \in \mathbb{R}_+$
Retired wind capacity of technology $y$ from existing capacity in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [MW AC]
$\Delta^{inv}_{y,z} \in \mathbb{R}_+$
Retired inverter capacity of technology $y$ from existing capacity in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [MW AC]
$\Delta^{dc,dis}_{y,z} \in \mathbb{R}_+$
Retired storage DC discharge capacity of technology $y$ from existing capacity in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [MW DC]
$\Delta^{dc,cha}_{y,z} \in \mathbb{R}_+$
Retired storage DC charge capacity of technology $y$ from existing capacity in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [MW DC]
$\Delta^{ac,dis}_{y,z} \in \mathbb{R}_+$
Retired storage AC discharge capacity of technology $y$ from existing capacity in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [MW AC]
$\Delta^{ac,cha}_{y,z} \in \mathbb{R}_+$
Retired storage AC charge capacity of technology $y$ from existing capacity in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC charge component, $y \in \mathcal{VS}^{asym,ac,cha}$ [MW AC]
$\Delta_{y,z}^{total} \in \mathbb{R}_+$
Total installed capacity of technology $y$ in zone $z$ [MW] (Note that co-located VRE and storage resources, this value represents the total capacity of the grid connection in MW AC)
$\Delta_{y,z}^{total,energy} \in \mathbb{R}_+$
Total installed energy capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [MWh] (Note that co-located VRE and storage resources, this value represents the total installed energy capacity of the storage component in MWh)
$\Delta_{y,z}^{total,charge} \in \mathbb{R}_+$
Total installed charging power capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O}^{asym}$ [MW]
$\Delta_{y,z}^{total,pv} \in \mathbb{R}_+$
Total installed solar PV capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [MW DC]
$\Delta_{y,z}^{total,wind} \in \mathbb{R}_+$
Total installed wind capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [MW AC]
$\Delta_{y,z}^{total,inv} \in \mathbb{R}_+$
Total installed inverter capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [MW AC]
$\Delta_{y,z}^{total,dc,dis} \in \mathbb{R}_+$
Total installed storage DC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [MW DC]
$\Delta_{y,z}^{total,dc,cha} \in \mathbb{R}_+$
Total installed storage DC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [MW DC]
$\Delta_{y,z}^{total,ac,dis} \in \mathbb{R}_+$
Total installed storage AC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [MW AC]
$\Delta_{y,z}^{total,ac,cha} \in \mathbb{R}_+$
Total installed storage AC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC charge component, $y \in \mathcal{VS}^{asym,ac,cha}$ [MW AC]
$\bigtriangleup\varphi^{max}_{l}$
Additional transmission capacity added to line $l$ [MW]
$\Theta_{y,z,t} \in \mathbb{R}_+$
Energy injected into the grid by technology $y$ at time step $t$ in zone $z$ [MWh]
$\Theta^{pv}_{y,z,t} \in \mathbb{R}_+$
Energy generated by the solar PV component into the grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [MWh]
$\Theta^{wind}_{y,z,t} \in \mathbb{R}_+$
Energy generated by the wind component into the grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [MWh]
$\Theta^{dc}_{y,z,t} \in \mathbb{R}_+$
Energy discharged by the storage DC component into the grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with a discharge DC component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,dis}$ [MWh]
$\Theta^{ac}_{y,z,t} \in \mathbb{R}_+$
Energy discharged by the storage AC component into the grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with a discharge AC component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,dis}$ [MWh]
$\Pi_{y,z,t} \in \mathbb{R}_+$
Energy withdrawn from grid by technology $y$ at time step $t$ in zone $z$ [MWh]
$\Pi^{dc}_{y,z,t} \in \mathbb{R}_+$
Energy withdrawn from the VRE and grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with a charge DC component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,cha}$ [MWh]
$\Pi^{ac}_{y,z,t} \in \mathbb{R}_+$
Energy withdrawn from the VRE and grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with a charge AC component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,cha}$ [MWh]
$\Gamma_{y,z,t} \in \mathbb{R}_+$
Stored energy level of technology $y$ at end of time step $t$ in zone $z$ [MWh]
$\Lambda_{s,z,t} \in \mathbb{R}_+$
Non-served energy/curtailed demand from the price-responsive demand segment $s$ in zone $z$ at time step $t$ [MWh]
$l_{l,t} \in \mathbb{R}_+$
Losses in line $l$ at time step $t$ [MWh]
$\varrho_{y,z,t}\in \mathbb{R}_+$
Spillage from a reservoir technology $y$ at end of time step $t$ in zone $z$ [MWh]
$f_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves from technology $y$ in zone $z$ at time $t$\footnote{Regulation reserve contribution are modeled to be symmetric, consistent with current practice in electricity markets}
$r_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] from technology $y$ in zone $z$ at time t (we are not modeling down spinning reserves since these are usually never binding for high variable renewable energy systems)
$f^{charge}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves from charging storage technology $y$ in zone $z$ at time $t$
$f^{discharge}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves from discharging storage technology $y$ in zone $z$ at time $t$
$r^{charge}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] from charging storage technology $y$ in zone $z$ at time $t$
$r^{discharge}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] from discharging storage technology $y$ in zone $z$ at time $t$
$r^{unmet}_t \in \mathbb{R}_+$
Shortfall in provision of upward operating spinning reserves during each time period $t \in T$
$f^{pv}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves for the solar PV component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$
$r^{pv}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] for the solar PV component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$
$f^{wind}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves for the wind component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$
$r^{wind}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] for the wind component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$
$f^{dc,dis}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves for the storage DC discharge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage DC discharge component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,dis}$
$r^{dc,dis}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] for the storage DC discharge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage DC discharge component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,dis}$
$f^{dc,cha}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves for the storage DC charge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage DC charge component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,cha}$
$r^{dc,cha}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] for the storage DC charge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage DC charge component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,cha}$
$f^{ac,dis}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves for the storage AC discharge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage AC discharge component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,dis}$
$r^{ac,dis}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] for the storage AC discharge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage AC discharge component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,dis}$
$f^{ac,cha}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves for the storage AC charge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage AC charge component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,cha}$
$r^{ac,cha}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] for the storage AC charge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage AC charge component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,cha}$
$\alpha^{Contingency,Aux}_{y,z} \in \{0,1\}$
Binary variable that is set to be 1 if the total installed capacity $\Delta^{\text{total}}_{y,z} > 0$ for any generator $y \in \mathcal{UC}$ and zone $z$, and can be 0 otherwise
$\Phi_{l,t} \in \mathbb{R}_+$
Power flow in line $l$ at time step $t$ [MWh]
$\theta_{z,t} \in \mathbb{R}$
Volta phase angle in zone $z$ at time step $t$ [radian]
$v_{y,z,t}$
Commitment state of the generation cluster $y$ in zone $z$ at time $t$
$\mathcal{X}_{y,z,t}$
Number of startup decisions, of the generation cluster $y$ in zone $z$ at time $t$
$\zeta_{y,z,t}$
Number of shutdown decisions, of the generation cluster $y$ in zone $z$ at time $t$
$\mathcal{Q}_{o,n} \in \mathbb{R}_+$
Inventory of storage of type $o$ at the beginning of input period $n$ [MWh]
$\Delta\mathcal{Q}_{o,m} \in \mathbb{R}$
Excess storage inventory built up during representative period $m$ [MWh]
$ON^{+}_{l,t} \in {0,1}$
Binary variable to activate positive flows on line $l$ in time $t$
$TransON^{+}_{l,t} \in \mathbb{R}_+$
Variable defining maximum positive flow in line $l$ in time $t$ [MW]
$\Theta^{CRM}_{y,z,t} \in \mathbb{R}_+$
"Virtual" energy discharged by a storage resource that contributes to the capacity reserve margin for technology $y$ at time step $t$ in zone $z$ - only applicable for storage resources with activated capacity reserve margin policies, $y \in \mathcal{O}$ [MWh]
$\Pi^{CRM}_{y,z,t} \in \mathbb{R}_+$
"Virtual" energy withdrawn by a storage resource from the grid by technology $y$ at time step $t$ in zone $z$ - only applicable for storage resources with activated capacity reserve margin policies, $y \in \mathcal{O}$ [MWh]
$\Theta^{CRM,dc}_{y,z,t} \in \mathbb{R}_+$
"Virtual" energy discharged by a storage DC component that contributes to the capacity reserve margin for technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with activated capacity reserve margin policies, $y \in \mathcal{VS}^{stor}$ [MWh]
$\Pi^{CRM,dc}_{y,z,t} \in \mathbb{R}_+$
"Virtual" energy withdrawn by a storage DC component from the grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with activated capacity reserve margin policies, $y \in \mathcal{VS}^{stor}$ [MWh]
$\Theta^{CRM,ac}_{y,z,t} \in \mathbb{R}_+$
"Virtual" energy discharged by a storage AC component that contributes to the capacity reserve margin for technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with activated capacity reserve margin policies, $y \in \mathcal{VS}^{stor}$ [MWh]
$\Pi^{CRM,ac}_{y,z,t} \in \mathbb{R}_+$
"Virtual" energy withdrawn by a storage AC component from the grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with activated capacity reserve margin policies, $y \in \mathcal{VS}^{stor}$ [MWh]
$\Gamma^{CRM}_{y,z,t} \in \mathbb{R}_+$
Total "virtual" state of charge being held in reserves for technology $y$ at time step $t$ in zone $z$ - only applicable for standalone storage and co-located VRE and storage resources with activated capacity reserve margin policies, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [MWh]
Electricity demand in zone $z$ and at time step $t$ [MWh]
$\tau^{period}$
number of time steps in each representative period $w \in \mathcal{W}^{rep}$ and each input period $w \in \mathcal{W}^{input}$
$\omega_{t}$
weight of each model time step $\omega_t =1 \forall t \in T$ when modeling each time step of the year at an hourly resolution [1/year]
$n_s^{slope}$
Cost of non-served energy/demand curtailment for price-responsive demand segment $s$ [$/MWh]
$n_s^{size}$
Size of price-responsive demand segment $s$ as a fraction of the hourly zonal demand [%]
$\overline{\Omega}_{y,z}$
Maximum capacity of technology $y$ in zone $z$ [MW] (Note that for co-located VRE and storage resources, this value represents the maximum grid connection capacity in MW AC)
$\underline{\Omega}_{y,z}$
Minimum capacity of technology $y$ in zone $z$ [MW] (Note that for co-located VRE and storage resources, this value represents the minimum grid connection capacity in MW AC)
$\overline{\Omega}^{energy}_{y,z}$
Maximum energy capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [MWh] (Note that for co-located VRE and storage resources, this value represents the maximum storage component in MWh)
$\underline{\Omega}^{energy}_{y,z}$
Minimum energy capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [MWh] (Note that for co-located VRE and storage resources, this value represents the minimum storage component in MWh)
$\overline{\Omega}^{charge}_{y,z}$
Maximum charging power capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O}^{asym}$ [MW]
$\underline{\Omega}^{charge}_{y,z}$
Minimum charging capacity of technology $y$ in zone $z$- only applicable for storage resources, $y \in \mathcal{O}^{asym}$ [MW]
$\overline{\Omega}^{pv}_{y,z}$
Maximum solar PV capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [MW DC]
$\underline{\Omega}^{pv}_{y,z}$
Minimum solar PV capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [MW DC]
$\overline{\Omega}^{wind}_{y,z}$
Maximum wind capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [MW AC]
$\underline{\Omega}^{wind}_{y,z}$
Minimum wind capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [MW AC]
$\overline{\Omega}^{inv}_{y,z}$
Maximum inverter capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [MW AC]
$\underline{\Omega}^{inv}_{y,z}$
Minimum inverter capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [MW AC]
$\overline{\Omega}^{dc,dis}_{y,z}$
Maximum storage DC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [MW DC]
$\underline{\Omega}^{dc,dis}_{y,z}$
Minimum storage DC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [MW DC]
$\overline{\Omega}^{dc,cha}_{y,z}$
Maximum storage DC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [MW DC]
$\underline{\Omega}^{dc,cha}_{y,z}$
Minimum storage DC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [MW DC]
$\overline{\Omega}^{ac,dis}_{y,z}$
Maximum storage AC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [MW AC]
$\underline{\Omega}^{ac,dis}_{y,z}$
Minimum storage AC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [MW AC]
$\overline{\Omega}^{ac,cha}_{y,z}$
Maximum storage AC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC charge component, $y \in \mathcal{VS}^{asym,ac,cha}$ [MW AC]
$\underline{\Omega}^{ac,cha}_{y,z}$
Minimum storage AC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC charge component, $y \in \mathcal{VS}^{asym,ac,cha}$ [MW AC]
$\overline{\Delta}_{y,z}$
Existing installed capacity of technology $y$ in zone $z$ [MW] (Note that for co-located VRE and storage resources, this value represents the existing installed capacity of the grid connection in [MW AC])
$\overline{\Delta^{energy}_{y,z}}$
Existing installed energy capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [MWh] (Note that for co-located VRE and storage resources, this value represents the existing installed energy capacity of the storage component in MWh)
$\overline{\Delta^{charge}_{y,z}}$
Existing installed charging capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O}$ [MW]
$\overline{\Delta^{pv}_{y,z}}$
Existing installed solar PV capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [MW DC]
$\overline{\Delta^{wind}_{y,z}}$
Existing installed wind capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [MW AC]
$\overline{\Delta^{inv}_{y,z}}$
Existing installed inverter capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [MW AC]
$\overline{\Delta^{dc,dis}_{y,z}}$
Existing installed storage DC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [MW DC]
$\overline{\Delta^{dc,cha}_{y,z}}$
Existing installed storage DC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [MW DC]
$\overline{\Delta^{ac,dis}_{y,z}}$
Existing installed storage AC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [MW AC]
$\overline{\Delta^{dc,cha}_{y,z}}$
Existing installed storage AC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [MW AC]
$\overline{\Omega}_{y,z}^{size}$
Unit size of technology $y$ in zone $z$ [MW]
$\pi_{y,z}^{INVEST}$
Investment cost (annual amortization of total construction cost) for power capacity of technology $y$ in zone $z$ [$/MW-yr] (Note that for co-located VRE and storage resources, this value represents the investment cost of the grid connection capacity in $/MW AC-yr)
$\pi_{y,z}^{INVEST,energy}$
Investment cost (annual amortization of total construction cost) for energy capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{pv}$ [$/MWh-yr] (Note that for co-located VRE and storage resources, this value represents the investment cost of the energy capacity of the storage component in $/MWh-yr)
$\pi_{y,z}^{INVEST,charge}$
Investment cost (annual amortization of total construction cost) for charging power capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O}$ [$/MW-yr]
$\pi_{y,z}^{INVEST,pv}$
Investment cost (annual amortization of total construction cost) for solar PV capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [$/MW DC-yr]
$\pi_{y,z}^{INVEST,wind}$
Investment cost (annual amortization of total construction cost) for wind capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [$/MW AC-yr]
$\pi_{y,z}^{INVEST,inv}$
Investment cost (annual amortization of total construction cost) for inverter capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [$/MW AC-yr]
$\pi_{y,z}^{INVEST,dc,dis}$
Investment cost (annual amortization of total construction cost) for storage DC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [$/MW DC-yr]
$\pi_{y,z}^{INVEST,dc,cha}$
Investment cost (annual amortization of total construction cost) for storage DC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [$/MW DC-yr]
$\pi_{y,z}^{INVEST,ac,dis}$
Investment cost (annual amortization of total construction cost) for storage AC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [$/MW AC-yr]
$\pi_{y,z}^{INVEST,ac,cha}$
Investment cost (annual amortization of total construction cost) for storage AC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a storage AC charge component, $y \in \mathcal{VS}^{asym,ac,cha}$ [$/MW AC-yr]
$\pi_{y,z}^{FOM}$
Fixed O&M cost of technology $y$ in zone $z$ [$/MW-yr] (Note that for co-located VRE and storage resources, this value represents the fixed O&M cost of the grid connection capacity in $/MW AC-yr)
$\pi_{y,z}^{FOM,energy}$
Fixed O&M cost of energy component of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [$/MWh-yr] (Note that for co-located VRE and storage resources, this value represents the fixed O&M cost of the storage energy capacity in $/MWh-yr)
$\pi_{y,z}^{FOM,charge}$
Fixed O&M cost of charging power component of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O}$ [$/MW-yr]
$\pi_{y,z}^{FOM,pv}$
Fixed O&M cost of the solar PV component of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [$/MW DC-yr]
$\pi_{y,z}^{FOM,wind}$
Fixed O&M cost of the wind component of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [$/MW AC-yr]
$\pi_{y,z}^{FOM,inv}$
Fixed O&M cost of the inverter component of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [$/MW AC-yr]
$\pi_{y,z}^{FOM,dc,dis}$
Fixed O&M cost of the storage DC discharge component of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [$/MW DC-yr]
$\pi_{y,z}^{FOM,dc,cha}$
Fixed O&M cost of the storage DC charge component of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [$/MW DC-yr]
$\pi_{y,z}^{FOM,ac,dis}$
Fixed O&M cost of the storage AC discharge component of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [$/MW AC-yr]
$\pi_{y,z}^{FOM,ac,cha}$
Fixed O&M cost of the storage AC charge component of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC charge component, $y \in \mathcal{VS}^{asym,ac,cha}$ [$/MW AC-yr]
$\pi_{y,z}^{VOM}$
Variable O&M cost of technology $y$ in zone $z$ [$/MWh]
$\pi_{y,z}^{VOM,charge}$
Variable O&M cost of charging technology $y$ in zone $z$ - only applicable for storage and demand flexibility resources, $y \in \mathcal{O} \cup \mathcal{DF}$ [$/MWh]
$\pi_{y,z}^{VOM,pv}$
Variable O&M cost of the solar PV component of technology $y$ in zone $z$ - only applicable to co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [$/MWh]
$\pi_{y,z}^{VOM,wind}$
Variable O&M cost of the wind component of technology $y$ in zone $z$ - only applicable to co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [$/MWh]
$\pi_{y,z}^{VOM,dc,dis}$
Variable O&M cost of the storage DC discharge component of technology $y$ in zone $z$ - only applicable to co-located VRE and storage resources with a storage DC discharge component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,dis}$ [$/MWh]
$\pi_{y,z}^{VOM,dc,cha}$
Variable O&M cost of the storage DC charge component of technology $y$ in zone $z$ - only applicable to co-located VRE and storage resources with a storage DC charge component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,cha}$ [$/MWh]
$\pi_{y,z}^{VOM,ac,dis}$
Variable O&M cost of the storage AC discharge component of technology $y$ in zone $z$ - only applicable to co-located VRE and storage resources with a storage AC discharge component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,dis}$ [$/MWh]
$\pi_{y,z}^{VOM,ac,cha}$
Variable O&M cost of the storage AC charge component of technology $y$ in zone $z$ - only applicable to co-located VRE and storage resources with a storage AC charge component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,cha}$ [$/MWh]
$\pi_{y,z}^{FUEL}$
Fuel cost of technology $y$ in zone $z$ [$/MWh]
$\pi_{y,z}^{START}$
Startup cost of technology $y$ in zone $z$ [$/startup]
$\upsilon^{reg}_{y,z}$
Maximum fraction of capacity that a resource $y$ in zone $z$ can contribute to frequency regulation reserve requirements
$\upsilon^{rsv}_{y,z}$
Maximum fraction of capacity that a resource $y$ in zone $z$ can contribute to upward operating (spinning) reserve requirements
$\pi^{Unmet}_{rsv}$
Cost of unmet spinning reserves in [$/MW]
$\epsilon^{demand}_{reg}$
Frequency regulation reserve requirement as a fraction of forecasted demand in each time step
$\epsilon^{vre}_{reg}$
Frequency regulation reserve requirement as a fraction of variable renewable energy generation in each time step
$\epsilon^{demand}_{rsv}$
Operating (spinning) reserve requirement as a fraction of forecasted demand in each time step
$\epsilon^{vre}_{rsv}$
Operating (spinning) reserve requirement as a fraction of forecasted variable renewable energy generation in each time step
$\epsilon_{y,z}^{CO_2}$
CO$_2$ emissions per unit energy produced by technology $y$ in zone $z$ [metric tons/MWh]
$\epsilon_{y,z,p}^{MinTech}$
Equals to 1 if a generator of technology $y$ in zone $z$ is eligible for minimum capacity carveout policy $p \in \mathcal{P}^{MinTech}$, otherwise 0
$REQ_p^{MinTech}$
The minimum capacity requirement of minimum capacity carveout policy $p \in \mathcal{P}^{MinTech}$ [MW]
$REQ_p^{MaxTech}$
The maximum capacity requirement of minimum capacity carveout policy $p \in \mathcal{P}^{MinTech}$ [MW]
$\epsilon_{y,z,p}^{CRM}$
Capacity derating factor of technology $y$ in zone $z$ for capacity reserve margin policy $p \in \mathcal{P}^{CRM}$ [fraction]
$RM_{z,p}^{CRM}$
Reserve margin of zone $z$ of capacity reserve margin policy $p \in \mathcal{P}^{CRM}$ [fraction]
$\epsilon_{z,p,mass}^{CO_2}$
Emission budget of zone $z$ under the emission cap $p \in \mathcal{P}^{CO_2}_{mass}$ [ million of metric tonnes]
$\epsilon_{z,p,demand}^{CO_2}$
Maximum carbon intensity of the demand of zone $z$ under the emission cap $p \in \mathcal{P}^{CO_2}_{demand}$ [metric tonnes/MWh]
$\epsilon_{z,p,gen}^{CO_2}$
Maximum emission rate of the generation of zone $z$ under the emission cap $p \in \mathcal{P}^{CO_2}_{gen}$ [metric tonnes/MWh]
$\rho_{y,z}^{min}$
Minimum stable power output per unit of installed capacity for technology $y$ in zone $z$ [%]
$\rho_{y,z,t}^{max}$
Maximum available generation per unit of installed capacity during time step t for technology y in zone z [%]
$\rho_{y,z,t}^{max,pv}$
Maximum available generation per unit of installed capacity for the solar PV component of a co-located VRE and storage resource during time step t for technology y in zone z [%]
$\rho_{y,z,t}^{max,wind}$
Maximum available generation per unit of installed capacity for the wind component of a co-located VRE and storage resource during time step t for technology y in zone z [%]
$VREIndex_{y,z}$
Resource bin index for VRE technology $y$ in zone $z$. $VREIndex_{y,z}=1$ for the first bin, and $VREIndex_{y,z}=0$ for remaining bins. Only defined for $y\in \mathcal{VRE}$
$\varphi^{map}_{l,z}$
Topology of the network, for line l: $\varphi^{map}_{l,z}=1$ for start zone $z$, - 1 for end zone $z$, 0 otherwise.
$\mathcal{B}_{l}$
DC-OPF coefficient for line $l$ [MWh]
$\Delta \theta^{\max}_{l}$
Maximum voltage phase angle difference for line $l$ [radian]
$\eta_{y,z}^{loss}$
Self discharge rate per time step per unit of installed capacity for storage technology $y$ in zone $z$ [%]
$\eta_{y,z}^{charge}$
Single-trip efficiency of storage charging/demand deferral for technology $y$ in zone $z$ [%]
$\eta_{y,z}^{discharge}$
Single-trip efficiency of storage (and hydro reservoir) discharging/demand satisfaction for technology $y$ in zone $z$ [%]
$\eta_{y,z}^{charge,dc}$
Single-trip efficiency of storage DC charging/demand deferral for technology $y$ in zone $z$ for co-located VRE and storage resources [%]
$\eta_{y,z}^{discharge,dc}$
Single-trip efficiency of storage DC discharging/demand satisfaction for technology $y$ in zone $z$ for co-located VRE and storage resources [%]
$\eta_{y,z}^{charge,ac}$
Single-trip efficiency of storage AC charging/demand deferral for technology $y$ in zone $z$ for co-located VRE and storage resources [%]
$\eta_{y,z}^{discharge,ac}$
Single-trip efficiency of storage AC discharging/demand satisfaction for technology $y$ in zone $z$ for co-located VRE and storage resources [%]
$\eta_{y,z}^{inverter}$
Inverter efficiency representing losses from converting DC to AC power and vice versa for technology $y$ in zone $z$ for co-located VRE and storage resources [%]
$\eta_{y,z}^{ILR,pv}$
Inverter loading ratio (the solar PV capacity sizing to the inverter capacity built) of technology $y$ in zone $z$ for co-located VRE and storage resources with a solar PV component [%]
$\eta_{y,z}^{ILR,wind}$
Inverter loading ratio (the wind PV capacity sizing to the grid connection capacity built) of technology $y$ in zone $z$ for co-located VRE and storage resources with a wind component [%]
$\mu_{y,z}^{stor}$
Ratio of energy capacity to discharge power capacity for storage technology (and hydro reservoir) $y$ in zone $z$ [MWh/MW]
$\mu_{y,z}^{dc,stor}$
Ratio of discharge power capacity to energy capacity for the storage DC component of co-located VRE and storage technology $y$ in zone $z$ [MW/MWh]
$\mu_{y,z}^{ac,stor}$
Ratio of discharge power capacity to energy capacity for the storage AC component of co-located VRE and storage technology $y$ in zone $z$ [MW/MWh]
$\mu_{y,z}^{\mathcal{DF}}$
Maximum percentage of hourly demand that can be shifted by technology $y$ in zone $z$ [%]
$\kappa_{y,z}^{up}$
Maximum ramp-up rate per time step as percentage of installed capacity of technology y in zone z [%/hr]
$\kappa_{y,z}^{down}$
Maximum ramp-down rate per time step as percentage of installed capacity of technology y in zone z [%/hr]
$\tau_{y,z}^{up}$
Minimum uptime for thermal generator type y in zone z before new shutdown [hours].
$\tau_{y,z}^{down}$
Minimum downtime or thermal generator type y in zone z before new restart [hours].
$\tau_{y,z}^{advance}$
maximum time by which flexible demand resource can be advanced [hours]
$\tau_{y,z}^{delay}$
maximum time by which flexible demand resource can be delayed [hours]
$\eta_{y,z}^{dflex}$
energy losses associated with shifting the flexible demand [%]
$\mu_{p,z}^{\mathcal{ESR}}$
share of total demand in each model zone $z \in \mathcal{ESR}^{p}$ that must be served by qualifying renewable energy resources $y \in \mathcal{G}^{ESR}_{p}$
$f(n)$
Mapping each modeled period $n \in \mathcal{N}$ to corresponding representative period $w \in \mathcal{W}$
$\eta_{y}^{electrolyzer}$
Efficiency of the electrolyzer $y$ in megawatt-hours (MWh) of electricity per metric tonne of hydrogen produced [MWh/t] (optional parameter)
$ $^{hydrogen}_y$
Price of hydrogen per metric tonne for electrolyzer $y$ [$/t] (optional parameter)
$\mathcal{Min kt}_y$
Minimum annual quantity of hydrogen that must be produced by electrolyzer $y$ in kilotonnes [kt] (optional parameter)
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
where $t$ denotes an time step and $\mathcal{T}$ is the set of time steps over which grid operations are modeled
$\mathcal{T}^{interior} \subseteq \mathcal{T}^{}$
where $\mathcal{T}^{interior}$ is the set of interior timesteps in the data series
$\mathcal{T}^{start} \subseteq \mathcal{T}$
where $\mathcal{T}^{start}$ is the set of initial timesteps in the data series. $\mathcal{T}^{start}={1}$ when representing entire year as a single contiguous period; $\mathcal{T}^{start}=\{\left(m-1\right) \times \tau^{period}+1 | m \in \mathcal{M}\}$, which corresponds to the first time step of each representative period $m \in \mathcal{M}$
$n \in \mathcal{N}$
where $n$ corresponds to a contiguous time period and $\mathcal{N}$ corresponds to the set of contiguous periods of length $\tau^{period}$ that make up the input time series (e.g. demand, variable renewable energy availability) to the model
$\mathcal{N}^{rep} \subseteq \mathcal{N}$
where $\mathcal{N}^{rep}$ corresponds to the set of representative time periods that are selected from the set of contiguous periods, $\mathcal{M}$
$m \in \mathcal{M}$
where $m$ corresponds to a representative time period and $\mathcal{M}$ corresponds to the set of representative time periods indexed as per their chronological ocurrence in the set of contiguous periods spanning the input time series data, i.e. $\mathcal{N}$
$z \in \mathcal{Z}$
where $z$ denotes a zone and $\mathcal{Z}$ is the set of zones in the network
$l \in \mathcal{L}$
where $l$ denotes a line and $\mathcal{L}$ is the set of transmission lines in the network
$y \in \mathcal{G}$
where $y$ denotes a technology and $\mathcal{G}$ is the set of available technologies
$\mathcal{H} \subseteq \mathcal{G}$
where $\mathcal{H}$ is the subset of thermal resources
$\mathcal{VRE} \subseteq \mathcal{G}$
where $\mathcal{VRE}$ is the subset of curtailable Variable Renewable Energy (VRE) resources
$\overline{\mathcal{VRE}}^{y,z}$
set of VRE resource bins for VRE technology type $y \in \mathcal{VRE}$ in zone $z$
$\mathcal{CE} \subseteq \mathcal{G}$
where $\mathcal{CE}$ is the subset of resources qualifying for the clean energy standard policy constraint
$\mathcal{UC} \subseteq \mathcal{H}$
where $\mathcal{UC}$ is the subset of thermal resources subject to unit commitment constraints
$s \in \mathcal{S}$
where $s$ denotes a segment and $\mathcal{S}$ is the set of consumers segments for price-responsive demand curtailment
$\mathcal{O} \subseteq \mathcal{G}$
where $\mathcal{O}$ is the subset of storage resources excluding heat storage and hydro storage
$o \in \mathcal{O}$
where $o$ denotes a storage technology in a set $\mathcal{O}$
$\mathcal{O}^{sym} \subseteq \mathcal{O}$
where $\mathcal{O}^{sym}$ corresponds to the set of energy storage technologies with equal (or symmetric) charge and discharge power capacities
$\mathcal{O}^{asym} \subseteq \mathcal{O}$
where $\mathcal{O}^{asym}$ corresponds to the set of energy storage technologies with independently sized (or asymmetric) charge and discharge power capacities
$\mathcal{O}^{LDES} \subseteq \mathcal{O}$
where $\mathcal{O}^{LDES}$ corresponds to the set of long-duration energy storage technologies for which inter-period energy exchange is permitted when using representative periods to model annual grid operations
$\mathcal{VS} \subseteq \mathcal{G}$
where $\mathcal{VS}$ is the subset of co-located VRE and storage resources
$\mathcal{VS}^{pv} \subseteq \mathcal{VS}$
where $\mathcal{VS}^{pv}$ corresponds to the set of co-located VRE and storage resources with a solar PV component
$\mathcal{VS}^{wind} \subseteq \mathcal{VS}$
where $\mathcal{VS}^{wind}$ corresponds to the set of co-located VRE and storage resources with a wind component
$\mathcal{VS}^{inv} \subseteq \mathcal{VS}$
where $\mathcal{VS}^{inv}$ corresponds to the set of co-located VRE and storage resources with an inverter component
$\mathcal{VS}^{stor} \subseteq \mathcal{VS}$
where $\mathcal{VS}^{stor}$ corresponds to the set of co-located VRE and storage resources with a storage component
$\mathcal{VS}^{sym, dc} \subseteq \mathcal{VS}$
where $\mathcal{VS}^{sym, dc}$ corresponds to the set of co-located VRE and storage resources with a storage DC component with equal (or symmetric) charge and discharge power capacities
$\mathcal{VS}^{sym, ac} \subseteq \mathcal{VS}$
where $\mathcal{VS}^{sym, ac}$ corresponds to the set of co-located VRE and storage resources with a storage AC component with equal (or symmetric) charge and discharge power capacities
where $\mathcal{VS}^{asym, dc, dis}$ corresponds to the set of co-located VRE and storage resources with a storage DC component with independently sized (or asymmetric) discharge power capabilities
where $\mathcal{VS}^{asym, dc, cha}$ corresponds to the set of co-located VRE and storage resources with a storage DC component with independently sized (or asymmetric) charge power capabilities
where $\mathcal{VS}^{asym, ac, dis}$ corresponds to the set of co-located VRE and storage with a storage AC component with independently sized (or asymmetric) discharge power capabilities
where $\mathcal{VS}^{asym, ac, cha}$ corresponds to the set of co-located VRE and storage resources with a storage AC component with independently sized (or asymmetric) charge power capabilities
$\mathcal{VS}^{LDES} \subseteq \mathcal{VS}$
where $\mathcal{VS}^{LDES}$ corresponds to the set of co-located VRE and storage resources with a long-duration energy storage component for which inter-period energy exchange is permitted when using representative periods to model annual grid operations
$\mathcal{W} \subseteq \mathcal{G}$
where $\mathcal{W}$ set of hydroelectric generators with water storage reservoirs
$\mathcal{W}^{nocap} \subseteq \mathcal{W}$
where $\mathcal{W}^{nocap}$ is a subset of set of $ \mathcal{W}$ and represents resources with unknown reservoir capacity
$\mathcal{W}^{cap} \subseteq \mathcal{W}$
where $\mathcal{W}^{cap}$ is a subset of set of $ \mathcal{W}$ and represents resources with known reservoir capacity
$\mathcal{MR} \subseteq \mathcal{G}$
where $\mathcal{MR}$ set of must-run resources
$\mathcal{DF} \subseteq \mathcal{G}$
where $\mathcal{DF}$ set of flexible demand resources
$\mathcal{ELECTROLYZER} \subseteq \mathcal{G}$
where $\mathcal{ELECTROLYZER}$ set of electrolyzer resources (optional set)
$\mathcal{G}_p^{ESR} \subseteq \mathcal{G}$
where $\mathcal{G}_p^{ESR}$ is a subset of $\mathcal{G}$ that is eligible for Energy Share Requirement (ESR) policy constraint $p$
$p \in \mathcal{P}$
where $p$ denotes a instance in the policy set $\mathcal{P}$
Installed capacity in terms of the number of units (each unit, being of size $\overline{\Omega}_{y,z}^{size}$) of resource $y$ in zone $z$ [Dimensionless] (Note that for co-located VRE and storage resources, this value represents the installed capacity of the grid connection in [MW AC])
$\Omega^{energy}_{y,z} \in \mathbb{R}_+$
Installed energy capacity of resource $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [MWh] (Note that for co-located VRE and storage resources, this value represents the installed capacity of the storage component in MWh)
$\Omega^{charge}_{y,z} \in \mathbb{R}_+$
Installed charging power capacity of resource $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O}^{asym}$ [MW]
$\Omega^{pv}_{y,z} \in \mathbb{R}_+$
Installed solar PV capacity of resource $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [MW DC]
$\Omega^{wind}_{y,z} \in \mathbb{R}_+$
Installed wind capacity of resource $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [MW AC]
$\Omega^{inv}_{y,z} \in \mathbb{R}_+$
Installed inverter capacity of resource $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [MW AC]
$\Omega^{dc,dis}_{y,z} \in \mathbb{R}_+$
Installed storage DC discharge capacity of resource $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [MW DC]
$\Omega^{dc,cha}_{y,z} \in \mathbb{R}_+$
Installed storage DC charge capacity of resource $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [MW DC]
$\Omega^{ac,dis}_{y,z} \in \mathbb{R}_+$
Installed storage AC discharge capacity of resource $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [MW AC]
$\Omega^{ac,cha}_{y,z} \in \mathbb{R}_+$
Installed storage AC charge capacity of resource $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC charge component, $y \in \mathcal{VS}^{asym,ac,cha}$ [MW AC]
$\Delta_{y,z} \in \mathbb{R}_+$
Retired capacity of technology $y$ from existing capacity in zone $z$ [MW] (Note that for co-located VRE and storage resources, this value represents the retired capacity of the grid connection in MW AC)
$\Delta^{energy}_{y,z} \in \mathbb{R}_+$
Retired energy capacity of technology $y$ from existing capacity in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [MWh] (Note that for co-located VRE and storage resources, this value represents the retired capacity of the storage component in MWh)
$\Delta^{charge}_{y,z} \in \mathbb{R}_+$
Retired charging capacity of technology $y$ from existing capacity in zone $z$ - only applicable for storage resources, $y \in \mathcal{O}^{asym}$[MW]
$\Delta^{pv}_{y,z} \in \mathbb{R}_+$
Retired solar PV capacity of technology $y$ from existing capacity in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [MW DC]
$\Delta^{wind}_{y,z} \in \mathbb{R}_+$
Retired wind capacity of technology $y$ from existing capacity in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [MW AC]
$\Delta^{inv}_{y,z} \in \mathbb{R}_+$
Retired inverter capacity of technology $y$ from existing capacity in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [MW AC]
$\Delta^{dc,dis}_{y,z} \in \mathbb{R}_+$
Retired storage DC discharge capacity of technology $y$ from existing capacity in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [MW DC]
$\Delta^{dc,cha}_{y,z} \in \mathbb{R}_+$
Retired storage DC charge capacity of technology $y$ from existing capacity in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [MW DC]
$\Delta^{ac,dis}_{y,z} \in \mathbb{R}_+$
Retired storage AC discharge capacity of technology $y$ from existing capacity in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [MW AC]
$\Delta^{ac,cha}_{y,z} \in \mathbb{R}_+$
Retired storage AC charge capacity of technology $y$ from existing capacity in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC charge component, $y \in \mathcal{VS}^{asym,ac,cha}$ [MW AC]
$\Delta_{y,z}^{total} \in \mathbb{R}_+$
Total installed capacity of technology $y$ in zone $z$ [MW] (Note that co-located VRE and storage resources, this value represents the total capacity of the grid connection in MW AC)
$\Delta_{y,z}^{total,energy} \in \mathbb{R}_+$
Total installed energy capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [MWh] (Note that co-located VRE and storage resources, this value represents the total installed energy capacity of the storage component in MWh)
$\Delta_{y,z}^{total,charge} \in \mathbb{R}_+$
Total installed charging power capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O}^{asym}$ [MW]
$\Delta_{y,z}^{total,pv} \in \mathbb{R}_+$
Total installed solar PV capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [MW DC]
$\Delta_{y,z}^{total,wind} \in \mathbb{R}_+$
Total installed wind capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [MW AC]
$\Delta_{y,z}^{total,inv} \in \mathbb{R}_+$
Total installed inverter capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [MW AC]
$\Delta_{y,z}^{total,dc,dis} \in \mathbb{R}_+$
Total installed storage DC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [MW DC]
$\Delta_{y,z}^{total,dc,cha} \in \mathbb{R}_+$
Total installed storage DC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [MW DC]
$\Delta_{y,z}^{total,ac,dis} \in \mathbb{R}_+$
Total installed storage AC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [MW AC]
$\Delta_{y,z}^{total,ac,cha} \in \mathbb{R}_+$
Total installed storage AC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC charge component, $y \in \mathcal{VS}^{asym,ac,cha}$ [MW AC]
$\bigtriangleup\varphi^{max}_{l}$
Additional transmission capacity added to line $l$ [MW]
$\Theta_{y,z,t} \in \mathbb{R}_+$
Energy injected into the grid by technology $y$ at time step $t$ in zone $z$ [MWh]
$\Theta^{pv}_{y,z,t} \in \mathbb{R}_+$
Energy generated by the solar PV component into the grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [MWh]
$\Theta^{wind}_{y,z,t} \in \mathbb{R}_+$
Energy generated by the wind component into the grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [MWh]
$\Theta^{dc}_{y,z,t} \in \mathbb{R}_+$
Energy discharged by the storage DC component into the grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with a discharge DC component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,dis}$ [MWh]
$\Theta^{ac}_{y,z,t} \in \mathbb{R}_+$
Energy discharged by the storage AC component into the grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with a discharge AC component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,dis}$ [MWh]
$\Pi_{y,z,t} \in \mathbb{R}_+$
Energy withdrawn from grid by technology $y$ at time step $t$ in zone $z$ [MWh]
$\Pi^{dc}_{y,z,t} \in \mathbb{R}_+$
Energy withdrawn from the VRE and grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with a charge DC component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,cha}$ [MWh]
$\Pi^{ac}_{y,z,t} \in \mathbb{R}_+$
Energy withdrawn from the VRE and grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with a charge AC component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,cha}$ [MWh]
$\Gamma_{y,z,t} \in \mathbb{R}_+$
Stored energy level of technology $y$ at end of time step $t$ in zone $z$ [MWh]
$\Lambda_{s,z,t} \in \mathbb{R}_+$
Non-served energy/curtailed demand from the price-responsive demand segment $s$ in zone $z$ at time step $t$ [MWh]
$l_{l,t} \in \mathbb{R}_+$
Losses in line $l$ at time step $t$ [MWh]
$\varrho_{y,z,t}\in \mathbb{R}_+$
Spillage from a reservoir technology $y$ at end of time step $t$ in zone $z$ [MWh]
$f_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves from technology $y$ in zone $z$ at time $t$\footnote{Regulation reserve contribution are modeled to be symmetric, consistent with current practice in electricity markets}
$r_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] from technology $y$ in zone $z$ at time t (we are not modeling down spinning reserves since these are usually never binding for high variable renewable energy systems)
$f^{charge}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves from charging storage technology $y$ in zone $z$ at time $t$
$f^{discharge}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves from discharging storage technology $y$ in zone $z$ at time $t$
$r^{charge}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] from charging storage technology $y$ in zone $z$ at time $t$
$r^{discharge}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] from discharging storage technology $y$ in zone $z$ at time $t$
$r^{unmet}_t \in \mathbb{R}_+$
Shortfall in provision of upward operating spinning reserves during each time period $t \in T$
$f^{pv}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves for the solar PV component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$
$r^{pv}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] for the solar PV component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$
$f^{wind}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves for the wind component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$
$r^{wind}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] for the wind component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$
$f^{dc,dis}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves for the storage DC discharge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage DC discharge component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,dis}$
$r^{dc,dis}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] for the storage DC discharge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage DC discharge component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,dis}$
$f^{dc,cha}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves for the storage DC charge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage DC charge component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,cha}$
$r^{dc,cha}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] for the storage DC charge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage DC charge component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,cha}$
$f^{ac,dis}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves for the storage AC discharge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage AC discharge component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,dis}$
$r^{ac,dis}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] for the storage AC discharge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage AC discharge component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,dis}$
$f^{ac,cha}_{y,z,t}\in \mathbb{R}_+$
Frequency regulation contribution [MW] for up and down reserves for the storage AC charge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage AC charge component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,cha}$
$r^{ac,cha}_{y,z,t} \in \mathbb{R}_+$
Upward spinning reserves contribution [MW] for the storage AC charge component from technology $y$ in zone $z$ at time $t$ - only applicable for co-located VRE and storage resources with a storage AC charge component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,cha}$
$\alpha^{Contingency,Aux}_{y,z} \in \{0,1\}$
Binary variable that is set to be 1 if the total installed capacity $\Delta^{\text{total}}_{y,z} > 0$ for any generator $y \in \mathcal{UC}$ and zone $z$, and can be 0 otherwise
$\Phi_{l,t} \in \mathbb{R}_+$
Power flow in line $l$ at time step $t$ [MWh]
$\theta_{z,t} \in \mathbb{R}$
Volta phase angle in zone $z$ at time step $t$ [radian]
$v_{y,z,t}$
Commitment state of the generation cluster $y$ in zone $z$ at time $t$
$\mathcal{X}_{y,z,t}$
Number of startup decisions, of the generation cluster $y$ in zone $z$ at time $t$
$\zeta_{y,z,t}$
Number of shutdown decisions, of the generation cluster $y$ in zone $z$ at time $t$
$\mathcal{Q}_{o,n} \in \mathbb{R}_+$
Inventory of storage of type $o$ at the beginning of input period $n$ [MWh]
$\Delta\mathcal{Q}_{o,m} \in \mathbb{R}$
Excess storage inventory built up during representative period $m$ [MWh]
$ON^{+}_{l,t} \in {0,1}$
Binary variable to activate positive flows on line $l$ in time $t$
$TransON^{+}_{l,t} \in \mathbb{R}_+$
Variable defining maximum positive flow in line $l$ in time $t$ [MW]
$\Theta^{CRM}_{y,z,t} \in \mathbb{R}_+$
"Virtual" energy discharged by a storage resource that contributes to the capacity reserve margin for technology $y$ at time step $t$ in zone $z$ - only applicable for storage resources with activated capacity reserve margin policies, $y \in \mathcal{O}$ [MWh]
$\Pi^{CRM}_{y,z,t} \in \mathbb{R}_+$
"Virtual" energy withdrawn by a storage resource from the grid by technology $y$ at time step $t$ in zone $z$ - only applicable for storage resources with activated capacity reserve margin policies, $y \in \mathcal{O}$ [MWh]
$\Theta^{CRM,dc}_{y,z,t} \in \mathbb{R}_+$
"Virtual" energy discharged by a storage DC component that contributes to the capacity reserve margin for technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with activated capacity reserve margin policies, $y \in \mathcal{VS}^{stor}$ [MWh]
$\Pi^{CRM,dc}_{y,z,t} \in \mathbb{R}_+$
"Virtual" energy withdrawn by a storage DC component from the grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with activated capacity reserve margin policies, $y \in \mathcal{VS}^{stor}$ [MWh]
$\Theta^{CRM,ac}_{y,z,t} \in \mathbb{R}_+$
"Virtual" energy discharged by a storage AC component that contributes to the capacity reserve margin for technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with activated capacity reserve margin policies, $y \in \mathcal{VS}^{stor}$ [MWh]
$\Pi^{CRM,ac}_{y,z,t} \in \mathbb{R}_+$
"Virtual" energy withdrawn by a storage AC component from the grid by technology $y$ at time step $t$ in zone $z$ - only applicable for co-located VRE and storage resources with activated capacity reserve margin policies, $y \in \mathcal{VS}^{stor}$ [MWh]
$\Gamma^{CRM}_{y,z,t} \in \mathbb{R}_+$
Total "virtual" state of charge being held in reserves for technology $y$ at time step $t$ in zone $z$ - only applicable for standalone storage and co-located VRE and storage resources with activated capacity reserve margin policies, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [MWh]
Electricity demand in zone $z$ and at time step $t$ [MWh]
$\tau^{period}$
number of time steps in each representative period $w \in \mathcal{W}^{rep}$ and each input period $w \in \mathcal{W}^{input}$
$\omega_{t}$
weight of each model time step $\omega_t =1 \forall t \in T$ when modeling each time step of the year at an hourly resolution [1/year]
$n_s^{slope}$
Cost of non-served energy/demand curtailment for price-responsive demand segment $s$ [$/MWh]
$n_s^{size}$
Size of price-responsive demand segment $s$ as a fraction of the hourly zonal demand [%]
$\overline{\Omega}_{y,z}$
Maximum capacity of technology $y$ in zone $z$ [MW] (Note that for co-located VRE and storage resources, this value represents the maximum grid connection capacity in MW AC)
$\underline{\Omega}_{y,z}$
Minimum capacity of technology $y$ in zone $z$ [MW] (Note that for co-located VRE and storage resources, this value represents the minimum grid connection capacity in MW AC)
$\overline{\Omega}^{energy}_{y,z}$
Maximum energy capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [MWh] (Note that for co-located VRE and storage resources, this value represents the maximum storage component in MWh)
$\underline{\Omega}^{energy}_{y,z}$
Minimum energy capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [MWh] (Note that for co-located VRE and storage resources, this value represents the minimum storage component in MWh)
$\overline{\Omega}^{charge}_{y,z}$
Maximum charging power capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O}^{asym}$ [MW]
$\underline{\Omega}^{charge}_{y,z}$
Minimum charging capacity of technology $y$ in zone $z$- only applicable for storage resources, $y \in \mathcal{O}^{asym}$ [MW]
$\overline{\Omega}^{pv}_{y,z}$
Maximum solar PV capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [MW DC]
$\underline{\Omega}^{pv}_{y,z}$
Minimum solar PV capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [MW DC]
$\overline{\Omega}^{wind}_{y,z}$
Maximum wind capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [MW AC]
$\underline{\Omega}^{wind}_{y,z}$
Minimum wind capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [MW AC]
$\overline{\Omega}^{inv}_{y,z}$
Maximum inverter capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [MW AC]
$\underline{\Omega}^{inv}_{y,z}$
Minimum inverter capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [MW AC]
$\overline{\Omega}^{dc,dis}_{y,z}$
Maximum storage DC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [MW DC]
$\underline{\Omega}^{dc,dis}_{y,z}$
Minimum storage DC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [MW DC]
$\overline{\Omega}^{dc,cha}_{y,z}$
Maximum storage DC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [MW DC]
$\underline{\Omega}^{dc,cha}_{y,z}$
Minimum storage DC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [MW DC]
$\overline{\Omega}^{ac,dis}_{y,z}$
Maximum storage AC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [MW AC]
$\underline{\Omega}^{ac,dis}_{y,z}$
Minimum storage AC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [MW AC]
$\overline{\Omega}^{ac,cha}_{y,z}$
Maximum storage AC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC charge component, $y \in \mathcal{VS}^{asym,ac,cha}$ [MW AC]
$\underline{\Omega}^{ac,cha}_{y,z}$
Minimum storage AC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC charge component, $y \in \mathcal{VS}^{asym,ac,cha}$ [MW AC]
$\overline{\Delta}_{y,z}$
Existing installed capacity of technology $y$ in zone $z$ [MW] (Note that for co-located VRE and storage resources, this value represents the existing installed capacity of the grid connection in [MW AC])
$\overline{\Delta^{energy}_{y,z}}$
Existing installed energy capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [MWh] (Note that for co-located VRE and storage resources, this value represents the existing installed energy capacity of the storage component in MWh)
$\overline{\Delta^{charge}_{y,z}}$
Existing installed charging capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O}$ [MW]
$\overline{\Delta^{pv}_{y,z}}$
Existing installed solar PV capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [MW DC]
$\overline{\Delta^{wind}_{y,z}}$
Existing installed wind capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [MW AC]
$\overline{\Delta^{inv}_{y,z}}$
Existing installed inverter capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [MW AC]
$\overline{\Delta^{dc,dis}_{y,z}}$
Existing installed storage DC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [MW DC]
$\overline{\Delta^{dc,cha}_{y,z}}$
Existing installed storage DC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [MW DC]
$\overline{\Delta^{ac,dis}_{y,z}}$
Existing installed storage AC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [MW AC]
$\overline{\Delta^{dc,cha}_{y,z}}$
Existing installed storage AC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [MW AC]
$\overline{\Omega}_{y,z}^{size}$
Unit size of technology $y$ in zone $z$ [MW]
$\pi_{y,z}^{INVEST}$
Investment cost (annual amortization of total construction cost) for power capacity of technology $y$ in zone $z$ [$/MW-yr] (Note that for co-located VRE and storage resources, this value represents the investment cost of the grid connection capacity in $/MW AC-yr)
$\pi_{y,z}^{INVEST,energy}$
Investment cost (annual amortization of total construction cost) for energy capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{pv}$ [$/MWh-yr] (Note that for co-located VRE and storage resources, this value represents the investment cost of the energy capacity of the storage component in $/MWh-yr)
$\pi_{y,z}^{INVEST,charge}$
Investment cost (annual amortization of total construction cost) for charging power capacity of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O}$ [$/MW-yr]
$\pi_{y,z}^{INVEST,pv}$
Investment cost (annual amortization of total construction cost) for solar PV capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [$/MW DC-yr]
$\pi_{y,z}^{INVEST,wind}$
Investment cost (annual amortization of total construction cost) for wind capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [$/MW AC-yr]
$\pi_{y,z}^{INVEST,inv}$
Investment cost (annual amortization of total construction cost) for inverter capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [$/MW AC-yr]
$\pi_{y,z}^{INVEST,dc,dis}$
Investment cost (annual amortization of total construction cost) for storage DC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [$/MW DC-yr]
$\pi_{y,z}^{INVEST,dc,cha}$
Investment cost (annual amortization of total construction cost) for storage DC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [$/MW DC-yr]
$\pi_{y,z}^{INVEST,ac,dis}$
Investment cost (annual amortization of total construction cost) for storage AC discharge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [$/MW AC-yr]
$\pi_{y,z}^{INVEST,ac,cha}$
Investment cost (annual amortization of total construction cost) for storage AC charge capacity of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a storage AC charge component, $y \in \mathcal{VS}^{asym,ac,cha}$ [$/MW AC-yr]
$\pi_{y,z}^{FOM}$
Fixed O&M cost of technology $y$ in zone $z$ [$/MW-yr] (Note that for co-located VRE and storage resources, this value represents the fixed O&M cost of the grid connection capacity in $/MW AC-yr)
$\pi_{y,z}^{FOM,energy}$
Fixed O&M cost of energy component of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O} \cup y \in \mathcal{VS}^{stor}$ [$/MWh-yr] (Note that for co-located VRE and storage resources, this value represents the fixed O&M cost of the storage energy capacity in $/MWh-yr)
$\pi_{y,z}^{FOM,charge}$
Fixed O&M cost of charging power component of technology $y$ in zone $z$ - only applicable for storage resources, $y \in \mathcal{O}$ [$/MW-yr]
$\pi_{y,z}^{FOM,pv}$
Fixed O&M cost of the solar PV component of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [$/MW DC-yr]
$\pi_{y,z}^{FOM,wind}$
Fixed O&M cost of the wind component of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [$/MW AC-yr]
$\pi_{y,z}^{FOM,inv}$
Fixed O&M cost of the inverter component of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an inverter component, $y \in \mathcal{VS}^{inv}$ [$/MW AC-yr]
$\pi_{y,z}^{FOM,dc,dis}$
Fixed O&M cost of the storage DC discharge component of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC discharge component, $y \in \mathcal{VS}^{asym,dc,dis}$ [$/MW DC-yr]
$\pi_{y,z}^{FOM,dc,cha}$
Fixed O&M cost of the storage DC charge component of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage DC charge component, $y \in \mathcal{VS}^{asym,dc,cha}$ [$/MW DC-yr]
$\pi_{y,z}^{FOM,ac,dis}$
Fixed O&M cost of the storage AC discharge component of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC discharge component, $y \in \mathcal{VS}^{asym,ac,dis}$ [$/MW AC-yr]
$\pi_{y,z}^{FOM,ac,cha}$
Fixed O&M cost of the storage AC charge component of technology $y$ in zone $z$ - only applicable for co-located VRE and storage resources with an asymmetric storage AC charge component, $y \in \mathcal{VS}^{asym,ac,cha}$ [$/MW AC-yr]
$\pi_{y,z}^{VOM}$
Variable O&M cost of technology $y$ in zone $z$ [$/MWh]
$\pi_{y,z}^{VOM,charge}$
Variable O&M cost of charging technology $y$ in zone $z$ - only applicable for storage and demand flexibility resources, $y \in \mathcal{O} \cup \mathcal{DF}$ [$/MWh]
$\pi_{y,z}^{VOM,pv}$
Variable O&M cost of the solar PV component of technology $y$ in zone $z$ - only applicable to co-located VRE and storage resources with a solar PV component, $y \in \mathcal{VS}^{pv}$ [$/MWh]
$\pi_{y,z}^{VOM,wind}$
Variable O&M cost of the wind component of technology $y$ in zone $z$ - only applicable to co-located VRE and storage resources with a wind component, $y \in \mathcal{VS}^{wind}$ [$/MWh]
$\pi_{y,z}^{VOM,dc,dis}$
Variable O&M cost of the storage DC discharge component of technology $y$ in zone $z$ - only applicable to co-located VRE and storage resources with a storage DC discharge component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,dis}$ [$/MWh]
$\pi_{y,z}^{VOM,dc,cha}$
Variable O&M cost of the storage DC charge component of technology $y$ in zone $z$ - only applicable to co-located VRE and storage resources with a storage DC charge component, $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{asym,dc,cha}$ [$/MWh]
$\pi_{y,z}^{VOM,ac,dis}$
Variable O&M cost of the storage AC discharge component of technology $y$ in zone $z$ - only applicable to co-located VRE and storage resources with a storage AC discharge component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,dis}$ [$/MWh]
$\pi_{y,z}^{VOM,ac,cha}$
Variable O&M cost of the storage AC charge component of technology $y$ in zone $z$ - only applicable to co-located VRE and storage resources with a storage AC charge component, $y \in \mathcal{VS}^{sym,ac} \cup y \in \mathcal{VS}^{asym,ac,cha}$ [$/MWh]
$\pi_{y,z}^{FUEL}$
Fuel cost of technology $y$ in zone $z$ [$/MWh]
$\pi_{y,z}^{START}$
Startup cost of technology $y$ in zone $z$ [$/startup]
$\upsilon^{reg}_{y,z}$
Maximum fraction of capacity that a resource $y$ in zone $z$ can contribute to frequency regulation reserve requirements
$\upsilon^{rsv}_{y,z}$
Maximum fraction of capacity that a resource $y$ in zone $z$ can contribute to upward operating (spinning) reserve requirements
$\pi^{Unmet}_{rsv}$
Cost of unmet spinning reserves in [$/MW]
$\epsilon^{demand}_{reg}$
Frequency regulation reserve requirement as a fraction of forecasted demand in each time step
$\epsilon^{vre}_{reg}$
Frequency regulation reserve requirement as a fraction of variable renewable energy generation in each time step
$\epsilon^{demand}_{rsv}$
Operating (spinning) reserve requirement as a fraction of forecasted demand in each time step
$\epsilon^{vre}_{rsv}$
Operating (spinning) reserve requirement as a fraction of forecasted variable renewable energy generation in each time step
$\epsilon_{y,z}^{CO_2}$
CO$_2$ emissions per unit energy produced by technology $y$ in zone $z$ [metric tons/MWh]
$\epsilon_{y,z,p}^{MinTech}$
Equals to 1 if a generator of technology $y$ in zone $z$ is eligible for minimum capacity carveout policy $p \in \mathcal{P}^{MinTech}$, otherwise 0
$REQ_p^{MinTech}$
The minimum capacity requirement of minimum capacity carveout policy $p \in \mathcal{P}^{MinTech}$ [MW]
$REQ_p^{MaxTech}$
The maximum capacity requirement of minimum capacity carveout policy $p \in \mathcal{P}^{MinTech}$ [MW]
$\epsilon_{y,z,p}^{CRM}$
Capacity derating factor of technology $y$ in zone $z$ for capacity reserve margin policy $p \in \mathcal{P}^{CRM}$ [fraction]
$RM_{z,p}^{CRM}$
Reserve margin of zone $z$ of capacity reserve margin policy $p \in \mathcal{P}^{CRM}$ [fraction]
$\epsilon_{z,p,mass}^{CO_2}$
Emission budget of zone $z$ under the emission cap $p \in \mathcal{P}^{CO_2}_{mass}$ [ million of metric tonnes]
$\epsilon_{z,p,demand}^{CO_2}$
Maximum carbon intensity of the demand of zone $z$ under the emission cap $p \in \mathcal{P}^{CO_2}_{demand}$ [metric tonnes/MWh]
$\epsilon_{z,p,gen}^{CO_2}$
Maximum emission rate of the generation of zone $z$ under the emission cap $p \in \mathcal{P}^{CO_2}_{gen}$ [metric tonnes/MWh]
$\rho_{y,z}^{min}$
Minimum stable power output per unit of installed capacity for technology $y$ in zone $z$ [%]
$\rho_{y,z,t}^{max}$
Maximum available generation per unit of installed capacity during time step t for technology y in zone z [%]
$\rho_{y,z,t}^{max,pv}$
Maximum available generation per unit of installed capacity for the solar PV component of a co-located VRE and storage resource during time step t for technology y in zone z [%]
$\rho_{y,z,t}^{max,wind}$
Maximum available generation per unit of installed capacity for the wind component of a co-located VRE and storage resource during time step t for technology y in zone z [%]
$VREIndex_{y,z}$
Resource bin index for VRE technology $y$ in zone $z$. $VREIndex_{y,z}=1$ for the first bin, and $VREIndex_{y,z}=0$ for remaining bins. Only defined for $y\in \mathcal{VRE}$
$\varphi^{map}_{l,z}$
Topology of the network, for line l: $\varphi^{map}_{l,z}=1$ for start zone $z$, - 1 for end zone $z$, 0 otherwise.
$\mathcal{B}_{l}$
DC-OPF coefficient for line $l$ [MWh]
$\Delta \theta^{\max}_{l}$
Maximum voltage phase angle difference for line $l$ [radian]
$\eta_{y,z}^{loss}$
Self discharge rate per time step per unit of installed capacity for storage technology $y$ in zone $z$ [%]
$\eta_{y,z}^{charge}$
Single-trip efficiency of storage charging/demand deferral for technology $y$ in zone $z$ [%]
$\eta_{y,z}^{discharge}$
Single-trip efficiency of storage (and hydro reservoir) discharging/demand satisfaction for technology $y$ in zone $z$ [%]
$\eta_{y,z}^{charge,dc}$
Single-trip efficiency of storage DC charging/demand deferral for technology $y$ in zone $z$ for co-located VRE and storage resources [%]
$\eta_{y,z}^{discharge,dc}$
Single-trip efficiency of storage DC discharging/demand satisfaction for technology $y$ in zone $z$ for co-located VRE and storage resources [%]
$\eta_{y,z}^{charge,ac}$
Single-trip efficiency of storage AC charging/demand deferral for technology $y$ in zone $z$ for co-located VRE and storage resources [%]
$\eta_{y,z}^{discharge,ac}$
Single-trip efficiency of storage AC discharging/demand satisfaction for technology $y$ in zone $z$ for co-located VRE and storage resources [%]
$\eta_{y,z}^{inverter}$
Inverter efficiency representing losses from converting DC to AC power and vice versa for technology $y$ in zone $z$ for co-located VRE and storage resources [%]
$\eta_{y,z}^{ILR,pv}$
Inverter loading ratio (the solar PV capacity sizing to the inverter capacity built) of technology $y$ in zone $z$ for co-located VRE and storage resources with a solar PV component [%]
$\eta_{y,z}^{ILR,wind}$
Inverter loading ratio (the wind PV capacity sizing to the grid connection capacity built) of technology $y$ in zone $z$ for co-located VRE and storage resources with a wind component [%]
$\mu_{y,z}^{stor}$
Ratio of energy capacity to discharge power capacity for storage technology (and hydro reservoir) $y$ in zone $z$ [MWh/MW]
$\mu_{y,z}^{dc,stor}$
Ratio of discharge power capacity to energy capacity for the storage DC component of co-located VRE and storage technology $y$ in zone $z$ [MW/MWh]
$\mu_{y,z}^{ac,stor}$
Ratio of discharge power capacity to energy capacity for the storage AC component of co-located VRE and storage technology $y$ in zone $z$ [MW/MWh]
$\mu_{y,z}^{\mathcal{DF}}$
Maximum percentage of hourly demand that can be shifted by technology $y$ in zone $z$ [%]
$\kappa_{y,z}^{up}$
Maximum ramp-up rate per time step as percentage of installed capacity of technology y in zone z [%/hr]
$\kappa_{y,z}^{down}$
Maximum ramp-down rate per time step as percentage of installed capacity of technology y in zone z [%/hr]
$\tau_{y,z}^{up}$
Minimum uptime for thermal generator type y in zone z before new shutdown [hours].
$\tau_{y,z}^{down}$
Minimum downtime or thermal generator type y in zone z before new restart [hours].
$\tau_{y,z}^{advance}$
maximum time by which flexible demand resource can be advanced [hours]
$\tau_{y,z}^{delay}$
maximum time by which flexible demand resource can be delayed [hours]
$\eta_{y,z}^{dflex}$
energy losses associated with shifting the flexible demand [%]
$\mu_{p,z}^{\mathcal{ESR}}$
share of total demand in each model zone $z \in \mathcal{ESR}^{p}$ that must be served by qualifying renewable energy resources $y \in \mathcal{G}^{ESR}_{p}$
$f(n)$
Mapping each modeled period $n \in \mathcal{N}$ to corresponding representative period $w \in \mathcal{W}$
$\eta_{y}^{electrolyzer}$
Efficiency of the electrolyzer $y$ in megawatt-hours (MWh) of electricity per metric tonne of hydrogen produced [MWh/t] (optional parameter)
$ $^{hydrogen}_y$
Price of hydrogen per metric tonne for electrolyzer $y$ [$/t] (optional parameter)
$\mathcal{Min kt}_y$
Minimum annual quantity of hydrogen that must be produced by electrolyzer $y$ in kilotonnes [kt] (optional parameter)
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
diff --git a/previews/PR662/Model_Concept_Overview/objective_function/index.html b/previews/PR662/Model_Concept_Overview/objective_function/index.html
index c022d0e256..16d79434a9 100644
--- a/previews/PR662/Model_Concept_Overview/objective_function/index.html
+++ b/previews/PR662/Model_Concept_Overview/objective_function/index.html
@@ -1,5 +1,5 @@
-Objective Function · GenX
The first summation represents the fixed costs of generation/discharge over all zones and technologies, which reflects the sum of the annualized capital cost, $\pi^{INVEST}_{y,z}$, times the total new capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM}_{y,z}$, times the net installed generation capacity, $\overline{\Omega}^{size}_{y,z} \times \Delta^{total}_{y,z}$ (e.g., existing capacity less retirements plus additions).
The second summation corresponds to the fixed cost of installed energy storage capacity and is summed over only the storage resources ($y \in \mathcal{O} \cup \mathcal{VS}^{stor}$). This term includes the sum of the annualized energy capital cost, $\pi^{INVEST,energy}_{y,z}$, times the total new energy capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, energy}_{y,z}$, times the net installed energy storage capacity, $\Delta^{total}_{y,z}$ (e.g., existing capacity less retirements plus additions).
The third summation corresponds to the fixed cost of installed charging power capacity and is summed over only over storage resources with independent/asymmetric charge and discharge power components ($y \in \mathcal{O}^{asym}$). This term includes the sum of the annualized charging power capital cost, $\pi^{INVEST,charge}_{y,z}$, times the total new charging power capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, energy}_{y,z}$, times the net installed charging power capacity, $\Delta^{total}_{y,z}$ (e.g., existing capacity less retirements plus additions).
The fourth and fifth summations correspond to the operational cost across all zones, technologies, and time steps. The fourth summation represents the sum of fuel cost, $\pi^{FUEL}_{y,z}$ (if any), plus variable O&M cost, $\pi^{VOM}_{y,z}$ times the energy generation/discharge by generation or storage resources (or demand satisfied via flexible demand resources, $y\in\mathcal{DF}$) in time step $t$, $\Theta_{y,z,t}$, and the weight of each time step $t$, $\omega_t$. The fifth summation represents the variable charging O&M cost, $\pi^{VOM,charge}_{y,z}$ times the energy withdrawn for charging by storage resources (or demand deferred by flexible demand resources) in time step $t$ , $\Pi_{y,z,t}$ and the annual weight of time step $t$,$\omega_t$. The weight of each time step, $\omega_t$, is equal to 1 when modeling grid operations over the entire year (8760 hours), but otherwise is equal to the number of hours in the year represented by the representative time step, $t$ such that the sum of $\omega_t \forall t \in T = 8760$, approximating annual operating costs.
The sixth summation represents the total cost of unserved demand across all segments $s$ of a segment-wise price-elastic demand curve, equal to the marginal value of consumption (or cost of non-served energy), $n_{s}^{slope}$, times the amount of non-served energy, $\Lambda_{y,z,t}$, for each segment on each zone during each time step (weighted by $\omega_t$).
The seventh summation represents the total cost of not meeting hourly operating reserve requirements (if modeled), where $\pi^{unmet}_{rsv}$ is the cost penalty per unit of non-served reserve requirement, and $r^{unmet}_t$ is the amount of non-served reserve requirement in each time step (weighted by $\omega_t$).
The eighth summation corresponds to the startup costs incurred by technologies to which unit commitment decisions apply (e.g. $y \in \mathcal{UC}$), equal to the cost of start-up, $\pi^{START}_{y,z}$, times the number of startup events, $\chi_{y,z,t}$, for the cluster of units in each zone and time step (weighted by $\omega_t$).
The ninth term corresponds to the transmission reinforcement or construction costs, for each transmission line (if modeled). Transmission reinforcement costs are equal to the sum across all lines of the product between the transmission reinforcement/construction cost, $pi^{TCAP}_{l}$, times the additional transmission capacity variable, $\bigtriangleup\varphi^{max}_{l}$. Note that fixed O&M and replacement capital costs (depreciation) for existing transmission capacity is treated as a sunk cost and not included explicitly in the GenX objective function.
The tenth term onwards specifically relates to the breakdown investment, fixed O&M, and variable O&M costs associated with each configurable component of a co-located VRE and storage resource. The tenth term represents to the fixed cost of installed inverter capacity and is summed over only the co-located resources with an inverter component ($y \in \mathcal{VS}^{inv}$). This term includes the sum of the annualized inverter capital cost, $\pi^{INVEST,inv}_{y,z}$, times the total new inverter capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, inv}_{y,z}$, times the net installed inverter capacity, $\Delta^{total,inv}_{y,z}$ (e.g., existing capacity less retirements plus additions). The eleventh term represents the fixed cost of installed solar PV capacity and is summed over only the co-located resources with a solar PV component ($y \in \mathcal{VS}^{pv}$). This term includes the sum of the annualized solar PV capital cost, $\pi^{INVEST,pv}_{y,z}$, times the total new solar PV capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, pv}_{y,z}$, times the net installed solar PV capacity, $\Delta^{total,pv}_{y,z}$ (e.g., existing capacity less retirements plus additions). The twelveth term represents the fixed cost of installed wind capacity and is summed over only the co-located resources with a wind component ($y \in \mathcal{VS}^{wind}$). This term includes the sum of the annualized wind capital cost, $\pi^{INVEST,wind}_{y,z}$, times the total new wind capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, wind}_{y,z}$, times the net installed wind capacity, $\Delta^{total,wind}_{y,z}$ (e.g., existing capacity less retirements plus additions). The thirteenth term represents the fixed cost of installed storage DC discharge capacity and is summed over only the co-located resources with an asymmetric storage DC discharge component ($y \in \mathcal{VS}^{asym,dc,dis}$). This term includes the sum of the annualized storage DC discharge capital cost, $\pi^{INVEST,dc,dis}_{y,z}$, times the total new storage DC discharge capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, dc, dis}_{y,z}$, times the net installed storage DC discharge capacity, $\Delta^{total,dc,dis}_{y,z}$ (e.g., existing capacity less retirements plus additions). The fourteenth term represents the fixed cost of installed storage DC charge capacity and is summed over only the co-located resources with an asymmetric storage DC charge component ($y \in \mathcal{VS}^{asym,dc,cha}$). This term includes the sum of the annualized storage DC charge capital cost, $\pi^{INVEST,dc,cha}_{y,z}$, times the total new storage DC charge capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, dc, cha}_{y,z}$, times the net installed storage DC charge capacity, $\Delta^{total,dc,cha}_{y,z}$ (e.g., existing capacity less retirements plus additions). The fifteenth term represents the fixed cost of installed storage AC discharge capacity and is summed over only the co-located resources with an asymmetric storage AC discharge component ($y \in \mathcal{VS}^{asym,ac,dis}$). This term includes the sum of the annualized storage AC discharge capital cost, $\pi^{INVEST,ac,dis}_{y,z}$, times the total new storage AC discharge capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, ac, dis}_{y,z}$, times the net installed storage AC discharge capacity, $\Delta^{total,ac,dis}_{y,z}$ (e.g., existing capacity less retirements plus additions). The sixteenth term represents to the fixed cost of installed storage AC charge capacity and is summed over only the co-located resources with an asymmetric storage AC charge component ($y \in \mathcal{VS}^{asym,ac,cha}$). This term includes the sum of the annualized storage AC charge capital cost, $\pi^{INVEST,ac,cha}_{y,z}$, times the total new storage AC charge capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, ac, cha}_{y,z}$, times the net installed storage AC charge capacity, $\Delta^{total,ac,cha}_{y,z}$ (e.g., existing capacity less retirements plus additions).
The seventeeth term onwards corresponds to the operational cost across all zones, technologies, and time steps for co-located VRE and storage resources. The seventeenth summation represents the variable O&M cost, $\pi^{VOM,pv}_{y,z}$, times the energy generation by solar PV resources ($y\in\mathcal{VS}^{pv}$) in time step $t$, $\Theta^{pv}_{y,z,t}$, the inverter efficiency, $\eta^{inverter}_{y,z}$, and the weight of each time step $t$, $\omega_t$. The eighteenth summation represents the variable O&M cost, $\pi^{VOM,wind}_{y,z}$, times the energy generation by wind resources ($y\in\mathcal{VS}^{wind}$) in time step $t$, $\Theta^{wind}_{y,z,t}$, and the weight of each time step $t$, $\omega_t$. The nineteenth summation represents the variable O&M cost, $\pi^{VOM,dc,dis}_{y,z}$, times the energy discharge by storage DC components ($y\in\mathcal{VS}^{sym,dc} \cup \mathcal{VS}^{asym,dc,dis}$) in time step $t$, $\Theta^{dc}_{y,z,t}$, the inverter efficiency, $\eta^{inverter}_{y,z}$, and the weight of each time step $t$, $\omega_t$. The twentieth summation represents the variable O&M cost, $\pi^{VOM,dc,cha}_{y,z}$, times the energy withdrawn by storage DC components ($y\in\mathcal{VS}^{sym,dc} \cup \mathcal{VS}^{asym,dc,cha}$) in time step $t$, $\Pi^{dc}_{y,z,t}$, and the weight of each time step $t$, $\omega_t$, and divided by the inverter efficiency, $\eta^{inverter}_{y,z}$. The twenty-first summation represents the variable O&M cost, $\pi^{VOM,ac,dis}_{y,z}$, times the energy discharge by storage AC components ($y\in\mathcal{VS}^{sym,ac} \cup \mathcal{VS}^{asym,ac,dis}$) in time step $t$, $\Theta^{ac}_{y,z,t}$, and the weight of each time step $t$, $\omega_t$. The twenty-second summation represents the variable O&M cost, $\pi^{VOM,ac,cha}_{y,z}$, times the energy withdrawn by storage AC components ($y\in\mathcal{VS}^{sym,ac} \cup \mathcal{VS}^{asym,ac,cha}$) in time step $t$, $\Pi^{ac}_{y,z,t}$, and the weight of each time step $t$, $\omega_t$.
In summary, the objective function can be understood as the minimization of costs associated with five sets of different decisions:
where and how to invest on capacity,
how to dispatch or operate that capacity,
which consumer demand segments to serve or curtail,
how to cycle and commit thermal units subject to unit commitment decisions,
and where and how to invest in additional transmission network capacity to increase power transfer capacity between zones.
Note however that each of these components are considered jointly and the optimization is performed over the whole problem at once as a monolithic co-optimization problem.
While the objective function is formulated as a cost minimization problem, it is also equivalent to a social welfare maximization problem, with the bulk of demand treated as inelastic and always served, and the utility of consumption for price-elastic consumers represented as a segment-wise approximation, as per the cost of unserved demand summation above.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+\end{aligned}\]
The first summation represents the fixed costs of generation/discharge over all zones and technologies, which reflects the sum of the annualized capital cost, $\pi^{INVEST}_{y,z}$, times the total new capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM}_{y,z}$, times the net installed generation capacity, $\overline{\Omega}^{size}_{y,z} \times \Delta^{total}_{y,z}$ (e.g., existing capacity less retirements plus additions).
The second summation corresponds to the fixed cost of installed energy storage capacity and is summed over only the storage resources ($y \in \mathcal{O} \cup \mathcal{VS}^{stor}$). This term includes the sum of the annualized energy capital cost, $\pi^{INVEST,energy}_{y,z}$, times the total new energy capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, energy}_{y,z}$, times the net installed energy storage capacity, $\Delta^{total}_{y,z}$ (e.g., existing capacity less retirements plus additions).
The third summation corresponds to the fixed cost of installed charging power capacity and is summed over only over storage resources with independent/asymmetric charge and discharge power components ($y \in \mathcal{O}^{asym}$). This term includes the sum of the annualized charging power capital cost, $\pi^{INVEST,charge}_{y,z}$, times the total new charging power capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, energy}_{y,z}$, times the net installed charging power capacity, $\Delta^{total}_{y,z}$ (e.g., existing capacity less retirements plus additions).
The fourth and fifth summations correspond to the operational cost across all zones, technologies, and time steps. The fourth summation represents the sum of fuel cost, $\pi^{FUEL}_{y,z}$ (if any), plus variable O&M cost, $\pi^{VOM}_{y,z}$ times the energy generation/discharge by generation or storage resources (or demand satisfied via flexible demand resources, $y\in\mathcal{DF}$) in time step $t$, $\Theta_{y,z,t}$, and the weight of each time step $t$, $\omega_t$. The fifth summation represents the variable charging O&M cost, $\pi^{VOM,charge}_{y,z}$ times the energy withdrawn for charging by storage resources (or demand deferred by flexible demand resources) in time step $t$ , $\Pi_{y,z,t}$ and the annual weight of time step $t$,$\omega_t$. The weight of each time step, $\omega_t$, is equal to 1 when modeling grid operations over the entire year (8760 hours), but otherwise is equal to the number of hours in the year represented by the representative time step, $t$ such that the sum of $\omega_t \forall t \in T = 8760$, approximating annual operating costs.
The sixth summation represents the total cost of unserved demand across all segments $s$ of a segment-wise price-elastic demand curve, equal to the marginal value of consumption (or cost of non-served energy), $n_{s}^{slope}$, times the amount of non-served energy, $\Lambda_{y,z,t}$, for each segment on each zone during each time step (weighted by $\omega_t$).
The seventh summation represents the total cost of not meeting hourly operating reserve requirements (if modeled), where $\pi^{unmet}_{rsv}$ is the cost penalty per unit of non-served reserve requirement, and $r^{unmet}_t$ is the amount of non-served reserve requirement in each time step (weighted by $\omega_t$).
The eighth summation corresponds to the startup costs incurred by technologies to which unit commitment decisions apply (e.g. $y \in \mathcal{UC}$), equal to the cost of start-up, $\pi^{START}_{y,z}$, times the number of startup events, $\chi_{y,z,t}$, for the cluster of units in each zone and time step (weighted by $\omega_t$).
The ninth term corresponds to the transmission reinforcement or construction costs, for each transmission line (if modeled). Transmission reinforcement costs are equal to the sum across all lines of the product between the transmission reinforcement/construction cost, $pi^{TCAP}_{l}$, times the additional transmission capacity variable, $\bigtriangleup\varphi^{max}_{l}$. Note that fixed O&M and replacement capital costs (depreciation) for existing transmission capacity is treated as a sunk cost and not included explicitly in the GenX objective function.
The tenth term onwards specifically relates to the breakdown investment, fixed O&M, and variable O&M costs associated with each configurable component of a co-located VRE and storage resource. The tenth term represents to the fixed cost of installed inverter capacity and is summed over only the co-located resources with an inverter component ($y \in \mathcal{VS}^{inv}$). This term includes the sum of the annualized inverter capital cost, $\pi^{INVEST,inv}_{y,z}$, times the total new inverter capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, inv}_{y,z}$, times the net installed inverter capacity, $\Delta^{total,inv}_{y,z}$ (e.g., existing capacity less retirements plus additions). The eleventh term represents the fixed cost of installed solar PV capacity and is summed over only the co-located resources with a solar PV component ($y \in \mathcal{VS}^{pv}$). This term includes the sum of the annualized solar PV capital cost, $\pi^{INVEST,pv}_{y,z}$, times the total new solar PV capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, pv}_{y,z}$, times the net installed solar PV capacity, $\Delta^{total,pv}_{y,z}$ (e.g., existing capacity less retirements plus additions). The twelveth term represents the fixed cost of installed wind capacity and is summed over only the co-located resources with a wind component ($y \in \mathcal{VS}^{wind}$). This term includes the sum of the annualized wind capital cost, $\pi^{INVEST,wind}_{y,z}$, times the total new wind capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, wind}_{y,z}$, times the net installed wind capacity, $\Delta^{total,wind}_{y,z}$ (e.g., existing capacity less retirements plus additions). The thirteenth term represents the fixed cost of installed storage DC discharge capacity and is summed over only the co-located resources with an asymmetric storage DC discharge component ($y \in \mathcal{VS}^{asym,dc,dis}$). This term includes the sum of the annualized storage DC discharge capital cost, $\pi^{INVEST,dc,dis}_{y,z}$, times the total new storage DC discharge capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, dc, dis}_{y,z}$, times the net installed storage DC discharge capacity, $\Delta^{total,dc,dis}_{y,z}$ (e.g., existing capacity less retirements plus additions). The fourteenth term represents the fixed cost of installed storage DC charge capacity and is summed over only the co-located resources with an asymmetric storage DC charge component ($y \in \mathcal{VS}^{asym,dc,cha}$). This term includes the sum of the annualized storage DC charge capital cost, $\pi^{INVEST,dc,cha}_{y,z}$, times the total new storage DC charge capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, dc, cha}_{y,z}$, times the net installed storage DC charge capacity, $\Delta^{total,dc,cha}_{y,z}$ (e.g., existing capacity less retirements plus additions). The fifteenth term represents the fixed cost of installed storage AC discharge capacity and is summed over only the co-located resources with an asymmetric storage AC discharge component ($y \in \mathcal{VS}^{asym,ac,dis}$). This term includes the sum of the annualized storage AC discharge capital cost, $\pi^{INVEST,ac,dis}_{y,z}$, times the total new storage AC discharge capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, ac, dis}_{y,z}$, times the net installed storage AC discharge capacity, $\Delta^{total,ac,dis}_{y,z}$ (e.g., existing capacity less retirements plus additions). The sixteenth term represents to the fixed cost of installed storage AC charge capacity and is summed over only the co-located resources with an asymmetric storage AC charge component ($y \in \mathcal{VS}^{asym,ac,cha}$). This term includes the sum of the annualized storage AC charge capital cost, $\pi^{INVEST,ac,cha}_{y,z}$, times the total new storage AC charge capacity added (if any), plus the Fixed O&M cost, $\pi^{FOM, ac, cha}_{y,z}$, times the net installed storage AC charge capacity, $\Delta^{total,ac,cha}_{y,z}$ (e.g., existing capacity less retirements plus additions).
The seventeeth term onwards corresponds to the operational cost across all zones, technologies, and time steps for co-located VRE and storage resources. The seventeenth summation represents the variable O&M cost, $\pi^{VOM,pv}_{y,z}$, times the energy generation by solar PV resources ($y\in\mathcal{VS}^{pv}$) in time step $t$, $\Theta^{pv}_{y,z,t}$, the inverter efficiency, $\eta^{inverter}_{y,z}$, and the weight of each time step $t$, $\omega_t$. The eighteenth summation represents the variable O&M cost, $\pi^{VOM,wind}_{y,z}$, times the energy generation by wind resources ($y\in\mathcal{VS}^{wind}$) in time step $t$, $\Theta^{wind}_{y,z,t}$, and the weight of each time step $t$, $\omega_t$. The nineteenth summation represents the variable O&M cost, $\pi^{VOM,dc,dis}_{y,z}$, times the energy discharge by storage DC components ($y\in\mathcal{VS}^{sym,dc} \cup \mathcal{VS}^{asym,dc,dis}$) in time step $t$, $\Theta^{dc}_{y,z,t}$, the inverter efficiency, $\eta^{inverter}_{y,z}$, and the weight of each time step $t$, $\omega_t$. The twentieth summation represents the variable O&M cost, $\pi^{VOM,dc,cha}_{y,z}$, times the energy withdrawn by storage DC components ($y\in\mathcal{VS}^{sym,dc} \cup \mathcal{VS}^{asym,dc,cha}$) in time step $t$, $\Pi^{dc}_{y,z,t}$, and the weight of each time step $t$, $\omega_t$, and divided by the inverter efficiency, $\eta^{inverter}_{y,z}$. The twenty-first summation represents the variable O&M cost, $\pi^{VOM,ac,dis}_{y,z}$, times the energy discharge by storage AC components ($y\in\mathcal{VS}^{sym,ac} \cup \mathcal{VS}^{asym,ac,dis}$) in time step $t$, $\Theta^{ac}_{y,z,t}$, and the weight of each time step $t$, $\omega_t$. The twenty-second summation represents the variable O&M cost, $\pi^{VOM,ac,cha}_{y,z}$, times the energy withdrawn by storage AC components ($y\in\mathcal{VS}^{sym,ac} \cup \mathcal{VS}^{asym,ac,cha}$) in time step $t$, $\Pi^{ac}_{y,z,t}$, and the weight of each time step $t$, $\omega_t$.
In summary, the objective function can be understood as the minimization of costs associated with five sets of different decisions:
where and how to invest on capacity,
how to dispatch or operate that capacity,
which consumer demand segments to serve or curtail,
how to cycle and commit thermal units subject to unit commitment decisions,
and where and how to invest in additional transmission network capacity to increase power transfer capacity between zones.
Note however that each of these components are considered jointly and the optimization is performed over the whole problem at once as a monolithic co-optimization problem.
While the objective function is formulated as a cost minimization problem, it is also equivalent to a social welfare maximization problem, with the bulk of demand treated as inelastic and always served, and the utility of consumption for price-elastic consumers represented as a segment-wise approximation, as per the cost of unserved demand summation above.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
The power balance constraint of the model ensures that electricity demand is met at every time step in each zone. As shown in the constraint, electricity demand, $D_{t,z}$, at each time step and for each zone must be strictly equal to the sum of generation, $\Theta_{y,z,t}$, from thermal technologies ($\mathcal{H}$), curtailable variable renewable energy resources ($\mathcal{VRE}$), must-run resources ($\mathcal{MR}$), and hydro resources ($\mathcal{W}$). At the same time, energy storage devices ($\mathcal{O}$) can discharge energy, $\Theta_{y,z,t}$ to help satisfy demand, while when these devices are charging, $\Pi_{y,z,t}$, they increase demand. Similarly, co-located variable renewable energy and storage resources ($\mathcal{VS}$ and $\mathcal{VS}^{stor}$ to represent co-located resources with a storage component) can generate electricity from the solar PV and/or wind component and discharge electricity from the storage resource, $\Theta_{y,z,t}$ to help satisfy demand, and charge from the grid, $\Pi_{y,z,t}$, if the storage component of the resource exists. (For the case of flexible demand resources ($\mathcal{DF}$), delaying demand, $\Pi_{y,z,t}$, decreases demand while satisfying delayed demand, $\Theta_{y,z,t}$, increases demand.) Price-responsive demand curtailment, $\Lambda_{s,z,t}$, also reduces demand. Finally, power flows, $\Phi_{l,t}$, on each line $l$ into or out of a zone (defined by the network map $\varphi^{map}_{l,z}$), are considered in the demand balance equation for each zone. By definition, power flows leaving their reference zone are positive, thus the minus sign in the below constraint. At the same time losses due to power flows increase demand, and one-half of losses across a line linking two zones are attributed to each connected zone. The losses function $\beta_{l,t}(\cdot)$ will depend on the configuration used to model losses (see Transmission).
The power balance constraint of the model ensures that electricity demand is met at every time step in each zone. As shown in the constraint, electricity demand, $D_{t,z}$, at each time step and for each zone must be strictly equal to the sum of generation, $\Theta_{y,z,t}$, from thermal technologies ($\mathcal{H}$), curtailable variable renewable energy resources ($\mathcal{VRE}$), must-run resources ($\mathcal{MR}$), and hydro resources ($\mathcal{W}$). At the same time, energy storage devices ($\mathcal{O}$) can discharge energy, $\Theta_{y,z,t}$ to help satisfy demand, while when these devices are charging, $\Pi_{y,z,t}$, they increase demand. Similarly, co-located variable renewable energy and storage resources ($\mathcal{VS}$ and $\mathcal{VS}^{stor}$ to represent co-located resources with a storage component) can generate electricity from the solar PV and/or wind component and discharge electricity from the storage resource, $\Theta_{y,z,t}$ to help satisfy demand, and charge from the grid, $\Pi_{y,z,t}$, if the storage component of the resource exists. (For the case of flexible demand resources ($\mathcal{DF}$), delaying demand, $\Pi_{y,z,t}$, decreases demand while satisfying delayed demand, $\Theta_{y,z,t}$, increases demand.) Price-responsive demand curtailment, $\Lambda_{s,z,t}$, also reduces demand. Finally, power flows, $\Phi_{l,t}$, on each line $l$ into or out of a zone (defined by the network map $\varphi^{map}_{l,z}$), are considered in the demand balance equation for each zone. By definition, power flows leaving their reference zone are positive, thus the minus sign in the below constraint. At the same time losses due to power flows increase demand, and one-half of losses across a line linking two zones are attributed to each connected zone. The losses function $\beta_{l,t}(\cdot)$ will depend on the configuration used to model losses (see Transmission).
function compute_overnight_capital_cost(settings_d::Dict,inv_costs_yr::Array,crp::Array,tech_wacc::Array)
This function computes overnight capital costs incured within the model horizon, assuming that annualized costs to be paid after the model horizon are fully recoverable, and so are not included in the cost computation.
For each resource $y \in \mathcal{G}$ with annualized investment cost $AIC_{y}$ and capital recovery period $CRP_{y}$, overnight capital costs $OCC_{y}$ are computed as follows:
function compute_overnight_capital_cost(settings_d::Dict,inv_costs_yr::Array,crp::Array,tech_wacc::Array)
This function computes overnight capital costs incured within the model horizon, assuming that annualized costs to be paid after the model horizon are fully recoverable, and so are not included in the cost computation.
For each resource $y \in \mathcal{G}$ with annualized investment cost $AIC_{y}$ and capital recovery period $CRP_{y}$, overnight capital costs $OCC_{y}$ are computed as follows:
where $WACC_y$ is the technology-specific weighted average cost of capital (set by the "WACC" field in the Generators_data.csv or Network.csv files), $H$ is the number of years remaining between the start of the current model stage and the model horizon (the end of the final model stage) and $CRP_y$ is the capital recovery period for technology $y$ (specified in Generators_data.csv).
inputs:
settings_d - dict object containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
crp - array object of capital recovery period values.
tech_wacc - array object containing technology-specific weighted costs of capital.
NOTE: The inv_costs_yr and crp arrays must be the same length; values with the same index in each array correspond to the same resource $y \in \mathcal{G}$.
returns: array object containing overnight capital costs, the discounted sum of annual investment costs incured within the model horizon.
function configure_multi_stage_inputs(inputs_d::Dict, settings_d::Dict, NetworkExpansion::Int64)
This function overwrites input parameters read in via the load_inputs() method for proper configuration of multi-stage modeling:
Overnight capital costs are computed via the compute_overnight_capital_cost() method and overwrite internal model representations of annualized investment costs.
Annualized fixed O&M costs are scaled up to represent total fixed O&M incured over the length of each model stage (specified by "StageLength" field in multi_stage_settings.yml).
Internal set representations of resources eligible for capacity retirements are overwritten to ensure compatability with multi-stage modeling.
When NetworkExpansion is active and there are multiple model zones, parameters related to transmission and network expansion are updated. First, annualized transmission reinforcement costs are converted into overnight capital costs. Next, the maximum allowable transmission line reinforcement parameter is overwritten by the model stage-specific value specified in the "Line_Max_Flow_Possible_MW" fields in the network_multi_stage.csv file. Finally, internal representations of lines eligible or not eligible for transmission expansion are overwritten based on the updated maximum allowable transmission line reinforcement parameters.
inputs:
inputs_d - dict object containing model inputs dictionary generated by load_inputs().
settings_d - dict object containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
NetworkExpansion - integer flag (0/1) indicating whether network expansion is on, set via the "NetworkExpansion" field in genx_settings.yml.
returns: dictionary containing updated model inputs, to be used in the generate_model() method.
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+\end{aligned}\]
where $WACC_y$ is the technology-specific weighted average cost of capital (set by the "WACC" field in the Generators_data.csv or Network.csv files), $H$ is the number of years remaining between the start of the current model stage and the model horizon (the end of the final model stage) and $CRP_y$ is the capital recovery period for technology $y$ (specified in Generators_data.csv).
inputs:
settings_d - dict object containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
crp - array object of capital recovery period values.
tech_wacc - array object containing technology-specific weighted costs of capital.
NOTE: The inv_costs_yr and crp arrays must be the same length; values with the same index in each array correspond to the same resource $y \in \mathcal{G}$.
returns: array object containing overnight capital costs, the discounted sum of annual investment costs incured within the model horizon.
function configure_multi_stage_inputs(inputs_d::Dict, settings_d::Dict, NetworkExpansion::Int64)
This function overwrites input parameters read in via the load_inputs() method for proper configuration of multi-stage modeling:
Overnight capital costs are computed via the compute_overnight_capital_cost() method and overwrite internal model representations of annualized investment costs.
Annualized fixed O&M costs are scaled up to represent total fixed O&M incured over the length of each model stage (specified by "StageLength" field in multi_stage_settings.yml).
Internal set representations of resources eligible for capacity retirements are overwritten to ensure compatability with multi-stage modeling.
When NetworkExpansion is active and there are multiple model zones, parameters related to transmission and network expansion are updated. First, annualized transmission reinforcement costs are converted into overnight capital costs. Next, the maximum allowable transmission line reinforcement parameter is overwritten by the model stage-specific value specified in the "Line_Max_Flow_Possible_MW" fields in the network_multi_stage.csv file. Finally, internal representations of lines eligible or not eligible for transmission expansion are overwritten based on the updated maximum allowable transmission line reinforcement parameters.
inputs:
inputs_d - dict object containing model inputs dictionary generated by load_inputs().
settings_d - dict object containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
NetworkExpansion - integer flag (0/1) indicating whether network expansion is on, set via the "NetworkExpansion" field in genx_settings.yml.
returns: dictionary containing updated model inputs, to be used in the generate_model() method.
EP_cur - JuMP model from the current model stage $p$.
EP_next - JuMP model from the next model stage $p+1$..
start_cap_d – Dictionary which contains key-value pairs of available capacity investment expression names (as Symbols) as keys and their corresponding linking constraint names (as Symbols) as values.
cap_track_d – Dictionary which contains key-value pairs of capacity addition and retirement tracking variable names (as Symbols) as keys and their corresponding linking constraint names (as Symbols) as values.
returns: JuMP expression representing a sum of Benders cuts for linking capacity investment variables to be added to the cost-to-go function.
This function instantiates Dictionary objects containing the names of linking expressions, constraints, and variables used in multi-stage modeling.
inputs:
setup - Dictionary object containing GenX settings and key parameters.
inputs – Dictionary of inputs for each model period, generated by the load_inputs() method.
returns:
start_cap_d – Dictionary which contains linking expression names as keys and linking constraint names as values, used for setting the end capacity in stage $p$ to the starting capacity in stage $p+1$.
cap_track_d – Dictionary which contains linking variable names as keys and linking constraint names as values, used for enforcing endogenous retirements.
This function sets the right hand side values of the new and retired capacity tracking linking constraints in the current stage $p$ to the realized values of the new and retired capacity tracking linking variables from the previous stage $p-1$ as part of the forward pass. where tracking linking variables are defined variables for tracking, linking and passing realized expansion and retirement of capacities of each stage to the next stage. Tracking linking variables are each defined in endogenous_retirement_discharge, endogenous_retirement_energy, and endogenous_retirement_charge functions. Three examples are "vCAPTRACK", "vCAPTRACKCHARGE", and ""vCAPTRACKENERGY"
inputs:
EP_prev - JuMP model from the previous model stage $p-1$.
EP_cur - JuMP model from the current model stage $p$.
cap_track_d – Dictionary which contains key-value pairs of capacity addition and retirement tracking variable names (as Symbols) as keys and their corresponding linking constraint names (as Symbols) as values.
cur_period – Int representing the current model stage $p$.
returns: JuMP model with updated linking constraints.
This function sets the right hand side values of the existing capacity linking constraints in the current stage $p$ to the realized values of the total available end capacity linking variable expressions from the previous stage $p-1$ as part of the forward pass.
inputs:
EP_prev - JuMP model from the previous model stage $p-1$.
EP_cur - JuMP model from the current model stage $p$.
start_cap_d – Dictionary which contains key-value pairs of available capacity investment expression names (as Symbols) as keys and their corresponding linking constraint names (as Symbols) as values.
returns: JuMP model with updated linking constraints.
EP_cur - JuMP model from the current model stage $p$.
EP_next - JuMP model from the next model stage $p+1$..
start_cap_d – Dictionary which contains key-value pairs of available capacity investment expression names (as Symbols) as keys and their corresponding linking constraint names (as Symbols) as values.
cap_track_d – Dictionary which contains key-value pairs of capacity addition and retirement tracking variable names (as Symbols) as keys and their corresponding linking constraint names (as Symbols) as values.
returns: JuMP expression representing a sum of Benders cuts for linking capacity investment variables to be added to the cost-to-go function.
This function instantiates Dictionary objects containing the names of linking expressions, constraints, and variables used in multi-stage modeling.
inputs:
setup - Dictionary object containing GenX settings and key parameters.
inputs – Dictionary of inputs for each model period, generated by the load_inputs() method.
returns:
start_cap_d – Dictionary which contains linking expression names as keys and linking constraint names as values, used for setting the end capacity in stage $p$ to the starting capacity in stage $p+1$.
cap_track_d – Dictionary which contains linking variable names as keys and linking constraint names as values, used for enforcing endogenous retirements.
This function sets the right hand side values of the new and retired capacity tracking linking constraints in the current stage $p$ to the realized values of the new and retired capacity tracking linking variables from the previous stage $p-1$ as part of the forward pass. where tracking linking variables are defined variables for tracking, linking and passing realized expansion and retirement of capacities of each stage to the next stage. Tracking linking variables are each defined in endogenous_retirement_discharge, endogenous_retirement_energy, and endogenous_retirement_charge functions. Three examples are "vCAPTRACK", "vCAPTRACKCHARGE", and ""vCAPTRACKENERGY"
inputs:
EP_prev - JuMP model from the previous model stage $p-1$.
EP_cur - JuMP model from the current model stage $p$.
cap_track_d – Dictionary which contains key-value pairs of capacity addition and retirement tracking variable names (as Symbols) as keys and their corresponding linking constraint names (as Symbols) as values.
cur_period – Int representing the current model stage $p$.
returns: JuMP model with updated linking constraints.
This function sets the right hand side values of the existing capacity linking constraints in the current stage $p$ to the realized values of the total available end capacity linking variable expressions from the previous stage $p-1$ as part of the forward pass.
inputs:
EP_prev - JuMP model from the previous model stage $p-1$.
EP_cur - JuMP model from the current model stage $p$.
start_cap_d – Dictionary which contains key-value pairs of available capacity investment expression names (as Symbols) as keys and their corresponding linking constraint names (as Symbols) as values.
returns: JuMP model with updated linking constraints.
where $\mu_{next}$ is a vector of dual values of the linking constraints defined by constr_name in EP_next, $\hat{x}_{cur}$ is a vector of realized values from the forward pass of the linking capacity investment variable expressions expr_name from EP_cur, and $x_{cur}$ is a vector of unrealized linking capacity investment variable expressions from EP_cur. inputs:
inputs:
EP_cur - JuMP model from the current model stage $p$, solved in the forward pass.
EP_next - JuMP model from the next model stage $p+1$, solved in the forward pass.
expr_name – Symbol representing the name of a JuMP expression array which contains linking capacity investment variables.
constr_name – Symbol representing the name of the array of linking JuMP constraints which contain the linking capacity investment variables.
returns: JuMP expression representing a sum of Benders cuts for linking capacity investment variables to be added to the cost-to-go function.
This function generates Bender's cut expressions for total new or retired capacity tracking linking variables in the form:
\[\begin{aligned}
+\end{aligned}\]
where $\mu_{next}$ is a vector of dual values of the linking constraints defined by constr_name in EP_next, $\hat{x}_{cur}$ is a vector of realized values from the forward pass of the linking capacity investment variable expressions expr_name from EP_cur, and $x_{cur}$ is a vector of unrealized linking capacity investment variable expressions from EP_cur. inputs:
inputs:
EP_cur - JuMP model from the current model stage $p$, solved in the forward pass.
EP_next - JuMP model from the next model stage $p+1$, solved in the forward pass.
expr_name – Symbol representing the name of a JuMP expression array which contains linking capacity investment variables.
constr_name – Symbol representing the name of the array of linking JuMP constraints which contain the linking capacity investment variables.
returns: JuMP expression representing a sum of Benders cuts for linking capacity investment variables to be added to the cost-to-go function.
where $\mu_{next}$ is a vector of dual values of the linking constraints defined by constr_name in EP_next, $\hat{x}_{cur}$ is a vector of realized values from the forward pass of the new or retired capacity tracking linking variables var_name from EP_cur, and $x_{cur}$ is a vector of unrealized new or retired capacity tracking linking variables from EP_cur.
inputs:
EP_cur - JuMP model from the current model stage $p$.
EP_next - JuMP model from the next model stage $p+1$.
var_name – Symbol representing the name of a JuMP variable array which contains total new or retired capacity tracking linking variables.
constr_name – Symbol representing the name of the array of linking JuMP constraints which contain total new or retired capacity tracking linking variables.
returns: JuMP expression representing a sum of Benders cuts for linking capacity investment variables to be added to the cost-to-go function.
This function scales the model objective function so that costs are consistent with multi-stage modeling and introduces a cost-to-go function variable to the objective function.
The updated objective function $OBJ^{*}$ returned by this method takes the form:
\[\begin{aligned}
+\end{aligned}\]
where $\mu_{next}$ is a vector of dual values of the linking constraints defined by constr_name in EP_next, $\hat{x}_{cur}$ is a vector of realized values from the forward pass of the new or retired capacity tracking linking variables var_name from EP_cur, and $x_{cur}$ is a vector of unrealized new or retired capacity tracking linking variables from EP_cur.
inputs:
EP_cur - JuMP model from the current model stage $p$.
EP_next - JuMP model from the next model stage $p+1$.
var_name – Symbol representing the name of a JuMP variable array which contains total new or retired capacity tracking linking variables.
constr_name – Symbol representing the name of the array of linking JuMP constraints which contain total new or retired capacity tracking linking variables.
returns: JuMP expression representing a sum of Benders cuts for linking capacity investment variables to be added to the cost-to-go function.
This function scales the model objective function so that costs are consistent with multi-stage modeling and introduces a cost-to-go function variable to the objective function.
The updated objective function $OBJ^{*}$ returned by this method takes the form:
where $OBJ$ is the original objective function. $OBJ$ is scaled by two terms. The first is a discount factor (applied only in the non-myopic case), which discounts costs associated with the model stage $p$ to year-0 dollars:
Note that although the objective function contains investment costs, which occur only once and thus do not need to be scaled by OPEXMULT, these costs are multiplied by a factor of $\frac{1}{WACC}$ before being added to the objective function in investment_discharge_multi_stage(), investment_charge_multi_stage(), investment_energy_multi_stage(), and transmission_multi_stage(). Thus, this step scales these costs back to their correct value.
The cost-to-go function $\alpha$ represents an approximation of future costs given the investment and retirement decisions in the current stage. It is constructed through the addition of cuts to the cost-to-go function $\alpha$ during the backwards pass.
inputs:
settings_d - Dictionary containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
EP – JuMP model.
returns: JuMP model with updated objective function.
This function run the dual dynamic programming (DDP) algorithm, as described in Pereira and Pinto (1991), and more recently, Lara et al. (2018). Note that if the algorithm does not converge within 10,000 (currently hardcoded) iterations, this function will return models with sub-optimal solutions. However, results will still be printed as if the model is finished solving. This sub-optimal termination is noted in the output with the 'Exiting Without Covergence!' message.
inputs:
models_d – Dictionary which contains a JuMP model for each model period.
setup - Dictionary object containing GenX settings and key parameters.
inputs_d – Dictionary of inputs for each model stage, generated by the load_inputs() method.
returns:
models_d – Dictionary which contains a JuMP model for each model stage, modified by this method.
stats_d – Dictionary which contains the run time, upper bound, and lower bound of each DDP iteration.
inputs_d – Dictionary of inputs for each model stage, generated by the load_inputs() method, modified by this method.
This function calls various methods which write multi-stage modeling outputs as .csv files.
inputs:
stats_d – Dictionary which contains the run time, upper bound, and lower bound of each DDP iteration.
outpath – String which represents the path to the Results directory.
settings_d - Dictionary containing settings configured in the GenX settings genx_settings.yml file as well as the multi-stage settings file multi_stage_settings.yml.
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+\end{aligned}\]
Note that although the objective function contains investment costs, which occur only once and thus do not need to be scaled by OPEXMULT, these costs are multiplied by a factor of $\frac{1}{WACC}$ before being added to the objective function in investment_discharge_multi_stage(), investment_charge_multi_stage(), investment_energy_multi_stage(), and transmission_multi_stage(). Thus, this step scales these costs back to their correct value.
The cost-to-go function $\alpha$ represents an approximation of future costs given the investment and retirement decisions in the current stage. It is constructed through the addition of cuts to the cost-to-go function $\alpha$ during the backwards pass.
inputs:
settings_d - Dictionary containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
EP – JuMP model.
returns: JuMP model with updated objective function.
This function run the dual dynamic programming (DDP) algorithm, as described in Pereira and Pinto (1991), and more recently, Lara et al. (2018). Note that if the algorithm does not converge within 10,000 (currently hardcoded) iterations, this function will return models with sub-optimal solutions. However, results will still be printed as if the model is finished solving. This sub-optimal termination is noted in the output with the 'Exiting Without Covergence!' message.
inputs:
models_d – Dictionary which contains a JuMP model for each model period.
setup - Dictionary object containing GenX settings and key parameters.
inputs_d – Dictionary of inputs for each model stage, generated by the load_inputs() method.
returns:
models_d – Dictionary which contains a JuMP model for each model stage, modified by this method.
stats_d – Dictionary which contains the run time, upper bound, and lower bound of each DDP iteration.
inputs_d – Dictionary of inputs for each model stage, generated by the load_inputs() method, modified by this method.
This function calls various methods which write multi-stage modeling outputs as .csv files.
inputs:
stats_d – Dictionary which contains the run time, upper bound, and lower bound of each DDP iteration.
outpath – String which represents the path to the Results directory.
settings_d - Dictionary containing settings configured in the GenX settings genx_settings.yml file as well as the multi-stage settings file multi_stage_settings.yml.
where $r \in \{1, ..., (p-1)\}$ is defined as the last stage such that if we built $y$ at the end of stage $r$, it would reach its end of life before the end of stage $p$. In other words, it is the largest index $r \in \{1, ..., (p-1)\}$ such that:
This function determines the model stage before which all newly built capacity must be retired. Used to enforce endogenous lifetime retirements in multi-stage modeling.
inputs:
cur_stage – An Int representing the current model stage $p$.
lifetime – An Int representing the lifetime of a particular resource.
stage_lens – An Int array representing the length $L$ of each model stage.
returns: An Int representing the model stage in before which the resource must retire due to endogenous lifetime retirements.
This function determines the model stage before which all newly built capacity must be retired. Used to enforce endogenous lifetime retirements in multi-stage modeling.
inputs:
cur_stage – An Int representing the current model stage $p$.
lifetime – An Int representing the lifetime of a particular resource.
stage_lens – An Int array representing the length $L$ of each model stage.
returns: An Int representing the model stage in before which the resource must retire due to endogenous lifetime retirements.
GenX can be used to study the long-term evolution of the power system across multiple investment stages, in the following two ways:
The user can formulate and solve a deterministic multi-stage planning problem with perfect foresight i.e. demand, cost, and policy assumptions about all stages are known and exploited to determine the least-cost investment trajectory for the entire period. The solution of this multi-stage problem relies on exploiting the decomposable nature of the multi-stage problem via the implementation of the dual dynamic programming algorithm, described in Lara et al. 2018 here. This algorithm splits up a multi-stage investment planning problem into multiple, single-period sub-problems. Each period is solved iteratively as a separate linear program sub-problem (“forward pass”), and information from future periods is shared with past periods (“backwards pass”) so that investment decisions made in subsequent iterations reflect the contributions of present-day investments to future costs. The decomposition algorithm adapts previous nested Benders methods by handling integer and continuous state variables, although at the expense of losing its finite convergence property due to potential duality gap.
The user can formulate a sequential, myopic multi-stage planning problem, where the model solves a sequence of single-stage investment planning problems wherein investment decisions in each stage are individually optimized to meet demand given assumptions for the current planning stage and with investment decisions from previous stages treated as inputs for the current stage. We refer to this as "myopic" (or shortsighted) mode since the solution does not account for information about future stages in determining investments for a given stage. This version is generally more computationally efficient than the deterministic multi-stage expansion with perfect foresight mode.
More information on this feature can be found in the section Multi-stage setup.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
GenX can be used to study the long-term evolution of the power system across multiple investment stages, in the following two ways:
The user can formulate and solve a deterministic multi-stage planning problem with perfect foresight i.e. demand, cost, and policy assumptions about all stages are known and exploited to determine the least-cost investment trajectory for the entire period. The solution of this multi-stage problem relies on exploiting the decomposable nature of the multi-stage problem via the implementation of the dual dynamic programming algorithm, described in Lara et al. 2018 here. This algorithm splits up a multi-stage investment planning problem into multiple, single-period sub-problems. Each period is solved iteratively as a separate linear program sub-problem (“forward pass”), and information from future periods is shared with past periods (“backwards pass”) so that investment decisions made in subsequent iterations reflect the contributions of present-day investments to future costs. The decomposition algorithm adapts previous nested Benders methods by handling integer and continuous state variables, although at the expense of losing its finite convergence property due to potential duality gap.
The user can formulate a sequential, myopic multi-stage planning problem, where the model solves a sequence of single-stage investment planning problems wherein investment decisions in each stage are individually optimized to meet demand given assumptions for the current planning stage and with investment decisions from previous stages treated as inputs for the current stage. We refer to this as "myopic" (or shortsighted) mode since the solution does not account for information about future stages in determining investments for a given stage. This version is generally more computationally efficient than the deterministic multi-stage expansion with perfect foresight mode.
More information on this feature can be found in the section Multi-stage setup.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
This function defines the constraints for operation of variable renewable energy (VRE) resources whose output can be curtailed ($y \in \mathcal{VRE}$), such as utility-scale solar PV or wind power resources or run-of-river hydro resources that can spill water. The operational constraints for VRE resources are a function of each technology's time-dependent hourly capacity factor (or availability factor, $\rho^{max}_{y,z,t}$), in per unit terms, and the total available capacity ($\Delta^{total}_{y,z}$).
Power output in each time step For each VRE technology type $y$ and model zone $z$, the model allows for incorporating multiple bins with different parameters for resource quality ($\rho^{max}_{y,z,t}$), maximum availability ($\overline{\Omega_{y,z}}$) and investment cost ($\Pi^{INVEST}_{y,z}$, for example, due to interconnection cost differences). We define variables related to installed capacity ($\Delta_{y,z}$) and retired capacity ($\Delta_{y,z}$) for all resource bins for a particular VRE resource type $y$ and zone $z$ ($\overline{\mathcal{VRE}}^{y,z}$). However, the variable corresponding to power output in each timestep is only defined for the first bin. Parameter $VREIndex_{y,z}$, is used to keep track of the first bin, where $VREIndex_{y,z}=1$ for the first bin and $VREIndex_{y,z}=0$ for the remaining bins. This approach allows for modeling many different bins per VRE technology type and zone while significantly reducing the number of operational variable (related to power output for each time step from each bin) added to the model with every additional bin. Thus, the maximum power output for each VRE resource type in each zone is given by the following equation:
This function defines the constraints for operation of variable renewable energy (VRE) resources whose output can be curtailed ($y \in \mathcal{VRE}$), such as utility-scale solar PV or wind power resources or run-of-river hydro resources that can spill water. The operational constraints for VRE resources are a function of each technology's time-dependent hourly capacity factor (or availability factor, $\rho^{max}_{y,z,t}$), in per unit terms, and the total available capacity ($\Delta^{total}_{y,z}$).
Power output in each time step For each VRE technology type $y$ and model zone $z$, the model allows for incorporating multiple bins with different parameters for resource quality ($\rho^{max}_{y,z,t}$), maximum availability ($\overline{\Omega_{y,z}}$) and investment cost ($\Pi^{INVEST}_{y,z}$, for example, due to interconnection cost differences). We define variables related to installed capacity ($\Delta_{y,z}$) and retired capacity ($\Delta_{y,z}$) for all resource bins for a particular VRE resource type $y$ and zone $z$ ($\overline{\mathcal{VRE}}^{y,z}$). However, the variable corresponding to power output in each timestep is only defined for the first bin. Parameter $VREIndex_{y,z}$, is used to keep track of the first bin, where $VREIndex_{y,z}=1$ for the first bin and $VREIndex_{y,z}=0$ for the remaining bins. This approach allows for modeling many different bins per VRE technology type and zone while significantly reducing the number of operational variable (related to power output for each time step from each bin) added to the model with every additional bin. Thus, the maximum power output for each VRE resource type in each zone is given by the following equation:
The above constraint is defined as an inequality instead of an equality to allow for VRE power output to be curtailed if desired. This adds the possibility of introducing VRE curtailment as an extra degree of freedom to guarantee that generation exactly meets demand in each time step. Note that if OperationalReserves=1 indicating that frequency regulation and operating reserves are modeled, then this function calls curtailable_variable_renewable_operational_reserves!(), which replaces the above constraints with a formulation inclusive of reserve provision.
When modeling operating reserves, this function is called by curtailable_variable_renewable(), which modifies the constraint for maximum power output in each time step from VRE resources to account for procuring some of the available capacity for frequency regulation ($f_{y,z,t}$) and upward operating (spinning) reserves ($r_{y,z,t}$).
\[\begin{aligned}
+\end{aligned}\]
The above constraint is defined as an inequality instead of an equality to allow for VRE power output to be curtailed if desired. This adds the possibility of introducing VRE curtailment as an extra degree of freedom to guarantee that generation exactly meets demand in each time step. Note that if OperationalReserves=1 indicating that frequency regulation and operating reserves are modeled, then this function calls curtailable_variable_renewable_operational_reserves!(), which replaces the above constraints with a formulation inclusive of reserve provision.
When modeling operating reserves, this function is called by curtailable_variable_renewable(), which modifies the constraint for maximum power output in each time step from VRE resources to account for procuring some of the available capacity for frequency regulation ($f_{y,z,t}$) and upward operating (spinning) reserves ($r_{y,z,t}$).
The amount of frequency regulation and operating reserves procured in each time step is bounded by the user-specified fraction ($\upsilon^{reg}_{y,z}$,$\upsilon^{rsv}_{y,z}$) of available capacity in each period for each reserve type, reflecting the maximum ramp rate for the VRE resource in whatever time interval defines the requisite response time for the regulation or reserve products (e.g., 5 mins or 15 mins or 30 mins). These response times differ by system operator and reserve product, and so the user should define these parameters in a self-consistent way for whatever system context they are modeling.
This function defines the expressions and constraints for operation of hydrogen electrolyzers ($y \in \mathcal{EL} \subseteq \mathcal{G}$). This is a basic implementation of hydrogen electrolyzers that allows the specification of an hourly clean supply constraint. For a richer formulation, please see the DOLPHYN code at https://github.com/macroenergy/DOLPHYN.
Expressions
Consumption of electricity by electrolyzer $y$ in time $t$, denoted by $\Pi_{y,z}$, is subtracted from power balance expression ePowerBalance (as per other demands or battery charging) and added to Energy Share Requirement policy balance (if applicable), eESR.
Revenue from hydrogen production by each electrolyzer $y$, equal to $\omega_t \times \Pi_{y,t} / \eta^{electrolyzer}_y \times \$^{hydrogen}y$, is subtracted from the objective function, where \eta^{electrolyzer}y$ is the efficiency of the electrolyzer $y$ in megawatt-hours (MWh) of electricity per metric tonne of hydrogen produced and $\$^{hydrogen}_y$ is the price of hydrogen per metric tonne for electrolyzer $y$.
Ramping limits
Electrolyzers adhere to the following ramping limits on hourly changes in power output:
This function defines the expressions and constraints for operation of hydrogen electrolyzers ($y \in \mathcal{EL} \subseteq \mathcal{G}$). This is a basic implementation of hydrogen electrolyzers that allows the specification of an hourly clean supply constraint. For a richer formulation, please see the DOLPHYN code at https://github.com/macroenergy/DOLPHYN.
Expressions
Consumption of electricity by electrolyzer $y$ in time $t$, denoted by $\Pi_{y,z}$, is subtracted from power balance expression ePowerBalance (as per other demands or battery charging) and added to Energy Share Requirement policy balance (if applicable), eESR.
Revenue from hydrogen production by each electrolyzer $y$, equal to $\omega_t \times \Pi_{y,t} / \eta^{electrolyzer}_y \times \$^{hydrogen}y$, is subtracted from the objective function, where \eta^{electrolyzer}y$ is the efficiency of the electrolyzer $y$ in megawatt-hours (MWh) of electricity per metric tonne of hydrogen produced and $\$^{hydrogen}_y$ is the price of hydrogen per metric tonne for electrolyzer $y$.
Ramping limits
Electrolyzers adhere to the following ramping limits on hourly changes in power output:
\[\begin{aligned}
\Pi_{y,t-1} - \Pi_{y,t} \leq \kappa_{y}^{down} \Delta^{\text{total}}_{y}, \hspace{1cm} \forall y \in \mathcal{EL}, \forall t \in \mathcal{T}
\end{aligned}\]
where $\eta^{electrolyzer}_y$ is the efficiency of the electrolyzer $y$ in megawatt-hours (MWh) of electricity per metric tonne of hydrogen produced and $\mathcal{Min kt}_y$ is the minimum annual quantity of hydrogen that must be produced by electrolyzer $y$ in kilotonnes. (See constraint 5 in the code)
Hourly clean supply matching constraint
This optional constraint (enabled by setting HydrogenHourlyMatching==1 in genx_settings.yml) requires generation from qualified resources ($y \in \mathcal{Qualified}$, indicated by Qualified_Hydrogen_Supply==1 in the resource .csv files) from within the same zone $z$ as the electrolyzers are located to be >= hourly consumption from electrolyzers in the zone (and any charging by qualified storage within the zone used to help increase electrolyzer utilization):
This constraint permits modeling of the 'three pillars' requirements for clean hydrogen supply of (1) new clean supply (if only new clean resources are designated as eligible), (2) that is deliverable to the electrolyzer (assuming co-location within the same modeled zone = deliverability), and (3) produced within the same hour as the electrolyzer consumes power (otherwise known as 'additionality/new supply', 'deliverability', and 'temporal matching requirements') See Ricks, Xu & Jenkins (2023), ''Minimizing emissions from grid-based hydrogen production in the United States'' Environ. Res. Lett. 18 014025 doi:10.1088/1748-9326/acacb5 for more.
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+\end{aligned}\]
(See constraint 6 in the code)
This constraint permits modeling of the 'three pillars' requirements for clean hydrogen supply of (1) new clean supply (if only new clean resources are designated as eligible), (2) that is deliverable to the electrolyzer (assuming co-location within the same modeled zone = deliverability), and (3) produced within the same hour as the electrolyzer consumes power (otherwise known as 'additionality/new supply', 'deliverability', and 'temporal matching requirements') See Ricks, Xu & Jenkins (2023), ''Minimizing emissions from grid-based hydrogen production in the United States'' Environ. Res. Lett. 18 014025 doi:10.1088/1748-9326/acacb5 for more.
This function defines the operating constraints for flexible demand resources. As implemented, flexible demand resources ($y \in \mathcal{DF}$) are characterized by: a) maximum deferrable demand as a fraction of available capacity in a particular time step $t$, $\rho^{max}_{y,z,t}$, b) the maximum time this demand can be advanced and delayed, defined by parameters, $\tau^{advance}_{y,z}$ and $\tau^{delay}_{y,z}$, respectively and c) the energy losses associated with shifting demand, $\eta_{y,z}^{dflex}$.
Tracking total deferred demand The operational constraints governing flexible demand resources are as follows. The first two constraints model keep track of inventory of deferred demand in each time step. Specifically, the amount of deferred demand remaining to be served ($\Gamma_{y,z,t}$) depends on the amount in the previous time step minus the served demand during time step $t$ ($\Theta_{y,z,t}$) while accounting for energy losses associated with demand flexibility, plus the demand that has been deferred during the current time step ($\Pi_{y,z,t}$). Note that variable $\Gamma_{y,z,t} \in \mathbb{R}$, $\forall y \in \mathcal{DF}, t \in \mathcal{T}$. Similar to hydro inventory or storage state of charge constraints, for the first time step of the year (or each representative period), we define the deferred demand level based on level of deferred demand in the last time step of the year (or each representative period).
This function defines the operating constraints for flexible demand resources. As implemented, flexible demand resources ($y \in \mathcal{DF}$) are characterized by: a) maximum deferrable demand as a fraction of available capacity in a particular time step $t$, $\rho^{max}_{y,z,t}$, b) the maximum time this demand can be advanced and delayed, defined by parameters, $\tau^{advance}_{y,z}$ and $\tau^{delay}_{y,z}$, respectively and c) the energy losses associated with shifting demand, $\eta_{y,z}^{dflex}$.
Tracking total deferred demand The operational constraints governing flexible demand resources are as follows. The first two constraints model keep track of inventory of deferred demand in each time step. Specifically, the amount of deferred demand remaining to be served ($\Gamma_{y,z,t}$) depends on the amount in the previous time step minus the served demand during time step $t$ ($\Theta_{y,z,t}$) while accounting for energy losses associated with demand flexibility, plus the demand that has been deferred during the current time step ($\Pi_{y,z,t}$). Note that variable $\Gamma_{y,z,t} \in \mathbb{R}$, $\forall y \in \mathcal{DF}, t \in \mathcal{T}$. Similar to hydro inventory or storage state of charge constraints, for the first time step of the year (or each representative period), we define the deferred demand level based on level of deferred demand in the last time step of the year (or each representative period).
\[\begin{aligned}
\Gamma_{y,z,t} = \Gamma_{y,z,t-1} -\eta_{y,z}^{dflex}\Theta_{y,z,t} +\Pi_{y,z,t} \hspace{4 cm} \forall y \in \mathcal{DF}, z \in \mathcal{Z}, t \in \mathcal{T}^{interior} \\
\Gamma_{y,z,t} = \Gamma_{y,z,t +\tau^{period}-1} -\eta_{y,z}^{dflex}\Theta_{y,z,t} +\Pi_{y,z,t} \hspace{4 cm} \forall y \in \mathcal{DF}, z \in \mathcal{Z}, t \in \mathcal{T}^{start}
\end{aligned}\]
Bounds on available demand flexibility At any given time step, the amount of demand that can be shifted or deferred cannot exceed the maximum deferrable demand, defined by product of the availability factor ($\rho^{max}_{y,t}$) times the available capacity($\Delta^{total}_{y,z}$).
A similar constraints maximum time steps of demand advancement. This is done by enforcing the sum of demand deferred ($\Pi_{y,t}$) in the following $\tau^{advance}_{y}$ time steps (e.g., t + 1 to t + $\tau^{advance}_{y}$) to be greater than or equal to the total level of energy deferred during time $t$ (-$\Gamma_{y,t}$). The negative sign is included to account for the established sign convention that treat demand deferred in advance of the actual demand is defined to be negative.
\[\begin{aligned}
\sum_{e=t+1}^{t+\tau^{advance}_{y,z}}{\Pi_{y,z,e}} \geq -\Gamma_{y,z,t}
\hspace{4 cm} \forall y \in \mathcal{DF}, z \in \mathcal{Z}, t \in \mathcal{T}
-\end{aligned}\]
If $t$ is first time step of the year (or the first time step of the representative period), then the above two constraints are implemented to look back over the last n time steps, starting with the last time step of the year (or the last time step of the representative period). This time-wrapping implementation is similar to the time-wrapping implementations used for defining the storage balance constraints for hydropower reservoir resources and energy storage resources.
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+\end{aligned}\]
If $t$ is first time step of the year (or the first time step of the representative period), then the above two constraints are implemented to look back over the last n time steps, starting with the last time step of the year (or the last time step of the representative period). This time-wrapping implementation is similar to the time-wrapping implementations used for defining the storage balance constraints for hydropower reservoir resources and energy storage resources.
This function creates variables and constraints enabling modeling of long duration storage resources when modeling representative time periods.
Storage inventory balance at beginning of each representative period The constraints in this section are used to approximate the behavior of long-duration energy storage technologies when approximating annual grid operations by modeling operations over representative periods. Previously, the state of charge balance for storage (as defined in storage_all()) assumed that state of charge at the beginning and end of each representative period has to be the same. In other words, the amount of energy built up or consumed by storage technology $o$ in zone $z$ over the representative period $m$, $\Delta Q_{o,z,m} = 0$. This assumption implicitly excludes the possibility of transferring energy from one representative period to the other which could be cost-optimal when the capital cost of energy storage capacity is relatively small. To model long-duration energy storage using representative periods, we replace the state of charge equation, such that the first term on the right hand side accounts for change in storage inventory associated with representative period $m$ ($\Delta Q_{o,z,m}$), which could be positive (net accumulation) or negative (net reduction).
This function creates variables and constraints enabling modeling of long duration storage resources when modeling representative time periods.
Storage inventory balance at beginning of each representative period The constraints in this section are used to approximate the behavior of long-duration energy storage technologies when approximating annual grid operations by modeling operations over representative periods. Previously, the state of charge balance for storage (as defined in storage_all()) assumed that state of charge at the beginning and end of each representative period has to be the same. In other words, the amount of energy built up or consumed by storage technology $o$ in zone $z$ over the representative period $m$, $\Delta Q_{o,z,m} = 0$. This assumption implicitly excludes the possibility of transferring energy from one representative period to the other which could be cost-optimal when the capital cost of energy storage capacity is relatively small. To model long-duration energy storage using representative periods, we replace the state of charge equation, such that the first term on the right hand side accounts for change in storage inventory associated with representative period $m$ ($\Delta Q_{o,z,m}$), which could be positive (net accumulation) or negative (net reduction).
\[\begin{aligned}
& \Gamma_{o,z,(m-1)\times \tau^{period}+1 } =\left(1-\eta_{o,z}^{loss}\right)\times \left(\Gamma_{o,z,m\times \tau^{period}} -\Delta Q_{o,z,m}\right) - \\
& \frac{1}{\eta_{o,z}^{discharge}}\Theta_{o,z,(m-1)\times \tau^{period}+1} + \eta_{o,z}^{charge}\Pi_{o,z,(m-1)\times \tau^{period}+1} \quad \forall o \in \mathcal{O}^{LDES}, z \in \mathcal{Z}, m \in \mathcal{M}
\end{aligned}\]
By definition $\mathcal{T}^{start}=\{\left(m-1\right) \times \tau^{period}+1 | m \in \mathcal{M}\}$, which implies that this constraint is defined for all values of $t \in T^{start}$.
Storage inventory change input periods We need additional variables and constraints to approximate energy exchange between representative periods, while accounting for their chronological occurence in the original input time series data and the possibility that two representative periods may not be adjacent to each other (see Figure below). To implement this, we introduce a new variable $Q_{o,z, n}$ that models inventory of storage technology $o \in O$ in zone $z$ in each input period $n \in \mathcal{N}$. Additionally we define a function mapping, $f: n \rightarrow m$, that uniquely maps each input period $n$ to its corresponding representative period $m$. This mapping is available as an output of the process used to identify representative periods (E.g. k-means clustering Mallapragada et al., 2018). Figure. Modeling inter-period energy exchange via long-duration storage when using representative period temporal resolution to approximate annual grid operations The following two equations define the storage inventory at the beginning of each input period $n+1$ as the sum of storage inventory at begining of previous input period $n$ plus change in storage inventory for that period. The latter is approximated by the change in storage inventory in the corresponding representative period, identified per the mapping $f(n)$. The second constraint relates the storage level of the last input period, $|N|$, with the storage level at the beginning of the first input period. Finally, if the input period is also a representative period, then a third constraint enforces that initial storage level estimated by the intra-period storage balance constraint should equal the initial storage level estimated from the inter-period storage balance constraints. Note that $|N|$ refers to the last modeled period.
Finally, the next constraint enforces that the initial storage level for each input period $n$ must be less than the installed energy capacity limit. This constraint ensures that installed energy storage capacity is consistent with the state of charge during both the operational time periods $t$ during each sample period $m$ as well as at the start of each chronologically ordered input period $n$ in the full annual time series.
\[\begin{aligned}
Q_{o,z,n} \leq \Delta^{total, energy}_{o,z}
\quad \forall n \in \mathcal{N}, o \in \mathcal{O}^{LDES}
-\end{aligned}\]
This module defines the operational constraints for reservoir hydropower plants. Hydroelectric generators with water storage reservoirs ($y \in \mathcal{W}$) are effectively modeled as energy storage devices that cannot charge from the grid and instead receive exogenous inflows to their storage reservoirs, reflecting stream flow inputs. For resources with unknown reservoir capacity ($y \in \mathcal{W}^{nocap}$), their operation is parametrized by their generation efficiency, $\eta_{y,z}^{down}$, and energy inflows to the reservoir at every time-step, represented as a fraction of the total power capacity,($\rho^{max}_{y,z,t}$). In case reservoir capacity is known ($y \in \mathcal{W}^{cap}$), an additional parameter, $\mu^{stor}_{y,z}$, referring to the ratio of energy capacity to discharge power capacity, is used to define the available reservoir storage capacity.
Storage inventory balance Reservoir hydro systems are governed by the storage inventory balance constraint given below. This constraint enforces that energy level of the reservoir resource $y$ and zone $z$ in time step $t$ ($\Gamma_{y,z,t}$) is defined as the sum of the reservoir level in the previous time step, less the amount of electricity generated, $\Theta_{y,z,t}$ (accounting for the generation efficiency, $\eta_{y,z}^{down}$), minus any spillage $\varrho_{y,z,t}$, plus the hourly inflows into the reservoir (equal to the installed reservoir discharged capacity times the normalized hourly inflow parameter $\rho^{max}_{y,z, t}$).
This module defines the operational constraints for reservoir hydropower plants. Hydroelectric generators with water storage reservoirs ($y \in \mathcal{W}$) are effectively modeled as energy storage devices that cannot charge from the grid and instead receive exogenous inflows to their storage reservoirs, reflecting stream flow inputs. For resources with unknown reservoir capacity ($y \in \mathcal{W}^{nocap}$), their operation is parametrized by their generation efficiency, $\eta_{y,z}^{down}$, and energy inflows to the reservoir at every time-step, represented as a fraction of the total power capacity,($\rho^{max}_{y,z,t}$). In case reservoir capacity is known ($y \in \mathcal{W}^{cap}$), an additional parameter, $\mu^{stor}_{y,z}$, referring to the ratio of energy capacity to discharge power capacity, is used to define the available reservoir storage capacity.
Storage inventory balance Reservoir hydro systems are governed by the storage inventory balance constraint given below. This constraint enforces that energy level of the reservoir resource $y$ and zone $z$ in time step $t$ ($\Gamma_{y,z,t}$) is defined as the sum of the reservoir level in the previous time step, less the amount of electricity generated, $\Theta_{y,z,t}$ (accounting for the generation efficiency, $\eta_{y,z}^{down}$), minus any spillage $\varrho_{y,z,t}$, plus the hourly inflows into the reservoir (equal to the installed reservoir discharged capacity times the normalized hourly inflow parameter $\rho^{max}_{y,z, t}$).
\[\begin{aligned}
&\Gamma_{y,z,t} = \Gamma_{y,z,t-1} -\frac{1}{\eta_{y,z}^{down}}\Theta_{y,z,t} - \varrho_{y,z,t} + \rho^{max}_{y,z,t} \times \Delta^{total}_{y,z} \hspace{.1 cm} \forall y \in \mathcal{W}, z \in \mathcal{Z}, t \in \mathcal{T}^{interior} \\
&\Gamma_{y,z,t} = \Gamma_{y,z,t+\tau^{period}-1} -\frac{1}{\eta_{y,z}^{down}}\Theta_{y,z,t} - \varrho_{y,z,t} + \rho^{max}_{y,z,t} \times \Delta^{total}_{y,z} \hspace{.1 cm} \forall y \in \mathcal{W}, z \in \mathcal{Z}, t \in \mathcal{T}^{start}
\end{aligned}\]
We implement time-wrapping to endogenize the definition of the intial state prior to the first period with the following assumption. If time step $t$ is the first time step of the year then storage inventory at $t$ is defined based on last time step of the year. Alternatively, if time step $t$ is the first time step of a representative period, then storage inventory at $t$ is defined based on the last time step of the representative period. Thus, when using representative periods, the storage balance constraint for hydro resources does not allow for energy exchange between representative periods. Note: in future updates, an option to model hydro resources with large reservoirs that can transfer energy across sample periods will be implemented, similar to the functions for modeling long duration energy storage in long_duration_storage.jl.
Ramping Limits The following constraints enforce hourly changes in power output (ramps down and ramps up) to be less than the maximum ramp rates ($\kappa^{down}_{y,z}$ and $\kappa^{up}_{y,z}$ ) in per unit terms times the total installed capacity of technology y ($\Delta^{total}_{y,z}$).
Reservoir energy capacity constraint In case the reservoir capacity is known ($y \in W^{cap}$), then an additional constraint enforces the total stored energy in each time step to be less than or equal to the available reservoir capacity. Here, the reservoir capacity is defined multiplying the parameter, $\mu^{stor}_{y,z}$ with the available power capacity.
\[\begin{aligned}
\Gamma_{y,z, t} \leq \mu^{stor}_{y,z}\times \Delta^{total}_{y,z}
\hspace{4 cm} \forall y \in \mathcal{W}^{cap}, z \in \mathcal{Z}, t\in \mathcal{T}
-\end{aligned}\]
This module defines the modified constraints and additional constraints needed when modeling operating reserves
Modifications when operating reserves are modeled When modeling operating reserves, the constraints regarding maximum power flow limits are modified to account for procuring some of the available capacity for frequency regulation ($f_{y,z,t}$) and "updward" operating (or spinning) reserves ($r_{y,z,t}$).
This module defines the modified constraints and additional constraints needed when modeling operating reserves
Modifications when operating reserves are modeled When modeling operating reserves, the constraints regarding maximum power flow limits are modified to account for procuring some of the available capacity for frequency regulation ($f_{y,z,t}$) and "updward" operating (or spinning) reserves ($r_{y,z,t}$).
\[\begin{aligned}
\Theta_{y,z,t} + f_{y,z,t} +r_{y,z,t} \leq \times \Delta^{total}_{y,z}
\hspace{4 cm} \forall y \in \mathcal{W}, z \in \mathcal{Z}, t\in \mathcal{T}
\end{aligned}\]
The amount of downward frequency regulation reserves cannot exceed the current power output.
\[\begin{aligned}
@@ -31,4 +31,4 @@
\hspace{4 cm} \forall y \in \mathcal{W}, z \in \mathcal{Z}, t \in \mathcal{T} \\
r_{y,z, t} \leq \upsilon^{rsv}_{y,z}\times \Delta^{total}_{y,z}
\hspace{4 cm} \forall y \in \mathcal{W}, z \in \mathcal{Z}, t \in \mathcal{T}
-\end{aligned}\]
This function defines the expressions and constraints keeping track of total available storage charge capacity across all resources as well as constraints on capacity retirements. The function also adds investment and fixed O\&M related costs related to charge capacity to the objective function.
The total capacity of each resource is defined as the sum of the existing capacity plus the newly invested capacity minus any retired capacity.
This function defines the expressions and constraints keeping track of total available storage charge capacity across all resources as well as constraints on capacity retirements. The function also adds investment and fixed O\&M related costs related to charge capacity to the objective function.
The total capacity of each resource is defined as the sum of the existing capacity plus the newly invested capacity minus any retired capacity.
\[\begin{aligned}
& \Delta^{total,charge}_{y,z} =(\overline{\Delta^{charge}_{y,z}}+\Omega^{charge}_{y,z}-\Delta^{charge}_{y,z}) \forall y \in \mathcal{O}^{asym}, z \in \mathcal{Z}
\end{aligned}\]
One cannot retire more capacity than existing capacity.
This function defines the expressions and constraints keeping track of total available storage charge capacity across all resources as well as constraints on capacity retirements. The function also adds investment and fixed O\&M related costs related to charge capacity to the objective function.
The total capacity of each resource is defined as the sum of the existing capacity plus the newly invested capacity minus any retired capacity.
This function defines the expressions and constraints keeping track of total available storage charge capacity across all resources as well as constraints on capacity retirements. The function also adds investment and fixed O\&M related costs related to charge capacity to the objective function.
The total capacity of each resource is defined as the sum of the existing capacity plus the newly invested capacity minus any retired capacity.
\[\begin{aligned}
& \Delta^{total,energy}_{y,z} =(\overline{\Delta^{energy}_{y,z}}+\Omega^{energy}_{y,z}-\Delta^{energy}_{y,z}) \forall y \in \mathcal{O}, z \in \mathcal{Z}
\end{aligned}\]
One cannot retire more capacity than existing capacity.
This function creates variables and constraints enabling modeling of long duration storage resources when modeling representative time periods. Storage inventory balance at beginning of each representative period The constraints in this section are used to approximate the behavior of long-duration energy storage technologies when approximating annual grid operations by modeling operations over representative periods. Previously, the state of charge balance for storage (as defined in storage_all()) assumed that state of charge at the beginning and end of each representative period has to be the same. In other words, the amount of energy built up or consumed by storage technology $o$ in zone $z$ over the representative period $m$, $\Delta Q_{o,z,m} = 0$. This assumption implicitly excludes the possibility of transferring energy from one representative period to the other which could be cost-optimal when the capital cost of energy storage capacity is relatively small. To model long-duration energy storage using representative periods, we replace the state of charge equation, such that the first term on the right hand side accounts for change in storage inventory associated with representative period $m$ ($\Delta Q_{o,z,m}$), which could be positive (net accumulation) or negative (net reduction).
This function creates variables and constraints enabling modeling of long duration storage resources when modeling representative time periods. Storage inventory balance at beginning of each representative period The constraints in this section are used to approximate the behavior of long-duration energy storage technologies when approximating annual grid operations by modeling operations over representative periods. Previously, the state of charge balance for storage (as defined in storage_all()) assumed that state of charge at the beginning and end of each representative period has to be the same. In other words, the amount of energy built up or consumed by storage technology $o$ in zone $z$ over the representative period $m$, $\Delta Q_{o,z,m} = 0$. This assumption implicitly excludes the possibility of transferring energy from one representative period to the other which could be cost-optimal when the capital cost of energy storage capacity is relatively small. To model long-duration energy storage using representative periods, we replace the state of charge equation, such that the first term on the right hand side accounts for change in storage inventory associated with representative period $m$ ($\Delta Q_{o,z,m}$), which could be positive (net accumulation) or negative (net reduction).
\[\begin{aligned}
& \Gamma_{o,z,(m-1)\times \tau^{period}+1 } =\left(1-\eta_{o,z}^{loss}\right)\times \left(\Gamma_{o,z,m\times \tau^{period}} -\Delta Q_{o,z,m}\right) - \\
& \frac{1}{\eta_{o,z}^{discharge}}\Theta_{o,z,(m-1)\times \tau^{period}+1} + \eta_{o,z}^{charge}\Pi_{o,z,(m-1)\times \tau^{period}+1} \quad \forall o \in \mathcal{O}^{LDES}, z \in \mathcal{Z}, m \in \mathcal{M}
\end{aligned}\]
By definition $\mathcal{T}^{start}=\{\left(m-1\right) \times \tau^{period}+1 | m \in \mathcal{M}\}$, which implies that this constraint is defined for all values of $t \in T^{start}$. Storage inventory change input periods We need additional variables and constraints to approximate energy exchange between representative periods, while accounting for their chronological occurence in the original input time series data and the possibility that two representative periods may not be adjacent to each other (see Figure below). To implement this, we introduce a new variable $Q_{o,z, n}$ that models inventory of storage technology $o \in O$ in zone $z$ in each input period $n \in \mathcal{N}$. Additionally we define a function mapping, $f: n \rightarrow m$, that uniquely maps each input period $n$ to its corresponding representative period $m$. This mapping is available as an output of the process used to identify representative periods (E.g. k-means clustering Mallapragada et al., 2018).
Figure. Modeling inter-period energy exchange via long-duration storage when using representative period temporal resolution to approximate annual grid operations
The following two equations define the storage inventory at the beginning of each input period $n+1$ as the sum of storage inventory at begining of previous input period $n$ plus change in storage inventory for that period. The latter is approximated by the change in storage inventory in the corresponding representative period, identified per the mapping $f(n)$. If the input period is also a representative period, then a second constraint enforces that initial storage level estimated by the intra-period storage balance constraint should equal the initial storage level estimated from the inter-period storage balance constraints.
If the capacity reserve margin constraint is enabled, a similar set of constraints is used to track the evolution of the energy held in reserve across representative periods. The main linking constraint is as follows:
\[\begin{aligned}
& \Gamma^{CRM}_{o,z,(m-1)\times \tau^{period}+1 } =\left(1-\eta_{o,z}^{loss}\right)\times \left(\Gamma^{CRM}_{o,z,m\times \tau^{period}} -\Delta Q_{o,z,m}\right) + \\
& \frac{1}{\eta_{o,z}^{discharge}}\Theta^{CRM}_{o,z,(m-1)\times \tau^{period}+1} - \eta_{o,z}^{charge}\Pi^{CRM}_{o,z,(m-1)\times \tau^{period}+1} \quad \forall o \in \mathcal{O}^{LDES}, z \in \mathcal{Z}, m \in \mathcal{M}
-\end{aligned}\]
All other constraints are identical to those used to track the actual state of charge, except with the new variables $Q^{CRM}_{o,z,n}$ and $\Delta Q^{CRM}_{o,z,n}$ used in place of $Q_{o,z,n}$ and $\Delta Q_{o,z,n}$, respectively.
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+\end{aligned}\]
All other constraints are identical to those used to track the actual state of charge, except with the new variables $Q^{CRM}_{o,z,n}$ and $\Delta Q^{CRM}_{o,z,n}$ used in place of $Q_{o,z,n}$ and $\Delta Q_{o,z,n}$, respectively.
In the real world, some types of resources (notably, fission) require regular scheduled maintenance, which often takes several weeks. During this time, the plant produces no power. This module allows GenX to find the best time of year for plants to undergo maintenance.
Scheduled maintenance is implemented only for thermal plants with unit commitment (THERM=1).
A plant requires a single contiguous period of $h \ge 1$ hours of maintenance, every $y \ge 1$ years. For each plant, the best time to start the maintenance period is determined by the optimizer.
During maintenance, the plant cannot be "commited", and therefore
uses no fuel,
produces no power,
and does not contribute to reserves.
Additionally,
the plant does not contribute to any Capacity Reserve Margin.
GenX models a long-term equilibrium, and each problem generally represents a single full year. If a plant requires maintenance every $y$ years, we take the simplification that at least $1/y$ of the plants must undergo maintenance in the modeled year.
See also "Interaction with integer unit commitment" below.
This module creates constraints which work across long periods, and consequently can be very expensive to solve. In order to reduce the expense, the set of possible maintenance start dates can be limited. Rather than have maintenance potentially start every hour, one can have possible start dates which are once per day, once per week, etc. (In reality, maintenance is likely scheduled months in advance, so optimizing down to the hour may not be realistic anyway.)
If integer unit commitment is on (UCommit=1) this module may not produce correct results; there may be more maintenance than the user wants. This is because the formulation specifies that the number of plants that go down for maintenance in the simulated year must be at least (the number of plants in the zone)/(the maintenance cycle length in years). As a reminder, the number of plants is eTotalCap / Cap_Size.
If there were three 500 MW plants (total 1500 MW) in a zone, and they require maintenance every three years (Maintenance_Cycle_Length_Years=3), the formulation will work properly: one of the three plants will go under maintenance.
But if there was only one 500 MW plant, and it requires maintenance every 3 years, the constraint will still make it do maintenance every year, because ceil(1/3) is 1. The whole 500 MW plant will do maintenance. This is the unexpected behavior.
However, if integer unit commitment was relaxed to "linearized" unit commitment (UCommit=2), the model will have only 500 MW / 3 = 166.6 MW worth of this plant do maintenance.
If you want to pre-schedule when maintenance occurs, you might not need this module. Instead, you could set the maximum power output of the plant to zero for a certain period, or make its fuel extremely expensive during that time. However, the plant would still be able to contribute to the Capacity Reserve Margin.
The formulation of the maintenance state is very similar to the formulation of unit commitment.
There is a variable called something like vMSHUT which is analogous to vSTART and controls the start of the maintenance period. There is another variable called something like vMDOWN analogous to vCOMMIT which controls the maintenance status in any hour.
A constraint ensures that the value of vMDOWN in any hour is always more than the number of vMSHUTs in the previous Maintenance_Duration hours.
Another constraint ensures that the number of plants committed (vCOMMIT) at any one time plus the number of plants under maintenance (vMDOWN) is less than the total number of plants.
In the real world, some types of resources (notably, fission) require regular scheduled maintenance, which often takes several weeks. During this time, the plant produces no power. This module allows GenX to find the best time of year for plants to undergo maintenance.
Scheduled maintenance is implemented only for thermal plants with unit commitment (THERM=1).
A plant requires a single contiguous period of $h \ge 1$ hours of maintenance, every $y \ge 1$ years. For each plant, the best time to start the maintenance period is determined by the optimizer.
During maintenance, the plant cannot be "commited", and therefore
uses no fuel,
produces no power,
and does not contribute to reserves.
Additionally,
the plant does not contribute to any Capacity Reserve Margin.
GenX models a long-term equilibrium, and each problem generally represents a single full year. If a plant requires maintenance every $y$ years, we take the simplification that at least $1/y$ of the plants must undergo maintenance in the modeled year.
See also "Interaction with integer unit commitment" below.
This module creates constraints which work across long periods, and consequently can be very expensive to solve. In order to reduce the expense, the set of possible maintenance start dates can be limited. Rather than have maintenance potentially start every hour, one can have possible start dates which are once per day, once per week, etc. (In reality, maintenance is likely scheduled months in advance, so optimizing down to the hour may not be realistic anyway.)
If integer unit commitment is on (UCommit=1) this module may not produce correct results; there may be more maintenance than the user wants. This is because the formulation specifies that the number of plants that go down for maintenance in the simulated year must be at least (the number of plants in the zone)/(the maintenance cycle length in years). As a reminder, the number of plants is eTotalCap / Cap_Size.
If there were three 500 MW plants (total 1500 MW) in a zone, and they require maintenance every three years (Maintenance_Cycle_Length_Years=3), the formulation will work properly: one of the three plants will go under maintenance.
But if there was only one 500 MW plant, and it requires maintenance every 3 years, the constraint will still make it do maintenance every year, because ceil(1/3) is 1. The whole 500 MW plant will do maintenance. This is the unexpected behavior.
However, if integer unit commitment was relaxed to "linearized" unit commitment (UCommit=2), the model will have only 500 MW / 3 = 166.6 MW worth of this plant do maintenance.
If you want to pre-schedule when maintenance occurs, you might not need this module. Instead, you could set the maximum power output of the plant to zero for a certain period, or make its fuel extremely expensive during that time. However, the plant would still be able to contribute to the Capacity Reserve Margin.
The formulation of the maintenance state is very similar to the formulation of unit commitment.
There is a variable called something like vMSHUT which is analogous to vSTART and controls the start of the maintenance period. There is another variable called something like vMDOWN analogous to vCOMMIT which controls the maintenance status in any hour.
A constraint ensures that the value of vMDOWN in any hour is always more than the number of vMSHUTs in the previous Maintenance_Duration hours.
Another constraint ensures that the number of plants committed (vCOMMIT) at any one time plus the number of plants under maintenance (vMDOWN) is less than the total number of plants.
maintenance_formulation!(EP::Model,
inputs::Dict,
resource_component::AbstractString,
r_id::Int,
@@ -31,36 +31,36 @@
commitment for operational variables.
Creates maintenance-tracking variables and adds their Symbols to two Sets in `inputs`.
-Adds constraints which act on the vCOMMIT-like variable.
resources_with_maintenance(df::DataFrame)::Vector{Int}
Get a vector of the R_ID's of all resources listed in a dataframe
that have maintenance requirements. If there are none, return an empty vector.
This method takes a specific dataframe because compound resources may have their
-data in multiple dataframes.
maintenance_down_name(resource_component::AbstractString)::String
JuMP variable name to control whether a resource-component is down for maintenance.
-Here resource-component could be a whole resource or a component (for complex resources).
maintenance_shut_name(resource_component::AbstractString)::String
+Here resource-component could be a whole resource or a component (for complex resources).
maintenance_shut_name(resource_component::AbstractString)::String
JuMP variable name to control when a resource-components begins maintenance.
-Here resource-component could be a whole resource or a component (for complex resources).
controlling_maintenance_start_hours(p::Int, t::Int, maintenance_duration::Int, maintenance_begin_hours::UnitRange{Int64})
+Here resource-component could be a whole resource or a component (for complex resources).
controlling_maintenance_start_hours(p::Int, t::Int, maintenance_duration::Int, maintenance_begin_hours::UnitRange{Int64})
p: hours_per_subperiod
t: the current hour
maintenance_duration: length of a maintenance period
-maintenance_begin_hours: collection of hours in which maintenance is allowed to start
ensure_maintenance_variable_records!(dict::Dict)
dict: a dictionary of model data
This should be called by each method that adds maintenance formulations,
-to ensure that certain entries in the model data dict exist.
has_maintenance(dict::Dict)
dict: a dictionary of model data
Checks whether the dictionary contains listings of maintenance-related variable names.
-This is true only after `maintenance_formulation!` has been called.
maintenance_down_variables(dict::Dict)
dict: a dictionary of model data
get listings of maintenance-related variable names.
-This is available only after `maintenance_formulation!` has been called.
This function defines the constraints for operation of `must-run' or non-dispatchable resources, such as rooftop solar systems that do not receive dispatch signals, run-of-river hydroelectric facilities without the ability to spill water, or cogeneration systems that must produce a fixed quantity of heat in each time step. This resource type can also be used to model baseloaded or self-committed thermal generators that do not respond to economic dispatch.
For must-run resources ($y\in \mathcal{MR}$) output in each time period $t$ must exactly equal the available capacity factor times the installed capacity, not allowing for curtailment. These resources are also not eligible for contributing to frequency regulation or operating reserve requirements.
This function defines the constraints for operation of `must-run' or non-dispatchable resources, such as rooftop solar systems that do not receive dispatch signals, run-of-river hydroelectric facilities without the ability to spill water, or cogeneration systems that must produce a fixed quantity of heat in each time step. This resource type can also be used to model baseloaded or self-committed thermal generators that do not respond to economic dispatch.
For must-run resources ($y\in \mathcal{MR}$) output in each time period $t$ must exactly equal the available capacity factor times the installed capacity, not allowing for curtailment. These resources are also not eligible for contributing to frequency regulation or operating reserve requirements.
\[\begin{aligned}
\Theta_{y,z,t} = \rho^{max}_{y,z,t}\times \Delta^{total}_{y,z}
\hspace{4 cm} \forall y \in \mathcal{MR}, z \in \mathcal{Z},t \in \mathcal{T}
-\end{aligned}\]
Retrieves the value of a specific attribute from an AbstractResource object. If the attribute exists, its value is returned; otherwise, the default value is returned.
Arguments:
r::AbstractResource: The resource object.
sym::Symbol: The symbol representing the attribute name.
default: The default value to return if the attribute does not exist.
Returns:
The value of the attribute if it exists in the parent object, default otherwise.
Allows to access the attributes of an AbstractResource object using dot syntax. It checks if the attribute exists in the object and returns its value, otherwise it throws an ErrorException indicating that the attribute does not exist.
Arguments:
r::AbstractResource: The resource object.
sym::Symbol: The symbol representing the attribute name.
Returns:
The value of the attribute if it exists in the parent object.
Throws:
ErrorException: If the attribute does not exist in the resource.
Allows to access attributes of a vector of AbstractResource objects using dot syntax. If the sym is an element of the resource_types constant, it returns all resources of that type. Otherwise, it returns the value of the attribute for each resource in the vector.
Arguments:
rs::Vector{<:AbstractResource}: The vector of AbstractResource objects.
sym::Symbol: The symbol representing the attribute name or a type from resource_types.
Returns:
If sym is an element of the resource_types constant, it returns a vector containing all resources of that type.
If sym is an attribute name, it returns a vector containing the value of the attribute for each resource.
Examples
julia> vre_gen = gen.Vre; # gen vector of resources
+ 50
Retrieves the value of a specific attribute from an AbstractResource object. If the attribute exists, its value is returned; otherwise, the default value is returned.
Arguments:
r::AbstractResource: The resource object.
sym::Symbol: The symbol representing the attribute name.
default: The default value to return if the attribute does not exist.
Returns:
The value of the attribute if it exists in the parent object, default otherwise.
Allows to access the attributes of an AbstractResource object using dot syntax. It checks if the attribute exists in the object and returns its value, otherwise it throws an ErrorException indicating that the attribute does not exist.
Arguments:
r::AbstractResource: The resource object.
sym::Symbol: The symbol representing the attribute name.
Returns:
The value of the attribute if it exists in the parent object.
Throws:
ErrorException: If the attribute does not exist in the resource.
Allows to access attributes of a vector of AbstractResource objects using dot syntax. If the sym is an element of the resource_types constant, it returns all resources of that type. Otherwise, it returns the value of the attribute for each resource in the vector.
Arguments:
rs::Vector{<:AbstractResource}: The vector of AbstractResource objects.
sym::Symbol: The symbol representing the attribute name or a type from resource_types.
Returns:
If sym is an element of the resource_types constant, it returns a vector containing all resources of that type.
If sym is an attribute name, it returns a vector containing the value of the attribute for each resource.
Examples
julia> vre_gen = gen.Vre; # gen vector of resources
julia> typeof(vre_gen)
Vector{Vre} (alias for Array{Vre, 1})
-julia> vre_gen.zone
storage_dc_charge(rs::Vector{T}) where T <: AbstractResource
-Returns the indices of all co-located storage resources in the vector `rs` that charge DC.
storage_dc_charge(rs::Vector{T}) where T <: AbstractResource
+Returns the indices of all co-located storage resources in the vector `rs` that charge DC.
This function defines the constraints for operation of retrofit technologies, including but not limited to carbon capture and thermal energy storage.
For retrofittable source technologies $y$ and retrofit technologies $r$ in the same region $z$ and retrofit cluster $id$, (i.e. $y \in RS(id)$ and $r \in RO(id)$), the total retrofit capacity $\Omega_{r}$ that may be installed is constrained by the available retrofittable capacity $P_{y}$ as well as the efficiency ${ef}_{r}$ of the retrofit technology.
This function defines the constraints for operation of retrofit technologies, including but not limited to carbon capture and thermal energy storage.
For retrofittable source technologies $y$ and retrofit technologies $r$ in the same region $z$ and retrofit cluster $id$, (i.e. $y \in RS(id)$ and $r \in RO(id)$), the total retrofit capacity $\Omega_{r}$ that may be installed is constrained by the available retrofittable capacity $P_{y}$ as well as the efficiency ${ef}_{r}$ of the retrofit technology.
A wide range of energy storage devices (all $o \in \mathcal{O}$) can be modeled in GenX, using one of two generic storage formulations: (1) storage technologies with symmetric charge and discharge capacity (all $o \in \mathcal{O}^{sym}$), such as Lithium-ion batteries and most other electrochemical storage devices that use the same components for both charge and discharge; and (2) storage technologies that employ distinct and potentially asymmetric charge and discharge capacities (all $o \in \mathcal{O}^{asym}$), such as most thermal storage technologies or hydrogen electrolysis/storage/fuel cell or combustion turbine systems.
If a capacity reserve margin is modeled, variables for virtual charge, $\Pi^{CRM}_{o,z,t}$, and virtual discharge, $\Theta^{CRM}_{o,z,t}$, are created to represent contributions that a storage device makes to the capacity reserve margin without actually generating power. (This functionality can be turned off with the parameter StorageVirtualDischarge in the GenX settings file.) These represent power that the storage device could have discharged or consumed if called upon to do so, based on its available state of charge. Importantly, a dedicated set of variables (those of the form $\Pi^{CRM}_{o,z,t}, \Theta^{CRM}_{o,z,t}$) and constraints are created to ensure that any virtual contributions to the capacity reserve margin could be made as actual charge/discharge if necessary without affecting system operations in any other timesteps. If a capacity reserve margin is not modeled, all related variables are fixed at 0. The overall contribution of storage devices to the system's capacity reserve margin in timestep $t$ is equal to $\sum_{y \in \mathcal{O}} \epsilon_{y,z,p}^{CRM} \times \left(\Theta_{y,z,t} + \Theta^{CRM}_{o,z,t} - \Pi^{CRM}_{o,z,t} - \Pi_{y,z,t} \right)$, and includes both actual and virtual charge and discharge.
A wide range of energy storage devices (all $o \in \mathcal{O}$) can be modeled in GenX, using one of two generic storage formulations: (1) storage technologies with symmetric charge and discharge capacity (all $o \in \mathcal{O}^{sym}$), such as Lithium-ion batteries and most other electrochemical storage devices that use the same components for both charge and discharge; and (2) storage technologies that employ distinct and potentially asymmetric charge and discharge capacities (all $o \in \mathcal{O}^{asym}$), such as most thermal storage technologies or hydrogen electrolysis/storage/fuel cell or combustion turbine systems.
If a capacity reserve margin is modeled, variables for virtual charge, $\Pi^{CRM}_{o,z,t}$, and virtual discharge, $\Theta^{CRM}_{o,z,t}$, are created to represent contributions that a storage device makes to the capacity reserve margin without actually generating power. (This functionality can be turned off with the parameter StorageVirtualDischarge in the GenX settings file.) These represent power that the storage device could have discharged or consumed if called upon to do so, based on its available state of charge. Importantly, a dedicated set of variables (those of the form $\Pi^{CRM}_{o,z,t}, \Theta^{CRM}_{o,z,t}$) and constraints are created to ensure that any virtual contributions to the capacity reserve margin could be made as actual charge/discharge if necessary without affecting system operations in any other timesteps. If a capacity reserve margin is not modeled, all related variables are fixed at 0. The overall contribution of storage devices to the system's capacity reserve margin in timestep $t$ is equal to $\sum_{y \in \mathcal{O}} \epsilon_{y,z,p}^{CRM} \times \left(\Theta_{y,z,t} + \Theta^{CRM}_{o,z,t} - \Pi^{CRM}_{o,z,t} - \Pi_{y,z,t} \right)$, and includes both actual and virtual charge and discharge.
\[\begin{aligned}
& \Pi_{o,z,t} + \Pi^{CRM}_{o,z,t} \leq \Delta^{total}_{o,z} & \quad \forall o \in \mathcal{O}^{sym}, z \in \mathcal{Z}, t \in \mathcal{T}\\
& \Pi_{o,z,t} + \Pi^{CRM}_{o,z,t} + \Theta_{o,z,t} + \Theta^{CRM}_{o,z,t} \leq \Delta^{total}_{o,z} & \quad \forall o \in \mathcal{O}^{sym}, z \in \mathcal{Z}, t \in \mathcal{T}
\end{aligned}\]
Storage with symmetric charge and discharge capacity For storage technologies with symmetric charge and discharge capacity (all $o \in \mathcal{O}^{sym}$), charge rate, $\Pi_{o,z,t}$, and virtual charge rate, $\Pi^{CRM}_{o,z,t}$, are jointly constrained by the total installed power capacity, $\Omega_{o,z}$. Since storage resources generally represent a `cluster' of multiple similar storage devices of the same type/cost in the same zone, GenX permits storage resources to simultaneously charge and discharge (as some units could be charging while others discharge), with the simultaenous sum of charge, $\Pi_{o,z,t}$, discharge, $\Theta_{o,z,t}$, virtual charge, $\Pi^{CRM}_{o,z,t}$, and virtual discharge, $\Theta^{CRM}_{o,z,t}$, also limited by the total installed power capacity, $\Delta^{total}_{o,z}$. These two constraints are as follows:
Sets up variables and constraints specific to storage resources with asymmetric charge and discharge capacities. See storage() in storage.jl for description of constraints.
Sets up variables and constraints specific to storage resources with asymmetric charge and discharge capacities when reserves are modeled. See storage() in storage.jl for description of constraints.
Sets up variables and constraints specific to storage resources with asymmetric charge and discharge capacities. See storage() in storage.jl for description of constraints.
Sets up variables and constraints specific to storage resources with asymmetric charge and discharge capacities when reserves are modeled. See storage() in storage.jl for description of constraints.
Sets up variables and constraints specific to storage resources with symmetric charge and discharge capacities. See storage() in storage.jl for description of constraints.
Sets up variables and constraints specific to storage resources with symmetric charge and discharge capacities when reserves are modeled. See storage() in storage.jl for description of constraints.
Sets up variables and constraints specific to storage resources with symmetric charge and discharge capacities. See storage() in storage.jl for description of constraints.
Sets up variables and constraints specific to storage resources with symmetric charge and discharge capacities when reserves are modeled. See storage() in storage.jl for description of constraints.
The thermal module creates decision variables, expressions, and constraints related to thermal power plants e.g. coal, oil or natural gas steam plants, natural gas combined cycle and combustion turbine plants, nuclear, hydrogen combustion etc. This module uses the following 'helper' functions in separate files: thermal_commit() for thermal resources subject to unit commitment decisions and constraints (if any) and thermal_no_commit() for thermal resources not subject to unit commitment (if any).
The thermal module creates decision variables, expressions, and constraints related to thermal power plants e.g. coal, oil or natural gas steam plants, natural gas combined cycle and combustion turbine plants, nuclear, hydrogen combustion etc. This module uses the following 'helper' functions in separate files: thermal_commit() for thermal resources subject to unit commitment decisions and constraints (if any) and thermal_no_commit() for thermal resources not subject to unit commitment (if any).
This function defines the operating constraints for thermal power plants subject to unit commitment constraints on power plant start-ups and shut-down decision ($y \in UC$).
We model capacity investment decisions and commitment and cycling (start-up, shut-down) of thermal generators using the integer clustering technique developed in Palmintier, 2011, Palmintier, 2013, and Palmintier, 2014. In a typical binary unit commitment formulation, each unit is either on or off. With the clustered unit commitment formulation, one or more cluster(s) of similar generators are clustered by type and zone (typically using heat rate and fixed O\&M cost to create clusters), and the integer commitment state variable for each cluster varies from zero to the number of units in the cluster, $\frac{\Delta^{total}_{y,z}}{\Omega^{size}_{y,z}}$. As discussed in \cite{Palmintier2014}, this approach replaces the large set of binary commitment decisions and associated constraints, which scale directly with the number of individual units, with a smaller set of integer commitment states and constraints, one for each cluster $y$. The dimensionality of the problem thus scales with the number of units of a given type in each zone, rather than by the number of discrete units, significantly improving computational efficiency. However, this method entails the simplifying assumption that all clustered units have identical parameters (e.g., capacity size, ramp rates, heat rate) and that all committed units in a given time step $t$ are operating at the same power output per unit.
Power balance expression
This function adds the sum of power generation from thermal units subject to unit commitment ($\Theta_{y \in UC,t \in T,z \in Z}$) to the power balance expression.
Startup and shutdown events (thermal plant cycling)
Capacitated limits on unit commitment decision variables
Thermal resources subject to unit commitment ($y \in \mathcal{UC}$) adhere to the following constraints on commitment states, startup events, and shutdown events, which limit each decision to be no greater than the maximum number of discrete units installed (as per the following three constraints):
This function defines the operating constraints for thermal power plants subject to unit commitment constraints on power plant start-ups and shut-down decision ($y \in UC$).
We model capacity investment decisions and commitment and cycling (start-up, shut-down) of thermal generators using the integer clustering technique developed in Palmintier, 2011, Palmintier, 2013, and Palmintier, 2014. In a typical binary unit commitment formulation, each unit is either on or off. With the clustered unit commitment formulation, one or more cluster(s) of similar generators are clustered by type and zone (typically using heat rate and fixed O\&M cost to create clusters), and the integer commitment state variable for each cluster varies from zero to the number of units in the cluster, $\frac{\Delta^{total}_{y,z}}{\Omega^{size}_{y,z}}$. As discussed in \cite{Palmintier2014}, this approach replaces the large set of binary commitment decisions and associated constraints, which scale directly with the number of individual units, with a smaller set of integer commitment states and constraints, one for each cluster $y$. The dimensionality of the problem thus scales with the number of units of a given type in each zone, rather than by the number of discrete units, significantly improving computational efficiency. However, this method entails the simplifying assumption that all clustered units have identical parameters (e.g., capacity size, ramp rates, heat rate) and that all committed units in a given time step $t$ are operating at the same power output per unit.
Power balance expression
This function adds the sum of power generation from thermal units subject to unit commitment ($\Theta_{y \in UC,t \in T,z \in Z}$) to the power balance expression.
Startup and shutdown events (thermal plant cycling)
Capacitated limits on unit commitment decision variables
Thermal resources subject to unit commitment ($y \in \mathcal{UC}$) adhere to the following constraints on commitment states, startup events, and shutdown events, which limit each decision to be no greater than the maximum number of discrete units installed (as per the following three constraints):
\[\begin{aligned}
\nu_{y,z,t} \leq \frac{\Delta^{\text{total}}_{y,z}}{\Omega^{size}_{y,z}}
\hspace{1.5cm} \forall y \in \mathcal{UC}, \forall z \in \mathcal{Z}, \forall t \in \mathcal{T}
\end{aligned}\]
\[\begin{aligned}
\frac{\overline{\Delta_{y,z}} + \Omega_{y,z} - \Delta_{y,z}}{\Omega^{size}_{y,z}} - \nu_{y,z,t} \geq \displaystyle \sum_{\hat{t} = t-(\tau^{down}_{y,z}-1)}^t \zeta_{y,z,\hat{t}}
\hspace{1.5cm} \forall y \in \mathcal{UC}, \forall z \in \mathcal{Z}, \forall t \in \mathcal{T}
-\end{aligned}\]
(See Constraints 9-10 in the code)
where $\tau_{y,z}^{up|down}$ is the minimum up or down time for units in generating cluster $y$ in zone $z$.
Like with the ramping constraints, the minimum up and down constraint time also wrap around from the start of each time period to the end of each period. It is recommended that users of GenX must use longer subperiods than the longest min up/down time if modeling UC. Otherwise, the model will report error.
This function is called by the thermal_commit() function when regulation and reserves constraints are active and defines reserve related constraints for thermal power plants subject to unit commitment constraints on power plant start-ups and shut-down decisions.
Maximum contributions to frequency regulation and reserves
When modeling frequency regulation and reserves contributions, thermal units subject to unit commitment adhere to the following constraints which limit the maximum contribution to regulation and reserves in each time step to a specified maximum fraction ($,\upsilon^{rsv}_{y,z}$) of the commitment capacity in that time step ($(\Omega^{size}_{y,z} \cdot \nu_{y,z,t})$):
\[\begin{aligned}
+\end{aligned}\]
(See Constraints 9-10 in the code)
where $\tau_{y,z}^{up|down}$ is the minimum up or down time for units in generating cluster $y$ in zone $z$.
Like with the ramping constraints, the minimum up and down constraint time also wrap around from the start of each time period to the end of each period. It is recommended that users of GenX must use longer subperiods than the longest min up/down time if modeling UC. Otherwise, the model will report error.
This function is called by the thermal_commit() function when regulation and reserves constraints are active and defines reserve related constraints for thermal power plants subject to unit commitment constraints on power plant start-ups and shut-down decisions.
Maximum contributions to frequency regulation and reserves
When modeling frequency regulation and reserves contributions, thermal units subject to unit commitment adhere to the following constraints which limit the maximum contribution to regulation and reserves in each time step to a specified maximum fraction ($,\upsilon^{rsv}_{y,z}$) of the commitment capacity in that time step ($(\Omega^{size}_{y,z} \cdot \nu_{y,z,t})$):
\[\begin{aligned}
f_{y,z,t} \leq \upsilon^{reg}_{y,z} \times \rho^{max}_{y,z,t} (\Omega^{size}_{y,z} \times \nu_{y,z,t}) \hspace{1.5cm} \forall y \in \mathcal{UC}, \forall z \in \mathcal{Z}, \forall t \in \mathcal{T}
\end{aligned}\]
\[\begin{aligned}
r_{y,z,t} \leq \upsilon^{rsv}_{y,z} \times \rho^{max}_{y,z,t} (\Omega^{size}_{y,z} \times \nu_{y,z,t}) \hspace{1.5cm} \forall y \in \mathcal{UC}, \forall z \in \mathcal{Z}, \forall t \in \mathcal{T}
@@ -43,4 +43,4 @@
\end{aligned}\]
\[\begin{aligned}
\Theta_{y,z,t} + f_{y,z,t} + r_{y,z,t} \leq \rho^{max}_{y,z,t} \times \Omega^{size}_{y,z} \times \nu_{y,z,t}
\hspace{1.5cm} \forall y \in \mathcal{UC}, \forall z \in \mathcal{Z}, \forall t \in \mathcal{T}
-\end{aligned}\]
This function defines the operating constraints for thermal power plants NOT subject to unit commitment constraints on power plant start-ups and shut-down decisions ($y \in H \setminus UC$).
Ramping limits
Thermal resources not subject to unit commitment ($y \in H \setminus UC$) adhere instead to the following ramping limits on hourly changes in power output:
This function defines the operating constraints for thermal power plants NOT subject to unit commitment constraints on power plant start-ups and shut-down decisions ($y \in H \setminus UC$).
Ramping limits
Thermal resources not subject to unit commitment ($y \in H \setminus UC$) adhere instead to the following ramping limits on hourly changes in power output:
\[\begin{aligned}
\Theta_{y,z,t-1} - \Theta_{y,z,t} \leq \kappa_{y,z}^{down} \Delta^{\text{total}}_{y,z} \hspace{1cm} \forall y \in \mathcal{H \setminus UC}, \forall z \in \mathcal{Z}, \forall t \in \mathcal{T}
\end{aligned}\]
\[\begin{aligned}
\Theta_{y,z,t} - \Theta_{y,z,t-1} \leq \kappa_{y,z}^{up} \Delta^{\text{total}}_{y,z} \hspace{1cm} \forall y \in \mathcal{H \setminus UC}, \forall z \in \mathcal{Z}, \forall t \in \mathcal{T}
@@ -9,7 +9,7 @@
\end{aligned}\]
\[\begin{aligned}
\Theta_{y,z,t} \leq \rho^{max}_{y,z,t} \times \Delta^{total}_{y,z}
\hspace{1cm} \forall y \in \mathcal{H \setminus UC}, \forall z \in \mathcal{Z}, \forall t \in \mathcal{T}
-\end{aligned}\]
This function is called by the thermal_no_commit() function when regulation and reserves constraints are active and defines reserve related constraints for thermal power plants not subject to unit commitment constraints on power plant start-ups and shut-down decisions.
Maximum contributions to frequency regulation and reserves
Thermal units not subject to unit commitment adhere instead to the following constraints on maximum reserve and regulation contributions:
This function is called by the thermal_no_commit() function when regulation and reserves constraints are active and defines reserve related constraints for thermal power plants not subject to unit commitment constraints on power plant start-ups and shut-down decisions.
Maximum contributions to frequency regulation and reserves
Thermal units not subject to unit commitment adhere instead to the following constraints on maximum reserve and regulation contributions:
\[\begin{aligned}
f_{y,z,t} \leq \upsilon^{reg}_{y,z} \times \rho^{max}_{y,z,t} \Delta^{\text{total}}_{y,z} \hspace{1cm} \forall y \in \mathcal{H \setminus UC}, \forall z \in \mathcal{Z}, \forall t \in \mathcal{T}
\end{aligned}\]
\[\begin{aligned}
r_{y,z,t} \leq \upsilon^{rsv}_{y,z} \times \rho^{max}_{y,z,t} \Delta^{\text{total}}_{y,z} \hspace{1cm} \forall y \in \mathcal{H \setminus UC}, \forall z \in \mathcal{Z}, \forall t \in \mathcal{T}
@@ -19,4 +19,4 @@
\end{aligned}\]
\[\begin{aligned}
\Theta_{y,z,t} + f_{y,z,t} + r_{y,z,t} \leq \rho^{max}_{y,z,t} \times \Delta^{\text{total}}_{y,z}
\hspace{1cm} \forall y \in \mathcal{H \setminus UC}, \forall z \in \mathcal{Z}, \forall t \in \mathcal{T}
-\end{aligned}\]
Note there are multiple versions of these constraints in the code in order to avoid creation of unecessary constraints and decision variables for thermal units unable to provide regulation and/or reserves contributions due to input parameters (e.g. Reg_Max=0 and/or RSV_Max=0).
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+\end{aligned}\]
Note there are multiple versions of these constraints in the code in order to avoid creation of unecessary constraints and decision variables for thermal units unable to provide regulation and/or reserves contributions due to input parameters (e.g. Reg_Max=0 and/or RSV_Max=0).
This function defines the decision variables, expressions, and constraints for the inverter component of each co-located VRE and storage generator.
The total inverter capacity of each resource is defined as the sum of the existing inverter capacity plus the newly invested inverter capacity minus any retired inverter capacity:
This function defines the decision variables, expressions, and constraints for the inverter component of each co-located VRE and storage generator.
The total inverter capacity of each resource is defined as the sum of the existing inverter capacity plus the newly invested inverter capacity minus any retired inverter capacity:
\[\begin{aligned}
& \Delta^{total, inv}_{y,z} = (\overline{\Delta^{inv}_{y,z}} + \Omega^{inv}_{y,z} - \Delta^{inv}_{y,z}) \quad \forall y \in \mathcal{VS}^{inv}, z \in \mathcal{Z}
\end{aligned}\]
One cannot retire more inverter capacity than existing inverter capacity:
This function activates the decision variables and constraints for asymmetric storage resources (independent charge and discharge power capacities (any STOR flag = 2)). For asymmetric storage resources, the function is enabled so charging and discharging can occur either through DC or AC capabilities. For example, a storage resource can be asymmetrically charged and discharged via DC capabilities or a storage resource could be charged via AC capabilities and discharged through DC capabilities. This module is configured such that both AC and DC charging (or discharging) cannot simultaneously occur.
The total charge/discharge DC and AC capacities of each resource are defined as the sum of the existing charge/discharge DC and AC capacities plus the newly invested charge/discharge DC and AC capacities minus any retired charge/discharge DC and AC capacities:
This function activates the decision variables and constraints for asymmetric storage resources (independent charge and discharge power capacities (any STOR flag = 2)). For asymmetric storage resources, the function is enabled so charging and discharging can occur either through DC or AC capabilities. For example, a storage resource can be asymmetrically charged and discharged via DC capabilities or a storage resource could be charged via AC capabilities and discharged through DC capabilities. This module is configured such that both AC and DC charging (or discharging) cannot simultaneously occur.
The total charge/discharge DC and AC capacities of each resource are defined as the sum of the existing charge/discharge DC and AC capacities plus the newly invested charge/discharge DC and AC capacities minus any retired charge/discharge DC and AC capacities:
\[\begin{aligned}
& \Delta^{total,dc,dis}_{y,z} =(\overline{\Delta^{dc,dis}_{y,z}}+\Omega^{dc,dis}_{y,z}-\Delta^{dc,dis}_{y,z}) \quad \forall y \in \mathcal{VS}^{asym,dc,dis}, z \in \mathcal{Z} \\
& \Delta^{total,dc,cha}_{y,z} =(\overline{\Delta^{dc,cha}_{y,z}}+\Omega^{dc,cha}_{y,z}-\Delta^{dc,cha}_{y,z}) \quad \forall y \in \mathcal{VS}^{asym,dc,cha}, z \in \mathcal{Z} \\
& \Delta^{total,ac,dis}_{y,z} =(\overline{\Delta^{ac,dis}_{y,z}}+\Omega^{ac,dis}_{y,z}-\Delta^{ac,dis}_{y,z}) \quad \forall y \in \mathcal{VS}^{asym,ac,dis}, z \in \mathcal{Z} \\
@@ -88,11 +88,11 @@
& + \sum_{y \in \mathcal{VS}^{asym,ac,cha} } \sum_{z \in \mathcal{Z}}
\left( (\pi^{INVEST,ac,cha}_{y,z} \times \Omega^{ac,cha}_{y,z})
+ (\pi^{FOM,ac,cha}_{y,z} \times \Delta^{total,ac,cha}_{y,z})\right)
-\end{aligned}\]
This function defines the decision variables, expressions, and constraints for any long duration energy storage component of each co-located VRE and storage generator ( there is more than one representative period and LDS_VRE_STOR=1 in the Vre_and_stor_data.csv).
These constraints follow the same formulation that is outlined by the function long_duration_storage!() in the storage module. One constraint changes, which links the state of charge between the start of periods for long duration energy storage resources because there are options to charge and discharge these resources through AC and DC capabilities. The main linking constraint changes to:
This function defines the decision variables, expressions, and constraints for any long duration energy storage component of each co-located VRE and storage generator ( there is more than one representative period and LDS_VRE_STOR=1 in the Vre_and_stor_data.csv).
These constraints follow the same formulation that is outlined by the function long_duration_storage!() in the storage module. One constraint changes, which links the state of charge between the start of periods for long duration energy storage resources because there are options to charge and discharge these resources through AC and DC capabilities. The main linking constraint changes to:
The rest of the long duration energy storage constraints are copied and applied to the co-located VRE and storage module for any long duration energy storage resources $y \in \mathcal{VS}^{LDES}$ from the long-duration storage module. Capacity reserve margin constraints for long duration energy storage resources are further elaborated upon in vre_stor_capres!().
This function defines the decision variables, expressions, and constraints for the solar PV component of each co-located VRE and storage generator.
The total solar PV capacity of each resource is defined as the sum of the existing solar PV capacity plus the newly invested solar PV capacity minus any retired solar PV capacity:
\[\begin{aligned}
+\end{aligned}\]
The rest of the long duration energy storage constraints are copied and applied to the co-located VRE and storage module for any long duration energy storage resources $y \in \mathcal{VS}^{LDES}$ from the long-duration storage module. Capacity reserve margin constraints for long duration energy storage resources are further elaborated upon in vre_stor_capres!().
This function defines the decision variables, expressions, and constraints for the solar PV component of each co-located VRE and storage generator.
The total solar PV capacity of each resource is defined as the sum of the existing solar PV capacity plus the newly invested solar PV capacity minus any retired solar PV capacity:
\[\begin{aligned}
& \Delta^{total, pv}_{y,z} = (\overline{\Delta^{pv}_{y,z}} + \Omega^{pv}_{y,z} - \Delta^{pv}_{y,z}) \quad \forall y \in \mathcal{VS}^{pv}, z \in \mathcal{Z}
\end{aligned}\]
One cannot retire more solar PV capacity than existing solar PV capacity:
This function defines the decision variables, expressions, and constraints for the storage component of each co-located VRE and storage generator. A wide range of energy storage devices (all $y \in \mathcal{VS}^{stor}$) can be modeled in GenX, using one of two generic storage formulations: (1) storage technologies with symmetric charge and discharge capacity (all $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{sym,ac}$), such as lithium-ion batteries and most other electrochemical storage devices that use the same components for both charge and discharge; and (2) storage technologies that employ distinct and potentially asymmetric charge and discharge capacities (all $y \in \mathcal{VS}^{asym,dc,dis} \cup y \in \mathcal{VS}^{asym,dc,cha} \cup y \in \mathcal{VS}^{asym,ac,dis} \cup y \in \mathcal{VS}^{asym,ac,cha}$), such as most thermal storage technologies or hydrogen electrolysis/storage/fuel cell or combustion turbine systems. The following constraints apply to all storage resources, $y \in \mathcal{VS}^{stor}$, regardless of whether or not the storage has symmetric or asymmetric charging/discharging capabilities or varying durations of discharge.
The total storage energy capacity of each resource is defined as the sum of the existing storage energy capacity plus the newly invested storage energy capacity minus any retired storage energy capacity:
This function defines the decision variables, expressions, and constraints for the storage component of each co-located VRE and storage generator. A wide range of energy storage devices (all $y \in \mathcal{VS}^{stor}$) can be modeled in GenX, using one of two generic storage formulations: (1) storage technologies with symmetric charge and discharge capacity (all $y \in \mathcal{VS}^{sym,dc} \cup y \in \mathcal{VS}^{sym,ac}$), such as lithium-ion batteries and most other electrochemical storage devices that use the same components for both charge and discharge; and (2) storage technologies that employ distinct and potentially asymmetric charge and discharge capacities (all $y \in \mathcal{VS}^{asym,dc,dis} \cup y \in \mathcal{VS}^{asym,dc,cha} \cup y \in \mathcal{VS}^{asym,ac,dis} \cup y \in \mathcal{VS}^{asym,ac,cha}$), such as most thermal storage technologies or hydrogen electrolysis/storage/fuel cell or combustion turbine systems. The following constraints apply to all storage resources, $y \in \mathcal{VS}^{stor}$, regardless of whether or not the storage has symmetric or asymmetric charging/discharging capabilities or varying durations of discharge.
The total storage energy capacity of each resource is defined as the sum of the existing storage energy capacity plus the newly invested storage energy capacity minus any retired storage energy capacity:
\[\begin{aligned}
& \Delta^{total,energy}_{y,z} = (\overline{\Delta^{energy}_{y,z}}+\Omega^{energy}_{y,z}-\Delta^{energy}_{y,z}) \quad \forall y \in \mathcal{VS}^{stor}, z \in \mathcal{Z}
\end{aligned}\]
One cannot retire more energy capacity than existing energy capacity:
This module enables the modeling of 1) co-located VRE and energy storage technologies, and 2) optimized interconnection sizing for VREs. Utility-scale solar PV and/or wind VRE technologies can be modeled at the same site with or without storage technologies. Storage resources can be charged/discharged behind the meter through the inverter (DC) and through AC charging/discharging capabilities. Each resource can be configured to have any combination of the following components: solar PV, wind, DC discharging/charging storage, and AC discharging/charging storage resources. For storage resources, both long duration energy storage and short-duration energy storage can be modeled, via asymmetric or symmetric charging and discharging options. Each resource connects to the grid via a grid connection component, which is the only required decision variable that each resource must have. If the configured resource has either solar PV and/or DC discharging/charging storage capabilities, an inverter decision variable is also created. The full module with the decision variables and interactions can be found below.
Figure. Configurable Co-located VRE and Storage Module Interactions and Decision Variables
This module is split such that functions are called for each configurable component of a co-located resource: inverter_vre_stor(), solar_vre_stor!(), wind_vre_stor!(), stor_vre_stor!(), lds_vre_stor!(), and investment_charge_vre_stor!(). The function vre_stor!() specifically ensures that all necessary functions are called to activate the appropriate constraints, creates constraints that apply to multiple components (i.e. inverter and grid connection balances and maximums), and activates all of the policies that have been created (minimum capacity requirements, maximum capacity requirements, capacity reserve margins, operating reserves, and energy share requirements can all be turned on for this module). Note that not all of these variables are indexed by each co-located VRE and storage resource (for example, some co-located resources may only have a solar PV component and battery technology or just a wind component). Thus, the function vre_stor!() ensures indexing issues do not arise across the various potential configurations of co-located VRE and storage module but showcases all constraints as if each decision variable (that may be only applicable to certain components) is indexed by each $y \in \mathcal{VS}$ for readability.
The first constraint is created with the function vre_stor!() and exists for all resources, regardless of the VRE and storage components that each resource contains and regardless of the policies invoked for the module. This constraint represents the energy balance, ensuring net DC power (discharge of battery, PV generation, and charge of battery) and net AC power (discharge of battery, wind generation, and charge of battery) are equal to the technology's total discharging to and charging from the grid:
This module enables the modeling of 1) co-located VRE and energy storage technologies, and 2) optimized interconnection sizing for VREs. Utility-scale solar PV and/or wind VRE technologies can be modeled at the same site with or without storage technologies. Storage resources can be charged/discharged behind the meter through the inverter (DC) and through AC charging/discharging capabilities. Each resource can be configured to have any combination of the following components: solar PV, wind, DC discharging/charging storage, and AC discharging/charging storage resources. For storage resources, both long duration energy storage and short-duration energy storage can be modeled, via asymmetric or symmetric charging and discharging options. Each resource connects to the grid via a grid connection component, which is the only required decision variable that each resource must have. If the configured resource has either solar PV and/or DC discharging/charging storage capabilities, an inverter decision variable is also created. The full module with the decision variables and interactions can be found below.
Figure. Configurable Co-located VRE and Storage Module Interactions and Decision Variables
This module is split such that functions are called for each configurable component of a co-located resource: inverter_vre_stor(), solar_vre_stor!(), wind_vre_stor!(), stor_vre_stor!(), lds_vre_stor!(), and investment_charge_vre_stor!(). The function vre_stor!() specifically ensures that all necessary functions are called to activate the appropriate constraints, creates constraints that apply to multiple components (i.e. inverter and grid connection balances and maximums), and activates all of the policies that have been created (minimum capacity requirements, maximum capacity requirements, capacity reserve margins, operating reserves, and energy share requirements can all be turned on for this module). Note that not all of these variables are indexed by each co-located VRE and storage resource (for example, some co-located resources may only have a solar PV component and battery technology or just a wind component). Thus, the function vre_stor!() ensures indexing issues do not arise across the various potential configurations of co-located VRE and storage module but showcases all constraints as if each decision variable (that may be only applicable to certain components) is indexed by each $y \in \mathcal{VS}$ for readability.
The first constraint is created with the function vre_stor!() and exists for all resources, regardless of the VRE and storage components that each resource contains and regardless of the policies invoked for the module. This constraint represents the energy balance, ensuring net DC power (discharge of battery, PV generation, and charge of battery) and net AC power (discharge of battery, wind generation, and charge of battery) are equal to the technology's total discharging to and charging from the grid:
The second constraint is also created with the function vre_stor!() and exists for all resources, regardless of the VRE and storage components that each resource contains. However, this constraint changes when either or both capacity reserve margins and operating reserves are activated. The following constraint enforces that the maximum grid exports and imports must be less than the grid connection capacity (without any policies):
This function activates capacity reserve margin constraints for co-located VRE and storage resources. The capacity reserve margin formulation for GenX is further elaborated upon in cap_reserve_margin!(). For co-located resources ($y \in \mathcal{VS}$), the available capacity to contribute to the capacity reserve margin is the net injection into the transmission network (which can come from the solar PV, wind, and/or storage component) plus the net virtual injection corresponding to charge held in reserve (which can only come from the storage component), derated by the derating factor. If a capacity reserve margin is modeled, variables for virtual charge DC, $\Pi^{CRM, dc}_{y,z,t}$, virtual charge AC, $\Pi^{CRM, ac}_{y,z,t}$, virtual discharge DC, $\Theta^{CRM, dc}_{y,z,t}$, virtual discharge AC, $\Theta^{CRM, ac}_{o,z,t}$, and virtual state of charge, $\Gamma^{CRM}_{y,z,t}$, are created to represent contributions that a storage device makes to the capacity reserve margin without actually generating power. These represent power that the storage device could have discharged or consumed if called upon to do so, based on its available state of charge. Importantly, a dedicated set of variables and constraints are created to ensure that any virtual contributions to the capacity reserve margin could be made as actual charge/discharge if necessary without affecting system operations in any other timesteps (similar to the standalone storage capacity reserve margin constraints).
If a capacity reserve margin is modeled, then the following constraints track the relationship between the virtual charge variables, $\Pi^{CRM,dc}_{y,z,t}, \Pi^{CRM,ac}_{y,z,t}$, virtual discharge variables, $\Theta^{CRM, dc}_{y,z,t}, \Theta^{CRM, ac}_{y,z,t}$, and the virtual state of charge, $\Gamma^{CRM}_{y,z,t}$, representing the amount of state of charge that must be held in reserve to enable these virtual capacity reserve margin contributions and ensuring that the storage device could deliver its pledged capacity if called upon to do so without affecting its operations in other timesteps. $\Gamma^{CRM}_{y,z,t}$ is tracked similarly to the devices' overall state of charge based on its value in the previous timestep and the virtual charge and discharge in the current timestep. Unlike the regular state of charge, virtual discharge $\Theta^{CRM,dc}_{y,z,t}, \Theta^{CRM,ac}_{y,z,t}$ increases $\Gamma^{CRM}_{y,z,t}$ (as more charge must be held in reserve to support more virtual discharge), and the virtual charge $\Pi^{CRM,dc}_{y,z,t}, \Pi^{CRM,ac}_{y,z,t}$ reduces $\Gamma^{CRM}_{y,z,t}$. Similar to the state of charge constraints in the stor_vre_stor!() function, the first of these two constraints enforces storage inventory balance for interior time steps $(t \in \mathcal{T}^{interior})$, while the second enforces storage balance constraint for the initial time step $(t \in \mathcal{T}^{start})$:
\[\begin{aligned}
+\end{aligned}\]
The rest of the constraints are dependent upon specific configurable components within the module and are listed below.
This function activates capacity reserve margin constraints for co-located VRE and storage resources. The capacity reserve margin formulation for GenX is further elaborated upon in cap_reserve_margin!(). For co-located resources ($y \in \mathcal{VS}$), the available capacity to contribute to the capacity reserve margin is the net injection into the transmission network (which can come from the solar PV, wind, and/or storage component) plus the net virtual injection corresponding to charge held in reserve (which can only come from the storage component), derated by the derating factor. If a capacity reserve margin is modeled, variables for virtual charge DC, $\Pi^{CRM, dc}_{y,z,t}$, virtual charge AC, $\Pi^{CRM, ac}_{y,z,t}$, virtual discharge DC, $\Theta^{CRM, dc}_{y,z,t}$, virtual discharge AC, $\Theta^{CRM, ac}_{o,z,t}$, and virtual state of charge, $\Gamma^{CRM}_{y,z,t}$, are created to represent contributions that a storage device makes to the capacity reserve margin without actually generating power. These represent power that the storage device could have discharged or consumed if called upon to do so, based on its available state of charge. Importantly, a dedicated set of variables and constraints are created to ensure that any virtual contributions to the capacity reserve margin could be made as actual charge/discharge if necessary without affecting system operations in any other timesteps (similar to the standalone storage capacity reserve margin constraints).
If a capacity reserve margin is modeled, then the following constraints track the relationship between the virtual charge variables, $\Pi^{CRM,dc}_{y,z,t}, \Pi^{CRM,ac}_{y,z,t}$, virtual discharge variables, $\Theta^{CRM, dc}_{y,z,t}, \Theta^{CRM, ac}_{y,z,t}$, and the virtual state of charge, $\Gamma^{CRM}_{y,z,t}$, representing the amount of state of charge that must be held in reserve to enable these virtual capacity reserve margin contributions and ensuring that the storage device could deliver its pledged capacity if called upon to do so without affecting its operations in other timesteps. $\Gamma^{CRM}_{y,z,t}$ is tracked similarly to the devices' overall state of charge based on its value in the previous timestep and the virtual charge and discharge in the current timestep. Unlike the regular state of charge, virtual discharge $\Theta^{CRM,dc}_{y,z,t}, \Theta^{CRM,ac}_{y,z,t}$ increases $\Gamma^{CRM}_{y,z,t}$ (as more charge must be held in reserve to support more virtual discharge), and the virtual charge $\Pi^{CRM,dc}_{y,z,t}, \Pi^{CRM,ac}_{y,z,t}$ reduces $\Gamma^{CRM}_{y,z,t}$. Similar to the state of charge constraints in the stor_vre_stor!() function, the first of these two constraints enforces storage inventory balance for interior time steps $(t \in \mathcal{T}^{interior})$, while the second enforces storage balance constraint for the initial time step $(t \in \mathcal{T}^{start})$:
All other constraints are identical to those used to track the actual state of charge, except with the new variables for the representation of 'virtual' state of charge, build up storage inventory and state of charge at the beginning of each period.
This function activates either or both frequency regulation and operating reserve options for co-located VRE-storage resources. Co-located VRE and storage resources ($y \in \mathcal{VS}$) have six pairs of auxilary variables to reflect contributions to regulation and reserves when generating electricity from solar PV or wind resources, DC charging and discharging from storage resources, and AC charging and discharging from storage resources. The primary variables ($f_{y,z,t}$ & $r_{y,z,t}$) becomes equal to the sum of these auxilary variables as follows:
\[\begin{aligned}
+\end{aligned}\]
All other constraints are identical to those used to track the actual state of charge, except with the new variables for the representation of 'virtual' state of charge, build up storage inventory and state of charge at the beginning of each period.
This function activates either or both frequency regulation and operating reserve options for co-located VRE-storage resources. Co-located VRE and storage resources ($y \in \mathcal{VS}$) have six pairs of auxilary variables to reflect contributions to regulation and reserves when generating electricity from solar PV or wind resources, DC charging and discharging from storage resources, and AC charging and discharging from storage resources. The primary variables ($f_{y,z,t}$ & $r_{y,z,t}$) becomes equal to the sum of these auxilary variables as follows:
\[\begin{aligned}
& f_{y,z,t} = f^{pv}_{y,z,t} + f^{wind}_{y,z,t} + f^{dc,dis}_{y,z,t} + f^{dc,cha}_{y,z,t} + f^{ac,dis}_{y,z,t} + f^{ac,cha}_{y,z,t} & \quad \forall y \in \mathcal{VS}, z \in \mathcal{Z}, t \in \mathcal{T}\\
& r_{y,z,t} = r^{pv}_{y,z,t} + r^{wind}_{y,z,t} + r^{dc,dis}_{y,z,t} + r^{dc,cha}_{y,z,t} + r^{ac,dis}_{y,z,t} + r^{ac,cha}_{y,z,t} & \quad \forall y \in \mathcal{VS}, z \in \mathcal{Z}, t \in \mathcal{T}\\
\end{aligned}\]
Furthermore, the frequency regulation and operating reserves require the maximum contribution from the entire resource to be a specified fraction of the installed grid connection capacity:
Lastly, if the co-located resource has a variable renewable energy component, the solar PV and wind resource can also contribute to frequency regulation reserves and must be greater than zero:
\[\begin{aligned}
& \Theta^{pv}_{y,z,t} - f^{pv}_{y,z,t} \geq 0 & \quad \forall y \in \mathcal{VS}^{pv}, z \in \mathcal{Z}, t \in \mathcal{T} \\
& \Theta^{wind}_{y,z,t} - f^{wind}_{y,z,t} \geq 0 & \quad \forall y \in \mathcal{VS}^{wind}, z \in \mathcal{Z}, t \in \mathcal{T}
-\end{aligned}\]
This function defines the decision variables, expressions, and constraints for the wind component of each co-located VRE and storage generator.
The total wind capacity of each resource is defined as the sum of the existing wind capacity plus the newly invested wind capacity minus any retired wind capacity:
This function defines the decision variables, expressions, and constraints for the wind component of each co-located VRE and storage generator.
The total wind capacity of each resource is defined as the sum of the existing wind capacity plus the newly invested wind capacity minus any retired wind capacity:
\[\begin{aligned}
& \Delta^{total, wind}_{y,z} = (\overline{\Delta^{wind}_{y,z}} + \Omega^{wind}_{y,z} - \Delta^{wind}_{y,z}) \quad \forall y \in \mathcal{VS}^{wind}, z \in \mathcal{Z}
\end{aligned}\]
One cannot retire more wind capacity than existing wind capacity:
Check whether the greatest Euclidean deviation in the input data and the clustered representation is within a given proportion of the "maximum" possible deviation.
(1 for Normalization covers 100%, 4 for Standardization covers ~95%)
Use kmeans or kmedoids to cluster raw demand profiles and resource capacity factor profiles into representative periods. Use Extreme Periods to capture noteworthy periods or periods with notably poor fits.
In Demand_data.csv, include the following:
Timesteps_per_Rep_Period - Typically 168 timesteps (e.g., hours) per period, this designates the length of each representative period.
UseExtremePeriods - Either 1 or 0, this designates whether or not to include outliers (by performance or demand/resource extreme) as their own representative periods. This setting automatically includes the periods with maximum demand, minimum solar cf and minimum wind cf as extreme periods.
ClusterMethod - Either 'kmeans' or 'kmedoids', this designates the method used to cluster periods and determine each point's representative period.
ScalingMethod - Either 'N' or 'S', this designates directs the module to normalize ([0,1]) or standardize (mean 0, variance 1) the input data.
MinPeriods - The minimum number of periods used to represent the input data. If using UseExtremePeriods, this must be at least three. If IterativelyAddPeriods if off, this will be the total number of periods.
MaxPeriods - The maximum number of periods - both clustered periods and extreme periods - that may be used to represent the input data.
IterativelyAddPeriods - Either 1 or 0, this designates whether or not to add periods until the error threshold between input data and represented data is met or the maximum number of periods is reached.
Threshold - Iterative period addition will end if the period farthest (Euclidean Distance) from its representative period is within this percentage of the total possible error (for normalization) or ~95% of the total possible error (for standardization). E.g., for a threshold of 0.01, every period must be within 1% of the spread of possible error before the clustering iterations will terminate (or until the max number of periods is reached).
IterateMethod - Either 'cluster' or 'extreme', this designates whether to add clusters to the kmeans/kmedoids method or to set aside the worst-fitting periods as a new extreme periods.
nReps - The number of times to repeat each kmeans/kmedoids clustering at the same setting.
DemandWeight - Default 1, this is an optional multiplier on demand columns in order to prioritize better fits for demand profiles over resource capacity factor profiles.
WeightTotal - Default 8760, the sum to which the relative weights of representative periods will be scaled.
ClusterFuelPrices - Either 1 or 0, this indicates whether or not to use the fuel price time series in Fuels_data.csv in the clustering process. If 'no', this function will still write Fuels_data_clustered.csv with reshaped fuel prices based on the number and size of the representative weeks, assuming a constant time series of fuel prices with length equal to the number of timesteps in the raw input data.
MultiStageConcatenate - (Only considered if MultiStage = 1 in genx_settings.yml) If 1, this designates that the model should time domain reduce the input data of all model stages together. Else if 0, [still in development] the model will time domain reduce only the first stage and will apply the periods of each other model stage to this set of representative periods by closest Eucliden distance.
For co-located VRE-STOR resources, all capacity factors must be in the Generatorsvariability.csv file in addition to separate Vreandstorsolarvariability.csv and Vreandstorwind_variability.csv files. The co-located solar PV and wind profiles for co-located resources will be separated into different CSV files to be read by loading the inputs after the clustering of the inputs has occurred.
get_demand_multipliers(ClusterOutputData, ModifiedData, M, W, DemandCols, TimestepsPerRepPeriod, NewColNames, NClusters, Ncols)
Get multipliers to linearly scale clustered demand profiles L zone-wise such that their weighted sum equals the original zonal total demand. Scale demand profiles later using these multipliers in order to ensure that a copy of the original demand is kept for validation.
where $Z$ is the set of zones, $I$ is the full time domain, $T$ is the length of one period (e.g., 168 for one week in hours), $M$ is the set of representative periods, $L_{i,z}$ is the original zonal demand profile over time (hour) index $i$, $C_{i,m,z}$ is the demand in timestep $i$ for representative period $m$ in zone $z$, $w_m$ is the weight of the representative period equal to the total number of hours that one hour in representative period $m$ represents in the original profile, and $k_z$ is the zonal demand multiplier returned by the function.
Identify extreme week by specification of profile type (Demand, PV, Wind), measurement type (absolute (timestep with min/max value) vs. integral (period with min/max summed value)), and statistic (minimum or maximum). I.e., the user could want the hour with the most demand across the whole system to be included among the extreme periods. They would select "Demand", "System, "Absolute, and "Max".
Check whether the greatest Euclidean deviation in the input data and the clustered representation is within a given proportion of the "maximum" possible deviation.
(1 for Normalization covers 100%, 4 for Standardization covers ~95%)
Use kmeans or kmedoids to cluster raw demand profiles and resource capacity factor profiles into representative periods. Use Extreme Periods to capture noteworthy periods or periods with notably poor fits.
In Demand_data.csv, include the following:
Timesteps_per_Rep_Period - Typically 168 timesteps (e.g., hours) per period, this designates the length of each representative period.
UseExtremePeriods - Either 1 or 0, this designates whether or not to include outliers (by performance or demand/resource extreme) as their own representative periods. This setting automatically includes the periods with maximum demand, minimum solar cf and minimum wind cf as extreme periods.
ClusterMethod - Either 'kmeans' or 'kmedoids', this designates the method used to cluster periods and determine each point's representative period.
ScalingMethod - Either 'N' or 'S', this designates directs the module to normalize ([0,1]) or standardize (mean 0, variance 1) the input data.
MinPeriods - The minimum number of periods used to represent the input data. If using UseExtremePeriods, this must be at least three. If IterativelyAddPeriods if off, this will be the total number of periods.
MaxPeriods - The maximum number of periods - both clustered periods and extreme periods - that may be used to represent the input data.
IterativelyAddPeriods - Either 1 or 0, this designates whether or not to add periods until the error threshold between input data and represented data is met or the maximum number of periods is reached.
Threshold - Iterative period addition will end if the period farthest (Euclidean Distance) from its representative period is within this percentage of the total possible error (for normalization) or ~95% of the total possible error (for standardization). E.g., for a threshold of 0.01, every period must be within 1% of the spread of possible error before the clustering iterations will terminate (or until the max number of periods is reached).
IterateMethod - Either 'cluster' or 'extreme', this designates whether to add clusters to the kmeans/kmedoids method or to set aside the worst-fitting periods as a new extreme periods.
nReps - The number of times to repeat each kmeans/kmedoids clustering at the same setting.
DemandWeight - Default 1, this is an optional multiplier on demand columns in order to prioritize better fits for demand profiles over resource capacity factor profiles.
WeightTotal - Default 8760, the sum to which the relative weights of representative periods will be scaled.
ClusterFuelPrices - Either 1 or 0, this indicates whether or not to use the fuel price time series in Fuels_data.csv in the clustering process. If 'no', this function will still write Fuels_data_clustered.csv with reshaped fuel prices based on the number and size of the representative weeks, assuming a constant time series of fuel prices with length equal to the number of timesteps in the raw input data.
MultiStageConcatenate - (Only considered if MultiStage = 1 in genx_settings.yml) If 1, this designates that the model should time domain reduce the input data of all model stages together. Else if 0, [still in development] the model will time domain reduce only the first stage and will apply the periods of each other model stage to this set of representative periods by closest Eucliden distance.
For co-located VRE-STOR resources, all capacity factors must be in the Generatorsvariability.csv file in addition to separate Vreandstorsolarvariability.csv and Vreandstorwind_variability.csv files. The co-located solar PV and wind profiles for co-located resources will be separated into different CSV files to be read by loading the inputs after the clustering of the inputs has occurred.
get_demand_multipliers(ClusterOutputData, ModifiedData, M, W, DemandCols, TimestepsPerRepPeriod, NewColNames, NClusters, Ncols)
Get multipliers to linearly scale clustered demand profiles L zone-wise such that their weighted sum equals the original zonal total demand. Scale demand profiles later using these multipliers in order to ensure that a copy of the original demand is kept for validation.
where $Z$ is the set of zones, $I$ is the full time domain, $T$ is the length of one period (e.g., 168 for one week in hours), $M$ is the set of representative periods, $L_{i,z}$ is the original zonal demand profile over time (hour) index $i$, $C_{i,m,z}$ is the demand in timestep $i$ for representative period $m$ in zone $z$, $w_m$ is the weight of the representative period equal to the total number of hours that one hour in representative period $m$ represents in the original profile, and $k_z$ is the zonal demand multiplier returned by the function.
Identify extreme week by specification of profile type (Demand, PV, Wind), measurement type (absolute (timestep with min/max value) vs. integral (period with min/max summed value)), and statistic (minimum or maximum). I.e., the user could want the hour with the most demand across the whole system to be included among the extreme periods. They would select "Demand", "System, "Absolute, and "Max".
This module defines the power decision variable $\Theta_{y,t} \forall y \in \mathcal{G}, t \in \mathcal{T}$, representing energy injected into the grid by resource $y$ by at time period $t$. This module additionally defines contributions to the objective function from variable costs of generation (variable O&M) from all resources $y \in \mathcal{G}$ over all time periods $t \in \mathcal{T}$:
This module defines the power decision variable $\Theta_{y,t} \forall y \in \mathcal{G}, t \in \mathcal{T}$, representing energy injected into the grid by resource $y$ by at time period $t$. This module additionally defines contributions to the objective function from variable costs of generation (variable O&M) from all resources $y \in \mathcal{G}$ over all time periods $t \in \mathcal{T}$:
This function defines the expressions and constraints keeping track of total available power generation/discharge capacity across all resources as well as constraints on capacity retirements. The total capacity of each resource is defined as the sum of the existing capacity plus the newly invested capacity minus any retired capacity. Note for storage and co-located resources, additional energy and charge power capacity decisions and constraints are defined in the storage and co-located VRE and storage module respectively.
This function defines the expressions and constraints keeping track of total available power generation/discharge capacity across all resources as well as constraints on capacity retirements. The total capacity of each resource is defined as the sum of the existing capacity plus the newly invested capacity minus any retired capacity. Note for storage and co-located resources, additional energy and charge power capacity decisions and constraints are defined in the storage and co-located VRE and storage module respectively.
\[\begin{aligned}
& \Delta^{total}_{y,z} =(\overline{\Delta_{y,z}}+\Omega_{y,z}-\Delta_{y,z}) \forall y \in \mathcal{G}, z \in \mathcal{Z}
\end{aligned}\]
One cannot retire more capacity than existing capacity.
This function writes the file capacities_multi_stage.csv to the Results directory. This file contains starting resource capacities from the first model stage and end resource capacities for the first and all subsequent model stages.
inputs:
outpath – String which represents the path to the Results directory.
settings_d - Dictionary containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
Function for writing the "virtual" discharge of each storage technology. Virtual discharge is used to allow storage resources to contribute to the capacity reserve margin without actually discharging.
This function defines the non-served energy/curtailed demand decision variable $\Lambda_{s,t,z} \forall s \in \mathcal{S}, \forall t \in \mathcal{T}, z \in \mathcal{Z}$, representing the total amount of demand curtailed in demand segment $s$ at time period $t$ in zone $z$. The first segment of non-served energy, $s=1$, is used to denote the cost of involuntary demand curtailment (e.g. emergency load shedding or rolling blackouts), specified as the value of $n_{1}^{slope}$. Additional segments, $s \geq 2$ can be used to specify a segment-wise approximation of a price elastic demand curve, or segments of price-responsive curtailable demands (aka demand response). Each segment denotes a price/cost at which the segment of demand is willing to curtail consumption, $n_{s}^{slope}$, representing the marginal willingness to pay for electricity of this segment of demand (or opportunity cost incurred when demand is not served) and a maximum quantity of demand in this segment, $n_{s}^{size}$, specified as a share of demand in each zone in each time step, $D_{t,z}.$ Note that the current implementation assumes demand segments are an equal share of hourly demand in all zones. This function defines contributions to the objective function from the cost of non-served energy/curtailed demand from all demand curtailment segments $s \in \mathcal{S}$ over all time periods $t \in \mathcal{T}$ and all zones $z \in \mathcal{Z}$:
This function writes the file capacities_multi_stage.csv to the Results directory. This file contains starting resource capacities from the first model stage and end resource capacities for the first and all subsequent model stages.
inputs:
outpath – String which represents the path to the Results directory.
settings_d - Dictionary containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
Function for writing the "virtual" discharge of each storage technology. Virtual discharge is used to allow storage resources to contribute to the capacity reserve margin without actually discharging.
This function defines the non-served energy/curtailed demand decision variable $\Lambda_{s,t,z} \forall s \in \mathcal{S}, \forall t \in \mathcal{T}, z \in \mathcal{Z}$, representing the total amount of demand curtailed in demand segment $s$ at time period $t$ in zone $z$. The first segment of non-served energy, $s=1$, is used to denote the cost of involuntary demand curtailment (e.g. emergency load shedding or rolling blackouts), specified as the value of $n_{1}^{slope}$. Additional segments, $s \geq 2$ can be used to specify a segment-wise approximation of a price elastic demand curve, or segments of price-responsive curtailable demands (aka demand response). Each segment denotes a price/cost at which the segment of demand is willing to curtail consumption, $n_{s}^{slope}$, representing the marginal willingness to pay for electricity of this segment of demand (or opportunity cost incurred when demand is not served) and a maximum quantity of demand in this segment, $n_{s}^{size}$, specified as a share of demand in each zone in each time step, $D_{t,z}.$ Note that the current implementation assumes demand segments are an equal share of hourly demand in all zones. This function defines contributions to the objective function from the cost of non-served energy/curtailed demand from all demand curtailment segments $s \in \mathcal{S}$ over all time periods $t \in \mathcal{T}$ and all zones $z \in \mathcal{Z}$:
Contributions to the power balance expression from non-served energy/curtailed demand from each demand segment $s \in \mathcal{S}$ are also defined as:
This function establishes several different versions of contingency reserve requirement expression, $CONTINGENCY$ used in the operationalreservescore() function below.
Contingency operational reserves represent requirements for upward ramping capability within a specified time frame to compensated for forced outages or unplanned failures of generators or transmission lines (e.g. N-1 contingencies).
There are three options for the $Contingency$ expression, depending on user settings: 1. a static contingency, in which the contingency requirement is set based on a fixed value (in MW) specified in the '''Operational_reserves.csv''' input file; 2. a dynamic contingency based on installed capacity decisions, in which the largest 'installed' generator is used to determine the contingency requirement for all time periods; and 3. dynamic unit commitment based contingency, in which the largest 'committed' generator in any time period is used to determine the contingency requirement in that time period.
Note that the two dynamic contigencies are only available if unit commitment is being modeled.
Static contingency Option 1 (static contingency) is expressed by the following constraint:
This function establishes several different versions of contingency reserve requirement expression, $CONTINGENCY$ used in the operationalreservescore() function below.
Contingency operational reserves represent requirements for upward ramping capability within a specified time frame to compensated for forced outages or unplanned failures of generators or transmission lines (e.g. N-1 contingencies).
There are three options for the $Contingency$ expression, depending on user settings: 1. a static contingency, in which the contingency requirement is set based on a fixed value (in MW) specified in the '''Operational_reserves.csv''' input file; 2. a dynamic contingency based on installed capacity decisions, in which the largest 'installed' generator is used to determine the contingency requirement for all time periods; and 3. dynamic unit commitment based contingency, in which the largest 'committed' generator in any time period is used to determine the contingency requirement in that time period.
Note that the two dynamic contigencies are only available if unit commitment is being modeled.
Static contingency Option 1 (static contingency) is expressed by the following constraint:
where $\epsilon^{contingency}$ is static contingency requirement in MWs.
Dynamic capacity-based contingency Option 2 (dynamic capacity-based contingency) is expressed by the following constraints:
\[\begin{aligned}
&Contingency \geq \Omega^{size}_{y,z} \times \alpha^{Contingency,Aux}_{y,z} & \forall y \in \mathcal{UC}, z \in \mathcal{Z}\\
@@ -39,7 +39,7 @@
& Contingency \geq \Omega^{size}_{y,z} \times Contingency\_Aux_{y,z,t} & \forall y \in \mathcal{UC}, z \in \mathcal{Z}\\
& Contingency\_Aux_{y,z,t} \leq \nu_{y,z,t} & \forall y \in \mathcal{UC}, z \in \mathcal{Z}\\
& Contingency\_Aux_{y,z,t} \geq M_y \times \nu_{y,z,t} & \forall y \in \mathcal{UC}, z \in \mathcal{Z}\\
-\end{aligned}\]
where $M_y$ is a `big M' constant equal to the largest possible capacity that can be installed for generation cluster $y$, and $Contingency\_Aux_{y,z,t} \in [0,1]$ is a binary auxiliary variable that is forced by the second and third equations above to be 1 if the commitment state for that generation cluster $\nu_{y,z,t} > 0$ for any generator $y \in \mathcal{UC}$ and zone $z$ and time period $t$, and can be 0 otherwise. Note that this dynamic commitment-based contingency can only be specified if discrete unit commitment decisions are used (e.g. it will not work if relaxed unit commitment is used).
This function creates decision variables related to frequency regulation and reserves provision and constraints setting overall system requirements for regulation and operating reserves.
Regulation and reserves decisions$f_{y,t,z} \geq 0$ is the contribution of generation or storage resource $y \in Y$ in time $t \in T$ and zone $z \in Z$ to frequency regulation
\[r_{y,t,z} \geq 0\]
is the contribution of generation or storage resource $y \in Y$ in time $t \in T$ and zone $z \in Z$ to operating reserves up
We assume frequency regulation is symmetric (provided in equal quantity towards both upwards and downwards regulation). To reduce computational complexity, operating reserves are only modeled in the upwards direction, as downwards reserves requirements are rarely binding in practice.
Storage resources ($y \in \mathcal{O}$) have two pairs of auxilary variables to reflect contributions to regulation and reserves when charging and discharging, where the primary variables ($f_{y,z,t}$ \& $r_{y,z,t}$) becomes equal to sum of these auxilary variables.
Co-located VRE-STOR resources are described further in the reserves function for colocated VRE and storage resources (vre_stor_operational_reserves!()).
Unmet operating reserves
\[unmet\_rsv_{t} \geq 0\]
denotes any shortfall in provision of operating reserves during each time period $t \in T$
There is a penalty $C^{rsv}$ added to the objective function to penalize reserve shortfalls, equal to:
\[\begin{aligned}
+\end{aligned}\]
where $M_y$ is a `big M' constant equal to the largest possible capacity that can be installed for generation cluster $y$, and $Contingency\_Aux_{y,z,t} \in [0,1]$ is a binary auxiliary variable that is forced by the second and third equations above to be 1 if the commitment state for that generation cluster $\nu_{y,z,t} > 0$ for any generator $y \in \mathcal{UC}$ and zone $z$ and time period $t$, and can be 0 otherwise. Note that this dynamic commitment-based contingency can only be specified if discrete unit commitment decisions are used (e.g. it will not work if relaxed unit commitment is used).
This function creates decision variables related to frequency regulation and reserves provision and constraints setting overall system requirements for regulation and operating reserves.
Regulation and reserves decisions$f_{y,t,z} \geq 0$ is the contribution of generation or storage resource $y \in Y$ in time $t \in T$ and zone $z \in Z$ to frequency regulation
\[r_{y,t,z} \geq 0\]
is the contribution of generation or storage resource $y \in Y$ in time $t \in T$ and zone $z \in Z$ to operating reserves up
We assume frequency regulation is symmetric (provided in equal quantity towards both upwards and downwards regulation). To reduce computational complexity, operating reserves are only modeled in the upwards direction, as downwards reserves requirements are rarely binding in practice.
Storage resources ($y \in \mathcal{O}$) have two pairs of auxilary variables to reflect contributions to regulation and reserves when charging and discharging, where the primary variables ($f_{y,z,t}$ \& $r_{y,z,t}$) becomes equal to sum of these auxilary variables.
Co-located VRE-STOR resources are described further in the reserves function for colocated VRE and storage resources (vre_stor_operational_reserves!()).
Unmet operating reserves
\[unmet\_rsv_{t} \geq 0\]
denotes any shortfall in provision of operating reserves during each time period $t \in T$
There is a penalty $C^{rsv}$ added to the objective function to penalize reserve shortfalls, equal to:
Total requirements for frequency regulation (aka primary reserves) in each time step $t$ are specified as fractions of hourly demand (to reflect demand forecast errors) and variable renewable avaialblity in the time step (to reflect wind and solar forecast errors).
where $\mathcal{D}_{z,t}$ is the forecasted electricity demand in zone $z$ at time $t$ (before any demand flexibility); $\rho^{max}_{y,z,t}$ is the forecasted capacity factor for standalone variable renewable resources $y \in VRE$ and zone $z$ in time step $t$; $\rho^{max,pv}_{y,z,t}$ is the forecasted capacity factor for co-located solar PV resources $y \in \mathcal{VS}^{pv}$ and zone $z$ in time step $t$; $\rho^{max,wind}_{y,z,t}$ is the forecasted capacity factor for co-located wind resources $y \in \mathcal{VS}^{pv}$ and zone $z$ in time step $t$; $\Delta^{\text{total,pv}}_{y,z}$ is the total installed capacity of co-located solar PV resources $y \in \mathcal{VS}^{pv}$ and zone $z$; $\Delta^{\text{total,wind}}_{y,z}$ is the total installed capacity of co-located wind resources $y \in \mathcal{VS}^{wind}$ and zone $z$; and $\epsilon^{demand}_{reg}$ and $\epsilon^{vre}_{reg}$ are parameters specifying the required frequency regulation as a fraction of forecasted demand and variable renewable generation.
Operating reserve requirements
Total requirements for operating reserves in the upward direction (aka spinning reserves or contingency reserces or secondary reserves) in each time step $t$ are specified as fractions of time step's demand (to reflect demand forecast errors) and variable renewable avaialblity in the time step (to reflect wind and solar forecast errors) plus the largest planning contingency (e.g. potential forced generation outage).
where $\mathcal{D}_{z,t}$ is the forecasted electricity demand in zone $z$ at time $t$ (before any demand flexibility); $\rho^{max}_{y,z,t}$ is the forecasted capacity factor for standalone variable renewable resources $y \in VRE$ and zone $z$ in time step $t$; $\rho^{max,pv}_{y,z,t}$ is the forecasted capacity factor for co-located solar PV resources $y \in \mathcal{VS}^{pv}$ and zone $z$ in time step $t$; $\rho^{max,wind}_{y,z,t}$ is the forecasted capacity factor for co-located wind resources $y \in \mathcal{VS}^{wind}$ and zone $z$ in time step $t$; $\Delta^{\text{total}}_{y,z}$ is the total installed capacity of standalone variable renewable resources $y \in VRE$ and zone $z$; $\Delta^{\text{total,pv}}_{y,z}$ is the total installed capacity of co-located solar PV resources $y \in \mathcal{VS}^{pv}$ and zone $z$; $\Delta^{\text{total,wind}}_{y,z}$ is the total installed capacity of co-located wind resources $y \in \mathcal{VS}^{wind}$ and zone $z$; and $\epsilon^{demand}_{rsv}$ and $\epsilon^{vre}_{rsv}$ are parameters specifying the required contingency reserves as a fraction of forecasted demand and variable renewable generation. $Contingency$ is an expression defined in the operational_reserves_contingency!() function meant to represent the largest N-1 contingency (unplanned generator outage) that the system operator must carry operating reserves to cover and depends on how the user wishes to specify contingency requirements.
function dcopf_transmission!(EP::Model, inputs::Dict, setup::Dict)
The addtional constraints imposed upon the line flows in the case of DC-OPF are as follows: For the definition of the line flows, in terms of the voltage phase angles:
\[\begin{aligned}
+\end{aligned}\]
where $\mathcal{D}_{z,t}$ is the forecasted electricity demand in zone $z$ at time $t$ (before any demand flexibility); $\rho^{max}_{y,z,t}$ is the forecasted capacity factor for standalone variable renewable resources $y \in VRE$ and zone $z$ in time step $t$; $\rho^{max,pv}_{y,z,t}$ is the forecasted capacity factor for co-located solar PV resources $y \in \mathcal{VS}^{pv}$ and zone $z$ in time step $t$; $\rho^{max,wind}_{y,z,t}$ is the forecasted capacity factor for co-located wind resources $y \in \mathcal{VS}^{wind}$ and zone $z$ in time step $t$; $\Delta^{\text{total}}_{y,z}$ is the total installed capacity of standalone variable renewable resources $y \in VRE$ and zone $z$; $\Delta^{\text{total,pv}}_{y,z}$ is the total installed capacity of co-located solar PV resources $y \in \mathcal{VS}^{pv}$ and zone $z$; $\Delta^{\text{total,wind}}_{y,z}$ is the total installed capacity of co-located wind resources $y \in \mathcal{VS}^{wind}$ and zone $z$; and $\epsilon^{demand}_{rsv}$ and $\epsilon^{vre}_{rsv}$ are parameters specifying the required contingency reserves as a fraction of forecasted demand and variable renewable generation. $Contingency$ is an expression defined in the operational_reserves_contingency!() function meant to represent the largest N-1 contingency (unplanned generator outage) that the system operator must carry operating reserves to cover and depends on how the user wishes to specify contingency requirements.
function dcopf_transmission!(EP::Model, inputs::Dict, setup::Dict)
The addtional constraints imposed upon the line flows in the case of DC-OPF are as follows: For the definition of the line flows, in terms of the voltage phase angles:
\[\begin{aligned}
& \Phi_{l,t}=\mathcal{B}_{l} \times (\sum_{z\in \mathcal{Z}}{(\varphi^{map}_{l,z} \times \theta_{z,t})}) \quad \forall l \in \mathcal{L}, \; \forall t \in \mathcal{T}\\
\end{aligned}\]
For imposing the constraint of maximum allowed voltage phase angle difference across lines:
\[\begin{aligned}
& \sum_{z\in \mathcal{Z}}{(\varphi^{map}_{l,z} \times \theta_{z,t})} \leq \Delta \theta^{\max}_{l} \quad \forall l \in \mathcal{L}, \forall t \in \mathcal{T}\\
& \sum_{z\in \mathcal{Z}}{(\varphi^{map}_{l,z} \times \theta_{z,t})} \geq -\Delta \theta^{\max}_{l} \quad \forall l \in \mathcal{L}, \forall t \in \mathcal{T}\\
\end{aligned}\]
Finally, we enforce the reference voltage phase angle constraint:
\[\begin{aligned}
\theta_{1,t} = 0 \quad \forall t \in \mathcal{T}
-\end{aligned}\]
function investment_transmission!(EP::Model, inputs::Dict, setup::Dict)
The function model transmission expansion and adds transmission reinforcement or construction costs to the objective function. Transmission reinforcement costs are equal to the sum across all lines of the product between the transmission reinforcement/construction cost, $pi^{TCAP}_{l}$, times the additional transmission capacity variable, $\bigtriangleup\varphi^{cap}_{l}$.
```math
\begin{aligned}
@@ -72,7 +72,7 @@
The additional transmission capacity, $\bigtriangleup\varphi^{cap}_{l} $, is constrained by a maximum allowed reinforcement, $\overline{\bigtriangleup\varphi^{cap}_{l}}$, for each line $l \in \mathcal{E}$.
\begin{aligned}
& \bigtriangleup\varphi^{cap}_{l} \leq \overline{\bigtriangleup\varphi^{cap}_{l}}, &\quad \forall l \in \mathcal{E}
- \end{aligned}
This function establishes decisions, expressions, and constraints related to transmission power flows between model zones and associated transmission losses (if modeled).
Power flow and transmission loss terms are also added to the power balance constraint for each zone:
This function establishes decisions, expressions, and constraints related to transmission power flows between model zones and associated transmission losses (if modeled).
Power flow and transmission loss terms are also added to the power balance constraint for each zone:
Power flows, $\Phi_{l,t}$, on each line $l$ into or out of a zone (defined by the network map $\varphi^{map}_{l,z}$), are considered in the demand balance equation for each zone. By definition, power flows leaving their reference zone are positive, thus the minus sign is used for this term. Losses due to power flows increase demand, and one-half of losses across a line linking two zones are attributed to each connected zone. The losses function $\beta_{l,t}(\cdot)$ will depend on the configuration used to model losses (see below). Accounting for Transmission Between Zones Power flow, $\Phi_{l,t}$, on each line (or more likely a `path' aggregating flows across multiple parallel lines) is constrained to be less than or equal to the line's power transfer capacity, $\varphi^{cap}_{l}$, plus any transmission capacity added on that line (for lines eligible for expansion in the set $\mathcal{E}$). The additional transmission capacity, $\bigtriangleup\varphi^{cap}_{l} $, is constrained by a maximum allowed reinforcement, $\overline{\bigtriangleup\varphi^{cap}_{l}}$, for each line $l \in \mathcal{E}$.
\[\begin{aligned}
% trasmission constraints
@@ -112,19 +112,19 @@
&\mathcal{S}^{-}_{m,l,t} \geq ON^{-}_{m+1,l,t} \times \overline{\mathcal{S}_{m,l}} , &\quad \forall m \in [1:M], \forall l \in \mathcal{L}, \forall t \in \mathcal{T}\\
&\mathcal{S}^{+}_{0,l,t} \leq \varphi^{max}_{l} \times (1- ON^{+}_{1,l,t}), &\quad \forall l \in \mathcal{L}, \forall t \in \mathcal{T}\\
&\mathcal{S}^{-}_{0,l,t} \leq \varphi^{max}_{l} \times (1- ON^{-}_{1,l,t}), &\quad \forall l \in \mathcal{L}, \forall t \in \mathcal{T}
-\end{aligned}\]
This function creates decision variables and cost expressions associated with thermal plant unit commitment or start-up and shut-down decisions (cycling on/off)
Unit commitment decision variables:
This function defines the following decision variables:
\[\nu_{y,t,z}\]
designates the commitment state of generator cluster $y$ in zone $z$ at time $t$; $\chi_{y,t,z}$ represents number of startup decisions in cluster $y$ in zone $z$ at time $t$; $\zeta_{y,t,z}$ represents number of shutdown decisions in cluster $y$ in zone $z$ at time $t$.
Cost expressions:
The total cost of start-ups across all generators subject to unit commitment ($y \in UC$) and all time periods, t is expressed as:
This function creates decision variables and cost expressions associated with thermal plant unit commitment or start-up and shut-down decisions (cycling on/off)
Unit commitment decision variables:
This function defines the following decision variables:
\[\nu_{y,t,z}\]
designates the commitment state of generator cluster $y$ in zone $z$ at time $t$; $\chi_{y,t,z}$ represents number of startup decisions in cluster $y$ in zone $z$ at time $t$; $\zeta_{y,t,z}$ represents number of shutdown decisions in cluster $y$ in zone $z$ at time $t$.
Cost expressions:
The total cost of start-ups across all generators subject to unit commitment ($y \in UC$) and all time periods, t is expressed as:
This function creates expressions to account for CO2 emissions as well as captured and sequestrated CO2 from thermal generators. It also has the capability to model the negative CO2 emissions from bioenergy with carbon capture and storage.
***** Expressions *****
For thermal generators which combust fuels (e.g., coal, natural gas, and biomass), the net CO2 emission to the environment is a function of fuel consumption, CO2 emission factor, CO2 capture fraction, and whether the feedstock is biomass. Biomass is a factor in this equation because biomass generators are assumed to generate zero net CO2 emissions, or negative net CO2 emissions in the case that the CO2 they emit is captured and sequestered underground.
If a user wishes to represent a generator that combusts biomass, then in the resource .csv files, the "Biomass" column (boolean, 1 or 0), which represents if a generator $y$ uses biomass or not, should be set to 1. The CO2 emissions from such a generator will be assumed to be zero without CCS and negative with CCS.
The CO2 emissions from generator $y$ at time $t$ are determined by total fuel consumption (MMBTU) multiplied by the CO2 content of the fuel (tCO2/MMBTU), and by (1 - Biomass [0 or 1] - CO2 capture fraction [a fraction, between 0 - 1]). The CO2 capture fraction could be differernt during the steady-state and startup events (generally startup events have a lower CO2 capture fraction), so we use distinct CO2 capture fractions to determine the emissions. In short, the CO2 emissions for a generator depend on the CO2 emission factor from fuel combustion, the CO2 capture fraction, and whether the generator uses biomass.
\[\begin{aligned}
+\end{aligned}\]
The sum of start-up costs is added to the objective function.
This function creates expressions to account for CO2 emissions as well as captured and sequestrated CO2 from thermal generators. It also has the capability to model the negative CO2 emissions from bioenergy with carbon capture and storage.
***** Expressions *****
For thermal generators which combust fuels (e.g., coal, natural gas, and biomass), the net CO2 emission to the environment is a function of fuel consumption, CO2 emission factor, CO2 capture fraction, and whether the feedstock is biomass. Biomass is a factor in this equation because biomass generators are assumed to generate zero net CO2 emissions, or negative net CO2 emissions in the case that the CO2 they emit is captured and sequestered underground.
If a user wishes to represent a generator that combusts biomass, then in the resource .csv files, the "Biomass" column (boolean, 1 or 0), which represents if a generator $y$ uses biomass or not, should be set to 1. The CO2 emissions from such a generator will be assumed to be zero without CCS and negative with CCS.
The CO2 emissions from generator $y$ at time $t$ are determined by total fuel consumption (MMBTU) multiplied by the CO2 content of the fuel (tCO2/MMBTU), and by (1 - Biomass [0 or 1] - CO2 capture fraction [a fraction, between 0 - 1]). The CO2 capture fraction could be differernt during the steady-state and startup events (generally startup events have a lower CO2 capture fraction), so we use distinct CO2 capture fractions to determine the emissions. In short, the CO2 emissions for a generator depend on the CO2 emission factor from fuel combustion, the CO2 capture fraction, and whether the generator uses biomass.
Where $Biomass_y$ represents a binary variable (1 or 0) that determines if the generator $y$ uses biomass, and $CO2\_Capture\_Fraction_y$ represents a fraction for CO2 capture rate.
In addition to CO2 emissions, for generators with a non-zero CO2 capture rate, we also determine the amount of CO2 being captured and sequestered. The CO2 emissions from generator $y$ at time $t$, denoted by $eEmissionsCaptureByPlant_{g,t}$, are determined by total fuel consumption (MMBTU) multiplied by the $CO_2$ content of the fuel (tCO2/MMBTU), times CO2 capture rate.
\[\begin{aligned}
eEmissionsCaptureByPlant_{g,t} = CO2\_Capture\_Fraction_y * vFuel_{y,t} * CO2_{content} + CO2\_Capture\_Fraction\_Startup_y * eStartFuel_{y,t} * CO2_{content}
\hspace{1cm} \forall y \in G, \forall t \in T
-\end{aligned}\]
This function creates expressions to account for total fuel consumption (e.g., coal, natural gas, hydrogen, etc). It also has the capability to model heat rates that are a function of load via a piecewise-linear approximation.
***** Expressions ****** Users have two options to model the fuel consumption as a function of power generation: (1). Use a constant heat rate, regardless of the minimum load or maximum load; and (2). Use the PiecewiseFuelUsage-related parameters to model the fuel consumption via a piecewise-linear approximation of the heat rate curves. By using this option, users can represent the fact that most generators have a decreasing heat rate as a function of load.
(1). Constant heat rate. The fuel consumption for power generation $vFuel_{y,t}$ is determined by power generation ($vP_{y,t}$) mutiplied by the corresponding heat rate ($Heat\_Rate_y$). The fuel costs for power generation and start fuel for a plant $y$ at time $t$, denoted by $eCFuelOut_{y,t}$ and $eFuelStart$, are determined by fuel consumption ($vFuel_{y,t}$ and $eStartFuel$) multiplied by the fuel costs ($/MMBTU) (2). Piecewise-linear approximation With this formulation, the heat rate of generators becomes a function of load. In reality this relationship takes a nonlinear form, but we model it through a piecewise-linear approximation:
This function creates expressions to account for total fuel consumption (e.g., coal, natural gas, hydrogen, etc). It also has the capability to model heat rates that are a function of load via a piecewise-linear approximation.
***** Expressions ****** Users have two options to model the fuel consumption as a function of power generation: (1). Use a constant heat rate, regardless of the minimum load or maximum load; and (2). Use the PiecewiseFuelUsage-related parameters to model the fuel consumption via a piecewise-linear approximation of the heat rate curves. By using this option, users can represent the fact that most generators have a decreasing heat rate as a function of load.
(1). Constant heat rate. The fuel consumption for power generation $vFuel_{y,t}$ is determined by power generation ($vP_{y,t}$) mutiplied by the corresponding heat rate ($Heat\_Rate_y$). The fuel costs for power generation and start fuel for a plant $y$ at time $t$, denoted by $eCFuelOut_{y,t}$ and $eFuelStart$, are determined by fuel consumption ($vFuel_{y,t}$ and $eStartFuel$) multiplied by the fuel costs ($/MMBTU) (2). Piecewise-linear approximation With this formulation, the heat rate of generators becomes a function of load. In reality this relationship takes a nonlinear form, but we model it through a piecewise-linear approximation:
\[\begin{aligned}
vFuel_{y,t} >= vP_{y,t} * h_{y,x} + U_{g,t}* f_{y,x}
\hspace{1cm} \forall y \in G, \forall t \in T, \forall x \in X
\end{aligned}\]
Where $h_{y,x}$ represents the heat rate slope for generator $y$ in segment $x$ [MMBTU/MWh], $f_{y,x}$ represents the heat rate intercept (MMBTU) for a generator $y$ in segment $x$ [MMBTU], and $U_{y,t}$ represents the commitment status of a generator $y$ at time $t$. These parameters are optional inputs to the resource .csv files. When Unit commitment is on, if a user provides slope and intercept, the standard heat rate (i.e., HeatRateMMBTUperMWh) will not be used. When unit commitment is off, the model will always use the standard heat rate. The user should determine the slope and intercept parameters based on the CapSize of the plant. For example, when a plant is operating at the full load (i.e., power output equal to the CapSize), the fuel usage determined by the effective segment divided by Cap_Size should be equal to the heat rate at full-load.
Since fuel consumption and fuel costs are postive, the optimization will force the fuel usage to be equal to the highest fuel usage segment for any given value of vP. When the power output is zero, the commitment variable $U_{g,t}$ will bring the intercept to be zero such that the fuel consumption is zero when thermal units are offline.
In order to run piecewise fuel consumption module, the unit commitment must be turned on (UC = 1 or 2), and users should provide PWFUSlope* and PWFUIntercept* for at least one segment.
To enable resources to use multiple fuels during both startup and normal operational processes, three additional variables were added: fuel $i$ consumption by plant $y$ at time $t$ ($vMulFuel_{y,i,t}$); startup fuel consumption for single-fuel plants ($vStartFuel_{y,t}$); and startup fuel consumption for multi-fuel plants ($vMulStartFuel_{y,i,t}$). By making startup fuel consumption variables, the model can choose the startup fuel to meet the constraints.
For plants using multiple fuels:
During startup, heat input from multiple startup fuels are equal to startup fuel requirements in plant $y$ at time $t$: $StartFuelMMBTUperMW$ times $Capsize$.
During normal operation, the sum of fuel consumptions from multiple fuels dividing by the correspnding heat rates, respectively, is equal to $vPower$ in plant $y$ at time $t$.
There are also constraints on how much heat input each fuel can provide, which are specified by $MinCofire$ and $MaxCofire$. ```math \begin{aligned} vMulFuels{y, i, t} >= vPower{y,t} \times MinCofire{i} \end{aligned} \begin{aligned} vMulFuels{y, i, t} <= vPower{y,t} \times MaxCofire{i} \end{aligned}
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+\end{aligned}\]
There are also constraints on how much heat input each fuel can provide, which are specified by $MinCofire$ and $MaxCofire$. ```math \begin{aligned} vMulFuels{y, i, t} >= vPower{y,t} \times MinCofire{i} \end{aligned} \begin{aligned} vMulFuels{y, i, t} <= vPower{y,t} \times MaxCofire{i} \end{aligned}
This function sets up and solves a constrained optimization model of electricity system capacity expansion and operation problem and extracts solution variables for later processing.
In addition to calling a number of other modules to create constraints for specific resources, policies, and transmission assets, this function initializes two key expressions that are successively expanded in each of the resource-specific modules: (1) the objective function; and (2) the zonal power balance expression. These two expressions are the only expressions which link together individual modules (e.g. resources, transmission assets, policies), which otherwise are self-contained in defining relevant variables, expressions, and constraints.
Objective Function
The objective function of GenX minimizes total annual electricity system costs over the following six components shown in the equation below:
This function sets up and solves a constrained optimization model of electricity system capacity expansion and operation problem and extracts solution variables for later processing.
In addition to calling a number of other modules to create constraints for specific resources, policies, and transmission assets, this function initializes two key expressions that are successively expanded in each of the resource-specific modules: (1) the objective function; and (2) the zonal power balance expression. These two expressions are the only expressions which link together individual modules (e.g. resources, transmission assets, policies), which otherwise are self-contained in defining relevant variables, expressions, and constraints.
Objective Function
The objective function of GenX minimizes total annual electricity system costs over the following six components shown in the equation below:
Determine the directory based on the setup parameters.
This function checks if the TimeDomainReduction setup parameter is equal to 1 and if time domain reduced files exist in the data directory. If the condition is met, it returns the path to the TDR_results data directory. Otherwise, it returns the system directory specified in the setup.
Parameters:
setup: Dict{String, Any} - The GenX settings parameters containing TimeDomainReduction and SystemFolder information.
TDR_directory: String - The data directory where files are located.
path: String - Path to the case folder.
Returns:
String: The directory path based on the setup parameters.
Loads various data inputs from multiple input .csv files in path directory and stores variables in a Dict (dictionary) object for use in model() function
inputs: setup - dict object containing setup parameters path - string path to working directory
returns: Dict (dictionary) object containing all data inputs
Adds the data contained in a DataFrame to a vector of resources. Each row in the DataFrame corresponds to a resource. If the name of the resource in the DataFrame matches a name of a resource in the model, all the columns of that DataFrameRow are added as new attributes to the corresponding resource.
Arguments
resources::Vector{<:AbstractResource}: A vector of resources.
Reads module dataframe and adds columns as new attributes to the resources in the model if the resource name in the module file matches a resource name in the model. The module file is assumed to have a column named "resource" containing the resource names.
Arguments
resources::Vector{<:AbstractResource}: A vector of resources.
module_in::DataFrame: The dataframe with the columns to add to the resources.
Loads a single policy file and adds the columns as new attributes to resources in the model if the resource name in the policy file matches a resource name in the model. The policy file is assumed to have a column named "resource" containing the resource names.
Arguments
resources::Vector{<:AbstractResource}: A vector of resources.
path::AbstractString: The path to the policy file.
filename::AbstractString: The name of the policy file.
Adds resources to the inputsDict with the key "RESOURCES" together with sevaral sets of resource indices that are used inside GenX to construct the optimization problem. The inputsDict is modified in-place.
Arguments
inputs (Dict): Dictionary to store the GenX input data.
Construct the array of resources from multiple files of different types located in the specified resource_folder. The resources_info NamedTuple contains the filename and GenX type for each type of resource available in GenX.
Arguments
resource_folder::AbstractString: The path to the folder containing the resource files.
resources_info::NamedTuple: A NamedTuple that maps a resource type to its filename and GenX type.
scale_factor::Float64: A scaling factor to adjust the attributes of the resources (default: 1.0).
Returns
Vector{<:AbstractResource}: An array of GenX resources.
Raises
Error: If no resources data is found. Check the data path or the configuration file "genx_settings.yml" inside Settings.
This function takes a DataFrame resource_in and a GenX ResourceType type, and converts the DataFrame to an array of AbstractResource of the specified type.
Arguments
resource_in::DataFrame: The input DataFrame containing the resources belonging to a specific type.
ResourceType: The GenX type of resources to be converted to.
Returns
resources::Vector{ResourceType}: An array of resources of the specified type.
Reads piecewise fuel usage data from the vector of generators, create a PWFU_data that contain processed intercept and slope (i.e., heat rate) and add them to the inputs dictionary.
Arguments
setup::Dict: The dictionary containing the setup parameters
case_path::AbstractString: The path to the case folder
gen::Vector{<:AbstractResource}: The vector of generators in the model
inputs::Dict: The dictionary containing the input data
Scales resources attributes in-place if necessary. Generally, these scalings converts energy and power units from MW to GW and /MW to M/GW. Both are done by dividing the values by 1000. See documentation for descriptions of each column being scaled.
Arguments
resource_in (DataFrame): A dataframe containing data for a specific resource.
scale_factor (Float64): A scaling factor for energy and currency units.
Scales vre_stor attributes in-place if necessary. Generally, these scalings converts energy and power units from MW to GW and /MW to M/GW. Both are done by dividing the values by 1000. See documentation for descriptions of each column being scaled.
Arguments
vre_stor_in (DataFrame): A dataframe containing data for co-located VREs and storage.
scale_factor (Float64): A scaling factor for energy and currency units.
For co-located VRE-storage resources, this function returns the storage type (1. long-duration or short-duration storage, 2. symmetric or asymmetric storage) for charging and discharging capacities
This function prevents TimeDomainReduction from running on a case which already has more than one Representative Period or has more than one Sub_Weight specified.
Determine the directory based on the setup parameters.
This function checks if the TimeDomainReduction setup parameter is equal to 1 and if time domain reduced files exist in the data directory. If the condition is met, it returns the path to the TDR_results data directory. Otherwise, it returns the system directory specified in the setup.
Parameters:
setup: Dict{String, Any} - The GenX settings parameters containing TimeDomainReduction and SystemFolder information.
TDR_directory: String - The data directory where files are located.
path: String - Path to the case folder.
Returns:
String: The directory path based on the setup parameters.
Loads various data inputs from multiple input .csv files in path directory and stores variables in a Dict (dictionary) object for use in model() function
inputs: setup - dict object containing setup parameters path - string path to working directory
returns: Dict (dictionary) object containing all data inputs
Adds the data contained in a DataFrame to a vector of resources. Each row in the DataFrame corresponds to a resource. If the name of the resource in the DataFrame matches a name of a resource in the model, all the columns of that DataFrameRow are added as new attributes to the corresponding resource.
Arguments
resources::Vector{<:AbstractResource}: A vector of resources.
Reads module dataframe and adds columns as new attributes to the resources in the model if the resource name in the module file matches a resource name in the model. The module file is assumed to have a column named "resource" containing the resource names.
Arguments
resources::Vector{<:AbstractResource}: A vector of resources.
module_in::DataFrame: The dataframe with the columns to add to the resources.
Loads a single policy file and adds the columns as new attributes to resources in the model if the resource name in the policy file matches a resource name in the model. The policy file is assumed to have a column named "resource" containing the resource names.
Arguments
resources::Vector{<:AbstractResource}: A vector of resources.
path::AbstractString: The path to the policy file.
filename::AbstractString: The name of the policy file.
Adds resources to the inputsDict with the key "RESOURCES" together with sevaral sets of resource indices that are used inside GenX to construct the optimization problem. The inputsDict is modified in-place.
Arguments
inputs (Dict): Dictionary to store the GenX input data.
Construct the array of resources from multiple files of different types located in the specified resource_folder. The resources_info NamedTuple contains the filename and GenX type for each type of resource available in GenX.
Arguments
resource_folder::AbstractString: The path to the folder containing the resource files.
resources_info::NamedTuple: A NamedTuple that maps a resource type to its filename and GenX type.
scale_factor::Float64: A scaling factor to adjust the attributes of the resources (default: 1.0).
Returns
Vector{<:AbstractResource}: An array of GenX resources.
Raises
Error: If no resources data is found. Check the data path or the configuration file "genx_settings.yml" inside Settings.
This function takes a DataFrame resource_in and a GenX ResourceType type, and converts the DataFrame to an array of AbstractResource of the specified type.
Arguments
resource_in::DataFrame: The input DataFrame containing the resources belonging to a specific type.
ResourceType: The GenX type of resources to be converted to.
Returns
resources::Vector{ResourceType}: An array of resources of the specified type.
Reads piecewise fuel usage data from the vector of generators, create a PWFU_data that contain processed intercept and slope (i.e., heat rate) and add them to the inputs dictionary.
Arguments
setup::Dict: The dictionary containing the setup parameters
case_path::AbstractString: The path to the case folder
gen::Vector{<:AbstractResource}: The vector of generators in the model
inputs::Dict: The dictionary containing the input data
Scales resources attributes in-place if necessary. Generally, these scalings converts energy and power units from MW to GW and /MW to M/GW. Both are done by dividing the values by 1000. See documentation for descriptions of each column being scaled.
Arguments
resource_in (DataFrame): A dataframe containing data for a specific resource.
scale_factor (Float64): A scaling factor for energy and currency units.
Scales vre_stor attributes in-place if necessary. Generally, these scalings converts energy and power units from MW to GW and /MW to M/GW. Both are done by dividing the values by 1000. See documentation for descriptions of each column being scaled.
Arguments
vre_stor_in (DataFrame): A dataframe containing data for co-located VREs and storage.
scale_factor (Float64): A scaling factor for energy and currency units.
For co-located VRE-storage resources, this function returns the storage type (1. long-duration or short-duration storage, 2. symmetric or asymmetric storage) for charging and discharging capacities
This function prevents TimeDomainReduction from running on a case which already has more than one Representative Period or has more than one Sub_Weight specified.
This is equivalent to the list-style interface where the zone zN with entry +1 is the starting zone of the line and the zone with entry -1 is the ending zone of the line.
Read input parameters related to mimimum energy share requirement constraints (e.g. renewable portfolio standard or clean electricity standard policies)
Read input parameters related to hourly maximum capacity factors for the solar PV (DC capacity factors) component and wind (AC capacity factors) component of co-located generators
Finds all columns in the dataframe which are of the form columnprefix_[Integer], and extracts them in order into a matrix. The function also checks that there's at least one column with this prefix, and that all columns numbered from 1...N exist.
This is now acceptable:
ESR_1, other_thing, ESR_3, ESR_2,
+ 2, 1, 0, -1,
This is equivalent to the list-style interface where the zone zN with entry +1 is the starting zone of the line and the zone with entry -1 is the ending zone of the line.
Read input parameters related to mimimum energy share requirement constraints (e.g. renewable portfolio standard or clean electricity standard policies)
Read input parameters related to hourly maximum capacity factors for the solar PV (DC capacity factors) component and wind (AC capacity factors) component of co-located generators
Finds all columns in the dataframe which are of the form columnprefix_[Integer], and extracts them in order into a matrix. The function also checks that there's at least one column with this prefix, and that all columns numbered from 1...N exist.
Attempts to load a dataframe from a csv file with the given directory and file name. If not found immediately, look for files with a different case (lower/upper) in the file's basename.
Attempts to load a dataframe from a csv file with the given path. If it's not found immediately, it will look for files with a different case (lower/upper) in the file's basename.
Attempts to load a dataframe from a csv file with the given directory and file name. If not found immediately, look for files with a different case (lower/upper) in the file's basename.
Attempts to load a dataframe from a csv file with the given path. If it's not found immediately, it will look for files with a different case (lower/upper) in the file's basename.
In the real world, some types of resources (notably, fission) require regular scheduled maintenance, which often takes several weeks. During this time, the plant produces no power. This module allows GenX to find the best time of year for plants to undergo maintenance.
Scheduled maintenance is implemented only for thermal plants with unit commitment (THERM=1).
A plant requires a single contiguous period of $h \ge 1$ hours of maintenance, every $y \ge 1$ years. For each plant, the best time to start the maintenance period is determined by the optimizer.
During maintenance, the plant cannot be "commited", and therefore
uses no fuel,
produces no power,
and does not contribute to reserves.
Additionally,
the plant does not contribute to any Capacity Reserve Margin.
GenX models a long-term equilibrium, and each problem generally represents a single full year. If a plant requires maintenance every $y$ years, we take the simplification that at least $1/y$ of the plants must undergo maintenance in the modeled year.
See also "Interaction with integer unit commitment" below.
This module creates constraints which work across long periods, and consequently can be very expensive to solve. In order to reduce the expense, the set of possible maintenance start dates can be limited. Rather than have maintenance potentially start every hour, one can have possible start dates which are once per day, once per week, etc. (In reality, maintenance is likely scheduled months in advance, so optimizing down to the hour may not be realistic anyway.)
If integer unit commitment is on (UCommit=1) this module may not produce correct results; there may be more maintenance than the user wants. This is because the formulation specifies that the number of plants that go down for maintenance in the simulated year must be at least (the number of plants in the zone)/(the maintenance cycle length in years). As a reminder, the number of plants is eTotalCap / Cap_Size.
If there were three 500 MW plants (total 1500 MW) in a zone, and they require maintenance every three years (Maintenance_Cycle_Length_Years=3), the formulation will work properly: one of the three plants will go under maintenance.
But if there was only one 500 MW plant, and it requires maintenance every 3 years, the constraint will still make it do maintenance every year, because ceil(1/3) is 1. The whole 500 MW plant will do maintenance. This is the unexpected behavior.
However, if integer unit commitment was relaxed to "linearized" unit commitment (UCommit=2), the model will have only 500 MW / 3 = 166.6 MW worth of this plant do maintenance.
If you want to pre-schedule when maintenance occurs, you might not need this module. Instead, you could set the maximum power output of the plant to zero for a certain period, or make its fuel extremely expensive during that time. However, the plant would still be able to contribute to the Capacity Reserve Margin.
The formulation of the maintenance state is very similar to the formulation of unit commitment.
There is a variable called something like vMSHUT which is analogous to vSTART and controls the start of the maintenance period. There is another variable called something like vMDOWN analogous to vCOMMIT which controls the maintenance status in any hour.
A constraint ensures that the value of vMDOWN in any hour is always more than the number of vMSHUTs in the previous Maintenance_Duration hours.
Another constraint ensures that the number of plants committed (vCOMMIT) at any one time plus the number of plants under maintenance (vMDOWN) is less than the total number of plants.
In the real world, some types of resources (notably, fission) require regular scheduled maintenance, which often takes several weeks. During this time, the plant produces no power. This module allows GenX to find the best time of year for plants to undergo maintenance.
Scheduled maintenance is implemented only for thermal plants with unit commitment (THERM=1).
A plant requires a single contiguous period of $h \ge 1$ hours of maintenance, every $y \ge 1$ years. For each plant, the best time to start the maintenance period is determined by the optimizer.
During maintenance, the plant cannot be "commited", and therefore
uses no fuel,
produces no power,
and does not contribute to reserves.
Additionally,
the plant does not contribute to any Capacity Reserve Margin.
GenX models a long-term equilibrium, and each problem generally represents a single full year. If a plant requires maintenance every $y$ years, we take the simplification that at least $1/y$ of the plants must undergo maintenance in the modeled year.
See also "Interaction with integer unit commitment" below.
This module creates constraints which work across long periods, and consequently can be very expensive to solve. In order to reduce the expense, the set of possible maintenance start dates can be limited. Rather than have maintenance potentially start every hour, one can have possible start dates which are once per day, once per week, etc. (In reality, maintenance is likely scheduled months in advance, so optimizing down to the hour may not be realistic anyway.)
If integer unit commitment is on (UCommit=1) this module may not produce correct results; there may be more maintenance than the user wants. This is because the formulation specifies that the number of plants that go down for maintenance in the simulated year must be at least (the number of plants in the zone)/(the maintenance cycle length in years). As a reminder, the number of plants is eTotalCap / Cap_Size.
If there were three 500 MW plants (total 1500 MW) in a zone, and they require maintenance every three years (Maintenance_Cycle_Length_Years=3), the formulation will work properly: one of the three plants will go under maintenance.
But if there was only one 500 MW plant, and it requires maintenance every 3 years, the constraint will still make it do maintenance every year, because ceil(1/3) is 1. The whole 500 MW plant will do maintenance. This is the unexpected behavior.
However, if integer unit commitment was relaxed to "linearized" unit commitment (UCommit=2), the model will have only 500 MW / 3 = 166.6 MW worth of this plant do maintenance.
If you want to pre-schedule when maintenance occurs, you might not need this module. Instead, you could set the maximum power output of the plant to zero for a certain period, or make its fuel extremely expensive during that time. However, the plant would still be able to contribute to the Capacity Reserve Margin.
The formulation of the maintenance state is very similar to the formulation of unit commitment.
There is a variable called something like vMSHUT which is analogous to vSTART and controls the start of the maintenance period. There is another variable called something like vMDOWN analogous to vCOMMIT which controls the maintenance status in any hour.
A constraint ensures that the value of vMDOWN in any hour is always more than the number of vMSHUTs in the previous Maintenance_Duration hours.
Another constraint ensures that the number of plants committed (vCOMMIT) at any one time plus the number of plants under maintenance (vMDOWN) is less than the total number of plants.
We apply the Method of Morris developed by Morris, M., 1991 in order to identify the input parameters that produce the largest change on total system cost. Method of Morris falls under the simplest class of one-factor-at-a-time (OAT) screening techniques. It assumes l levels per input factor and generates a set of trajectories through the input space. As such, the Method of Morris generates a grid of uncertain model input parameters, $x_i, i=1, ..., k$,, where the range $[x_i^{-}, x_i^{+}$ of each uncertain input parameter i is split into l intervals of equal length. Each trajectory starts at different realizations of input parameters chosen at random and are built by successively selecting one of the inputs randomly and moving it to an adjacent level. These trajectories are used to estimate the mean and the standard deviation of each input parameter on total system cost. A high estimated mean indicates that the input parameter is important; a high estimated standard deviation indicates important interactions between that input parameter and other inputs.
We apply the Method of Morris developed by Morris, M., 1991 in order to identify the input parameters that produce the largest change on total system cost. Method of Morris falls under the simplest class of one-factor-at-a-time (OAT) screening techniques. It assumes l levels per input factor and generates a set of trajectories through the input space. As such, the Method of Morris generates a grid of uncertain model input parameters, $x_i, i=1, ..., k$,, where the range $[x_i^{-}, x_i^{+}$ of each uncertain input parameter i is split into l intervals of equal length. Each trajectory starts at different realizations of input parameters chosen at random and are built by successively selecting one of the inputs randomly and moving it to an adjacent level. These trajectories are used to estimate the mean and the standard deviation of each input parameter on total system cost. A high estimated mean indicates that the input parameter is important; a high estimated standard deviation indicates important interactions between that input parameter and other inputs.
We have implemented an updated Modeling to Generate Alternatives (MGA) Algorithm proposed by Berntsen and Trutnevyte (2017) to generate a set of feasible, near cost-optimal technology portfolios. This algorithm was developed by Brill Jr, E. D., 1979 and introduced to energy system planning by DeCarolia, J. F., 2011.
To create the MGA formulation, we replace the cost-minimizing objective function of GenX with a new objective function that creates multiple generation portfolios by zone. We further add a new budget constraint based on the optimal objective function value $f^*$ of the least-cost model and the user-specified value of slack $\delta$. After adding the slack constraint, the resulting MGA formulation is given as:
We have implemented an updated Modeling to Generate Alternatives (MGA) Algorithm proposed by Berntsen and Trutnevyte (2017) to generate a set of feasible, near cost-optimal technology portfolios. This algorithm was developed by Brill Jr, E. D., 1979 and introduced to energy system planning by DeCarolia, J. F., 2011.
To create the MGA formulation, we replace the cost-minimizing objective function of GenX with a new objective function that creates multiple generation portfolios by zone. We further add a new budget constraint based on the optimal objective function value $f^*$ of the least-cost model and the user-specified value of slack $\delta$. After adding the slack constraint, the resulting MGA formulation is given as:
where, $\beta_{zr}$ is a random objective fucntion coefficient betwen $[0,100]$ for MGA iteration $k$. $\Theta_{y,t,z,r}$ is a generation of technology $y$ in zone $z$ in time period $t$ that belongs to a resource type $r$. We aggregate $\Theta_{y,t,z,r}$ into a new variable $P_{z,r}$ that represents total generation from technology type $r$ in a zone $z$. In the second constraint above, $\delta$ denote the increase in budget from the least-cost solution and $f$ represents the expression for the total system cost. The constraint $Ax = b$ represents all other constraints in the power system model. We then solve the formulation with minimization and maximization objective function to explore near optimal solution space.
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+\end{aligned}\]
where, $\beta_{zr}$ is a random objective fucntion coefficient betwen $[0,100]$ for MGA iteration $k$. $\Theta_{y,t,z,r}$ is a generation of technology $y$ in zone $z$ in time period $t$ that belongs to a resource type $r$. We aggregate $\Theta_{y,t,z,r}$ into a new variable $P_{z,r}$ that represents total generation from technology type $r$ in a zone $z$. In the second constraint above, $\delta$ denote the increase in budget from the least-cost solution and $f$ represents the expression for the total system cost. The constraint $Ax = b$ represents all other constraints in the power system model. We then solve the formulation with minimization and maximization objective function to explore near optimal solution space.
Instead of modeling capacity reserve margin requirement (a.k.a. capacity market or resource adequacy requirement) using an annual constraint, we model each requirement with hourly constraint by simulating the activation of the capacity obligation. We define capacity reserve margin constraint for subsets of zones, $z \in \mathcal{Z}^{CRM}_{p}$, and each subset stands for a locational deliverability area (LDA) or a reserve sharing group. For thermal resources, the available capacity is the total capacity in the LDA derated by the outage rate, $\epsilon_{y,z,p}^{CRM}$. For variable renewable energy ($y \in \mathcal{VRE}$), the available capacity is the maximum discharge potential in time step $t$ derated by the derating factor. For standalone storage and co-located VRE and storage resources ($y \in \mathcal{O} \cup \mathcal{VS}$) the available capacity is the net injection into the transmission network plus the net virtual injection corresponding to charge held in reserve, derated by the derating factor. For information on how each component contributes to the capacity reserve margin formulation for co-located VRE and storage resources, see vre_stor_capres!(). For flexible demand resources ($y \in \mathcal{DF}$), the available capacity is the net injection into the transmission network in time step $t$ derated by the derating factor, also stored in the parameter, $\epsilon_{y,z,p}^{CRM}$. If the imported capacity is eligible to provide capacity to the CRM constraint, the inbound powerflow on all lines $\mathcal{L}_{p}^{in}$ in time step $t$ will be derated to form the available capacity from outside of the LDA. The reverse is true as well: the outbound derated powerflow on all lines $\mathcal{L}_{p}^{out}$ in time step $t$ is taken out from the total available capacity. The derating factor should be equal to the expected availability of the resource during periods when the capacity reserve constraint is binding (e.g. accounting for forced outages during supply constrained periods) and is similar to derating factors used in the capacity markets. On top of the flexible demand resources, demand curtailment can also provide capacity (i.e., demand response or load management). We allow all segments of voluntary demand curtailment, $s \geq 2 \in S$, to contribute to capacity requirements. The first segment $s = 1 \in S$ corresponds to involuntary demand curtailment or emergency load shedding at the price cap or value of lost demand, and thus does not contribute to reserve requirements. Note that the time step-weighted sum of the shadow prices of this constraint corresponds to the capacity market payments reported by ISOs with mandate capacity market mechanism.
Instead of modeling capacity reserve margin requirement (a.k.a. capacity market or resource adequacy requirement) using an annual constraint, we model each requirement with hourly constraint by simulating the activation of the capacity obligation. We define capacity reserve margin constraint for subsets of zones, $z \in \mathcal{Z}^{CRM}_{p}$, and each subset stands for a locational deliverability area (LDA) or a reserve sharing group. For thermal resources, the available capacity is the total capacity in the LDA derated by the outage rate, $\epsilon_{y,z,p}^{CRM}$. For variable renewable energy ($y \in \mathcal{VRE}$), the available capacity is the maximum discharge potential in time step $t$ derated by the derating factor. For standalone storage and co-located VRE and storage resources ($y \in \mathcal{O} \cup \mathcal{VS}$) the available capacity is the net injection into the transmission network plus the net virtual injection corresponding to charge held in reserve, derated by the derating factor. For information on how each component contributes to the capacity reserve margin formulation for co-located VRE and storage resources, see vre_stor_capres!(). For flexible demand resources ($y \in \mathcal{DF}$), the available capacity is the net injection into the transmission network in time step $t$ derated by the derating factor, also stored in the parameter, $\epsilon_{y,z,p}^{CRM}$. If the imported capacity is eligible to provide capacity to the CRM constraint, the inbound powerflow on all lines $\mathcal{L}_{p}^{in}$ in time step $t$ will be derated to form the available capacity from outside of the LDA. The reverse is true as well: the outbound derated powerflow on all lines $\mathcal{L}_{p}^{out}$ in time step $t$ is taken out from the total available capacity. The derating factor should be equal to the expected availability of the resource during periods when the capacity reserve constraint is binding (e.g. accounting for forced outages during supply constrained periods) and is similar to derating factors used in the capacity markets. On top of the flexible demand resources, demand curtailment can also provide capacity (i.e., demand response or load management). We allow all segments of voluntary demand curtailment, $s \geq 2 \in S$, to contribute to capacity requirements. The first segment $s = 1 \in S$ corresponds to involuntary demand curtailment or emergency load shedding at the price cap or value of lost demand, and thus does not contribute to reserve requirements. Note that the time step-weighted sum of the shadow prices of this constraint corresponds to the capacity market payments reported by ISOs with mandate capacity market mechanism.
Note that multiple capacity reserve margin requirements can be specified covering different individual zones or aggregations of zones, where the total number of constraints is specified by the GenX settings parameter CapacityReserveMargin (where this parameter should be an integer value > 0). The expressions establishing the capacity reserve margin contributions of each technology class are included in their respective technology modules.
This policy constraints mimics the CO$_2$ emissions cap and permit trading systems, allowing for emissions trading across each zone for which the cap applies. The constraint $p \in \mathcal{P}^{CO_2}$ can be flexibly defined for mass-based or rate-based emission limits for one or more model zones, where zones can trade CO$_2$ emissions permits and earn revenue based on their CO$_2$ allowance. Note that if the model is fully linear (e.g. no unit commitment or linearized unit commitment), the dual variable of the emissions constraints can be interpreted as the marginal CO$_2$ price per tonne associated with the emissions target. Alternatively, for integer model formulations, the marginal CO$_2$ price can be obtained after solving the model with fixed integer/binary variables.
The CO$_2$ emissions limit can be defined in one of the following ways: a) a mass-based limit defined in terms of annual CO$_2$ emissions budget (in million tonnes of CO2), b) a demand-side rate-based limit defined in terms of tonnes CO$_2$ per MWh of fulfilled demand and c) a generation-side rate-based limit defined in terms of tonnes CO$_2$ per MWh of generation.
Mass-based emissions constraint
Mass-based emission limits are implemented in the following expression. For each constraint, $p \in \mathcal{P}^{CO_2}_{mass}$, we define a set of zones $z \in \mathcal{Z}^{CO_2}_{p,mass}$ that can trade CO$_2$ allowance. Input data for each constraint $p \in \mathcal{P}^{CO_2}_{mass}$ requires the CO$_2$ allowance/ budget for each model zone, $\epsilon^{CO_{2}}_{z,p, mass}$, to be provided in terms of million metric tonnes. For every generator $y$, the parameter $\epsilon_{y,z}^{CO_2}$ reflects the specific $CO_2$ emission intensity in tCO$_2$/MWh associated with its operation. The resulting constraint is given as:
\[\begin{aligned}
+\end{aligned}\]
Note that multiple capacity reserve margin requirements can be specified covering different individual zones or aggregations of zones, where the total number of constraints is specified by the GenX settings parameter CapacityReserveMargin (where this parameter should be an integer value > 0). The expressions establishing the capacity reserve margin contributions of each technology class are included in their respective technology modules.
This policy constraints mimics the CO$_2$ emissions cap and permit trading systems, allowing for emissions trading across each zone for which the cap applies. The constraint $p \in \mathcal{P}^{CO_2}$ can be flexibly defined for mass-based or rate-based emission limits for one or more model zones, where zones can trade CO$_2$ emissions permits and earn revenue based on their CO$_2$ allowance. Note that if the model is fully linear (e.g. no unit commitment or linearized unit commitment), the dual variable of the emissions constraints can be interpreted as the marginal CO$_2$ price per tonne associated with the emissions target. Alternatively, for integer model formulations, the marginal CO$_2$ price can be obtained after solving the model with fixed integer/binary variables.
The CO$_2$ emissions limit can be defined in one of the following ways: a) a mass-based limit defined in terms of annual CO$_2$ emissions budget (in million tonnes of CO2), b) a demand-side rate-based limit defined in terms of tonnes CO$_2$ per MWh of fulfilled demand and c) a generation-side rate-based limit defined in terms of tonnes CO$_2$ per MWh of generation.
Mass-based emissions constraint
Mass-based emission limits are implemented in the following expression. For each constraint, $p \in \mathcal{P}^{CO_2}_{mass}$, we define a set of zones $z \in \mathcal{Z}^{CO_2}_{p,mass}$ that can trade CO$_2$ allowance. Input data for each constraint $p \in \mathcal{P}^{CO_2}_{mass}$ requires the CO$_2$ allowance/ budget for each model zone, $\epsilon^{CO_{2}}_{z,p, mass}$, to be provided in terms of million metric tonnes. For every generator $y$, the parameter $\epsilon_{y,z}^{CO_2}$ reflects the specific $CO_2$ emission intensity in tCO$_2$/MWh associated with its operation. The resulting constraint is given as:
In the above constraint, we include both power discharge and charge term for each resource to account for the potential for CO$_2$ emissions (or removal when considering negative emissions technologies) associated with each step. Note that if a limit is applied to each zone separately, then the set $\mathcal{Z}^{CO_2}_{p,mass}$ will contain only one zone with no possibility of trading. If a system-wide emission limit constraint is applied, then $\mathcal{Z}^{CO_2}_{p,mass}$ will be equivalent to a set of all zones.
Demand-side rate-based emissions constraint
We modify the right hand side of the above mass-based constraint, $p \in \mathcal{P}^{CO_2}_{demand}$, to set emissions target based on a CO$_2$ emission rate limit in tCO$_2$/MWh $\times$ the total demand served (fulfilled) in each zone. In the following constraint, total demand served takes into account non-served energy and storage related losses. Here, $\epsilon_{z,p,demand}^{maxCO_2}$ denotes the emission limit in terms on tCO$_2$/MWh.
Similarly, a generation based emission constraint is defined by setting the emission limit based on the total generation times the carbon emission rate limit in tCO$_2$/MWh of the region. The resulting constraint is given as:
Note that the generator-side rate-based constraint can be used to represent a fee-rebate (``feebate'') system: the dirty generators that emit above the bar ($\epsilon_{z,p,gen}^{maxCO_2}$) have to buy emission allowances from the emission regulator in the region $z$ where they are located; in the same vein, the clean generators get rebates from the emission regulator at an emission allowance price being the dual variable of the emissions rate constraint.
Read input parameters related to mimimum energy share requirement constraints (e.g. renewable portfolio standard or clean electricity standard policies)
This function establishes constraints that can be flexibily applied to define alternative forms of policies that require generation of a minimum quantity of megawatt-hours from a set of qualifying resources, such as renewable portfolio standard (RPS) or clean electricity standard (CES) policies prevalent in different jurisdictions. These policies usually require that the annual MWh generation from a subset of qualifying generators has to be higher than a pre-specified percentage of demand from qualifying zones. The implementation allows for user to define one or multiple RPS/CES style minimum energy share constraints, where each constraint can cover different combination of model zones to mimic real-world policy implementation (e.g. multiple state policies, multiple RPS tiers or overlapping RPS and CES policies). The number of energy share requirement constraints is specified by the user by the value of the GenX settings parameter EnergyShareRequirement (this value should be an integer >=0). For each constraint $p \in \mathcal{P}^{ESR}$, we define a subset of zones $z \in \mathcal{Z}^{ESR}_{p} \subset \mathcal{Z}$ that are eligible for trading renewable/clean energy credits to meet the corresponding renewable/clean energy requirement. For each energy share requirement constraint $p \in \mathcal{P}^{ESR}$, we specify the share of total demand in each eligible model zone, $z \in \mathcal{Z}^{ESR}_{p}$, that must be served by qualifying resources, $\mathcal{G}_{p}^{ESR} \subset \mathcal{G}$:
\[\begin{aligned}
+\end{aligned}\]
Note that the generator-side rate-based constraint can be used to represent a fee-rebate (``feebate'') system: the dirty generators that emit above the bar ($\epsilon_{z,p,gen}^{maxCO_2}$) have to buy emission allowances from the emission regulator in the region $z$ where they are located; in the same vein, the clean generators get rebates from the emission regulator at an emission allowance price being the dual variable of the emissions rate constraint.
Read input parameters related to mimimum energy share requirement constraints (e.g. renewable portfolio standard or clean electricity standard policies)
This function establishes constraints that can be flexibily applied to define alternative forms of policies that require generation of a minimum quantity of megawatt-hours from a set of qualifying resources, such as renewable portfolio standard (RPS) or clean electricity standard (CES) policies prevalent in different jurisdictions. These policies usually require that the annual MWh generation from a subset of qualifying generators has to be higher than a pre-specified percentage of demand from qualifying zones. The implementation allows for user to define one or multiple RPS/CES style minimum energy share constraints, where each constraint can cover different combination of model zones to mimic real-world policy implementation (e.g. multiple state policies, multiple RPS tiers or overlapping RPS and CES policies). The number of energy share requirement constraints is specified by the user by the value of the GenX settings parameter EnergyShareRequirement (this value should be an integer >=0). For each constraint $p \in \mathcal{P}^{ESR}$, we define a subset of zones $z \in \mathcal{Z}^{ESR}_{p} \subset \mathcal{Z}$ that are eligible for trading renewable/clean energy credits to meet the corresponding renewable/clean energy requirement. For each energy share requirement constraint $p \in \mathcal{P}^{ESR}$, we specify the share of total demand in each eligible model zone, $z \in \mathcal{Z}^{ESR}_{p}$, that must be served by qualifying resources, $\mathcal{G}_{p}^{ESR} \subset \mathcal{G}$:
The final two terms in the summation above adds roundtrip storage losses to the total demand to which the energy share obligation applies. This term is included in the constraint if the GenX setup parameter StorageLosses=1. If StorageLosses=0, this term is removed from the constraint. In practice, most existing renewable portfolio standard policies do not account for storage losses when determining energy share requirements. However, with 100% RPS or CES policies enacted in several jurisdictions, policy makers may wish to include storage losses in the minimum energy share, as otherwise there will be a difference between total generation and total demand that will permit continued use of non-qualifying resources (e.g. emitting generators).
The minimum capacity requirement constraint allows for modeling minimum deployment of a certain technology or set of eligible technologies across the eligible model zones and can be used to mimic policies supporting specific technology build out (i.e. capacity deployment targets/mandates for storage, offshore wind, solar etc.). The default unit of the constraint is in MW. For each requirement $p \in \mathcal{P}^{MinCapReq}$, we model the policy with the following constraint.
\[\begin{aligned}
+\end{aligned}\]
The final two terms in the summation above adds roundtrip storage losses to the total demand to which the energy share obligation applies. This term is included in the constraint if the GenX setup parameter StorageLosses=1. If StorageLosses=0, this term is removed from the constraint. In practice, most existing renewable portfolio standard policies do not account for storage losses when determining energy share requirements. However, with 100% RPS or CES policies enacted in several jurisdictions, policy makers may wish to include storage losses in the minimum energy share, as otherwise there will be a difference between total generation and total demand that will permit continued use of non-qualifying resources (e.g. emitting generators).
The minimum capacity requirement constraint allows for modeling minimum deployment of a certain technology or set of eligible technologies across the eligible model zones and can be used to mimic policies supporting specific technology build out (i.e. capacity deployment targets/mandates for storage, offshore wind, solar etc.). The default unit of the constraint is in MW. For each requirement $p \in \mathcal{P}^{MinCapReq}$, we model the policy with the following constraint.
Note that $\epsilon_{y,z,p}^{MinCapReq}$ is the eligiblity of a generator of technology $y$ in zone $z$ of requirement $p$ and will be equal to $1$ for eligible generators and will be zero for ineligible resources. The dual value of each minimum capacity constraint can be interpreted as the required payment (e.g. subsidy) per MW per year required to ensure adequate revenue for the qualifying resources.
Also note that co-located VRE and storage resources, there are three different components that minimum capacity requirements can be created for. The capacity of solar PV (in AC terms since the capacity is multiplied by the inverter efficiency), the capacity of wind, and the discharge capacity of storage (power to energy ratio times the energy capacity) can all have minimum capacity requirements.
The maximum capacity requirement constraint allows for modeling maximum deployment of a certain technology or set of eligible technologies across the eligible model zones and can be used to mimic policies supporting specific technology build out (i.e. capacity deployment targets/mandates for storage, offshore wind, solar etc.). The default unit of the constraint is in MW. For each requirement $p \in \mathcal{P}^{MaxCapReq}$, we model the policy with the following constraint.
\[\begin{aligned}
+\end{aligned}\]
Note that $\epsilon_{y,z,p}^{MinCapReq}$ is the eligiblity of a generator of technology $y$ in zone $z$ of requirement $p$ and will be equal to $1$ for eligible generators and will be zero for ineligible resources. The dual value of each minimum capacity constraint can be interpreted as the required payment (e.g. subsidy) per MW per year required to ensure adequate revenue for the qualifying resources.
Also note that co-located VRE and storage resources, there are three different components that minimum capacity requirements can be created for. The capacity of solar PV (in AC terms since the capacity is multiplied by the inverter efficiency), the capacity of wind, and the discharge capacity of storage (power to energy ratio times the energy capacity) can all have minimum capacity requirements.
The maximum capacity requirement constraint allows for modeling maximum deployment of a certain technology or set of eligible technologies across the eligible model zones and can be used to mimic policies supporting specific technology build out (i.e. capacity deployment targets/mandates for storage, offshore wind, solar etc.). The default unit of the constraint is in MW. For each requirement $p \in \mathcal{P}^{MaxCapReq}$, we model the policy with the following constraint.
Note that $\epsilon_{y,z,p}^{MaxCapReq}$ is the eligiblity of a generator of technology $y$ in zone $z$ of requirement $p$ and will be equal to $1$ for eligible generators and will be zero for ineligible resources. The dual value of each maximum capacity constraint can be interpreted as the required payment (e.g. subsidy) per MW per year required to ensure adequate revenue for the qualifying resources.
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+\end{aligned}\]
Note that $\epsilon_{y,z,p}^{MaxCapReq}$ is the eligiblity of a generator of technology $y$ in zone $z$ of requirement $p$ and will be equal to $1$ for eligible generators and will be zero for ineligible resources. The dual value of each maximum capacity constraint can be interpreted as the required payment (e.g. subsidy) per MW per year required to ensure adequate revenue for the qualifying resources.
Reads user-specified solver settings from highs_settings.yml in the directory specified by the string solver_settings_path.
Returns a MathOptInterface.OptimizerWithAttributes HiGHS optimizer instance to be used in the GenX.generate_model() method.
The HiGHS optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided: All the references are in https://github.com/jump-dev/HiGHS.jl, https://github.com/ERGO-Code/HiGHS, and https://highs.dev/
Reads user-specified solver settings from highs_settings.yml in the directory specified by the string solver_settings_path.
Returns a MathOptInterface.OptimizerWithAttributes HiGHS optimizer instance to be used in the GenX.generate_model() method.
The HiGHS optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided: All the references are in https://github.com/jump-dev/HiGHS.jl, https://github.com/ERGO-Code/HiGHS, and https://highs.dev/
Reads user-specified solver settings from gurobi_settings.yml in the directory specified by the string solver_settings_path.
Returns a MathOptInterface.OptimizerWithAttributes Gurobi optimizer instance to be used in the GenX.generate_model() method.
The Gurobi optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:
FeasibilityTol = 1e-6 (Constraint (primal) feasibility tolerances. See https://www.gurobi.com/documentation/8.1/refman/feasibilitytol.html)
OptimalityTol = 1e-4 (Dual feasibility tolerances. See https://www.gurobi.com/documentation/8.1/refman/optimalitytol.html#parameter:OptimalityTol)
Presolve = -1 (Controls presolve level. See https://www.gurobi.com/documentation/8.1/refman/presolve.html)
AggFill = -1 (Allowed fill during presolve aggregation. See https://www.gurobi.com/documentation/8.1/refman/aggfill.html#parameter:AggFill)
PreDual = -1 (Presolve dualization. See https://www.gurobi.com/documentation/8.1/refman/predual.html#parameter:PreDual)
TimeLimit = Inf (Limits total time solver. See https://www.gurobi.com/documentation/8.1/refman/timelimit.html)
MIPGap = 1e-4 (Relative (p.u. of optimal) mixed integer optimality tolerance for MIP problems (ignored otherwise). See https://www.gurobi.com/documentation/8.1/refman/mipgap2.html)
Crossover = -1 (Barrier crossver strategy. See https://www.gurobi.com/documentation/8.1/refman/crossover.html#parameter:Crossover)
Method = -1 (Algorithm used to solve continuous models (including MIP root relaxation). See https://www.gurobi.com/documentation/8.1/refman/method.html)
BarConvTol = 1e-8 (Barrier convergence tolerance (determines when barrier terminates). See https://www.gurobi.com/documentation/8.1/refman/barconvtol.html)
NumericFocus = 0 (Numerical precision emphasis. See https://www.gurobi.com/documentation/8.1/refman/numericfocus.html)
Reads user-specified solver settings from cplex_settings.yml in the directory specified by the string solver_settings_path.
Returns a MathOptInterface.OptimizerWithAttributes CPLEX optimizer instance.
The optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:
Feasib_Tol,
sets CPX_PARAM_EPRHS. Control the primal feasibility tolerance. Default is 1e-6.
Optimal_Tol,
sets CPX_PARAM_EPOPT. Control the optimality tolerance. Default is 1e-4.
AggFill,
sets CPX_PARAM_AGGFILL. Control the allowed fill during presolve aggregation. Default is 10.
PreDual,
sets CPX_PARAM_PREDUAL. Decides whether presolve should pass the primal or dual linear programming problem to the LP optimization algorithm. Default is 0.
TimeLimit,
sets CPX_PARAM_TILIM. Limits total solver time. Default is 1e+75.
MIPGap,
sets CPX_PARAM_EPGAP Relative (p.u. of optimal) mixed integer optimality tolerance for MIP problems (ignored otherwise). Default is 1e-3.
Method,
sets CPX_PARAM_LPMETHOD. Algorithm used to solve continuous models (including MIP root relaxation) Default is 0.
BarConvTol,
sets CPX_PARAM_BAREPCOMP. Barrier convergence tolerance (determines when barrier terminates). Default is 1e-8.
Reads user-specified solver settings from clp_settings.yml in the directory specified by the string solver_settings_path.
Returns a MathOptInterface.OptimizerWithAttributes Clp optimizer instance to be used in the GenX.generate_model() method.
The Clp optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:
Reads user-specified solver settings from cbc_settings.yml in the directory specified by the string solver_settings_path.
Returns a MathOptInterface.OptimizerWithAttributes Cbc optimizer instance to be used in the GenX.generate_model() method.
The Cbc optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:
Reads user-specified solver settings from scip_settings.yml in the directory specified by the string solver_settings_path.
Returns a MathOptInterface.OptimizerWithAttributes SCIP optimizer instance to be used in the GenX.generate_model() method.
The SCIP optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:
Reads user-specified solver settings from gurobi_settings.yml in the directory specified by the string solver_settings_path.
Returns a MathOptInterface.OptimizerWithAttributes Gurobi optimizer instance to be used in the GenX.generate_model() method.
The Gurobi optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:
FeasibilityTol = 1e-6 (Constraint (primal) feasibility tolerances. See https://www.gurobi.com/documentation/8.1/refman/feasibilitytol.html)
OptimalityTol = 1e-4 (Dual feasibility tolerances. See https://www.gurobi.com/documentation/8.1/refman/optimalitytol.html#parameter:OptimalityTol)
Presolve = -1 (Controls presolve level. See https://www.gurobi.com/documentation/8.1/refman/presolve.html)
AggFill = -1 (Allowed fill during presolve aggregation. See https://www.gurobi.com/documentation/8.1/refman/aggfill.html#parameter:AggFill)
PreDual = -1 (Presolve dualization. See https://www.gurobi.com/documentation/8.1/refman/predual.html#parameter:PreDual)
TimeLimit = Inf (Limits total time solver. See https://www.gurobi.com/documentation/8.1/refman/timelimit.html)
MIPGap = 1e-4 (Relative (p.u. of optimal) mixed integer optimality tolerance for MIP problems (ignored otherwise). See https://www.gurobi.com/documentation/8.1/refman/mipgap2.html)
Crossover = -1 (Barrier crossver strategy. See https://www.gurobi.com/documentation/8.1/refman/crossover.html#parameter:Crossover)
Method = -1 (Algorithm used to solve continuous models (including MIP root relaxation). See https://www.gurobi.com/documentation/8.1/refman/method.html)
BarConvTol = 1e-8 (Barrier convergence tolerance (determines when barrier terminates). See https://www.gurobi.com/documentation/8.1/refman/barconvtol.html)
NumericFocus = 0 (Numerical precision emphasis. See https://www.gurobi.com/documentation/8.1/refman/numericfocus.html)
Reads user-specified solver settings from cplex_settings.yml in the directory specified by the string solver_settings_path.
Returns a MathOptInterface.OptimizerWithAttributes CPLEX optimizer instance.
The optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:
Feasib_Tol,
sets CPX_PARAM_EPRHS. Control the primal feasibility tolerance. Default is 1e-6.
Optimal_Tol,
sets CPX_PARAM_EPOPT. Control the optimality tolerance. Default is 1e-4.
AggFill,
sets CPX_PARAM_AGGFILL. Control the allowed fill during presolve aggregation. Default is 10.
PreDual,
sets CPX_PARAM_PREDUAL. Decides whether presolve should pass the primal or dual linear programming problem to the LP optimization algorithm. Default is 0.
TimeLimit,
sets CPX_PARAM_TILIM. Limits total solver time. Default is 1e+75.
MIPGap,
sets CPX_PARAM_EPGAP Relative (p.u. of optimal) mixed integer optimality tolerance for MIP problems (ignored otherwise). Default is 1e-3.
Method,
sets CPX_PARAM_LPMETHOD. Algorithm used to solve continuous models (including MIP root relaxation) Default is 0.
BarConvTol,
sets CPX_PARAM_BAREPCOMP. Barrier convergence tolerance (determines when barrier terminates). Default is 1e-8.
Reads user-specified solver settings from clp_settings.yml in the directory specified by the string solver_settings_path.
Returns a MathOptInterface.OptimizerWithAttributes Clp optimizer instance to be used in the GenX.generate_model() method.
The Clp optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:
Reads user-specified solver settings from cbc_settings.yml in the directory specified by the string solver_settings_path.
Returns a MathOptInterface.OptimizerWithAttributes Cbc optimizer instance to be used in the GenX.generate_model() method.
The Cbc optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:
Reads user-specified solver settings from scip_settings.yml in the directory specified by the string solver_settings_path.
Returns a MathOptInterface.OptimizerWithAttributes SCIP optimizer instance to be used in the GenX.generate_model() method.
The SCIP optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:
by_rid_res(rid::Integer, sym::Symbol, rs::Vector{<:AbstractResource})
-This function returns the value of the attribute `sym` for the resource given by the ID `rid`.
Function for the entry-point for writing the different output files. From here, onward several other functions are called, each for writing specific output files, like costs, capacities, etc.
Function for writing the diferent capacities for the different generation technologies (starting capacities or, existing capacities, retired capacities, and new-built capacities).
Function for the entry-point for writing the different output files. From here, onward several other functions are called, each for writing specific output files, like costs, capacities, etc.
Function for writing the diferent capacities for the different generation technologies (starting capacities or, existing capacities, retired capacities, and new-built capacities).
Marginal electricity price for each model zone and time step. This is equal to the dual variable of the power balance constraint. When solving a linear program (i.e. linearized unit commitment or economic dispatch) this output is always available; when solving a mixed integer linear program, this can be calculated only if WriteShadowPrices is activated.
Function for writing the capacity factor of different resources. For co-located VRE-storage resources, this value is calculated if the site has either or both a solar PV or wind resource.
Marginal electricity price for each model zone and time step. This is equal to the dual variable of the power balance constraint. When solving a linear program (i.e. linearized unit commitment or economic dispatch) this output is always available; when solving a mixed integer linear program, this can be calculated only if WriteShadowPrices is activated.
Returns a matrix of size (T, Z).
-Values have units of $/MWh
Function for reporting marginal electricity price for each model zone and time step. Marginal electricity price is equal to the dual variable of the power balance constraint. If GenX is configured as a mixed integer linear program, then this output is only generated if WriteShadowPrices flag is activated. If configured as a linear program (i.e. linearized unit commitment or economic dispatch) then output automatically available.
Function for reporting dual variable of maximum non-served energy constraint (shadow price of reliability constraint) for each model zone and time step.
Function for reporting subsidy revenue earned if a generator specified Min_Cap is provided in the input file, or if a generator is subject to a Minimum Capacity Requirement constraint. The unit is $.
Function for reporting the operating reserve and regulation revenue earned by generators listed in the input file. GenX will print this file only when operating reserve and regulation are modeled and the shadow price can be obtained from the solver. The revenues are calculated as the operating reserve and regulation contributions in each time step multiplied by the corresponding shadow price, and then the sum is taken over all modeled time steps. The last column is the total revenue received from all operating reserve and regulation constraints. As a reminder, GenX models the operating reserve and regulation at the time-dependent level, and each constraint either stands for an overall market or a locality constraint.
Function for reporting the capacity revenue earned by each generator listed in the input file. GenX will print this file only when capacity reserve margin is modeled and the shadow price can be obtained form the solver. Each row corresponds to a generator, and each column starting from the 6th to the second last is the total revenue from each capacity reserve margin constraint. The revenue is calculated as the capacity contribution of each time steps multiplied by the shadow price, and then the sum is taken over all modeled time steps. The last column is the total revenue received from all capacity reserve margin constraints. As a reminder, GenX models the capacity reserve margin (aka capacity market) at the time-dependent level, and each constraint either stands for an overall market or a locality constraint.
Function for reporting the renewable/clean credit revenue earned by each generator listed in the input file. GenX will print this file only when RPS/CES is modeled and the shadow price can be obtained form the solver. Each row corresponds to a generator, and each column starting from the 6th to the second last is the total revenue earned from each RPS constraint. The revenue is calculated as the total annual generation (if elgible for the corresponding constraint) multiplied by the RPS/CES price. The last column is the total revenue received from all constraint. The unit is $.
This function writes the file costs_multi_stage.csv to the Results directory. This file contains variable, fixed, startup, network expansion, unmet reserve, and non-served energy costs discounted to year zero.
inputs:
outpath – String which represents the path to the Results directory.
settings_d - Dictionary containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
This function writes the file stats_multi_stage.csv. to the Results directory. This file contains the runtime, upper bound, lower bound, and relative optimality gap for each iteration of the DDP algorithm.
inputs:
outpath – String which represents the path to the Results directory.
stats_d – Dictionary which contains the run time, upper bound, and lower bound of each DDP iteration.
This function writes the file network_expansion_multi_stage.csv to the Results directory. This file contains new transmission capacities for each modeled transmission line for the first and all subsequent model stages.
inputs:
outpath – String which represents the path to the Results directory.
settings_d - Dictionary containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
This function writes the file capacities_charge_multi_stage.csv to the Results directory. This file contains starting resource charge capacities from the first model stage and end resource charge capacities for the first and all subsequent model stages.
inputs:
outpath – String which represents the path to the Results directory.
settings_d - Dictionary containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
This function writes the file capacities_energy_multi_stage.csv to the Results directory. This file contains starting resource energy capacities from the first model stage and end resource energy capacities for the first and all subsequent model stages.
inputs:
outpath – String which represents the path to the Results directory.
settings_d - Dictionary containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+ capres_zone::Int)::Vector{Float64}
Marginal electricity price for each model zone and time step. This is equal to the dual variable of the power balance constraint. When solving a linear program (i.e. linearized unit commitment or economic dispatch) this output is always available; when solving a mixed integer linear program, this can be calculated only if WriteShadowPrices is activated.
Function for writing the capacity factor of different resources. For co-located VRE-storage resources, this value is calculated if the site has either or both a solar PV or wind resource.
Marginal electricity price for each model zone and time step. This is equal to the dual variable of the power balance constraint. When solving a linear program (i.e. linearized unit commitment or economic dispatch) this output is always available; when solving a mixed integer linear program, this can be calculated only if WriteShadowPrices is activated.
Returns a matrix of size (T, Z).
+Values have units of $/MWh
Function for reporting marginal electricity price for each model zone and time step. Marginal electricity price is equal to the dual variable of the power balance constraint. If GenX is configured as a mixed integer linear program, then this output is only generated if WriteShadowPrices flag is activated. If configured as a linear program (i.e. linearized unit commitment or economic dispatch) then output automatically available.
Function for reporting dual variable of maximum non-served energy constraint (shadow price of reliability constraint) for each model zone and time step.
Function for reporting subsidy revenue earned if a generator specified Min_Cap is provided in the input file, or if a generator is subject to a Minimum Capacity Requirement constraint. The unit is $.
Function for reporting the operating reserve and regulation revenue earned by generators listed in the input file. GenX will print this file only when operating reserve and regulation are modeled and the shadow price can be obtained from the solver. The revenues are calculated as the operating reserve and regulation contributions in each time step multiplied by the corresponding shadow price, and then the sum is taken over all modeled time steps. The last column is the total revenue received from all operating reserve and regulation constraints. As a reminder, GenX models the operating reserve and regulation at the time-dependent level, and each constraint either stands for an overall market or a locality constraint.
Function for reporting the capacity revenue earned by each generator listed in the input file. GenX will print this file only when capacity reserve margin is modeled and the shadow price can be obtained form the solver. Each row corresponds to a generator, and each column starting from the 6th to the second last is the total revenue from each capacity reserve margin constraint. The revenue is calculated as the capacity contribution of each time steps multiplied by the shadow price, and then the sum is taken over all modeled time steps. The last column is the total revenue received from all capacity reserve margin constraints. As a reminder, GenX models the capacity reserve margin (aka capacity market) at the time-dependent level, and each constraint either stands for an overall market or a locality constraint.
Function for reporting the renewable/clean credit revenue earned by each generator listed in the input file. GenX will print this file only when RPS/CES is modeled and the shadow price can be obtained form the solver. Each row corresponds to a generator, and each column starting from the 6th to the second last is the total revenue earned from each RPS constraint. The revenue is calculated as the total annual generation (if elgible for the corresponding constraint) multiplied by the RPS/CES price. The last column is the total revenue received from all constraint. The unit is $.
This function writes the file costs_multi_stage.csv to the Results directory. This file contains variable, fixed, startup, network expansion, unmet reserve, and non-served energy costs discounted to year zero.
inputs:
outpath – String which represents the path to the Results directory.
settings_d - Dictionary containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
This function writes the file stats_multi_stage.csv. to the Results directory. This file contains the runtime, upper bound, lower bound, and relative optimality gap for each iteration of the DDP algorithm.
inputs:
outpath – String which represents the path to the Results directory.
stats_d – Dictionary which contains the run time, upper bound, and lower bound of each DDP iteration.
This function writes the file network_expansion_multi_stage.csv to the Results directory. This file contains new transmission capacities for each modeled transmission line for the first and all subsequent model stages.
inputs:
outpath – String which represents the path to the Results directory.
settings_d - Dictionary containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
This function writes the file capacities_charge_multi_stage.csv to the Results directory. This file contains starting resource charge capacities from the first model stage and end resource charge capacities for the first and all subsequent model stages.
inputs:
outpath – String which represents the path to the Results directory.
settings_d - Dictionary containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
This function writes the file capacities_energy_multi_stage.csv to the Results directory. This file contains starting resource energy capacities from the first model stage and end resource energy capacities for the first and all subsequent model stages.
inputs:
outpath – String which represents the path to the Results directory.
settings_d - Dictionary containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
Reads in the settings from the genx_settings.yml and output_settings.yml YAML files and merges them with the default settings. It then validates the settings and returns the settings dictionary.
Arguments
settings_path::String: The path to the settings YAML file.
output_settings_path::String: The path to the output settings YAML file.
Loads various data inputs from multiple input .csv files in path directory and stores variables in a Dict (dictionary) object for use in model() function
inputs: setup - dict object containing setup parameters path - string path to working directory
returns: Dict (dictionary) object containing all data inputs
Attempts to load a dataframe from a csv file with the given path. If it's not found immediately, it will look for files with a different case (lower/upper) in the file's basename.
Attempts to load a dataframe from a csv file with the given directory and file name. If not found immediately, look for files with a different case (lower/upper) in the file's basename.
This function sets up and solves a constrained optimization model of electricity system capacity expansion and operation problem and extracts solution variables for later processing.
In addition to calling a number of other modules to create constraints for specific resources, policies, and transmission assets, this function initializes two key expressions that are successively expanded in each of the resource-specific modules: (1) the objective function; and (2) the zonal power balance expression. These two expressions are the only expressions which link together individual modules (e.g. resources, transmission assets, policies), which otherwise are self-contained in defining relevant variables, expressions, and constraints.
Objective Function
The objective function of GenX minimizes total annual electricity system costs over the following six components shown in the equation below:
Reads in the settings from the genx_settings.yml and output_settings.yml YAML files and merges them with the default settings. It then validates the settings and returns the settings dictionary.
Arguments
settings_path::String: The path to the settings YAML file.
output_settings_path::String: The path to the output settings YAML file.
Loads various data inputs from multiple input .csv files in path directory and stores variables in a Dict (dictionary) object for use in model() function
inputs: setup - dict object containing setup parameters path - string path to working directory
returns: Dict (dictionary) object containing all data inputs
Attempts to load a dataframe from a csv file with the given path. If it's not found immediately, it will look for files with a different case (lower/upper) in the file's basename.
Attempts to load a dataframe from a csv file with the given directory and file name. If not found immediately, look for files with a different case (lower/upper) in the file's basename.
This function sets up and solves a constrained optimization model of electricity system capacity expansion and operation problem and extracts solution variables for later processing.
In addition to calling a number of other modules to create constraints for specific resources, policies, and transmission assets, this function initializes two key expressions that are successively expanded in each of the resource-specific modules: (1) the objective function; and (2) the zonal power balance expression. These two expressions are the only expressions which link together individual modules (e.g. resources, transmission assets, policies), which otherwise are self-contained in defining relevant variables, expressions, and constraints.
Objective Function
The objective function of GenX minimizes total annual electricity system costs over the following six components shown in the equation below:
Function for the entry-point for writing the different output files. From here, onward several other functions are called, each for writing specific output files, like costs, capacities, etc.
We have implemented an updated Modeling to Generate Alternatives (MGA) Algorithm proposed by Berntsen and Trutnevyte (2017) to generate a set of feasible, near cost-optimal technology portfolios. This algorithm was developed by Brill Jr, E. D., 1979 and introduced to energy system planning by DeCarolia, J. F., 2011.
To create the MGA formulation, we replace the cost-minimizing objective function of GenX with a new objective function that creates multiple generation portfolios by zone. We further add a new budget constraint based on the optimal objective function value $f^*$ of the least-cost model and the user-specified value of slack $\delta$. After adding the slack constraint, the resulting MGA formulation is given as:
\[\begin{aligned}
+\end{aligned}\]
Arguments
setup::Dict: Dictionary containing the settings for the model.
inputs::Dict: Dictionary containing the inputs for the model.
OPTIMIZER::MOI.OptimizerWithAttributes: The optimizer to use for solving the model.
Returns
Model: The model object containing the entire optimization problem model to be solved by solve_model.jl
Function for the entry-point for writing the different output files. From here, onward several other functions are called, each for writing specific output files, like costs, capacities, etc.
We have implemented an updated Modeling to Generate Alternatives (MGA) Algorithm proposed by Berntsen and Trutnevyte (2017) to generate a set of feasible, near cost-optimal technology portfolios. This algorithm was developed by Brill Jr, E. D., 1979 and introduced to energy system planning by DeCarolia, J. F., 2011.
To create the MGA formulation, we replace the cost-minimizing objective function of GenX with a new objective function that creates multiple generation portfolios by zone. We further add a new budget constraint based on the optimal objective function value $f^*$ of the least-cost model and the user-specified value of slack $\delta$. After adding the slack constraint, the resulting MGA formulation is given as:
where, $\beta_{zr}$ is a random objective fucntion coefficient betwen $[0,100]$ for MGA iteration $k$. $\Theta_{y,t,z,r}$ is a generation of technology $y$ in zone $z$ in time period $t$ that belongs to a resource type $r$. We aggregate $\Theta_{y,t,z,r}$ into a new variable $P_{z,r}$ that represents total generation from technology type $r$ in a zone $z$. In the second constraint above, $\delta$ denote the increase in budget from the least-cost solution and $f$ represents the expression for the total system cost. The constraint $Ax = b$ represents all other constraints in the power system model. We then solve the formulation with minimization and maximization objective function to explore near optimal solution space.
function configure_multi_stage_inputs(inputs_d::Dict, settings_d::Dict, NetworkExpansion::Int64)
This function overwrites input parameters read in via the load_inputs() method for proper configuration of multi-stage modeling:
Overnight capital costs are computed via the compute_overnight_capital_cost() method and overwrite internal model representations of annualized investment costs.
Annualized fixed O&M costs are scaled up to represent total fixed O&M incured over the length of each model stage (specified by "StageLength" field in multi_stage_settings.yml).
Internal set representations of resources eligible for capacity retirements are overwritten to ensure compatability with multi-stage modeling.
When NetworkExpansion is active and there are multiple model zones, parameters related to transmission and network expansion are updated. First, annualized transmission reinforcement costs are converted into overnight capital costs. Next, the maximum allowable transmission line reinforcement parameter is overwritten by the model stage-specific value specified in the "Line_Max_Flow_Possible_MW" fields in the network_multi_stage.csv file. Finally, internal representations of lines eligible or not eligible for transmission expansion are overwritten based on the updated maximum allowable transmission line reinforcement parameters.
inputs:
inputs_d - dict object containing model inputs dictionary generated by load_inputs().
settings_d - dict object containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
NetworkExpansion - integer flag (0/1) indicating whether network expansion is on, set via the "NetworkExpansion" field in genx_settings.yml.
returns: dictionary containing updated model inputs, to be used in the generate_model() method.
This function run the dual dynamic programming (DDP) algorithm, as described in Pereira and Pinto (1991), and more recently, Lara et al. (2018). Note that if the algorithm does not converge within 10,000 (currently hardcoded) iterations, this function will return models with sub-optimal solutions. However, results will still be printed as if the model is finished solving. This sub-optimal termination is noted in the output with the 'Exiting Without Covergence!' message.
inputs:
models_d – Dictionary which contains a JuMP model for each model period.
setup - Dictionary object containing GenX settings and key parameters.
inputs_d – Dictionary of inputs for each model stage, generated by the load_inputs() method.
returns:
models_d – Dictionary which contains a JuMP model for each model stage, modified by this method.
stats_d – Dictionary which contains the run time, upper bound, and lower bound of each DDP iteration.
inputs_d – Dictionary of inputs for each model stage, generated by the load_inputs() method, modified by this method.
This function calls various methods which write multi-stage modeling outputs as .csv files.
inputs:
stats_d – Dictionary which contains the run time, upper bound, and lower bound of each DDP iteration.
outpath – String which represents the path to the Results directory.
settings_d - Dictionary containing settings configured in the GenX settings genx_settings.yml file as well as the multi-stage settings file multi_stage_settings.yml.
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+\end{aligned}\]
where, $\beta_{zr}$ is a random objective fucntion coefficient betwen $[0,100]$ for MGA iteration $k$. $\Theta_{y,t,z,r}$ is a generation of technology $y$ in zone $z$ in time period $t$ that belongs to a resource type $r$. We aggregate $\Theta_{y,t,z,r}$ into a new variable $P_{z,r}$ that represents total generation from technology type $r$ in a zone $z$. In the second constraint above, $\delta$ denote the increase in budget from the least-cost solution and $f$ represents the expression for the total system cost. The constraint $Ax = b$ represents all other constraints in the power system model. We then solve the formulation with minimization and maximization objective function to explore near optimal solution space.
function configure_multi_stage_inputs(inputs_d::Dict, settings_d::Dict, NetworkExpansion::Int64)
This function overwrites input parameters read in via the load_inputs() method for proper configuration of multi-stage modeling:
Overnight capital costs are computed via the compute_overnight_capital_cost() method and overwrite internal model representations of annualized investment costs.
Annualized fixed O&M costs are scaled up to represent total fixed O&M incured over the length of each model stage (specified by "StageLength" field in multi_stage_settings.yml).
Internal set representations of resources eligible for capacity retirements are overwritten to ensure compatability with multi-stage modeling.
When NetworkExpansion is active and there are multiple model zones, parameters related to transmission and network expansion are updated. First, annualized transmission reinforcement costs are converted into overnight capital costs. Next, the maximum allowable transmission line reinforcement parameter is overwritten by the model stage-specific value specified in the "Line_Max_Flow_Possible_MW" fields in the network_multi_stage.csv file. Finally, internal representations of lines eligible or not eligible for transmission expansion are overwritten based on the updated maximum allowable transmission line reinforcement parameters.
inputs:
inputs_d - dict object containing model inputs dictionary generated by load_inputs().
settings_d - dict object containing settings dictionary configured in the multi-stage settings file multi_stage_settings.yml.
NetworkExpansion - integer flag (0/1) indicating whether network expansion is on, set via the "NetworkExpansion" field in genx_settings.yml.
returns: dictionary containing updated model inputs, to be used in the generate_model() method.
This function run the dual dynamic programming (DDP) algorithm, as described in Pereira and Pinto (1991), and more recently, Lara et al. (2018). Note that if the algorithm does not converge within 10,000 (currently hardcoded) iterations, this function will return models with sub-optimal solutions. However, results will still be printed as if the model is finished solving. This sub-optimal termination is noted in the output with the 'Exiting Without Covergence!' message.
inputs:
models_d – Dictionary which contains a JuMP model for each model period.
setup - Dictionary object containing GenX settings and key parameters.
inputs_d – Dictionary of inputs for each model stage, generated by the load_inputs() method.
returns:
models_d – Dictionary which contains a JuMP model for each model stage, modified by this method.
stats_d – Dictionary which contains the run time, upper bound, and lower bound of each DDP iteration.
inputs_d – Dictionary of inputs for each model stage, generated by the load_inputs() method, modified by this method.
This function calls various methods which write multi-stage modeling outputs as .csv files.
inputs:
stats_d – Dictionary which contains the run time, upper bound, and lower bound of each DDP iteration.
outpath – String which represents the path to the Results directory.
settings_d - Dictionary containing settings configured in the GenX settings genx_settings.yml file as well as the multi-stage settings file multi_stage_settings.yml.
GenX is easy to customize to fit a variety of problems. In this tutorial, we show which settings are available to change, what their defaults are, and how to change them in your code.
There are 21 settings available to edit in GenX, found in the file genx_settings.yml. These settings are described at the Model settings parameters page of the documentation. The file is located in the settings folder in the working directory. To change the location of the file, edit the settings_path variable in Run.jl within your directory.
Most settings are set as either 0 or 1, which correspond to whether or not to include a specifc feature. For example, to use TimeDomainReduction, you would set its parameter to 0 within genx_settings.yml. If you would like to run GenX without it, you would set its parameter to 1.
Other settings, such as CO2Cap, have more options corresponding to integers, while some settings such as ModelingtoGenerateAlternativeSlack take a numerical input directly (in this case, the slack value). Two settings, Solver and TimeDomainReductionFolder take in text as input. To learn more about different solvers, read here. For TimeDomainReductionFolder, specify the name of the directory you wish to see the results in. For a more comprehensive description of the input options, see the documentation linked above.
To see how changing the settings affects the outputs, see Tutorials 3 and 7.
Below is the settings file for example_systems/1_three_zones:
All genx_settings.yml files in Example_Systems specify most parameters. When configuring your own settings, however, it is not necessary to input all parameters as defaults are specified for each one in configure_settings.jl.
To open genx_settings.yml in Jupyter, use the function YAML.load(open(...)) and navigate to file in the desired directory:
using YAML
+Tutorial 1: Configuring Settings · GenX.jl
GenX is easy to customize to fit a variety of problems. In this tutorial, we show which settings are available to change, what their defaults are, and how to change them in your code.
There are 21 settings available to edit in GenX, found in the file genx_settings.yml. These settings are described at the Model settings parameters page of the documentation. The file is located in the settings folder in the working directory. To change the location of the file, edit the settings_path variable in Run.jl within your directory.
Most settings are set as either 0 or 1, which correspond to whether or not to include a specifc feature. For example, to use TimeDomainReduction, you would set its parameter to 0 within genx_settings.yml. If you would like to run GenX without it, you would set its parameter to 1.
Other settings, such as CO2Cap, have more options corresponding to integers, while some settings such as ModelingtoGenerateAlternativeSlack take a numerical input directly (in this case, the slack value). Two settings, Solver and TimeDomainReductionFolder take in text as input. To learn more about different solvers, read here. For TimeDomainReductionFolder, specify the name of the directory you wish to see the results in. For a more comprehensive description of the input options, see the documentation linked above.
To see how changing the settings affects the outputs, see Tutorials 3 and 7.
Below is the settings file for example_systems/1_three_zones:
All genx_settings.yml files in Example_Systems specify most parameters. When configuring your own settings, however, it is not necessary to input all parameters as defaults are specified for each one in configure_settings.jl.
To open genx_settings.yml in Jupyter, use the function YAML.load(open(...)) and navigate to file in the desired directory:
using YAML
genx_settings_SNE = YAML.load(open("example_systems/1_three_zones/settings/genx_settings.yml"))
Dict{Any, Any} with 19 entries:
"NetworkExpansion" => 1
"ModelingToGenerateAlternativeIterations" => 3
@@ -265,4 +265,4 @@
Time elapsed for writing is
8.276978416
The function Run.jl will build and then solve the model according to the specified parameters. These results will then be output into a results folder in the same directory. Note that the results folders are not overwritten with each run.
using CSV
using DataFrames
-results = CSV.read(open("example_systems/1_three_zones/Results/capacity.csv"),DataFrame)
11×15 DataFrame
Row
Resource
Zone
StartCap
RetCap
NewCap
EndCap
CapacityConstraintDual
StartEnergyCap
RetEnergyCap
NewEnergyCap
EndEnergyCap
StartChargeCap
RetChargeCap
NewChargeCap
EndChargeCap
String31
String3
Float64
Float64
Float64
Float64
String3
Float64
Float64
Float64
Float64
Float64
Float64
Float64
Float64
1
MA_natural_gas_combined_cycle
1
0.0
0.0
7394.75
7394.75
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
2
CT_natural_gas_combined_cycle
2
0.0
0.0
2305.82
2305.82
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
3
ME_natural_gas_combined_cycle
3
0.0
0.0
716.666
716.666
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
4
MA_solar_pv
1
0.0
0.0
21186.5
21186.5
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
5
CT_onshore_wind
2
0.0
0.0
11905.5
11905.5
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
6
CT_solar_pv
2
0.0
0.0
16578.8
16578.8
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
7
ME_onshore_wind
3
0.0
0.0
12767.3
12767.3
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
0.0
8
MA_battery
1
0.0
0.0
3362.3
3362.3
0.0
0.0
0.0
19427.7
19427.7
0.0
0.0
0.0
0.0
9
CT_battery
2
0.0
0.0
5318.36
5318.36
0.0
0.0
0.0
27274.1
27274.1
0.0
0.0
0.0
0.0
10
ME_battery
3
0.0
0.0
2095.3
2095.3
0.0
0.0
0.0
7096.27
7096.27
0.0
0.0
0.0
0.0
11
Total
n/a
0.0
0.0
83631.3
83631.3
n/a
0.0
0.0
53798.1
53798.1
0.0
0.0
0.0
0.0
As you can see, this runs without a problem! To try with your own parameters, edit the new_params dictionary with whatever parameters you'd like to try and run the cells again.Note: to output the results, you'll have to either delete the previous results folder, or input the name of the new results folder (e.g. results_1) when calling CSV.read as above.
Finally, let's rewite genx_settings.yml to put the original settings in the example back:
As you can see, this runs without a problem! To try with your own parameters, edit the new_params dictionary with whatever parameters you'd like to try and run the cells again.Note: to output the results, you'll have to either delete the previous results folder, or input the name of the new results folder (e.g. results_1) when calling CSV.read as above.
Finally, let's rewite genx_settings.yml to put the original settings in the example back:
To run GenX, there are five mandatory input files: Fuels_data.csv, Network.csv, Load_data.csv, Generators_variability.csv, and Generators_data.csv. Detailed descriptions of these files can be found in the GenX Inputs page of the documentation. This tutorial helps visualize the file Network.csv using the example system example_systems/1_three_zones.
using CSV
-using DataFrames
The input file Network.csv contains the nodes of your network, how they connect to each other, and some important features about them. Below is the network file for example_systems/1_three_zones:
MA, CT, and ME are the abbreviations for states Massachusetts, Connecticut, and Maine. However, since the US region of New England contains other states as well, MA in this case is also used to refer to those states.
Columns Start_Zone and End_Zone specify the network of the three regions. In this case, there are only two network lines, specified in the Network_Lines columns. The Start_Zone column indicates that the first node, MA, is the source of both lines as both rows have value 1. Rows z1 and z2 have values of 2 and 3 in End_Zone, which means both nodes CT and ME recieve energy from node MA. This is also indicated in the column `transmissionpathname'.
Below is a visualization of the network:
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
To run GenX, there are five mandatory input files: Fuels_data.csv, Network.csv, Load_data.csv, Generators_variability.csv, and Generators_data.csv. Detailed descriptions of these files can be found in the GenX Inputs page of the documentation. This tutorial helps visualize the file Network.csv using the example system example_systems/1_three_zones.
using CSV
+using DataFrames
The input file Network.csv contains the nodes of your network, how they connect to each other, and some important features about them. Below is the network file for example_systems/1_three_zones:
MA, CT, and ME are the abbreviations for states Massachusetts, Connecticut, and Maine. However, since the US region of New England contains other states as well, MA in this case is also used to refer to those states.
Columns Start_Zone and End_Zone specify the network of the three regions. In this case, there are only two network lines, specified in the Network_Lines columns. The Start_Zone column indicates that the first node, MA, is the source of both lines as both rows have value 1. Rows z1 and z2 have values of 2 and 3 in End_Zone, which means both nodes CT and ME recieve energy from node MA. This is also indicated in the column `transmissionpathname'.
Below is a visualization of the network:
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
diff --git a/previews/PR662/Tutorials/Tutorial_3_K-means_time_domain_reduction/index.html b/previews/PR662/Tutorials/Tutorial_3_K-means_time_domain_reduction/index.html
index b685fb90d7..d04f09e667 100644
--- a/previews/PR662/Tutorials/Tutorial_3_K-means_time_domain_reduction/index.html
+++ b/previews/PR662/Tutorials/Tutorial_3_K-means_time_domain_reduction/index.html
@@ -1,5 +1,5 @@
-Tutorial 3: K-Means and Time Domain Reduction · GenX
A good tool to reduce computation time of GenX is to use Time-domain reduction. Time Domain Reduction is a method that selects a smaller set of time steps from the data in a way that reduces computation time while still capturing the main information of the model. In this tutorial, we go over how TDR works in GenX and how it uses K-means clustering to choose the optimal time steps. For more information on TDR in capacity expansion models, see Mallapragada et al.
A good tool to reduce computation time of GenX is to use Time-domain reduction. Time Domain Reduction is a method that selects a smaller set of time steps from the data in a way that reduces computation time while still capturing the main information of the model. In this tutorial, we go over how TDR works in GenX and how it uses K-means clustering to choose the optimal time steps. For more information on TDR in capacity expansion models, see Mallapragada et al.
To see how Time Domain Reduction works, let's look at the Doad_data in example_systems/1_three_zones:
# First, load all packages needed
using DataFrames
using CSV
using VegaLite
@@ -241,4 +241,4 @@
scatter!(twinx(),obj_val_plot[:,1],times,color=:red,markeralpha=.5,label=:"Time",legend=:topleft,
yaxis=(label="Time"))
ygrid!(:on, :dashdot, 0.1)
Here, we can see that while having very few representative periods produces an objective value that differs greatly from the orignal, once we reach around 12 representative periods the difference begins to taper out. Therefore, the original choice of 11 maximum periods in 1_three_zones decreases the run time of GenX significantly while while maintaining an objective value close to the original.
It's important to note, however, that the difference does not always taper out, and for some systems you'll find that the error in objective value continues to decrease as the number of representative periods increases. There also is no way to know apriori what number of periods works.
Finally, let's set TDR to have 8 and 11 min/max periods again, and delete the TDR Results folder.
julia rm(joinpath(case,"TDR_results"), recursive=true) YAML.write_file(joinpath(case,"settings/time_domain_reduction_settings.yml"), time_domain_reduction_settings) folders = cd(readdir,case) for folder in folders if length(folder) >= 7 && folder[1:7] == "results" rm("example_systems/1_three_zones/" * folder,recursive=true) end end
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
julia rm(joinpath(case,"TDR_results"), recursive=true) YAML.write_file(joinpath(case,"settings/time_domain_reduction_settings.yml"), time_domain_reduction_settings) folders = cd(readdir,case) for folder in folders if length(folder) >= 7 && folder[1:7] == "results" rm("example_systems/1_three_zones/" * folder,recursive=true) end end
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
To run GenX, we use the file Run.jl. This file will solve the optimization problem and generate the output files as described in the documentation and previous tutorial. It does so by first generating the model, then solving the model, both according to settings described in genx_settings.yml. However, Run.jl only contains one commmand, run_genx_case!(dirname(@__FILE__)). This can be confusing for users viewing the files for the first time. In reality, this function signals many more functions to run, generating and solving the model. This tutorial explains how the model in GenX is generated. The next tutorial will then describe how it is solved.
We'll start by explaining JuMP, the optimization package that GenX uses to generate and solve the model.
JuMP is a modeling language for Julia. It allows users to create models for optimization problems, define variables and constraints, and apply a variety of solvers for the model.
GenX is a Linear Program (LP), which is a form of optimization problem in which a linear objective is minimized (or maximized) according to a set of linear constraints. For more information on LPs, see Wikipedia.
using JuMP
+Tutorial 4: Model Generation · GenX.jl
To run GenX, we use the file Run.jl. This file will solve the optimization problem and generate the output files as described in the documentation and previous tutorial. It does so by first generating the model, then solving the model, both according to settings described in genx_settings.yml. However, Run.jl only contains one commmand, run_genx_case!(dirname(@__FILE__)). This can be confusing for users viewing the files for the first time. In reality, this function signals many more functions to run, generating and solving the model. This tutorial explains how the model in GenX is generated. The next tutorial will then describe how it is solved.
We'll start by explaining JuMP, the optimization package that GenX uses to generate and solve the model.
JuMP is a modeling language for Julia. It allows users to create models for optimization problems, define variables and constraints, and apply a variety of solvers for the model.
GenX is a Linear Program (LP), which is a form of optimization problem in which a linear objective is minimized (or maximized) according to a set of linear constraints. For more information on LPs, see Wikipedia.
using JuMP
using HiGHS
Let's say we want to build a power grid consisting of and coal and wind plants. We want to decrease the cost of producing energy while still meeting a certain emissions threshold and full grid demand. Coal plants are cheaper to build and run but have higher emissions than wind farms. To find the minimum cost of a power grid meeting these constraints, we construct an LP using JuMP.
After this final constraint is defined, generate_model finishes compiling the EP, and run_genx_simple (or multistage) uses solve_model to solve the EP. This will be described in Tutorial 5.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
After this final constraint is defined, generate_model finishes compiling the EP, and run_genx_simple (or multistage) uses solve_model to solve the EP. This will be described in Tutorial 5.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
diff --git a/previews/PR662/Tutorials/Tutorial_5_solve_model/index.html b/previews/PR662/Tutorials/Tutorial_5_solve_model/index.html
index 24a2b165c0..9fa9e588b0 100644
--- a/previews/PR662/Tutorials/Tutorial_5_solve_model/index.html
+++ b/previews/PR662/Tutorials/Tutorial_5_solve_model/index.html
@@ -1,5 +1,5 @@
-Tutorial 5: Solving the Model · GenX
In Tutorial 4, we went over how the model is generated when GenX is run using Run.jl. In the function run_genx_case_simple (or multistage), after generate_model is called, solve_model is called to solve the EP.
In this tutorial, we go over how to use JuMP to solve a model, what it looks like to solve GenX, and how to edit the solver settings.
In Tutorial 4, we went over how the model is generated when GenX is run using Run.jl. In the function run_genx_case_simple (or multistage), after generate_model is called, solve_model is called to solve the EP.
In this tutorial, we go over how to use JuMP to solve a model, what it looks like to solve GenX, and how to edit the solver settings.
\[\begin{aligned}
& \min 10 x + 15 y &\text{Objective function (cost)}\\
& \text{s.t.} & \\
& x + y \geq 10 &\text{Grid Demand}\\
@@ -166,4 +166,4 @@
LP iterations 0 (total)
0 (strong br.)
0 (separation)
- 0 (heuristics)
In this case, the infeasibility was detected on the presovle since it's clear no solution would fit within all constraints. For information on how to debug an infeasible solution, see the JuMP documentaion. Some solvers, such as Gurobi, will compute what is causing the conflict, e.g. which constraints are infeasible with one another (HiGHS does not do this).
GenX version 0.4 has the feature ComputeConflict in settings. If the model does not work, try setting ComputeConflict = 1, and the conflicting constraints will be returned.
Tutorial 6 describes the solver settings, how to change them, and the effects of PreSolve, Crossover, and Feasibility Tolerance.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+ 0 (heuristics)
In this case, the infeasibility was detected on the presovle since it's clear no solution would fit within all constraints. For information on how to debug an infeasible solution, see the JuMP documentaion. Some solvers, such as Gurobi, will compute what is causing the conflict, e.g. which constraints are infeasible with one another (HiGHS does not do this).
GenX version 0.4 has the feature ComputeConflict in settings. If the model does not work, try setting ComputeConflict = 1, and the conflicting constraints will be returned.
Tutorial 6 describes the solver settings, how to change them, and the effects of PreSolve, Crossover, and Feasibility Tolerance.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
Though solving the model relies only on optimize, there are a number of ways to change the way in which the model is optimized. This tutorial goes over solver parameters and how they affect the model solution.
Though solving the model relies only on optimize, there are a number of ways to change the way in which the model is optimized. This tutorial goes over solver parameters and how they affect the model solution.
Welcome to the GenX tutorials! In the following tutorials, we outline some important features of GenX and how to run them. All the tutorials are written in Julia and are available as Jupyter notebooks at the GenX-Tutorials repository.
Welcome to the GenX tutorials! In the following tutorials, we outline some important features of GenX and how to run them. All the tutorials are written in Julia and are available as Jupyter notebooks at the GenX-Tutorials repository.
Modeling grid operations for each hour of the year can be computationally expensive for models with many zones and resources. Rather than modeling and optimizing power grid operations at a high temporal resolution (e.g., hourly, over a full year) while evaluating new capacity investments, which can be computationally expensive for large-scale studies with several resources, it may be useful to consider a reduced temporal resolution to model annual grid operations. Time-domain reduction is often employed in capacity expansion models as a way to balance model spatial and temporal resolution as well as representation of dispatch, while ensuring reasonable computational times. Such a time-domain reduction is often employed in capacity expansion models as a way to balance model spatial and temporal resolution as well as representation of dispatch, while ensuring reasonable computational times. GenX allows the option of performing time-domain reduction on the user supplied time-series input data to produce a representative time series at the desired level of temporal resolution. The time-domain reduction method provided allows the user to automate these features while specifying the various parameters of the time-domain reduction 'clustering' algorithm to be used in formulating the resulting optimization model. The below table summarizes the list of parameters to be specified by the user to perform the time domain reduction implemented in GenX. These parameters are passed to GenX via the YAML file time_domain_reduction_settings.yml.
It's also possible for GenX perform clustering separately from the optimization task. Check out the Running a case with Time Domain Reduction section for more information.
Structure of the time_domain_reduction.yml file
Key
Description
Timesteps_per_period
The number of timesteps (e.g., hours) in each representative period (i.e. 168 for weeks, 24 for days, 72 for three-day periods, etc).
UseExtremePeriods
1 = Include outliers (by performance or demand/resource extreme) as their own representative extreme periods. This setting automatically includes periods based on criteria outlined in the dictionary ExtremePeriods. Extreme periods can be selected based on following criteria applied to demand profiles or solar and wind capacity factors profiles, at either the zonal or system level. A) absolute (timestep with min/max value) statistic (minimum, maximum) and B) integral (period with min/max summed value) statistic (minimum, maximum). For example, the user could want the hour with the most demand across the whole system to be included among the extreme periods. They would select Demand, System, Absolute, and Max.
0 = Do not include extreme periods.
ExtremePeriods
If UseExtremePeriods = 1, use this dictionary to select which types of extreme periods to use. Select by profile type (Demand, PV, or Wind), geography (Zone or System), grouping by timestep or by period (Absolute or Integral), and statistic (Maximum or Minimum).
ClusterMethod
Either kmeans or kmedoids, the method used to cluster periods and determine each time step's representative period.
ScalingMethod
Either N or S, the decision to normalize ([0,1]) or standardize (mean 0, variance 1) the input data prior to clustering.
MinPeriods
The minimum number of representative periods used to represent the input data. If using UseExtremePeriods, this must be greater or equal to the number of selected extreme periods. If IterativelyAddPeriods is off, this will be the total number of representative periods.
MaxPeriods
The maximum number of representative periods - both clustered and extreme - that may be used to represent the input data.
IterativelyAddPeriods
1 = Add representative periods until the error threshold between input data and represented data is met or the maximum number of representative periods is reached.
0 = Use only the minimum number of representative periods. This minimum value includes the selected extreme periods if UseExtremePeriods is on.
Threshold
Iterative period addition will end if the period farthest from its representative period (as measured using Euclidean distance) is within this percentage of the total possible error (for normalization) or 95% of the total possible error (± 2 σ for standardization). E.g., for a threshold of 0.01, each period must be within 1% of the spread of possible error before the clustering iterations will terminate (or until the maximum is reached).
IterateMethod
Either ‘cluster' (Default) or ‘extreme', whether to increment the number of clusters to the kmeans/kmedoids method or to set aside the worst-fitting periods as a new extreme periods.
nReps
Default = 200, the number of kmeans/kmedoids repetitions at the same setting.
DemandWeight
Default = 1, a multiplier on demand columns to optionally prioritize better fits for demand profiles over resource capacity factor or fuel price profiles.
WeightTotal
Default = 8760, the sum to which the relative weights of representative periods will be scaled.
ClusterFuelPrices
Either 1 or 0, whether or not to use the fuel price time series in Fuels_data.csv in the clustering process. If 'no', this function will still write Fuels_data.csv in the TimeDomainReductionFolder with reshaped fuel prices based on the number and size of the representative periods but will not use the fuel price time series for selection of representative periods.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
Modeling grid operations for each hour of the year can be computationally expensive for models with many zones and resources. Rather than modeling and optimizing power grid operations at a high temporal resolution (e.g., hourly, over a full year) while evaluating new capacity investments, which can be computationally expensive for large-scale studies with several resources, it may be useful to consider a reduced temporal resolution to model annual grid operations. Time-domain reduction is often employed in capacity expansion models as a way to balance model spatial and temporal resolution as well as representation of dispatch, while ensuring reasonable computational times. Such a time-domain reduction is often employed in capacity expansion models as a way to balance model spatial and temporal resolution as well as representation of dispatch, while ensuring reasonable computational times. GenX allows the option of performing time-domain reduction on the user supplied time-series input data to produce a representative time series at the desired level of temporal resolution. The time-domain reduction method provided allows the user to automate these features while specifying the various parameters of the time-domain reduction 'clustering' algorithm to be used in formulating the resulting optimization model. The below table summarizes the list of parameters to be specified by the user to perform the time domain reduction implemented in GenX. These parameters are passed to GenX via the YAML file time_domain_reduction_settings.yml.
It's also possible for GenX perform clustering separately from the optimization task. Check out the Running a case with Time Domain Reduction section for more information.
Structure of the time_domain_reduction.yml file
Key
Description
Timesteps_per_period
The number of timesteps (e.g., hours) in each representative period (i.e. 168 for weeks, 24 for days, 72 for three-day periods, etc).
UseExtremePeriods
1 = Include outliers (by performance or demand/resource extreme) as their own representative extreme periods. This setting automatically includes periods based on criteria outlined in the dictionary ExtremePeriods. Extreme periods can be selected based on following criteria applied to demand profiles or solar and wind capacity factors profiles, at either the zonal or system level. A) absolute (timestep with min/max value) statistic (minimum, maximum) and B) integral (period with min/max summed value) statistic (minimum, maximum). For example, the user could want the hour with the most demand across the whole system to be included among the extreme periods. They would select Demand, System, Absolute, and Max.
0 = Do not include extreme periods.
ExtremePeriods
If UseExtremePeriods = 1, use this dictionary to select which types of extreme periods to use. Select by profile type (Demand, PV, or Wind), geography (Zone or System), grouping by timestep or by period (Absolute or Integral), and statistic (Maximum or Minimum).
ClusterMethod
Either kmeans or kmedoids, the method used to cluster periods and determine each time step's representative period.
ScalingMethod
Either N or S, the decision to normalize ([0,1]) or standardize (mean 0, variance 1) the input data prior to clustering.
MinPeriods
The minimum number of representative periods used to represent the input data. If using UseExtremePeriods, this must be greater or equal to the number of selected extreme periods. If IterativelyAddPeriods is off, this will be the total number of representative periods.
MaxPeriods
The maximum number of representative periods - both clustered and extreme - that may be used to represent the input data.
IterativelyAddPeriods
1 = Add representative periods until the error threshold between input data and represented data is met or the maximum number of representative periods is reached.
0 = Use only the minimum number of representative periods. This minimum value includes the selected extreme periods if UseExtremePeriods is on.
Threshold
Iterative period addition will end if the period farthest from its representative period (as measured using Euclidean distance) is within this percentage of the total possible error (for normalization) or 95% of the total possible error (± 2 σ for standardization). E.g., for a threshold of 0.01, each period must be within 1% of the spread of possible error before the clustering iterations will terminate (or until the maximum is reached).
IterateMethod
Either ‘cluster' (Default) or ‘extreme', whether to increment the number of clusters to the kmeans/kmedoids method or to set aside the worst-fitting periods as a new extreme periods.
nReps
Default = 200, the number of kmeans/kmedoids repetitions at the same setting.
DemandWeight
Default = 1, a multiplier on demand columns to optionally prioritize better fits for demand profiles over resource capacity factor or fuel price profiles.
WeightTotal
Default = 8760, the sum to which the relative weights of representative periods will be scaled.
ClusterFuelPrices
Either 1 or 0, whether or not to use the fuel price time series in Fuels_data.csv in the clustering process. If 'no', this function will still write Fuels_data.csv in the TimeDomainReductionFolder with reshaped fuel prices based on the number and size of the representative periods but will not use the fuel price time series for selection of representative periods.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
GenX includes a modeling to generate alternatives (MGA) package that can be used to automatically enumerate a diverse set of near cost-optimal solutions to electricity system planning problems. To use the MGA algorithm, user will need to perform the following tasks:
Add a Resource_Type column in all the resource .csv files denoting the type of each technology.
Add a MGA column in all the resource .csv files denoting the availability of the technology.
Set the ModelingToGenerateAlternatives flag in the GenX_Settings.yml file to 1.
Set the ModelingtoGenerateAlternativeSlack flag in the GenX_Settings.yml file to the desirable level of slack.
Create a Rand_mga_objective_coefficients.csv file to provide random objective function coefficients for each MGA iteration.
For each iteration, number of rows in the Rand_mga_objective_coefficients.csv file represents the number of distinct technology types while number of columns represent the number of model zones.
Solve the model using Run.jl file.
Results from the MGA algorithm would be saved in MGAmax and MGAmin folders in the Example_Systems/ folder.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
GenX includes a modeling to generate alternatives (MGA) package that can be used to automatically enumerate a diverse set of near cost-optimal solutions to electricity system planning problems. To use the MGA algorithm, user will need to perform the following tasks:
Add a Resource_Type column in all the resource .csv files denoting the type of each technology.
Add a MGA column in all the resource .csv files denoting the availability of the technology.
Set the ModelingToGenerateAlternatives flag in the GenX_Settings.yml file to 1.
Set the ModelingtoGenerateAlternativeSlack flag in the GenX_Settings.yml file to the desirable level of slack.
Create a Rand_mga_objective_coefficients.csv file to provide random objective function coefficients for each MGA iteration.
For each iteration, number of rows in the Rand_mga_objective_coefficients.csv file represents the number of distinct technology types while number of columns represent the number of model zones.
Solve the model using Run.jl file.
Results from the MGA algorithm would be saved in MGAmax and MGAmin folders in the Example_Systems/ folder.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
This file contains the settings parameters required to run the Method of Morris algorithm in GenX.
Note
This file is needed if the MethodofMorris flag is ON in the YAML file genx_settings.yml.
Column Name
Description
Resource
This column contains unique names of resources available to the model. Resources can include generators, storage, and flexible or time shiftable demand.
Zone
Integer representing zone number where the resource is located.
Lower_bound
Percentage lower deviation from the nominal value
Upper_bound
Percentage upper deviation from the nominal value
Parameter
Column from the Generators_data.csv file containing uncertain parameters
Group
Group the uncertain parameters that will be changed all at once while performing the sensitivity analysis. For example, if the fuel price of natural gas is uncertain, all generators consuming natural gas should be in the same group. Group name is user defined
p_steps
Number of steps between upper and lower bound
total_num_trajectory
Total number of trakectories through the design matrix
num_trajectory
Selected number of trajectories throigh the design matrix
len_design_mat
Length of the design matrix
policy
Name of the policy
Notes:
Upper and lower bounds are specified in terms of percentage deviation from the nominal value.
Percentage variation for uncertain parameters in a given group is identical. For example, if solar cluster 1 and solar cluster 2 both belong to the ‘solar’ group, their Lower_bound and Upper_bound must be identical.
P_steps should at least be = 1%, i.e., Upper_bound – Lower_bound < p_steps
P_steps for parameters in one group must be identical
Total_num_trajectory should be around 3 to 4 times the total number of uncertain parameters
num_trajectory should be approximately equal to the total number of uncertain parameters
len_design_mat should be 1.5 to 2 times the total number of uncertain parameters
Higher number of num_trajectory and len_design_mat would lead to higher accuracy
Upper and lower bounds should be specified for all the resources included in the Generators_data.csv file. If a parameter related to a particular resource is not uncertain, specify upper bound = lower bound = 0.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
This file contains the settings parameters required to run the Method of Morris algorithm in GenX.
Note
This file is needed if the MethodofMorris flag is ON in the YAML file genx_settings.yml.
Column Name
Description
Resource
This column contains unique names of resources available to the model. Resources can include generators, storage, and flexible or time shiftable demand.
Zone
Integer representing zone number where the resource is located.
Lower_bound
Percentage lower deviation from the nominal value
Upper_bound
Percentage upper deviation from the nominal value
Parameter
Column from the Generators_data.csv file containing uncertain parameters
Group
Group the uncertain parameters that will be changed all at once while performing the sensitivity analysis. For example, if the fuel price of natural gas is uncertain, all generators consuming natural gas should be in the same group. Group name is user defined
p_steps
Number of steps between upper and lower bound
total_num_trajectory
Total number of trakectories through the design matrix
num_trajectory
Selected number of trajectories throigh the design matrix
len_design_mat
Length of the design matrix
policy
Name of the policy
Notes:
Upper and lower bounds are specified in terms of percentage deviation from the nominal value.
Percentage variation for uncertain parameters in a given group is identical. For example, if solar cluster 1 and solar cluster 2 both belong to the ‘solar’ group, their Lower_bound and Upper_bound must be identical.
P_steps should at least be = 1%, i.e., Upper_bound – Lower_bound < p_steps
P_steps for parameters in one group must be identical
Total_num_trajectory should be around 3 to 4 times the total number of uncertain parameters
num_trajectory should be approximately equal to the total number of uncertain parameters
len_design_mat should be 1.5 to 2 times the total number of uncertain parameters
Higher number of num_trajectory and len_design_mat would lead to higher accuracy
Upper and lower bounds should be specified for all the resources included in the Generators_data.csv file. If a parameter related to a particular resource is not uncertain, specify upper bound = lower bound = 0.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
The first step in configuring a GenX model is to specify the model settings parameters. These parameters are specified in a genx_settings.yml file inside a settings folder which must be located in the current working directory. Settings include those related to model structure, solution strategy and outputs, policy constraints, and others. In particular:
Model structure related settings parameters affect the formulation of the model constraints and objective function.
Computational performance related parameters affect the accuracy of the solution.
Policy related parameters specify the policy type and policy goal.
Network related parameters specify settings related to transmission network expansion and losses.
Note that all settings parameters are case sensitive.
(Optional) The user can also select the output files that they want to export using the output_settings.yml file. This file containes a list of yes/no options for each output file, and should be located in the settings folder. By default, if output_settings.yml is not included, GenX will export all output files.
The following tables summarize the model settings parameters and their default/possible values.
Select technical resolution of of modeling thermal generators.
0 = no unit commitment.
1 = unit commitment with integer clustering.
2 = unit commitment with linearized clustering.
OperationalReserves
Flag for modeling operational reserves .
0 = No operational reserves considered.
1 = Consider regulation (primary) and spinning (secondary) reserves.
StorageLosses
Flag to account for storage related losses.
0 = VRE and CO2 constraints DO NOT account for energy lost.
1 = constraints account for energy lost.
TimeDomainReduction
1 = Use time domain reduced inputs available in the folder with the name defined by settings parameter TimeDomainReductionFolder. If such a folder does not exist or it is empty, time domain reduction will reduce the input data and save the results there.
0 = Use the data in the main case folder; do not perform clustering.
TimeDomainReductionFolder
Name of the folder insie the current working directory where time domain reduced input data is stored.
VirtualChargeDischargeCost
Hypothetical cost of charging and discharging storage resources (in /MWh).
Flag to turn on parameter scaling wherein demand, capacity and power variables defined in GW rather than MW. This flag aides in improving the computational performance of the model.
1 = Scaling is activated.
0 = Scaling is not activated.
MultiStage
Model multiple planning stages
1 = Model multiple planning stages as specified in multi_stage_settings.yml
0 = Model single planning stage
ModelingToGenerateAlternatives
Modeling to Generate Alternative Algorithm. For details, see here
1 = Use the algorithm.
0 = Do not use the algorithm.
ModelingtoGenerateAlternativeSlack
value used to define the maximum deviation from the least-cost solution as a part of Modeling to Generate Alternative Algorithm. Can take any real value between 0 and 1.
Flag for printing the model equations as .lp file.
1 = including the model equation as an output
0 = the model equation won't be included as an output
WriteShadowPrices
Get the optimal values of dual variables of various model related constraints, including to estimate electricity prices, stored value of energy and the marginal CO2 prices.
WriteOutputs
Flag for writing the model outputs with hourly resolution or just the annual sum.
"full" = write the model outputs with hourly resolution.
"annual" = write only the annual sum of the model outputs.
The next step in configuring a GenX model is to specify the solver settings parameters using a [solver_name]_settings.yml file inside the settings folder. The solver settings parameters are solver specific and are described in the following section.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
The first step in configuring a GenX model is to specify the model settings parameters. These parameters are specified in a genx_settings.yml file inside a settings folder which must be located in the current working directory. Settings include those related to model structure, solution strategy and outputs, policy constraints, and others. In particular:
Model structure related settings parameters affect the formulation of the model constraints and objective function.
Computational performance related parameters affect the accuracy of the solution.
Policy related parameters specify the policy type and policy goal.
Network related parameters specify settings related to transmission network expansion and losses.
Note that all settings parameters are case sensitive.
(Optional) The user can also select the output files that they want to export using the output_settings.yml file. This file containes a list of yes/no options for each output file, and should be located in the settings folder. By default, if output_settings.yml is not included, GenX will export all output files.
The following tables summarize the model settings parameters and their default/possible values.
Select technical resolution of of modeling thermal generators.
0 = no unit commitment.
1 = unit commitment with integer clustering.
2 = unit commitment with linearized clustering.
OperationalReserves
Flag for modeling operational reserves .
0 = No operational reserves considered.
1 = Consider regulation (primary) and spinning (secondary) reserves.
StorageLosses
Flag to account for storage related losses.
0 = VRE and CO2 constraints DO NOT account for energy lost.
1 = constraints account for energy lost.
TimeDomainReduction
1 = Use time domain reduced inputs available in the folder with the name defined by settings parameter TimeDomainReductionFolder. If such a folder does not exist or it is empty, time domain reduction will reduce the input data and save the results there.
0 = Use the data in the main case folder; do not perform clustering.
TimeDomainReductionFolder
Name of the folder insie the current working directory where time domain reduced input data is stored.
VirtualChargeDischargeCost
Hypothetical cost of charging and discharging storage resources (in /MWh).
Flag to turn on parameter scaling wherein demand, capacity and power variables defined in GW rather than MW. This flag aides in improving the computational performance of the model.
1 = Scaling is activated.
0 = Scaling is not activated.
MultiStage
Model multiple planning stages
1 = Model multiple planning stages as specified in multi_stage_settings.yml
0 = Model single planning stage
ModelingToGenerateAlternatives
Modeling to Generate Alternative Algorithm. For details, see here
1 = Use the algorithm.
0 = Do not use the algorithm.
ModelingtoGenerateAlternativeSlack
value used to define the maximum deviation from the least-cost solution as a part of Modeling to Generate Alternative Algorithm. Can take any real value between 0 and 1.
Flag for printing the model equations as .lp file.
1 = including the model equation as an output
0 = the model equation won't be included as an output
WriteShadowPrices
Get the optimal values of dual variables of various model related constraints, including to estimate electricity prices, stored value of energy and the marginal CO2 prices.
WriteOutputs
Flag for writing the model outputs with hourly resolution or just the annual sum.
"full" = write the model outputs with hourly resolution.
"annual" = write only the annual sum of the model outputs.
The next step in configuring a GenX model is to specify the solver settings parameters using a [solver_name]_settings.yml file inside the settings folder. The solver settings parameters are solver specific and are described in the following section.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
All input files are in CSV format. Running the GenX model requires a minimum of five mandatory input files:
Fuels_data.csv: specify fuel type, CO2 emissions intensity, and time-series of fuel prices.
Network.csv: specify network topology, transmission fixed costs, capacity and loss parameters.
Demand_data.csv: specify time-series of demand profiles for each model zone, weights for each time step, demand shedding costs, and optional time domain reduction parameters.
Generators_variability.csv: specify time-series of capacity factor/availability for each resource.
Generators_data.csv: specify cost and performance data for generation, storage and demand flexibility resources.
Additionally, the user may need to specify eight more settings-specific input files based on model configuration and type of scenarios of interest:
Operational_reserves.csv: specify operational reserve requirements as a function of demand and renewables generation and penalty for not meeting these requirements.
Energy_share_requirement.csv: specify regional renewable portfolio standard and clean energy standard style policies requiring minimum energy generation from qualifying resources.
CO2_cap.csv: specify regional CO2 emission limits.
Vre_and_stor_data.csv: specify cost and performance data for co-located VRE and storage resources.
Vre_and_stor_solar_variability.csv: specify time-series of capacity factor/availability for each solar PV resource that exists for every co-located VRE and storage resource (in DC terms).
Vre_and_stor_wind_variability.csv: specify time-series of capacity factor/availability for each wind resource that exists for every co-located VRE and storage resource (in AC terms).
• First row: names of all fuels used in the model instance which should match the labels used in Fuel column in one of the resource .csv file in the resources folder. For renewable resources or other resources that do not consume a fuel, the name of the fuel is None.
• Second row: The second row specifies the CO2 emissions intensity of each fuel in tons/MMBtu (million British thermal units). Note that by convention, tons correspond to metric tonnes and not short tons (although as long as the user is internally consistent in their application of units, either can be used).
• Remaining rows: Rest of the rows in this input file specify the time-series for prices for each fuel in /MMBtu. A constant price can be specified by entering the same value for all hours.
** First column:** The first column in this file denotes, Time_index, represents the index of time steps in a model instance.
This input file contains input parameters related to: 1) definition of model zones (regions between which transmission flows are explicitly modeled) and 2) definition of transmission network topology, existing capacity, losses and reinforcement costs. The following table describe each of the mandatory parameter inputs need to be specified to run an instance of the model, along with comments for the model configurations when they are needed.
Numerical index for each network line. The length of this column is counted but the actual values are not used.
z* (Network map) OR StartZone, EndZone
See below
Line_Max_Flow_MW
Existing capacity of the inter-regional transmission line.
NetworkExpansion = 1
Line_Max_Reinforcement_MW
Maximum allowable capacity addition to the existing transmission line.
Line_Reinforcement_Cost_per_MWyr
Cost of adding new capacity to the inter-regional transmission line.
Trans_Loss_Segments = 1
Line_Loss_Percentage
fractional transmission loss for each transmission line
Trans_Loss_Segments > 1
Ohms
Line resistance in Ohms (used to calculate I^2R losses)
kV
Line voltage in kV (used to calculate I^2R losses)
CapacityReserveMargin > 0
CapRes_*
Eligibility of the transmission line for adding firm capacity to the capacity reserve margin constraint. * represents the number of the capacity reserve margin constraint.
1 = the transmission line is eligible for adding firm capacity to the region
0 = the transmission line is not eligible for adding firm capacity to the region
DerateCapRes_*
(0,1) value represents the derating of the firm transmission capacity for the capacity reserve margin constraint.
CapResExcl_*
(-1,1,0) = -1 if the designated direction of the transmission line is inbound to locational deliverability area (LDA) modeled by the capacity reserve margin constraint. = 1 if the designated direction of the transmission line is outbound from the LDA modeled by the capacity reserve margin constraint. Zero otherwise.
MultiStage == 1
Capital_Recovery_Period
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for network transmission line expansion.
Line_Max_Flow_Possible_MW
Maximum possible line flow in the current model period. Overrides Line_Max_Reinforcement_MW, which is not used when performing multi-stage modeling.
There are two interfaces implemented for specifying the network topology itself: a matrix interface and a list interface. Only one choice is permitted in a given file.
The list interface consists of a column for the lines start zone and one for the line's end zone. Here is a snippet of the Network.csv file for a map with three zones and two lines:
All input files are in CSV format. Running the GenX model requires a minimum of five mandatory input files:
Fuels_data.csv: specify fuel type, CO2 emissions intensity, and time-series of fuel prices.
Network.csv: specify network topology, transmission fixed costs, capacity and loss parameters.
Demand_data.csv: specify time-series of demand profiles for each model zone, weights for each time step, demand shedding costs, and optional time domain reduction parameters.
Generators_variability.csv: specify time-series of capacity factor/availability for each resource.
Generators_data.csv: specify cost and performance data for generation, storage and demand flexibility resources.
Additionally, the user may need to specify eight more settings-specific input files based on model configuration and type of scenarios of interest:
Operational_reserves.csv: specify operational reserve requirements as a function of demand and renewables generation and penalty for not meeting these requirements.
Energy_share_requirement.csv: specify regional renewable portfolio standard and clean energy standard style policies requiring minimum energy generation from qualifying resources.
CO2_cap.csv: specify regional CO2 emission limits.
Vre_and_stor_data.csv: specify cost and performance data for co-located VRE and storage resources.
Vre_and_stor_solar_variability.csv: specify time-series of capacity factor/availability for each solar PV resource that exists for every co-located VRE and storage resource (in DC terms).
Vre_and_stor_wind_variability.csv: specify time-series of capacity factor/availability for each wind resource that exists for every co-located VRE and storage resource (in AC terms).
• First row: names of all fuels used in the model instance which should match the labels used in Fuel column in one of the resource .csv file in the resources folder. For renewable resources or other resources that do not consume a fuel, the name of the fuel is None.
• Second row: The second row specifies the CO2 emissions intensity of each fuel in tons/MMBtu (million British thermal units). Note that by convention, tons correspond to metric tonnes and not short tons (although as long as the user is internally consistent in their application of units, either can be used).
• Remaining rows: Rest of the rows in this input file specify the time-series for prices for each fuel in /MMBtu. A constant price can be specified by entering the same value for all hours.
** First column:** The first column in this file denotes, Time_index, represents the index of time steps in a model instance.
This input file contains input parameters related to: 1) definition of model zones (regions between which transmission flows are explicitly modeled) and 2) definition of transmission network topology, existing capacity, losses and reinforcement costs. The following table describe each of the mandatory parameter inputs need to be specified to run an instance of the model, along with comments for the model configurations when they are needed.
Numerical index for each network line. The length of this column is counted but the actual values are not used.
z* (Network map) OR StartZone, EndZone
See below
Line_Max_Flow_MW
Existing capacity of the inter-regional transmission line.
NetworkExpansion = 1
Line_Max_Reinforcement_MW
Maximum allowable capacity addition to the existing transmission line.
Line_Reinforcement_Cost_per_MWyr
Cost of adding new capacity to the inter-regional transmission line.
Trans_Loss_Segments = 1
Line_Loss_Percentage
fractional transmission loss for each transmission line
Trans_Loss_Segments > 1
Ohms
Line resistance in Ohms (used to calculate I^2R losses)
kV
Line voltage in kV (used to calculate I^2R losses)
CapacityReserveMargin > 0
CapRes_*
Eligibility of the transmission line for adding firm capacity to the capacity reserve margin constraint. * represents the number of the capacity reserve margin constraint.
1 = the transmission line is eligible for adding firm capacity to the region
0 = the transmission line is not eligible for adding firm capacity to the region
DerateCapRes_*
(0,1) value represents the derating of the firm transmission capacity for the capacity reserve margin constraint.
CapResExcl_*
(-1,1,0) = -1 if the designated direction of the transmission line is inbound to locational deliverability area (LDA) modeled by the capacity reserve margin constraint. = 1 if the designated direction of the transmission line is outbound from the LDA modeled by the capacity reserve margin constraint. Zero otherwise.
MultiStage == 1
Capital_Recovery_Period
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for network transmission line expansion.
Line_Max_Flow_Possible_MW
Maximum possible line flow in the current model period. Overrides Line_Max_Reinforcement_MW, which is not used when performing multi-stage modeling.
There are two interfaces implemented for specifying the network topology itself: a matrix interface and a list interface. Only one choice is permitted in a given file.
The list interface consists of a column for the lines start zone and one for the line's end zone. Here is a snippet of the Network.csv file for a map with three zones and two lines:
The matrix interface requires N columns labeled z1, z2, z3 ... zN, and L rows, one for each network line (or interregional path), with a 1 in the column corresponding to the 'start' zone and a -1 in the column corresponding to the 'end' zone for each line. Here is the same network map implemented as a matrix:
This file includes parameters to characterize model temporal resolution to approximate annual grid operations, electricity demand for each time step for each zone, and cost of load shedding. Note that GenX is designed to model hourly time steps. With some care and effort, finer (e.g. 15 minute) or courser (e.g. 2 hour) time steps can be modeled so long as all time-related parameters are scaled appropriately (e.g. time period weights, heat rates, ramp rates and minimum up and down times for generators, variable costs, etc).
Value of lost load (also referred to as non-served energy) in /MWh.
Demand_Segment
Number of demand curtailment/unserved demand segments with different cost and capacity of curtailable demand for each segment. User-specified demand segments. Integer values starting with 1 in the first row. Additional segements added in subsequent rows.
Cost_of_Demand_Curtailment_per_MW
Cost of non-served energy/demand curtailment (for each segment), reported as a fraction of value of the lost load (non-served demand). If Demand_Segment = 1, then this parameter is a scalar and equal to one. In general this parameter is a vector of length equal to the length of Demand_Segment.
Max_Demand_Curtailment
Maximum time-dependent demand curtailable in each segment, reported as % of the demand in each zone and each period. If Demand_Segment = 1, then this parameter is a scalar and equal to one. In general this parameter is a vector of length given by length of Demand_segment.
Time_Index
Index defining time step in the model.
Demand_MW_z*
Demand profile of a zone z* in MW; if multiple zones, this parameter will be a matrix with columns equal to number of zones (each column named appropriate zone number appended to parameter) and rows equal to number of time periods of grid operations being modeled.
Rep_Periods
Number of representative periods (e.g. weeks, days) that are modeled to approximate annual grid operations. This is always a single entry. For a full-year model, this is 1.
Timesteps_per_Rep_Period
Number of timesteps per representative period (e.g. 168 if period is set as a week using hour-long time steps). This is always a single entry: all representative periods have the same length. For a full-year model, this entry is equal to the number of time steps.
Sub_Weights
Number of annual time steps (e.g. hours) represented by each timestep in a representative period. The length of this column is equal to the number of representative periods. The sum of the elements should be equal to the total number of time steps in a model time horizon (e.g. 8760 hours if modeling 365 days or 8736 if modeling 52 weeks).
The resources folder contains the input files for each resource type. At the current version of GenX, the following resources are included in the model:
thermal generators, specified in the Thermal.csv file,
variable renewable energy resources (VRE), specified in the VRE.csv file,
reservoir hydro resources, specified in the Hydro.csv file,
storage resources, specified in the Storage.csv file,
flexible demand resources, specified in the Flex_demand.csv file,
must-run resources, specified in the Must_run.csv file,
electrolyzers, specified in the Electrolyzer.csv file, and
co-located VRE and storage resources, specified in the Vre_stor.csv file.
Each file contains cost and performance parameters for various generators and other resources included in the model formulation. The following table describes the mandatory columns in each of these files. Note that the column names are case insensitive.
This column contains unique names of resources available to the model. Resources can include generators, storage, and flexible or time shiftable demand.
Zone
Integer representing zone number where the resource is located.
Technology type flags
New_Build
{0, 1}, Flag for resource (storage, generation) eligibility for capacity expansion.
New_Build = 1: eligible for capacity expansion.
New_Build = 0: not eligible for capacity expansion.
Can_Retire
{0, 1}, Flag for resource (storage, generation) eligibility for retirement.
Can_Retire = 1: eligible for retirement.
Can_Retire = 0: not eligible for retirement.
Existing technology capacity
Existing_Cap_MW
The existing capacity of a power plant in MW. Note that for co-located VRE-STOR resources, this capacity represents the existing AC grid connection capacity in MW.
Capacity/Energy requirements
Max_Cap_MW
-1 (default) – no limit on maximum discharge capacity of the resource. If non-negative, represents maximum allowed discharge capacity (in MW) of the resource. Note that for co-located VRE-STOR resources, this capacity represents the maximum AC grid connection capacity in MW.
Min_Cap_MW
-1 (default) – no limit on minimum discharge capacity of the resource. If non-negative, represents minimum allowed discharge capacity (in MW) of the resource. Note that for co-located VRE-STOR resources, this capacity represents the minimum AC grid connection capacity in MW.
Cost parameters
Inv_Cost_per_MWyr
Annualized capacity investment cost of a technology (/MW/year). Note that for co-located VRE-STOR resources, this annualized capacity investment cost pertains to the grid connection.
Fixed_OM_Cost_per_MWyr
Fixed operations and maintenance cost of a technology (/MW/year). Note that for co-located VRE-STOR resources, this fixed operations and maintenance cost pertains to the grid connection.
Var_OM_Cost_per_MWh
Variable operations and maintenance cost of a technology (/MWh). Note that for co-located VRE-STOR resources, these costs apply to the AC generation sent to the grid from the entire site.
Technical performance parameters
Heat_Rate_MMBTU_per_MWh
Heat rate of a generator or MMBtu of fuel consumed per MWh of electricity generated for export (net of on-site consumption). The heat rate is the inverse of the efficiency: a lower heat rate is better. Should be consistent with fuel prices in terms of reporting on higher heating value (HHV) or lower heating value (LHV) basis.
Fuel
Fuel needed for a generator. The names should match with the ones in the Fuels_data.csv.
Required for writing outputs
region
Name of the model region
cluster
Number of the cluster when representing multiple clusters of a given technology in a given region.
Required if electrolyzer is included in the model
QualifiedHydrogenSupply
{0,1}, Indicates that generator or storage resources is eligible to supply electrolyzers in the same zone (used for hourly clean supply constraint)
Required for retrofitting
Can_Retrofit
{0, 1}, Flag for resource (storage, generation) eligibility for retrofit.
Can_Retrofit = 1: eligible for retrofit.
Can_Retrofit = 0: not eligible for retrofit.
Retrofit
{0, 1}, Flag for resource retrofit technologies (i.e., retrofit options, e.g. CCS retrofit for coal plants).
Retrofit = 1: is a retrofit technology.
Retrofit = 0: is not a retrofit technology.
Retrofit_Id
Unique identifier to group retrofittable source technologies with retrofit options inside the same zone.
Eligibility of the technology for Modeling To Generate Alternative (MGA) run.
1 = Technology is available for the MGA run.
0 = Technology is unavailable for the MGA run (e.g. storage technologies).
Resource_Type
For the MGA run, we categorize all the resources in a few resource types. We then find maximally different generation portfolio based on these resource types. For example, existing solar and new solar resources could be represented by a resource type names Solar. Categorization of resources into resource types is user dependent.
Maintenance data
MAINT
[0,1], toggles scheduled maintenance formulation.
Maintenance_Duration
(Positive integer, less than total length of simulation.) Duration of the maintenance period, in number of timesteps. Only used if MAINT=1.
Maintenance_Cycle_Length_Years
Length of scheduled maintenance cycle, in years. 1 is maintenance every year, 3 is every three years, etc. (Positive integer. Only used if MAINT=1.)
Maintenance_Begin_Cadence
Cadence of timesteps in which scheduled maintenance can begin. 1 means that a maintenance period can start in any timestep, 24 means it can start only in timesteps 1, 25, 49, etc. A larger number can decrease the simulation computational cost as it limits the optimizer's choices. (Positive integer, less than total length of simulation. Only used if MAINT=1.)
CO2-related parameters required if any resources have nonzero CO2CaptureFraction
CO2_Capture_Fraction
[0,1], The CO2 capture fraction of CCS-equipped power plants during steady state operation. This value should be 0 for generators without CCS.
CO2_Capture_Fraction_Startup
[0,1], The CO2 capture fraction of CCS-equipped power plants during the startup events. This value should be 0 for generators without CCS
Biomass
{0, 1}, Flag to indicate if generator uses biomass as feedstock (optional input column).
Biomass = 0: Not part of set (default).
Biomass = 1: Uses biomass as fuel.
CCS_Disposal_Cost_per_Metric_Ton
Cost associated with CCS disposal (/tCO2), including pipeline, injection and storage costs of CCS-equipped generators.
{1, 2}, Flag to indicate membership in set of thermal resources (e.g. nuclear, combined heat and power, natural gas combined cycle, coal power plant)
Model = 1: If the power plant relies on thermal energy input and subject unit commitment constraints/decisions if UCommit >= 1 (e.g. cycling decisions/costs/constraints).
Model = 2: If the power plant relies on thermal energy input and is subject to simplified economic dispatch constraints (ramping limits and minimum output level but no cycling decisions/costs/constraints).
Min_Power
[0,1], The minimum generation level for a unit as a fraction of total capacity. This value cannot be higher than the smallest time-dependent CF value for a resource in Generators_variability.csv.
Ramp_Up_Percentage
[0,1], Maximum increase in power output from between two periods (typically hours), reported as a fraction of nameplate capacity.
Ramp_Dn_Percentage
[0,1], Maximum decrease in power output from between two periods (typically hours), reported as a fraction of nameplate capacity.
PiecewiseFuelUsage-related parameters
PWFU_Fuel_Usage_Zero_Load_MMBTU_per_h
The fuel usage (MMBTU/h) for the first PWFU segemnt (y-intercept) at zero load.
PWFU_Heat_Rate_MMBTU_per_MWh_*i
The slope of fuel usage function of the segment i.
PWFU_Load_Point_MW_*i
The end of segment i (MW).
Multi-fuel parameters
MULTI_FUELS
{0, 1}, Flag to indicate membership in set of thermal resources that can burn multiple fuels at the same time (e.g., natural gas combined cycle cofiring with hydrogen, coal power plant cofiring with natural gas.
MULTI_FUELS = 0: Not part of set (default)
MULTI_FUELS = 1: Resources that can use fuel blending.
Num_Fuels
Number of fuels that a multi-fuel generator (MULTIFUELS = 1) can use at the same time. The length of ['Fuel1', 'Fuel2', ...] should be equal to 'Num\Fuels'. Each fuel will requires its corresponding heat rate, min cofire level, and max cofire level.
Fuel1
Frist fuel needed for a mulit-fuel generator (MULTIFUELS = 1). The names should match with the ones in the `Fuelsdata.csv`.
Fuel2
Second fuel needed for a mulit-fuel generator (MULTIFUELS = 1). The names should match with the ones in the `Fuelsdata.csv`.
Heat1_Rate_MMBTU_per_MWh
Heat rate of a multi-fuel generator (MULTI_FUELS = 1) for Fuel1.
Heat2_Rate_MMBTU_per_MWh
Heat rate of a multi-fuel generator (MULTI_FUELS = 1) for Fuel2.
Fuel1_Min_Cofire_Level
The minimum blendng level of 'Fuel1' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the normal generation process.
Fuel1_Min_CofireLevel\Start
The minimum blendng level of 'Fuel1' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the start-up process.
Fuel1_Max_Cofire_Level
The maximum blendng level of 'Fuel1' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the normal generation process.
Fuel1_Max_CofireLevel\Start
The maximum blendng level of 'Fuel1' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the start-up process.
Fuel2_Min_Cofire_Level
The minimum blendng level of 'Fuel2' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the normal generation process.
Fuel2_Min_CofireLevel\Start
The minimum blendng level of 'Fuel2' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the start-up process.
Fuel2_Max_Cofire_Level
The maximum blendng level of 'Fuel2' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the normal generation process.
Fuel2_Max_CofireLevel\Start
The maximum blendng level of 'Fuel2' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the start-up process.
The following settings apply only to thermal plants with unit commitment constraints
Up_Time
Minimum amount of time a resource has to stay in the committed state.
Down_Time
Minimum amount of time a resource has to remain in the shutdown state.
Start_Cost_per_MW
Cost per MW of nameplate capacity to start a generator (/MW per start). Multiplied by the number of generation units (each with a pre-specified nameplate capacity) that is turned on.
Start_Fuel_MMBTU_per_MW
Startup fuel use per MW of nameplate capacity of each generator (MMBtu/MW per start).
OperationalReserves = 1
Reg_Cost
Cost of providing regulation reserves (/MW per time step/hour).
Rsv_Cost
Cost of providing upwards spinning or contingency reserves (/MW per time step/hour).
Reg_Max
[0,1], Fraction of nameplate capacity that can committed to provided regulation reserves. .
Rsv_Max
[0,1], Fraction of nameplate capacity that can committed to provided upwards spinning or contingency reserves.
Number of resource availability profiles considered for each VRE resource per zone. This parameter is used to decide the number of capacity investment decision variables related to a single variable renewable energy technology in each zone.
Num_VRE_bins = 1: using a single resource availability profile per technology per zone. 1 capacity investment decision variable and 1 generator RID tracking technology power output (and in each zone).
Num_VRE_bins > 1: using multiple resource availability profiles per technology per zone. Num_VRE_bins capacity investment decision variables and 1 generator RID used to define technology power output at each time step (and in each zone). Example: Suppose we are modeling 3 bins of wind profiles for each zone. Then include 3 rows with wind resource names as Wind_1, Wind_2, and Wind_3 and a corresponding increasing sequence of RIDs. Set Num_VRE_bins for the generator with smallest RID, Wind_1, to be 3 and set Num_VRE_bins for the other rows corresponding to Wind_2 and Wind_3, to be zero. By setting Num_VRE_bins for Wind_2 and Wind_3, the model eliminates the power outputs variables for these generators. The power output from the technology across all bins is reported in the power output variable for the first generator. This allows for multiple bins without significantly increasing number of model variables (adding each bin only adds one new capacity variable and no operational variables). See documentation for curtailable_variable_renewable() for more.
[0,1], The minimum generation level for a unit as a fraction of total capacity. This value cannot be higher than the smallest time-dependent CF value for a resource in Generators_variability.csv.
Ramp_Up_Percentage
[0,1], Maximum increase in power output from between two periods (typically hours), reported as a fraction of nameplate capacity.
Ramp_Dn_Percentage
[0,1], Maximum decrease in power output from between two periods (typically hours), reported as a fraction of nameplate capacity.
Hydro_Energy_to_Power_Ratio
The rated number of hours of reservoir hydro storage at peak discharge power output. (hours).
LDS
{0, 1}, Flag to indicate the resources eligible for long duration storage constraints with inter period linkage.
{0, 1, 2}, Flag to indicate membership in set of storage resources and designate which type of storage resource formulation to employ.
Model = 0: Not part of set (default)
Model = 1: Discharging power capacity and energy capacity are the investment decision variables; symmetric charge/discharge power capacity with charging capacity equal to discharging capacity (e.g. lithium-ion battery storage).
Model = 2: Discharging, charging power capacity and energy capacity are investment variables; asymmetric charge and discharge capacities using distinct processes (e.g. hydrogen electrolysis, storage, and conversion to power using fuel cell or combustion turbine).
LDS
{0, 1}, Flag to indicate the resources eligible for long duration storage constraints with inter period linkage.
LDS = 0: Not part of set (default)
LDS = 1: Long duration storage resources
Self_Disch
[0,1], The power loss of storage technologies per hour (fraction loss per hour)- only applies to storage techs.
Eff_Up
[0,1], Efficiency of charging storage.
Eff_Down
[0,1], Efficiency of discharging storage.
Min_Duration
Specifies the minimum ratio of installed energy to discharged power capacity that can be installed (hours).
Max_Duration
Specifies the maximum ratio of installed energy to discharged power capacity that can be installed (hours).
Existing technology capacity
Existing_Cap_MWh
The existing capacity of storage in MWh where Model = 1 or Model = 2.
Existing_Charge_Cap_MW
The existing charging capacity for resources where Model = 2.
Capacity/Energy requirements
Max_Cap_MWh
-1 (default) – no limit on maximum energy capacity of the resource. If non-negative, represents maximum allowed energy capacity (in MWh) of the resource with Model = 1 or Model = 2.
Max_Charge_Cap_MW
-1 (default) – no limit on maximum charge capacity of the resource. If non-negative, represents maximum allowed charge capacity (in MW) of the resource with Model = 2.
Min_Cap_MWh
-1 (default) – no limit on minimum energy capacity of the resource. If non-negative, represents minimum allowed energy capacity (in MWh) of the resource with Model = 1 or Model = 2.
Min_Charge_Cap_MW
-1 (default) – no limit on minimum charge capacity of the resource. If non-negative, represents minimum allowed charge capacity (in MW) of the resource with Model = 2.
Cost parameters
Inv_Cost_per_MWhyr
Annualized investment cost of the energy capacity for a storage technology (/MW/year), applicable to either Model = 1 or Model = 2.
Inv_Cost_Charge_per_MWyr
Annualized capacity investment cost for the charging portion of a storage technology with Model = 2 (/MW/year).
Fixed_OM_Cost_per_MWhyr
Fixed operations and maintenance cost of the energy component of a storage technology (/MWh/year).
Fixed_OM_Cost_Charge_per_MWyr
Fixed operations and maintenance cost of the charging component of a storage technology of type Model = 2.
Var_OM_Cost_per_MWhIn
Variable operations and maintenance cost of the charging aspect of a storage technology with Model = 2. Otherwise 0 (/MWh).
Maximum number of hours that demand can be deferred or delayed (hours).
Max_Flexible_Demand_Advance
Maximum number of hours that demand can be scheduled in advance of the original schedule (hours).
Flexible_Demand_Energy_Eff
[0,1], Energy efficiency associated with time shifting demand. Represents energy losses due to time shifting (or 'snap back' effect of higher consumption due to delay in use) that may apply to some forms of flexible demand (hours). For example, one may need to pre-cool a building more than normal to advance demand.
Cost parameters
Var_OM_Cost_per_MWhIn
Variable operations and maintenance costs associated with flexible demand deferral. Otherwise 0 (/MWh).
Electrolyzer efficiency in megawatt-hours (MWh) of electricity per metric tonne of hydrogen produced (MWh/t)
ElectrolyzerMinkt
Minimum annual quantity of hydrogen that must be produced by electrolyzer in kilotonnes (kt)
HydrogenPricePer_Tonne
Price (or value) of hydrogen per metric tonne (/t)
Min_Power
[0,1], The minimum generation level for a unit as a fraction of total capacity. This value cannot be higher than the smallest time-dependent CF value for a resource in Generators_variability.csv.
Ramp_Up_Percentage
[0,1], Maximum increase in power output from between two periods (typically hours), reported as a fraction of nameplate capacity.
Ramp_Dn_Percentage
[0,1], Maximum decrease in power output from between two periods (typically hours), reported as a fraction of nameplate capacity.
Note
Check Qualified_Hydrogen_Supply column in table 5a if electrolyzers are included in the model. This column is used to indicate which resources are eligible to supply electrolyzers in the same zone (used for hourly clean supply constraint).
Each co-located VRE and storage resource can be easily configured to contain either a co-located VRE-storage resource, standalone VRE resource (either wind, solar PV, or both), or standalone storage resource.
{0, 1}, Flag to indicate membership in the set of co-located VRE-storage resources with a solar PV component.
SOLAR = 0: Not part of set (default)
SOLAR = 1: If the co-located VRE-storage resource can produce solar PV energy.
WIND
{0, 1}, Flag to indicate membership in the set of co-located VRE-storage resources with a wind component.
WIND = 0: Not part of set (default)
WIND = 1: If the co-located VRE-storage resource can produce wind energy.
STORDCDISCHARGE
{0, 1, 2}, Flag to indicate membership in set of co-located VRE-storage resources that discharge behind the meter and through the inverter (DC).
STORDCDISCHARGE = 0: Not part of set (default)
STORDCDISCHARGE = 1: If the co-located VRE-storage resource contains symmetric charge/discharge power capacity with charging capacity equal to discharging capacity (e.g. lithium-ion battery storage). Note that if STORDCDISCHARGE = 1, STORDCCHARGE = 1.
STORDCDISCHARGE = 2: If the co-located VRE-storage resource has asymmetric discharge capacities using distinct processes (e.g. hydrogen electrolysis, storage, and conversion to power using fuel cell or combustion turbine).
STORDCCHARGE
{0, 1, 2}, Flag to indicate membership in set of co-located VRE-storage resources that charge through the inverter (DC).
STORDCCHARGE = 0: Not part of set (default)
STORDCCHARGE = 1: If the co-located VRE-storage resource contains symmetric charge/discharge power capacity with charging capacity equal to discharging capacity (e.g. lithium-ion battery storage). Note that if STORDCCHARGE = 1, STORDCDISCHARGE = 1.
STORDCCHARGE = 2: If the co-located VRE-storage resource has asymmetric charge capacities using distinct processes (e.g. hydrogen electrolysis, storage, and conversion to power using fuel cell or combustion turbine).
STORACDISCHARGE
{0, 1, 2}, Flag to indicate membership in set of co-located VRE-storage resources that discharges AC.
STORACDISCHARGE = 0: Not part of set (default)
STORACDISCHARGE = 1: If the co-located VRE-storage resource contains symmetric charge/discharge power capacity with charging capacity equal to discharging capacity (e.g. lithium-ion battery storage). Note that if STORACDISCHARGE = 1, STORACCHARGE = 1.
STORACDISCHARGE = 2: If the co-located VRE-storage resource has asymmetric discharge capacities using distinct processes (e.g. hydrogen electrolysis, storage, and conversion to power using fuel cell or combustion turbine).
STORACCHARGE
{0, 1, 2}, Flag to indicate membership in set of co-located VRE-storage resources that charge AC.
STORACCHARGE = 0: Not part of set (default)
STORACCHARGE = 1: If the co-located VRE-storage resource contains symmetric charge/discharge power capacity with charging capacity equal to discharging capacity (e.g. lithium-ion battery storage). Note that if STORACCHARGE = 1, STORACDISCHARGE = 1.
STORACCHARGE = 2: If the co-located VRE-storage resource has asymmetric charge capacities using distinct processes (e.g. hydrogen electrolysis, storage, and conversion to power using fuel cell or combustion turbine).
LDSVRESTOR
{0, 1}, Flag to indicate the co-located VRE-storage resources eligible for long duration storage constraints with inter period linkage (e.g., reservoir hydro, hydrogen storage).
LDSVRESTOR = 0: Not part of set (default)
LDSVRESTOR = 1: Long duration storage resources
Existing technology capacity
Existing_Cap_MW
The existing AC grid connection capacity in MW.
Existing_Cap_MWh
The existing capacity of storage in MWh.
Existing_Cap_Inverter_MW
The existing capacity of co-located VRE-STOR resource's inverter in MW (AC).
Existing_Cap_Solar_MW
The existing capacity of co-located VRE-STOR resource's solar PV in MW (DC).
Existing_Cap_Wind_MW
The existing capacity of co-located VRE-STOR resource's wind in MW (AC).
Existing_Cap_Discharge_DC_MW
The existing discharge capacity of co-located VRE-STOR resource's storage component in MW (DC). Note that this only applies to resources where STOR_DC_DISCHARGE = 2.
Existing_Cap_Charge_DC_MW
The existing charge capacity of co-located VRE-STOR resource's storage component in MW (DC). Note that this only applies to resources where STOR_DC_CHARGE = 2.
Existing_Cap_Discharge_AC_MW
The existing discharge capacity of co-located VRE-STOR resource's storage component in MW (AC). Note that this only applies to resources where STOR_AC_DISCHARGE = 2.
Existing_Cap_Charge_AC_MW
The existing charge capacity of co-located VRE-STOR resource's storage component in MW (AC). Note that this only applies to resources where STOR_DC_CHARGE = 2.
Capacity/Energy requirements
Max_Cap_MW
-1 (default) – no limit on maximum discharge capacity of the resource. If non-negative, represents maximum allowed AC grid connection capacity in MW of the resource.
Max_Cap_MWh
-1 (default) – no limit on maximum energy capacity of the resource. If non-negative, represents maximum allowed energy capacity of storage in MWh.
Min_Cap_MW
-1 (default) – no limit on minimum discharge capacity of the resource. If non-negative, represents minimum allowed AC grid connection capacity in MW.
Min_Cap_MWh
-1 (default) – no limit on minimum energy capacity of the resource. If non-negative, represents minimum allowed energy capacity of storage in MWh.
Max_Cap_Inverter_MW
-1 (default) – no limit on maximum inverter capacity of the resource. If non-negative, represents maximum allowed inverter capacity (in MW AC) of the resource.
Max_Cap_Solar_MW
-1 (default) – no limit on maximum solar PV capacity of the resource. If non-negative, represents maximum allowed solar PV capacity (in MW DC) of the resource.
Max_Cap_Wind_MW
-1 (default) – no limit on maximum wind capacity of the resource. If non-negative, represents maximum allowed wind capacity (in MW AC) of the resource.
Max_Cap_Discharge_DC_MW
-1 (default) – no limit on maximum DC discharge capacity of the resource. If non-negative, represents maximum allowed DC discharge capacity (in MW DC) of the resource with STOR_DC_DISCHARGE = 2.
Max_Cap_Charge_DC_MW
-1 (default) – no limit on maximum DC charge capacity of the resource. If non-negative, represents maximum allowed DC charge capacity (in MW DC) of the resource with STOR_DC_CHARGE = 2.
Max_Cap_Discharge_AC_MW
-1 (default) – no limit on maximum AC discharge capacity of the resource. If non-negative, represents maximum allowed AC discharge capacity (in MW AC) of the resource with STOR_AC_DISCHARGE = 2.
Max_Cap_Charge_AC_MW
-1 (default) – no limit on maximum AC charge capacity of the resource. If non-negative, represents maximum allowed AC charge capacity (in MW AC) of the resource with STOR_AC_CHARGE = 2.
Min_Cap_Inverter_MW
-1 (default) – no limit on minimum inverter capacity of the resource. If non-negative, represents minimum allowed inverter capacity (in MW AC) of the resource.
Min_Cap_Solar_MW
-1 (default) – no limit on minimum solar PV capacity of the resource. If non-negative, represents minimum allowed solar PV capacity (in MW DC) of the resource.
Min_Cap_Wind_MW
-1 (default) – no limit on minimum wind capacity of the resource. If non-negative, represents minimum allowed wind capacity (in MW AC) of the resource.
Min_Cap_Discharge_DC_MW
-1 (default) – no limit on minimum DC discharge capacity of the resource. If non-negative, represents minimum allowed DC discharge capacity (in MW DC) of the resource with STOR_DC_DISCHARGE = 2.
Min_Cap_Charge_DC_MW
-1 (default) – no limit on minimum DC charge capacity of the resource. If non-negative, represents minimum allowed DC charge capacity (in MW DC) of the resource with STOR_DC_CHARGE = 2.
Min_Cap_Discharge_AC_MW
-1 (default) – no limit on minimum AC discharge capacity of the resource. If non-negative, represents minimum allowed AC discharge capacity (in MW AC) of the resource with STOR_AC_DISCHARGE = 2.
Min_Cap_Charge_AC_MW
-1 (default) – no limit on minimum AC charge capacity of the resource. If non-negative, represents minimum allowed AC charge capacity (in MW AC) of the resource with STOR_AC_CHARGE = 2.
Cost parameters
Inv_Cost_per_MWyr
Annualized capacity investment cost of the grid connection (/MW/year).
Inv_Cost_per_MWhyr
Annualized investment cost of the energy capacity for the co-located storage resource (/MW/year)
Fixed_OM_Cost_per_MWyr
Fixed operations and maintenance cost of the grid connection (/MW/year).
Fixed_OM_Cost_per_MWhyr
Fixed operations and maintenance cost of the energy component of the co-located storage resource. (/MWh/year).
Inv_Cost_Inverter_per_MWyr
Annualized capacity investment cost of the inverter component (/MW-AC/year).
Inv_Cost_Solar_per_MWyr
Annualized capacity investment cost of the solar PV component (/MW-DC/year).
Inv_Cost_Wind_per_MWyr
Annualized capacity investment cost of the wind component (/MW-AC/year).
Inv_Cost_Discharge_DC_per_MWyr
Annualized capacity investment cost for the discharging portion of a storage technology with STOR_DC_DISCHARGE = 2 (/MW-DC/year).
Inv_Cost_Charge_DC_per_MWyr
Annualized capacity investment cost for the charging portion of a storage technology with STOR_DC_CHARGE = 2 (/MW-DC/year).
Inv_Cost_Discharge_AC_per_MWyr
Annualized capacity investment cost for the discharging portion of a storage technology with STOR_AC_DISCHARGE = 2 (/MW-AC/year).
Inv_Cost_Charge_AC_per_MWyr
Annualized capacity investment cost for the charging portion of a storage technology with STOR_AC_CHARGE = 2 (/MW-AC/year).
Fixed_OM_Inverter_Cost_per_MWyr
Fixed operations and maintenance cost of the inverter component (/MW-AC/year).
Fixed_OM_Solar_Cost_per_MWyr
Fixed operations and maintenance cost of the solar PV component (/MW-DC/year).
Fixed_OM_Wind_Cost_per_MWyr
Fixed operations and maintenance cost of the wind component (/MW-AC/year).
Fixed_OM_Cost_Discharge_DC_per_MWyr
Fixed operations and maintenance cost of the discharging component of a storage technology with STOR_DC_DISCHARGE = 2 (/MW-DC/year).
Fixed_OM_Cost_Charge_DC_per_MWyr
Fixed operations and maintenance cost of the charging component of a storage technology with STOR_DC_CHARGE = 2 (/MW-DC/year).
Fixed_OM_Cost_Discharge_AC_per_MWyr
Fixed operations and maintenance cost of the discharging component of a storage technology with STOR_AC_DISCHARGE = 2 (/MW-AC/year).
Fixed_OM_Cost_Charge_AC_per_MWyr
Fixed operations and maintenance cost of the charging component of a storage technology with STOR_AC_CHARGE = 2 (/MW-AC/year).
Var_OM_Cost_per_MWh_Solar
Variable operations and maintenance cost of the solar PV component (multiplied by the inverter efficiency for AC terms) (/MWh).
Var_OM_Cost_per_MWh_Wind
Variable operations and maintenance cost of the wind component (/MWh).
Var_OM_Cost_per_MWh_Discharge_DC
Variable operations and maintenance cost of the discharging component of a storage technology with STOR_DC_DISCHARGE = 2 (multiplied by the inverter efficiency for AC terms) (/MWh).
Var_OM_Cost_per_MWh_Charge_DC
Variable operations and maintenance cost of the charging component of a storage technology with STOR_DC_CHARGE = 2 (divided by the inverter efficiency for AC terms) (/MWh).
Var_OM_Cost_per_MWh_Discharge_AC
Variable operations and maintenance cost of the discharging component of a storage technology with STOR_AC_DISCHARGE = 2 (/MWh).
Var_OM_Cost_per_MWh_Charge_AC
Variable operations and maintenance cost of the charging component of a storage technology with STOR_AC_CHARGE = 2 (/MWh).
Technical performance parameters
Self_Disch
[0,1], The power loss of storage component of each resource per hour (fraction loss per hour).
EtaInverter
[0,1], Inverter efficiency representing losses from converting DC to AC power and vice versa for each technology
InverterRatioSolar
-1 (default) - no required ratio between solar PV capacity built to inverter capacity built. If non-negative, represents the ratio of solar PV capacity built to inverter capacity built.
InverterRatioWind
-1 (default) - no required ratio between wind capacity built to grid connection capacity built. If non-negative, represents the ratio of wind capacity built to grid connection capacity built.
Power_to_Energy_AC
The power to energy conversion for the storage component for AC discharging/charging of symmetric storage resources.
Power_to_Energy_DC
The power to energy conversion for the storage component for DC discharging/charging of symmetric storage resources.
Eff_Up_DC
[0,1], Efficiency of DC charging storage – applies to storage technologies (all STOR types).
Eff_Down_DC
[0,1], Efficiency of DC discharging storage – applies to storage technologies (all STOR types).
Eff_Up_AC
[0,1], Efficiency of AC charging storage – applies to storage technologies (all STOR types).
Eff_Down_AC
[0,1], Efficiency of AC discharging storage – applies to storage technologies (all STOR types).
In addition to the files described above, the resources folder contains the following files that are used to specify policy-related parameters for specific resources:
Resource_energy_share_requirement.csv
Resource_minimum_capacity_requirement.csv
Resource_maximum_capacity_requirement.csv
Resource_capacity_reserve_margin.csv
Note
These files are optional and can be omitted if no policy-related parameters are specified in the settings file. Also, not all the resources need to be included in these files, only those for which the policy applies.
The following table describes the columns in each of these four files.
Warning
The first column of each file must contain the resource name corresponding to a resource in one of the resource data files described above. Note that the order of resources in the policy files is not important.
This policy is applied when if EnergyShareRequirement > 0 in the settings file. * corresponds to the ith row of the file Energy_share_requirement.csv.
Resource name corresponding to a resource in one of the resource data files described above.
MinCap\*
Flag to indicate which resources are considered for the Minimum Capacity Requirement constraint.
co-located VRE-STOR resources only
MinCapSolar_*
Eligibility of resources with a solar PV component (multiplied by the inverter efficiency for AC terms) to participate in Minimum Technology Carveout constraint.
MinCapWind_*
Eligibility of resources with a wind component to participate in Minimum Technology Carveout constraint (AC terms).
MinCapStor_*
Eligibility of resources with a storage component to participate in Minimum Technology Carveout constraint (discharge capacity in AC terms).
This policy is applied when if MaxCapReq = 1 in the settings file. * corresponds to the ith row of the file Maximum_capacity_requirement.csv.
Resource name corresponding to a resource in one of the resource data files described above.
MaxCap\*
Flag to indicate which resources are considered for the Maximum Capacity Requirement constraint.
co-located VRE-STOR resources only
MaxCapSolar_*
Eligibility of resources with a solar PV component (multiplied by the inverter efficiency for AC terms) to participate in Maximum Technology Carveout constraint.
MaxCapWind_*
Eligibility of resources with a wind component to participate in Maximum Technology Carveout constraint (AC terms).
MaxCapStor_*
Eligibility of resources with a storage component to participate in Maximum Technology Carveout constraint (discharge capacity in AC terms).
This policy is applied when if CapacityReserveMargin > 0 in the settings file. * corresponds to the ith row of the file Capacity_reserve_margin.csv.
In addition to the files described above, the resources folder can contain additional files that are used to specify attributes for specific resources and modules. Currently, the following files are supported:
Resource_multistage_data.csv: mandatory if MultiStage = 1 in the settings file
<!– 2) Resource_piecewisefuel_usage.csv –>
Warning
The first column of each additional module file must contain the resource name corresponding to a resource in one of the resource data files described above. Note that the order of resources in these files is not important.
This file is mandatory if MultiStage = 1 in the settings file.
Column Name
Description
Resource
Resource name corresponding to a resource in one of the resource data files described above.
Capital_Recovery_Period
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs. Note that for co-located VRE-STOR resources, this value pertains to the grid connection.
Lifetime
Lifetime (in years) used for determining endogenous retirements of newly built capacity. Note that the same lifetime is used for each component of a co-located VRE-STOR resource.
Min_Retired_Cap_MW
Minimum required discharge capacity retirements in the current model period. This field can be used to enforce lifetime retirements of existing capacity. Note that for co-located VRE-STOR resources, this value pertains to the grid connection.
Min_Retired_Energy_Cap_MW
Minimum required energy capacity retirements in the current model period. This field can be used to enforce lifetime retirements of existing energy capacity. Note that for co-located VRE-STOR resources, this value pertains to the storage component.
Min_Retired_Charge_Cap_MW
Minimum required energy capacity retirements in the current model period. This field can be used to enforce lifetime retirements of existing charge capacity.
Contribute_Min_Retirement
{0, 1}, Flag to indicate whether the (retrofitting) resource can contribute to the minimum retirement requirement.
co-located VRE-STOR resources only
Capital_Recovery_Period_DC
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the inverter component.
Capital_Recovery_Period_Solar
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the solar PV component.
Capital_Recovery_Period_Wind
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the wind component.
Capital_Recovery_PeriodDischargeDC
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the discharge DC component when STOR_DC_DISCHARGE = 2.
Capital_Recovery_PeriodChargeDC
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the charge DC component when STOR_DC_CHARGE = 2.
Capital_Recovery_PeriodDischargeAC
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the discharge AC component when STOR_AC_DISCHARGE = 2.
Capital_Recovery_PeriodChargeAC
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the charge AC component when STOR_AC_CHARGE = 2.
Min_Retired_Cap_Inverter_MW
Minimum required inverter capacity retirements in the current model period. This field can be used to enforce lifetime retirements of existing capacity.
Min_Retired_Cap_Solar_MW
Minimum required solar capacity retirements in the current model period. This field can be used to enforce lifetime retirements of existing capacity.
Min_Retired_Cap_Wind_MW
Minimum required wind capacity retirements in the current model period. This field can be used to enforce lifetime retirements of existing capacity.
Min_Retired_Cap_DischargeDC\MW
Minimum required discharge capacity retirements in the current model period for storage resources with STOR_DC_DISCHARGE = 2. This field can be used to enforce lifetime retirements of existing capacity.
Min_Retired_Cap_ChargeDC\MW
Minimum required charge capacity retirements in the current model period for storage resources with STOR_DC_CHARGE = 2. This field can be used to enforce lifetime retirements of existing capacity.
Min_Retired_Cap_DischargeAC\MW
Minimum required discharge capacity retirements in the current model period for storage resources with STOR_AC_DISCHARGE = 2. This field can be used to enforce lifetime retirements of existing capacity.
Min_Retired_Cap_ChargeAC\MW
Minimum required charge capacity retirements in the current model period for storage resources with STOR_AC_CHARGE = 2. This field can be used to enforce lifetime retirements of existing capacity.
WACC_DC
The line-specific weighted average cost of capital for the inverter component.
WACC_Solar
The line-specific weighted average cost of capital for the solar PV component.
WACC_Wind
The line-specific weighted average cost of capital for the wind component.
WACC_Discharge_DC
The line-specific weighted average cost of capital for the discharging DC storage component with STOR_DC_DISCHARGE = 2.
WACC_Charge_DC
The line-specific weighted average cost of capital for the charging DC storage component with STOR_DC_CHARGE = 2.
WACC_Discharge_AC
The line-specific weighted average cost of capital for the discharging AC storage component with STOR_AC_DISCHARGE = 2.
WACC_Charge_AC
The line-specific weighted average cost of capital for the charging AC storage component with STOR_AC_CHARGE = 2.
This file contains the time-series of capacity factors / availability of each resource included in the resource .csv file in the resources folder for each time step (e.g. hour) modeled.
• First column: The first column contains the time index of each row (starting in the second row) from 1 to N.
• Second column onwards: Resources are listed from the second column onward with headers matching each resource name in the resource .csv file in the resources folder in any order. The availability for each resource at each time step is defined as a fraction of installed capacity and should be between 0 and 1. Note that for this reason, resource names specified in the resource .csv file must be unique. Note that for Hydro reservoir resources (i.e. Hydro.csv), values in this file correspond to inflows (in MWhs) to the hydro reservoir as a fraction of installed power capacity, rather than hourly capacity factor. Note that for co-located VRE and storage resources, solar PV and wind resource profiles should not be located in this file but rather in separate variability files (these variabilities can be in the Generators_variability.csv if time domain reduction functionalities will be utilized because the time domain reduction functionalities will separate the files after the clustering is completed).
|Self_Disch |[0,1], The power loss of storage technologies per hour (fraction loss per hour)- only applies to storage techs. Note that for co-located VRE-STOR resources, this value applies to the storage component of each resource.| |Min_Power |[0,1], The minimum generation level for a unit as a fraction of total capacity. This value cannot be higher than the smallest time-dependent CF value for a resource in Generators_variability.csv. Applies to thermal plants, and reservoir hydro resource (HYDRO = 1).| |Ramp_Up_Percentage |[0,1], Maximum increase in power output from between two periods (typically hours), reported as a fraction of nameplate capacity. Applies to thermal plants, and reservoir hydro resource (HYDRO = 1).| |Ramp_Dn_Percentage |[0,1], Maximum decrease in power output from between two periods (typically hours), reported as a fraction of nameplate capacity. Applies to thermal plants, and reservoir hydro resource (HYDRO = 1).| |Eff_Up |[0,1], Efficiency of charging storage – applies to storage technologies (all STOR types except co-located storage resources).| |Eff_Down |[0,1], Efficiency of discharging storage – applies to storage technologies (all STOR types except co-located storage resources). |
|Min_Duration |Specifies the minimum ratio of installed energy to discharged power capacity that can be installed. Applies to STOR types 1 and 2 (hours). Note that for co-located VRE-STOR resources, this value does not apply. | |Max_Duration |Specifies the maximum ratio of installed energy to discharged power capacity that can be installed. Applies to STOR types 1 and 2 (hours). Note that for co-located VRE-STOR resources, this value does not apply. | |Max_Flexible_Demand_Delay |Maximum number of hours that demand can be deferred or delayed. Applies to resources with FLEX type 1 (hours). | |Max_Flexible_Demand_Advance |Maximum number of hours that demand can be scheduled in advance of the original schedule. Applies to resources with FLEX type 1 (hours). | |Flexible_Demand_Energy_Eff |[0,1], Energy efficiency associated with time shifting demand. Represents energy losses due to time shifting (or 'snap back' effect of higher consumption due to delay in use) that may apply to some forms of flexible demand. Applies to resources with FLEX type 1 (hours). For example, one may need to pre-cool a building more than normal to advance demand. |
This file contains the time-series of capacity factors / availability of the solar PV component (DC capacity factors) of each co-located resource included in the Vre_and_stor_data.csv file for each time step (e.g. hour) modeled.
• first column: The first column contains the time index of each row (starting in the second row) from 1 to N.
• Second column onwards: Resources are listed from the second column onward with headers matching each resource name in the Vre_stor.csv files in any order. The availability for each resource at each time step is defined as a fraction of installed capacity and should be between 0 and 1. Note that for this reason, resource names specified in all the resource .csv files must be unique.
This file contains the time-series of capacity factors / availability of the wind component (AC capacity factors) of each co-located resource included in the Vre_and_stor_data.csv file for each time step (e.g. hour) modeled.
• First column: The first column contains the time index of each row (starting in the second row) from 1 to N.
• Second column onwards: Resources are listed from the second column onward with headers matching each resource name in the Vre_stor.csv files in any order. The availability for each resource at each time step is defined as a fraction of installed capacity and should be between 0 and 1. Note that for this reason, resource names specified in all the resource .csv files must be unique.
This file includes parameter inputs needed to model time-dependent procurement of regulation and spinning reserves. This file is needed if OperationalReserves flag is activated in the YAML file genx_settings.yml.
[0,1], Regulation requirement as a percent of time-dependent demand; here demand is the total across all model zones.
Reg_Req_Percent_VRE
[0,1], Regulation requirement as a percent of time-dependent wind and solar generation (summed across all model zones).
Rsv_Req_Percent_Demand [0,1],
Spinning up or contingency reserve requirement as a percent of time-dependent demand (which is summed across all zones).
Rsv_Req_Percent_VRE
[0,1], Spinning up or contingency reserve requirement as a percent of time-dependent wind and solar generation (which is summed across all zones).
Unmet_Rsv_Penalty_Dollar_per_MW
Penalty for not meeting time-dependent spinning reserve requirement (/MW per time step).
Dynamic_Contingency
Flags to include capacity (generation or transmission) contingency to be added to the spinning reserve requirement.
Dynamic_Contingency
= 1: contingency set to be equal to largest installed thermal unit (only applied when UCommit = 1).
= 2: contingency set to be equal to largest committed thermal unit each time period (only applied when UCommit = 1).
Static_Contingency_MW
A fixed static contingency in MW added to reserve requirement. Applied when UCommit = 1 and DynamicContingency = 0, or when UCommit = 2. Contingency term not included in operating reserve requirement when this value is set to 0 and DynamicContingency is not active.
This file contains inputs specifying minimum energy share requirement policies, such as Renewable Portfolio Standard (RPS) or Clean Energy Standard (CES) policies. This file is needed if parameter EnergyShareRequirement has a non-zero value in the YAML file genx_settings.yml.
Note: this file should use the same region name as specified in the the resource .csv file (inside the Resource).
[0,1], Energy share requirements as a share of zonal demand (calculated on an annual basis). * represents the number of the ESR constraint, given by the number of ESR_* columns in the Energy_share_requirement.csv file.
This file contains inputs specifying CO2 emission limits policies (e.g. emissions cap and permit trading programs). This file is needed if CO2Cap flag is activated in the YAML file genx_settings.yml. CO2Cap flag set to 1 represents mass-based (tCO2 ) emission target. CO2Cap flag set to 2 is specified when emission target is given in terms of rate (tCO2/MWh) and is based on total demand met. CO2Cap flag set to 3 is specified when emission target is given in terms of rate (tCO2 /MWh) and is based on total generation.
If a zone is eligible for the emission limit constraint, then this column is set to 1, else 0.
CO_2_Max_tons_MWh_*
Emission limit in terms of rate
CO_2_Max_Mtons_*
Emission limit in absolute values, in Million of tons
where in the above inputs, * represents the number of the emission limit constraints. For example, if the model has 2 emission limit constraints applied separately for 2 zones, the above CSV file will have 2 columns for specifying emission limit in terms on rate: CO_2_Max_tons_MWh_1 and CO_2_Max_tons_MWh_2.
This file contains the regional capacity reserve margin requirements. This file is needed if parameter CapacityReserveMargin has a non-zero value in the YAML file genx_settings.yml.
Note: this file should use the same region name as specified in the resource .csv file (inside the Resource).
This file contains the minimum capacity carve-out requirement to be imposed (e.g. a storage capacity mandate or offshore wind capacity mandate). This file is needed if the MinCapReq flag has a non-zero value in the YAML file genx_settings.yml.
Index of the minimum capacity carve-out requirement.
Constraint_Description
Names of minimum capacity carve-out constraints; not to be read by model, but used as a helpful notation to the model user.
Min_MW
minimum capacity requirement [MW]
Some of the columns specified in the input files in Section 2.2 and 2.1 are not used in the GenX model formulation. These columns are necessary for interpreting the model outputs and used in the output module of the GenX.
This contains the maximum capacity limits to be imposed (e.g. limits on total deployment of solar, wind, or batteries in the system as a whole or in certain collections of zones). It is required if the MaxCapReq flag has a non-zero value in genx_settings.yml.
Names of maximum capacity limit; not to be read by model, but used as a helpful notation to the model user.
Max_MW
maximum capacity limit [MW]
Some of the columns specified in the input files in Section 2.2 and 2.1 are not used in the GenX model formulation. These columns are necessary for interpreting the model outputs and used in the output module of the GenX.
This file contains the settings parameters required to run the Method of Morris algorithm in GenX. This file is needed if the MethodofMorris flag is ON in the YAML file genx_settings.yml.
This column contains unique names of resources available to the model. Resources can include generators, storage, and flexible or time shiftable demand/loads.
Zone
Integer representing zone number where the resource is located.
Lower_bound
Percentage lower deviation from the nominal value
Upper_bound
Percentage upper deviation from the nominal value
Parameter
Column from the resource .csv file (inside the Resource) containing uncertain parameters
Group
Group the uncertain parameters that will be changed all at once while performing the sensitivity analysis. For example, if the fuel price of natural gas is uncertain, all generators consuming natural gas should be in the same group. Group name is user defined
p_steps
Number of steps between upper and lower bound
total_num_trajectory
Total number of trakectories through the design matrix
num_trajectory
Selected number of trajectories throigh the design matrix
len_design_mat
Length of the design matrix
policy
Name of the policy
Notes
Upper and lower bounds are specified in terms of percentage deviation from the nominal value.
Percentage variation for uncertain parameters in a given group is identical. For example, if solar cluster 1 and solar cluster 2 both belong to the ‘solar’ group, their Lowerbound and Upperbound must be identical
P_steps should at least be = 1\%, i.e., Upper_bound – Lower_bound $<$ p_steps
P_steps for parameters in one group must be identical
Total_num_trajectory should be around 3 to 4 times the total number of uncertain parameters
num_trajectory should be approximately equal to the total number of uncertain parameters
len_design_mat should be 1.5 to 2 times the total number of uncertain parameters
Higher number of num_trajectory and lendesignmat would lead to higher accuracy
Upper and lower bounds should be specified for all the resources included in the resource .csv file (inside the Resource). If a parameter related to a particular resource is not uncertain, specify upper bound = lower bound = 0.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+ 2, 1, 0, -1,
Note that in either case, positive flows indicate flow from start to end zone; negative flows indicate flow from end to start zone.
This file includes parameters to characterize model temporal resolution to approximate annual grid operations, electricity demand for each time step for each zone, and cost of load shedding. Note that GenX is designed to model hourly time steps. With some care and effort, finer (e.g. 15 minute) or courser (e.g. 2 hour) time steps can be modeled so long as all time-related parameters are scaled appropriately (e.g. time period weights, heat rates, ramp rates and minimum up and down times for generators, variable costs, etc).
Value of lost load (also referred to as non-served energy) in /MWh.
Demand_Segment
Number of demand curtailment/unserved demand segments with different cost and capacity of curtailable demand for each segment. User-specified demand segments. Integer values starting with 1 in the first row. Additional segements added in subsequent rows.
Cost_of_Demand_Curtailment_per_MW
Cost of non-served energy/demand curtailment (for each segment), reported as a fraction of value of the lost load (non-served demand). If Demand_Segment = 1, then this parameter is a scalar and equal to one. In general this parameter is a vector of length equal to the length of Demand_Segment.
Max_Demand_Curtailment
Maximum time-dependent demand curtailable in each segment, reported as % of the demand in each zone and each period. If Demand_Segment = 1, then this parameter is a scalar and equal to one. In general this parameter is a vector of length given by length of Demand_segment.
Time_Index
Index defining time step in the model.
Demand_MW_z*
Demand profile of a zone z* in MW; if multiple zones, this parameter will be a matrix with columns equal to number of zones (each column named appropriate zone number appended to parameter) and rows equal to number of time periods of grid operations being modeled.
Rep_Periods
Number of representative periods (e.g. weeks, days) that are modeled to approximate annual grid operations. This is always a single entry. For a full-year model, this is 1.
Timesteps_per_Rep_Period
Number of timesteps per representative period (e.g. 168 if period is set as a week using hour-long time steps). This is always a single entry: all representative periods have the same length. For a full-year model, this entry is equal to the number of time steps.
Sub_Weights
Number of annual time steps (e.g. hours) represented by each timestep in a representative period. The length of this column is equal to the number of representative periods. The sum of the elements should be equal to the total number of time steps in a model time horizon (e.g. 8760 hours if modeling 365 days or 8736 if modeling 52 weeks).
The resources folder contains the input files for each resource type. At the current version of GenX, the following resources are included in the model:
thermal generators, specified in the Thermal.csv file,
variable renewable energy resources (VRE), specified in the VRE.csv file,
reservoir hydro resources, specified in the Hydro.csv file,
storage resources, specified in the Storage.csv file,
flexible demand resources, specified in the Flex_demand.csv file,
must-run resources, specified in the Must_run.csv file,
electrolyzers, specified in the Electrolyzer.csv file, and
co-located VRE and storage resources, specified in the Vre_stor.csv file.
Each file contains cost and performance parameters for various generators and other resources included in the model formulation. The following table describes the mandatory columns in each of these files. Note that the column names are case insensitive.
This column contains unique names of resources available to the model. Resources can include generators, storage, and flexible or time shiftable demand.
Zone
Integer representing zone number where the resource is located.
Technology type flags
New_Build
{0, 1}, Flag for resource (storage, generation) eligibility for capacity expansion.
New_Build = 1: eligible for capacity expansion.
New_Build = 0: not eligible for capacity expansion.
Can_Retire
{0, 1}, Flag for resource (storage, generation) eligibility for retirement.
Can_Retire = 1: eligible for retirement.
Can_Retire = 0: not eligible for retirement.
Existing technology capacity
Existing_Cap_MW
The existing capacity of a power plant in MW. Note that for co-located VRE-STOR resources, this capacity represents the existing AC grid connection capacity in MW.
Capacity/Energy requirements
Max_Cap_MW
-1 (default) – no limit on maximum discharge capacity of the resource. If non-negative, represents maximum allowed discharge capacity (in MW) of the resource. Note that for co-located VRE-STOR resources, this capacity represents the maximum AC grid connection capacity in MW.
Min_Cap_MW
-1 (default) – no limit on minimum discharge capacity of the resource. If non-negative, represents minimum allowed discharge capacity (in MW) of the resource. Note that for co-located VRE-STOR resources, this capacity represents the minimum AC grid connection capacity in MW.
Cost parameters
Inv_Cost_per_MWyr
Annualized capacity investment cost of a technology (/MW/year). Note that for co-located VRE-STOR resources, this annualized capacity investment cost pertains to the grid connection.
Fixed_OM_Cost_per_MWyr
Fixed operations and maintenance cost of a technology (/MW/year). Note that for co-located VRE-STOR resources, this fixed operations and maintenance cost pertains to the grid connection.
Var_OM_Cost_per_MWh
Variable operations and maintenance cost of a technology (/MWh). Note that for co-located VRE-STOR resources, these costs apply to the AC generation sent to the grid from the entire site.
Technical performance parameters
Heat_Rate_MMBTU_per_MWh
Heat rate of a generator or MMBtu of fuel consumed per MWh of electricity generated for export (net of on-site consumption). The heat rate is the inverse of the efficiency: a lower heat rate is better. Should be consistent with fuel prices in terms of reporting on higher heating value (HHV) or lower heating value (LHV) basis.
Fuel
Fuel needed for a generator. The names should match with the ones in the Fuels_data.csv.
Required for writing outputs
region
Name of the model region
cluster
Number of the cluster when representing multiple clusters of a given technology in a given region.
Required if electrolyzer is included in the model
QualifiedHydrogenSupply
{0,1}, Indicates that generator or storage resources is eligible to supply electrolyzers in the same zone (used for hourly clean supply constraint)
Required for retrofitting
Can_Retrofit
{0, 1}, Flag for resource (storage, generation) eligibility for retrofit.
Can_Retrofit = 1: eligible for retrofit.
Can_Retrofit = 0: not eligible for retrofit.
Retrofit
{0, 1}, Flag for resource retrofit technologies (i.e., retrofit options, e.g. CCS retrofit for coal plants).
Retrofit = 1: is a retrofit technology.
Retrofit = 0: is not a retrofit technology.
Retrofit_Id
Unique identifier to group retrofittable source technologies with retrofit options inside the same zone.
Eligibility of the technology for Modeling To Generate Alternative (MGA) run.
1 = Technology is available for the MGA run.
0 = Technology is unavailable for the MGA run (e.g. storage technologies).
Resource_Type
For the MGA run, we categorize all the resources in a few resource types. We then find maximally different generation portfolio based on these resource types. For example, existing solar and new solar resources could be represented by a resource type names Solar. Categorization of resources into resource types is user dependent.
Maintenance data
MAINT
[0,1], toggles scheduled maintenance formulation.
Maintenance_Duration
(Positive integer, less than total length of simulation.) Duration of the maintenance period, in number of timesteps. Only used if MAINT=1.
Maintenance_Cycle_Length_Years
Length of scheduled maintenance cycle, in years. 1 is maintenance every year, 3 is every three years, etc. (Positive integer. Only used if MAINT=1.)
Maintenance_Begin_Cadence
Cadence of timesteps in which scheduled maintenance can begin. 1 means that a maintenance period can start in any timestep, 24 means it can start only in timesteps 1, 25, 49, etc. A larger number can decrease the simulation computational cost as it limits the optimizer's choices. (Positive integer, less than total length of simulation. Only used if MAINT=1.)
CO2-related parameters required if any resources have nonzero CO2CaptureFraction
CO2_Capture_Fraction
[0,1], The CO2 capture fraction of CCS-equipped power plants during steady state operation. This value should be 0 for generators without CCS.
CO2_Capture_Fraction_Startup
[0,1], The CO2 capture fraction of CCS-equipped power plants during the startup events. This value should be 0 for generators without CCS
Biomass
{0, 1}, Flag to indicate if generator uses biomass as feedstock (optional input column).
Biomass = 0: Not part of set (default).
Biomass = 1: Uses biomass as fuel.
CCS_Disposal_Cost_per_Metric_Ton
Cost associated with CCS disposal (/tCO2), including pipeline, injection and storage costs of CCS-equipped generators.
{1, 2}, Flag to indicate membership in set of thermal resources (e.g. nuclear, combined heat and power, natural gas combined cycle, coal power plant)
Model = 1: If the power plant relies on thermal energy input and subject unit commitment constraints/decisions if UCommit >= 1 (e.g. cycling decisions/costs/constraints).
Model = 2: If the power plant relies on thermal energy input and is subject to simplified economic dispatch constraints (ramping limits and minimum output level but no cycling decisions/costs/constraints).
Min_Power
[0,1], The minimum generation level for a unit as a fraction of total capacity. This value cannot be higher than the smallest time-dependent CF value for a resource in Generators_variability.csv.
Ramp_Up_Percentage
[0,1], Maximum increase in power output from between two periods (typically hours), reported as a fraction of nameplate capacity.
Ramp_Dn_Percentage
[0,1], Maximum decrease in power output from between two periods (typically hours), reported as a fraction of nameplate capacity.
PiecewiseFuelUsage-related parameters
PWFU_Fuel_Usage_Zero_Load_MMBTU_per_h
The fuel usage (MMBTU/h) for the first PWFU segemnt (y-intercept) at zero load.
PWFU_Heat_Rate_MMBTU_per_MWh_*i
The slope of fuel usage function of the segment i.
PWFU_Load_Point_MW_*i
The end of segment i (MW).
Multi-fuel parameters
MULTI_FUELS
{0, 1}, Flag to indicate membership in set of thermal resources that can burn multiple fuels at the same time (e.g., natural gas combined cycle cofiring with hydrogen, coal power plant cofiring with natural gas.
MULTI_FUELS = 0: Not part of set (default)
MULTI_FUELS = 1: Resources that can use fuel blending.
Num_Fuels
Number of fuels that a multi-fuel generator (MULTIFUELS = 1) can use at the same time. The length of ['Fuel1', 'Fuel2', ...] should be equal to 'Num\Fuels'. Each fuel will requires its corresponding heat rate, min cofire level, and max cofire level.
Fuel1
Frist fuel needed for a mulit-fuel generator (MULTIFUELS = 1). The names should match with the ones in the `Fuelsdata.csv`.
Fuel2
Second fuel needed for a mulit-fuel generator (MULTIFUELS = 1). The names should match with the ones in the `Fuelsdata.csv`.
Heat1_Rate_MMBTU_per_MWh
Heat rate of a multi-fuel generator (MULTI_FUELS = 1) for Fuel1.
Heat2_Rate_MMBTU_per_MWh
Heat rate of a multi-fuel generator (MULTI_FUELS = 1) for Fuel2.
Fuel1_Min_Cofire_Level
The minimum blendng level of 'Fuel1' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the normal generation process.
Fuel1_Min_CofireLevel\Start
The minimum blendng level of 'Fuel1' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the start-up process.
Fuel1_Max_Cofire_Level
The maximum blendng level of 'Fuel1' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the normal generation process.
Fuel1_Max_CofireLevel\Start
The maximum blendng level of 'Fuel1' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the start-up process.
Fuel2_Min_Cofire_Level
The minimum blendng level of 'Fuel2' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the normal generation process.
Fuel2_Min_CofireLevel\Start
The minimum blendng level of 'Fuel2' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the start-up process.
Fuel2_Max_Cofire_Level
The maximum blendng level of 'Fuel2' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the normal generation process.
Fuel2_Max_CofireLevel\Start
The maximum blendng level of 'Fuel2' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the start-up process.
The following settings apply only to thermal plants with unit commitment constraints
Up_Time
Minimum amount of time a resource has to stay in the committed state.
Down_Time
Minimum amount of time a resource has to remain in the shutdown state.
Start_Cost_per_MW
Cost per MW of nameplate capacity to start a generator (/MW per start). Multiplied by the number of generation units (each with a pre-specified nameplate capacity) that is turned on.
Start_Fuel_MMBTU_per_MW
Startup fuel use per MW of nameplate capacity of each generator (MMBtu/MW per start).
OperationalReserves = 1
Reg_Cost
Cost of providing regulation reserves (/MW per time step/hour).
Rsv_Cost
Cost of providing upwards spinning or contingency reserves (/MW per time step/hour).
Reg_Max
[0,1], Fraction of nameplate capacity that can committed to provided regulation reserves. .
Rsv_Max
[0,1], Fraction of nameplate capacity that can committed to provided upwards spinning or contingency reserves.
Number of resource availability profiles considered for each VRE resource per zone. This parameter is used to decide the number of capacity investment decision variables related to a single variable renewable energy technology in each zone.
Num_VRE_bins = 1: using a single resource availability profile per technology per zone. 1 capacity investment decision variable and 1 generator RID tracking technology power output (and in each zone).
Num_VRE_bins > 1: using multiple resource availability profiles per technology per zone. Num_VRE_bins capacity investment decision variables and 1 generator RID used to define technology power output at each time step (and in each zone). Example: Suppose we are modeling 3 bins of wind profiles for each zone. Then include 3 rows with wind resource names as Wind_1, Wind_2, and Wind_3 and a corresponding increasing sequence of RIDs. Set Num_VRE_bins for the generator with smallest RID, Wind_1, to be 3 and set Num_VRE_bins for the other rows corresponding to Wind_2 and Wind_3, to be zero. By setting Num_VRE_bins for Wind_2 and Wind_3, the model eliminates the power outputs variables for these generators. The power output from the technology across all bins is reported in the power output variable for the first generator. This allows for multiple bins without significantly increasing number of model variables (adding each bin only adds one new capacity variable and no operational variables). See documentation for curtailable_variable_renewable() for more.
[0,1], The minimum generation level for a unit as a fraction of total capacity. This value cannot be higher than the smallest time-dependent CF value for a resource in Generators_variability.csv.
Ramp_Up_Percentage
[0,1], Maximum increase in power output from between two periods (typically hours), reported as a fraction of nameplate capacity.
Ramp_Dn_Percentage
[0,1], Maximum decrease in power output from between two periods (typically hours), reported as a fraction of nameplate capacity.
Hydro_Energy_to_Power_Ratio
The rated number of hours of reservoir hydro storage at peak discharge power output. (hours).
LDS
{0, 1}, Flag to indicate the resources eligible for long duration storage constraints with inter period linkage.
{0, 1, 2}, Flag to indicate membership in set of storage resources and designate which type of storage resource formulation to employ.
Model = 0: Not part of set (default)
Model = 1: Discharging power capacity and energy capacity are the investment decision variables; symmetric charge/discharge power capacity with charging capacity equal to discharging capacity (e.g. lithium-ion battery storage).
Model = 2: Discharging, charging power capacity and energy capacity are investment variables; asymmetric charge and discharge capacities using distinct processes (e.g. hydrogen electrolysis, storage, and conversion to power using fuel cell or combustion turbine).
LDS
{0, 1}, Flag to indicate the resources eligible for long duration storage constraints with inter period linkage.
LDS = 0: Not part of set (default)
LDS = 1: Long duration storage resources
Self_Disch
[0,1], The power loss of storage technologies per hour (fraction loss per hour)- only applies to storage techs.
Eff_Up
[0,1], Efficiency of charging storage.
Eff_Down
[0,1], Efficiency of discharging storage.
Min_Duration
Specifies the minimum ratio of installed energy to discharged power capacity that can be installed (hours).
Max_Duration
Specifies the maximum ratio of installed energy to discharged power capacity that can be installed (hours).
Existing technology capacity
Existing_Cap_MWh
The existing capacity of storage in MWh where Model = 1 or Model = 2.
Existing_Charge_Cap_MW
The existing charging capacity for resources where Model = 2.
Capacity/Energy requirements
Max_Cap_MWh
-1 (default) – no limit on maximum energy capacity of the resource. If non-negative, represents maximum allowed energy capacity (in MWh) of the resource with Model = 1 or Model = 2.
Max_Charge_Cap_MW
-1 (default) – no limit on maximum charge capacity of the resource. If non-negative, represents maximum allowed charge capacity (in MW) of the resource with Model = 2.
Min_Cap_MWh
-1 (default) – no limit on minimum energy capacity of the resource. If non-negative, represents minimum allowed energy capacity (in MWh) of the resource with Model = 1 or Model = 2.
Min_Charge_Cap_MW
-1 (default) – no limit on minimum charge capacity of the resource. If non-negative, represents minimum allowed charge capacity (in MW) of the resource with Model = 2.
Cost parameters
Inv_Cost_per_MWhyr
Annualized investment cost of the energy capacity for a storage technology (/MW/year), applicable to either Model = 1 or Model = 2.
Inv_Cost_Charge_per_MWyr
Annualized capacity investment cost for the charging portion of a storage technology with Model = 2 (/MW/year).
Fixed_OM_Cost_per_MWhyr
Fixed operations and maintenance cost of the energy component of a storage technology (/MWh/year).
Fixed_OM_Cost_Charge_per_MWyr
Fixed operations and maintenance cost of the charging component of a storage technology of type Model = 2.
Var_OM_Cost_per_MWhIn
Variable operations and maintenance cost of the charging aspect of a storage technology with Model = 2. Otherwise 0 (/MWh).
Maximum number of hours that demand can be deferred or delayed (hours).
Max_Flexible_Demand_Advance
Maximum number of hours that demand can be scheduled in advance of the original schedule (hours).
Flexible_Demand_Energy_Eff
[0,1], Energy efficiency associated with time shifting demand. Represents energy losses due to time shifting (or 'snap back' effect of higher consumption due to delay in use) that may apply to some forms of flexible demand (hours). For example, one may need to pre-cool a building more than normal to advance demand.
Cost parameters
Var_OM_Cost_per_MWhIn
Variable operations and maintenance costs associated with flexible demand deferral. Otherwise 0 (/MWh).
Electrolyzer efficiency in megawatt-hours (MWh) of electricity per metric tonne of hydrogen produced (MWh/t)
ElectrolyzerMinkt
Minimum annual quantity of hydrogen that must be produced by electrolyzer in kilotonnes (kt)
HydrogenPricePer_Tonne
Price (or value) of hydrogen per metric tonne (/t)
Min_Power
[0,1], The minimum generation level for a unit as a fraction of total capacity. This value cannot be higher than the smallest time-dependent CF value for a resource in Generators_variability.csv.
Ramp_Up_Percentage
[0,1], Maximum increase in power output from between two periods (typically hours), reported as a fraction of nameplate capacity.
Ramp_Dn_Percentage
[0,1], Maximum decrease in power output from between two periods (typically hours), reported as a fraction of nameplate capacity.
Note
Check Qualified_Hydrogen_Supply column in table 5a if electrolyzers are included in the model. This column is used to indicate which resources are eligible to supply electrolyzers in the same zone (used for hourly clean supply constraint).
Each co-located VRE and storage resource can be easily configured to contain either a co-located VRE-storage resource, standalone VRE resource (either wind, solar PV, or both), or standalone storage resource.
{0, 1}, Flag to indicate membership in the set of co-located VRE-storage resources with a solar PV component.
SOLAR = 0: Not part of set (default)
SOLAR = 1: If the co-located VRE-storage resource can produce solar PV energy.
WIND
{0, 1}, Flag to indicate membership in the set of co-located VRE-storage resources with a wind component.
WIND = 0: Not part of set (default)
WIND = 1: If the co-located VRE-storage resource can produce wind energy.
STORDCDISCHARGE
{0, 1, 2}, Flag to indicate membership in set of co-located VRE-storage resources that discharge behind the meter and through the inverter (DC).
STORDCDISCHARGE = 0: Not part of set (default)
STORDCDISCHARGE = 1: If the co-located VRE-storage resource contains symmetric charge/discharge power capacity with charging capacity equal to discharging capacity (e.g. lithium-ion battery storage). Note that if STORDCDISCHARGE = 1, STORDCCHARGE = 1.
STORDCDISCHARGE = 2: If the co-located VRE-storage resource has asymmetric discharge capacities using distinct processes (e.g. hydrogen electrolysis, storage, and conversion to power using fuel cell or combustion turbine).
STORDCCHARGE
{0, 1, 2}, Flag to indicate membership in set of co-located VRE-storage resources that charge through the inverter (DC).
STORDCCHARGE = 0: Not part of set (default)
STORDCCHARGE = 1: If the co-located VRE-storage resource contains symmetric charge/discharge power capacity with charging capacity equal to discharging capacity (e.g. lithium-ion battery storage). Note that if STORDCCHARGE = 1, STORDCDISCHARGE = 1.
STORDCCHARGE = 2: If the co-located VRE-storage resource has asymmetric charge capacities using distinct processes (e.g. hydrogen electrolysis, storage, and conversion to power using fuel cell or combustion turbine).
STORACDISCHARGE
{0, 1, 2}, Flag to indicate membership in set of co-located VRE-storage resources that discharges AC.
STORACDISCHARGE = 0: Not part of set (default)
STORACDISCHARGE = 1: If the co-located VRE-storage resource contains symmetric charge/discharge power capacity with charging capacity equal to discharging capacity (e.g. lithium-ion battery storage). Note that if STORACDISCHARGE = 1, STORACCHARGE = 1.
STORACDISCHARGE = 2: If the co-located VRE-storage resource has asymmetric discharge capacities using distinct processes (e.g. hydrogen electrolysis, storage, and conversion to power using fuel cell or combustion turbine).
STORACCHARGE
{0, 1, 2}, Flag to indicate membership in set of co-located VRE-storage resources that charge AC.
STORACCHARGE = 0: Not part of set (default)
STORACCHARGE = 1: If the co-located VRE-storage resource contains symmetric charge/discharge power capacity with charging capacity equal to discharging capacity (e.g. lithium-ion battery storage). Note that if STORACCHARGE = 1, STORACDISCHARGE = 1.
STORACCHARGE = 2: If the co-located VRE-storage resource has asymmetric charge capacities using distinct processes (e.g. hydrogen electrolysis, storage, and conversion to power using fuel cell or combustion turbine).
LDSVRESTOR
{0, 1}, Flag to indicate the co-located VRE-storage resources eligible for long duration storage constraints with inter period linkage (e.g., reservoir hydro, hydrogen storage).
LDSVRESTOR = 0: Not part of set (default)
LDSVRESTOR = 1: Long duration storage resources
Existing technology capacity
Existing_Cap_MW
The existing AC grid connection capacity in MW.
Existing_Cap_MWh
The existing capacity of storage in MWh.
Existing_Cap_Inverter_MW
The existing capacity of co-located VRE-STOR resource's inverter in MW (AC).
Existing_Cap_Solar_MW
The existing capacity of co-located VRE-STOR resource's solar PV in MW (DC).
Existing_Cap_Wind_MW
The existing capacity of co-located VRE-STOR resource's wind in MW (AC).
Existing_Cap_Discharge_DC_MW
The existing discharge capacity of co-located VRE-STOR resource's storage component in MW (DC). Note that this only applies to resources where STOR_DC_DISCHARGE = 2.
Existing_Cap_Charge_DC_MW
The existing charge capacity of co-located VRE-STOR resource's storage component in MW (DC). Note that this only applies to resources where STOR_DC_CHARGE = 2.
Existing_Cap_Discharge_AC_MW
The existing discharge capacity of co-located VRE-STOR resource's storage component in MW (AC). Note that this only applies to resources where STOR_AC_DISCHARGE = 2.
Existing_Cap_Charge_AC_MW
The existing charge capacity of co-located VRE-STOR resource's storage component in MW (AC). Note that this only applies to resources where STOR_DC_CHARGE = 2.
Capacity/Energy requirements
Max_Cap_MW
-1 (default) – no limit on maximum discharge capacity of the resource. If non-negative, represents maximum allowed AC grid connection capacity in MW of the resource.
Max_Cap_MWh
-1 (default) – no limit on maximum energy capacity of the resource. If non-negative, represents maximum allowed energy capacity of storage in MWh.
Min_Cap_MW
-1 (default) – no limit on minimum discharge capacity of the resource. If non-negative, represents minimum allowed AC grid connection capacity in MW.
Min_Cap_MWh
-1 (default) – no limit on minimum energy capacity of the resource. If non-negative, represents minimum allowed energy capacity of storage in MWh.
Max_Cap_Inverter_MW
-1 (default) – no limit on maximum inverter capacity of the resource. If non-negative, represents maximum allowed inverter capacity (in MW AC) of the resource.
Max_Cap_Solar_MW
-1 (default) – no limit on maximum solar PV capacity of the resource. If non-negative, represents maximum allowed solar PV capacity (in MW DC) of the resource.
Max_Cap_Wind_MW
-1 (default) – no limit on maximum wind capacity of the resource. If non-negative, represents maximum allowed wind capacity (in MW AC) of the resource.
Max_Cap_Discharge_DC_MW
-1 (default) – no limit on maximum DC discharge capacity of the resource. If non-negative, represents maximum allowed DC discharge capacity (in MW DC) of the resource with STOR_DC_DISCHARGE = 2.
Max_Cap_Charge_DC_MW
-1 (default) – no limit on maximum DC charge capacity of the resource. If non-negative, represents maximum allowed DC charge capacity (in MW DC) of the resource with STOR_DC_CHARGE = 2.
Max_Cap_Discharge_AC_MW
-1 (default) – no limit on maximum AC discharge capacity of the resource. If non-negative, represents maximum allowed AC discharge capacity (in MW AC) of the resource with STOR_AC_DISCHARGE = 2.
Max_Cap_Charge_AC_MW
-1 (default) – no limit on maximum AC charge capacity of the resource. If non-negative, represents maximum allowed AC charge capacity (in MW AC) of the resource with STOR_AC_CHARGE = 2.
Min_Cap_Inverter_MW
-1 (default) – no limit on minimum inverter capacity of the resource. If non-negative, represents minimum allowed inverter capacity (in MW AC) of the resource.
Min_Cap_Solar_MW
-1 (default) – no limit on minimum solar PV capacity of the resource. If non-negative, represents minimum allowed solar PV capacity (in MW DC) of the resource.
Min_Cap_Wind_MW
-1 (default) – no limit on minimum wind capacity of the resource. If non-negative, represents minimum allowed wind capacity (in MW AC) of the resource.
Min_Cap_Discharge_DC_MW
-1 (default) – no limit on minimum DC discharge capacity of the resource. If non-negative, represents minimum allowed DC discharge capacity (in MW DC) of the resource with STOR_DC_DISCHARGE = 2.
Min_Cap_Charge_DC_MW
-1 (default) – no limit on minimum DC charge capacity of the resource. If non-negative, represents minimum allowed DC charge capacity (in MW DC) of the resource with STOR_DC_CHARGE = 2.
Min_Cap_Discharge_AC_MW
-1 (default) – no limit on minimum AC discharge capacity of the resource. If non-negative, represents minimum allowed AC discharge capacity (in MW AC) of the resource with STOR_AC_DISCHARGE = 2.
Min_Cap_Charge_AC_MW
-1 (default) – no limit on minimum AC charge capacity of the resource. If non-negative, represents minimum allowed AC charge capacity (in MW AC) of the resource with STOR_AC_CHARGE = 2.
Cost parameters
Inv_Cost_per_MWyr
Annualized capacity investment cost of the grid connection (/MW/year).
Inv_Cost_per_MWhyr
Annualized investment cost of the energy capacity for the co-located storage resource (/MW/year)
Fixed_OM_Cost_per_MWyr
Fixed operations and maintenance cost of the grid connection (/MW/year).
Fixed_OM_Cost_per_MWhyr
Fixed operations and maintenance cost of the energy component of the co-located storage resource. (/MWh/year).
Inv_Cost_Inverter_per_MWyr
Annualized capacity investment cost of the inverter component (/MW-AC/year).
Inv_Cost_Solar_per_MWyr
Annualized capacity investment cost of the solar PV component (/MW-DC/year).
Inv_Cost_Wind_per_MWyr
Annualized capacity investment cost of the wind component (/MW-AC/year).
Inv_Cost_Discharge_DC_per_MWyr
Annualized capacity investment cost for the discharging portion of a storage technology with STOR_DC_DISCHARGE = 2 (/MW-DC/year).
Inv_Cost_Charge_DC_per_MWyr
Annualized capacity investment cost for the charging portion of a storage technology with STOR_DC_CHARGE = 2 (/MW-DC/year).
Inv_Cost_Discharge_AC_per_MWyr
Annualized capacity investment cost for the discharging portion of a storage technology with STOR_AC_DISCHARGE = 2 (/MW-AC/year).
Inv_Cost_Charge_AC_per_MWyr
Annualized capacity investment cost for the charging portion of a storage technology with STOR_AC_CHARGE = 2 (/MW-AC/year).
Fixed_OM_Inverter_Cost_per_MWyr
Fixed operations and maintenance cost of the inverter component (/MW-AC/year).
Fixed_OM_Solar_Cost_per_MWyr
Fixed operations and maintenance cost of the solar PV component (/MW-DC/year).
Fixed_OM_Wind_Cost_per_MWyr
Fixed operations and maintenance cost of the wind component (/MW-AC/year).
Fixed_OM_Cost_Discharge_DC_per_MWyr
Fixed operations and maintenance cost of the discharging component of a storage technology with STOR_DC_DISCHARGE = 2 (/MW-DC/year).
Fixed_OM_Cost_Charge_DC_per_MWyr
Fixed operations and maintenance cost of the charging component of a storage technology with STOR_DC_CHARGE = 2 (/MW-DC/year).
Fixed_OM_Cost_Discharge_AC_per_MWyr
Fixed operations and maintenance cost of the discharging component of a storage technology with STOR_AC_DISCHARGE = 2 (/MW-AC/year).
Fixed_OM_Cost_Charge_AC_per_MWyr
Fixed operations and maintenance cost of the charging component of a storage technology with STOR_AC_CHARGE = 2 (/MW-AC/year).
Var_OM_Cost_per_MWh_Solar
Variable operations and maintenance cost of the solar PV component (multiplied by the inverter efficiency for AC terms) (/MWh).
Var_OM_Cost_per_MWh_Wind
Variable operations and maintenance cost of the wind component (/MWh).
Var_OM_Cost_per_MWh_Discharge_DC
Variable operations and maintenance cost of the discharging component of a storage technology with STOR_DC_DISCHARGE = 2 (multiplied by the inverter efficiency for AC terms) (/MWh).
Var_OM_Cost_per_MWh_Charge_DC
Variable operations and maintenance cost of the charging component of a storage technology with STOR_DC_CHARGE = 2 (divided by the inverter efficiency for AC terms) (/MWh).
Var_OM_Cost_per_MWh_Discharge_AC
Variable operations and maintenance cost of the discharging component of a storage technology with STOR_AC_DISCHARGE = 2 (/MWh).
Var_OM_Cost_per_MWh_Charge_AC
Variable operations and maintenance cost of the charging component of a storage technology with STOR_AC_CHARGE = 2 (/MWh).
Technical performance parameters
Self_Disch
[0,1], The power loss of storage component of each resource per hour (fraction loss per hour).
EtaInverter
[0,1], Inverter efficiency representing losses from converting DC to AC power and vice versa for each technology
InverterRatioSolar
-1 (default) - no required ratio between solar PV capacity built to inverter capacity built. If non-negative, represents the ratio of solar PV capacity built to inverter capacity built.
InverterRatioWind
-1 (default) - no required ratio between wind capacity built to grid connection capacity built. If non-negative, represents the ratio of wind capacity built to grid connection capacity built.
Power_to_Energy_AC
The power to energy conversion for the storage component for AC discharging/charging of symmetric storage resources.
Power_to_Energy_DC
The power to energy conversion for the storage component for DC discharging/charging of symmetric storage resources.
Eff_Up_DC
[0,1], Efficiency of DC charging storage – applies to storage technologies (all STOR types).
Eff_Down_DC
[0,1], Efficiency of DC discharging storage – applies to storage technologies (all STOR types).
Eff_Up_AC
[0,1], Efficiency of AC charging storage – applies to storage technologies (all STOR types).
Eff_Down_AC
[0,1], Efficiency of AC discharging storage – applies to storage technologies (all STOR types).
In addition to the files described above, the resources folder contains the following files that are used to specify policy-related parameters for specific resources:
Resource_energy_share_requirement.csv
Resource_minimum_capacity_requirement.csv
Resource_maximum_capacity_requirement.csv
Resource_capacity_reserve_margin.csv
Note
These files are optional and can be omitted if no policy-related parameters are specified in the settings file. Also, not all the resources need to be included in these files, only those for which the policy applies.
The following table describes the columns in each of these four files.
Warning
The first column of each file must contain the resource name corresponding to a resource in one of the resource data files described above. Note that the order of resources in the policy files is not important.
This policy is applied when if EnergyShareRequirement > 0 in the settings file. * corresponds to the ith row of the file Energy_share_requirement.csv.
Resource name corresponding to a resource in one of the resource data files described above.
MinCap\*
Flag to indicate which resources are considered for the Minimum Capacity Requirement constraint.
co-located VRE-STOR resources only
MinCapSolar_*
Eligibility of resources with a solar PV component (multiplied by the inverter efficiency for AC terms) to participate in Minimum Technology Carveout constraint.
MinCapWind_*
Eligibility of resources with a wind component to participate in Minimum Technology Carveout constraint (AC terms).
MinCapStor_*
Eligibility of resources with a storage component to participate in Minimum Technology Carveout constraint (discharge capacity in AC terms).
This policy is applied when if MaxCapReq = 1 in the settings file. * corresponds to the ith row of the file Maximum_capacity_requirement.csv.
Resource name corresponding to a resource in one of the resource data files described above.
MaxCap\*
Flag to indicate which resources are considered for the Maximum Capacity Requirement constraint.
co-located VRE-STOR resources only
MaxCapSolar_*
Eligibility of resources with a solar PV component (multiplied by the inverter efficiency for AC terms) to participate in Maximum Technology Carveout constraint.
MaxCapWind_*
Eligibility of resources with a wind component to participate in Maximum Technology Carveout constraint (AC terms).
MaxCapStor_*
Eligibility of resources with a storage component to participate in Maximum Technology Carveout constraint (discharge capacity in AC terms).
This policy is applied when if CapacityReserveMargin > 0 in the settings file. * corresponds to the ith row of the file Capacity_reserve_margin.csv.
In addition to the files described above, the resources folder can contain additional files that are used to specify attributes for specific resources and modules. Currently, the following files are supported:
Resource_multistage_data.csv: mandatory if MultiStage = 1 in the settings file
<!– 2) Resource_piecewisefuel_usage.csv –>
Warning
The first column of each additional module file must contain the resource name corresponding to a resource in one of the resource data files described above. Note that the order of resources in these files is not important.
This file is mandatory if MultiStage = 1 in the settings file.
Column Name
Description
Resource
Resource name corresponding to a resource in one of the resource data files described above.
Capital_Recovery_Period
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs. Note that for co-located VRE-STOR resources, this value pertains to the grid connection.
Lifetime
Lifetime (in years) used for determining endogenous retirements of newly built capacity. Note that the same lifetime is used for each component of a co-located VRE-STOR resource.
Min_Retired_Cap_MW
Minimum required discharge capacity retirements in the current model period. This field can be used to enforce lifetime retirements of existing capacity. Note that for co-located VRE-STOR resources, this value pertains to the grid connection.
Min_Retired_Energy_Cap_MW
Minimum required energy capacity retirements in the current model period. This field can be used to enforce lifetime retirements of existing energy capacity. Note that for co-located VRE-STOR resources, this value pertains to the storage component.
Min_Retired_Charge_Cap_MW
Minimum required energy capacity retirements in the current model period. This field can be used to enforce lifetime retirements of existing charge capacity.
Contribute_Min_Retirement
{0, 1}, Flag to indicate whether the (retrofitting) resource can contribute to the minimum retirement requirement.
co-located VRE-STOR resources only
Capital_Recovery_Period_DC
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the inverter component.
Capital_Recovery_Period_Solar
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the solar PV component.
Capital_Recovery_Period_Wind
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the wind component.
Capital_Recovery_PeriodDischargeDC
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the discharge DC component when STOR_DC_DISCHARGE = 2.
Capital_Recovery_PeriodChargeDC
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the charge DC component when STOR_DC_CHARGE = 2.
Capital_Recovery_PeriodDischargeAC
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the discharge AC component when STOR_AC_DISCHARGE = 2.
Capital_Recovery_PeriodChargeAC
Capital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the charge AC component when STOR_AC_CHARGE = 2.
Min_Retired_Cap_Inverter_MW
Minimum required inverter capacity retirements in the current model period. This field can be used to enforce lifetime retirements of existing capacity.
Min_Retired_Cap_Solar_MW
Minimum required solar capacity retirements in the current model period. This field can be used to enforce lifetime retirements of existing capacity.
Min_Retired_Cap_Wind_MW
Minimum required wind capacity retirements in the current model period. This field can be used to enforce lifetime retirements of existing capacity.
Min_Retired_Cap_DischargeDC\MW
Minimum required discharge capacity retirements in the current model period for storage resources with STOR_DC_DISCHARGE = 2. This field can be used to enforce lifetime retirements of existing capacity.
Min_Retired_Cap_ChargeDC\MW
Minimum required charge capacity retirements in the current model period for storage resources with STOR_DC_CHARGE = 2. This field can be used to enforce lifetime retirements of existing capacity.
Min_Retired_Cap_DischargeAC\MW
Minimum required discharge capacity retirements in the current model period for storage resources with STOR_AC_DISCHARGE = 2. This field can be used to enforce lifetime retirements of existing capacity.
Min_Retired_Cap_ChargeAC\MW
Minimum required charge capacity retirements in the current model period for storage resources with STOR_AC_CHARGE = 2. This field can be used to enforce lifetime retirements of existing capacity.
WACC_DC
The line-specific weighted average cost of capital for the inverter component.
WACC_Solar
The line-specific weighted average cost of capital for the solar PV component.
WACC_Wind
The line-specific weighted average cost of capital for the wind component.
WACC_Discharge_DC
The line-specific weighted average cost of capital for the discharging DC storage component with STOR_DC_DISCHARGE = 2.
WACC_Charge_DC
The line-specific weighted average cost of capital for the charging DC storage component with STOR_DC_CHARGE = 2.
WACC_Discharge_AC
The line-specific weighted average cost of capital for the discharging AC storage component with STOR_AC_DISCHARGE = 2.
WACC_Charge_AC
The line-specific weighted average cost of capital for the charging AC storage component with STOR_AC_CHARGE = 2.
This file contains the time-series of capacity factors / availability of each resource included in the resource .csv file in the resources folder for each time step (e.g. hour) modeled.
• First column: The first column contains the time index of each row (starting in the second row) from 1 to N.
• Second column onwards: Resources are listed from the second column onward with headers matching each resource name in the resource .csv file in the resources folder in any order. The availability for each resource at each time step is defined as a fraction of installed capacity and should be between 0 and 1. Note that for this reason, resource names specified in the resource .csv file must be unique. Note that for Hydro reservoir resources (i.e. Hydro.csv), values in this file correspond to inflows (in MWhs) to the hydro reservoir as a fraction of installed power capacity, rather than hourly capacity factor. Note that for co-located VRE and storage resources, solar PV and wind resource profiles should not be located in this file but rather in separate variability files (these variabilities can be in the Generators_variability.csv if time domain reduction functionalities will be utilized because the time domain reduction functionalities will separate the files after the clustering is completed).
|Self_Disch |[0,1], The power loss of storage technologies per hour (fraction loss per hour)- only applies to storage techs. Note that for co-located VRE-STOR resources, this value applies to the storage component of each resource.| |Min_Power |[0,1], The minimum generation level for a unit as a fraction of total capacity. This value cannot be higher than the smallest time-dependent CF value for a resource in Generators_variability.csv. Applies to thermal plants, and reservoir hydro resource (HYDRO = 1).| |Ramp_Up_Percentage |[0,1], Maximum increase in power output from between two periods (typically hours), reported as a fraction of nameplate capacity. Applies to thermal plants, and reservoir hydro resource (HYDRO = 1).| |Ramp_Dn_Percentage |[0,1], Maximum decrease in power output from between two periods (typically hours), reported as a fraction of nameplate capacity. Applies to thermal plants, and reservoir hydro resource (HYDRO = 1).| |Eff_Up |[0,1], Efficiency of charging storage – applies to storage technologies (all STOR types except co-located storage resources).| |Eff_Down |[0,1], Efficiency of discharging storage – applies to storage technologies (all STOR types except co-located storage resources). |
|Min_Duration |Specifies the minimum ratio of installed energy to discharged power capacity that can be installed. Applies to STOR types 1 and 2 (hours). Note that for co-located VRE-STOR resources, this value does not apply. | |Max_Duration |Specifies the maximum ratio of installed energy to discharged power capacity that can be installed. Applies to STOR types 1 and 2 (hours). Note that for co-located VRE-STOR resources, this value does not apply. | |Max_Flexible_Demand_Delay |Maximum number of hours that demand can be deferred or delayed. Applies to resources with FLEX type 1 (hours). | |Max_Flexible_Demand_Advance |Maximum number of hours that demand can be scheduled in advance of the original schedule. Applies to resources with FLEX type 1 (hours). | |Flexible_Demand_Energy_Eff |[0,1], Energy efficiency associated with time shifting demand. Represents energy losses due to time shifting (or 'snap back' effect of higher consumption due to delay in use) that may apply to some forms of flexible demand. Applies to resources with FLEX type 1 (hours). For example, one may need to pre-cool a building more than normal to advance demand. |
This file contains the time-series of capacity factors / availability of the solar PV component (DC capacity factors) of each co-located resource included in the Vre_and_stor_data.csv file for each time step (e.g. hour) modeled.
• first column: The first column contains the time index of each row (starting in the second row) from 1 to N.
• Second column onwards: Resources are listed from the second column onward with headers matching each resource name in the Vre_stor.csv files in any order. The availability for each resource at each time step is defined as a fraction of installed capacity and should be between 0 and 1. Note that for this reason, resource names specified in all the resource .csv files must be unique.
This file contains the time-series of capacity factors / availability of the wind component (AC capacity factors) of each co-located resource included in the Vre_and_stor_data.csv file for each time step (e.g. hour) modeled.
• First column: The first column contains the time index of each row (starting in the second row) from 1 to N.
• Second column onwards: Resources are listed from the second column onward with headers matching each resource name in the Vre_stor.csv files in any order. The availability for each resource at each time step is defined as a fraction of installed capacity and should be between 0 and 1. Note that for this reason, resource names specified in all the resource .csv files must be unique.
This file includes parameter inputs needed to model time-dependent procurement of regulation and spinning reserves. This file is needed if OperationalReserves flag is activated in the YAML file genx_settings.yml.
[0,1], Regulation requirement as a percent of time-dependent demand; here demand is the total across all model zones.
Reg_Req_Percent_VRE
[0,1], Regulation requirement as a percent of time-dependent wind and solar generation (summed across all model zones).
Rsv_Req_Percent_Demand [0,1],
Spinning up or contingency reserve requirement as a percent of time-dependent demand (which is summed across all zones).
Rsv_Req_Percent_VRE
[0,1], Spinning up or contingency reserve requirement as a percent of time-dependent wind and solar generation (which is summed across all zones).
Unmet_Rsv_Penalty_Dollar_per_MW
Penalty for not meeting time-dependent spinning reserve requirement (/MW per time step).
Dynamic_Contingency
Flags to include capacity (generation or transmission) contingency to be added to the spinning reserve requirement.
Dynamic_Contingency
= 1: contingency set to be equal to largest installed thermal unit (only applied when UCommit = 1).
= 2: contingency set to be equal to largest committed thermal unit each time period (only applied when UCommit = 1).
Static_Contingency_MW
A fixed static contingency in MW added to reserve requirement. Applied when UCommit = 1 and DynamicContingency = 0, or when UCommit = 2. Contingency term not included in operating reserve requirement when this value is set to 0 and DynamicContingency is not active.
This file contains inputs specifying minimum energy share requirement policies, such as Renewable Portfolio Standard (RPS) or Clean Energy Standard (CES) policies. This file is needed if parameter EnergyShareRequirement has a non-zero value in the YAML file genx_settings.yml.
Note: this file should use the same region name as specified in the the resource .csv file (inside the Resource).
[0,1], Energy share requirements as a share of zonal demand (calculated on an annual basis). * represents the number of the ESR constraint, given by the number of ESR_* columns in the Energy_share_requirement.csv file.
This file contains inputs specifying CO2 emission limits policies (e.g. emissions cap and permit trading programs). This file is needed if CO2Cap flag is activated in the YAML file genx_settings.yml. CO2Cap flag set to 1 represents mass-based (tCO2 ) emission target. CO2Cap flag set to 2 is specified when emission target is given in terms of rate (tCO2/MWh) and is based on total demand met. CO2Cap flag set to 3 is specified when emission target is given in terms of rate (tCO2 /MWh) and is based on total generation.
If a zone is eligible for the emission limit constraint, then this column is set to 1, else 0.
CO_2_Max_tons_MWh_*
Emission limit in terms of rate
CO_2_Max_Mtons_*
Emission limit in absolute values, in Million of tons
where in the above inputs, * represents the number of the emission limit constraints. For example, if the model has 2 emission limit constraints applied separately for 2 zones, the above CSV file will have 2 columns for specifying emission limit in terms on rate: CO_2_Max_tons_MWh_1 and CO_2_Max_tons_MWh_2.
This file contains the regional capacity reserve margin requirements. This file is needed if parameter CapacityReserveMargin has a non-zero value in the YAML file genx_settings.yml.
Note: this file should use the same region name as specified in the resource .csv file (inside the Resource).
This file contains the minimum capacity carve-out requirement to be imposed (e.g. a storage capacity mandate or offshore wind capacity mandate). This file is needed if the MinCapReq flag has a non-zero value in the YAML file genx_settings.yml.
Index of the minimum capacity carve-out requirement.
Constraint_Description
Names of minimum capacity carve-out constraints; not to be read by model, but used as a helpful notation to the model user.
Min_MW
minimum capacity requirement [MW]
Some of the columns specified in the input files in Section 2.2 and 2.1 are not used in the GenX model formulation. These columns are necessary for interpreting the model outputs and used in the output module of the GenX.
This contains the maximum capacity limits to be imposed (e.g. limits on total deployment of solar, wind, or batteries in the system as a whole or in certain collections of zones). It is required if the MaxCapReq flag has a non-zero value in genx_settings.yml.
Names of maximum capacity limit; not to be read by model, but used as a helpful notation to the model user.
Max_MW
maximum capacity limit [MW]
Some of the columns specified in the input files in Section 2.2 and 2.1 are not used in the GenX model formulation. These columns are necessary for interpreting the model outputs and used in the output module of the GenX.
This file contains the settings parameters required to run the Method of Morris algorithm in GenX. This file is needed if the MethodofMorris flag is ON in the YAML file genx_settings.yml.
This column contains unique names of resources available to the model. Resources can include generators, storage, and flexible or time shiftable demand/loads.
Zone
Integer representing zone number where the resource is located.
Lower_bound
Percentage lower deviation from the nominal value
Upper_bound
Percentage upper deviation from the nominal value
Parameter
Column from the resource .csv file (inside the Resource) containing uncertain parameters
Group
Group the uncertain parameters that will be changed all at once while performing the sensitivity analysis. For example, if the fuel price of natural gas is uncertain, all generators consuming natural gas should be in the same group. Group name is user defined
p_steps
Number of steps between upper and lower bound
total_num_trajectory
Total number of trakectories through the design matrix
num_trajectory
Selected number of trajectories throigh the design matrix
len_design_mat
Length of the design matrix
policy
Name of the policy
Notes
Upper and lower bounds are specified in terms of percentage deviation from the nominal value.
Percentage variation for uncertain parameters in a given group is identical. For example, if solar cluster 1 and solar cluster 2 both belong to the ‘solar’ group, their Lowerbound and Upperbound must be identical
P_steps should at least be = 1\%, i.e., Upper_bound – Lower_bound $<$ p_steps
P_steps for parameters in one group must be identical
Total_num_trajectory should be around 3 to 4 times the total number of uncertain parameters
num_trajectory should be approximately equal to the total number of uncertain parameters
len_design_mat should be 1.5 to 2 times the total number of uncertain parameters
Higher number of num_trajectory and lendesignmat would lead to higher accuracy
Upper and lower bounds should be specified for all the resources included in the resource .csv file (inside the Resource). If a parameter related to a particular resource is not uncertain, specify upper bound = lower bound = 0.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
The table below summarizes the units of each output variable reported as part of the various CSV files produced after each model run. The reported units are also provided. If a result file includes time-dependent values, the value will not include the hour weight in it. An annual sum ("AnnualSum") column/row will be provided whenever it is possible (e.g., emissions.csv).
Reports CO2 emissions by zone at each hour; an annual sum row will be provided. If any emission cap is present, emission prices each zone faced by each cap will be copied on top of this table with the following strucutre.
Marginal CO2 abatement cost associated with constraint on maximum annual CO2 emissions; will be same across zones if CO2 emissions constraint is applied for the entire region and not zone-wise
Reports marginal electricity price for each model zone and time step. Marginal electricity price is equal to the dual variable of the load balance constraint. If GenX is configured as a mixed integer linear program, then this output is only generated if WriteShadowPrices flag is activated. If configured as a linear program (i.e. linearized unit commitment or economic dispatch) then output automatically available.
Optimality gap at termination in case of a mixed-integer linear program (MIP gap); when using Gurobi, the lower bound and MIP gap is reported excluding constant terms (E.g. fixed cost of existing generators that cannot be retired) in the objective function and hence may not be directly usable.
This file includes the time-dependent capacity value calculated for each generator. GenX will print this file only if the capacity reserve margin constraints are modeled through the setting file. Each row of the file (excluding the header) corresponds to a generator specified in the inputs. Each column starting from the t1 to the second last one stores the result of capacity obligation provided in each hour divided by the total capacity. Thus the number is unitless. If the capacity margin reserve is not binding for one hour, GenX will return zero. The last column specified the name of the corresponding capacity reserve constraint. Note that, if the user calculates the hour-weight-averaged capacity value for each generator using data of the binding hours, the result is what RTO/ISO call capacity credit.
<!– #### 2.2 ExportRevenue.csv
This file includes the export revenue in $ of each zone. GenX will print this file only when a network is present and Locational Marginal Price (LMP) data is available to the GenX. The Total row includes the time-step-weighted summation of the time-dependent values shown below. For each time-step, the export revenue is calculated as the net outbound powerflow multiplied by the LMP. It is noteworthy that this export revenue is already part of the generation revenue, and the user should not double count.
This file includes the import cost in $ of each zone. GenX will print this file only when a network is present and Locational Marginal Price (LMP) data is available to the GenX. The Total row includes the time-step -weighted summation of the time-dependent values shown below. For each time step, the import cost is calculated as the net inbound powerflow multiplied by the LMP. It is noteworthy that this import cost is already part of the load payment, and the user should not double count. –>
This file includes the shadow prices of the capacity reserve margin constraints. GenX will print this file only when capacity reserve margin is modeled and the shadow price can be obtained form the solver, as described earlier. Each row (except the header) corresponds to a capacity reserve margin constraint, and each column corresponds to an time step. As a reminder, GenX models the capacity reserve margin (aka capacity market) at the time-dependent level, and each constraint either stands for an overall market or a locality constraint.
This file includes the capacity revenue earned by each generator listed in the input file. GenX will print this file only when capacity reserve margin is modeled and the shadow price can be obtained form the solver. Each row corresponds to a generator, and each column starting from the 6th to the second last is the total revenue from each capacity reserve margin constraint. The revenue is calculated as the capacity contribution of each time steps multiplied by the shadow price, and then the sum is taken over all modeled time steps. The last column is the total revenue received from all capacity reserve margin constraints. As a reminder, GenX models the capacity reserve margin (aka capacity market) at the time-dependent level, and each constraint either stands for an overall market or a locality constraint.
This file includes the renewable/clean energy credit price of each modeled RPS/CES constraint. GenX will print this file only when RPS/CES is modeled and the shadow price can be obtained form the solver. The unit is /MWh.
This file includes the renewable/clean credit revenue earned by each generator listed in the input file. GenX will print this file only when RPS/CES is modeled and the shadow price can be obtained form the solver. Each row corresponds to a generator, and each column starting from the 6th to the second last is the total revenue earned from each RPS constraint. The revenue is calculated as the total annual generation (if elgible for the corresponding constraint) multiplied by the RPS/CES price. The last column is the total revenue received from all constraint. The unit is $.
This file includes subsidy revenue earned if a generator specified Min_Cap is provided in the input file. GenX will print this file only the shadow price can be obtained form the solver. Do not confuse this with the Minimum Capacity Carveout constraint, which is for a subset of generators, and a separate revenue term will be calculated in other files. The unit is $.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
The table below summarizes the units of each output variable reported as part of the various CSV files produced after each model run. The reported units are also provided. If a result file includes time-dependent values, the value will not include the hour weight in it. An annual sum ("AnnualSum") column/row will be provided whenever it is possible (e.g., emissions.csv).
Reports CO2 emissions by zone at each hour; an annual sum row will be provided. If any emission cap is present, emission prices each zone faced by each cap will be copied on top of this table with the following strucutre.
Marginal CO2 abatement cost associated with constraint on maximum annual CO2 emissions; will be same across zones if CO2 emissions constraint is applied for the entire region and not zone-wise
Reports marginal electricity price for each model zone and time step. Marginal electricity price is equal to the dual variable of the load balance constraint. If GenX is configured as a mixed integer linear program, then this output is only generated if WriteShadowPrices flag is activated. If configured as a linear program (i.e. linearized unit commitment or economic dispatch) then output automatically available.
Optimality gap at termination in case of a mixed-integer linear program (MIP gap); when using Gurobi, the lower bound and MIP gap is reported excluding constant terms (E.g. fixed cost of existing generators that cannot be retired) in the objective function and hence may not be directly usable.
This file includes the time-dependent capacity value calculated for each generator. GenX will print this file only if the capacity reserve margin constraints are modeled through the setting file. Each row of the file (excluding the header) corresponds to a generator specified in the inputs. Each column starting from the t1 to the second last one stores the result of capacity obligation provided in each hour divided by the total capacity. Thus the number is unitless. If the capacity margin reserve is not binding for one hour, GenX will return zero. The last column specified the name of the corresponding capacity reserve constraint. Note that, if the user calculates the hour-weight-averaged capacity value for each generator using data of the binding hours, the result is what RTO/ISO call capacity credit.
<!– #### 2.2 ExportRevenue.csv
This file includes the export revenue in $ of each zone. GenX will print this file only when a network is present and Locational Marginal Price (LMP) data is available to the GenX. The Total row includes the time-step-weighted summation of the time-dependent values shown below. For each time-step, the export revenue is calculated as the net outbound powerflow multiplied by the LMP. It is noteworthy that this export revenue is already part of the generation revenue, and the user should not double count.
This file includes the import cost in $ of each zone. GenX will print this file only when a network is present and Locational Marginal Price (LMP) data is available to the GenX. The Total row includes the time-step -weighted summation of the time-dependent values shown below. For each time step, the import cost is calculated as the net inbound powerflow multiplied by the LMP. It is noteworthy that this import cost is already part of the load payment, and the user should not double count. –>
This file includes the shadow prices of the capacity reserve margin constraints. GenX will print this file only when capacity reserve margin is modeled and the shadow price can be obtained form the solver, as described earlier. Each row (except the header) corresponds to a capacity reserve margin constraint, and each column corresponds to an time step. As a reminder, GenX models the capacity reserve margin (aka capacity market) at the time-dependent level, and each constraint either stands for an overall market or a locality constraint.
This file includes the capacity revenue earned by each generator listed in the input file. GenX will print this file only when capacity reserve margin is modeled and the shadow price can be obtained form the solver. Each row corresponds to a generator, and each column starting from the 6th to the second last is the total revenue from each capacity reserve margin constraint. The revenue is calculated as the capacity contribution of each time steps multiplied by the shadow price, and then the sum is taken over all modeled time steps. The last column is the total revenue received from all capacity reserve margin constraints. As a reminder, GenX models the capacity reserve margin (aka capacity market) at the time-dependent level, and each constraint either stands for an overall market or a locality constraint.
This file includes the renewable/clean energy credit price of each modeled RPS/CES constraint. GenX will print this file only when RPS/CES is modeled and the shadow price can be obtained form the solver. The unit is /MWh.
This file includes the renewable/clean credit revenue earned by each generator listed in the input file. GenX will print this file only when RPS/CES is modeled and the shadow price can be obtained form the solver. Each row corresponds to a generator, and each column starting from the 6th to the second last is the total revenue earned from each RPS constraint. The revenue is calculated as the total annual generation (if elgible for the corresponding constraint) multiplied by the RPS/CES price. The last column is the total revenue received from all constraint. The unit is $.
This file includes subsidy revenue earned if a generator specified Min_Cap is provided in the input file. GenX will print this file only the shadow price can be obtained form the solver. Do not confuse this with the Minimum Capacity Carveout constraint, which is for a subset of generators, and a separate revenue term will be calculated in other files. The unit is $.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
diff --git a/previews/PR662/User_Guide/multi_stage_input/index.html b/previews/PR662/User_Guide/multi_stage_input/index.html
index 437b70c3b5..8e98189057 100644
--- a/previews/PR662/User_Guide/multi_stage_input/index.html
+++ b/previews/PR662/User_Guide/multi_stage_input/index.html
@@ -1,5 +1,5 @@
-Multi-stage Model · GenX
This section describes the available features, inputs and model components related to formulating and solving multi-stage investment planning problems. Two different types of multi-stage problems can be setup:
Perfect foresight: A single multi-stage investment planning problem that simultaneously optimizes capacity and operations across all specified investment stages
Myopic: Sequential solution of single-stage investment planning for each investment stage, where capacity additions and retirements from the previous stages are used to determine initial (or existing) capacity at the beginning of the current stage.
The table below summarizes the key differences in the two model setups.
Instead of one set of input files, there is one directory of input files that needs to be provided for each planning period or stage (e.g., “inputs/inputs_p1/” for the first period “inputs/inputs_p2/” for the second period, etc.). Below we list the additional parameters that must be provided in the corresponding stage-specific input files to instantiate a multi-stage planning problem.
Resourcemultistagedata.csv files
Min_Retired_Cap_MW
Minimum capacity in MW that must retire in this planning stage. Note that for the co-located VRE-STOR module, this value represents the grid connection component.
Min_Retired_Energy_Cap_MW
Minimum energy capacity in MW that must retire in this planning stage. Note that for the co-located VRE-STOR module, this value represents the storage component.
Min_Retired_Charge_Cap_MW
Minimum charge capacity in MW that must retire in this planning stage.
Lifetime
The operational lifespan in years of this technology after which it must be retired.
Capital_Recovery_Period
The technology-specific period in years over which initial capital costs must be recovered. Note that for the co-located VRE-STOR module, this value represents the grid connection component.
WACC
The technology-specific weighted average cost of capital. Note that for the co-located VRE-STOR module, this value represents the grid connection component.
Contribute_Min_Retirement
{0, 1}, Flag to indicate whether the (retrofitting) resource can contribute to the minimum retirement requirement.
co-located VRE-STOR resources only
Min_Retired_Cap_Inverter_MW
Minimum inverter capacity in MW AC that must retire in this plannig stage.
Min_Retired_Cap_Solar_MW
Minimum solar PV capacity in MW DC that must retire in this plannig stage.
Min_Retired_Cap_Wind_MW
Minimum wind capacity in MW AC that must retire in this plannig stage.
Min_Retired_Cap_DischargeDC\MW
Minimum storage DC discharge capacity that must retire in this planning stage with STOR_DC_DISCHARGE = 2.
Min_Retired_Cap_ChargeDC\MW
Minimum storage DC charge capacity that must retire in this planning stage with STOR_DC_CHARGE = 2.
Min_Retired_Cap_DischargeAC\MW
Minimum storage AC discharge capacity that must retire in this planning stage with STOR_AC_DISCHARGE = 2.
Min_Retired_Cap_ChargeAC\MW
Minimum storage AC charge capacity that must retire in this planning stage with STOR_AC_CHARGE = 2.
Capital_Recovery_Period_DC
The technology-specific period in years over which initial capital costs for the inverter component must be recovered.
Capital_Recovery_Period_Solar
The technology-specific period in years over which initial capital costs for the solar PV component must be recovered.
Capital_Recovery_Period_Wind
The technology-specific period in years over which initial capital costs for the wind component must be recovered.
Capital_Recovery_PeriodDischargeDC
The technology-specific period in years over which initial capital costs for the storage DC discharge component must be recovered when STOR_DC_DISCHARGE = 2.
Capital_Recovery_PeriodChargeDC
The technology-specific period in years over which initial capital costs for the storage DC charge component must be recovered when STOR_DC_CHARGE = 2.
Capital_Recovery_PeriodDischargeAC
The technology-specific period in years over which initial capital costs for the storage AC discharge component must be recovered when STOR_AC_DISCHARGE = 2.
Capital_Recovery_PeriodChargeAC
The technology-specific period in years over which initial capital costs for the storage AC charge component must be recovered when STOR_DC_CHARGE = 2.
WACC_DC
The line-specific weighted average cost of capital for the inverter component.
WACC_Solar
The line-specific weighted average cost of capital for the solar PV component.
WACC_Wind
The line-specific weighted average cost of capital for the wind component.
WACC_Discharge_DC
The line-specific weighted average cost of capital for the discharging DC storage component with STOR_DC_DISCHARGE = 2.
WACC_Charge_DC
The line-specific weighted average cost of capital for the charging DC storage component with STOR_DC_CHARGE = 2.
WACC_Discharge_AC
The line-specific weighted average cost of capital for the discharging AC storage component with STOR_AC_DISCHARGE = 2.
WACC_Charge_AC
The line-specific weighted average cost of capital for the charging AC storage component with STOR_AC_CHARGE = 2.
Network.csv
Line_Max_Flow_Possible_MW
The maximum transmission capacity of the line, as opposed to Line_Max_Reinforcement_MW which now specifies the maximum expansion to the line in one stage.
Capital_Recovery_Period
The line-specific period in years over which initial capital costs must be recovered.
WACC
The line-specific weighted average cost of capital.
Allowing retrofitted capacity to not contribute to minimum retirement requirements (`myopic=0` only)
Special considerations must be taken into account when utilizing the retrofit module alongside multi-stage planning, particularly when using a non zero value for the Min_Retired_Cap_MW column in the Resource_multistage_data.csv file.
When assigning a non-zero value to the Min_Retired_Cap_MW column in the Resource_multistage_data.csv file, the user can specify whether the model should consider the retrofitted capacity to contribute to the minimum retirement requirement. This is done by setting the Contribute_Min_Retirement column to 1 for the retrofit options in the same retrofit cluster (i.e., same Retrofit_Id).
By default, the model assumes that retrofitted capacity contributes to fulfilling minimum retirement requirements.
Should users wish to exclude retrofitted capacity from contributing to minimum retirement requirements, they must set the Contribute_Min_Retirement column to 0 for all retrofit options within the same retrofit cluster (i.e., sharing the same Retrofit_Id).
It's important to note that this additional functionality is not currently supported when myopic=1. In this case, the retrofit options are only allowed to contribute to the minimum retirement requirement.
Example 1: Retrofitted capacity is allowed to contribute to the minimum retirement requirement (i.e., retrofit options in the same cluster (Retrofit_Id = 1) all have Contribute_Min_Retirement = 1):
This section describes the available features, inputs and model components related to formulating and solving multi-stage investment planning problems. Two different types of multi-stage problems can be setup:
Perfect foresight: A single multi-stage investment planning problem that simultaneously optimizes capacity and operations across all specified investment stages
Myopic: Sequential solution of single-stage investment planning for each investment stage, where capacity additions and retirements from the previous stages are used to determine initial (or existing) capacity at the beginning of the current stage.
The table below summarizes the key differences in the two model setups.
Instead of one set of input files, there is one directory of input files that needs to be provided for each planning period or stage (e.g., “inputs/inputs_p1/” for the first period “inputs/inputs_p2/” for the second period, etc.). Below we list the additional parameters that must be provided in the corresponding stage-specific input files to instantiate a multi-stage planning problem.
Resourcemultistagedata.csv files
Min_Retired_Cap_MW
Minimum capacity in MW that must retire in this planning stage. Note that for the co-located VRE-STOR module, this value represents the grid connection component.
Min_Retired_Energy_Cap_MW
Minimum energy capacity in MW that must retire in this planning stage. Note that for the co-located VRE-STOR module, this value represents the storage component.
Min_Retired_Charge_Cap_MW
Minimum charge capacity in MW that must retire in this planning stage.
Lifetime
The operational lifespan in years of this technology after which it must be retired.
Capital_Recovery_Period
The technology-specific period in years over which initial capital costs must be recovered. Note that for the co-located VRE-STOR module, this value represents the grid connection component.
WACC
The technology-specific weighted average cost of capital. Note that for the co-located VRE-STOR module, this value represents the grid connection component.
Contribute_Min_Retirement
{0, 1}, Flag to indicate whether the (retrofitting) resource can contribute to the minimum retirement requirement.
co-located VRE-STOR resources only
Min_Retired_Cap_Inverter_MW
Minimum inverter capacity in MW AC that must retire in this plannig stage.
Min_Retired_Cap_Solar_MW
Minimum solar PV capacity in MW DC that must retire in this plannig stage.
Min_Retired_Cap_Wind_MW
Minimum wind capacity in MW AC that must retire in this plannig stage.
Min_Retired_Cap_DischargeDC\MW
Minimum storage DC discharge capacity that must retire in this planning stage with STOR_DC_DISCHARGE = 2.
Min_Retired_Cap_ChargeDC\MW
Minimum storage DC charge capacity that must retire in this planning stage with STOR_DC_CHARGE = 2.
Min_Retired_Cap_DischargeAC\MW
Minimum storage AC discharge capacity that must retire in this planning stage with STOR_AC_DISCHARGE = 2.
Min_Retired_Cap_ChargeAC\MW
Minimum storage AC charge capacity that must retire in this planning stage with STOR_AC_CHARGE = 2.
Capital_Recovery_Period_DC
The technology-specific period in years over which initial capital costs for the inverter component must be recovered.
Capital_Recovery_Period_Solar
The technology-specific period in years over which initial capital costs for the solar PV component must be recovered.
Capital_Recovery_Period_Wind
The technology-specific period in years over which initial capital costs for the wind component must be recovered.
Capital_Recovery_PeriodDischargeDC
The technology-specific period in years over which initial capital costs for the storage DC discharge component must be recovered when STOR_DC_DISCHARGE = 2.
Capital_Recovery_PeriodChargeDC
The technology-specific period in years over which initial capital costs for the storage DC charge component must be recovered when STOR_DC_CHARGE = 2.
Capital_Recovery_PeriodDischargeAC
The technology-specific period in years over which initial capital costs for the storage AC discharge component must be recovered when STOR_AC_DISCHARGE = 2.
Capital_Recovery_PeriodChargeAC
The technology-specific period in years over which initial capital costs for the storage AC charge component must be recovered when STOR_DC_CHARGE = 2.
WACC_DC
The line-specific weighted average cost of capital for the inverter component.
WACC_Solar
The line-specific weighted average cost of capital for the solar PV component.
WACC_Wind
The line-specific weighted average cost of capital for the wind component.
WACC_Discharge_DC
The line-specific weighted average cost of capital for the discharging DC storage component with STOR_DC_DISCHARGE = 2.
WACC_Charge_DC
The line-specific weighted average cost of capital for the charging DC storage component with STOR_DC_CHARGE = 2.
WACC_Discharge_AC
The line-specific weighted average cost of capital for the discharging AC storage component with STOR_AC_DISCHARGE = 2.
WACC_Charge_AC
The line-specific weighted average cost of capital for the charging AC storage component with STOR_AC_CHARGE = 2.
Network.csv
Line_Max_Flow_Possible_MW
The maximum transmission capacity of the line, as opposed to Line_Max_Reinforcement_MW which now specifies the maximum expansion to the line in one stage.
Capital_Recovery_Period
The line-specific period in years over which initial capital costs must be recovered.
WACC
The line-specific weighted average cost of capital.
Allowing retrofitted capacity to not contribute to minimum retirement requirements (`myopic=0` only)
Special considerations must be taken into account when utilizing the retrofit module alongside multi-stage planning, particularly when using a non zero value for the Min_Retired_Cap_MW column in the Resource_multistage_data.csv file.
When assigning a non-zero value to the Min_Retired_Cap_MW column in the Resource_multistage_data.csv file, the user can specify whether the model should consider the retrofitted capacity to contribute to the minimum retirement requirement. This is done by setting the Contribute_Min_Retirement column to 1 for the retrofit options in the same retrofit cluster (i.e., same Retrofit_Id).
By default, the model assumes that retrofitted capacity contributes to fulfilling minimum retirement requirements.
Should users wish to exclude retrofitted capacity from contributing to minimum retirement requirements, they must set the Contribute_Min_Retirement column to 0 for all retrofit options within the same retrofit cluster (i.e., sharing the same Retrofit_Id).
It's important to note that this additional functionality is not currently supported when myopic=1. In this case, the retrofit options are only allowed to contribute to the minimum retirement requirement.
Example 1: Retrofitted capacity is allowed to contribute to the minimum retirement requirement (i.e., retrofit options in the same cluster (Retrofit_Id = 1) all have Contribute_Min_Retirement = 1):
And the case where some retrofit options contribute to the minimum retirement requirement and some do not is not currently supported and will be addressed in a future release.
Warning
If New_Build and Can_Retire are both set to 0, the model will not transfer built capacity from one stage to the next, but will instead set capacity to the value of existing capacity from the input files for each stage. Therefore, the user must ensure that the capacity is correctly set in the input files for each stage. Not following this guideline may result in incorrect or unexpected results, particularly when setting a a non-zero value for the Min_Retired_Cap_MW parameter.
A separate settings.yml file includes a list of parameters to be specified to formulate the multi-stage planning model.
multi_stage_settings.yml
NumStages
The number of model investment planning stages.
StageLengths
A list of lengths of each model stage in years (e.g., [10, 10, 10] for three stages each of length 10). Note that stages could be defined to be of varying length.
Myopic
0 = perfect foresight, 1 = myopic model (see above table)
ConvergenceTolerance
The relative optimality gap used for convergence of the dual dynamic programming algorithm. Only required when Myopic = 0
WACC
Rate used to discount non-technology-specific costs from stage to stage (i.e., the “social discount rate”).
time_domain_reduction_settings.yml
MultiStageConcatenate
Designates whether to use time domain reduction for the full set of input data together (1) or to reduce only the first stage data and apply the returned representative periods to the rest of the input data (0).
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+20_NH3_retrofit_2 │ 0 │ 0 <---------
And the case where some retrofit options contribute to the minimum retirement requirement and some do not is not currently supported and will be addressed in a future release.
Warning
If New_Build and Can_Retire are both set to 0, the model will not transfer built capacity from one stage to the next, but will instead set capacity to the value of existing capacity from the input files for each stage. Therefore, the user must ensure that the capacity is correctly set in the input files for each stage. Not following this guideline may result in incorrect or unexpected results, particularly when setting a a non-zero value for the Min_Retired_Cap_MW parameter.
A separate settings.yml file includes a list of parameters to be specified to formulate the multi-stage planning model.
multi_stage_settings.yml
NumStages
The number of model investment planning stages.
StageLengths
A list of lengths of each model stage in years (e.g., [10, 10, 10] for three stages each of length 10). Note that stages could be defined to be of varying length.
Myopic
0 = perfect foresight, 1 = myopic model (see above table)
ConvergenceTolerance
The relative optimality gap used for convergence of the dual dynamic programming algorithm. Only required when Myopic = 0
WACC
Rate used to discount non-technology-specific costs from stage to stage (i.e., the “social discount rate”).
time_domain_reduction_settings.yml
MultiStageConcatenate
Designates whether to use time domain reduction for the full set of input data together (1) or to reduce only the first stage data and apply the returned representative periods to the rest of the input data (0).
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
Set TimeDomainReduction: 1in the GenX settings for the case.
When the case is run (but before the optimization model is built), reduced time series data will be output to a folder within the case, (typically) TDR_results. Note that if the data already exists in that folder, it will not be overwritten. If a user wants to change the time domain reduction settings and try again, the folder should be deleted before the case is run.
The clustering is done according to the settings in time_domain_reduction.yml. These are described in the Inputs section of data_documentation.
Time domain clustering can only be performed on data which represents a single contiguous period: typically a year of 8760 or 8736 hours.
The header of the file Load_data.csv in the main case folder will typically look like this:
Set TimeDomainReduction: 1in the GenX settings for the case.
When the case is run (but before the optimization model is built), reduced time series data will be output to a folder within the case, (typically) TDR_results. Note that if the data already exists in that folder, it will not be overwritten. If a user wants to change the time domain reduction settings and try again, the folder should be deleted before the case is run.
The clustering is done according to the settings in time_domain_reduction.yml. These are described in the Inputs section of data_documentation.
Time domain clustering can only be performed on data which represents a single contiguous period: typically a year of 8760 or 8736 hours.
The header of the file Load_data.csv in the main case folder will typically look like this:
The second method is to use an external program to generate the reduced ('clustered') time series data. For instance, PowerGenome has a capability to construct GenX cases with clustered time series data.
Running using this method requires setting TimeDomainReduction: 0 in the GenX settings for the case.
Clustered time series data requires specifying the clustering data using three columns in Load_data.csv: Rep_Periods, Timesteps_per_Rep_Period, and Sub_Weights. For example, a problem representing a full year via 3 representative weeks, and where the first week represents one which is twice as common as the others, would look like
In this example, the first week represents a total of 26*168 = 4368 hours over a full year.
The time series data are written in single unbroken columns: in this example, the Time_Index ranges from 1 to 504.
For problems involving Long Duration Storage, a file Period_map.csv is necessary to describe how these representative periods occur throughout the modeled year.
It may be useful to perform time domain reduction (TDR) (or "clustering") on a set of inputs before using them as part of full GenX optimization task. For example, a user might want to test various TDR settings and examine the resulting clustered inputs. This can now be performed using the run_timedomainreduction! function.
$ julia --project=/home/youruser/GenX
julia> using GenX
-julia> run_timedomainreduction!("/path/to/case")
This function will obey the settings in path/to/case/settings/time_domain_reduction_settings.yml. It will output the resulting clustered time series files in the case.
Running this function will overwrite these files in the case. This is done with the expectation that the user is trying out various settings.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+julia> run_timedomainreduction!("/path/to/case")
This function will obey the settings in path/to/case/settings/time_domain_reduction_settings.yml. It will output the resulting clustered time series files in the case.
Running this function will overwrite these files in the case. This is done with the expectation that the user is trying out various settings.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
diff --git a/previews/PR662/User_Guide/running_model/index.html b/previews/PR662/User_Guide/running_model/index.html
index 62e49b7134..8fa27cc157 100644
--- a/previews/PR662/User_Guide/running_model/index.html
+++ b/previews/PR662/User_Guide/running_model/index.html
@@ -1,6 +1,6 @@
-Running the Model · GenX
When running a new case, it is recommended to create a new folder for the case outside of the GenX repository. This folder should contain all the .csv input files described in the GenX Inputs section, as well as the settings folder containing at least the genx_settings.yml and [solver_name].yml files.
Tip
Check out the Running GenX for additional information on how to run GenX and what happens when you run a case.
Once the model and the solver are set up, and once all the .csv input files are ready, GenX can be run using the following command:
$ julia --project=/path/to/GenX
+Running the Model · GenX.jl
When running a new case, it is recommended to create a new folder for the case outside of the GenX repository. This folder should contain all the .csv input files described in the GenX Inputs section, as well as the settings folder containing at least the genx_settings.yml and [solver_name].yml files.
Tip
Check out the Running GenX for additional information on how to run GenX and what happens when you run a case.
Once the model and the solver are set up, and once all the .csv input files are ready, GenX can be run using the following command:
$ julia --project=/path/to/GenX
julia> using GenX
julia> run_genx_case!("/path/to/case")
where /path/to/GenX is the path to the GenX repository, and /path/to/case is the path to the folder of the case.
Alternatively, you can create a Run.jl file with the following code:
using GenX
-run_genx_case!(dirname(@__FILE__))
and and place it in the case folder. Then, you can run the case by opening a terminal and running the following command:
$ julia --project="/path/to/GenX" /path/to/case/Run.jl
where /path/to/GenX is the path to the GenX repository, and /path/to/case is the path to the folder of the case.
The output files will be saved in the Results folder inside the case folder. Check out the GenX Outputs section for more information on the output files.
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
+run_genx_case!(dirname(@__FILE__))
and and place it in the case folder. Then, you can run the case by opening a terminal and running the following command:
$ julia --project="/path/to/GenX" /path/to/case/Run.jl
where /path/to/GenX is the path to the GenX repository, and /path/to/case is the path to the folder of the case.
The output files will be saved in the Results folder inside the case folder. Check out the GenX Outputs section for more information on the output files.
Rather than modeling policy requirements as inflexible constraints, it may be advantageous to instead allow these requirements to be violated at some predetermined cost. This is accomplished via 'slack variables,' which can be used by the model to meet a policy constraint if it cannot be met cost-effectively by normal means. Once the incremental shadow price of meeting a policy constraint rises above a cost threshold set by the user, the model will rely on the slack variable to fill any remaining gap.
Using slack variables rather than hard constraints may be useful for GenX users who wish to avoid unexpected infeasibilities resulting from policy requirements that cannot be met. Using slack variables with very high cost thresholds, users can quickly identify specific policy constraints that are effectively infeasible without causing errors.
Slack variables with lower assigned costs can also be used to model policies with built-in cost thresholds, for example a CO2 Cap with a maximum allowable carbon price of $200/ton. They can be activated for each individual policy type available in GenX, including: Capacity Reserve Margins, Energy Share Requirements, CO2 Caps, Minimum Capacity Requirements, and Maximum Capacity Requirements.
Slack variables are turned off by default in GenX, but can be automatically activated for each policy type by providing the relevant inputs. Slack variables will only be activated when the relevant policy type is itself activated in GenX_settings.yml. For some policy types, slack variables are activated by providing a new input file, while for others they are activated by modifying an existing file. Instructions for each policy type are listed below:
Slack variables for Capacity Reserve Margin constraints are created when GenX detects the presence of the file Capacity_reserve_margin_slack.csv in the Inputs folder. This file should contain two columns: one titled 'CRMConstraint' naming the individual Capacity Reserve Margin constraints in the same order in which they are listed in the first row of `Capacityreserve_margin.csv`, and a second titled 'PriceCap' containing the price thresholds for each constraint. The units for these thresholds are /MW.
Slack variables for CO2 Cap constraints are created when GenX detects the presence of the file CO2_cap_slack.csv in the Inputs folder. This file should contain two columns: one titled 'CO2CapConstraint' naming the individual CO2 Cap constraints in the same order in which they are listed in the first row of CO2_Cap.csv, and a second titled 'PriceCap' containing the price thresholds for each constraint. The units for these thresholds are /ton. The CO2 Cap slack variable itself is always in units of tons of CO2, even if the CO2 Cap is a rate-based cap.
Slack variables for Energy Share Requirement constraints are created when GenX detects the presence of the file Energy_share_requirement_slack.csv in the Inputs folder. This file should contain two columns: one titled 'ESRConstraint' naming the individual Energy Share Requirement constraints in the same order in which they are listed in the first row of `Energyshare_requirement.csv`, and a second titled 'PriceCap' containing the price thresholds for each constraint. The units for these thresholds are $/MWh.
Slack variables for Minimum Capacity Requirement constraints are created when GenX detects the presence of a column titled 'PriceCap' in the file Minimum_capacity_requirement.csv. This column contains the price thresholds for each Minimum Capacity Requirement constraint, in units of $/MW.
Slack variables for Maximum Capacity Requirement constraints are created when GenX detects the presence of a column titled 'PriceCap' in the file Maximum_capacity_requirement.csv. This column contains the price thresholds for each Maximum Capacity Requirement constraint, in units of $/MW.
By default, a policy type's result files include the shadow prices for each policy constraint. When slack variables are activated, outputs also include the final values of the slack variables (i.e. the amount by which the policy constraint was violated), and the total costs associated with those slack variables. These files are named using the convention X_prices_and_penalties.csv, where X is the name of the relevant policy type.
GenX will also print the total cost associated with each activated slack variable type in the file costs.csv.
The folder Example_Systems/SmallNewEngland/ThreeZones_Slack_Variables_Example contains examples of the input files needed to activate slack variables for each of the policy types in GenX. Running this example with a given set of policy constraints activated will generate the relevant slack variables and print their outputs.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
Rather than modeling policy requirements as inflexible constraints, it may be advantageous to instead allow these requirements to be violated at some predetermined cost. This is accomplished via 'slack variables,' which can be used by the model to meet a policy constraint if it cannot be met cost-effectively by normal means. Once the incremental shadow price of meeting a policy constraint rises above a cost threshold set by the user, the model will rely on the slack variable to fill any remaining gap.
Using slack variables rather than hard constraints may be useful for GenX users who wish to avoid unexpected infeasibilities resulting from policy requirements that cannot be met. Using slack variables with very high cost thresholds, users can quickly identify specific policy constraints that are effectively infeasible without causing errors.
Slack variables with lower assigned costs can also be used to model policies with built-in cost thresholds, for example a CO2 Cap with a maximum allowable carbon price of $200/ton. They can be activated for each individual policy type available in GenX, including: Capacity Reserve Margins, Energy Share Requirements, CO2 Caps, Minimum Capacity Requirements, and Maximum Capacity Requirements.
Slack variables are turned off by default in GenX, but can be automatically activated for each policy type by providing the relevant inputs. Slack variables will only be activated when the relevant policy type is itself activated in GenX_settings.yml. For some policy types, slack variables are activated by providing a new input file, while for others they are activated by modifying an existing file. Instructions for each policy type are listed below:
Slack variables for Capacity Reserve Margin constraints are created when GenX detects the presence of the file Capacity_reserve_margin_slack.csv in the Inputs folder. This file should contain two columns: one titled 'CRMConstraint' naming the individual Capacity Reserve Margin constraints in the same order in which they are listed in the first row of `Capacityreserve_margin.csv`, and a second titled 'PriceCap' containing the price thresholds for each constraint. The units for these thresholds are /MW.
Slack variables for CO2 Cap constraints are created when GenX detects the presence of the file CO2_cap_slack.csv in the Inputs folder. This file should contain two columns: one titled 'CO2CapConstraint' naming the individual CO2 Cap constraints in the same order in which they are listed in the first row of CO2_Cap.csv, and a second titled 'PriceCap' containing the price thresholds for each constraint. The units for these thresholds are /ton. The CO2 Cap slack variable itself is always in units of tons of CO2, even if the CO2 Cap is a rate-based cap.
Slack variables for Energy Share Requirement constraints are created when GenX detects the presence of the file Energy_share_requirement_slack.csv in the Inputs folder. This file should contain two columns: one titled 'ESRConstraint' naming the individual Energy Share Requirement constraints in the same order in which they are listed in the first row of `Energyshare_requirement.csv`, and a second titled 'PriceCap' containing the price thresholds for each constraint. The units for these thresholds are $/MWh.
Slack variables for Minimum Capacity Requirement constraints are created when GenX detects the presence of a column titled 'PriceCap' in the file Minimum_capacity_requirement.csv. This column contains the price thresholds for each Minimum Capacity Requirement constraint, in units of $/MW.
Slack variables for Maximum Capacity Requirement constraints are created when GenX detects the presence of a column titled 'PriceCap' in the file Maximum_capacity_requirement.csv. This column contains the price thresholds for each Maximum Capacity Requirement constraint, in units of $/MW.
By default, a policy type's result files include the shadow prices for each policy constraint. When slack variables are activated, outputs also include the final values of the slack variables (i.e. the amount by which the policy constraint was violated), and the total costs associated with those slack variables. These files are named using the convention X_prices_and_penalties.csv, where X is the name of the relevant policy type.
GenX will also print the total cost associated with each activated slack variable type in the file costs.csv.
The folder Example_Systems/SmallNewEngland/ThreeZones_Slack_Variables_Example contains examples of the input files needed to activate slack variables for each of the policy types in GenX. Running this example with a given set of policy constraints activated will generate the relevant slack variables and print their outputs.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
To define and solve the optimization problems, GenX relies on JuMP, a domain-specific modeling language for mathematical optimization written in Julia, and on a variety of open-source and commercial solvers. GenX supports the following solvers:
Solver related settings parameters are specified in the appropriate .yml file (e.g. highs_settings.yml, gurobi_settings.yml, etc.), which should be located in the settings folder inside the current working directory (the same settings folder where genx_settings.yml is located). Settings are specific to each solver. Check the Example_Systems folder for examples of solver settings files and parameters.
Note
GenX supplies default settings for most solver settings in the various solver-specific functions found in the src/configure_solver/ directory. To overwrite default settings, you can specify the below Solver specific settings.
The following table summarizes the solver settings parameters and their default/possible values.
Tip
Since each solver has its own set of parameters names, together with a description of the parameter, the table provides a reference to the the corresponding solver specific parameter name.
Algorithm used to solve continuous models or the root node of a MIP model. Generally, barrier method provides the fastest run times for real-world problem set.
CPLEX: CPX_PARAM_LPMETHOD - Default = 0; See link for more specifications.
Gurobi: Method - Default = -1; See link for more specifications.
clp: SolveType - Default = 5; See link for more specifications.
HiGHS: Method - Default = "choose"; See link for more specifications.
BarConvTol
Convergence tolerance for barrier algorithm.
CPLEX: CPX_PARAM_BAREPCOMP - Default = 1e-8; See link for more specifications.
Gurobi: BarConvTol - Default = 1e-8; See link for more specifications.
Feasib_Tol
All constraints must be satisfied as per this tolerance. Note that this tolerance is absolute.
CPLEX: CPX_PARAM_EPRHS - Default = 1e-6; See link for more specifications.
Gurobi: FeasibilityTol - Default = 1e-6; See link for more specifications.
clp: PrimalTolerance - Default = 1e-7; See link for more specifications.
clp: DualTolerance - Default = 1e-7; See link for more specifications.
Optimal_Tol
Reduced costs must all be smaller than Optimal_Tol in the improving direction in order for a model to be declared optimal.
CPLEX: CPX_PARAM_EPOPT - Default = 1e-6; See link for more specifications.
Gurobi: OptimalityTol - Default = 1e-6; See link for more specifications.
Pre_Solve
Controls the presolve level.
Gurobi: Presolve - Default = -1; See link for more specifications.
clp: PresolveType - Default = 5; See link for more specifications.
Crossover
Determines the crossover strategy used to transform the interior solution produced by barrier algorithm into a basic solution.
CPLEX: CPX_PARAM_SOLUTIONTYPE - Default = 2; See link for more specifications.
Gurobi: Crossover - Default = 0; See link for more specifications.
NumericFocus
Controls the degree to which the code attempts to detect and manage numerical issues.
CPLEX: CPX_PARAM_NUMERICALEMPHASIS - Default = 0; See link for more specifications.
Gurobi: NumericFocus - Default = 0; See link for more specifications.
TimeLimit
Time limit to terminate the solution algorithm, model could also terminate if it reaches MIPGap before this time.
CPLEX: CPX_PARAM_TILIM- Default = 1e+75; See link for more specifications.
Gurobi: TimeLimit - Default = infinity; See link for more specifications.
clp: MaximumSeconds - Default = -1; See link for more specifications.
MIPGap
Optimality gap in case of mixed-integer program.
CPLEX: CPX_PARAM_EPGAP- Default = 1e-4; See link for more specifications.
Gurobi: MIPGap - Default = 1e-4; See link for more specifications.
DualObjectiveLimit
When using dual simplex (where the objective is monotonically changing), terminate when the objective exceeds this limit.
clp: DualObjectiveLimit - Default = 1e308; See link for more specifications.
MaximumIterations
Terminate after performing this number of simplex iterations.
clp: MaximumIterations - Default = 2147483647; See link for more specifications.
LogLevel
Set to 1, 2, 3, or 4 for increasing output. Set to 0 to disable output.
clp: logLevel - Default = 1; See link for more specifications.
cbc: logLevel - Default = 1; See link for more specifications.
InfeasibleReturn
Set to 1 to return as soon as the problem is found to be infeasible (by default, an infeasibility proof is computed as well).
clp: InfeasibleReturn - Default = 0; See link for more specifications.
To define and solve the optimization problems, GenX relies on JuMP, a domain-specific modeling language for mathematical optimization written in Julia, and on a variety of open-source and commercial solvers. GenX supports the following solvers:
Solver related settings parameters are specified in the appropriate .yml file (e.g. highs_settings.yml, gurobi_settings.yml, etc.), which should be located in the settings folder inside the current working directory (the same settings folder where genx_settings.yml is located). Settings are specific to each solver. Check the Example_Systems folder for examples of solver settings files and parameters.
Note
GenX supplies default settings for most solver settings in the various solver-specific functions found in the src/configure_solver/ directory. To overwrite default settings, you can specify the below Solver specific settings.
The following table summarizes the solver settings parameters and their default/possible values.
Tip
Since each solver has its own set of parameters names, together with a description of the parameter, the table provides a reference to the the corresponding solver specific parameter name.
Algorithm used to solve continuous models or the root node of a MIP model. Generally, barrier method provides the fastest run times for real-world problem set.
CPLEX: CPX_PARAM_LPMETHOD - Default = 0; See link for more specifications.
Gurobi: Method - Default = -1; See link for more specifications.
clp: SolveType - Default = 5; See link for more specifications.
HiGHS: Method - Default = "choose"; See link for more specifications.
BarConvTol
Convergence tolerance for barrier algorithm.
CPLEX: CPX_PARAM_BAREPCOMP - Default = 1e-8; See link for more specifications.
Gurobi: BarConvTol - Default = 1e-8; See link for more specifications.
Feasib_Tol
All constraints must be satisfied as per this tolerance. Note that this tolerance is absolute.
CPLEX: CPX_PARAM_EPRHS - Default = 1e-6; See link for more specifications.
Gurobi: FeasibilityTol - Default = 1e-6; See link for more specifications.
clp: PrimalTolerance - Default = 1e-7; See link for more specifications.
clp: DualTolerance - Default = 1e-7; See link for more specifications.
Optimal_Tol
Reduced costs must all be smaller than Optimal_Tol in the improving direction in order for a model to be declared optimal.
CPLEX: CPX_PARAM_EPOPT - Default = 1e-6; See link for more specifications.
Gurobi: OptimalityTol - Default = 1e-6; See link for more specifications.
Pre_Solve
Controls the presolve level.
Gurobi: Presolve - Default = -1; See link for more specifications.
clp: PresolveType - Default = 5; See link for more specifications.
Crossover
Determines the crossover strategy used to transform the interior solution produced by barrier algorithm into a basic solution.
CPLEX: CPX_PARAM_SOLUTIONTYPE - Default = 2; See link for more specifications.
Gurobi: Crossover - Default = 0; See link for more specifications.
NumericFocus
Controls the degree to which the code attempts to detect and manage numerical issues.
CPLEX: CPX_PARAM_NUMERICALEMPHASIS - Default = 0; See link for more specifications.
Gurobi: NumericFocus - Default = 0; See link for more specifications.
TimeLimit
Time limit to terminate the solution algorithm, model could also terminate if it reaches MIPGap before this time.
CPLEX: CPX_PARAM_TILIM- Default = 1e+75; See link for more specifications.
Gurobi: TimeLimit - Default = infinity; See link for more specifications.
clp: MaximumSeconds - Default = -1; See link for more specifications.
MIPGap
Optimality gap in case of mixed-integer program.
CPLEX: CPX_PARAM_EPGAP- Default = 1e-4; See link for more specifications.
Gurobi: MIPGap - Default = 1e-4; See link for more specifications.
DualObjectiveLimit
When using dual simplex (where the objective is monotonically changing), terminate when the objective exceeds this limit.
clp: DualObjectiveLimit - Default = 1e308; See link for more specifications.
MaximumIterations
Terminate after performing this number of simplex iterations.
clp: MaximumIterations - Default = 2147483647; See link for more specifications.
LogLevel
Set to 1, 2, 3, or 4 for increasing output. Set to 0 to disable output.
clp: logLevel - Default = 1; See link for more specifications.
cbc: logLevel - Default = 1; See link for more specifications.
InfeasibleReturn
Set to 1 to return as soon as the problem is found to be infeasible (by default, an infeasibility proof is computed as well).
clp: InfeasibleReturn - Default = 0; See link for more specifications.
GenX is a constrained linear or mixed integer linear optimization model that determines the portfolio of electricity generation, storage, transmission, and demand-side resource investments and operational decisions to meet electricity demand in one or more future planning years at lowest cost, while subject to a variety of power system operational constraints, resource availability limits, and other imposed environmental, market design, and policy constraints.
Depending on the planning problem or question to be studied, GenX can be configured with varying levels of model resolution and scope, with regards to:
Temporal resolution of time series data such as electricity demand and renewable energy availability;
Power system operational detail and unit commitment constraints;
Geospatial resolution and transmission network representation.
The model is also capable of representing a full range of conventional and novel electricity resources, including thermal generators, variable renewable resources (wind and solar), run-of-river, reservoir and pumped-storage hydroelectric generators, energy storage devices, demand-side flexibility, demand response, and several advanced technologies such as long-duration energy storage.
The flexibility of GenX is achieved through a modular and transparent code structure developed in Julia + JuMP. The software workflow includes two main steps:
Model configuration and building: this step involves the specification of the planning problem to be studied, including time dependent data like electricity demand, renewable energy availability and fuel prices, number and type of resources included in the model, graph representation of the transmission network, and the set of constraints and objectives to be imposed.
Model execution: once the model is configured, a solver is called to find the optimal solution to the planning problem. The solution is then post-processed to generate a set of output files that can be used for further analysis.
The next sections in this guide provide more details on how to perform all the steps in the workflow:
This section details as to what happens in the process of running a GenX case. As a first step, the GenX package and the desired solver (is it's anyting other than the default solver, HiGHS; for instance, Gurobi) are loaded
GenX is a constrained linear or mixed integer linear optimization model that determines the portfolio of electricity generation, storage, transmission, and demand-side resource investments and operational decisions to meet electricity demand in one or more future planning years at lowest cost, while subject to a variety of power system operational constraints, resource availability limits, and other imposed environmental, market design, and policy constraints.
Depending on the planning problem or question to be studied, GenX can be configured with varying levels of model resolution and scope, with regards to:
Temporal resolution of time series data such as electricity demand and renewable energy availability;
Power system operational detail and unit commitment constraints;
Geospatial resolution and transmission network representation.
The model is also capable of representing a full range of conventional and novel electricity resources, including thermal generators, variable renewable resources (wind and solar), run-of-river, reservoir and pumped-storage hydroelectric generators, energy storage devices, demand-side flexibility, demand response, and several advanced technologies such as long-duration energy storage.
The flexibility of GenX is achieved through a modular and transparent code structure developed in Julia + JuMP. The software workflow includes two main steps:
Model configuration and building: this step involves the specification of the planning problem to be studied, including time dependent data like electricity demand, renewable energy availability and fuel prices, number and type of resources included in the model, graph representation of the transmission network, and the set of constraints and objectives to be imposed.
Model execution: once the model is configured, a solver is called to find the optimal solution to the planning problem. The solution is then post-processed to generate a set of output files that can be used for further analysis.
The next sections in this guide provide more details on how to perform all the steps in the workflow:
This section details as to what happens in the process of running a GenX case. As a first step, the GenX package and the desired solver (is it's anyting other than the default solver, HiGHS; for instance, Gurobi) are loaded
using GenX
using Gurobi
optimizer=Gurobi.Optimizer
The next command the user needs to run is the following:
Contingent upon whether a single stage model or a multi-stage model is intended to be run, the above function, inturn makes calls to either of these two functions: For single-stage case:
run_genx_case_simple!(case, mysetup, optimizer)
From within this function, if time-domain reduction (TDR) is needed, GenX first checks whether there already is time domain clustered data (in order to avoid duplication of efforts) by running
prevent_doubled_timedomainreduction(case)
and if the function
!time_domain_reduced_files_exist(TDRpath)
returns true value, it then runs
cluster_inputs(case, settings_path, mysetup)
to generate the time-domain clustered data for the time-series. -OR- For multi-stage case:
In this case also, the TDR clustering is done in a similar way, exxcept for the fact that if TDRSettingsDict["MultiStageConcatenate"] is set to 0, the TDR clustering is done individually for each stage. Otherwise, the clustering is done for all the stages together. The next step is configuring the solver, which is done by
The call to configure_solver first gets the particular solver that is being used to solve the particular case at hand, which then calls a function specific to that solver in order to use either the default values of the solver settings parameter or, any other set of values, specified in the settings YAML file for that particular solver.
The configuration of solver is followed by loading the input files by running the following function:
myinputs = load_inputs(mysetup, case)
The above function in its turn calls separate functions to load different resources, demand data, fuels data etc. and returns the dictionary myinputs populated by the input data. The next function call is to generate the model
time_elapsed = @elapsed EP = generate_model(mysetup, myinputs, OPTIMIZER)
println("Time elapsed for model building is")
println(time_elapsed)
The above function call instantiates the different decision variables, constraints, and objective function expressions from the input data. It can be seen that we also keep track of the time required to build the model. Follwoing this, the solve_model function makes the call to the solver and return the results as well as the solve time.
EP, solve_time = solve_model(EP, mysetup)
myinputs["solve_time"] = solve_time # Store the model solve time in myinputs
For writing the results, we invoke the following function:
The call to the writeoutputs() function in turn calls a series of functions (writecapacity, write_power etc.) each of which querries the respective decision variables and creates dataframes, eventually outputting the results to separate CSV files.
In addition to the standard single-stage planning mode, in which the produces a single snapshot of the minimum-cost generation capacity mix to meet demand at least cost under some pre-specified future conditions, recent improvements in the GenX source code (part of v0.3 release) enable its use for studying long-term evolution of the power system across multiple investment stages. GenX can be used to study multi-stage power system planning in the following two ways:
The user can formulate and solve a deterministic multi-stage planning problem with perfect foresight i.e. demand, cost, and policy assumptions about all stages are known and exploited to determine the least-cost investment trajectory for the entire period. The solution relies on exploiting the decomposable nature of the multi-stage problem via the implementation of the dual dynamic programming algorithm, described in Lara et al. 2018 here.
The user can formulate a sequential, myopic multi-stage planning problem, where the model solves a sequence of single-stage investment planning problems wherein investment decisions in each stage are individually optimized to meet demand given assumptions for the current planning stage and with investment decisions from previous stages treated as inputs for the current stage. We refer to this as "myopic" (or shortsighted) mode since the solution does not account for information about future stages in determining investments for a given stage. This version is generally more computationally efficient than the deterministic multi-stage expansion with perfect foresight mode.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
The call to the writeoutputs() function in turn calls a series of functions (writecapacity, write_power etc.) each of which querries the respective decision variables and creates dataframes, eventually outputting the results to separate CSV files.
In addition to the standard single-stage planning mode, in which the produces a single snapshot of the minimum-cost generation capacity mix to meet demand at least cost under some pre-specified future conditions, recent improvements in the GenX source code (part of v0.3 release) enable its use for studying long-term evolution of the power system across multiple investment stages. GenX can be used to study multi-stage power system planning in the following two ways:
The user can formulate and solve a deterministic multi-stage planning problem with perfect foresight i.e. demand, cost, and policy assumptions about all stages are known and exploited to determine the least-cost investment trajectory for the entire period. The solution relies on exploiting the decomposable nature of the multi-stage problem via the implementation of the dual dynamic programming algorithm, described in Lara et al. 2018 here.
The user can formulate a sequential, myopic multi-stage planning problem, where the model solves a sequence of single-stage investment planning problems wherein investment decisions in each stage are individually optimized to meet demand given assumptions for the current planning stage and with investment decisions from previous stages treated as inputs for the current stage. We refer to this as "myopic" (or shortsighted) mode since the solution does not account for information about future stages in determining investments for a given stage. This version is generally more computationally efficient than the deterministic multi-stage expansion with perfect foresight mode.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
diff --git a/previews/PR662/additional_third_party_extensions/index.html b/previews/PR662/additional_third_party_extensions/index.html
index cfb09717dd..68792ae68b 100644
--- a/previews/PR662/additional_third_party_extensions/index.html
+++ b/previews/PR662/additional_third_party_extensions/index.html
@@ -1,2 +1,2 @@
-Third Party Extensions · GenX
Python users can now run GenX from a thin-python-wrapper interface, developed by Daniel Olsen. This tool is called pygenx and can be cloned from the github page: pygenx. It needs installation of Julia 1.3 and a clone of GenX repo along with your python installation.
It is now possible to run a list of GenX cases as separate batch jobs. Alternatively, they can also be run locally in sequence, as one job. It has been developed by Jacob Schwartz. This tool is called SimpleGenXCaseRunner and can be cloned from the github page: SimpleGenXCaseRunner
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
Python users can now run GenX from a thin-python-wrapper interface, developed by Daniel Olsen. This tool is called pygenx and can be cloned from the github page: pygenx. It needs installation of Julia 1.3 and a clone of GenX repo along with your python installation.
It is now possible to run a list of GenX cases as separate batch jobs. Alternatively, they can also be run locally in sequence, as one job. It has been developed by Jacob Schwartz. This tool is called SimpleGenXCaseRunner and can be cloned from the github page: SimpleGenXCaseRunner
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
GenX is an open-source project, and we welcome contributions from the community. This guide aims to help you get started with GenX and explain how to contribute to the project. In general, the two main ways to contribute to GenX are:
Use of GitHub issues to report bugs and request new features
In GenX, a resource is defined as an instance of a GenX resource type, a subtype of an AbstractResource. This allows the code to use multiple dispatch and define a common interface (behavior) for all resources in the code. Type hierarchy of GenX resources:
Note
All the interface and utility functions available for resources are defined in the resources.jl file.
The set of all the resource types available in GenX are contained in the resource_typesTuple defined at the of the resources.jl file. During the initialization process, GenX reads the input data files and creates a new instance of the corresponding resource type for each row in the file.
Resources in GenX are constructed from a set of input files (in .csv format, one for each type of resource) located in the resources folder inside the case folder. Each row in one of these files defines a new resource instance, and each column corresponds to an attribute of that resource type.
Warning
The first column of each input data file should be called Resource and contain a unique identifier for each resource.
For example, in the case below, the files Hydro.csv, Thermal.csv, Vre.csv, and Storage.csv contain the resource data for the hydro, thermal, VRE, and storage resources, respectively. These files are read by GenX during the initialization process and used to create the corresponding resource instances.
GenX is an open-source project, and we welcome contributions from the community. This guide aims to help you get started with GenX and explain how to contribute to the project. In general, the two main ways to contribute to GenX are:
Use of GitHub issues to report bugs and request new features
In GenX, a resource is defined as an instance of a GenX resource type, a subtype of an AbstractResource. This allows the code to use multiple dispatch and define a common interface (behavior) for all resources in the code. Type hierarchy of GenX resources:
Note
All the interface and utility functions available for resources are defined in the resources.jl file.
The set of all the resource types available in GenX are contained in the resource_typesTuple defined at the of the resources.jl file. During the initialization process, GenX reads the input data files and creates a new instance of the corresponding resource type for each row in the file.
Resources in GenX are constructed from a set of input files (in .csv format, one for each type of resource) located in the resources folder inside the case folder. Each row in one of these files defines a new resource instance, and each column corresponds to an attribute of that resource type.
Warning
The first column of each input data file should be called Resource and contain a unique identifier for each resource.
For example, in the case below, the files Hydro.csv, Thermal.csv, Vre.csv, and Storage.csv contain the resource data for the hydro, thermal, VRE, and storage resources, respectively. These files are read by GenX during the initialization process and used to create the corresponding resource instances.
case_folder
├── resources
│ ├── Hydro.csv
│ ├── Thermal.csv
@@ -133,4 +133,4 @@
attribute_1 (generic function with 1 method)
add_similar_to_expression!(expr1::AbstractArray{GenericAffExpr{C,T}, dim1}, expr2::AbstractArray{V, dim2}) where {C,T,V,dim1,dim2}
Add an array of some type V to an array of expressions, in-place. This will work on JuMP DenseContainers which do not have linear indexing from 1:length(arr). However, the accessed parts of both arrays must have the same dimensions.
add_term_to_expression!(expr1::AbstractArray{GenericAffExpr{C,T}, dims}, expr2::V) where {C,T,V,dims}
Add an entry of type V to an array of expressions, in-place. This will work on JuMP DenseContainers which do not have linear indexing from 1:length(arr).
Check that two datatype can be added using addtoexpression!(). Raises an error if not.
This needs some work to make it more flexible. Right now it's challenging to use with GenericAffExpr{C,T} as the method only works on the constituent types making up the GenericAffExpr, not the resulting expression type. Also, the default MethodError from addtoexpression! is sometime more informative than the error message here.
create_empty_expression!(EP::Model, exprname::Symbol, dims::NTuple{N, Int64}) where N
Create an dense array filled with zeros which can be altered later. Other approaches to creating zero-filled arrays will often return an array of floats, not expressions. This can lead to errors later if a method can only operate on expressions.
We don't currently have a method to do this with non-contiguous indexing.
sum_expression(expr::AbstractArray{C, dims}) where {C,dims} :: C
Sum an array of expressions into a single expression and return the result. We're using errors from addtoexpression!() to check that the types are compatible.
add_similar_to_expression!(expr1::AbstractArray{GenericAffExpr{C,T}, dim1}, expr2::AbstractArray{V, dim2}) where {C,T,V,dim1,dim2}
Add an array of some type V to an array of expressions, in-place. This will work on JuMP DenseContainers which do not have linear indexing from 1:length(arr). However, the accessed parts of both arrays must have the same dimensions.
add_term_to_expression!(expr1::AbstractArray{GenericAffExpr{C,T}, dims}, expr2::V) where {C,T,V,dims}
Add an entry of type V to an array of expressions, in-place. This will work on JuMP DenseContainers which do not have linear indexing from 1:length(arr).
Check that two datatype can be added using addtoexpression!(). Raises an error if not.
This needs some work to make it more flexible. Right now it's challenging to use with GenericAffExpr{C,T} as the method only works on the constituent types making up the GenericAffExpr, not the resulting expression type. Also, the default MethodError from addtoexpression! is sometime more informative than the error message here.
create_empty_expression!(EP::Model, exprname::Symbol, dims::NTuple{N, Int64}) where N
Create an dense array filled with zeros which can be altered later. Other approaches to creating zero-filled arrays will often return an array of floats, not expressions. This can lead to errors later if a method can only operate on expressions.
We don't currently have a method to do this with non-contiguous indexing.
sum_expression(expr::AbstractArray{C, dims}) where {C,dims} :: C
Sum an array of expressions into a single expression and return the result. We're using errors from addtoexpression!() to check that the types are compatible.
GenX is a highly-configurable, open source electricity resource capacity expansion model that incorporates several state-of-the-art practices in electricity system planning to offer improved decision support for a changing electricity landscape.
GenX is a constrained linear or mixed integer linear optimization model that determines the portfolio of electricity generation, storage, transmission, and demand-side resource investments and operational decisions to meet electricity demand in one or more future planning years at lowest cost, while subject to a variety of power system operational constraints, resource availability limits, and other imposed environmental, market design, and policy constraints.
GenX features a modular and transparent code structure developed in Julia + JuMP. The model is designed to be highly flexible and configurable for use in a variety of applications from academic research and technology evaluation to public policy and regulatory analysis and resource planning. See the User Guide for more information on how to use GenX and the Developer Guide for more information on how to contribute to GenX.
From a centralized planning perspective, the GenX model can help to determine the investments needed to supply future electricity demand at minimum cost, as is common in least-cost utility planning or integrated resource planning processes. In the context of liberalized markets, the model can be used by regulators and policy makers for indicative energy planning or policy analysis in order to establish a long-term vision of efficient market and policy outcomes. The model can also be used for techno-economic assessment of emerging electricity generation, storage, and demand-side resources and to enumerate the effect of parametric uncertainty (e.g., technology costs, fuel costs, demand, policy decisions) on the system-wide value or role of different resources.
This section provides a quick guidance as to how to navigate through the different parts of the documentation pages; what the different sections contain, and how to relate it to the different parts of the GenX code-base.
This page serves as a gentle introduction to what GenX is meant for and what it does.
The next subsection, Installation Guide goes over how to download and install GenX and also how to download and install the Julia programming language (in which GenX is written) and the different open-source non-commercial freely available solvers, as well as the commercial solvers and the respective JuMP interfaces. This subsection also goes over installing the environment dependencies and instantiating a virtual environment.
We also mention the shortcomings of GenX and some third party extentions in the next couple subsections
The next section is Getting Started goes over Running GenX and has two subsections. The first subsection, Example cases, gives a walkthrough through some predefined example systems and how to run GenX for those and interpret the results. It also tells how to run GenX for a user-defined case. The subsection Using commercial solvers: Gurobi or CPLEX talks specifically about how to run GenX with commercial solvers like Gurobi and CPLEX that are absolutely indispensable for solving large cases.
The third section, Tutorial starts with GenX Tutorials and gives a comprehensive tour of the different steps that are involved when a GenX capacity expansion simulation is run. It consists of 6 tutorial sections, each of which highlights the different important aspects of model construction and run of GenX. The different sections are configuring the GenX settings, visualizing the network, time domain reduction, generating the model, solving the model, and adjusting the different solver settings.
The User Guide, which the fourth section (User Guide) goes into the depths and details of the different steps and the settings and input parameters from the previous Tutorial section. The sections starts off with an overview of the workflow in GenX, briefing about the different steps (some of which we encountered in the Tutorials) of running GenX model. It then explains the different parameters of settings, policy, time-domain reduction, model structure, and output. Following this, the next subsection explains the different solver settings parameters of the different solvers. The next subsection goes over the different input CSV files and the different fields that are used there. The following two subsections are devoted to Time Domain Reduction (TDR). The first one walks through and explains the different settings parameters for TDR and the second one explains the couple different ways to run TDR for GenX and what exactly happens when we run TDR. The next four subsections, respectively, explains the different parameters, inputs, and outputs, and what happens when Modeling to Generate Alternatives (MGA), Multi-stage model, slack variables for policies (when we want to satisfy policy constraints in a soft manner by adding penalty of violation in the objective function), and Method of Morris. Finally, the last two sections are about the different steps involved while solving the model and the explanation of different output fields for both the default settings and user-specific settings.
The Model Concept and Overview section first introduces the GenX model in GenX Model Introduction and talks about its scope. It also introduces the notations, the objective function, and the power balance constraints. This is the first section which delves into the theoretical and mathematical details of the model, which is the most important one for model developers.
The Model Reference, which is the sixth section delves deep into the GenX model and introduces the mathematical formulation, while discussing the physical interpretations of all the different parts of the GenX model. This section starts off with discussing the Core of the model, which models the Discharge, Non-Served Energy, Operational Reserves, Transmission, Unit Commitment, CO2, and Fuel. The different parts of the model consists of the different tyoe of generating resources (thermal, hydro, VRE, storage etc.), transmission network (modeling of flows as well as losses), demand modeling, operating reserves, unit commitment, different policies (such as CO2 constraint, capacity reserve margin, energy share requirement, min and max cap requirement etc.). This section also mentions about the different Julia functions (or methods) used for loading the input files, building the model, solving it, and generating the output files. Also, this is the section that explains the internal details of the Julia functions used for TDR, MGA, Method of Morris, Multi-stage modeling, and the several utility functions used throughout the GenX code-base.
The seventh section, Public API ReferencePublic Documentation is for describing the functions that are directly accessible to an external program from GenX (like loading inputs, generating output, running TDR script etc.) and how an external "client" code can access the GenX features, if the user desires to run his/her own code instead of the Run.jl provided by us.
The eighth section, Third Party ExtensionAdditional Third Party Extensions to GenX mentions about Pygenx, a Python interface for GenX, that was built by Daniel Olsen and GenX case runner for automated batch running, built by Jacob Schwartz.
Finally, the ninth and last section, Developer DocsHow to contribute to GenX talks about the resource organization in GenX, how to add a new user-defined resource, and also several JuMP functions that are used as utility throughout the GenX code-base.
We recommend users of GenX to cite it in their academic publications and patent filings. Here's the text to put up as the citation for GenX: MIT Energy Initiative and Princeton University ZERO lab. [GenX](https://github.com/GenXProject/GenX): a configurable power system capacity expansion model for studying low-carbon energy futures n.d. https://github.com/GenXProject/GenX.
The GenX team expresses deep gratitude to Maya Mutic for developing the tutorials along with Filippo Pecci and Luca Bonaldo. The Julia-themed GenX logo was designed by Laura Zwanziger and Jacob Schwartz.
GenX is a highly-configurable, open source electricity resource capacity expansion model that incorporates several state-of-the-art practices in electricity system planning to offer improved decision support for a changing electricity landscape.
GenX is a constrained linear or mixed integer linear optimization model that determines the portfolio of electricity generation, storage, transmission, and demand-side resource investments and operational decisions to meet electricity demand in one or more future planning years at lowest cost, while subject to a variety of power system operational constraints, resource availability limits, and other imposed environmental, market design, and policy constraints.
GenX features a modular and transparent code structure developed in Julia + JuMP. The model is designed to be highly flexible and configurable for use in a variety of applications from academic research and technology evaluation to public policy and regulatory analysis and resource planning. See the User Guide for more information on how to use GenX and the Developer Guide for more information on how to contribute to GenX.
From a centralized planning perspective, the GenX model can help to determine the investments needed to supply future electricity demand at minimum cost, as is common in least-cost utility planning or integrated resource planning processes. In the context of liberalized markets, the model can be used by regulators and policy makers for indicative energy planning or policy analysis in order to establish a long-term vision of efficient market and policy outcomes. The model can also be used for techno-economic assessment of emerging electricity generation, storage, and demand-side resources and to enumerate the effect of parametric uncertainty (e.g., technology costs, fuel costs, demand, policy decisions) on the system-wide value or role of different resources.
This section provides a quick guidance as to how to navigate through the different parts of the documentation pages; what the different sections contain, and how to relate it to the different parts of the GenX code-base.
This page serves as a gentle introduction to what GenX is meant for and what it does.
The next subsection, Installation Guide goes over how to download and install GenX and also how to download and install the Julia programming language (in which GenX is written) and the different open-source non-commercial freely available solvers, as well as the commercial solvers and the respective JuMP interfaces. This subsection also goes over installing the environment dependencies and instantiating a virtual environment.
We also mention the shortcomings of GenX and some third party extentions in the next couple subsections
The next section is Getting Started goes over Running GenX and has two subsections. The first subsection, Example cases, gives a walkthrough through some predefined example systems and how to run GenX for those and interpret the results. It also tells how to run GenX for a user-defined case. The subsection Using commercial solvers: Gurobi or CPLEX talks specifically about how to run GenX with commercial solvers like Gurobi and CPLEX that are absolutely indispensable for solving large cases.
The third section, Tutorial starts with GenX Tutorials and gives a comprehensive tour of the different steps that are involved when a GenX capacity expansion simulation is run. It consists of 6 tutorial sections, each of which highlights the different important aspects of model construction and run of GenX. The different sections are configuring the GenX settings, visualizing the network, time domain reduction, generating the model, solving the model, and adjusting the different solver settings.
The User Guide, which the fourth section (User Guide) goes into the depths and details of the different steps and the settings and input parameters from the previous Tutorial section. The sections starts off with an overview of the workflow in GenX, briefing about the different steps (some of which we encountered in the Tutorials) of running GenX model. It then explains the different parameters of settings, policy, time-domain reduction, model structure, and output. Following this, the next subsection explains the different solver settings parameters of the different solvers. The next subsection goes over the different input CSV files and the different fields that are used there. The following two subsections are devoted to Time Domain Reduction (TDR). The first one walks through and explains the different settings parameters for TDR and the second one explains the couple different ways to run TDR for GenX and what exactly happens when we run TDR. The next four subsections, respectively, explains the different parameters, inputs, and outputs, and what happens when Modeling to Generate Alternatives (MGA), Multi-stage model, slack variables for policies (when we want to satisfy policy constraints in a soft manner by adding penalty of violation in the objective function), and Method of Morris. Finally, the last two sections are about the different steps involved while solving the model and the explanation of different output fields for both the default settings and user-specific settings.
The Model Concept and Overview section first introduces the GenX model in GenX Model Introduction and talks about its scope. It also introduces the notations, the objective function, and the power balance constraints. This is the first section which delves into the theoretical and mathematical details of the model, which is the most important one for model developers.
The Model Reference, which is the sixth section delves deep into the GenX model and introduces the mathematical formulation, while discussing the physical interpretations of all the different parts of the GenX model. This section starts off with discussing the Core of the model, which models the Discharge, Non-Served Energy, Operational Reserves, Transmission, Unit Commitment, CO2, and Fuel. The different parts of the model consists of the different tyoe of generating resources (thermal, hydro, VRE, storage etc.), transmission network (modeling of flows as well as losses), demand modeling, operating reserves, unit commitment, different policies (such as CO2 constraint, capacity reserve margin, energy share requirement, min and max cap requirement etc.). This section also mentions about the different Julia functions (or methods) used for loading the input files, building the model, solving it, and generating the output files. Also, this is the section that explains the internal details of the Julia functions used for TDR, MGA, Method of Morris, Multi-stage modeling, and the several utility functions used throughout the GenX code-base.
The seventh section, Public API ReferencePublic Documentation is for describing the functions that are directly accessible to an external program from GenX (like loading inputs, generating output, running TDR script etc.) and how an external "client" code can access the GenX features, if the user desires to run his/her own code instead of the Run.jl provided by us.
The eighth section, Third Party ExtensionAdditional Third Party Extensions to GenX mentions about Pygenx, a Python interface for GenX, that was built by Daniel Olsen and GenX case runner for automated batch running, built by Jacob Schwartz.
Finally, the ninth and last section, Developer DocsHow to contribute to GenX talks about the resource organization in GenX, how to add a new user-defined resource, and also several JuMP functions that are used as utility throughout the GenX code-base.
We recommend users of GenX to cite it in their academic publications and patent filings. Here's the text to put up as the citation for GenX: MIT Energy Initiative and Princeton University ZERO lab. [GenX](https://github.com/GenXProject/GenX): a configurable power system capacity expansion model for studying low-carbon energy futures n.d. https://github.com/GenXProject/GenX.
The GenX team expresses deep gratitude to Maya Mutic for developing the tutorials along with Filippo Pecci and Luca Bonaldo. The Julia-themed GenX logo was designed by Laura Zwanziger and Jacob Schwartz.
GenX currently exists in version 0.4.0 and runs only on Julia v1.6.x, 1.7.x, 1.8.x, and 1.9.x, where x>=0 and a minimum version of JuMP v1.1.1. To install Julia, please follow the instructions on the Julia website.
Note
We recommend the users to stick to a particular version of Julia to run GenX. If however, the users decide to switch between versions, it's very important to delete the old Manifest.toml file and do a fresh build of GenX.
After installing Julia, you can download GenX by either cloning the repository or downloading the zip file from the GenX GitHub page. For this tutorial it will be assumed to be within your home directory: /home/youruser/GenX. Once you have downloaded GenX, you can install the dependencies by following the steps below:
1. Start a terminal and navigate into the GenX folder.
2. Type julia --project=. to start an instance of the julia kernel with the project set to the current folder. The flag --project=. indicates that Julia will activate the project environment using the Project.toml present in the current folder, .. If running on Windows, the location of Julia can also be specified as e.g., C:\julia-1.6.0\bin\julia.exe --project=..
Tip
The file Project.toml in the parent directory lists all of the dependencies and their versions needed to run GenX. You can see all of the packages installed in your Julia environment and their version numbers by running pkg> status or pkg> st on the package manager command line in the Jula REPL (for more information on the Julia package manager, read the documentation for the Pkg.jl or for the Julia standard library).
Tip
julia --project is a shortcut for julia --project=.
3. Type ] to bring up the package system (GenX) pkg > prompt. This indicates that the GenX project was detected.
Warning
If you see (@v1.6) pkg> as the prompt, then the project was not successfully set.
4. Type instantiate from the (GenX) pkg prompt.
Note for Windows users
On Windows there is an issue with the prepopulated MUMPS_seq_jll v5.5.1 that prevents compilation of the solvers. To avoid this issue type add MUMPS_seq_jll@5.4.1 after running instantiate.
5. Type st to check that the dependecies have been installed. If there is no error, it has been successful.
Tip
Type the back key to come back to the julia> prompt from the package manager.
The above steps are shown in Figure 1 and Figure 2.
Figure 1. Creating the Julia environment and installing dependencies from Project.toml file from inside the GenX folder.
Figure 2. Creating the Julia environment and installing dependencies from Project.toml file from inside the GenX folder: Step 5
GenX requires a solver to be installed to solve the optimization problem. By default, GenX uses one of the following open-source freely available solvers:
HiGHS for linear programming and MILP (default solver)
For those users who has previously cloned GenX, and has been running it successfully so far, and therefore might be unwilling to run it on the latest version of Julia: please look into the GitHub branch, old_version.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
GenX currently exists in version 0.4.0 and runs only on Julia v1.6.x, 1.7.x, 1.8.x, and 1.9.x, where x>=0 and a minimum version of JuMP v1.1.1. To install Julia, please follow the instructions on the Julia website.
Note
We recommend the users to stick to a particular version of Julia to run GenX. If however, the users decide to switch between versions, it's very important to delete the old Manifest.toml file and do a fresh build of GenX.
After installing Julia, you can download GenX by either cloning the repository or downloading the zip file from the GenX GitHub page. For this tutorial it will be assumed to be within your home directory: /home/youruser/GenX. Once you have downloaded GenX, you can install the dependencies by following the steps below:
1. Start a terminal and navigate into the GenX folder.
2. Type julia --project=. to start an instance of the julia kernel with the project set to the current folder. The flag --project=. indicates that Julia will activate the project environment using the Project.toml present in the current folder, .. If running on Windows, the location of Julia can also be specified as e.g., C:\julia-1.6.0\bin\julia.exe --project=..
Tip
The file Project.toml in the parent directory lists all of the dependencies and their versions needed to run GenX. You can see all of the packages installed in your Julia environment and their version numbers by running pkg> status or pkg> st on the package manager command line in the Jula REPL (for more information on the Julia package manager, read the documentation for the Pkg.jl or for the Julia standard library).
Tip
julia --project is a shortcut for julia --project=.
3. Type ] to bring up the package system (GenX) pkg > prompt. This indicates that the GenX project was detected.
Warning
If you see (@v1.6) pkg> as the prompt, then the project was not successfully set.
4. Type instantiate from the (GenX) pkg prompt.
Note for Windows users
On Windows there is an issue with the prepopulated MUMPS_seq_jll v5.5.1 that prevents compilation of the solvers. To avoid this issue type add MUMPS_seq_jll@5.4.1 after running instantiate.
5. Type st to check that the dependecies have been installed. If there is no error, it has been successful.
Tip
Type the back key to come back to the julia> prompt from the package manager.
The above steps are shown in Figure 1 and Figure 2.
Figure 1. Creating the Julia environment and installing dependencies from Project.toml file from inside the GenX folder.
Figure 2. Creating the Julia environment and installing dependencies from Project.toml file from inside the GenX folder: Step 5
GenX requires a solver to be installed to solve the optimization problem. By default, GenX uses one of the following open-source freely available solvers:
HiGHS for linear programming and MILP (default solver)
For those users who has previously cloned GenX, and has been running it successfully so far, and therefore might be unwilling to run it on the latest version of Julia: please look into the GitHub branch, old_version.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
diff --git a/previews/PR662/limitations_genx/index.html b/previews/PR662/limitations_genx/index.html
index b51b4a87c0..35e734fa32 100644
--- a/previews/PR662/limitations_genx/index.html
+++ b/previews/PR662/limitations_genx/index.html
@@ -1,2 +1,2 @@
-Limitation of GenX · GenX
While the benefits of an openly available generation and transmission expansion model are high, many approximations have been made due to missing data or to manage computational tractability. The assumptions of the GenX model are listed below. It serves as a caveat to the user and as an encouragement to improve the approximations.
GenX makes the simplifying assumption that each time period contains n copies of a single, representative year. GenX optimizes generation and transmission capacity for just this characteristic year within each time period, assuming the results for different years in the same time period are identical. However, the GenX objective function accounts only for the cost of the final model time period.
The GenX objective function assumes that the cost of powerplants is specified in the unit of currency per unit of capacity. GenX also assumes that the capital cost of technologies is paid through loans.
GenX is a bottom-up (technology-explicit), partial equilibrium model that assumes perfect markets for commodities. In other words, each commodity is produced such that the sum of producer and consumer surplus is maximized.
Behavioral response and acceptance of new technology are often modeled simplistically as a discount rate or by externally fixing the technology capacity. A higher, technology-specific discount rate represents consumer reluctance to accept newer technologies.
Because each model realization assumes a particular state of the world based on the input values drawn, the parameter uncertainty is propagated through the model in the case of myopic model runs.
GenX assumes rational decision making, with perfect information and perfect foresight, and simultaneously optimizes all decisions over the user-specified time horizon.
GenX assumes price-elastic demand segments that are represented using piece-wise approximation rather than an inverse demand curve to keep the model linear.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
While the benefits of an openly available generation and transmission expansion model are high, many approximations have been made due to missing data or to manage computational tractability. The assumptions of the GenX model are listed below. It serves as a caveat to the user and as an encouragement to improve the approximations.
GenX makes the simplifying assumption that each time period contains n copies of a single, representative year. GenX optimizes generation and transmission capacity for just this characteristic year within each time period, assuming the results for different years in the same time period are identical. However, the GenX objective function accounts only for the cost of the final model time period.
The GenX objective function assumes that the cost of powerplants is specified in the unit of currency per unit of capacity. GenX also assumes that the capital cost of technologies is paid through loans.
GenX is a bottom-up (technology-explicit), partial equilibrium model that assumes perfect markets for commodities. In other words, each commodity is produced such that the sum of producer and consumer surplus is maximized.
Behavioral response and acceptance of new technology are often modeled simplistically as a discount rate or by externally fixing the technology capacity. A higher, technology-specific discount rate represents consumer reluctance to accept newer technologies.
Because each model realization assumes a particular state of the world based on the input values drawn, the parameter uncertainty is propagated through the model in the case of myopic model runs.
GenX assumes rational decision making, with perfect information and perfect foresight, and simultaneously optimizes all decisions over the user-specified time horizon.
GenX assumes price-elastic demand segments that are represented using piece-wise approximation rather than an inverse demand curve to keep the model linear.
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
diff --git a/previews/PR662/objects.inv b/previews/PR662/objects.inv
index 7eea8b8c85..a5d9f79f8d 100644
Binary files a/previews/PR662/objects.inv and b/previews/PR662/objects.inv differ
diff --git a/previews/PR662/third_party_genx/index.html b/previews/PR662/third_party_genx/index.html
index d9ba7fc9f0..2fe665a1f3 100644
--- a/previews/PR662/third_party_genx/index.html
+++ b/previews/PR662/third_party_genx/index.html
@@ -1,2 +1,2 @@
-Third Party Extensions · GenX
Python users can now run GenX from a thin-python-wrapper interface, developed by Daniel Olsen. This tool is called pygenx and can be cloned from the github page: pygenx. It needs installation of Julia 1.3 and a clone of GenX repo along with your python installation.
It is now possible to run a list of GenX cases as separate batch jobs. Alternatively, they can also be run locally in sequence, as one job. It has been developed by Jacob Schwartz. This tool is called SimpleGenXCaseRunner and can be cloned from the github page: SimpleGenXCaseRunner
If you would like to report a bug in the code or request a feature, please use our Issue Tracker. If you're unsure or have questions on how to use GenX that are not addressed by the above documentation, please reach out to Sambuddha Chakrabarti (sc87@princeton.edu), Luca Bonaldo (lucabonaldo@princeton.edu), Jesse Jenkins (jdj2@princeton.edu) or Dharik Mallapragada (dharik@mit.edu).
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.
Python users can now run GenX from a thin-python-wrapper interface, developed by Daniel Olsen. This tool is called pygenx and can be cloned from the github page: pygenx. It needs installation of Julia 1.3 and a clone of GenX repo along with your python installation.
It is now possible to run a list of GenX cases as separate batch jobs. Alternatively, they can also be run locally in sequence, as one job. It has been developed by Jacob Schwartz. This tool is called SimpleGenXCaseRunner and can be cloned from the github page: SimpleGenXCaseRunner
If you would like to report a bug in the code or request a feature, please use our Issue Tracker. If you're unsure or have questions on how to use GenX that are not addressed by the above documentation, please reach out to Sambuddha Chakrabarti (sc87@princeton.edu), Luca Bonaldo (lucabonaldo@princeton.edu), Jesse Jenkins (jdj2@princeton.edu) or Dharik Mallapragada (dharik@mit.edu).
Settings
This document was generated with Documenter.jl version 1.3.0 on Wednesday 20 March 2024. Using Julia version 1.10.2.