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 @@ -Commertial solvers · GenX

Using commercial solvers: Gurobi or CPLEX

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
+Commertial solvers · GenX.jl

Using commercial solvers: Gurobi or CPLEX

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.

+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.

diff --git a/previews/PR662/Getting_Started/examples_casestudies/index.html b/previews/PR662/Getting_Started/examples_casestudies/index.html index 044f3e89f0..050a5681ed 100644 --- a/previews/PR662/Getting_Started/examples_casestudies/index.html +++ b/previews/PR662/Getting_Started/examples_casestudies/index.html @@ -1,5 +1,5 @@ -Running GenX · GenX

Running GenX

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.

Example cases

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 available examples are:

Note

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:

  1. Open a terminal and run Julia with an environment containing GenX;
  2. 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
+Running GenX · GenX.jl

Running GenX

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.

Example cases

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 available examples are:

Note

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:

  1. Open a terminal and run Julia with an environment containing GenX;
  2. 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

What happens when you run a case

Added in 0.3.4

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:

  1. Establish path to environment setup files and GenX source files.
  2. Read in model settings genx_settings.yml from the example directory.
  3. Configure solver settings.
  4. Load the model inputs from the example directory and perform time-domain clustering if required.
  5. Generate a GenX model instance.
  6. Solve the model.
  7. 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.

+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

What happens when you run a case

Added in 0.3.4

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:

  1. Establish path to environment setup files and GenX source files.
  2. Read in model settings genx_settings.yml from the example directory.
  3. Configure solver settings.
  4. Load the model inputs from the example directory and perform time-domain clustering if required.
  5. Generate a GenX model instance.
  6. Solve the model.
  7. 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.

diff --git a/previews/PR662/Model_Concept_Overview/model_introduction/index.html b/previews/PR662/Model_Concept_Overview/model_introduction/index.html index bda83988c7..90b871bfc8 100644 --- a/previews/PR662/Model_Concept_Overview/model_introduction/index.html +++ b/previews/PR662/Model_Concept_Overview/model_introduction/index.html @@ -1,2 +1,2 @@ -Model Introduction · GenX

GenX Model Introduction

Introduction

GenX allows for the simultaneous co-optimization of several interlinked power system decision layers, described below:

  1. Capacity expansion planning (e.g., investment and retirement decisions for a full range of centralized and distributed generation, storage, and demand-side resources)
  2. Hourly dispatch of generation, storage, and demand-side resources,
  3. Unit commitment decisions and operational constraints for thermal generators,
  4. Commitment of generation, storage, and demand-side capacity to meet system operating reserves requirements,
  5. Commitment of generation, storage, and demand-side capacity to meet capacity reserve requirements,
  6. Transmission network power flows (including losses) and network expansion decisions, and
  7. 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.

Range of configurations currently implemented in GenX along three key dimensions of model resolution 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.

Uses

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.

+Model Introduction · GenX.jl

GenX Model Introduction

Introduction

GenX allows for the simultaneous co-optimization of several interlinked power system decision layers, described below:

  1. Capacity expansion planning (e.g., investment and retirement decisions for a full range of centralized and distributed generation, storage, and demand-side resources)
  2. Hourly dispatch of generation, storage, and demand-side resources,
  3. Unit commitment decisions and operational constraints for thermal generators,
  4. Commitment of generation, storage, and demand-side capacity to meet system operating reserves requirements,
  5. Commitment of generation, storage, and demand-side capacity to meet capacity reserve requirements,
  6. Transmission network power flows (including losses) and network expansion decisions, and
  7. 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.

Range of configurations currently implemented in GenX along three key dimensions of model resolution 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.

Uses

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.

diff --git a/previews/PR662/Model_Concept_Overview/model_notation/index.html b/previews/PR662/Model_Concept_Overview/model_notation/index.html index 21fec27c26..4206e4d874 100644 --- a/previews/PR662/Model_Concept_Overview/model_notation/index.html +++ b/previews/PR662/Model_Concept_Overview/model_notation/index.html @@ -1,2 +1,2 @@ -Notation · GenX

Model Notation

Model Indices and Sets


NotationDescription
$t \in \mathcal{T}$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
$\mathcal{VS}^{asym, dc, dis} \subseteq \mathcal{VS}$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
$\mathcal{VS}^{asym, dc, cha} \subseteq \mathcal{VS}$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
$\mathcal{VS}^{asym, ac, dis} \subseteq \mathcal{VS}$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
$\mathcal{VS}^{asym, ac, cha} \subseteq \mathcal{VS}$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}$
$\mathcal{P}^{ESR} \subseteq \mathcal{P}$Energy Share Requirement type policies
$\mathcal{P}^{CO_2} \subseteq \mathcal{P}$CO$_2$ emission cap policies
$\mathcal{P}^{CO_2}_{mass} \subseteq \mathcal{P}^{CO_2}$CO$_2$ emissions limit policy constraints, mass-based
$\mathcal{P}^{CO_2}_{demand} \subseteq \mathcal{P}^{CO_2}$CO$_2$ emissions limit policy constraints, demand and emission-rate based
$\mathcal{P}^{CO_2}_{gen} \subseteq \mathcal{P}^{CO_2}$CO$_2$ emissions limit policy constraints, generation emission-rate based
$\mathcal{P}^{CRM} \subseteq \mathcal{P}$Capacity reserve margin (CRM) type policy constraints
$\mathcal{P}^{MinTech} \subseteq \mathcal{P}$Minimum Capacity Carve-out type policy constraint
$\mathcal{Z}^{ESR}_{p} \subseteq \mathcal{Z}$set of zones eligible for ESR policy constraint $p \in \mathcal{P}^{ESR}$
$\mathcal{Z}^{CRM}_{p} \subseteq \mathcal{Z}$set of zones that form the locational deliverable area for capacity reserve margin policy constraint $p \in \mathcal{P}^{CRM}$
$\mathcal{Z}^{CO_2}_{p,mass} \subseteq \mathcal{Z}$set of zones are under the emission cap mass-based cap-and-trade policy constraint $p \in \mathcal{P}^{CO_2}_{mass}$
$\mathcal{Z}^{CO_2}_{p,demand} \subseteq \mathcal{Z}$set of zones are under the emission cap demand-and-emission-rate based cap-and-trade policy constraint $p \in \mathcal{P}^{CO_2}_{demand}$
$\mathcal{Z}^{CO_2}_{p,gen} \subseteq \mathcal{Z}$set of zones are under the emission cap generation emission-rate based cap-and-trade policy constraint $p \in \mathcal{P}^{CO2,gen}$
$\mathcal{L}_p^{in} \subseteq \mathcal{L}$The subset of transmission lines entering Locational Deliverability Area of capacity reserve margin policy $p \in \mathcal{P}^{CRM}$
$\mathcal{L}_p^{out} \subseteq \mathcal{L}$The subset of transmission lines leaving Locational Deliverability Area of capacity reserve margin policy $p \in \mathcal{P}^{CRM}$
$\mathcal{Qualified} \subseteq \mathcal{G}$where $\mathcal{Qualified}$ is the subset of generation and storage resources eligible to supply electrolyzers within the same zone (optional set)

Decision Variables


NotationDescription
$\Omega_{y,z} \in \mathbb{R}_+$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]

Parameters


NotationDescription
$D_{z,t}$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)

+Notation · GenX.jl

Model Notation

Model Indices and Sets


NotationDescription
$t \in \mathcal{T}$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
$\mathcal{VS}^{asym, dc, dis} \subseteq \mathcal{VS}$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
$\mathcal{VS}^{asym, dc, cha} \subseteq \mathcal{VS}$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
$\mathcal{VS}^{asym, ac, dis} \subseteq \mathcal{VS}$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
$\mathcal{VS}^{asym, ac, cha} \subseteq \mathcal{VS}$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}$
$\mathcal{P}^{ESR} \subseteq \mathcal{P}$Energy Share Requirement type policies
$\mathcal{P}^{CO_2} \subseteq \mathcal{P}$CO$_2$ emission cap policies
$\mathcal{P}^{CO_2}_{mass} \subseteq \mathcal{P}^{CO_2}$CO$_2$ emissions limit policy constraints, mass-based
$\mathcal{P}^{CO_2}_{demand} \subseteq \mathcal{P}^{CO_2}$CO$_2$ emissions limit policy constraints, demand and emission-rate based
$\mathcal{P}^{CO_2}_{gen} \subseteq \mathcal{P}^{CO_2}$CO$_2$ emissions limit policy constraints, generation emission-rate based
$\mathcal{P}^{CRM} \subseteq \mathcal{P}$Capacity reserve margin (CRM) type policy constraints
$\mathcal{P}^{MinTech} \subseteq \mathcal{P}$Minimum Capacity Carve-out type policy constraint
$\mathcal{Z}^{ESR}_{p} \subseteq \mathcal{Z}$set of zones eligible for ESR policy constraint $p \in \mathcal{P}^{ESR}$
$\mathcal{Z}^{CRM}_{p} \subseteq \mathcal{Z}$set of zones that form the locational deliverable area for capacity reserve margin policy constraint $p \in \mathcal{P}^{CRM}$
$\mathcal{Z}^{CO_2}_{p,mass} \subseteq \mathcal{Z}$set of zones are under the emission cap mass-based cap-and-trade policy constraint $p \in \mathcal{P}^{CO_2}_{mass}$
$\mathcal{Z}^{CO_2}_{p,demand} \subseteq \mathcal{Z}$set of zones are under the emission cap demand-and-emission-rate based cap-and-trade policy constraint $p \in \mathcal{P}^{CO_2}_{demand}$
$\mathcal{Z}^{CO_2}_{p,gen} \subseteq \mathcal{Z}$set of zones are under the emission cap generation emission-rate based cap-and-trade policy constraint $p \in \mathcal{P}^{CO2,gen}$
$\mathcal{L}_p^{in} \subseteq \mathcal{L}$The subset of transmission lines entering Locational Deliverability Area of capacity reserve margin policy $p \in \mathcal{P}^{CRM}$
$\mathcal{L}_p^{out} \subseteq \mathcal{L}$The subset of transmission lines leaving Locational Deliverability Area of capacity reserve margin policy $p \in \mathcal{P}^{CRM}$
$\mathcal{Qualified} \subseteq \mathcal{G}$where $\mathcal{Qualified}$ is the subset of generation and storage resources eligible to supply electrolyzers within the same zone (optional set)

Decision Variables


NotationDescription
$\Omega_{y,z} \in \mathbb{R}_+$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]

Parameters


NotationDescription
$D_{z,t}$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)

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

Objective Function

The objective function of GenX minimizes total annual electricity system costs over the following components shown in the below equation:

\[\begin{aligned} +Objective Function · GenX.jl

Objective Function

The objective function of GenX minimizes total annual electricity system costs over the following components shown in the below equation:

\[\begin{aligned} \text{min} \quad &\sum_{y \in \mathcal{G}} \sum_{z \in \mathcal{Z}} \left((\pi^{INVEST}_{y,z} \times \overline{\Omega}^{size}_{y,z} \times \Omega_{y,z}) + (\pi^{FOM}_{y,z} \times \overline{\Omega}^{size}_{y,z} \times \Delta^{total}_{y,z})\right) + \\ &\sum_{y \in \mathcal{O}} \sum_{z \in \mathcal{Z}} \left( (\pi^{INVEST,energy}_{y,z} \times \Omega^{energy}_{y,z}) + (\pi^{FOM,energy}_{y,z} \times \Delta^{total,energy}_{y,z})\right) + \\ @@ -28,4 +28,4 @@ & \sum_{y \in \mathcal{VS}^{sym,dc} \cup \mathcal{VS}^{asym,dc,cha}} \sum_{z \in \mathcal{Z}} \sum_{t \in \mathcal{T}} \left( \omega_{t}\times\pi^{VOM,dc,cha}_{y,z} \times \frac{\Pi^{dc}_{y,z,t}}{\eta^{inverter}_{y,z}}\right) + \\ & \sum_{y \in \mathcal{VS}^{sym,ac} \cup \mathcal{VS}^{asym,ac,dis}} \sum_{z \in \mathcal{Z}} \sum_{t \in \mathcal{T}} \left( \omega_{t}\times\pi^{VOM,ac,dis}_{y,z} \times \Theta^{ac}_{y,z,t}\right) + \\ & \sum_{y \in \mathcal{VS}^{sym,ac} \cup \mathcal{VS}^{asym,ac,cha}} \sum_{z \in \mathcal{Z}} \sum_{t \in \mathcal{T}} \left( \omega_{t}\times\pi^{VOM,ac,cha}_{y,z} \times \Pi^{ac}_{y,z,t}\right) -\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:

  1. where and how to invest on capacity,
  2. how to dispatch or operate that capacity,
  3. which consumer demand segments to serve or curtail,
  4. how to cycle and commit thermal units subject to unit commitment decisions,
  5. 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.

+\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:

  1. where and how to invest on capacity,
  2. how to dispatch or operate that capacity,
  3. which consumer demand segments to serve or curtail,
  4. how to cycle and commit thermal units subject to unit commitment decisions,
  5. 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.

diff --git a/previews/PR662/Model_Concept_Overview/power_balance/index.html b/previews/PR662/Model_Concept_Overview/power_balance/index.html index 81070d665a..85262efb5a 100644 --- a/previews/PR662/Model_Concept_Overview/power_balance/index.html +++ b/previews/PR662/Model_Concept_Overview/power_balance/index.html @@ -1,7 +1,7 @@ -Power Balance · GenX

Power Balance

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).

\[\begin{aligned} +Power Balance · GenX.jl

Power Balance

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).

\[\begin{aligned} &\sum_{y\in \mathcal{H}}{\Theta_{y,z,t}} +\sum_{y\in \mathcal{VRE}}{\Theta_{y,z,t}} +\sum_{y\in \mathcal{MR}}{\Theta_{y,z,t}} + \sum_{y\in \mathcal{O}}{(\Theta_{y,z,t}-\Pi_{y,z,t})} + \\ & \sum_{y\in \mathcal{DF}}{(-\Theta_{y,z,t}+\Pi_{y,z,t})} +\sum_{y\in \mathcal{W}}{\Theta_{y,z,t}}+ \sum_{y\in \mathcal{VS}}{\Theta_{y,z,t}} - \sum_{y\in \mathcal{VS}^{stor}}{\Pi_{y,z,t}} + \\ & \sum_{s\in \mathcal{S}}{\Lambda_{s,z,t}} - \sum_{l\in \mathcal{L}}{(\varphi^{map}_{l,z} \times \Phi_{l,t})} -\frac{1}{2} \sum_{l\in \mathcal{L}}{(\varphi^{map}_{l,z} \times \beta_{l,t}(\cdot))} = D_{z,t} \quad \quad \forall z\in \mathcal{Z}, t \in \mathcal{T} -\end{aligned}\]

+\end{aligned}\]

diff --git a/previews/PR662/Model_Reference/Multi_Stage/configure_multi_stage_inputs/index.html b/previews/PR662/Model_Reference/Multi_Stage/configure_multi_stage_inputs/index.html index 1eca1ae641..67d9e49998 100644 --- a/previews/PR662/Model_Reference/Multi_Stage/configure_multi_stage_inputs/index.html +++ b/previews/PR662/Model_Reference/Multi_Stage/configure_multi_stage_inputs/index.html @@ -1,4 +1,4 @@ -Configure multi-stage inputs · GenX

Configure multi stage inputs

GenX.compute_overnight_capital_costMethod
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:

\[\begin{aligned} +Configure multi-stage inputs · GenX.jl

Configure multi stage inputs

GenX.compute_overnight_capital_costMethod
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:

\[\begin{aligned} & OCC_{y} = \sum^{min(CRP_{y},H)}_{i=1}\frac{AIC_{y}}{(1+WACC_{y})^{i}} -\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.
  • inv_costs_yr - array object containing annualized investment costs.
  • 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.

source
GenX.configure_multi_stage_inputsMethod
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:

  1. Overnight capital costs are computed via the compute_overnight_capital_cost() method and overwrite internal model representations of annualized investment costs.

  2. 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).

  3. Internal set representations of resources eligible for capacity retirements are overwritten to ensure compatability with multi-stage modeling.

  4. 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.

source
+\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.
  • inv_costs_yr - array object containing annualized investment costs.
  • 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.

source
GenX.configure_multi_stage_inputsMethod
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:

  1. Overnight capital costs are computed via the compute_overnight_capital_cost() method and overwrite internal model representations of annualized investment costs.

  2. 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).

  3. Internal set representations of resources eligible for capacity retirements are overwritten to ensure compatability with multi-stage modeling.

  4. 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.

source
diff --git a/previews/PR662/Model_Reference/Multi_Stage/dual_dynamic_programming/index.html b/previews/PR662/Model_Reference/Multi_Stage/dual_dynamic_programming/index.html index 9f2f39fc7a..0b65128fd3 100644 --- a/previews/PR662/Model_Reference/Multi_Stage/dual_dynamic_programming/index.html +++ b/previews/PR662/Model_Reference/Multi_Stage/dual_dynamic_programming/index.html @@ -1,12 +1,12 @@ -Model multi stage: Dual Dynamic Programming Algorithm · GenX

Dual Dynamic Programming Algorithm

GenX.add_cutMethod
add_cut(EP_cur::Model, EP_next::Model, start_cap_d::Dict, cap_track_d::Dict)

inputs:

  • 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.

source
GenX.configure_ddp_dictsMethod
configure_ddp_dicts(setup::Dict, inputs::Dict)

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.
source
GenX.fix_capacity_trackingMethod
fix_capacity_tracking(EP_prev::Model, EP_cur::Model, cap_track_d::Dict, cur_stage::Int)

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.

source
GenX.fix_initial_investmentsMethod
fix_initial_investments(EP_prev::Model, EP_cur::Model, start_cap_d::Dict)

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.

source
GenX.generate_cut_component_invMethod
generate_cut_component_inv(EP_cur::Model, EP_next::Model, expr_name::Symbol, constr_name::Symbol)

This function generates Bender's cut expressions for linking capacity investment variable expression in the form:

\[\begin{aligned} +Model multi stage: Dual Dynamic Programming Algorithm · GenX.jl

Dual Dynamic Programming Algorithm

GenX.add_cutMethod
add_cut(EP_cur::Model, EP_next::Model, start_cap_d::Dict, cap_track_d::Dict)

inputs:

  • 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.

source
GenX.configure_ddp_dictsMethod
configure_ddp_dicts(setup::Dict, inputs::Dict)

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.
source
GenX.fix_capacity_trackingMethod
fix_capacity_tracking(EP_prev::Model, EP_cur::Model, cap_track_d::Dict, cur_stage::Int)

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.

source
GenX.fix_initial_investmentsMethod
fix_initial_investments(EP_prev::Model, EP_cur::Model, start_cap_d::Dict)

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.

source
GenX.generate_cut_component_invMethod
generate_cut_component_inv(EP_cur::Model, EP_next::Model, expr_name::Symbol, constr_name::Symbol)

This function generates Bender's cut expressions for linking capacity investment variable expression in the form:

\[\begin{aligned} \mu_{next}^{\top}(\hat{x}_{cur} - x_{cur}) -\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.

source
GenX.generate_cut_component_trackMethod
generate_cut_component_inv(EP_cur::Model, EP_next::Model, expr_name::Symbol, constr_name::Symbol)

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.

source
GenX.generate_cut_component_trackMethod
generate_cut_component_inv(EP_cur::Model, EP_next::Model, expr_name::Symbol, constr_name::Symbol)

This function generates Bender's cut expressions for total new or retired capacity tracking linking variables in the form:

\[\begin{aligned} \mu_{next}^{\top}(\hat{x}_{cur} - x_{cur}) -\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.

source
GenX.initialize_cost_to_goMethod
initialize_cost_to_go(settings_d::Dict, EP::Model)

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.

source
GenX.initialize_cost_to_goMethod
initialize_cost_to_go(settings_d::Dict, EP::Model)

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} OBJ^{*} = DF * OPEXMULT * OBJ + \alpha \end{aligned}\]

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:

\[\begin{aligned} DF = \frac{1}{(1+WACC)^{L*(p-1)}} \end{aligned}\]

where $WACC$ is the weighted average cost of capital, and $L$ is the length of each stage in years (both set in multi_stage_settings.yml)

The second term is a discounted sum of annual operational expenses incurred each year of a multi-year model stage:

\[\begin{aligned} & OPEXMULT = \sum^{L}_{l=1}\frac{1}{(1+WACC)^{l-1}} -\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.

source
GenX.run_ddpMethod
run_ddp(models_d::Dict, setup::Dict, inputs_d::Dict)

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.
source
GenX.write_multi_stage_outputsMethod
write_multi_stage_outputs(stats_d::Dict, outpath::String, settings_d::Dict)

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.
source
+\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.

source
GenX.run_ddpMethod
run_ddp(models_d::Dict, setup::Dict, inputs_d::Dict)

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.
source
GenX.write_multi_stage_outputsMethod
write_multi_stage_outputs(stats_d::Dict, outpath::String, settings_d::Dict)

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.
source
diff --git a/previews/PR662/Model_Reference/Multi_Stage/endogenous_retirement/index.html b/previews/PR662/Model_Reference/Multi_Stage/endogenous_retirement/index.html index db31a7582b..12bcc62652 100644 --- a/previews/PR662/Model_Reference/Multi_Stage/endogenous_retirement/index.html +++ b/previews/PR662/Model_Reference/Multi_Stage/endogenous_retirement/index.html @@ -1,6 +1,6 @@ -Endogenous Retirement · GenX

Endogenous Retirement

GenX.endogenous_retirement_discharge!Method
endogenous_retirement_discharge!(EP::Model, inputs::Dict, num_stages::Int, cur_stage::Int, stage_lens::Array{Int, 1})

This function models the following constraint

\[\begin{aligned} +Endogenous Retirement · GenX.jl

Endogenous Retirement

GenX.endogenous_retirement_discharge!Method
endogenous_retirement_discharge!(EP::Model, inputs::Dict, num_stages::Int, cur_stage::Int, stage_lens::Array{Int, 1})

This function models the following constraint

\[\begin{aligned} & RETCAP_{y,p} \geq \sum^p_{t=1} MINRET_{y,t} + \sum^r_{t=1}CAP_{y,t} - \sum^{(p-1)}_{t=1}RETCAP_{y,t} \end{aligned}\]

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:

\[\begin{aligned} \sum^p_{t=r+1}StageLength_{t} \leq LifeTime_{y} -\end{aligned}\]

source
GenX.get_retirement_stageMethod
get_retirement_stage(cur_stage::Int, stage_len::Int, lifetime::Int, stage_lens::Array{Int, 1})

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.

source
+\end{aligned}\]

source
GenX.get_retirement_stageMethod
get_retirement_stage(cur_stage::Int, stage_len::Int, lifetime::Int, stage_lens::Array{Int, 1})

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.

source
diff --git a/previews/PR662/Model_Reference/Multi_Stage/multi_stage_overview/index.html b/previews/PR662/Model_Reference/Multi_Stage/multi_stage_overview/index.html index 1db17b90dd..d9b251b27c 100644 --- a/previews/PR662/Model_Reference/Multi_Stage/multi_stage_overview/index.html +++ b/previews/PR662/Model_Reference/Multi_Stage/multi_stage_overview/index.html @@ -1,2 +1,2 @@ -Multi-Stage Modeling Introduction · GenX

Multi-stage investment planning

Added in 0.3

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.

+Multi-Stage Modeling Introduction · GenX.jl

Multi-stage investment planning

Added in 0.3

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.

diff --git a/previews/PR662/Model_Reference/Resources/curtailable_variable_renewable/index.html b/previews/PR662/Model_Reference/Resources/curtailable_variable_renewable/index.html index c7a7da5e28..b4affd2a03 100644 --- a/previews/PR662/Model_Reference/Resources/curtailable_variable_renewable/index.html +++ b/previews/PR662/Model_Reference/Resources/curtailable_variable_renewable/index.html @@ -1,7 +1,7 @@ -Curtailable Variable Renewable · GenX

Curtailable Variable Renewables

GenX.curtailable_variable_renewable!Method
curtailable_variable_renewable!(EP::Model, inputs::Dict, setup::Dict)

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:

\[\begin{aligned} +Curtailable Variable Renewable · GenX.jl

Curtailable Variable Renewables

GenX.curtailable_variable_renewable!Method
curtailable_variable_renewable!(EP::Model, inputs::Dict, setup::Dict)

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:

\[\begin{aligned} \Theta_{y,z,t} \leq \sum_{(x,z)\in \overline{\mathcal{VRE}}^{x,z}}{\rho^{max}_{x,z,t} \times \Delta^{total}_{x,z}} \hspace{2 cm} \forall y,z \in \{(y,z)|VREIndex_{y,z}=1, z \in \mathcal{Z}\},t \in \mathcal{T} -\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.

source
GenX.curtailable_variable_renewable_operational_reserves!Method
curtailable_variable_renewable_operational_reserves!(EP::Model, inputs::Dict)

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.

source
GenX.curtailable_variable_renewable_operational_reserves!Method
curtailable_variable_renewable_operational_reserves!(EP::Model, inputs::Dict)

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} \Theta_{y,z,t} + f_{y,z,t} + r_{y,z,t} \leq \sum_{(x,z)\in \overline{\mathcal{VRE}}^{x,z}}{\rho^{max}_{x,z,t}\times \Delta^{total}_{x,z}} \hspace{0.1 cm} \forall y,z \in \{(y,z)|VREIndex_{y,z}=1, z \in \mathcal{Z}\},t \in \mathcal{T} \end{aligned}\]

The amount of downward frequency regulation reserves also cannot exceed the current power output.

\[\begin{aligned} f_{y,z,t} \leq \Theta_{y,z,t} @@ -9,4 +9,4 @@ \end{aligned}\]

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.

\[\begin{aligned} r_{y,z,t} \leq \upsilon^{rsv}_{y,z} \sum_{(x,z)\in \overline{\mathcal{VRE}}^{x,z}}{\rho^{max}_{x,z,t}\times \Delta^{total}_{x,z}} \hspace{1 cm} \forall y,z \in \{(y,z)|VREIndex_{y,z}=1, z \in \mathcal{Z}\},t \in \mathcal{T} \\ f_{y,z,t} \leq \upsilon^{reg}_{y,z} \sum_{(x,z)\in \overline{\mathcal{VRE}}^{x,z}}{\rho^{max}_{x,z,t}\times \Delta^{total}_{x,z}} \hspace{1 cm} \forall y,z \in \{(y,z)|VREIndex_{y,z}=1, z \in \mathcal{Z}\},t \in \mathcal{T} -\end{aligned}\]

source
+\end{aligned}\]

source
diff --git a/previews/PR662/Model_Reference/Resources/electrolyzers/index.html b/previews/PR662/Model_Reference/Resources/electrolyzers/index.html index d549c80fc2..6349f2c18f 100644 --- a/previews/PR662/Model_Reference/Resources/electrolyzers/index.html +++ b/previews/PR662/Model_Reference/Resources/electrolyzers/index.html @@ -1,5 +1,5 @@ -Hydrogen Electrolyzers · GenX

Hydrogen Electrolyzers

GenX.electrolyzer!Method
electrolyzer!(EP::Model, inputs::Dict, setup::Dict)

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} +Hydrogen Electrolyzers · GenX.jl

Hydrogen Electrolyzers

GenX.electrolyzer!Method
electrolyzer!(EP::Model, inputs::Dict, setup::Dict)

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}\]

\[\begin{aligned} \Pi_{y,t} - \Pi_{y,t-1} \leq \kappa_{y}^{up} \Delta^{\text{total}}_{y} \hspace{1cm} \forall y \in \mathcal{EL}, \forall t \in \mathcal{T} @@ -15,4 +15,4 @@ \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):

\[\begin{aligned} \sum_{y \in \{z \cap \mathcal{Qualified}\}} \Theta_{y,t} \geq \sum_{y \in \{z \cap \mathcal{EL}\}} \Pi_{y,t} + \sum_{y \in \{z \cap \mathcal{Qualified} \cap \mathcal{STOR}\}} \Pi_{y,t} \hspace{1cm} \forall z \in \mathcal{Z}, \forall t \in \mathcal{T}, -\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.

source
+\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.

source
diff --git a/previews/PR662/Model_Reference/Resources/flexible_demand/index.html b/previews/PR662/Model_Reference/Resources/flexible_demand/index.html index e31a77ca83..9fffebbaed 100644 --- a/previews/PR662/Model_Reference/Resources/flexible_demand/index.html +++ b/previews/PR662/Model_Reference/Resources/flexible_demand/index.html @@ -1,5 +1,5 @@ -Flexible Demand · GenX

Flexible Demand

GenX.flexible_demand!Method
flexible_demand!(EP::Model, inputs::Dict, setup::Dict)

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} +Flexible Demand · GenX.jl

Flexible Demand

GenX.flexible_demand!Method
flexible_demand!(EP::Model, inputs::Dict, setup::Dict)

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}$).

\[\begin{aligned} @@ -10,4 +10,4 @@ \end{aligned}\]

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.

source
+\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.

source
diff --git a/previews/PR662/Model_Reference/Resources/hydro_inter_period_linkage/index.html b/previews/PR662/Model_Reference/Resources/hydro_inter_period_linkage/index.html index 500d788b33..a3e903b262 100644 --- a/previews/PR662/Model_Reference/Resources/hydro_inter_period_linkage/index.html +++ b/previews/PR662/Model_Reference/Resources/hydro_inter_period_linkage/index.html @@ -1,5 +1,5 @@ -Long Duration Hydro · GenX

Reservoir Hydro

GenX.hydro_inter_period_linkage!Method
hydro_inter_period_linkage!(EP::Model, inputs::Dict)

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} +Long Duration Hydro · GenX.jl

Reservoir Hydro

GenX.hydro_inter_period_linkage!Method
hydro_inter_period_linkage!(EP::Model, inputs::Dict)

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). Modeling inter-period energy exchange via long-duration storage when using representative period temporal resolution to approximate annual grid operations 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.

\[\begin{aligned} @@ -14,4 +14,4 @@ \end{aligned}\]

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}\]

source
+\end{aligned}\]

source
diff --git a/previews/PR662/Model_Reference/Resources/hydro_res/index.html b/previews/PR662/Model_Reference/Resources/hydro_res/index.html index 17f38e0ae5..73e608e386 100644 --- a/previews/PR662/Model_Reference/Resources/hydro_res/index.html +++ b/previews/PR662/Model_Reference/Resources/hydro_res/index.html @@ -1,5 +1,5 @@ -Hydro Reservoir · GenX

Hydro Resources

GenX.hydro_res!Method
hydro_res!(EP::Model, inputs::Dict, setup::Dict)

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} +Hydro Reservoir · GenX.jl

Hydro Resources

GenX.hydro_res!Method
hydro_res!(EP::Model, inputs::Dict, setup::Dict)

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}$).

\[\begin{aligned} @@ -20,7 +20,7 @@ \end{aligned}\]

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}\]

source
GenX.hydro_res_operational_reserves!Method
hydro_res_operational_reserves!(EP::Model, inputs::Dict)

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} +\end{aligned}\]

source
GenX.hydro_res_operational_reserves!Method
hydro_res_operational_reserves!(EP::Model, inputs::Dict)

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}\]

source
+\end{aligned}\]

source
diff --git a/previews/PR662/Model_Reference/Resources/investment_charge/index.html b/previews/PR662/Model_Reference/Resources/investment_charge/index.html index 7fea536d49..9137cfb7d2 100644 --- a/previews/PR662/Model_Reference/Resources/investment_charge/index.html +++ b/previews/PR662/Model_Reference/Resources/investment_charge/index.html @@ -1,5 +1,5 @@ -Investment Charge · GenX

Investment Charge

GenX.investment_charge!Method
investment_charge!(EP::Model, inputs::Dict)

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} +Investment Charge · GenX.jl

Investment Charge

GenX.investment_charge!Method
investment_charge!(EP::Model, inputs::Dict)

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.

\[\begin{aligned} &\Delta^{charge}_{y,z} \leq \overline{\Delta^{charge}_{y,z}} @@ -13,4 +13,4 @@ & \sum_{y \in \mathcal{O}^{asym} } \sum_{z \in \mathcal{Z}} \left( (\pi^{INVEST,charge}_{y,z} \times \Omega^{charge}_{y,z}) + (\pi^{FOM,charge}_{y,z} \times \Delta^{total,charge}_{y,z})\right) -\end{aligned}\]

source
+\end{aligned}\]

source
diff --git a/previews/PR662/Model_Reference/Resources/investment_energy/index.html b/previews/PR662/Model_Reference/Resources/investment_energy/index.html index c9f4d91258..4789530c79 100644 --- a/previews/PR662/Model_Reference/Resources/investment_energy/index.html +++ b/previews/PR662/Model_Reference/Resources/investment_energy/index.html @@ -1,5 +1,5 @@ -Investment Energy · GenX

Investment Energy

GenX.investment_energy!Method
investment_energy!(EP::Model, inputs::Dict)

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} +Investment Energy · GenX.jl

Investment Energy

GenX.investment_energy!Method
investment_energy!(EP::Model, inputs::Dict)

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.

\[\begin{aligned} &\Delta^{energy}_{y,z} \leq \overline{\Delta^{energy}_{y,z}} @@ -13,4 +13,4 @@ & \sum_{y \in \mathcal{O} } \sum_{z \in \mathcal{Z}} \left( (\pi^{INVEST,energy}_{y,z} \times \Omega^{energy}_{y,z}) + (\pi^{FOM,energy}_{y,z} \times \Delta^{total,energy}_{y,z})\right) -\end{aligned}\]

source
+\end{aligned}\]

source
diff --git a/previews/PR662/Model_Reference/Resources/long_duration_storage/index.html b/previews/PR662/Model_Reference/Resources/long_duration_storage/index.html index c5de37521c..58f3b9b025 100644 --- a/previews/PR662/Model_Reference/Resources/long_duration_storage/index.html +++ b/previews/PR662/Model_Reference/Resources/long_duration_storage/index.html @@ -1,5 +1,5 @@ -Long Duration Storage · GenX

Long Duration Storage

GenX.long_duration_storage!Method
long_duration_storage!(EP::Model, inputs::Dict, setup::Dict)

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} +Long Duration Storage · GenX.jl

Long Duration Storage

GenX.long_duration_storage!Method
long_duration_storage!(EP::Model, inputs::Dict, setup::Dict)

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).

Modeling inter-period energy exchange via long-duration storage when using representative period temporal resolution to approximate annual grid operations 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.

\[\begin{aligned} @@ -14,4 +14,4 @@ \end{aligned}\]

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.

source
+\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.

source
diff --git a/previews/PR662/Model_Reference/Resources/maintenance/index.html b/previews/PR662/Model_Reference/Resources/maintenance/index.html index 42edd94b73..7efb8afd5c 100644 --- a/previews/PR662/Model_Reference/Resources/maintenance/index.html +++ b/previews/PR662/Model_Reference/Resources/maintenance/index.html @@ -1,5 +1,5 @@ -Scheduled maintenance for various resources · GenX

Optimized Scheduled Maintenance

Added in v0.4

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).

Description of the maintenance model

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.

Treatment of plants that require maintenance only every few years

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.

Reduction of number of possible start dates

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.)

How to use

There are four columns which need to be added to the plant data, i.e. in the resource .csv files:

  1. MAINT should be 1 for plants that require maintenance and 0 otherwise.
  2. Maintenance_Duration is the number of hours the maintenance period lasts.
  3. Maintenance_Cycle_Length_Years. If 1, maintenance every year, if 3 maintenance every 3 years, etc.
  4. Maintenance_Begin_Cadence. Spacing between hours in which maintenance can start.

The last three fields must be integers which are greater than 0. They are ignored for any plants which do not require maintenance.

Maintenance_Duration must be less than the total number of hours in the year.

If Maintenance_Begin_Cadence is 1 then the maintenance can begin in any hour. If it is 168 then it can begin in hours 1, 169, 337, etc.

Restrictions on use

The maintenance module has these restrictions:

  • More than a single maintenance period per year (i.e. every three months) is not possible in the current formulation.
  • Only full-year cases can be run; there must be only one "representative period".

It would not make sense to model a month-long maintenance period when the year is modeled as a series of representative weeks, for example.

Interaction with integer unit commitment

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.

Hint: pre-scheduling 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.

Outputs produced

If at least one plant has MAINT=1, a file maint_down.csv will be written listing how many plants are down for maintenance in each timestep.

Notes on mathematical formulation

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.

Developer note: adding maintenance to a resource

The maintenance formulation is applied on a per-resource basis, by calling the function maintenance_formulation!.

GenX.maintenance_formulation!Function
maintenance_formulation!(EP::Model,
+Scheduled maintenance for various resources · GenX.jl

Optimized Scheduled Maintenance

Added in v0.4

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).

Description of the maintenance model

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.

Treatment of plants that require maintenance only every few years

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.

Reduction of number of possible start dates

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.)

How to use

There are four columns which need to be added to the plant data, i.e. in the resource .csv files:

  1. MAINT should be 1 for plants that require maintenance and 0 otherwise.
  2. Maintenance_Duration is the number of hours the maintenance period lasts.
  3. Maintenance_Cycle_Length_Years. If 1, maintenance every year, if 3 maintenance every 3 years, etc.
  4. Maintenance_Begin_Cadence. Spacing between hours in which maintenance can start.

The last three fields must be integers which are greater than 0. They are ignored for any plants which do not require maintenance.

Maintenance_Duration must be less than the total number of hours in the year.

If Maintenance_Begin_Cadence is 1 then the maintenance can begin in any hour. If it is 168 then it can begin in hours 1, 169, 337, etc.

Restrictions on use

The maintenance module has these restrictions:

  • More than a single maintenance period per year (i.e. every three months) is not possible in the current formulation.
  • Only full-year cases can be run; there must be only one "representative period".

It would not make sense to model a month-long maintenance period when the year is modeled as a series of representative weeks, for example.

Interaction with integer unit commitment

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.

Hint: pre-scheduling 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.

Outputs produced

If at least one plant has MAINT=1, a file maint_down.csv will be written listing how many plants are down for maintenance in each timestep.

Notes on mathematical formulation

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.

Developer note: adding maintenance to a resource

The maintenance formulation is applied on a per-resource basis, by calling the function maintenance_formulation!.

GenX.maintenance_formulation!Function
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.
source
GenX.resources_with_maintenanceFunction
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.
source
GenX.maintenance_down_nameFunction
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).
source
GenX.maintenance_shut_nameFunction
maintenance_shut_name(resource_component::AbstractString)::String
+Here resource-component could be a whole resource or a component (for complex resources).
source
GenX.maintenance_shut_nameFunction
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).
source
GenX.controlling_maintenance_start_hoursFunction
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).
source
GenX.controlling_maintenance_start_hoursFunction
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
source
GenX.ensure_maintenance_variable_records!Function
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.
source
GenX.has_maintenanceFunction
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.
source
GenX.maintenance_down_variablesFunction
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.
source
+This is available only after `maintenance_formulation!` has been called.
source
diff --git a/previews/PR662/Model_Reference/Resources/must_run/index.html b/previews/PR662/Model_Reference/Resources/must_run/index.html index 9a748d9efe..0b533c6f94 100644 --- a/previews/PR662/Model_Reference/Resources/must_run/index.html +++ b/previews/PR662/Model_Reference/Resources/must_run/index.html @@ -1,5 +1,5 @@ -Must Run · GenX

Must Run

GenX.must_run!Method
must_run!(EP::Model, inputs::Dict, setup::Dict)

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} +Must Run · GenX.jl

Must Run

GenX.must_run!Method
must_run!(EP::Model, inputs::Dict, setup::Dict)

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}\]

source
+\end{aligned}\]

source
diff --git a/previews/PR662/Model_Reference/Resources/resource/index.html b/previews/PR662/Model_Reference/Resources/resource/index.html index 68119ccda2..b95eb1af1d 100644 --- a/previews/PR662/Model_Reference/Resources/resource/index.html +++ b/previews/PR662/Model_Reference/Resources/resource/index.html @@ -1,39 +1,39 @@ -Resource types · GenX

Resource types and function interfaces

GenX.resource_typesConstant
resource_types

Name of the type of resources available in the model.

Possible values:

  • :Thermal
  • :Vre
  • :Hydro
  • :Storage
  • :MustRun
  • :FlexDemand
  • :VreStorage
  • :Electrolyzer
source
Base.findallMethod
findall(f::Function, rs::Vector{<:AbstractResource})

Find all resources in the vector rs that satisfy the condition given by the function f. Return the resource id instead of the vector index.

Arguments

  • f::Function: The condition function.
  • rs::Vector{<:AbstractResource}: The vector of resources.

Returns

  • Vector: The vector of resource ids.

Examples

julia> findall(r -> max_cap_mwh(r) != 0, gen.Storage)
+Resource types · GenX.jl

Resource types and function interfaces

GenX.resource_typesConstant
resource_types

Name of the type of resources available in the model.

Possible values:

  • :Thermal
  • :Vre
  • :Hydro
  • :Storage
  • :MustRun
  • :FlexDemand
  • :VreStorage
  • :Electrolyzer
source
Base.findallMethod
findall(f::Function, rs::Vector{<:AbstractResource})

Find all resources in the vector rs that satisfy the condition given by the function f. Return the resource id instead of the vector index.

Arguments

  • f::Function: The condition function.
  • rs::Vector{<:AbstractResource}: The vector of resources.

Returns

  • Vector: The vector of resource ids.

Examples

julia> findall(r -> max_cap_mwh(r) != 0, gen.Storage)
 3-element Vector{Int64}:
  48
  49
- 50
source
Base.getMethod
Base.get(r::AbstractResource, sym::Symbol, default)

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.
source
Base.getpropertyMethod
Base.getproperty(r::AbstractResource, sym::Symbol)

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.
source
Base.getpropertyMethod
Base.getproperty(rs::Vector{<:AbstractResource}, sym::Symbol)

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
source
Base.getMethod
Base.get(r::AbstractResource, sym::Symbol, default)

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.
source
Base.getpropertyMethod
Base.getproperty(r::AbstractResource, sym::Symbol)

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.
source
Base.getpropertyMethod
Base.getproperty(rs::Vector{<:AbstractResource}, sym::Symbol)

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
source
Base.haskeyMethod
haskey(r::AbstractResource, sym::Symbol)

Check if an AbstractResource object has a specific attribute. It returns a boolean value indicating whether the attribute exists in the parent object.

Arguments:

  • r::AbstractResource: The resource object.
  • sym::Symbol: The symbol representing the attribute name.

Returns:

  • true if the attribute exists in the parent object, false otherwise.
source
Base.pairsMethod
pairs(r::AbstractResource)

Return an iterator of key-value pairs with the attributes of a given resource.

Arguments

  • r::AbstractResource: The resource.

Returns

  • Pairs: An iterator of key-value pairs over the attributes.
source
Base.setindex!Method
Base.setindex!(rs::Vector{<:AbstractResource}, value::Vector, sym::Symbol)

Define dot syntax for setting the attributes specified by sym to the corresponding values in value for a vector of resources.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • value::Vector: The vector of values to set for the attribute.
  • sym::Symbol: The symbol representing the attribute to set.

Returns

  • rs::Vector{<:AbstractResource}: The updated vector of resources.
source
Base.setproperty!Method
setproperty!(r::AbstractResource, sym::Symbol, value)

Allows to set the attribute sym of an AbstractResource object using dot syntax.

Arguments:

  • r::AbstractResource: The resource object.
  • sym::Symbol: The symbol representing the attribute name.
  • value: The value to set for the attribute.
source
Base.setproperty!Method
Base.setproperty!(rs::Vector{<:AbstractResource}, sym::Symbol, value::Vector)

Set the attributes specified by sym to the corresponding values in value for a vector of resources.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • sym::Symbol: The symbol representing the attribute to set.
  • value::Vector: The vector of values to set for the attribute.

Returns

  • rs::Vector{<:AbstractResource}: The updated vector of resources.
source
Base.showMethod
show(io::IO, r::AbstractResource)

Print the attributes of the given resource.

Arguments

  • io::IO: The IO stream to print to.
  • r::AbstractResource: The resource.
source
GenX.attributesMethod
attributes(r::AbstractResource)

Returns a tuple of the attribute names of the given resource.

Arguments

  • r::AbstractResource: The resource.

Returns

  • Tuple: A tuple with symbols representing the attribute names.
source
GenX.electrolyzerMethod
electrolyzer(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all electrolyzer resources in the vector rs.

source
GenX.flex_demandMethod
flex_demand(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all flexible demand resources in the vector rs.

source
GenX.has_all_options_contributingMethod
has_all_options_contributing(retrofit_res::AbstractResource, rs::Vector{T}) where T <: AbstractResource

Check if all retrofit options in the retrofit cluster of the retrofit resource retrofit_res contribute to min retirement.

Arguments

  • retrofit_res::AbstractResource: The retrofit resource.
  • rs::Vector{T}: The vector of resources.

Returns

  • Bool: True if all retrofit options contribute to min retirement, otherwise false.
source
GenX.has_all_options_not_contributingMethod
has_all_options_not_contributing(retrofit_res::AbstractResource, rs::Vector{T}) where T <: AbstractResource

Check if all retrofit options in the retrofit cluster of the retrofit resource retrofit_res do not contribute to min retirement.

Arguments

  • retrofit_res::AbstractResource: The retrofit resource.
  • rs::Vector{T}: The vector of resources.

Returns

  • Bool: True if all retrofit options do not contribute to min retirement, otherwise false.
source
GenX.hydroMethod
hydro(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all hydro resources in the vector rs.

source
GenX.ids_withMethod
ids_with(rs::Vector{T}, f::Function, default=default_zero) where T <: AbstractResource

Function for finding resources in a vector rs where the attribute specified by f is not equal to default.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • f::Function: The getter of the attribute.
  • default: The default value of the attribute.

Returns

  • ids (Vector{Int64}): The vector of resource ids with attribute not equal to default.

Examples

julia> ids_with(gen.Thermal, existing_cap_mw)
+julia> vre_gen.zone
source
Base.haskeyMethod
haskey(r::AbstractResource, sym::Symbol)

Check if an AbstractResource object has a specific attribute. It returns a boolean value indicating whether the attribute exists in the parent object.

Arguments:

  • r::AbstractResource: The resource object.
  • sym::Symbol: The symbol representing the attribute name.

Returns:

  • true if the attribute exists in the parent object, false otherwise.
source
Base.pairsMethod
pairs(r::AbstractResource)

Return an iterator of key-value pairs with the attributes of a given resource.

Arguments

  • r::AbstractResource: The resource.

Returns

  • Pairs: An iterator of key-value pairs over the attributes.
source
Base.setindex!Method
Base.setindex!(rs::Vector{<:AbstractResource}, value::Vector, sym::Symbol)

Define dot syntax for setting the attributes specified by sym to the corresponding values in value for a vector of resources.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • value::Vector: The vector of values to set for the attribute.
  • sym::Symbol: The symbol representing the attribute to set.

Returns

  • rs::Vector{<:AbstractResource}: The updated vector of resources.
source
Base.setproperty!Method
setproperty!(r::AbstractResource, sym::Symbol, value)

Allows to set the attribute sym of an AbstractResource object using dot syntax.

Arguments:

  • r::AbstractResource: The resource object.
  • sym::Symbol: The symbol representing the attribute name.
  • value: The value to set for the attribute.
source
Base.setproperty!Method
Base.setproperty!(rs::Vector{<:AbstractResource}, sym::Symbol, value::Vector)

Set the attributes specified by sym to the corresponding values in value for a vector of resources.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • sym::Symbol: The symbol representing the attribute to set.
  • value::Vector: The vector of values to set for the attribute.

Returns

  • rs::Vector{<:AbstractResource}: The updated vector of resources.
source
Base.showMethod
show(io::IO, r::AbstractResource)

Print the attributes of the given resource.

Arguments

  • io::IO: The IO stream to print to.
  • r::AbstractResource: The resource.
source
GenX.attributesMethod
attributes(r::AbstractResource)

Returns a tuple of the attribute names of the given resource.

Arguments

  • r::AbstractResource: The resource.

Returns

  • Tuple: A tuple with symbols representing the attribute names.
source
GenX.electrolyzerMethod
electrolyzer(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all electrolyzer resources in the vector rs.

source
GenX.flex_demandMethod
flex_demand(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all flexible demand resources in the vector rs.

source
GenX.has_all_options_contributingMethod
has_all_options_contributing(retrofit_res::AbstractResource, rs::Vector{T}) where T <: AbstractResource

Check if all retrofit options in the retrofit cluster of the retrofit resource retrofit_res contribute to min retirement.

Arguments

  • retrofit_res::AbstractResource: The retrofit resource.
  • rs::Vector{T}: The vector of resources.

Returns

  • Bool: True if all retrofit options contribute to min retirement, otherwise false.
source
GenX.has_all_options_not_contributingMethod
has_all_options_not_contributing(retrofit_res::AbstractResource, rs::Vector{T}) where T <: AbstractResource

Check if all retrofit options in the retrofit cluster of the retrofit resource retrofit_res do not contribute to min retirement.

Arguments

  • retrofit_res::AbstractResource: The retrofit resource.
  • rs::Vector{T}: The vector of resources.

Returns

  • Bool: True if all retrofit options do not contribute to min retirement, otherwise false.
source
GenX.hydroMethod
hydro(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all hydro resources in the vector rs.

source
GenX.ids_withMethod
ids_with(rs::Vector{T}, f::Function, default=default_zero) where T <: AbstractResource

Function for finding resources in a vector rs where the attribute specified by f is not equal to default.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • f::Function: The getter of the attribute.
  • default: The default value of the attribute.

Returns

  • ids (Vector{Int64}): The vector of resource ids with attribute not equal to default.

Examples

julia> ids_with(gen.Thermal, existing_cap_mw)
 4-element Vector{Int64}:
  21
  22
  23
  24
 julia> existing_cap_mw(gen[21])
-7.0773
source
GenX.ids_withMethod
ids_with(rs::Vector{T}, name::Symbol, default=default_zero) where T <: AbstractResource

Function for finding resources in a vector rs where the attribute specified by name is not equal to the default value of the attribute.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • name::Symbol: The name of the attribute.
  • default: The default value of the attribute.

Returns

  • ids (Vector{Int64}): The vector of resource ids with attribute not equal to default.

Examples

julia> ids_with(gen.Thermal, :existing_cap_mw)
+7.0773
source
GenX.ids_withMethod
ids_with(rs::Vector{T}, name::Symbol, default=default_zero) where T <: AbstractResource

Function for finding resources in a vector rs where the attribute specified by name is not equal to the default value of the attribute.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • name::Symbol: The name of the attribute.
  • default: The default value of the attribute.

Returns

  • ids (Vector{Int64}): The vector of resource ids with attribute not equal to default.

Examples

julia> ids_with(gen.Thermal, :existing_cap_mw)
 4-element Vector{Int64}:
  21
  22
  23
  24
 julia> existing_cap_mw(gen[21])
-7.0773
source
GenX.ids_with_all_options_contributingMethod
ids_with_all_options_contributing(rs::Vector{T}) where T <: AbstractResource

Find the resource ids of the retrofit units in the vector rs where all retrofit options contribute to min retirement.

Arguments

  • rs::Vector{T}: The vector of resources.

Returns

  • Vector{Int64}: The vector of resource ids.
source
GenX.ids_with_all_options_not_contributingMethod
ids_with_all_options_not_contributing(rs::Vector{T}) where T <: AbstractResource

Find the resource ids of the retrofit units in the vector rs where all retrofit options do not contribute to min retirement.

Arguments

  • rs::Vector{T}: The vector of resources.

Returns

  • Vector{Int64}: The vector of resource ids.
source
GenX.ids_with_nonnegMethod
ids_with_nonneg(rs::Vector{T}, f::Function) where T <: AbstractResource

Function for finding resources in a vector rs where the attribute specified by f is non-negative.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • f::Function: The getter of the attribute.

Returns

  • ids (Vector{Int64}): The vector of resource ids with non-negative attribute.

Examples

julia> ids_with_nonneg(gen, max_cap_mw)
source
GenX.ids_with_nonnegMethod
ids_with_nonneg(rs::Vector{T}, f::Function) where T <: AbstractResource

Function for finding resources in a vector rs where the attribute specified by name is non-negative.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • name::Symbol: The name of the attribute.

Returns

  • ids (Vector{Int64}): The vector of resource ids with non-negative attribute.

Examples

julia> ids_with_nonneg(gen, max_cap_mw)
source
GenX.ids_with_policyMethod
ids_with_policy(rs::Vector{T}, f::Function; tag::Int64) where T <: AbstractResource

Function for finding resources in a vector rs where the policy specified by f with tag equal to tag is positive.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • f::Function: The policy getter function.
  • tag::Int64: The tag of the policy.

Returns

  • ids (Vector{Int64}): The vector of resource ids with a positive value for policy f and tag tag.
source
GenX.ids_with_policyMethod

idswithpolicy(rs::Vector{T}, name::Symbol; tag::Int64) where T <: AbstractResource

Function for finding resources in a vector rs where the policy specified by name with tag equal to tag is positive.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • name::Symbol: The name of the policy.
  • tag::Int64: The tag of the policy.

Returns

  • ids (Vector{Int64}): The vector of resource ids with a positive value for policy name and tag tag.
source
GenX.ids_with_positiveMethod
ids_with_positive(rs::Vector{T}, f::Function) where T <: AbstractResource

Function for finding indices of resources in a vector rs where the attribute specified by f is positive.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • f::Function: The getter of the attribute.

Returns

  • ids (Vector{Int64}): The vector of resource ids with positive attribute.

Examples

julia> ids_with_positive(gen, max_cap_mw)
+7.0773
source
GenX.ids_with_all_options_contributingMethod
ids_with_all_options_contributing(rs::Vector{T}) where T <: AbstractResource

Find the resource ids of the retrofit units in the vector rs where all retrofit options contribute to min retirement.

Arguments

  • rs::Vector{T}: The vector of resources.

Returns

  • Vector{Int64}: The vector of resource ids.
source
GenX.ids_with_all_options_not_contributingMethod
ids_with_all_options_not_contributing(rs::Vector{T}) where T <: AbstractResource

Find the resource ids of the retrofit units in the vector rs where all retrofit options do not contribute to min retirement.

Arguments

  • rs::Vector{T}: The vector of resources.

Returns

  • Vector{Int64}: The vector of resource ids.
source
GenX.ids_with_nonnegMethod
ids_with_nonneg(rs::Vector{T}, f::Function) where T <: AbstractResource

Function for finding resources in a vector rs where the attribute specified by f is non-negative.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • f::Function: The getter of the attribute.

Returns

  • ids (Vector{Int64}): The vector of resource ids with non-negative attribute.

Examples

julia> ids_with_nonneg(gen, max_cap_mw)
source
GenX.ids_with_nonnegMethod
ids_with_nonneg(rs::Vector{T}, f::Function) where T <: AbstractResource

Function for finding resources in a vector rs where the attribute specified by name is non-negative.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • name::Symbol: The name of the attribute.

Returns

  • ids (Vector{Int64}): The vector of resource ids with non-negative attribute.

Examples

julia> ids_with_nonneg(gen, max_cap_mw)
source
GenX.ids_with_policyMethod
ids_with_policy(rs::Vector{T}, f::Function; tag::Int64) where T <: AbstractResource

Function for finding resources in a vector rs where the policy specified by f with tag equal to tag is positive.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • f::Function: The policy getter function.
  • tag::Int64: The tag of the policy.

Returns

  • ids (Vector{Int64}): The vector of resource ids with a positive value for policy f and tag tag.
source
GenX.ids_with_policyMethod

idswithpolicy(rs::Vector{T}, name::Symbol; tag::Int64) where T <: AbstractResource

Function for finding resources in a vector rs where the policy specified by name with tag equal to tag is positive.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • name::Symbol: The name of the policy.
  • tag::Int64: The tag of the policy.

Returns

  • ids (Vector{Int64}): The vector of resource ids with a positive value for policy name and tag tag.
source
GenX.ids_with_positiveMethod
ids_with_positive(rs::Vector{T}, f::Function) where T <: AbstractResource

Function for finding indices of resources in a vector rs where the attribute specified by f is positive.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • f::Function: The getter of the attribute.

Returns

  • ids (Vector{Int64}): The vector of resource ids with positive attribute.

Examples

julia> ids_with_positive(gen, max_cap_mw)
 3-element Vector{Int64}:
  3 
  4
  5
 julia> max_cap_mw(gen[3])
-4.888236
source
GenX.ids_with_positiveMethod
ids_with_positive(rs::Vector{T}, name::Symbol) where T <: AbstractResource

Function for finding indices of resources in a vector rs where the attribute specified by name is positive.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • name::Symbol: The name of the attribute.

Returns

  • Vector{Int64}: The vector of resource ids with positive attribute.

Examples

julia> ids_with_positive(gen, :max_cap_mw)
+4.888236
source
GenX.ids_with_positiveMethod
ids_with_positive(rs::Vector{T}, name::Symbol) where T <: AbstractResource

Function for finding indices of resources in a vector rs where the attribute specified by name is positive.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • name::Symbol: The name of the attribute.

Returns

  • Vector{Int64}: The vector of resource ids with positive attribute.

Examples

julia> ids_with_positive(gen, :max_cap_mw)
 3-element Vector{Int64}:
  3 
  4
  5
 julia> max_cap_mw(gen[3])
-4.888236
source
GenX.must_runMethod
must_run(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all must-run resources in the vector rs.

source
GenX.resource_by_nameMethod
resource_by_name(rs::Vector{<:AbstractResource}, name::AbstractString)

Find the resource with name in the vector rs.

Arguments

  • rs: A vector of resources.
  • name: The name of the resource.

Returns

  • AbstractResource: The resource with the name name.
source
GenX.resources_in_retrofit_cluster_by_ridMethod
resources_in_retrofit_cluster_by_rid(rs::Vector{<:AbstractResource}, cluster_id::String)

Find RID's of resources with retrofit cluster id `clusterid`.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • cluster_id::String: The retrofit cluster id.

Returns

  • Vector{Int64}: The vector of resource ids in the retrofit cluster.
source
GenX.solarMethod
solar(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all co-located solar resources in the vector rs.

source
GenX.storageMethod
storage(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all storage resources in the vector rs.

source
GenX.storage_ac_chargeMethod
storage_ac_charge(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all co-located storage resources in the vector rs that charge AC.

source
GenX.storage_ac_dischargeMethod
storage_ac_discharge(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all co-located storage resources in the vector rs that discharge AC.

source
GenX.storage_dc_chargeMethod
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.
source
GenX.storage_dc_dischargeMethod
storage_dc_discharge(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all co-located storage resources in the vector rs that discharge DC.

source
GenX.thermalMethod
thermal(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all thermal resources in the vector rs.

source
GenX.validate_boolean_attributeMethod
validate_boolean_attribute(r::AbstractResource, attr::Symbol)

Validate that the attribute attr in the resource r is boolean {0, 1}.

Arguments

  • r::AbstractResource: The resource.
  • attr::Symbol: The name of the attribute.
source
GenX.vreMethod
vre(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all Vre resources in the vector rs.

source
GenX.vre_storMethod
vre_stor(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all VRE_STOR resources in the vector rs.

source
GenX.windMethod
wind(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all co-located wind resources in the vector rs.

source
GenX.@interfaceMacro
interface(name, default=default_zero, type=AbstractResource)

Define a function interface for accessing the attribute specified by name in a resource of type type.

Arguments

  • name: The name of the attribute.
  • default: The default value to return if the attribute is not found.
  • type: The type of the resource.

Returns

  • Function: The generated function.

Examples

julia> @interface max_cap_mw 0 Vre
+4.888236
source
GenX.must_runMethod
must_run(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all must-run resources in the vector rs.

source
GenX.resource_by_nameMethod
resource_by_name(rs::Vector{<:AbstractResource}, name::AbstractString)

Find the resource with name in the vector rs.

Arguments

  • rs: A vector of resources.
  • name: The name of the resource.

Returns

  • AbstractResource: The resource with the name name.
source
GenX.resources_in_retrofit_cluster_by_ridMethod
resources_in_retrofit_cluster_by_rid(rs::Vector{<:AbstractResource}, cluster_id::String)

Find RID's of resources with retrofit cluster id `clusterid`.

Arguments

  • rs::Vector{<:AbstractResource}: The vector of resources.
  • cluster_id::String: The retrofit cluster id.

Returns

  • Vector{Int64}: The vector of resource ids in the retrofit cluster.
source
GenX.solarMethod
solar(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all co-located solar resources in the vector rs.

source
GenX.storageMethod
storage(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all storage resources in the vector rs.

source
GenX.storage_ac_chargeMethod
storage_ac_charge(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all co-located storage resources in the vector rs that charge AC.

source
GenX.storage_ac_dischargeMethod
storage_ac_discharge(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all co-located storage resources in the vector rs that discharge AC.

source
GenX.storage_dc_chargeMethod
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.
source
GenX.storage_dc_dischargeMethod
storage_dc_discharge(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all co-located storage resources in the vector rs that discharge DC.

source
GenX.thermalMethod
thermal(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all thermal resources in the vector rs.

source
GenX.validate_boolean_attributeMethod
validate_boolean_attribute(r::AbstractResource, attr::Symbol)

Validate that the attribute attr in the resource r is boolean {0, 1}.

Arguments

  • r::AbstractResource: The resource.
  • attr::Symbol: The name of the attribute.
source
GenX.vreMethod
vre(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all Vre resources in the vector rs.

source
GenX.vre_storMethod
vre_stor(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all VRE_STOR resources in the vector rs.

source
GenX.windMethod
wind(rs::Vector{T}) where T <: AbstractResource

Returns the indices of all co-located wind resources in the vector rs.

source
GenX.@interfaceMacro
interface(name, default=default_zero, type=AbstractResource)

Define a function interface for accessing the attribute specified by name in a resource of type type.

Arguments

  • name: The name of the attribute.
  • default: The default value to return if the attribute is not found.
  • type: The type of the resource.

Returns

  • Function: The generated function.

Examples

julia> @interface max_cap_mw 0 Vre
 julia> max_cap_mw(gen.Vre[3])
 4.888236
 julia> max_cap_mw.(gen.Vre) # vectorized
@@ -42,4 +42,4 @@
   0.0
   4.888236
  20.835569
-  9.848441999999999
source
+ 9.848441999999999
source
diff --git a/previews/PR662/Model_Reference/Resources/retrofit/index.html b/previews/PR662/Model_Reference/Resources/retrofit/index.html index e566c81563..16308a4f62 100644 --- a/previews/PR662/Model_Reference/Resources/retrofit/index.html +++ b/previews/PR662/Model_Reference/Resources/retrofit/index.html @@ -1,4 +1,4 @@ -Retrofit · GenX

Retrofit

GenX.retrofitMethod
retrofit(EP::Model, inputs::Dict)

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.

\[\begin{aligned} +Retrofit · GenX.jl

Retrofit

GenX.retrofitMethod
retrofit(EP::Model, inputs::Dict)

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.

\[\begin{aligned} \sum_{y \in RS(id)}P_{y} = \sum_{r \in RO(id)}\frac{\Omega_{r}}{{ef}_{r}} \quad \quad \quad \quad \forall id \in {RETROFIT}, -\end{aligned}\]

where ${RETROFIT}$ represents the set of all retrofit IDs (clusters) in the model.

source
+\end{aligned}\]

where ${RETROFIT}$ represents the set of all retrofit IDs (clusters) in the model.

source
diff --git a/previews/PR662/Model_Reference/Resources/storage/index.html b/previews/PR662/Model_Reference/Resources/storage/index.html index d5515ca0de..f6f5798c1b 100644 --- a/previews/PR662/Model_Reference/Resources/storage/index.html +++ b/previews/PR662/Model_Reference/Resources/storage/index.html @@ -1,5 +1,5 @@ -Storage · GenX

Storage

GenX.storage!Function
storage!(EP::Model, inputs::Dict, setup::Dict)

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} +Storage · GenX.jl

Storage

GenX.storage!Function
storage!(EP::Model, inputs::Dict, setup::Dict)

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:

\[\begin{aligned} @@ -40,4 +40,4 @@ \end{aligned}\]

Finally, the constraints on maximum discharge rate are replaced by the following, to account for capacity contributed to regulation and reserves:

\[\begin{aligned} & \Theta_{o,z,t} + \Theta^{CRM}_{o,z,t} + f^{discharge}_{o,z,t} + r^{discharge}_{o,z,t} \leq \Delta^{total}_{o,z} & \quad \forall o \in \mathcal{O}, z \in \mathcal{Z}, t \in \mathcal{T}\\ & \Theta_{o,z,t} + \Theta^{CRM}_{o,z,t} + f^{discharge}_{o,z,t} + r^{discharge}_{o,z,t} \leq \Gamma_{o,z,t-1} & \quad \forall o \in \mathcal{O}, z \in \mathcal{Z}, t \in \mathcal{T} -\end{aligned}\]

The above reserve related constraints are established by storage_all_operational_reserves!() in storage_all.jl

source
+\end{aligned}\]

The above reserve related constraints are established by storage_all_operational_reserves!() in storage_all.jl

source
diff --git a/previews/PR662/Model_Reference/Resources/storage_all/index.html b/previews/PR662/Model_Reference/Resources/storage_all/index.html index 919ee80237..4ac4d089db 100644 --- a/previews/PR662/Model_Reference/Resources/storage_all/index.html +++ b/previews/PR662/Model_Reference/Resources/storage_all/index.html @@ -1,2 +1,2 @@ -Storage All · GenX

Storage All

GenX.storage_all!Method
storage_all!(EP::Model, inputs::Dict, setup::Dict)

Sets up variables and constraints common to all storage resources. See storage() in storage.jl for description of constraints.

source
+Storage All · GenX.jl

Storage All

GenX.storage_all!Method
storage_all!(EP::Model, inputs::Dict, setup::Dict)

Sets up variables and constraints common to all storage resources. See storage() in storage.jl for description of constraints.

source
diff --git a/previews/PR662/Model_Reference/Resources/storage_asymmetric/index.html b/previews/PR662/Model_Reference/Resources/storage_asymmetric/index.html index 906f24765a..687936a683 100644 --- a/previews/PR662/Model_Reference/Resources/storage_asymmetric/index.html +++ b/previews/PR662/Model_Reference/Resources/storage_asymmetric/index.html @@ -1,2 +1,2 @@ -Storage Asymmetric · GenX

Storage Asymmetric

GenX.storage_asymmetric!Method
storage_asymmetric!(EP::Model, inputs::Dict, setup::Dict)

Sets up variables and constraints specific to storage resources with asymmetric charge and discharge capacities. See storage() in storage.jl for description of constraints.

source
GenX.storage_asymmetric_operational_reserves!Method
storage_asymmetric_operational_reserves!(EP::Model, inputs::Dict)

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.

source
+Storage Asymmetric · GenX.jl

Storage Asymmetric

GenX.storage_asymmetric!Method
storage_asymmetric!(EP::Model, inputs::Dict, setup::Dict)

Sets up variables and constraints specific to storage resources with asymmetric charge and discharge capacities. See storage() in storage.jl for description of constraints.

source
GenX.storage_asymmetric_operational_reserves!Method
storage_asymmetric_operational_reserves!(EP::Model, inputs::Dict)

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.

source
diff --git a/previews/PR662/Model_Reference/Resources/storage_symmetric/index.html b/previews/PR662/Model_Reference/Resources/storage_symmetric/index.html index 8e0aef5cff..b60e5fbf60 100644 --- a/previews/PR662/Model_Reference/Resources/storage_symmetric/index.html +++ b/previews/PR662/Model_Reference/Resources/storage_symmetric/index.html @@ -1,2 +1,2 @@ -Storage Symmetric · GenX

Storage Symmetric

GenX.storage_symmetric!Method
storage_symmetric!(EP::Model, inputs::Dict, setup::Dict)

Sets up variables and constraints specific to storage resources with symmetric charge and discharge capacities. See storage() in storage.jl for description of constraints.

source
GenX.storage_symmetric_operational_reserves!Method
storage_symmetric_operational_reserves!(EP::Model, inputs::Dict)

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.

source
+Storage Symmetric · GenX.jl

Storage Symmetric

GenX.storage_symmetric!Method
storage_symmetric!(EP::Model, inputs::Dict, setup::Dict)

Sets up variables and constraints specific to storage resources with symmetric charge and discharge capacities. See storage() in storage.jl for description of constraints.

source
GenX.storage_symmetric_operational_reserves!Method
storage_symmetric_operational_reserves!(EP::Model, inputs::Dict)

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.

source
diff --git a/previews/PR662/Model_Reference/Resources/thermal/index.html b/previews/PR662/Model_Reference/Resources/thermal/index.html index 4e66550ed1..0b4a160d8f 100644 --- a/previews/PR662/Model_Reference/Resources/thermal/index.html +++ b/previews/PR662/Model_Reference/Resources/thermal/index.html @@ -1,6 +1,6 @@ -Thermal · GenX

Thermal

GenX.thermal!Method
thermal!(EP::Model, inputs::Dict, setup::Dict)

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).

source
GenX.thermal_plant_effective_capacityMethod
thermal_plant_effective_capacity(EP::Model,
+Thermal · GenX.jl

Thermal

GenX.thermal!Method
thermal!(EP::Model, inputs::Dict, setup::Dict)

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).

source
GenX.thermal_plant_effective_capacityMethod
thermal_plant_effective_capacity(EP::Model,
                                  inputs::Dict,
                                  resources::Vector{Int},
                                  capres_zone::Int,
-                                 timesteps::Vector{Int})::Matrix{Float64}

Effective capacity in a capacity reserve margin zone for certain resources in the given timesteps.

source
+ timesteps::Vector{Int})::Matrix{Float64}

Effective capacity in a capacity reserve margin zone for certain resources in the given timesteps.

source
diff --git a/previews/PR662/Model_Reference/Resources/thermal_commit/index.html b/previews/PR662/Model_Reference/Resources/thermal_commit/index.html index 936599d252..b4f91bd8fc 100644 --- a/previews/PR662/Model_Reference/Resources/thermal_commit/index.html +++ b/previews/PR662/Model_Reference/Resources/thermal_commit/index.html @@ -1,5 +1,5 @@ -Thermal Commit · GenX

Thermal Commit

GenX.thermal_commit!Method
thermal_commit!(EP::Model, inputs::Dict, setup::Dict)

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} +Thermal Commit · GenX.jl

Thermal Commit

GenX.thermal_commit!Method
thermal_commit!(EP::Model, inputs::Dict, setup::Dict)

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} @@ -33,7 +33,7 @@ \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.

source
GenX.thermal_commit_operational_reserves!Method
thermal_commit_operational_reserves!(EP::Model, inputs::Dict)

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.

source
GenX.thermal_commit_operational_reserves!Method
thermal_commit_operational_reserves!(EP::Model, inputs::Dict)

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}\]

source
+\end{aligned}\]

source
diff --git a/previews/PR662/Model_Reference/Resources/thermal_no_commit/index.html b/previews/PR662/Model_Reference/Resources/thermal_no_commit/index.html index e59ab8a2d4..d70cab8b7a 100644 --- a/previews/PR662/Model_Reference/Resources/thermal_no_commit/index.html +++ b/previews/PR662/Model_Reference/Resources/thermal_no_commit/index.html @@ -1,5 +1,5 @@ -Thermal No Commit · GenX

Thermal No Commit

GenX.thermal_no_commit!Method
thermal_no_commit!(EP::Model, inputs::Dict, setup::Dict)

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} +Thermal No Commit · GenX.jl

Thermal No Commit

GenX.thermal_no_commit!Method
thermal_no_commit!(EP::Model, inputs::Dict, setup::Dict)

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}\]

(See Constraints 3-4 in the code)

source
GenX.thermal_no_commit_operational_reserves!Method
thermal_no_commit_operational_reserves!(EP::Model, inputs::Dict)

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} +\end{aligned}\]

(See Constraints 3-4 in the code)

source
GenX.thermal_no_commit_operational_reserves!Method
thermal_no_commit_operational_reserves!(EP::Model, inputs::Dict)

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).

source
+\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).

source
diff --git a/previews/PR662/Model_Reference/Resources/vre_stor/index.html b/previews/PR662/Model_Reference/Resources/vre_stor/index.html index 8cf8f3d75d..509382a1e8 100644 --- a/previews/PR662/Model_Reference/Resources/vre_stor/index.html +++ b/previews/PR662/Model_Reference/Resources/vre_stor/index.html @@ -1,5 +1,5 @@ -Co-located VRE and Storage · GenX

Co-located VRE-Storage Module

GenX.inverter_vre_stor!Method
inverter_vre_stor!(EP::Model, inputs::Dict, setup::Dict)

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} +Co-located VRE and Storage · GenX.jl

Co-located VRE-Storage Module

GenX.inverter_vre_stor!Method
inverter_vre_stor!(EP::Model, inputs::Dict, setup::Dict)

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:

\[\begin{aligned} & \Delta^{inv}_{y,z} \leq \overline{\Delta^{inv}_{y,z}} @@ -24,7 +24,7 @@ & \sum_{y \in \mathcal{VS}^{inv}} \sum_{z \in \mathcal{Z}} \left( (\pi^{INVEST, inv}_{y,z} \times \Omega^{inv}_{y,z}) + (\pi^{FOM, inv}_{y,z} \times \Delta^{total,inv}_{y,z})\right) -\end{aligned}\]

source
GenX.investment_charge_vre_stor!Method
investment_charge_vre_stor!(EP::Model, inputs::Dict, setup::Dict)

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} +\end{aligned}\]

source
GenX.investment_charge_vre_stor!Method
investment_charge_vre_stor!(EP::Model, inputs::Dict, setup::Dict)

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}\]

source
GenX.lds_vre_stor!Method
lds_vre_stor!(EP::Model, inputs::Dict)

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:

\[\begin{aligned} +\end{aligned}\]

source
GenX.lds_vre_stor!Method
lds_vre_stor!(EP::Model, inputs::Dict)

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:

\[\begin{aligned} & \Gamma_{y,z,(m-1)\times \tau^{period}+1 } =\left(1-\eta_{y,z}^{loss}\right) \times \left(\Gamma_{y,z,m\times \tau^{period}} -\Delta Q_{y,z,m}\right) \\ & - \frac{\Theta^{dc}_{y,z,(m-1) \times \tau^{period}+1}}{\eta_{y,z}^{discharge,dc}} - \frac{\Theta^{ac}_{y,z,(m-1)\times \tau^{period}+1}}{\eta_{y,z}^{discharge,ac}} \\ & + \eta_{y,z}^{charge,dc} \times \Pi^{dc}_{y,z,(m-1)\times \tau^{period}+1} + \eta_{y,z}^{charge,ac} \times \Pi^{ac}_{y,z,(m-1)\times \tau^{period}+1} \quad \forall y \in \mathcal{VS}^{LDES}, z \in \mathcal{Z}, m \in \mathcal{M} -\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!().

source
GenX.solar_vre_stor!Method
solar_vre_stor!(EP::Model, inputs::Dict, setup::Dict)

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!().

source
GenX.solar_vre_stor!Method
solar_vre_stor!(EP::Model, inputs::Dict, setup::Dict)

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:

\[\begin{aligned} & \Delta^{pv}_{y,z} \leq \overline{\Delta^{pv}_{y,z}} @@ -112,7 +112,7 @@ & \sum_{y \in \mathcal{VS}^{pv}} \sum_{z \in \mathcal{Z}} \left( (\pi^{INVEST, pv}_{y,z} \times \Omega^{pv}_{y,z}) + (\pi^{FOM, pv}_{y,z} \times \Delta^{total,pv}_{y,z}) \right) \\ & + \sum_{y \in \mathcal{VS}^{pv}} \sum_{z \in \mathcal{Z}} \sum_{t \in \mathcal{T}} (\pi^{VOM, pv}_{y,z} \times \eta^{inverter}_{y,z} \times \Theta^{pv}_{y,z,t}) -\end{aligned}\]

source
GenX.stor_vre_stor!Method
stor_vre_stor!(EP::Model, inputs::Dict, setup::Dict)

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} +\end{aligned}\]

source
GenX.stor_vre_stor!Method
stor_vre_stor!(EP::Model, inputs::Dict, setup::Dict)

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:

\[\begin{aligned} &\Delta^{energy}_{y,z} \leq \overline{\Delta^{energy}_{y,z}} @@ -154,7 +154,7 @@ & + \sum_{y \in \mathcal{VS}^{sym,dc} \cup \mathcal{VS}^{asym,dc,cha}} \sum_{z \in \mathcal{Z}} \sum_{t \in \mathcal{T}} (\pi^{VOM,dc,cha}_{y,z} \times \frac{\Pi^{dc}_{y,z,t}}{\eta^{inverter}_{y,z}}) \\ & + \sum_{y \in \mathcal{VS}^{sym,ac} \cup \mathcal{VS}^{asym,ac,dis}} \sum_{z \in \mathcal{Z}} \sum_{t \in \mathcal{T}} (\pi^{VOM,ac,dis}_{y,z} \times \Theta^{ac}_{y,z,t}) \\ & + \sum_{y \in \mathcal{VS}^{sym,ac} \cup \mathcal{VS}^{asym,ac,cha}} \sum_{z \in \mathcal{Z}} \sum_{t \in \mathcal{T}} (\pi^{VOM,ac,cha}_{y,z} \times \Pi^{ac}_{y,z,t}) -\end{aligned}\]

source
GenX.vre_stor!Method
vre_stor!(EP::Model, inputs::Dict, setup::Dict)

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.

Configurable Co-located VRE and Storage Module Interactions and Decision Variables 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:

\[\begin{aligned} +\end{aligned}\]

source
GenX.vre_stor!Method
vre_stor!(EP::Model, inputs::Dict, setup::Dict)

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.

Configurable Co-located VRE and Storage Module Interactions and Decision Variables 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:

\[\begin{aligned} & \Theta_{y,z,t} - \Pi_{y,z,t} = \Theta_{y,z,t}^{wind} + \Theta_{y,z,t}^{ac} - \Pi_{y,z,t}^{ac} + \eta^{inverter}_{y,z} \times (\Theta_{y,z,t}^{pv} + \Theta_{y,z,t}^{dc}) - \frac{\Pi^{dc}_{y,z,t}}{\eta^{inverter}_{y,z}} \\ & \forall y \in \mathcal{VS}, \forall z \in \mathcal{Z}, \forall t \in \mathcal{T} \end{aligned}\]

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):

\[\begin{aligned} @@ -169,7 +169,7 @@ & \Theta_{y,z,t} + \Pi_{y,z,t} + \Theta^{CRM,ac}_{y,z,t} + \Pi^{CRM,ac}_{y,z,t} + f^{ac,dis}_{y,z,t} + r^{ac,dis}_{y,z,t} + f^{ac,cha}_{y,z,t} + f^{wind}_{y,z,t} + r^{wind}_{y,z,t} \\ & + \eta^{inverter}_{y,z} \times (\Theta^{CRM,dc}_{y,z,t} + f^{pv}_{y,z,t} + r^{pv}_{y,z,t} + f^{dc,dis}_{y,z,t} + r^{dc,dis}_{y,z,t}) + \frac{\Pi^{CRM,dc}_{y,z,t} + f^{dc,cha}_{y,z,t}}{\eta^{inverter}_{y,z}} \\ & \leq \Delta^{total}_{y,z} \quad \forall y \in \mathcal{VS}, \forall z \in \mathcal{Z}, \forall t \in \mathcal{T} -\end{aligned}\]

The rest of the constraints are dependent upon specific configurable components within the module and are listed below.

source
GenX.vre_stor_capres!Method
vre_stor_capres!(EP::Model, inputs::Dict, setup::Dict)

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.

source
GenX.vre_stor_capres!Method
vre_stor_capres!(EP::Model, inputs::Dict, setup::Dict)

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} & \Gamma^{CRM}_{y,z,t} = \Gamma^{CRM}_{y,z,t-1} + \frac{\Theta^{CRM, dc}_{y,z,t}}{\eta_{y,z}^{discharge,dc}} + \frac{\Theta^{CRM,ac}_{y,z,t}}{\eta_{y,z}^{discharge,ac}} - \eta_{y,z}^{charge,dc} \times \Pi^{CRM,dc}_{y,z,t} - \eta_{y,z}^{charge,ac} \times \Pi^{CRM, ac}_{y,z,t} \\ & - \eta_{y,z}^{loss} \times \Gamma^{CRM}_{y,z,t-1} \quad \forall y \in \mathcal{VS}^{stor}, z \in \mathcal{Z}, t \in \mathcal{T}^{interior}\\ & \Gamma^{CRM}_{y,z,t} = \Gamma^{CRM}_{y,z,t+\tau^{period}-1} + \frac{\Theta^{CRM,dc}_{y,z,t}}{\eta_{y,z}^{discharge,dc}} + \frac{\Theta^{CRM,ac}_{y,z,t}}{\eta_{y,z}^{discharge,ac}} - \eta_{y,z}^{charge,dc} \times \Pi^{CRM,dc}_{y,z,t} - \eta_{y,z}^{charge,ac} \times \Pi^{CRM,ac}_{y,z,t} \\ @@ -188,7 +188,7 @@ & + \frac{\Theta^{CRM,dc}_{y,z,(m-1)\times \tau^{period}+1}}{\eta_{y,z}^{discharge,dc}} + \frac{\Theta^{CRM,ac}_{y,z,(m-1)\times \tau^{period}+1}}{\eta_{y,z}^{discharge,ac}} \\ & - \eta_{y,z}^{charge,dc} \times \Pi^{CRM,dc}_{y,z,(m-1)\times \tau^{period}+1} - \eta_{y,z}^{charge,ac} \times \Pi^{CRM,ac}_{y,z,(m-1)\times \tau^{period}+1} \\ & \forall y \in \mathcal{VS}^{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 for the representation of 'virtual' state of charge, build up storage inventory and state of charge at the beginning of each period.

source
GenX.vre_stor_operational_reserves!Method
vre_stor_operational_reserves!(EP::Model, inputs::Dict, setup::Dict)

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.

source
GenX.vre_stor_operational_reserves!Method
vre_stor_operational_reserves!(EP::Model, inputs::Dict, setup::Dict)

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:

\[\begin{aligned} @@ -213,7 +213,7 @@ \end{aligned}\]

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}\]

source
GenX.wind_vre_stor!Method
wind_vre_stor!(EP::Model, inputs::Dict, setup::Dict)

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} +\end{aligned}\]

source
GenX.wind_vre_stor!Method
wind_vre_stor!(EP::Model, inputs::Dict, setup::Dict)

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:

\[\begin{aligned} & \Delta^{wind}_{y,z} \leq \overline{\Delta^{wind}_{y,z}} @@ -233,4 +233,4 @@ & \sum_{y \in \mathcal{VS}^{wind}} \sum_{z \in \mathcal{Z}} \left( (\pi^{INVEST, wind}_{y,z} \times \Omega^{wind}_{y,z}) + (\pi^{FOM, wind}_{y,z} \times \Delta^{total,wind}_{y,z}) \right) \\ & + \sum_{y \in \mathcal{VS}^{wind}} \sum_{z \in \mathcal{Z}} \sum_{t \in \mathcal{T}} (\pi^{VOM, wind}_{y,z} \times \Theta^{wind}_{y,z,t}) -\end{aligned}\]

source
GenX.write_vre_storMethod
write_vre_stor(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage specific files.

source
GenX.write_vre_stor_capacityMethod
write_vre_stor_capacity(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage capacities.

source
GenX.write_vre_stor_chargeMethod
write_vre_stor_charge(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage charging decision variables/expressions.

source
GenX.write_vre_stor_dischargeMethod
write_vre_stor_discharge(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage discharging decision variables/expressions.

source
+\end{aligned}\]

source
GenX.write_vre_storMethod
write_vre_stor(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage specific files.

source
GenX.write_vre_stor_capacityMethod
write_vre_stor_capacity(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage capacities.

source
GenX.write_vre_stor_chargeMethod
write_vre_stor_charge(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage charging decision variables/expressions.

source
GenX.write_vre_stor_dischargeMethod
write_vre_stor_discharge(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage discharging decision variables/expressions.

source
diff --git a/previews/PR662/Model_Reference/TDR/index.html b/previews/PR662/Model_Reference/TDR/index.html index ebe6b86ca4..fb606d4501 100644 --- a/previews/PR662/Model_Reference/TDR/index.html +++ b/previews/PR662/Model_Reference/TDR/index.html @@ -1,3 +1,3 @@ -Time-domain Reduction · GenX

Time Domain Reduction (TDR)

GenX.RemoveConstColsFunction
RemoveConstCols(all_profiles, all_col_names)

Remove and store the columns that do not vary during the period.

source
GenX.check_conditionMethod
check_condition(Threshold, R, OldColNames, ScalingMethod, TimestepsPerRepPeriod)

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%)

source
GenX.cluster_inputsFunction
cluster_inputs(inpath, settings_path, mysetup, stage_id=-99, v=false; random=true)

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.

source
GenX.get_absolute_extremeMethod
get_absolute_extreme(DF, statKey, col_names, ConstCols)

Get the period index of the single timestep with the minimum or maximum demand or capacity factor.

source
GenX.get_demand_multipliersFunction
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.

Find $k_z$ such that:

\[\sum_{i \in I} L_{i,z} = \sum_{t \in T, m \in M} C_{t,m,z} \cdot \frac{w_m}{T} \cdot k_z \: \: \: \forall z \in Z\]

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.

source
GenX.get_extreme_periodFunction
get_extreme_period(DF, GDF, profKey, typeKey, statKey,
-   ConstCols, demand_col_names, solar_col_names, wind_col_names)

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".

source
GenX.get_integral_extremeMethod
get_integral_extreme(GDF, statKey, col_names, ConstCols)

Get the period index with the minimum or maximum demand or capacity factor summed over the period.

source
GenX.get_worst_period_idxMethod
get_worst_period_idx(R)

Get the index of the period that is farthest from its representative period by Euclidean distance.

source
GenX.parse_dataMethod
parse_data(myinputs)

Get demand, solar, wind, and other curves from the input data.

source
GenX.rmse_scoreMethod
rmse_score(y_true, y_pred)

Calculates Root Mean Square Error.

\[RMSE = \sqrt{\frac{1}{n}\Sigma_{i=1}^{n}{\Big(\frac{d_i -f_i}{\sigma_i}\Big)^2}}\]

source
GenX.scale_weightsFunction
scale_weights(W, H)

Linearly scale weights W such that they sum to the desired number of timesteps (hours) H.

\[w_j \leftarrow H \cdot \frac{w_j}{\sum_i w_i} \: \: \: \forall w_j \in W\]

source
GenX.run_timedomainreduction!Function

Run the GenX time domain reduction on the given case folder

case - folder for the case stage_id - possibly something to do with MultiStage verbose - print extra outputs

This function overwrites the time-domain-reduced inputs if they already exist.

source
+Time-domain Reduction · GenX.jl

Time Domain Reduction (TDR)

GenX.RemoveConstColsFunction
RemoveConstCols(all_profiles, all_col_names)

Remove and store the columns that do not vary during the period.

source
GenX.check_conditionMethod
check_condition(Threshold, R, OldColNames, ScalingMethod, TimestepsPerRepPeriod)

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%)

source
GenX.cluster_inputsFunction
cluster_inputs(inpath, settings_path, mysetup, stage_id=-99, v=false; random=true)

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.

source
GenX.get_absolute_extremeMethod
get_absolute_extreme(DF, statKey, col_names, ConstCols)

Get the period index of the single timestep with the minimum or maximum demand or capacity factor.

source
GenX.get_demand_multipliersFunction
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.

Find $k_z$ such that:

\[\sum_{i \in I} L_{i,z} = \sum_{t \in T, m \in M} C_{t,m,z} \cdot \frac{w_m}{T} \cdot k_z \: \: \: \forall z \in Z\]

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.

source
GenX.get_extreme_periodFunction
get_extreme_period(DF, GDF, profKey, typeKey, statKey,
+   ConstCols, demand_col_names, solar_col_names, wind_col_names)

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".

source
GenX.get_integral_extremeMethod
get_integral_extreme(GDF, statKey, col_names, ConstCols)

Get the period index with the minimum or maximum demand or capacity factor summed over the period.

source
GenX.get_worst_period_idxMethod
get_worst_period_idx(R)

Get the index of the period that is farthest from its representative period by Euclidean distance.

source
GenX.parse_dataMethod
parse_data(myinputs)

Get demand, solar, wind, and other curves from the input data.

source
GenX.rmse_scoreMethod
rmse_score(y_true, y_pred)

Calculates Root Mean Square Error.

\[RMSE = \sqrt{\frac{1}{n}\Sigma_{i=1}^{n}{\Big(\frac{d_i -f_i}{\sigma_i}\Big)^2}}\]

source
GenX.scale_weightsFunction
scale_weights(W, H)

Linearly scale weights W such that they sum to the desired number of timesteps (hours) H.

\[w_j \leftarrow H \cdot \frac{w_j}{\sum_i w_i} \: \: \: \forall w_j \in W\]

source
GenX.run_timedomainreduction!Function

Run the GenX time domain reduction on the given case folder

case - folder for the case stage_id - possibly something to do with MultiStage verbose - print extra outputs

This function overwrites the time-domain-reduced inputs if they already exist.

source
diff --git a/previews/PR662/Model_Reference/core/index.html b/previews/PR662/Model_Reference/core/index.html index cab69c34fc..1a80b34fa6 100644 --- a/previews/PR662/Model_Reference/core/index.html +++ b/previews/PR662/Model_Reference/core/index.html @@ -1,8 +1,8 @@ -Core · GenX

Core

Discharge

GenX.discharge!Method
discharge!(EP::Model, inputs::Dict, setup::Dict)

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}$:

\[\begin{aligned} +Core · GenX.jl

Core

Discharge

GenX.discharge!Method
discharge!(EP::Model, inputs::Dict, setup::Dict)

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}$:

\[\begin{aligned} Obj_{Var\_gen} = \sum_{y \in \mathcal{G} } \sum_{t \in \mathcal{T}}\omega_{t}\times(\pi^{VOM}_{y})\times \Theta_{y,t} -\end{aligned}\]

source
GenX.investment_discharge!Method
investment_discharge!(EP::Model, inputs::Dict, setup::Dict)

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} +\end{aligned}\]

source
GenX.investment_discharge!Method
investment_discharge!(EP::Model, inputs::Dict, setup::Dict)

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.

\[\begin{aligned} &\Delta_{y,z} \leq \overline{\Delta_{y,z}} @@ -16,7 +16,7 @@ & \sum_{y \in \mathcal{G} } \sum_{z \in \mathcal{Z}} \left( (\pi^{INVEST}_{y,z} \times \overline{\Omega}^{size}_{y,z} \times \Omega_{y,z}) + (\pi^{FOM}_{y,z} \times \overline{\Omega}^{size}_{y,z} \times \Delta^{total}_{y,z})\right) -\end{aligned}\]

source
GenX.write_multi_stage_capacities_dischargeMethod
write_multi_stage_capacities_discharge(outpath::String, settings_d::Dict)

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.
source
GenX.write_virtual_dischargeMethod
write_virtual_discharge(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

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.

source

Non-served Energy

GenX.non_served_energy!Method
non_served_energy!(EP::Model, inputs::Dict, setup::Dict)

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}$:

\[\begin{aligned} +\end{aligned}\]

source
GenX.write_multi_stage_capacities_dischargeMethod
write_multi_stage_capacities_discharge(outpath::String, settings_d::Dict)

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.
source
GenX.write_virtual_dischargeMethod
write_virtual_discharge(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

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.

source

Non-served Energy

GenX.non_served_energy!Method
non_served_energy!(EP::Model, inputs::Dict, setup::Dict)

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}$:

\[\begin{aligned} Obj_{NSE} = \sum_{s \in \mathcal{S} } \sum_{t \in \mathcal{T}} \sum_{z \in \mathcal{Z}}\omega_{t} \times n_{s}^{slope} \times \Lambda_{s,t,z} \end{aligned}\]

Contributions to the power balance expression from non-served energy/curtailed demand from each demand segment $s \in \mathcal{S}$ are also defined as:

\[\begin{aligned} @@ -29,7 +29,7 @@ \end{aligned}\]

Additionally, total demand curtailed in each time step cannot exceed total demand:

\[\begin{aligned} \sum_{s \in \mathcal{S} } \Lambda_{s,t,z} \leq D_{t,z} \hspace{4 cm} \forall t \in \mathcal{T}, z\in \mathcal{Z} -\end{aligned}\]

source

Operational Reserves

GenX.load_operational_reserves!Method
load_operational_reserves!(setup::Dict,path::AbstractString, inputs::Dict)

Read input parameters related to frequency regulation and operating reserve requirements

source
GenX.operational_reserves!Method
operational_reserves!(EP::Model, inputs::Dict, setup::Dict)

This function sets up reserve decisions and constraints, using the operationalreservescore()and operational_reserves_contingency() functions.

source
GenX.operational_reserves_contingency!Method
operational_reserves_contingency!(EP::Model, inputs::Dict, setup::Dict)

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:

\[\begin{aligned} +\end{aligned}\]

source

Operational Reserves

GenX.load_operational_reserves!Method
load_operational_reserves!(setup::Dict,path::AbstractString, inputs::Dict)

Read input parameters related to frequency regulation and operating reserve requirements

source
GenX.operational_reserves!Method
operational_reserves!(EP::Model, inputs::Dict, setup::Dict)

This function sets up reserve decisions and constraints, using the operationalreservescore()and operational_reserves_contingency() functions.

source
GenX.operational_reserves_contingency!Method
operational_reserves_contingency!(EP::Model, inputs::Dict, setup::Dict)

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:

\[\begin{aligned} Contingency = \epsilon^{contingency} \end{aligned}\]

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).

source
GenX.operational_reserves_core!Method
operational_reserves_core!(EP::Model, inputs::Dict, setup::Dict)

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).

source
GenX.operational_reserves_core!Method
operational_reserves_core!(EP::Model, inputs::Dict, setup::Dict)

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} C^{rvs} = \sum_{t \in T} \omega_t \times unmet\_rsv_{t} \end{aligned}\]

Frequency regulation requirements

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).

\[\begin{aligned} & \sum_{y \in Y, z \in Z} f_{y,t,z} \geq \epsilon^{demand}_{reg} \times \sum_{z \in Z} \mathcal{D}_{z,t} + \epsilon^{vre}_{reg} \times (\sum_{z \in Z} \rho^{max}_{y,z,t} \times \Delta^{\text{total}}_{y,z} \\ @@ -47,14 +47,14 @@ \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}^{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).

\[\begin{aligned} & \sum_{y \in Y, z \in Z} r_{y,z,t} + r^{unmet}_{t} \geq \epsilon^{demand}_{rsv} \times \sum_{z \in Z} \mathcal{D}_{z,t} + \epsilon^{vre}_{rsv} \times (\sum_{z \in Z} \rho^{max}_{y,z,t} \times \Delta^{\text{total}}_{y,z} \\ & + \sum_{z \in Z} \rho^{max,pv}_{y,z,t} \times \Delta^{\text{total,pv}}_{y,z} + \sum_{z \in Z} \rho^{max,wind}_{y,z,t} \times \Delta^{\text{total,wind}}_{y,z}) + Contingency \quad \forall t \in T -\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.

source

Transmission

GenX.dcopf_transmission!Method
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.

source

Transmission

GenX.dcopf_transmission!Method
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}\]

source
GenX.investment_transmission!Method
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}
source
GenX.transmission!Method
transmission!(EP::Model, inputs::Dict, setup::Dict)

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:

\[\begin{aligned} + \end{aligned}

source
GenX.transmission!Method
transmission!(EP::Model, inputs::Dict, setup::Dict)

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:

\[\begin{aligned} & - \sum_{l\in \mathcal{L}}{(\varphi^{map}_{l,z} \times \Phi_{l,t})} - \frac{1}{2} \sum_{l\in \mathcal{L}}{(\varphi^{map}_{l,z} \times \beta_{l,t}(\cdot))} \end{aligned}\]

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}\]

source

Unit Commitment

GenX.ucommit!Method
ucommit!(EP::Model, inputs::Dict, setup::Dict)

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:

\[\begin{aligned} +\end{aligned}\]

source

Unit Commitment

GenX.ucommit!Method
ucommit!(EP::Model, inputs::Dict, setup::Dict)

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:

\[\begin{aligned} C^{start} = \sum_{y \in UC, t \in T} \omega_t \times start\_cost_{y,t} \times \chi_{y,t} -\end{aligned}\]

The sum of start-up costs is added to the objective function.

source

CO2

GenX.co2!Method
co2!(EP::Model, inputs::Dict)

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.

source

CO2

GenX.co2!Method
co2!(EP::Model, inputs::Dict)

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} eEmissionsByPlant_{g,t} = (1-Biomass_y- CO2\_Capture\_Fraction_y) * vFuel_{y,t} * CO2_{content} + (1-Biomass_y- CO2\_Capture\_Fraction\_Startup_y) * eStartFuel_{y,t} * CO2_{content} \hspace{1cm} \forall y \in G, \forall t \in T, Biomass_y \in {{0,1}} \end{aligned}\]

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}\]

source
GenX.write_co2Method
write_co2(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for reporting time-dependent CO2 emissions by zone.

source

Fuel

GenX.fuel!Method
fuel!(EP::Model, inputs::Dict, setup::Dict)

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} +\end{aligned}\]

source
GenX.write_co2Method
write_co2(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for reporting time-dependent CO2 emissions by zone.

source

Fuel

GenX.fuel!Method
fuel!(EP::Model, inputs::Dict, setup::Dict)

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$.

\[\begin{aligned} \sum_{i \in \mathcal{I} } vMulStartFuels_{y, i, t}= CapSize_{y} \times StartFuelMMBTUperMW_{y} \times vSTART_{y,t} \end{aligned}\]

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$.

\[\begin{aligned} \sum_{i \in \mathcal{I} } \frac{vMulFuels_{y, i, t}} {HeatRate_{i,y} } = vPower_{y,t} -\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}

source
+\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}

source
diff --git a/previews/PR662/Model_Reference/generate_model/index.html b/previews/PR662/Model_Reference/generate_model/index.html index b21cd2e0d4..0cf7ce1bde 100644 --- a/previews/PR662/Model_Reference/generate_model/index.html +++ b/previews/PR662/Model_Reference/generate_model/index.html @@ -1,5 +1,5 @@ -Generate the Model · GenX

Generating the model

GenX.generate_modelMethod
generate_model(setup::Dict,inputs::Dict,OPTIMIZER::MOI.OptimizerWithAttributes,modeloutput = nothing)

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:

\[\begin{aligned} +Generate the Model · GenX.jl

Generating the model

GenX.generate_modelMethod
generate_model(setup::Dict,inputs::Dict,OPTIMIZER::MOI.OptimizerWithAttributes,modeloutput = nothing)

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:

\[\begin{aligned} &\sum_{y \in \mathcal{G} } \sum_{z \in \mathcal{Z}} \left( (\pi^{INVEST}_{y,z} \times \overline{\Omega}^{size}_{y,z} \times \Omega_{y,z}) + (\pi^{FOM}_{y,z} \times \overline{\Omega}^{size}_{y,z} \times \Delta^{total}_{y,z})\right) + \notag \\ @@ -18,4 +18,4 @@ & \sum_{y\in \mathcal{DF}}{(-\Theta_{y,z,t}+\Pi_{y,z,t})} +\sum_{y\in \mathcal{W}}{\Theta_{y,z,t}}+ \notag\\ &+ \sum_{s\in \mathcal{S}}{\Lambda_{s,z,t}} - \sum_{l\in \mathcal{L}}{(\varphi^{map}_{l,z} \times \Phi_{l,t})} -\frac{1}{2} \sum_{l\in \mathcal{L}}{(\varphi^{map}_{l,z} \times \beta_{l,t}(\cdot))} = D_{z,t} \forall z\in \mathcal{Z}, t \in \mathcal{T} -\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
source
+\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
source
diff --git a/previews/PR662/Model_Reference/load_inputs/index.html b/previews/PR662/Model_Reference/load_inputs/index.html index fe7764ff6d..fc120f2f53 100644 --- a/previews/PR662/Model_Reference/load_inputs/index.html +++ b/previews/PR662/Model_Reference/load_inputs/index.html @@ -1,8 +1,8 @@ -Inputs Functions · GenX

Reading Input Files

GenX.get_systemfiles_pathMethod
get_systemfiles_path(setup::Dict, TDR_directory::AbstractString, path::AbstractString)

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.
source
GenX.load_inputsMethod
load_inputs(setup::Dict,path::AbstractString)

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

source

Fuels Data

GenX.load_fuels_data!Method
load_fuels_data!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to fuel costs and CO$_2$ content of fuels

source

Generators Input Data

GenX._get_policyfile_infoMethod
_get_policyfile_info()

Internal function to get policy file information.

Returns

policyfile_info (NamedTuple): A tuple containing policy file information.
source
GenX._get_resource_infoMethod
_get_resource_info()

Internal function to get resource information (filename and GenX type) for each type of resource available in GenX.

resource_info (NamedTuple): A tuple containing resource information.
source
GenX._get_summary_mapMethod
_get_summary_map()

Internal function to get a map of GenX resource type their corresponding names in the summary table.

source
GenX.add_attributes_to_resource!Method
add_attributes_to_resource!(resource::AbstractResource, new_symbols::Vector{Symbol}, new_values::T) where T <: DataFrameRow

Adds a set of new attributes (names and corresponding values) to a resource. The resource is modified in-place.

Arguments

  • resource::AbstractResource: The resource to add attributes to.
  • new_symbols::Vector{Symbol}: Vector of symbols containing the names of the new attributes.
  • new_values::DataFrameRow: DataFrameRow containing the values of the new attributes.
source
GenX.add_df_to_resources!Method
add_df_to_resources!(resources::Vector{<:AbstractResource}, module_in::DataFrame)

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.
  • module_in::DataFrame: The dataframe to add.
source
GenX.add_id_to_resource_df!Method
add_id_to_resource_df!(df::DataFrame, indices::AbstractVector)

Adds a new column 'id' to the DataFrame with the provided resource indices. The dataframe is modified in-place.

Arguments

  • df::DataFrame: The input DataFrame to which the indices are to be added.
  • indices::AbstractVector: The array of indices to be added as a new column.
source
GenX.add_module_to_resources!Method
add_module_to_resources!(resources::Vector{<:AbstractResource}, module_in::DataFrame)

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.
source
GenX.add_modules_to_resources!Method
add_modules_to_resources!(resources::Vector{<:AbstractResource}, setup::Dict, resources_path::AbstractString)

Reads module dataframes, loops over files and adds columns as new attributes to the resources in the model.

Arguments

  • resources::Vector{<:AbstractResource}: A vector of resources.
  • setup (Dict): A dictionary containing GenX settings.
  • resources_path::AbstractString: The path to the resources folder.
source
GenX.add_policies_to_resources!Method
add_policies_to_resources!(resources::Vector{<:AbstractResource}, resources_path::AbstractString)

Reads policy files and adds policies-related attributes to resources in the model.

Arguments

  • resources::Vector{<:AbstractResource}: Vector of resources in the model.
  • resources_path::AbstractString: The path to the resources folder.
source
GenX.add_policy_to_resources!Method
add_policy_to_resources!(resources::Vector{<:AbstractResource}, path::AbstractString, filename::AbstractString)

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.
source
GenX.add_resources_to_input_data!Method
add_resources_to_input_data!(inputs::Dict, setup::Dict, case_path::AbstractString, gen::Vector{<:AbstractResource})

Adds resources to the inputs Dict with the key "RESOURCES" together with sevaral sets of resource indices that are used inside GenX to construct the optimization problem. The inputs Dict is modified in-place.

Arguments

  • inputs (Dict): Dictionary to store the GenX input data.
  • setup (Dict): Dictionary containing GenX settings.
  • case_path (AbstractString): Path to the case.
  • gen (Vector{<:AbstractResource}): Array of GenX resources.
source
GenX.check_resourceMethod
check_resource(resources::Vector{T})::Vector{String} where T <: AbstractResource

Validate the consistency of a vector of GenX resources Reports any errors/warnings as a vector of messages.

source
GenX.compute_resource_indicesMethod
compute_resource_indices(resources_in::DataFrame, offset::Int64)

Computes the indices for the resources loaded from a single dataframe by shifting the indices by an offset value.

Arguments

  • resources_in::DataFrame: The input DataFrame containing the resources.
  • offset::Int64: The offset value to be added to the indices.

Returns

  • UnitRange{Int64}: An array of indices.
source
GenX.create_resource_arrayFunction
create_resource_array(resource_folder::AbstractString, resources_info::NamedTuple, scale_factor::Float64=1.0)

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.
source
GenX.create_resource_arrayMethod
create_resource_array(setup::Dict, resources_path::AbstractString)

Function that loads and scales resources data from folder specified in resources_path and returns an array of GenX resources.

Arguments

  • setup (Dict): Dictionary containing GenX settings.
  • resources_path (AbstractString): The path to the resources folder.

Returns

  • resources (Vector{<:AbstractResource}): An array of scaled resources.
source
GenX.create_resources_sametypeMethod
create_resources_sametype(resource_in::DataFrame, ResourceType)

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.
source
GenX.dataframerow_to_dictMethod
dataframerow_to_dict(dfr::DataFrameRow)

Converts a DataFrameRow to a Dict.

Arguments

  • dfr::DataFrameRow: The DataFrameRow to be converted.

Returns

  • Dict: Dictionary containing the DataFrameRow data.
source
GenX.load_multi_fuels_data!Method
load_multi_fuels_data!(inputs::Dict, gen::Vector{<:AbstractResource}, setup::Dict, path::AbstractString)

Function for reading input parameters related to multi fuels

source
GenX.load_resource_dfMethod
load_resource_df(path::AbstractString, scale_factor::Float64, resource_type::Type)

Function to load and scale the dataframe of a given resource.

Arguments

  • path::AbstractString: Path to the resource dataframe.
  • scale_factor::Float64: Scaling factor for the resource data.
  • resource_type::Type: GenX type of the resource.

Returns

  • resource_in::DataFrame: The loaded and scaled resource data.
source
GenX.load_resources_data!Method
load_resources_data!(inputs::Dict, setup::Dict, case_path::AbstractString, resources_path::AbstractString)

This function loads resources data from the resources_path folder and create the GenX data structures and add them to the inputs Dict.

Arguments

  • inputs (Dict): A dictionary to store the input data.
  • setup (Dict): A dictionary containing GenX settings.
  • case_path (AbstractString): The path to the case folder.
  • resources_path (AbstractString): The path to the case resources folder.

Raises: DeprecationWarning: If the Generators_data.csv file is found, a deprecation warning is issued, together with an error message.

source
GenX.process_piecewisefuelusage!Method
process_piecewisefuelusage!(setup::Dict, case_path::AbstractString, gen::Vector{<:AbstractResource}, inputs::Dict)

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
source
GenX.scale_columns!Method
scale_columns!(df::DataFrame, columns_to_scale::Vector{Symbol}, scale_factor::Float64)

Scales in-place the columns in columns_to_scale of a dataframe df by a scale_factor.

Arguments

  • df (DataFrame): A dataframe containing data to scale.
  • columns_to_scale (Vector{Symbol}): A vector of column names to scale.
  • scale_factor (Float64): A scaling factor for energy and currency units.
source
GenX.scale_resources_data!Method
scale_resources_data!(resource_in::DataFrame, scale_factor::Float64)

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.
source
GenX.scale_vre_stor_data!Method
scale_vre_stor_data!(vre_stor_in::DataFrame, scale_factor::Float64)

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.
source
GenX.split_storage_resources!Method
split_storage_resources!(inputs::Dict, gen::Vector{<:AbstractResource})

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

source
GenX.summaryMethod
summary(rs::Vector{<:AbstractResource})

Prints a summary of the resources loaded into the model.

Arguments

  • rs (Vector{<:AbstractResource}): An array of GenX resources.
source
GenX.update_retrofit_idMethod
update_retrofit_id(r::AbstractResource)

Updates the retrofitid of a resource that can be retrofit or is a retrofit option by appending the region to the retrofitid.

Arguments

  • r::AbstractResource: The resource to update.
source
GenX.validate_policy_dataframe!Method
validate_policy_dataframe!(filename::AbstractString, policy_in::DataFrame)

Validate the policy dataframe by checking if it has any attributes and if the column names are valid. The dataframe is modified in-place.

Arguments

  • filename::AbstractString: The name of the policy file.
  • policy_in::DataFrame: The policy dataframe.
source
GenX.validate_policy_filesMethod
validate_policy_files(resource_policies_path::AbstractString, setup::Dict)

Validate the policy files by checking if they exist in the specified folder and if the setup flags are consistent with the files found.

Arguments

  • resource_policies_path::AbstractString: The path to the policy files.
  • setup::Dict: Dictionary containing GenX settings.

Returns

  • warning messages if the polcies are set to 1 in settings but the files are not found in the resourcepoliciespath.

!isfile(joinpath(resourcepoliciespath, filename))

source

Variability of Generators' Outputs

GenX.load_generators_variability!Method
load_generators_variability!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to hourly maximum capacity factors for generators, storage, and flexible demand resources

source

Demand Data

GenX.load_demand_data!Method
load_demand_data!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to electricity demand (load)

source
GenX.prevent_doubled_timedomainreductionMethod
prevent_doubled_timedomainreduction(path::AbstractString)

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.

source

Transmission Network

GenX.load_network_data!Method
load_network_data!(setup::Dict, path::AbstractString, inputs_nw::Dict)

Function for reading input parameters related to the electricity transmission network

source
GenX.load_network_map_from_listMethod
load_network_map_from_list(network_var::DataFrame, Z, L, list_columns)

Loads the network map from a list-style interface

..., Network_Lines, Start_Zone, End_Zone, ...
+Inputs Functions · GenX.jl

Reading Input Files

GenX.get_systemfiles_pathMethod
get_systemfiles_path(setup::Dict, TDR_directory::AbstractString, path::AbstractString)

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.
source
GenX.load_inputsMethod
load_inputs(setup::Dict,path::AbstractString)

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

source

Fuels Data

GenX.load_fuels_data!Method
load_fuels_data!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to fuel costs and CO$_2$ content of fuels

source

Generators Input Data

GenX._get_policyfile_infoMethod
_get_policyfile_info()

Internal function to get policy file information.

Returns

policyfile_info (NamedTuple): A tuple containing policy file information.
source
GenX._get_resource_infoMethod
_get_resource_info()

Internal function to get resource information (filename and GenX type) for each type of resource available in GenX.

resource_info (NamedTuple): A tuple containing resource information.
source
GenX._get_summary_mapMethod
_get_summary_map()

Internal function to get a map of GenX resource type their corresponding names in the summary table.

source
GenX.add_attributes_to_resource!Method
add_attributes_to_resource!(resource::AbstractResource, new_symbols::Vector{Symbol}, new_values::T) where T <: DataFrameRow

Adds a set of new attributes (names and corresponding values) to a resource. The resource is modified in-place.

Arguments

  • resource::AbstractResource: The resource to add attributes to.
  • new_symbols::Vector{Symbol}: Vector of symbols containing the names of the new attributes.
  • new_values::DataFrameRow: DataFrameRow containing the values of the new attributes.
source
GenX.add_df_to_resources!Method
add_df_to_resources!(resources::Vector{<:AbstractResource}, module_in::DataFrame)

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.
  • module_in::DataFrame: The dataframe to add.
source
GenX.add_id_to_resource_df!Method
add_id_to_resource_df!(df::DataFrame, indices::AbstractVector)

Adds a new column 'id' to the DataFrame with the provided resource indices. The dataframe is modified in-place.

Arguments

  • df::DataFrame: The input DataFrame to which the indices are to be added.
  • indices::AbstractVector: The array of indices to be added as a new column.
source
GenX.add_module_to_resources!Method
add_module_to_resources!(resources::Vector{<:AbstractResource}, module_in::DataFrame)

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.
source
GenX.add_modules_to_resources!Method
add_modules_to_resources!(resources::Vector{<:AbstractResource}, setup::Dict, resources_path::AbstractString)

Reads module dataframes, loops over files and adds columns as new attributes to the resources in the model.

Arguments

  • resources::Vector{<:AbstractResource}: A vector of resources.
  • setup (Dict): A dictionary containing GenX settings.
  • resources_path::AbstractString: The path to the resources folder.
source
GenX.add_policies_to_resources!Method
add_policies_to_resources!(resources::Vector{<:AbstractResource}, resources_path::AbstractString)

Reads policy files and adds policies-related attributes to resources in the model.

Arguments

  • resources::Vector{<:AbstractResource}: Vector of resources in the model.
  • resources_path::AbstractString: The path to the resources folder.
source
GenX.add_policy_to_resources!Method
add_policy_to_resources!(resources::Vector{<:AbstractResource}, path::AbstractString, filename::AbstractString)

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.
source
GenX.add_resources_to_input_data!Method
add_resources_to_input_data!(inputs::Dict, setup::Dict, case_path::AbstractString, gen::Vector{<:AbstractResource})

Adds resources to the inputs Dict with the key "RESOURCES" together with sevaral sets of resource indices that are used inside GenX to construct the optimization problem. The inputs Dict is modified in-place.

Arguments

  • inputs (Dict): Dictionary to store the GenX input data.
  • setup (Dict): Dictionary containing GenX settings.
  • case_path (AbstractString): Path to the case.
  • gen (Vector{<:AbstractResource}): Array of GenX resources.
source
GenX.check_resourceMethod
check_resource(resources::Vector{T})::Vector{String} where T <: AbstractResource

Validate the consistency of a vector of GenX resources Reports any errors/warnings as a vector of messages.

source
GenX.compute_resource_indicesMethod
compute_resource_indices(resources_in::DataFrame, offset::Int64)

Computes the indices for the resources loaded from a single dataframe by shifting the indices by an offset value.

Arguments

  • resources_in::DataFrame: The input DataFrame containing the resources.
  • offset::Int64: The offset value to be added to the indices.

Returns

  • UnitRange{Int64}: An array of indices.
source
GenX.create_resource_arrayFunction
create_resource_array(resource_folder::AbstractString, resources_info::NamedTuple, scale_factor::Float64=1.0)

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.
source
GenX.create_resource_arrayMethod
create_resource_array(setup::Dict, resources_path::AbstractString)

Function that loads and scales resources data from folder specified in resources_path and returns an array of GenX resources.

Arguments

  • setup (Dict): Dictionary containing GenX settings.
  • resources_path (AbstractString): The path to the resources folder.

Returns

  • resources (Vector{<:AbstractResource}): An array of scaled resources.
source
GenX.create_resources_sametypeMethod
create_resources_sametype(resource_in::DataFrame, ResourceType)

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.
source
GenX.dataframerow_to_dictMethod
dataframerow_to_dict(dfr::DataFrameRow)

Converts a DataFrameRow to a Dict.

Arguments

  • dfr::DataFrameRow: The DataFrameRow to be converted.

Returns

  • Dict: Dictionary containing the DataFrameRow data.
source
GenX.load_multi_fuels_data!Method
load_multi_fuels_data!(inputs::Dict, gen::Vector{<:AbstractResource}, setup::Dict, path::AbstractString)

Function for reading input parameters related to multi fuels

source
GenX.load_resource_dfMethod
load_resource_df(path::AbstractString, scale_factor::Float64, resource_type::Type)

Function to load and scale the dataframe of a given resource.

Arguments

  • path::AbstractString: Path to the resource dataframe.
  • scale_factor::Float64: Scaling factor for the resource data.
  • resource_type::Type: GenX type of the resource.

Returns

  • resource_in::DataFrame: The loaded and scaled resource data.
source
GenX.load_resources_data!Method
load_resources_data!(inputs::Dict, setup::Dict, case_path::AbstractString, resources_path::AbstractString)

This function loads resources data from the resources_path folder and create the GenX data structures and add them to the inputs Dict.

Arguments

  • inputs (Dict): A dictionary to store the input data.
  • setup (Dict): A dictionary containing GenX settings.
  • case_path (AbstractString): The path to the case folder.
  • resources_path (AbstractString): The path to the case resources folder.

Raises: DeprecationWarning: If the Generators_data.csv file is found, a deprecation warning is issued, together with an error message.

source
GenX.process_piecewisefuelusage!Method
process_piecewisefuelusage!(setup::Dict, case_path::AbstractString, gen::Vector{<:AbstractResource}, inputs::Dict)

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
source
GenX.scale_columns!Method
scale_columns!(df::DataFrame, columns_to_scale::Vector{Symbol}, scale_factor::Float64)

Scales in-place the columns in columns_to_scale of a dataframe df by a scale_factor.

Arguments

  • df (DataFrame): A dataframe containing data to scale.
  • columns_to_scale (Vector{Symbol}): A vector of column names to scale.
  • scale_factor (Float64): A scaling factor for energy and currency units.
source
GenX.scale_resources_data!Method
scale_resources_data!(resource_in::DataFrame, scale_factor::Float64)

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.
source
GenX.scale_vre_stor_data!Method
scale_vre_stor_data!(vre_stor_in::DataFrame, scale_factor::Float64)

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.
source
GenX.split_storage_resources!Method
split_storage_resources!(inputs::Dict, gen::Vector{<:AbstractResource})

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

source
GenX.summaryMethod
summary(rs::Vector{<:AbstractResource})

Prints a summary of the resources loaded into the model.

Arguments

  • rs (Vector{<:AbstractResource}): An array of GenX resources.
source
GenX.update_retrofit_idMethod
update_retrofit_id(r::AbstractResource)

Updates the retrofitid of a resource that can be retrofit or is a retrofit option by appending the region to the retrofitid.

Arguments

  • r::AbstractResource: The resource to update.
source
GenX.validate_policy_dataframe!Method
validate_policy_dataframe!(filename::AbstractString, policy_in::DataFrame)

Validate the policy dataframe by checking if it has any attributes and if the column names are valid. The dataframe is modified in-place.

Arguments

  • filename::AbstractString: The name of the policy file.
  • policy_in::DataFrame: The policy dataframe.
source
GenX.validate_policy_filesMethod
validate_policy_files(resource_policies_path::AbstractString, setup::Dict)

Validate the policy files by checking if they exist in the specified folder and if the setup flags are consistent with the files found.

Arguments

  • resource_policies_path::AbstractString: The path to the policy files.
  • setup::Dict: Dictionary containing GenX settings.

Returns

  • warning messages if the polcies are set to 1 in settings but the files are not found in the resourcepoliciespath.

!isfile(joinpath(resourcepoliciespath, filename))

source

Variability of Generators' Outputs

GenX.load_generators_variability!Method
load_generators_variability!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to hourly maximum capacity factors for generators, storage, and flexible demand resources

source

Demand Data

GenX.load_demand_data!Method
load_demand_data!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to electricity demand (load)

source
GenX.prevent_doubled_timedomainreductionMethod
prevent_doubled_timedomainreduction(path::AbstractString)

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.

source

Transmission Network

GenX.load_network_data!Method
load_network_data!(setup::Dict, path::AbstractString, inputs_nw::Dict)

Function for reading input parameters related to the electricity transmission network

source
GenX.load_network_map_from_listMethod
load_network_map_from_list(network_var::DataFrame, Z, L, list_columns)

Loads the network map from a list-style interface

..., Network_Lines, Start_Zone, End_Zone, ...
                  1,           1,       2,
-                 2,           1,       3,
source
GenX.load_network_map_from_matrixMethod
load_network_map_from_matrix(network_var::DataFrame, Z, L)

Loads the network map from a matrix-style interface

..., Network_Lines, z1, z2, z3, ...
+                 2,           1,       3,
source
GenX.load_network_map_from_matrixMethod
load_network_map_from_matrix(network_var::DataFrame, Z, L)

Loads the network map from a matrix-style interface

..., Network_Lines, z1, z2, z3, ...
                  1,  1, -1,  0,
-                 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.

source

Minimum Capacity Requirements

GenX.load_minimum_capacity_requirement!Method
load_minimum_capacity_requirement!(path::AbstractString, inputs::Dict, setup::Dict)

Read input parameters related to mimimum capacity requirement constraints (e.g. technology specific deployment mandates)

source

Capacity Reserve Margin

GenX.load_cap_reserve_margin!Method
load_cap_reserve_margin!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to planning reserve margin constraints

source
GenX.load_cap_reserve_margin_trans!Method
load_cap_reserve_margin_trans!(setup::Dict, inputs::Dict, network_var::DataFrame)

Read input parameters related to participation of transmission imports/exports in capacity reserve margin constraint.

source

CO$_2$ Emissions Cap

GenX.load_co2_cap!Method
load_co2_cap!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to CO$_2$ emissions cap constraints

source

Energy Share Requirement

GenX.load_energy_share_requirement!Method
load_energy_share_requirement!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to mimimum energy share requirement constraints (e.g. renewable portfolio standard or clean electricity standard policies)

source

Mapping Representative Time Periods

GenX.load_period_map!Method
load_period_map!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to mapping of representative time periods to full chronological time series

source

Variability of the Solar PV and Wind Components' Outputs (for Co-located Storage Resources)

GenX.load_vre_stor_variability!Method
load_vre_stor_variability!(setup::Dict, path::AbstractString, inputs::Dict)

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

source

Functions for developers

Standardized loading of dataframes from CSV files

GenX.extract_matrix_from_dataframeMethod
extract_matrix_from_dataframe(df::DataFrame, columnprefix::AbstractString)

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.

source

Minimum Capacity Requirements

GenX.load_minimum_capacity_requirement!Method
load_minimum_capacity_requirement!(path::AbstractString, inputs::Dict, setup::Dict)

Read input parameters related to mimimum capacity requirement constraints (e.g. technology specific deployment mandates)

source

Capacity Reserve Margin

GenX.load_cap_reserve_margin!Method
load_cap_reserve_margin!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to planning reserve margin constraints

source
GenX.load_cap_reserve_margin_trans!Method
load_cap_reserve_margin_trans!(setup::Dict, inputs::Dict, network_var::DataFrame)

Read input parameters related to participation of transmission imports/exports in capacity reserve margin constraint.

source

CO$_2$ Emissions Cap

GenX.load_co2_cap!Method
load_co2_cap!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to CO$_2$ emissions cap constraints

source

Energy Share Requirement

GenX.load_energy_share_requirement!Method
load_energy_share_requirement!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to mimimum energy share requirement constraints (e.g. renewable portfolio standard or clean electricity standard policies)

source

Mapping Representative Time Periods

GenX.load_period_map!Method
load_period_map!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to mapping of representative time periods to full chronological time series

source

Variability of the Solar PV and Wind Components' Outputs (for Co-located Storage Resources)

GenX.load_vre_stor_variability!Method
load_vre_stor_variability!(setup::Dict, path::AbstractString, inputs::Dict)

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

source

Functions for developers

Standardized loading of dataframes from CSV files

GenX.extract_matrix_from_dataframeMethod
extract_matrix_from_dataframe(df::DataFrame, columnprefix::AbstractString)

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,
   0.1,           1,   0.3,   0.2,
-  0.4,           2,   0.6,   0.5,
source
GenX.file_existsMethod
file_exists(dir::AbstractString, basenames::Vector{String})::Bool

Checks that a file exists in a directory under (at least) one of a list of 'aliases'.

source
GenX.load_dataframeMethod
load_dataframe(dir::AbstractString, base::AbstractString)

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.

source
GenX.load_dataframeMethod
load_dataframe(path::AbstractString)

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.

source
GenX.validate_df_colsMethod
validate_df_cols(df::DataFrame, df_name::AbstractString, required_cols::Vector{AbstractString})

Check that the dataframe has all the required columns.

Arguments

  • df::DataFrame: the dataframe to check
  • df_name::AbstractString: the name of the dataframe, for error messages
  • required_cols::Vector{AbstractString}: the names of the required columns
source
+ 0.4, 2, 0.6, 0.5,
source
GenX.file_existsMethod
file_exists(dir::AbstractString, basenames::Vector{String})::Bool

Checks that a file exists in a directory under (at least) one of a list of 'aliases'.

source
GenX.load_dataframeMethod
load_dataframe(dir::AbstractString, base::AbstractString)

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.

source
GenX.load_dataframeMethod
load_dataframe(path::AbstractString)

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.

source
GenX.validate_df_colsMethod
validate_df_cols(df::DataFrame, df_name::AbstractString, required_cols::Vector{AbstractString})

Check that the dataframe has all the required columns.

Arguments

  • df::DataFrame: the dataframe to check
  • df_name::AbstractString: the name of the dataframe, for error messages
  • required_cols::Vector{AbstractString}: the names of the required columns
source
diff --git a/previews/PR662/Model_Reference/maintenance_overview/index.html b/previews/PR662/Model_Reference/maintenance_overview/index.html index 93c9a50821..9ae11726e6 100644 --- a/previews/PR662/Model_Reference/maintenance_overview/index.html +++ b/previews/PR662/Model_Reference/maintenance_overview/index.html @@ -1,2 +1,2 @@ -Maintenance · GenX

Optimized Scheduled Maintenance

Added in v0.4

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).

Description of the maintenance model

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.

Treatment of plants that require maintenance only every few years

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.

Reduction of number of possible start dates

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.)

How to use

There are four columns which need to be added to the plant data, i.e. in Generators_data.csv:

  1. MAINT should be 1 for plants that require maintenance and 0 otherwise.
  2. Maintenance_Duration is the number of hours the maintenance period lasts.
  3. Maintenance_Cycle_Length_Years. If 1, maintenance every year, if 3 maintenance every 3 years, etc.
  4. Maintenance_Begin_Cadence. Spacing between hours in which maintenance can start.

The last three fields must be integers which are greater than 0. They are ignored for any plants which do not require maintenance.

Maintenance_Duration must be less than the total number of hours in the year.

If Maintenance_Begin_Cadence is 1 then the maintenance can begin in any hour. If it is 168 then it can begin in hours 1, 169, 337, etc.

Restrictions on use

The maintenance module has these restrictions:

  • More than a single maintenance period per year (i.e. every three months) is not possible in the current formulation.
  • Only full-year cases can be run; there must be only one "representative period".

It would not make sense to model a month-long maintenance period when the year is modeled as a series of representative weeks, for example.

Interaction with integer unit commitment

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.

Hint: pre-scheduling 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.

Outputs produced

If at least one plant has MAINT=1, a file maint_down.csv will be written listing how many plants are down for maintenance in each timestep.

Notes on mathematical formulation

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.

Developer note: adding maintenance to a resource

The maintenance formulation is applied on a per-resource basis, by calling the function GenX.maintenance_formulation!.

See GenX.maintenance_formulation_thermal_commit! for an example of how to apply it to a new resource.

  • The resource must have a vCOMMIT-like variable which is proportional to maximum the power output, etc at any given timestep.
  • The resource must have a eTotalCap-like quantity and a Cap_Size-like parameter; only the ratio of the two is used.
+Maintenance · GenX.jl

Optimized Scheduled Maintenance

Added in v0.4

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).

Description of the maintenance model

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.

Treatment of plants that require maintenance only every few years

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.

Reduction of number of possible start dates

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.)

How to use

There are four columns which need to be added to the plant data, i.e. in Generators_data.csv:

  1. MAINT should be 1 for plants that require maintenance and 0 otherwise.
  2. Maintenance_Duration is the number of hours the maintenance period lasts.
  3. Maintenance_Cycle_Length_Years. If 1, maintenance every year, if 3 maintenance every 3 years, etc.
  4. Maintenance_Begin_Cadence. Spacing between hours in which maintenance can start.

The last three fields must be integers which are greater than 0. They are ignored for any plants which do not require maintenance.

Maintenance_Duration must be less than the total number of hours in the year.

If Maintenance_Begin_Cadence is 1 then the maintenance can begin in any hour. If it is 168 then it can begin in hours 1, 169, 337, etc.

Restrictions on use

The maintenance module has these restrictions:

  • More than a single maintenance period per year (i.e. every three months) is not possible in the current formulation.
  • Only full-year cases can be run; there must be only one "representative period".

It would not make sense to model a month-long maintenance period when the year is modeled as a series of representative weeks, for example.

Interaction with integer unit commitment

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.

Hint: pre-scheduling 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.

Outputs produced

If at least one plant has MAINT=1, a file maint_down.csv will be written listing how many plants are down for maintenance in each timestep.

Notes on mathematical formulation

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.

Developer note: adding maintenance to a resource

The maintenance formulation is applied on a per-resource basis, by calling the function GenX.maintenance_formulation!.

See GenX.maintenance_formulation_thermal_commit! for an example of how to apply it to a new resource.

  • The resource must have a vCOMMIT-like variable which is proportional to maximum the power output, etc at any given timestep.
  • The resource must have a eTotalCap-like quantity and a Cap_Size-like parameter; only the ratio of the two is used.
diff --git a/previews/PR662/Model_Reference/methodofmorris/index.html b/previews/PR662/Model_Reference/methodofmorris/index.html index 243601c672..a306265fd9 100644 --- a/previews/PR662/Model_Reference/methodofmorris/index.html +++ b/previews/PR662/Model_Reference/methodofmorris/index.html @@ -1,2 +1,2 @@ -Method of Morris · GenX

Method of Morris

GenX.MatSpreadType
morris(EP::Model, path::AbstractString, setup::Dict, inputs::Dict, outpath::AbstractString, OPTIMIZER)

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.

source
+Method of Morris · GenX.jl

Method of Morris

GenX.MatSpreadType
morris(EP::Model, path::AbstractString, setup::Dict, inputs::Dict, outpath::AbstractString, OPTIMIZER)

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.

source
diff --git a/previews/PR662/Model_Reference/mga/index.html b/previews/PR662/Model_Reference/mga/index.html index 9cbb42fc05..ac5f7cb647 100644 --- a/previews/PR662/Model_Reference/mga/index.html +++ b/previews/PR662/Model_Reference/mga/index.html @@ -1,9 +1,9 @@ -Modeling to Generate Alternatives · GenX

Modeling to Generate Alternatives

GenX.mgaMethod
mga(EP::Model, path::AbstractString, setup::Dict, inputs::Dict)

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} +Modeling to Generate Alternatives · GenX.jl

Modeling to Generate Alternatives

GenX.mgaMethod
mga(EP::Model, path::AbstractString, setup::Dict, inputs::Dict)

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} \text{max/min} \quad &\sum_{z \in \mathcal{Z}}\sum_{r \in \mathcal{R}} \beta_{z,r}^{k}P_{z,r}\\ \text{s.t.} \quad &P_{zr} = \sum_{y \in \mathcal{G}}\sum_{t \in \mathcal{T}} \omega_{t} \Theta_{y,t,z,r} \\ & f \leq f^* + \delta \\ &Ax = b -\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.

source
+\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.

source
diff --git a/previews/PR662/Model_Reference/policies/index.html b/previews/PR662/Model_Reference/policies/index.html index 029d35e56f..2a37ca670b 100644 --- a/previews/PR662/Model_Reference/policies/index.html +++ b/previews/PR662/Model_Reference/policies/index.html @@ -1,5 +1,5 @@ -Policies · GenX

Emission mitigation policies

Capacity Reserve Margin

GenX.cap_reserve_margin!Function
cap_reserve_margin!(EP::Model, inputs::Dict, setup::Dict)

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.

\[\begin{aligned} +Policies · GenX.jl

Emission mitigation policies

Capacity Reserve Margin

GenX.cap_reserve_margin!Function
cap_reserve_margin!(EP::Model, inputs::Dict, setup::Dict)

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.

\[\begin{aligned} & \sum_{z \in \mathcal{Z}^{CRM}_{p}} \Big( \sum_{y \in \mathcal{H}} \epsilon_{y,z,p}^{CRM} \times \Delta^{\text{total}}_{y,z} + \sum_{y \in \mathcal{VRE}} \epsilon_{y,z,p}^{CRM} \times \rho^{max}_{y,z,t} \\ & + \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) + \sum_{y \in \mathcal{DF}} \epsilon_{y,z,p}^{CRM} \times \left(\Pi_{y,z,t} - \Theta_{y,z,t} \right) \\ & + \sum_{y \in \mathcal{VS}^{pv}} (\epsilon_{y,z,p}^{CRM} \times \eta^{inverter}_{y,z} \times \rho^{max,pv}_{y,z,t} \times \Delta^{total,pv}_{y,z}) \\ @@ -11,7 +11,7 @@ & + \sum_{l \in \mathcal{L}_{p}^{in}} \epsilon_{y,z,p}^{CRM} \times \Phi_{l,t} - \sum_{l \in \mathcal{L}_{p}^{out}} \epsilon_{y,z,p}^{CRM} \times \Phi_{l,t} + \sum_{s \geq 2} \Lambda_{s,t,z} \Big) \\ & \geq \sum_{z \in \mathcal{Z}^{CRM}_{p}} \left( \left(1 + RM_{z,p}^{CRM} \right) \times D_{z,t} \right) \hspace{1 cm} \forall t \in \mathcal{T}, \forall p\in \mathcal{P}^{CRM} -\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.

source

CO$_2$ Constraint Policy

GenX.co2_cap!Function
co2_cap!(EP::Model, inputs::Dict, setup::Dict)

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.

source

CO$_2$ Constraint Policy

GenX.co2_cap!Function
co2_cap!(EP::Model, inputs::Dict, setup::Dict)

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} \sum_{z \in \mathcal{Z}^{CO_2}_{p,mass}} \sum_{y \in \mathcal{G}} \sum_{t \in \mathcal{T}} \left(\epsilon_{y,z}^{CO_2} \times \omega_{t} \times \Theta_{y,z,t} \right) & \leq \sum_{z \in \mathcal{Z}^{CO_2}_{p,mass}} \epsilon^{CO_{2}}_{z,p, mass} \hspace{1 cm} \forall p \in \mathcal{P}^{CO_2}_{mass} \end{aligned}\]

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.

\[\begin{aligned} @@ -24,12 +24,12 @@ \end{aligned}\]

Generator-side emissions rate-based constraint

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:

\[\begin{aligned} \sum_{z \in \mathcal{Z}^{CO_2}_{p,gen}} \sum_{y \in \mathcal{G}} \sum_{t \in \mathcal{T}} & \left(\epsilon_{y,z}^{CO_2} \times \omega_{t} \times \Theta_{y,t,z} \right) \\ \leq \sum_{z \in \mathcal{Z}^{CO_2}_{p,gen}} \sum_{y \in \mathcal{G}} \sum_{t \in \mathcal{T}} & \left(\epsilon_{z,p,gen}^{CO_2} \times \omega_{t} \times \Theta_{y,t,z} \right) \hspace{1 cm} \forall p \in \mathcal{P}^{CO_2}_{gen} -\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.

source

Energy Share Requirement

GenX.load_energy_share_requirement!Function
load_energy_share_requirement!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to mimimum energy share requirement constraints (e.g. renewable portfolio standard or clean electricity standard policies)

source
GenX.energy_share_requirement!Function
energy_share_requirement!(EP::Model, inputs::Dict, setup::Dict)

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.

source

Energy Share Requirement

GenX.load_energy_share_requirement!Function
load_energy_share_requirement!(setup::Dict, path::AbstractString, inputs::Dict)

Read input parameters related to mimimum energy share requirement constraints (e.g. renewable portfolio standard or clean electricity standard policies)

source
GenX.energy_share_requirement!Function
energy_share_requirement!(EP::Model, inputs::Dict, setup::Dict)

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} &\sum_{z \in \mathcal{Z}_{p}^{ESR}} \sum_{y \in \mathcal{G}_{p}^{ESR}} \sum_{t \in \mathcal{T}} (\omega_{t} \times \Theta_{y,z,t}) \geq \sum_{z \in \mathcal{Z}^{ESR}_{p}} \sum_{t \in \mathcal{T}} (\mu_{p,z}^{ESR} \times \omega_{t} \times D_{z,t}) + \\ &\sum_{y \in \mathcal{VS}^{stor}} \sum_{z \in \mathcal{Z}^{ESR}_{p}} \sum_{t \in \mathcal{T}} \left(\mu_{p,z}^{ESR} \times \omega_{t} \times (\frac{\Pi^{dc}_{y,z,t}}{\eta_{y,z}^{inverter}} + \Pi^{ac}_{y,z,t} - \eta_{y,z}^{inverter} \times \Theta^{dc}_{y,z,t} - \Theta^{ac}_{y,z,t}) \right) + \\ &\sum_{y \in \mathcal{O}} \sum_{z \in \mathcal{Z}^{ESR}_{p}} \sum_{t \in \mathcal{T}} \left(\mu_{p,z}^{ESR} \times \omega_{t} \times (\Pi_{y,z,t} - \Theta_{y,z,t}) \right) \hspace{1 cm} \forall p \in \mathcal{P}^{ESR} \\ -\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).

source

Minimum Capacity Requirement

GenX.minimum_capacity_requirement!Function
minimum_capacity_requirement!(EP::Model, inputs::Dict, setup::Dict)

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).

source

Minimum Capacity Requirement

GenX.minimum_capacity_requirement!Function
minimum_capacity_requirement!(EP::Model, inputs::Dict, setup::Dict)

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} \sum_{y \in \mathcal{G} } \sum_{z \in \mathcal{Z} } \left( \epsilon_{y,z,p}^{MinCapReq} \times \Delta^{\text{total}}_{y,z} \right) \geq REQ_{p}^{MinCapReq} \hspace{1 cm} \forall p \in \mathcal{P}^{MinCapReq} -\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.

source

Maximum Capacity Requirement

GenX.load_maximum_capacity_requirement!Method
load_maximum_capacity_requirement!(path::AbstractString, inputs::Dict, setup::Dict)

Read input parameters related to maximum capacity requirement constraints (e.g. technology specific deployment mandates)

source
GenX.maximum_capacity_requirement!Method
maximum_capacity_requirement!(EP::Model, inputs::Dict, setup::Dict)

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.

source

Maximum Capacity Requirement

GenX.load_maximum_capacity_requirement!Method
load_maximum_capacity_requirement!(path::AbstractString, inputs::Dict, setup::Dict)

Read input parameters related to maximum capacity requirement constraints (e.g. technology specific deployment mandates)

source
GenX.maximum_capacity_requirement!Method
maximum_capacity_requirement!(EP::Model, inputs::Dict, setup::Dict)

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} \sum_{y \in \mathcal{G} } \sum_{z \in \mathcal{Z} } \left( \epsilon_{y,z,p}^{MaxCapReq} \times \Delta^{\text{total}}_{y,z} \right) \leq REQ_{p}^{MaxCapReq} \hspace{1 cm} \forall p \in \mathcal{P}^{MaxCapReq} -\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.

source
+\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.

source
diff --git a/previews/PR662/Model_Reference/solve_model/index.html b/previews/PR662/Model_Reference/solve_model/index.html index 1d4c7f5ff6..852f5d3d41 100644 --- a/previews/PR662/Model_Reference/solve_model/index.html +++ b/previews/PR662/Model_Reference/solve_model/index.html @@ -1,2 +1,2 @@ -Solving the Model · GenX

Solving the Model

GenX.fix_integersMethod
fix_integers(jump_model::Model)

This function fixes the iteger variables ones the model has been solved in order to calculate approximations of dual variables.

Arguments

  • jump_model::Model: a model object containing that has been previously solved.

Returns

nothing (modifies an existing-solved model in the memory). solve() must be run again to solve and getdual veriables

source
GenX.solve_modelMethod
solve_model(EP::Model, setup::Dict)

Description: Solves and extracts solution variables for later processing

Arguments

  • EP::Model: a JuMP model representing the energy optimization problem
  • setup::Dict: a Dict containing GenX setup flags

Returns

  • EP::Model: the solved JuMP model
  • solver_time::Float64: time taken to solve the model
source
+Solving the Model · GenX.jl

Solving the Model

GenX.fix_integersMethod
fix_integers(jump_model::Model)

This function fixes the iteger variables ones the model has been solved in order to calculate approximations of dual variables.

Arguments

  • jump_model::Model: a model object containing that has been previously solved.

Returns

nothing (modifies an existing-solved model in the memory). solve() must be run again to solve and getdual veriables

source
GenX.solve_modelMethod
solve_model(EP::Model, setup::Dict)

Description: Solves and extracts solution variables for later processing

Arguments

  • EP::Model: a JuMP model representing the energy optimization problem
  • setup::Dict: a Dict containing GenX setup flags

Returns

  • EP::Model: the solved JuMP model
  • solver_time::Float64: time taken to solve the model
source
diff --git a/previews/PR662/Model_Reference/solver_configuration_api/index.html b/previews/PR662/Model_Reference/solver_configuration_api/index.html index 359c281d24..42b756755a 100644 --- a/previews/PR662/Model_Reference/solver_configuration_api/index.html +++ b/previews/PR662/Model_Reference/solver_configuration_api/index.html @@ -1,5 +1,5 @@ -Solver Configurations · GenX

Configuring the Solvers

GenX.configure_solverMethod
configure_solver(solver_settings_path::String, optimizer::Any)

This method returns a solver-specific MathOptInterface.OptimizerWithAttributes optimizer instance to be used in the GenX.generate\_model() method.

Arguments

  • solver_settings_path::String: specifies the path to the directory that contains the settings YAML file for the specified solver.
  • optimizer::Any: the optimizer instance to be configured.

Currently supported solvers include: "Gurobi", "CPLEX", "Clp", "Cbc", or "SCIP"

Returns

  • optimizer::MathOptInterface.OptimizerWithAttributes: the configured optimizer instance.
source
GenX.infer_solverMethod
infer_solver(optimizer::Any)

Return the name (String) of the solver to be used in the GenX.configure_solver method according to the solver imported by the user.

source
GenX.rename_keysMethod
rename_keys(attributes:Dict, new_key_names::Dict)

Renames the keys of the attributes dictionary based on old->new pairs in the newkeynames dictionary.

source

Configuring HiGHS

GenX.configure_highsMethod
configure_highs(solver_settings_path::String)

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/

# HiGHS Solver Parameters
+Solver Configurations · GenX.jl

Configuring the Solvers

GenX.configure_solverMethod
configure_solver(solver_settings_path::String, optimizer::Any)

This method returns a solver-specific MathOptInterface.OptimizerWithAttributes optimizer instance to be used in the GenX.generate\_model() method.

Arguments

  • solver_settings_path::String: specifies the path to the directory that contains the settings YAML file for the specified solver.
  • optimizer::Any: the optimizer instance to be configured.

Currently supported solvers include: "Gurobi", "CPLEX", "Clp", "Cbc", or "SCIP"

Returns

  • optimizer::MathOptInterface.OptimizerWithAttributes: the configured optimizer instance.
source
GenX.infer_solverMethod
infer_solver(optimizer::Any)

Return the name (String) of the solver to be used in the GenX.configure_solver method according to the solver imported by the user.

source
GenX.rename_keysMethod
rename_keys(attributes:Dict, new_key_names::Dict)

Renames the keys of the attributes dictionary based on old->new pairs in the newkeynames dictionary.

source

Configuring HiGHS

GenX.configure_highsMethod
configure_highs(solver_settings_path::String)

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/

# HiGHS Solver Parameters
 # Common solver settings
 Feasib_Tol: 1.0e-06        # Primal feasibility tolerance # [type: double, advanced: false, range: [1e-10, inf], default: 1e-07]
 Optimal_Tol: 1.0e-03       # Dual feasibility tolerance # [type: double, advanced: false, range: [1e-10, inf], default: 1e-07]
@@ -318,4 +318,4 @@
 
 Use LiDSE if LP has right properties
 [type: bool, advanced: true, range: {false, true}, default: true]
-less_infeasible_DSE_choose_row: true
source

Configuring Gurobi

GenX.configure_gurobiMethod
configure_gurobi(solver_settings_path::String)

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)
source

Configuring CPLEX

GenX.configure_cplexMethod
configure_cplex(solver_settings_path::String)

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.

  • NumericFocus,

    sets CPX_PARAM_NUMERICALEMPHASIS. Numerical precision emphasis. Default is 0.

  • BarObjRng,

    sets CPX_PARAM_BAROBJRNG. The maximum absolute value of the objective function. Default is 1e+75.

  • SolutionType,

    sets CPX_PARAM_SOLUTIONTYPE. Solution type for LP or QP. Default is 2.

The optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:

Any other attributes in the settings file (which typically start with CPX_PARAM_) will also be passed to the solver.

source

Configuring Clp

GenX.configure_clpMethod
configure_clp(solver_settings_path::String)

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:

  • PrimalTolerance = 1e-7 (Primal feasibility tolerance)
  • DualTolerance = 1e-7 (Dual feasibility tolerance)
  • DualObjectiveLimit = 1e308 (When using dual simplex (where the objective is monotonically changing), terminate when the objective exceeds this limit)
  • MaximumIterations = 2147483647 (Terminate after performing this number of simplex iterations)
  • MaximumSeconds = -1.0 (Terminate after this many seconds have passed. A negative value means no time limit)
  • LogLevel = 1 (Set to 1, 2, 3, or 4 for increasing output. Set to 0 to disable output)
  • PresolveType = 0 (Set to 1 to disable presolve)
  • SolveType = 5 (Solution method: dual simplex (0), primal simplex (1), sprint (2), barrier with crossover (3), barrier without crossover (4), automatic (5))
  • InfeasibleReturn = 0 (Set to 1 to return as soon as the problem is found to be infeasible (by default, an infeasibility proof is computed as well))
  • Scaling = 3 (0 0ff, 1 equilibrium, 2 geometric, 3 auto, 4 dynamic (later))
  • Perturbation = 100 (switch on perturbation (50), automatic (100), don't try perturbing (102))
source

Configuring Cbc

GenX.configure_cbcMethod
configure_cbc(solver_settings_path::String)

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:

  • seconds = 1e-6
  • logLevel = 1e-6
  • maxSolutions = -1
  • maxNodes = -1
  • allowableGap = -1
  • ratioGap = Inf
  • threads = 1
source

Configuring SCIP

GenX.configure_scipMethod
configure_scip(solver_settings_path::String)

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:

  • Dispverblevel = 0
  • limitsgap = 0.05
source
+less_infeasible_DSE_choose_row: true
source

Configuring Gurobi

GenX.configure_gurobiMethod
configure_gurobi(solver_settings_path::String)

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)
source

Configuring CPLEX

GenX.configure_cplexMethod
configure_cplex(solver_settings_path::String)

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.

  • NumericFocus,

    sets CPX_PARAM_NUMERICALEMPHASIS. Numerical precision emphasis. Default is 0.

  • BarObjRng,

    sets CPX_PARAM_BAROBJRNG. The maximum absolute value of the objective function. Default is 1e+75.

  • SolutionType,

    sets CPX_PARAM_SOLUTIONTYPE. Solution type for LP or QP. Default is 2.

The optimizer instance is configured with the following default parameters if a user-specified parameter for each respective field is not provided:

Any other attributes in the settings file (which typically start with CPX_PARAM_) will also be passed to the solver.

source

Configuring Clp

GenX.configure_clpMethod
configure_clp(solver_settings_path::String)

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:

  • PrimalTolerance = 1e-7 (Primal feasibility tolerance)
  • DualTolerance = 1e-7 (Dual feasibility tolerance)
  • DualObjectiveLimit = 1e308 (When using dual simplex (where the objective is monotonically changing), terminate when the objective exceeds this limit)
  • MaximumIterations = 2147483647 (Terminate after performing this number of simplex iterations)
  • MaximumSeconds = -1.0 (Terminate after this many seconds have passed. A negative value means no time limit)
  • LogLevel = 1 (Set to 1, 2, 3, or 4 for increasing output. Set to 0 to disable output)
  • PresolveType = 0 (Set to 1 to disable presolve)
  • SolveType = 5 (Solution method: dual simplex (0), primal simplex (1), sprint (2), barrier with crossover (3), barrier without crossover (4), automatic (5))
  • InfeasibleReturn = 0 (Set to 1 to return as soon as the problem is found to be infeasible (by default, an infeasibility proof is computed as well))
  • Scaling = 3 (0 0ff, 1 equilibrium, 2 geometric, 3 auto, 4 dynamic (later))
  • Perturbation = 100 (switch on perturbation (50), automatic (100), don't try perturbing (102))
source

Configuring Cbc

GenX.configure_cbcMethod
configure_cbc(solver_settings_path::String)

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:

  • seconds = 1e-6
  • logLevel = 1e-6
  • maxSolutions = -1
  • maxNodes = -1
  • allowableGap = -1
  • ratioGap = Inf
  • threads = 1
source

Configuring SCIP

GenX.configure_scipMethod
configure_scip(solver_settings_path::String)

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:

  • Dispverblevel = 0
  • limitsgap = 0.05
source
diff --git a/previews/PR662/Model_Reference/utility_functions/index.html b/previews/PR662/Model_Reference/utility_functions/index.html index 1a3b7ce6ba..48eb7a1b00 100644 --- a/previews/PR662/Model_Reference/utility_functions/index.html +++ b/previews/PR662/Model_Reference/utility_functions/index.html @@ -1,4 +1,4 @@ -Utility Functions · GenX

Utility Functions

GenX.by_rid_resMethod
by_rid_res(rid::Integer, sym::Symbol, rs::Vector{<:AbstractResource})
+Utility Functions · GenX.jl

Utility Functions

GenX.by_rid_resMethod
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`.
source
GenX.hoursafterMethod
hoursafter(p::Int, t::Int, a::Int)

Determines the time index a hours after index t in a landscape starting from t=1 which is separated into distinct periods of length p.

For example, if p = 10, 1 hour after t=9 is t=10, 1 hour after t=10 is t=1, 1 hour after t=11 is t=2

source
GenX.hoursafterMethod
hoursafter(p::Int, t::Int, b::UnitRange)

This is a generalization of hoursafter(... b::Int) to allow for example a=1:3 to fetch a Vector{Int} of the three hours after time index t.

source
GenX.hoursbeforeMethod
hoursbefore(p::Int, t::Int, b::Int)

Determines the time index b hours before index t in a landscape starting from t=1 which is separated into distinct periods of length p.

For example, if p = 10, 1 hour before t=1 is t=10, 1 hour before t=10 is t=9 1 hour before t=11 is t=20

source
GenX.hoursbeforeMethod
hoursbefore(p::Int, t::Int, b::UnitRange)

This is a generalization of hoursbefore(... b::Int) to allow for example b=1:3 to fetch a Vector{Int} of the three hours before time index t.

source
GenX.is_nonzeroMethod
is_nonzero(df::DataFrame, col::Symbol)::BitVector

This function checks if a column in a dataframe is all zeros.

source
+This function returns the value of the attribute `sym` for the resource given by the ID `rid`.
source
GenX.hoursafterMethod
hoursafter(p::Int, t::Int, a::Int)

Determines the time index a hours after index t in a landscape starting from t=1 which is separated into distinct periods of length p.

For example, if p = 10, 1 hour after t=9 is t=10, 1 hour after t=10 is t=1, 1 hour after t=11 is t=2

source
GenX.hoursafterMethod
hoursafter(p::Int, t::Int, b::UnitRange)

This is a generalization of hoursafter(... b::Int) to allow for example a=1:3 to fetch a Vector{Int} of the three hours after time index t.

source
GenX.hoursbeforeMethod
hoursbefore(p::Int, t::Int, b::Int)

Determines the time index b hours before index t in a landscape starting from t=1 which is separated into distinct periods of length p.

For example, if p = 10, 1 hour before t=1 is t=10, 1 hour before t=10 is t=9 1 hour before t=11 is t=20

source
GenX.hoursbeforeMethod
hoursbefore(p::Int, t::Int, b::UnitRange)

This is a generalization of hoursbefore(... b::Int) to allow for example b=1:3 to fetch a Vector{Int} of the three hours before time index t.

source
GenX.is_nonzeroMethod
is_nonzero(df::DataFrame, col::Symbol)::BitVector

This function checks if a column in a dataframe is all zeros.

source
diff --git a/previews/PR662/Model_Reference/write_outputs/index.html b/previews/PR662/Model_Reference/write_outputs/index.html index 1df13794d4..2b229bd21b 100644 --- a/previews/PR662/Model_Reference/write_outputs/index.html +++ b/previews/PR662/Model_Reference/write_outputs/index.html @@ -1,6 +1,6 @@ -Outputs Functions · GenX

Functions for Writing the Different Results/Outputs to Separate Files

GenX.write_annualMethod
write_annual(fullpath::AbstractString, dfOut::DataFrame)

Internal function for writing annual outputs.

source
GenX.write_fulltimeseriesMethod
write_fulltimeseries(fullpath::AbstractString, dataOut::Matrix{Float64}, dfOut::DataFrame)

Internal function for writing full time series outputs. This function wraps the instructions for creating the full time series output files.

source
GenX.write_outputsMethod
write_outputs(EP::Model, path::AbstractString, setup::Dict, inputs::Dict)

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.

source
GenX.choose_output_dirMethod
path = choose_output_dir(pathinit)

Avoid overwriting (potentially important) existing results by appending to the directory name

Checks if the suggested output directory already exists. While yes, it appends _1, _2, etc till an unused name is found

source
GenX.dftransposeMethod

df = dftranspose(df::DataFrame, withhead::Bool)

Returns a transpose of a Dataframe.

FIXME: This is for DataFrames@0.20.2, as used in GenX. Versions 0.21+ could use stack and unstack to make further changes while retaining the order

source

Write Status

GenX.write_statusMethod
write_status(path::AbstractString, inputs::Dict, EP::Model)

Function for writing the final solve status of the optimization problem solved.

source

Write CO_2 Cap

GenX.write_co2_capFunction
write_co2_cap(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for reporting carbon price associated with carbon cap constraints.

source

Write Costs

GenX.write_costsMethod
write_costs(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the costs pertaining to the objective function (fixed, variable O&M etc.).

source

Write Fuel Consumption

GenX.write_fuel_consumptionFunction
write_fuel_consumption(path::AbstractString, inputs::Dict, setup::Dict, EP::Model).

Write fuel consumption of each power plant.

source

Write Emissions

GenX.write_emissionsMethod
write_emissions(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for reporting time-dependent CO$_2$ emissions by zone.

source

Write Capacities

GenX.write_capacityMethod
write_capacity(path::AbstractString, inputs::Dict, setup::Dict, EP::Model))

Function for writing the diferent capacities for the different generation technologies (starting capacities or, existing capacities, retired capacities, and new-built capacities).

source

Write Capacity Value # TODO: add it

GenX.capacity_reserve_margin_priceMethod
capacity_reserve_margin_price(EP::Model,
+Outputs Functions · GenX.jl

Functions for Writing the Different Results/Outputs to Separate Files

GenX.write_annualMethod
write_annual(fullpath::AbstractString, dfOut::DataFrame)

Internal function for writing annual outputs.

source
GenX.write_fulltimeseriesMethod
write_fulltimeseries(fullpath::AbstractString, dataOut::Matrix{Float64}, dfOut::DataFrame)

Internal function for writing full time series outputs. This function wraps the instructions for creating the full time series output files.

source
GenX.write_outputsMethod
write_outputs(EP::Model, path::AbstractString, setup::Dict, inputs::Dict)

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.

source
GenX.choose_output_dirMethod
path = choose_output_dir(pathinit)

Avoid overwriting (potentially important) existing results by appending to the directory name

Checks if the suggested output directory already exists. While yes, it appends _1, _2, etc till an unused name is found

source
GenX.dftransposeMethod

df = dftranspose(df::DataFrame, withhead::Bool)

Returns a transpose of a Dataframe.

FIXME: This is for DataFrames@0.20.2, as used in GenX. Versions 0.21+ could use stack and unstack to make further changes while retaining the order

source

Write Status

GenX.write_statusMethod
write_status(path::AbstractString, inputs::Dict, EP::Model)

Function for writing the final solve status of the optimization problem solved.

source

Write CO_2 Cap

GenX.write_co2_capFunction
write_co2_cap(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for reporting carbon price associated with carbon cap constraints.

source

Write Costs

GenX.write_costsMethod
write_costs(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the costs pertaining to the objective function (fixed, variable O&M etc.).

source

Write Fuel Consumption

GenX.write_fuel_consumptionFunction
write_fuel_consumption(path::AbstractString, inputs::Dict, setup::Dict, EP::Model).

Write fuel consumption of each power plant.

source

Write Emissions

GenX.write_emissionsMethod
write_emissions(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for reporting time-dependent CO$_2$ emissions by zone.

source

Write Capacities

GenX.write_capacityMethod
write_capacity(path::AbstractString, inputs::Dict, setup::Dict, EP::Model))

Function for writing the diferent capacities for the different generation technologies (starting capacities or, existing capacities, retired capacities, and new-built capacities).

source

Write Capacity Value # TODO: add it

GenX.capacity_reserve_margin_priceMethod
capacity_reserve_margin_price(EP::Model,
                               inputs::Dict,
                               setup::Dict,
-                              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.

Returns a vector, with units of $/MW
source

Write Capacity Factors

GenX.write_capacityfactorMethod
write_capacityfactor(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

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.

source

Write Charge Values

GenX.write_chargeMethod
write_charge(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the charging energy values of the different storage technologies.

source

Write Non-served-energy

GenX.write_nseMethod
write_nse(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for reporting non-served energy for every model zone, time step and cost-segment.

source

Write Storage State of Charge

GenX.write_storageMethod
write_storage(path::AbstractString, inputs::Dict,setup::Dict, EP::Model)

Function for writing the capacities of different storage technologies, including hydro reservoir, flexible storage tech etc.

source

Write Storage Dual

GenX.write_storagedualMethod
write_storagedual(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for reporting dual of storage level (state of charge) balance of each resource in each time step.

source

Write Power

GenX.write_powerMethod
write_power(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the different values of power generated by the different technologies in operation.

source

Write Curtailment

GenX.write_curtailmentMethod
write_curtailment(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the curtailment values of the different variable renewable resources (both standalone and co-located).

source

Write Prices

GenX.locational_marginal_priceMethod
locational_marginal_price(EP::Model, inputs::Dict, setup::Dict)

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
source
GenX.write_priceMethod
write_price(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

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.

source

Write Reliability

GenX.write_reliabilityMethod
write_reliability(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for reporting dual variable of maximum non-served energy constraint (shadow price of reliability constraint) for each model zone and time step.

source

Write Energy Revenue

GenX.write_energy_revenueMethod
write_energy_revenue(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing energy revenue from the different generation technologies.

source

Write Subsidy Revenue

GenX.write_subsidy_revenueMethod
write_subsidy_revenue(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

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 $.

source

Write Operating Reserve and Regulation Revenue

GenX.write_operating_reserve_regulation_revenueMethod
write_operating_reserve_regulation_revenue(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

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.

source

Write Capacity Revenue

GenX.write_reserve_margin_revenueMethod
write_reserve_margin_revenue(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

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.

source

Write Energy Share Requirement Revenue

GenX.write_esr_revenueMethod
write_esr_revenue(path::AbstractString, inputs::Dict, setup::Dict, dfPower::DataFrame, dfESR::DataFrame, EP::Model)

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 $.

source

Write Net Revenue

GenX.write_net_revenueMethod
write_net_revenue(path::AbstractString, inputs::Dict, setup::Dict, EP::Model, dfCap::DataFrame, dfESRRev::DataFrame, dfResRevenue::DataFrame, dfChargingcost::DataFrame, dfPower::DataFrame, dfEnergyRevenue::DataFrame, dfSubRevenue::DataFrame, dfRegSubRevenue::DataFrame, dfVreStor::DataFrame, dfOpRegRevenue::DataFrame, dfOpRsvRevenue::DataFrame)

Function for writing net revenue of different generation technologies.

source

Write Co-Located VRE and Storage files

GenX.write_vre_storFunction
write_vre_stor(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage specific files.

source
GenX.write_vre_stor_capacityFunction
write_vre_stor_capacity(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage capacities.

source
GenX.write_vre_stor_chargeFunction
write_vre_stor_charge(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage charging decision variables/expressions.

source
GenX.write_vre_stor_dischargeFunction
write_vre_stor_discharge(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage discharging decision variables/expressions.

source

Write Multi-stage files

GenX.write_multi_stage_costsFunction
write_multi_stage_costs(outpath::String, settings_d::Dict)

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.
source
GenX.write_multi_stage_statsFunction

writemultistagestats(outpath::String, statsd::Dict)

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.
source
GenX.write_multi_stage_settingsFunction
write_multi_stage_settings(outpath::AbstractString, settings_d::Dict)

Function for writing the multi-stage settings file to the output path for future reference.

source
GenX.write_multi_stage_network_expansionFunction
write_multi_stage_network_expansion(outpath::String, settings_d::Dict)

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.
source
GenX.write_multi_stage_capacities_chargeFunction
write_multi_stage_capacities_charge(outpath::String, settings_d::Dict)

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.
source
GenX.write_multi_stage_capacities_energyFunction
write_multi_stage_capacities_energy(outpath::String, settings_d::Dict)

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.
source

Write maintenance files

Write DCOPF files

GenX.write_anglesFunction
write_angles(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for reporting the bus angles for each model zone and time step if the DC_OPF flag is activated

source

Write Settings files

+ 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.

Returns a vector, with units of $/MW
source

Write Capacity Factors

GenX.write_capacityfactorMethod
write_capacityfactor(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

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.

source

Write Charge Values

GenX.write_chargeMethod
write_charge(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the charging energy values of the different storage technologies.

source

Write Non-served-energy

GenX.write_nseMethod
write_nse(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for reporting non-served energy for every model zone, time step and cost-segment.

source

Write Storage State of Charge

GenX.write_storageMethod
write_storage(path::AbstractString, inputs::Dict,setup::Dict, EP::Model)

Function for writing the capacities of different storage technologies, including hydro reservoir, flexible storage tech etc.

source

Write Storage Dual

GenX.write_storagedualMethod
write_storagedual(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for reporting dual of storage level (state of charge) balance of each resource in each time step.

source

Write Power

GenX.write_powerMethod
write_power(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the different values of power generated by the different technologies in operation.

source

Write Curtailment

GenX.write_curtailmentMethod
write_curtailment(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the curtailment values of the different variable renewable resources (both standalone and co-located).

source

Write Prices

GenX.locational_marginal_priceMethod
locational_marginal_price(EP::Model, inputs::Dict, setup::Dict)

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
source
GenX.write_priceMethod
write_price(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

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.

source

Write Reliability

GenX.write_reliabilityMethod
write_reliability(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for reporting dual variable of maximum non-served energy constraint (shadow price of reliability constraint) for each model zone and time step.

source

Write Energy Revenue

GenX.write_energy_revenueMethod
write_energy_revenue(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing energy revenue from the different generation technologies.

source

Write Subsidy Revenue

GenX.write_subsidy_revenueMethod
write_subsidy_revenue(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

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 $.

source

Write Operating Reserve and Regulation Revenue

GenX.write_operating_reserve_regulation_revenueMethod
write_operating_reserve_regulation_revenue(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

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.

source

Write Capacity Revenue

GenX.write_reserve_margin_revenueMethod
write_reserve_margin_revenue(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

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.

source

Write Energy Share Requirement Revenue

GenX.write_esr_revenueMethod
write_esr_revenue(path::AbstractString, inputs::Dict, setup::Dict, dfPower::DataFrame, dfESR::DataFrame, EP::Model)

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 $.

source

Write Net Revenue

GenX.write_net_revenueMethod
write_net_revenue(path::AbstractString, inputs::Dict, setup::Dict, EP::Model, dfCap::DataFrame, dfESRRev::DataFrame, dfResRevenue::DataFrame, dfChargingcost::DataFrame, dfPower::DataFrame, dfEnergyRevenue::DataFrame, dfSubRevenue::DataFrame, dfRegSubRevenue::DataFrame, dfVreStor::DataFrame, dfOpRegRevenue::DataFrame, dfOpRsvRevenue::DataFrame)

Function for writing net revenue of different generation technologies.

source

Write Co-Located VRE and Storage files

GenX.write_vre_storFunction
write_vre_stor(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage specific files.

source
GenX.write_vre_stor_capacityFunction
write_vre_stor_capacity(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage capacities.

source
GenX.write_vre_stor_chargeFunction
write_vre_stor_charge(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage charging decision variables/expressions.

source
GenX.write_vre_stor_dischargeFunction
write_vre_stor_discharge(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for writing the vre-storage discharging decision variables/expressions.

source

Write Multi-stage files

GenX.write_multi_stage_costsFunction
write_multi_stage_costs(outpath::String, settings_d::Dict)

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.
source
GenX.write_multi_stage_statsFunction

writemultistagestats(outpath::String, statsd::Dict)

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.
source
GenX.write_multi_stage_settingsFunction
write_multi_stage_settings(outpath::AbstractString, settings_d::Dict)

Function for writing the multi-stage settings file to the output path for future reference.

source
GenX.write_multi_stage_network_expansionFunction
write_multi_stage_network_expansion(outpath::String, settings_d::Dict)

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.
source
GenX.write_multi_stage_capacities_chargeFunction
write_multi_stage_capacities_charge(outpath::String, settings_d::Dict)

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.
source
GenX.write_multi_stage_capacities_energyFunction
write_multi_stage_capacities_energy(outpath::String, settings_d::Dict)

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.
source

Write maintenance files

Write DCOPF files

GenX.write_anglesFunction
write_angles(path::AbstractString, inputs::Dict, setup::Dict, EP::Model)

Function for reporting the bus angles for each model zone and time step if the DC_OPF flag is activated

source

Write Settings files

diff --git a/previews/PR662/Public_API/public_api/index.html b/previews/PR662/Public_API/public_api/index.html index 72b1fc4cd9..34e0fed9ad 100644 --- a/previews/PR662/Public_API/public_api/index.html +++ b/previews/PR662/Public_API/public_api/index.html @@ -1,5 +1,5 @@ -Public API · GenX

Public Documentation

Documentation for GenX public interface.

GenX.run_genx_case!Function
run_genx_case!(case::AbstractString, optimizer::Any=HiGHS.Optimizer)

Run a GenX case with the specified optimizer. The optimizer can be any solver supported by MathOptInterface.

Arguments

  • case::AbstractString: the path to the case folder
  • optimizer::Any: the optimizer instance to be used in the optimization model

Example

run_genx_case!("path/to/case", HiGHS.Optimizer)
run_genx_case!("path/to/case", Gurobi.Optimizer)
source
GenX.configure_settingsFunction
configure_settings(settings_path::String, output_settings_path::String)

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.

Returns

  • settings::Dict: The settings dictionary.
source
GenX.configure_solverFunction
configure_solver(solver_settings_path::String, optimizer::Any)

This method returns a solver-specific MathOptInterface.OptimizerWithAttributes optimizer instance to be used in the GenX.generate\_model() method.

Arguments

  • solver_settings_path::String: specifies the path to the directory that contains the settings YAML file for the specified solver.
  • optimizer::Any: the optimizer instance to be configured.

Currently supported solvers include: "Gurobi", "CPLEX", "Clp", "Cbc", or "SCIP"

Returns

  • optimizer::MathOptInterface.OptimizerWithAttributes: the configured optimizer instance.
source
GenX.load_inputsFunction
load_inputs(setup::Dict,path::AbstractString)

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

source
GenX.load_dataframeFunction
load_dataframe(path::AbstractString)

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.

source
load_dataframe(dir::AbstractString, base::AbstractString)

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.

source
GenX.generate_modelFunction
generate_model(setup::Dict,inputs::Dict,OPTIMIZER::MOI.OptimizerWithAttributes,modeloutput = nothing)

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:

\[\begin{aligned} +Public API · GenX.jl

Public Documentation

Documentation for GenX public interface.

GenX.run_genx_case!Function
run_genx_case!(case::AbstractString, optimizer::Any=HiGHS.Optimizer)

Run a GenX case with the specified optimizer. The optimizer can be any solver supported by MathOptInterface.

Arguments

  • case::AbstractString: the path to the case folder
  • optimizer::Any: the optimizer instance to be used in the optimization model

Example

run_genx_case!("path/to/case", HiGHS.Optimizer)
run_genx_case!("path/to/case", Gurobi.Optimizer)
source
GenX.configure_settingsFunction
configure_settings(settings_path::String, output_settings_path::String)

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.

Returns

  • settings::Dict: The settings dictionary.
source
GenX.configure_solverFunction
configure_solver(solver_settings_path::String, optimizer::Any)

This method returns a solver-specific MathOptInterface.OptimizerWithAttributes optimizer instance to be used in the GenX.generate\_model() method.

Arguments

  • solver_settings_path::String: specifies the path to the directory that contains the settings YAML file for the specified solver.
  • optimizer::Any: the optimizer instance to be configured.

Currently supported solvers include: "Gurobi", "CPLEX", "Clp", "Cbc", or "SCIP"

Returns

  • optimizer::MathOptInterface.OptimizerWithAttributes: the configured optimizer instance.
source
GenX.load_inputsFunction
load_inputs(setup::Dict,path::AbstractString)

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

source
GenX.load_dataframeFunction
load_dataframe(path::AbstractString)

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.

source
load_dataframe(dir::AbstractString, base::AbstractString)

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.

source
GenX.generate_modelFunction
generate_model(setup::Dict,inputs::Dict,OPTIMIZER::MOI.OptimizerWithAttributes,modeloutput = nothing)

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:

\[\begin{aligned} &\sum_{y \in \mathcal{G} } \sum_{z \in \mathcal{Z}} \left( (\pi^{INVEST}_{y,z} \times \overline{\Omega}^{size}_{y,z} \times \Omega_{y,z}) + (\pi^{FOM}_{y,z} \times \overline{\Omega}^{size}_{y,z} \times \Delta^{total}_{y,z})\right) + \notag \\ @@ -18,11 +18,11 @@ & \sum_{y\in \mathcal{DF}}{(-\Theta_{y,z,t}+\Pi_{y,z,t})} +\sum_{y\in \mathcal{W}}{\Theta_{y,z,t}}+ \notag\\ &+ \sum_{s\in \mathcal{S}}{\Lambda_{s,z,t}} - \sum_{l\in \mathcal{L}}{(\varphi^{map}_{l,z} \times \Phi_{l,t})} -\frac{1}{2} \sum_{l\in \mathcal{L}}{(\varphi^{map}_{l,z} \times \beta_{l,t}(\cdot))} = D_{z,t} \forall z\in \mathcal{Z}, t \in \mathcal{T} -\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
source
GenX.solve_modelFunction
solve_model(EP::Model, setup::Dict)

Description: Solves and extracts solution variables for later processing

Arguments

  • EP::Model: a JuMP model representing the energy optimization problem
  • setup::Dict: a Dict containing GenX setup flags

Returns

  • EP::Model: the solved JuMP model
  • solver_time::Float64: time taken to solve the model
source
GenX.write_outputsFunction
write_outputs(EP::Model, path::AbstractString, setup::Dict, inputs::Dict)

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.

source
GenX.mgaFunction
mga(EP::Model, path::AbstractString, setup::Dict, inputs::Dict)

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
source
GenX.solve_modelFunction
solve_model(EP::Model, setup::Dict)

Description: Solves and extracts solution variables for later processing

Arguments

  • EP::Model: a JuMP model representing the energy optimization problem
  • setup::Dict: a Dict containing GenX setup flags

Returns

  • EP::Model: the solved JuMP model
  • solver_time::Float64: time taken to solve the model
source
GenX.write_outputsFunction
write_outputs(EP::Model, path::AbstractString, setup::Dict, inputs::Dict)

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.

source
GenX.mgaFunction
mga(EP::Model, path::AbstractString, setup::Dict, inputs::Dict)

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} \text{max/min} \quad &\sum_{z \in \mathcal{Z}}\sum_{r \in \mathcal{R}} \beta_{z,r}^{k}P_{z,r}\\ \text{s.t.} \quad &P_{zr} = \sum_{y \in \mathcal{G}}\sum_{t \in \mathcal{T}} \omega_{t} \Theta_{y,t,z,r} \\ & f \leq f^* + \delta \\ &Ax = b -\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.

source

Multi-stage specific functions

GenX.configure_multi_stage_inputsFunction
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:

  1. Overnight capital costs are computed via the compute_overnight_capital_cost() method and overwrite internal model representations of annualized investment costs.

  2. 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).

  3. Internal set representations of resources eligible for capacity retirements are overwritten to ensure compatability with multi-stage modeling.

  4. 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.

source
GenX.run_ddpFunction
run_ddp(models_d::Dict, setup::Dict, inputs_d::Dict)

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.
source
GenX.write_multi_stage_outputsFunction
write_multi_stage_outputs(stats_d::Dict, outpath::String, settings_d::Dict)

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.
source
+\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.

source

Multi-stage specific functions

GenX.configure_multi_stage_inputsFunction
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:

  1. Overnight capital costs are computed via the compute_overnight_capital_cost() method and overwrite internal model representations of annualized investment costs.

  2. 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).

  3. Internal set representations of resources eligible for capacity retirements are overwritten to ensure compatability with multi-stage modeling.

  4. 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.

source
GenX.run_ddpFunction
run_ddp(models_d::Dict, setup::Dict, inputs_d::Dict)

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.
source
GenX.write_multi_stage_outputsFunction
write_multi_stage_outputs(stats_d::Dict, outpath::String, settings_d::Dict)

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.
source
diff --git a/previews/PR662/Tutorials/Tutorial_1_configuring_settings/index.html b/previews/PR662/Tutorials/Tutorial_1_configuring_settings/index.html index 04d10601fa..d15dbcbeb7 100644 --- a/previews/PR662/Tutorials/Tutorial_1_configuring_settings/index.html +++ b/previews/PR662/Tutorials/Tutorial_1_configuring_settings/index.html @@ -1,5 +1,5 @@ -Tutorial 1: Configuring Settings · GenX

Tutorial 1: Configuring Settings

Interactive Notebook of the tutorial

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.

What settings are there?

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

Tutorial 1: Configuring Settings

Interactive Notebook of the tutorial

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.

What settings are there?

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
RowResourceZoneStartCapRetCapNewCapEndCapCapacityConstraintDualStartEnergyCapRetEnergyCapNewEnergyCapEndEnergyCapStartChargeCapRetChargeCapNewChargeCapEndChargeCap
String31String3Float64Float64Float64Float64String3Float64Float64Float64Float64Float64Float64Float64Float64
1MA_natural_gas_combined_cycle10.00.07394.757394.750.00.00.00.00.00.00.00.00.0
2CT_natural_gas_combined_cycle20.00.02305.822305.820.00.00.00.00.00.00.00.00.0
3ME_natural_gas_combined_cycle30.00.0716.666716.6660.00.00.00.00.00.00.00.00.0
4MA_solar_pv10.00.021186.521186.50.00.00.00.00.00.00.00.00.0
5CT_onshore_wind20.00.011905.511905.50.00.00.00.00.00.00.00.00.0
6CT_solar_pv20.00.016578.816578.80.00.00.00.00.00.00.00.00.0
7ME_onshore_wind30.00.012767.312767.30.00.00.00.00.00.00.00.00.0
8MA_battery10.00.03362.33362.30.00.00.019427.719427.70.00.00.00.0
9CT_battery20.00.05318.365318.360.00.00.027274.127274.10.00.00.00.0
10ME_battery30.00.02095.32095.30.00.00.07096.277096.270.00.00.00.0
11Totaln/a0.00.083631.383631.3n/a0.00.053798.153798.10.00.00.00.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:

YAML.write_file("example_systems/1_three_zones/settings/genx_settings.yml", genx_settings_TZ)
+results = CSV.read(open("example_systems/1_three_zones/Results/capacity.csv"),DataFrame)
11×15 DataFrame
RowResourceZoneStartCapRetCapNewCapEndCapCapacityConstraintDualStartEnergyCapRetEnergyCapNewEnergyCapEndEnergyCapStartChargeCapRetChargeCapNewChargeCapEndChargeCap
String31String3Float64Float64Float64Float64String3Float64Float64Float64Float64Float64Float64Float64Float64
1MA_natural_gas_combined_cycle10.00.07394.757394.750.00.00.00.00.00.00.00.00.0
2CT_natural_gas_combined_cycle20.00.02305.822305.820.00.00.00.00.00.00.00.00.0
3ME_natural_gas_combined_cycle30.00.0716.666716.6660.00.00.00.00.00.00.00.00.0
4MA_solar_pv10.00.021186.521186.50.00.00.00.00.00.00.00.00.0
5CT_onshore_wind20.00.011905.511905.50.00.00.00.00.00.00.00.00.0
6CT_solar_pv20.00.016578.816578.80.00.00.00.00.00.00.00.00.0
7ME_onshore_wind30.00.012767.312767.30.00.00.00.00.00.00.00.00.0
8MA_battery10.00.03362.33362.30.00.00.019427.719427.70.00.00.00.0
9CT_battery20.00.05318.365318.360.00.00.027274.127274.10.00.00.00.0
10ME_battery30.00.02095.32095.30.00.00.07096.277096.270.00.00.00.0
11Totaln/a0.00.083631.383631.3n/a0.00.053798.153798.10.00.00.00.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:

YAML.write_file("example_systems/1_three_zones/settings/genx_settings.yml", genx_settings_TZ)
diff --git a/previews/PR662/Tutorials/Tutorial_2_network_visualization/index.html b/previews/PR662/Tutorials/Tutorial_2_network_visualization/index.html index 41b2ca1911..0646b24660 100644 --- a/previews/PR662/Tutorials/Tutorial_2_network_visualization/index.html +++ b/previews/PR662/Tutorials/Tutorial_2_network_visualization/index.html @@ -1,3 +1,3 @@ -Tutorial 2: Network Visualization · GenX

Tutorial 2: Network Visualization

Interactive Notebook of the tutorial

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:

network = CSV.read("example_systems/1_three_zones/system/Network.csv",DataFrame,missingstring="NA")
3×14 DataFrame
RowColumn1Network_zonesNetwork_LinesStart_ZoneEnd_ZoneLine_Max_Flow_MWtransmission_path_namedistance_mileLine_Loss_PercentageLine_Max_Reinforcement_MWLine_Reinforcement_Cost_per_MWyrDerateCapRes_1CapRes_1CapRes_Excl_1
String3String3String3String3String3String7String15String15String15String7String7String7String3Int64?
1MAz11122950MA_to_CT123.05840.0123058372950120600.9500
2CTz22132000MA_to_ME196.53850.0196538472000192610.9500
3MEz3missing

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:

+Tutorial 2: Network Visualization · GenX.jl

Tutorial 2: Network Visualization

Interactive Notebook of the tutorial

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:

network = CSV.read("example_systems/1_three_zones/system/Network.csv",DataFrame,missingstring="NA")
3×14 DataFrame
RowColumn1Network_zonesNetwork_LinesStart_ZoneEnd_ZoneLine_Max_Flow_MWtransmission_path_namedistance_mileLine_Loss_PercentageLine_Max_Reinforcement_MWLine_Reinforcement_Cost_per_MWyrDerateCapRes_1CapRes_1CapRes_Excl_1
String3String3String3String3String3String7String15String15String15String7String7String7String3Int64?
1MAz11122950MA_to_CT123.05840.0123058372950120600.9500
2CTz22132000MA_to_ME196.53850.0196538472000192610.9500
3MEz3missing

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:

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

Tutorial 3: K-Means and Time Domain Reduction

Interactive Notebook of the tutorial

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.

Table of Contents

Time Domain Reduction

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
+Tutorial 3: K-Means and Time Domain Reduction · GenX.jl

Tutorial 3: K-Means and Time Domain Reduction

Interactive Notebook of the tutorial

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.

Table of Contents

Time Domain Reduction

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.

time_domain_reduction_settings["MinPeriods"] = 8;
-time_domain_reduction_settings["MaxPeriods"] = 11;
time_domain_reduction_settings
rm(joinpath(case,"TDR_results", recursive=true))

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

+time_domain_reduction_settings["MaxPeriods"] = 11;
time_domain_reduction_settings
rm(joinpath(case,"TDR_results", recursive=true))

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

diff --git a/previews/PR662/Tutorials/Tutorial_4_model_generation/index.html b/previews/PR662/Tutorials/Tutorial_4_model_generation/index.html index a9cb0b0f81..b8e29e68f7 100644 --- a/previews/PR662/Tutorials/Tutorial_4_model_generation/index.html +++ b/previews/PR662/Tutorials/Tutorial_4_model_generation/index.html @@ -1,5 +1,5 @@ -Tutorial 4: Model Generation · GenX

Tutorial 4: Model Generation

Interactive Notebook of the tutorial

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.

Table of Contents

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

Tutorial 4: Model Generation

Interactive Notebook of the tutorial

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.

Table of Contents

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.

\[\begin{aligned} & \min 10 x + 15 y &\text{Objective function (cost)}\\ & \text{s.t.} & \\ @@ -324,4 +324,4 @@ cPowerBalance[1845,1] : vP[2,1845] + vP[3,1845] + vP[4,1845] + vNSE[1,1845,1] - vCHARGE[4,1845] = 15.392 cPowerBalance[1846,1] : vP[2,1846] + vP[3,1846] + vP[4,1846] + vNSE[1,1846,1] - vCHARGE[4,1846] = 14.663 cPowerBalance[1847,1] : vP[2,1847] + vP[3,1847] + vP[4,1847] + vNSE[1,1847,1] - vCHARGE[4,1847] = 13.62 - cPowerBalance[1848,1] : vP[2,1848] + vP[3,1848] + vP[4,1848] + vNSE[1,1848,1] - vCHARGE[4,1848] = 12.388

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.

+ cPowerBalance[1848,1] : vP[2,1848] + vP[3,1848] + vP[4,1848] + vNSE[1,1848,1] - vCHARGE[4,1848] = 12.388

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.

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

Tutorial 5: Solving the Model

Interactive Notebook of the tutorial

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.

Table of Contents

A Simple Example

From Tutorial 4, we have the model:

\[\begin{aligned} +Tutorial 5: Solving the Model · GenX.jl

Tutorial 5: Solving the Model

Interactive Notebook of the tutorial

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.

Table of Contents

A Simple Example

From Tutorial 4, we have the model:

\[\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.

+ 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.

diff --git a/previews/PR662/Tutorials/Tutorial_6_solver_settings/index.html b/previews/PR662/Tutorials/Tutorial_6_solver_settings/index.html index d7477f4d0d..04469009cb 100644 --- a/previews/PR662/Tutorials/Tutorial_6_solver_settings/index.html +++ b/previews/PR662/Tutorials/Tutorial_6_solver_settings/index.html @@ -1,5 +1,5 @@ -Tutorial 6: Post Processing · GenX

Tutorial 6: Solver Settings

Interactive Notebook of the tutorial

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.

Table of Contents

using YAML
+Tutorial 6: Post Processing · GenX.jl
+ 140.74829025
diff --git a/previews/PR662/Tutorials/Tutorials_intro/index.html b/previews/PR662/Tutorials/Tutorials_intro/index.html index db5a38246f..4c0208c23b 100644 --- a/previews/PR662/Tutorials/Tutorials_intro/index.html +++ b/previews/PR662/Tutorials/Tutorials_intro/index.html @@ -1,2 +1,2 @@ -Tutorials Overview · GenX
+Tutorials Overview · GenX.jl
diff --git a/previews/PR662/User_Guide/TDR_input/index.html b/previews/PR662/User_Guide/TDR_input/index.html index 977675c630..c1bbe75c92 100644 --- a/previews/PR662/User_Guide/TDR_input/index.html +++ b/previews/PR662/User_Guide/TDR_input/index.html @@ -1,2 +1,2 @@ -Time-domain Reduction Inputs · GenX

Time-domain reduction

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

KeyDescription
Timesteps_per_periodThe number of timesteps (e.g., hours) in each representative period (i.e. 168 for weeks, 24 for days, 72 for three-day periods, etc).
UseExtremePeriods1 = 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.
ExtremePeriodsIf 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).
ClusterMethodEither kmeans or kmedoids, the method used to cluster periods and determine each time step's representative period.
ScalingMethodEither N or S, the decision to normalize ([0,1]) or standardize (mean 0, variance 1) the input data prior to clustering.
MinPeriodsThe 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.
MaxPeriodsThe maximum number of representative periods - both clustered and extreme - that may be used to represent the input data.
IterativelyAddPeriods1 = 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.
ThresholdIterative 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).
IterateMethodEither ‘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.
nRepsDefault = 200, the number of kmeans/kmedoids repetitions at the same setting.
DemandWeightDefault = 1, a multiplier on demand columns to optionally prioritize better fits for demand profiles over resource capacity factor or fuel price profiles.
WeightTotalDefault = 8760, the sum to which the relative weights of representative periods will be scaled.
ClusterFuelPricesEither 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.
+Time-domain Reduction Inputs · GenX.jl

Time-domain reduction

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

KeyDescription
Timesteps_per_periodThe number of timesteps (e.g., hours) in each representative period (i.e. 168 for weeks, 24 for days, 72 for three-day periods, etc).
UseExtremePeriods1 = 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.
ExtremePeriodsIf 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).
ClusterMethodEither kmeans or kmedoids, the method used to cluster periods and determine each time step's representative period.
ScalingMethodEither N or S, the decision to normalize ([0,1]) or standardize (mean 0, variance 1) the input data prior to clustering.
MinPeriodsThe 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.
MaxPeriodsThe maximum number of representative periods - both clustered and extreme - that may be used to represent the input data.
IterativelyAddPeriods1 = 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.
ThresholdIterative 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).
IterateMethodEither ‘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.
nRepsDefault = 200, the number of kmeans/kmedoids repetitions at the same setting.
DemandWeightDefault = 1, a multiplier on demand columns to optionally prioritize better fits for demand profiles over resource capacity factor or fuel price profiles.
WeightTotalDefault = 8760, the sum to which the relative weights of representative periods will be scaled.
ClusterFuelPricesEither 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.
diff --git a/previews/PR662/User_Guide/generate_alternatives/index.html b/previews/PR662/User_Guide/generate_alternatives/index.html index 49b25cd2b0..3862fff1bd 100644 --- a/previews/PR662/User_Guide/generate_alternatives/index.html +++ b/previews/PR662/User_Guide/generate_alternatives/index.html @@ -1,2 +1,2 @@ -MGA package · GenX

Running Modeling to Generate Alternatives with GenX

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:

  1. Add a Resource_Type column in all the resource .csv files denoting the type of each technology.
  2. Add a MGA column in all the resource .csv files denoting the availability of the technology.
  3. Set the ModelingToGenerateAlternatives flag in the GenX_Settings.yml file to 1.
  4. Set the ModelingtoGenerateAlternativeSlack flag in the GenX_Settings.yml file to the desirable level of slack.
  5. 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.

+MGA package · GenX.jl

Running Modeling to Generate Alternatives with GenX

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:

  1. Add a Resource_Type column in all the resource .csv files denoting the type of each technology.
  2. Add a MGA column in all the resource .csv files denoting the availability of the technology.
  3. Set the ModelingToGenerateAlternatives flag in the GenX_Settings.yml file to 1.
  4. Set the ModelingtoGenerateAlternativeSlack flag in the GenX_Settings.yml file to the desirable level of slack.
  5. 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.

diff --git a/previews/PR662/User_Guide/methodofmorris_input/index.html b/previews/PR662/User_Guide/methodofmorris_input/index.html index f73f590255..88ba9746f2 100644 --- a/previews/PR662/User_Guide/methodofmorris_input/index.html +++ b/previews/PR662/User_Guide/methodofmorris_input/index.html @@ -1,2 +1,2 @@ -Method of Morris Inputs · GenX

Method_of_morris_range.csv (Example)

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 NameDescription
ResourceThis column contains unique names of resources available to the model. Resources can include generators, storage, and flexible or time shiftable demand.
ZoneInteger representing zone number where the resource is located.
Lower_boundPercentage lower deviation from the nominal value
Upper_boundPercentage upper deviation from the nominal value
ParameterColumn from the Generators_data.csv file containing uncertain parameters
GroupGroup 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_stepsNumber of steps between upper and lower bound
total_num_trajectoryTotal number of trakectories through the design matrix
num_trajectorySelected number of trajectories throigh the design matrix
len_design_matLength of the design matrix
policyName of the policy

Notes:

  1. Upper and lower bounds are specified in terms of percentage deviation from the nominal value.
  2. 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.
  3. P_steps should at least be = 1%, i.e., Upper_bound – Lower_bound < p_steps
  4. P_steps for parameters in one group must be identical
  5. Total_num_trajectory should be around 3 to 4 times the total number of uncertain parameters
  6. num_trajectory should be approximately equal to the total number of uncertain parameters
  7. len_design_mat should be 1.5 to 2 times the total number of uncertain parameters
  8. Higher number of num_trajectory and len_design_mat would lead to higher accuracy
  9. 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.
+Method of Morris Inputs · GenX.jl

Method_of_morris_range.csv (Example)

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 NameDescription
ResourceThis column contains unique names of resources available to the model. Resources can include generators, storage, and flexible or time shiftable demand.
ZoneInteger representing zone number where the resource is located.
Lower_boundPercentage lower deviation from the nominal value
Upper_boundPercentage upper deviation from the nominal value
ParameterColumn from the Generators_data.csv file containing uncertain parameters
GroupGroup 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_stepsNumber of steps between upper and lower bound
total_num_trajectoryTotal number of trakectories through the design matrix
num_trajectorySelected number of trajectories throigh the design matrix
len_design_matLength of the design matrix
policyName of the policy

Notes:

  1. Upper and lower bounds are specified in terms of percentage deviation from the nominal value.
  2. 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.
  3. P_steps should at least be = 1%, i.e., Upper_bound – Lower_bound < p_steps
  4. P_steps for parameters in one group must be identical
  5. Total_num_trajectory should be around 3 to 4 times the total number of uncertain parameters
  6. num_trajectory should be approximately equal to the total number of uncertain parameters
  7. len_design_mat should be 1.5 to 2 times the total number of uncertain parameters
  8. Higher number of num_trajectory and len_design_mat would lead to higher accuracy
  9. 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.
diff --git a/previews/PR662/User_Guide/model_configuration/index.html b/previews/PR662/User_Guide/model_configuration/index.html index 42fa9b033d..5b4962fcc2 100644 --- a/previews/PR662/User_Guide/model_configuration/index.html +++ b/previews/PR662/User_Guide/model_configuration/index.html @@ -1,2 +1,2 @@ -Model Configuration · GenX

Model settings parameters

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.

ParameterDescription
UCommitSelect technical resolution of of modeling thermal generators.
0 = no unit commitment.
1 = unit commitment with integer clustering.
2 = unit commitment with linearized clustering.
OperationalReservesFlag for modeling operational reserves .
0 = No operational reserves considered.
1 = Consider regulation (primary) and spinning (secondary) reserves.
StorageLossesFlag to account for storage related losses.
0 = VRE and CO2 constraints DO NOT account for energy lost.
1 = constraints account for energy lost.
TimeDomainReduction1 = 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.
TimeDomainReductionFolderName of the folder insie the current working directory where time domain reduced input data is stored.
VirtualChargeDischargeCostHypothetical cost of charging and discharging storage resources (in /MWh).

2. Solution strategy

ParameterDescription
ParameterScaleFlag 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.
MultiStageModel multiple planning stages
1 = Model multiple planning stages as specified in multi_stage_settings.yml
0 = Model single planning stage
ModelingToGenerateAlternativesModeling to Generate Alternative Algorithm. For details, see here
1 = Use the algorithm.
0 = Do not use the algorithm.
ModelingtoGenerateAlternativeSlackvalue 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.
MethodofMorrisMethod of Morris algorithm
1 = Use the algorithm.
0 = Do not use the algorithm.
ParameterDescription
CO2CapFlag for specifying the type of CO2 emission limit constraint.
0 = no CO2 emission limit
1 = mass-based emission limit constraint
2 = demand + rate-based emission limit constraint
3 = generation + rate-based emission limit constraint
EnergyShareRequirementFlag for specifying regional renewable portfolio standard (RPS) and clean energy standard policy (CES) related constraints.
Default = 0 (No RPS or CES constraints).
1 = activate energy share requirement related constraints.
CapacityReserveMarginFlag for Capacity Reserve Margin constraints.
Default = 0 (No Capacity Reserve Margin constraints)
1 = activate Capacity Reserve Margin related constraints
MinCapReqMinimum technology carve out requirement constraints.
1 = if one or more minimum technology capacity constraints are specified
0 = otherwise
MaxCapReqMaximum system-wide technology capacity limit constraints.
1 = if one or more maximum technology capacity constraints are specified
0 = otherwise
ParameterDescription
NetworkExpansionFlag for activating or deactivating inter-regional transmission expansion.
1 = active
0 = modeling single zone or for multi-zone problems in which inter regional transmission expansion is not allowed.
Trans_Loss_SegmentsNumber of segments to use in piece-wise linear approximation of losses.
1: linear
>=2: piece-wise quadratic

5. Outputs

ParameterDescription
PrintModelFlag 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
WriteShadowPricesGet 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.
WriteOutputsFlag 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.

+Model Configuration · GenX.jl

Model settings parameters

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.

ParameterDescription
UCommitSelect technical resolution of of modeling thermal generators.
0 = no unit commitment.
1 = unit commitment with integer clustering.
2 = unit commitment with linearized clustering.
OperationalReservesFlag for modeling operational reserves .
0 = No operational reserves considered.
1 = Consider regulation (primary) and spinning (secondary) reserves.
StorageLossesFlag to account for storage related losses.
0 = VRE and CO2 constraints DO NOT account for energy lost.
1 = constraints account for energy lost.
TimeDomainReduction1 = 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.
TimeDomainReductionFolderName of the folder insie the current working directory where time domain reduced input data is stored.
VirtualChargeDischargeCostHypothetical cost of charging and discharging storage resources (in /MWh).

2. Solution strategy

ParameterDescription
ParameterScaleFlag 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.
MultiStageModel multiple planning stages
1 = Model multiple planning stages as specified in multi_stage_settings.yml
0 = Model single planning stage
ModelingToGenerateAlternativesModeling to Generate Alternative Algorithm. For details, see here
1 = Use the algorithm.
0 = Do not use the algorithm.
ModelingtoGenerateAlternativeSlackvalue 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.
MethodofMorrisMethod of Morris algorithm
1 = Use the algorithm.
0 = Do not use the algorithm.
ParameterDescription
CO2CapFlag for specifying the type of CO2 emission limit constraint.
0 = no CO2 emission limit
1 = mass-based emission limit constraint
2 = demand + rate-based emission limit constraint
3 = generation + rate-based emission limit constraint
EnergyShareRequirementFlag for specifying regional renewable portfolio standard (RPS) and clean energy standard policy (CES) related constraints.
Default = 0 (No RPS or CES constraints).
1 = activate energy share requirement related constraints.
CapacityReserveMarginFlag for Capacity Reserve Margin constraints.
Default = 0 (No Capacity Reserve Margin constraints)
1 = activate Capacity Reserve Margin related constraints
MinCapReqMinimum technology carve out requirement constraints.
1 = if one or more minimum technology capacity constraints are specified
0 = otherwise
MaxCapReqMaximum system-wide technology capacity limit constraints.
1 = if one or more maximum technology capacity constraints are specified
0 = otherwise
ParameterDescription
NetworkExpansionFlag for activating or deactivating inter-regional transmission expansion.
1 = active
0 = modeling single zone or for multi-zone problems in which inter regional transmission expansion is not allowed.
Trans_Loss_SegmentsNumber of segments to use in piece-wise linear approximation of losses.
1: linear
>=2: piece-wise quadratic

5. Outputs

ParameterDescription
PrintModelFlag 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
WriteShadowPricesGet 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.
WriteOutputsFlag 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.

diff --git a/previews/PR662/User_Guide/model_input/index.html b/previews/PR662/User_Guide/model_input/index.html index c15a8d9ada..1566505d8a 100644 --- a/previews/PR662/User_Guide/model_input/index.html +++ b/previews/PR662/User_Guide/model_input/index.html @@ -1,6 +1,6 @@ -Model Inputs · GenX

GenX Inputs

All input files are in CSV format. Running the GenX model requires a minimum of five mandatory input files:

  1. Fuels_data.csv: specify fuel type, CO2 emissions intensity, and time-series of fuel prices.
  2. Network.csv: specify network topology, transmission fixed costs, capacity and loss parameters.
  3. 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.
  4. Generators_variability.csv: specify time-series of capacity factor/availability for each resource.
  5. 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:

  1. Operational_reserves.csv: specify operational reserve requirements as a function of demand and renewables generation and penalty for not meeting these requirements.
  2. Energy_share_requirement.csv: specify regional renewable portfolio standard and clean energy standard style policies requiring minimum energy generation from qualifying resources.
  3. CO2_cap.csv: specify regional CO2 emission limits.
  4. Capacity_reserve_margin.csv: specify regional capacity reserve margin requirements.
  5. Minimum_capacity_requirement.csv: specify regional minimum technology capacity deployment requirements.
  6. Vre_and_stor_data.csv: specify cost and performance data for co-located VRE and storage resources.
  7. 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).
  8. 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).
Note

Names of the input files are case sensitive.

1 Mandatory input data

1.1 Fuels_data.csv

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.

1.2 Network.csv

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.

Table 3: Structure of the Network.csv file

Column NameDescription
Settings-specific Columns
Multiple zone model
Network_LinesNumerical index for each network line. The length of this column is counted but the actual values are not used.
z* (Network map) OR StartZone, EndZoneSee below
Line_Max_Flow_MWExisting capacity of the inter-regional transmission line.
NetworkExpansion = 1
Line_Max_Reinforcement_MWMaximum allowable capacity addition to the existing transmission line.
Line_Reinforcement_Cost_per_MWyrCost of adding new capacity to the inter-regional transmission line.
Trans_Loss_Segments = 1
Line_Loss_Percentagefractional transmission loss for each transmission line
Trans_Loss_Segments > 1
OhmsLine resistance in Ohms (used to calculate I^2R losses)
kVLine 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_PeriodCapital recovery period (in years) used for determining overnight capital costs from annualized investment costs for network transmission line expansion.
Line_Max_Flow_Possible_MWMaximum 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:

Network_Lines, Start_Zone, End_Zone,
+Model Inputs · GenX.jl

GenX Inputs

All input files are in CSV format. Running the GenX model requires a minimum of five mandatory input files:

  1. Fuels_data.csv: specify fuel type, CO2 emissions intensity, and time-series of fuel prices.
  2. Network.csv: specify network topology, transmission fixed costs, capacity and loss parameters.
  3. 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.
  4. Generators_variability.csv: specify time-series of capacity factor/availability for each resource.
  5. 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:

  1. Operational_reserves.csv: specify operational reserve requirements as a function of demand and renewables generation and penalty for not meeting these requirements.
  2. Energy_share_requirement.csv: specify regional renewable portfolio standard and clean energy standard style policies requiring minimum energy generation from qualifying resources.
  3. CO2_cap.csv: specify regional CO2 emission limits.
  4. Capacity_reserve_margin.csv: specify regional capacity reserve margin requirements.
  5. Minimum_capacity_requirement.csv: specify regional minimum technology capacity deployment requirements.
  6. Vre_and_stor_data.csv: specify cost and performance data for co-located VRE and storage resources.
  7. 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).
  8. 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).
Note

Names of the input files are case sensitive.

1 Mandatory input data

1.1 Fuels_data.csv

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.

1.2 Network.csv

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.

Table 3: Structure of the Network.csv file

Column NameDescription
Settings-specific Columns
Multiple zone model
Network_LinesNumerical index for each network line. The length of this column is counted but the actual values are not used.
z* (Network map) OR StartZone, EndZoneSee below
Line_Max_Flow_MWExisting capacity of the inter-regional transmission line.
NetworkExpansion = 1
Line_Max_Reinforcement_MWMaximum allowable capacity addition to the existing transmission line.
Line_Reinforcement_Cost_per_MWyrCost of adding new capacity to the inter-regional transmission line.
Trans_Loss_Segments = 1
Line_Loss_Percentagefractional transmission loss for each transmission line
Trans_Loss_Segments > 1
OhmsLine resistance in Ohms (used to calculate I^2R losses)
kVLine 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_PeriodCapital recovery period (in years) used for determining overnight capital costs from annualized investment costs for network transmission line expansion.
Line_Max_Flow_Possible_MWMaximum 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:

Network_Lines, Start_Zone, End_Zone,
             1,          1,        2,
             2,          1,        3,

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:

Network_Lines, z1, z2, z3,
             1,  1, -1,  0,
-            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.

1.3 Demand_data.csv (Load_data.csv)

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).

Table 4: Structure of the Demand_data.csv file

Column NameDescription
Mandatory Columns
VollValue of lost load (also referred to as non-served energy) in /MWh.
Demand_SegmentNumber 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_MWCost 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_CurtailmentMaximum 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_IndexIndex 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_PeriodsNumber 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_PeriodNumber 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_WeightsNumber 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).

1.4 Resources input files

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:

  1. thermal generators, specified in the Thermal.csv file,
  2. variable renewable energy resources (VRE), specified in the VRE.csv file,
  3. reservoir hydro resources, specified in the Hydro.csv file,
  4. storage resources, specified in the Storage.csv file,
  5. flexible demand resources, specified in the Flex_demand.csv file,
  6. must-run resources, specified in the Must_run.csv file,
  7. electrolyzers, specified in the Electrolyzer.csv file, and
  8. 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.

Table 5a: Mandatory columns in all resource .csv file

Column NameDescription
ResourceThis column contains unique names of resources available to the model. Resources can include generators, storage, and flexible or time shiftable demand.
ZoneInteger 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_MWThe 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_MWyrAnnualized 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_MWyrFixed 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_MWhVariable 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_MWhHeat 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.
FuelFuel needed for a generator. The names should match with the ones in the Fuels_data.csv.
Required for writing outputs
regionName of the model region
clusterNumber 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_IdUnique identifier to group retrofittable source technologies with retrofit options inside the same zone.
Retrofit_Efficiency[0,1], Efficiency of the retrofit technology.
Table 5b: Settings-specific columns in all resource .csv file

Column NameDescription
ModelingToGenerateAlternatives = 1
MGAEligibility 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_TypeFor 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_YearsLength 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_CadenceCadence 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_TonCost associated with CCS disposal (/tCO2), including pipeline, injection and storage costs of CCS-equipped generators.
Table 6a: Additional columns in the Thermal.csv file
Column NameDescription
Model{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_hThe fuel usage (MMBTU/h) for the first PWFU segemnt (y-intercept) at zero load.
PWFU_Heat_Rate_MMBTU_per_MWh_*iThe slope of fuel usage function of the segment i.
PWFU_Load_Point_MW_*iThe 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_FuelsNumber 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.
Fuel1Frist fuel needed for a mulit-fuel generator (MULTIFUELS = 1). The names should match with the ones in the `Fuelsdata.csv`.
Fuel2Second fuel needed for a mulit-fuel generator (MULTIFUELS = 1). The names should match with the ones in the `Fuelsdata.csv`.
Heat1_Rate_MMBTU_per_MWhHeat rate of a multi-fuel generator (MULTI_FUELS = 1) for Fuel1.
Heat2_Rate_MMBTU_per_MWhHeat rate of a multi-fuel generator (MULTI_FUELS = 1) for Fuel2.
Fuel1_Min_Cofire_LevelThe 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\StartThe 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_LevelThe 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\StartThe 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_LevelThe 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\StartThe 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_LevelThe 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\StartThe maximum blendng level of 'Fuel2' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the start-up process.
Table 6b: Settings-specific columns in the Thermal.csv file

Column NameDescription
UCommit >= 1The following settings apply only to thermal plants with unit commitment constraints
Up_TimeMinimum amount of time a resource has to stay in the committed state.
Down_TimeMinimum amount of time a resource has to remain in the shutdown state.
Start_Cost_per_MWCost 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_MWStartup fuel use per MW of nameplate capacity of each generator (MMBtu/MW per start).
OperationalReserves = 1
Reg_CostCost of providing regulation reserves (/MW per time step/hour).
Rsv_CostCost 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.
Table 7a: Additional columns in the Vre.csv file

Column NameDescription
Num_VRE_binsNumber 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.
Table 6b: Settings-specific columns in the Vre.csv file

Column NameDescription
OperationalReserves = 1
Reg_CostCost of providing regulation reserves (/MW per time step/hour).
Rsv_CostCost 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.
Table 7a: Additional columns in the Hydro.csv file

Column NameDescription
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.
Hydro_Energy_to_Power_RatioThe 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.
LDS = 0: Not part of set (default)
LDS = 1: Long duration storage resources
Table 7b: Settings-specific columns in the Hydro.csv file

Column NameDescription
OperationalReserves = 1
Reg_CostCost of providing regulation reserves (/MW per time step/hour).
Rsv_CostCost 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.
Table 8a: Additional columns in the Storage.csv file

Column NameDescription
Model{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_DurationSpecifies the minimum ratio of installed energy to discharged power capacity that can be installed (hours).
Max_DurationSpecifies the maximum ratio of installed energy to discharged power capacity that can be installed (hours).
Existing technology capacity
Existing_Cap_MWhThe existing capacity of storage in MWh where Model = 1 or Model = 2.
Existing_Charge_Cap_MWThe 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_MWhyrAnnualized investment cost of the energy capacity for a storage technology (/MW/year), applicable to either Model = 1 or Model = 2.
Inv_Cost_Charge_per_MWyrAnnualized capacity investment cost for the charging portion of a storage technology with Model = 2 (/MW/year).
Fixed_OM_Cost_per_MWhyrFixed operations and maintenance cost of the energy component of a storage technology (/MWh/year).
Fixed_OM_Cost_Charge_per_MWyrFixed operations and maintenance cost of the charging component of a storage technology of type Model = 2.
Var_OM_Cost_per_MWhInVariable operations and maintenance cost of the charging aspect of a storage technology with Model = 2. Otherwise 0 (/MWh).
Table 8b: Settings-specific columns in the Storage.csv file

Column NameDescription
OperationalReserves = 1
Reg_CostCost of providing regulation reserves (/MW per time step/hour).
Rsv_CostCost 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.
Table 9: Additional columns in the Flex_demand.csv file

Column NameDescription
Max_Flexible_Demand_DelayMaximum number of hours that demand can be deferred or delayed (hours).
Max_Flexible_Demand_AdvanceMaximum 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_MWhInVariable operations and maintenance costs associated with flexible demand deferral. Otherwise 0 (/MWh).
Table 10: Additional columns in the Electrolyzer.csv file

Column NameDescription
HydrogenMWhPer_TonneElectrolyzer efficiency in megawatt-hours (MWh) of electricity per metric tonne of hydrogen produced (MWh/t)
ElectrolyzerMinktMinimum annual quantity of hydrogen that must be produced by electrolyzer in kilotonnes (kt)
HydrogenPricePer_TonnePrice (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.

Table 11a: Additional columns in the Vre_stor.csv file

Column NameDescription
Technology type flags
SOLAR{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_MWThe existing AC grid connection capacity in MW.
Existing_Cap_MWhThe existing capacity of storage in MWh.
Existing_Cap_Inverter_MWThe existing capacity of co-located VRE-STOR resource's inverter in MW (AC).
Existing_Cap_Solar_MWThe existing capacity of co-located VRE-STOR resource's solar PV in MW (DC).
Existing_Cap_Wind_MWThe existing capacity of co-located VRE-STOR resource's wind in MW (AC).
Existing_Cap_Discharge_DC_MWThe 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_MWThe 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_MWThe 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_MWThe 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_MWyrAnnualized capacity investment cost of the grid connection (/MW/year).
Inv_Cost_per_MWhyrAnnualized investment cost of the energy capacity for the co-located storage resource (/MW/year)
Fixed_OM_Cost_per_MWyrFixed operations and maintenance cost of the grid connection (/MW/year).
Fixed_OM_Cost_per_MWhyrFixed operations and maintenance cost of the energy component of the co-located storage resource. (/MWh/year).
Inv_Cost_Inverter_per_MWyrAnnualized capacity investment cost of the inverter component (/MW-AC/year).
Inv_Cost_Solar_per_MWyrAnnualized capacity investment cost of the solar PV component (/MW-DC/year).
Inv_Cost_Wind_per_MWyrAnnualized capacity investment cost of the wind component (/MW-AC/year).
Inv_Cost_Discharge_DC_per_MWyrAnnualized capacity investment cost for the discharging portion of a storage technology with STOR_DC_DISCHARGE = 2 (/MW-DC/year).
Inv_Cost_Charge_DC_per_MWyrAnnualized capacity investment cost for the charging portion of a storage technology with STOR_DC_CHARGE = 2 (/MW-DC/year).
Inv_Cost_Discharge_AC_per_MWyrAnnualized capacity investment cost for the discharging portion of a storage technology with STOR_AC_DISCHARGE = 2 (/MW-AC/year).
Inv_Cost_Charge_AC_per_MWyrAnnualized capacity investment cost for the charging portion of a storage technology with STOR_AC_CHARGE = 2 (/MW-AC/year).
Fixed_OM_Inverter_Cost_per_MWyrFixed operations and maintenance cost of the inverter component (/MW-AC/year).
Fixed_OM_Solar_Cost_per_MWyrFixed operations and maintenance cost of the solar PV component (/MW-DC/year).
Fixed_OM_Wind_Cost_per_MWyrFixed operations and maintenance cost of the wind component (/MW-AC/year).
Fixed_OM_Cost_Discharge_DC_per_MWyrFixed 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_MWyrFixed 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_MWyrFixed 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_MWyrFixed 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_SolarVariable operations and maintenance cost of the solar PV component (multiplied by the inverter efficiency for AC terms) (/MWh).
Var_OM_Cost_per_MWh_WindVariable operations and maintenance cost of the wind component (/MWh).
Var_OM_Cost_per_MWh_Discharge_DCVariable 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_DCVariable 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_ACVariable operations and maintenance cost of the discharging component of a storage technology with STOR_AC_DISCHARGE = 2 (/MWh).
Var_OM_Cost_per_MWh_Charge_ACVariable 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_ACThe power to energy conversion for the storage component for AC discharging/charging of symmetric storage resources.
Power_to_Energy_DCThe 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).
Table 11b: Settings-specific columns in the Vre_stor.csv file

Column NameDescription
OperationalReserves = 1
Reg_CostCost of providing regulation reserves (/MW per time step/hour).
Rsv_CostCost 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.

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:

  1. Resource_energy_share_requirement.csv
  2. Resource_minimum_capacity_requirement.csv
  3. Resource_maximum_capacity_requirement.csv
  4. 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.

Table 12: Energy share requirement policy parameters

Column NameDescription
ResourceResource name corresponding to a resource in one of the resource data files described above.
ESR_*Flag to indicate which resources are considered for the Energy Share Requirement constraint.
1- included
0- excluded
co-located VRE-STOR resources only
ESRVreStor_*Flag to indicate which resources are considered for the Energy Share Requirement constraint.
1- included
0- excluded

This policy is applied when if MinCapReq = 1 in the settings file. * corresponds to the ith row of the file Minimum_capacity_requirement.csv.

Table 13: Minimum capacity requirement policy parameters

Column NameDescription
ResourceResource 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.

Table 14: Maximum capacity requirement policy parameters

Column NameDescription
ResourceResource 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.

Table 15: Capacity reserve margin policy parameters

Column NameDescription
ResourceResource name corresponding to a resource in one of the resource data files described above.
EligibleCapRes_*Fraction of the resource capacity eligible for contributing to the capacity reserve margin constraint (e.g. derate factor).

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:

  1. 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.

Table 16: Multistage parameters
Warning

This file is mandatory if MultiStage = 1 in the settings file.


Column NameDescription
ResourceResource name corresponding to a resource in one of the resource data files described above.
Capital_Recovery_PeriodCapital 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.
LifetimeLifetime (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_MWMinimum 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_MWMinimum 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_MWMinimum 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_DCCapital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the inverter component.
Capital_Recovery_Period_SolarCapital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the solar PV component.
Capital_Recovery_Period_WindCapital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the wind component.
Capital_Recovery_PeriodDischargeDCCapital 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_PeriodChargeDCCapital 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_PeriodDischargeACCapital 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_PeriodChargeACCapital 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_MWMinimum 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_MWMinimum 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_MWMinimum 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\MWMinimum 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\MWMinimum 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\MWMinimum 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\MWMinimum 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_DCThe line-specific weighted average cost of capital for the inverter component.
WACC_SolarThe line-specific weighted average cost of capital for the solar PV component.
WACC_WindThe line-specific weighted average cost of capital for the wind component.
WACC_Discharge_DCThe line-specific weighted average cost of capital for the discharging DC storage component with STOR_DC_DISCHARGE = 2.
WACC_Charge_DCThe line-specific weighted average cost of capital for the charging DC storage component with STOR_DC_CHARGE = 2.
WACC_Discharge_ACThe line-specific weighted average cost of capital for the discharging AC storage component with STOR_AC_DISCHARGE = 2.
WACC_Charge_ACThe line-specific weighted average cost of capital for the charging AC storage component with STOR_AC_CHARGE = 2.

1.5 Generator_variability.csv

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. |

1.6 Vre_and_stor_solar_variability.csv

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.

1.7 Vre_and_stor_wind_variability.csv

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.

2. Optional inputs files

2.1 Operational_reserves.csv

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.

Table 7: Structure of the Operational_reserves.csv file

Column NameDescription
Reg_Req_Percent_Demand[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_MWPenalty for not meeting time-dependent spinning reserve requirement (/MW per time step).
Dynamic_ContingencyFlags 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_MWA 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.

2.2 Energy_share_requirement.csv

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).

Table 8: Structure of the Energy_share_requirement.csv file

Column NameDescription
Region_descriptionRegion name
Network_zoneszone number represented as z*
ESR_*[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.

2.3 CO2_cap.csv

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.

Table 9: Structure of the CO2_cap.csv file

Column NameDescription
Region_descriptionRegion name
Network_zoneszone number represented as z*
CO_2_Cap_Zone_*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.

2.4 Capacity_reserve_margin.csv

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).

Table 10: Structure of the Capacity_reserve_margin.csv file

Column NameDescription
Region_descriptionRegion name
Network_zoneszone number represented as z*
CapRes_*[0,1], Capacity reserve margin requirements of a zone, reported as a fraction of demand

2.5 Minimum_capacity_requirement.csv

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.

Table 11: Structure of the Minimum_capacity_requirement.csv file

Column NameDescription
MinCapReqConstraintIndex of the minimum capacity carve-out requirement.
Constraint_DescriptionNames of minimum capacity carve-out constraints; not to be read by model, but used as a helpful notation to the model user.
Min_MWminimum 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.

2.6 Maximum_capacity_requirement.csv

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.

Table 12: Structure of the Maximum_capacity_requirement.csv file

Column NameDescription
MaxCapReqConstraintIndex of the maximum capacity limit.
Constraint_DescriptionNames of maximum capacity limit; not to be read by model, but used as a helpful notation to the model user.
Max_MWmaximum 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.

2.7 Method_of_morris_range.csv

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.

Table 13: Structure of the Method_of_morris_range.csv file

Column NameDescription
ResourceThis column contains unique names of resources available to the model. Resources can include generators, storage, and flexible or time shiftable demand/loads.
ZoneInteger representing zone number where the resource is located.
Lower_boundPercentage lower deviation from the nominal value
Upper_boundPercentage upper deviation from the nominal value
ParameterColumn from the resource .csv file (inside the Resource) containing uncertain parameters
GroupGroup 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_stepsNumber of steps between upper and lower bound
total_num_trajectoryTotal number of trakectories through the design matrix
num_trajectorySelected number of trajectories throigh the design matrix
len_design_matLength of the design matrix
policyName of the policy
Notes
  1. Upper and lower bounds are specified in terms of percentage deviation from the nominal value.
  2. 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
  3. P_steps should at least be = 1\%, i.e., Upper_bound – Lower_bound $<$ p_steps
  4. P_steps for parameters in one group must be identical
  5. Total_num_trajectory should be around 3 to 4 times the total number of uncertain parameters
  6. num_trajectory should be approximately equal to the total number of uncertain parameters
  7. len_design_mat should be 1.5 to 2 times the total number of uncertain parameters
  8. Higher number of num_trajectory and lendesignmat would lead to higher accuracy
  9. 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.
+ 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.

1.3 Demand_data.csv (Load_data.csv)

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).

Table 4: Structure of the Demand_data.csv file

Column NameDescription
Mandatory Columns
VollValue of lost load (also referred to as non-served energy) in /MWh.
Demand_SegmentNumber 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_MWCost 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_CurtailmentMaximum 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_IndexIndex 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_PeriodsNumber 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_PeriodNumber 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_WeightsNumber 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).

1.4 Resources input files

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:

  1. thermal generators, specified in the Thermal.csv file,
  2. variable renewable energy resources (VRE), specified in the VRE.csv file,
  3. reservoir hydro resources, specified in the Hydro.csv file,
  4. storage resources, specified in the Storage.csv file,
  5. flexible demand resources, specified in the Flex_demand.csv file,
  6. must-run resources, specified in the Must_run.csv file,
  7. electrolyzers, specified in the Electrolyzer.csv file, and
  8. 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.

Table 5a: Mandatory columns in all resource .csv file

Column NameDescription
ResourceThis column contains unique names of resources available to the model. Resources can include generators, storage, and flexible or time shiftable demand.
ZoneInteger 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_MWThe 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_MWyrAnnualized 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_MWyrFixed 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_MWhVariable 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_MWhHeat 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.
FuelFuel needed for a generator. The names should match with the ones in the Fuels_data.csv.
Required for writing outputs
regionName of the model region
clusterNumber 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_IdUnique identifier to group retrofittable source technologies with retrofit options inside the same zone.
Retrofit_Efficiency[0,1], Efficiency of the retrofit technology.
Table 5b: Settings-specific columns in all resource .csv file

Column NameDescription
ModelingToGenerateAlternatives = 1
MGAEligibility 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_TypeFor 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_YearsLength 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_CadenceCadence 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_TonCost associated with CCS disposal (/tCO2), including pipeline, injection and storage costs of CCS-equipped generators.
Table 6a: Additional columns in the Thermal.csv file
Column NameDescription
Model{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_hThe fuel usage (MMBTU/h) for the first PWFU segemnt (y-intercept) at zero load.
PWFU_Heat_Rate_MMBTU_per_MWh_*iThe slope of fuel usage function of the segment i.
PWFU_Load_Point_MW_*iThe 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_FuelsNumber 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.
Fuel1Frist fuel needed for a mulit-fuel generator (MULTIFUELS = 1). The names should match with the ones in the `Fuelsdata.csv`.
Fuel2Second fuel needed for a mulit-fuel generator (MULTIFUELS = 1). The names should match with the ones in the `Fuelsdata.csv`.
Heat1_Rate_MMBTU_per_MWhHeat rate of a multi-fuel generator (MULTI_FUELS = 1) for Fuel1.
Heat2_Rate_MMBTU_per_MWhHeat rate of a multi-fuel generator (MULTI_FUELS = 1) for Fuel2.
Fuel1_Min_Cofire_LevelThe 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\StartThe 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_LevelThe 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\StartThe 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_LevelThe 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\StartThe 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_LevelThe 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\StartThe maximum blendng level of 'Fuel2' in total heat inputs of a mulit-fuel generator (MULTI_FUELS = 1) during the start-up process.
Table 6b: Settings-specific columns in the Thermal.csv file

Column NameDescription
UCommit >= 1The following settings apply only to thermal plants with unit commitment constraints
Up_TimeMinimum amount of time a resource has to stay in the committed state.
Down_TimeMinimum amount of time a resource has to remain in the shutdown state.
Start_Cost_per_MWCost 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_MWStartup fuel use per MW of nameplate capacity of each generator (MMBtu/MW per start).
OperationalReserves = 1
Reg_CostCost of providing regulation reserves (/MW per time step/hour).
Rsv_CostCost 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.
Table 7a: Additional columns in the Vre.csv file

Column NameDescription
Num_VRE_binsNumber 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.
Table 6b: Settings-specific columns in the Vre.csv file

Column NameDescription
OperationalReserves = 1
Reg_CostCost of providing regulation reserves (/MW per time step/hour).
Rsv_CostCost 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.
Table 7a: Additional columns in the Hydro.csv file

Column NameDescription
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.
Hydro_Energy_to_Power_RatioThe 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.
LDS = 0: Not part of set (default)
LDS = 1: Long duration storage resources
Table 7b: Settings-specific columns in the Hydro.csv file

Column NameDescription
OperationalReserves = 1
Reg_CostCost of providing regulation reserves (/MW per time step/hour).
Rsv_CostCost 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.
Table 8a: Additional columns in the Storage.csv file

Column NameDescription
Model{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_DurationSpecifies the minimum ratio of installed energy to discharged power capacity that can be installed (hours).
Max_DurationSpecifies the maximum ratio of installed energy to discharged power capacity that can be installed (hours).
Existing technology capacity
Existing_Cap_MWhThe existing capacity of storage in MWh where Model = 1 or Model = 2.
Existing_Charge_Cap_MWThe 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_MWhyrAnnualized investment cost of the energy capacity for a storage technology (/MW/year), applicable to either Model = 1 or Model = 2.
Inv_Cost_Charge_per_MWyrAnnualized capacity investment cost for the charging portion of a storage technology with Model = 2 (/MW/year).
Fixed_OM_Cost_per_MWhyrFixed operations and maintenance cost of the energy component of a storage technology (/MWh/year).
Fixed_OM_Cost_Charge_per_MWyrFixed operations and maintenance cost of the charging component of a storage technology of type Model = 2.
Var_OM_Cost_per_MWhInVariable operations and maintenance cost of the charging aspect of a storage technology with Model = 2. Otherwise 0 (/MWh).
Table 8b: Settings-specific columns in the Storage.csv file

Column NameDescription
OperationalReserves = 1
Reg_CostCost of providing regulation reserves (/MW per time step/hour).
Rsv_CostCost 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.
Table 9: Additional columns in the Flex_demand.csv file

Column NameDescription
Max_Flexible_Demand_DelayMaximum number of hours that demand can be deferred or delayed (hours).
Max_Flexible_Demand_AdvanceMaximum 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_MWhInVariable operations and maintenance costs associated with flexible demand deferral. Otherwise 0 (/MWh).
Table 10: Additional columns in the Electrolyzer.csv file

Column NameDescription
HydrogenMWhPer_TonneElectrolyzer efficiency in megawatt-hours (MWh) of electricity per metric tonne of hydrogen produced (MWh/t)
ElectrolyzerMinktMinimum annual quantity of hydrogen that must be produced by electrolyzer in kilotonnes (kt)
HydrogenPricePer_TonnePrice (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.

Table 11a: Additional columns in the Vre_stor.csv file

Column NameDescription
Technology type flags
SOLAR{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_MWThe existing AC grid connection capacity in MW.
Existing_Cap_MWhThe existing capacity of storage in MWh.
Existing_Cap_Inverter_MWThe existing capacity of co-located VRE-STOR resource's inverter in MW (AC).
Existing_Cap_Solar_MWThe existing capacity of co-located VRE-STOR resource's solar PV in MW (DC).
Existing_Cap_Wind_MWThe existing capacity of co-located VRE-STOR resource's wind in MW (AC).
Existing_Cap_Discharge_DC_MWThe 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_MWThe 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_MWThe 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_MWThe 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_MWyrAnnualized capacity investment cost of the grid connection (/MW/year).
Inv_Cost_per_MWhyrAnnualized investment cost of the energy capacity for the co-located storage resource (/MW/year)
Fixed_OM_Cost_per_MWyrFixed operations and maintenance cost of the grid connection (/MW/year).
Fixed_OM_Cost_per_MWhyrFixed operations and maintenance cost of the energy component of the co-located storage resource. (/MWh/year).
Inv_Cost_Inverter_per_MWyrAnnualized capacity investment cost of the inverter component (/MW-AC/year).
Inv_Cost_Solar_per_MWyrAnnualized capacity investment cost of the solar PV component (/MW-DC/year).
Inv_Cost_Wind_per_MWyrAnnualized capacity investment cost of the wind component (/MW-AC/year).
Inv_Cost_Discharge_DC_per_MWyrAnnualized capacity investment cost for the discharging portion of a storage technology with STOR_DC_DISCHARGE = 2 (/MW-DC/year).
Inv_Cost_Charge_DC_per_MWyrAnnualized capacity investment cost for the charging portion of a storage technology with STOR_DC_CHARGE = 2 (/MW-DC/year).
Inv_Cost_Discharge_AC_per_MWyrAnnualized capacity investment cost for the discharging portion of a storage technology with STOR_AC_DISCHARGE = 2 (/MW-AC/year).
Inv_Cost_Charge_AC_per_MWyrAnnualized capacity investment cost for the charging portion of a storage technology with STOR_AC_CHARGE = 2 (/MW-AC/year).
Fixed_OM_Inverter_Cost_per_MWyrFixed operations and maintenance cost of the inverter component (/MW-AC/year).
Fixed_OM_Solar_Cost_per_MWyrFixed operations and maintenance cost of the solar PV component (/MW-DC/year).
Fixed_OM_Wind_Cost_per_MWyrFixed operations and maintenance cost of the wind component (/MW-AC/year).
Fixed_OM_Cost_Discharge_DC_per_MWyrFixed 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_MWyrFixed 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_MWyrFixed 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_MWyrFixed 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_SolarVariable operations and maintenance cost of the solar PV component (multiplied by the inverter efficiency for AC terms) (/MWh).
Var_OM_Cost_per_MWh_WindVariable operations and maintenance cost of the wind component (/MWh).
Var_OM_Cost_per_MWh_Discharge_DCVariable 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_DCVariable 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_ACVariable operations and maintenance cost of the discharging component of a storage technology with STOR_AC_DISCHARGE = 2 (/MWh).
Var_OM_Cost_per_MWh_Charge_ACVariable 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_ACThe power to energy conversion for the storage component for AC discharging/charging of symmetric storage resources.
Power_to_Energy_DCThe 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).
Table 11b: Settings-specific columns in the Vre_stor.csv file

Column NameDescription
OperationalReserves = 1
Reg_CostCost of providing regulation reserves (/MW per time step/hour).
Rsv_CostCost 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.

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:

  1. Resource_energy_share_requirement.csv
  2. Resource_minimum_capacity_requirement.csv
  3. Resource_maximum_capacity_requirement.csv
  4. 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.

Table 12: Energy share requirement policy parameters

Column NameDescription
ResourceResource name corresponding to a resource in one of the resource data files described above.
ESR_*Flag to indicate which resources are considered for the Energy Share Requirement constraint.
1- included
0- excluded
co-located VRE-STOR resources only
ESRVreStor_*Flag to indicate which resources are considered for the Energy Share Requirement constraint.
1- included
0- excluded

This policy is applied when if MinCapReq = 1 in the settings file. * corresponds to the ith row of the file Minimum_capacity_requirement.csv.

Table 13: Minimum capacity requirement policy parameters

Column NameDescription
ResourceResource 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.

Table 14: Maximum capacity requirement policy parameters

Column NameDescription
ResourceResource 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.

Table 15: Capacity reserve margin policy parameters

Column NameDescription
ResourceResource name corresponding to a resource in one of the resource data files described above.
EligibleCapRes_*Fraction of the resource capacity eligible for contributing to the capacity reserve margin constraint (e.g. derate factor).

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:

  1. 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.

Table 16: Multistage parameters
Warning

This file is mandatory if MultiStage = 1 in the settings file.


Column NameDescription
ResourceResource name corresponding to a resource in one of the resource data files described above.
Capital_Recovery_PeriodCapital 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.
LifetimeLifetime (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_MWMinimum 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_MWMinimum 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_MWMinimum 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_DCCapital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the inverter component.
Capital_Recovery_Period_SolarCapital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the solar PV component.
Capital_Recovery_Period_WindCapital recovery period (in years) used for determining overnight capital costs from annualized investment costs for the wind component.
Capital_Recovery_PeriodDischargeDCCapital 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_PeriodChargeDCCapital 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_PeriodDischargeACCapital 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_PeriodChargeACCapital 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_MWMinimum 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_MWMinimum 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_MWMinimum 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\MWMinimum 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\MWMinimum 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\MWMinimum 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\MWMinimum 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_DCThe line-specific weighted average cost of capital for the inverter component.
WACC_SolarThe line-specific weighted average cost of capital for the solar PV component.
WACC_WindThe line-specific weighted average cost of capital for the wind component.
WACC_Discharge_DCThe line-specific weighted average cost of capital for the discharging DC storage component with STOR_DC_DISCHARGE = 2.
WACC_Charge_DCThe line-specific weighted average cost of capital for the charging DC storage component with STOR_DC_CHARGE = 2.
WACC_Discharge_ACThe line-specific weighted average cost of capital for the discharging AC storage component with STOR_AC_DISCHARGE = 2.
WACC_Charge_ACThe line-specific weighted average cost of capital for the charging AC storage component with STOR_AC_CHARGE = 2.

1.5 Generator_variability.csv

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. |

1.6 Vre_and_stor_solar_variability.csv

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.

1.7 Vre_and_stor_wind_variability.csv

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.

2. Optional inputs files

2.1 Operational_reserves.csv

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.

Table 7: Structure of the Operational_reserves.csv file

Column NameDescription
Reg_Req_Percent_Demand[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_MWPenalty for not meeting time-dependent spinning reserve requirement (/MW per time step).
Dynamic_ContingencyFlags 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_MWA 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.

2.2 Energy_share_requirement.csv

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).

Table 8: Structure of the Energy_share_requirement.csv file

Column NameDescription
Region_descriptionRegion name
Network_zoneszone number represented as z*
ESR_*[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.

2.3 CO2_cap.csv

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.

Table 9: Structure of the CO2_cap.csv file

Column NameDescription
Region_descriptionRegion name
Network_zoneszone number represented as z*
CO_2_Cap_Zone_*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.

2.4 Capacity_reserve_margin.csv

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).

Table 10: Structure of the Capacity_reserve_margin.csv file

Column NameDescription
Region_descriptionRegion name
Network_zoneszone number represented as z*
CapRes_*[0,1], Capacity reserve margin requirements of a zone, reported as a fraction of demand

2.5 Minimum_capacity_requirement.csv

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.

Table 11: Structure of the Minimum_capacity_requirement.csv file

Column NameDescription
MinCapReqConstraintIndex of the minimum capacity carve-out requirement.
Constraint_DescriptionNames of minimum capacity carve-out constraints; not to be read by model, but used as a helpful notation to the model user.
Min_MWminimum 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.

2.6 Maximum_capacity_requirement.csv

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.

Table 12: Structure of the Maximum_capacity_requirement.csv file

Column NameDescription
MaxCapReqConstraintIndex of the maximum capacity limit.
Constraint_DescriptionNames of maximum capacity limit; not to be read by model, but used as a helpful notation to the model user.
Max_MWmaximum 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.

2.7 Method_of_morris_range.csv

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.

Table 13: Structure of the Method_of_morris_range.csv file

Column NameDescription
ResourceThis column contains unique names of resources available to the model. Resources can include generators, storage, and flexible or time shiftable demand/loads.
ZoneInteger representing zone number where the resource is located.
Lower_boundPercentage lower deviation from the nominal value
Upper_boundPercentage upper deviation from the nominal value
ParameterColumn from the resource .csv file (inside the Resource) containing uncertain parameters
GroupGroup 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_stepsNumber of steps between upper and lower bound
total_num_trajectoryTotal number of trakectories through the design matrix
num_trajectorySelected number of trajectories throigh the design matrix
len_design_matLength of the design matrix
policyName of the policy
Notes
  1. Upper and lower bounds are specified in terms of percentage deviation from the nominal value.
  2. 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
  3. P_steps should at least be = 1\%, i.e., Upper_bound – Lower_bound $<$ p_steps
  4. P_steps for parameters in one group must be identical
  5. Total_num_trajectory should be around 3 to 4 times the total number of uncertain parameters
  6. num_trajectory should be approximately equal to the total number of uncertain parameters
  7. len_design_mat should be 1.5 to 2 times the total number of uncertain parameters
  8. Higher number of num_trajectory and lendesignmat would lead to higher accuracy
  9. 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.
diff --git a/previews/PR662/User_Guide/model_output/index.html b/previews/PR662/User_Guide/model_output/index.html index 684feec1a9..b9907c8c08 100644 --- a/previews/PR662/User_Guide/model_output/index.html +++ b/previews/PR662/User_Guide/model_output/index.html @@ -1,2 +1,2 @@ -Model Outputs · GenX

GenX Outputs

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).

1 Default output files

1.1 capacity.csv

Reports optimal values of investment variables (except StartCap, which is an input)

Table 15: Structure of the capacity.csv file

OutputDescriptionUnits
StartCapInitial power capacity of each resource type in each zone; this is an inputMW
RetCapRetired power capacity of each resource type in each zoneMW
NewCapInstalled capacity of each resource type in each zoneMW
EndCapTotal power capacity of each resource type in each zoneMW
StartEnergyCapInitial energy capacity of each resource type in each zone; this is an input and applies only to storage tech.MWh
RetEnergyCapRetired energy capacity of each resource type in each zone; applies only to storage tech.MWh
NewEnergyCapInstalled energy capacity of each resource type in each zone; applies only to storage tech.MWh
EndEnergyCapTotal installed energy capacity of each resource type in each zone; applies only to storage tech.MWh
StartChargeCapInitial charging power capacity of STOR = 2 resource type in each zone; this is an inputMW
RetChargeCapRetired charging power capacity of STOR = 2 resource type in each zoneMW
NewChargeCapInstalled charging capacity of each resource type in each zoneMW
EndChargeCapTotal charging power capacity of each resource type in each zoneMW

1.2 costs.csv

Reports optimal objective function value and contribution of each term by zone.

Table 16: Structure of the costs.csv file

OutputDescriptionUnits
cTotalTotal objective function value$
cFixTotal annualized investment and fixed operating & maintainenance (FOM) costs associated with all resources$
cVarTotal annual variable cost associated with all resources; includes fuel costs for thermal plants$
cNSETotal annual cost of non-served energy$
cStartTotal annual cost of start-up of thermal power plants$
cUnmetRsvTotal annual cost of not meeting time-dependent operating reserve (spinning) requirements$
cNetworkExpTotal cost of network expansion$
cEmissionsRevenueTotal and zonal emissions revenue$
cEmissionsCostTotal an zonal emissions cost$

1.3 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.

Table 17: Structure of emission prices in the emissions.csv file

OutputDescriptionUnits
CO2\priceMarginal 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$/ tonne CO2.

1.4 nse.csv

Reports non-served energy for every model zone, time step and cost-segment.

1.5 power.csv

Reports power discharged by each resource (generation, storage, demand response) in each model time step.

1.6 reliability.csv

Reports dual variable of maximum non-served energy constraint (shadow price of reliability constraint) for each model zone and time step.

1.7 prices.csv

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.

1.8 status.csv

Reports computational performance of the model and objective function related information.

Table 18: Structure of the status.csv file

OutputDescriptionUnits
Statustermination criteria (optimal, timelimit etc.).
solveSolve time including time for pre-solveseconds
ObjvalOptimal objective function value$
ObjboundBest objective lower bound$
FinalMIPGapOptimality 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.Fraction

1.9 NetRevenue.csv

This file summarizes the cost, revenue and profit for each generation technology for each region.

Table 19: Stucture of the NetRevenue.csv file

OutputDescriptionUnits
Fixed_OM_cost_MWFixed Operation and Maintenance cost of the MW capacity.$
Fixed_OM_cost_MWhFixed Operation and Maintenance cost of the MWh capacity. Only applicable to energy storage.$
Var_OM_cost_outVariable Operation and Maintenance cost of the power generation or discharge.$
Var_OM_cost_inVariable Operation and Maintenance cost of the power charge/pumping. Only applicable to energy storage.$
Fuel_costFuel cost of the power generation. Only applicable to generation that burns fuel.$
Charge_costCost of charging power (due to the payment for electricity) Only applicable to energy storage.$
EmissionsCostCost of buying emission credit.$
StartCostCost of generator start-up.$
Inv_cost_MWCost of building MW capacity.$
Inv_cost_MWhCost of building MWh capacity.$
EnergyRevenueRevenue of generating power.$
SubsidyRevenueRevenue of Min_Cap subsidy.$
ReserveMarginRevenueRevenue earned from capacity reserve margin constraints.$
ESRRevenueRevenue selling renewable/clean energy credits.$
RevenueTotal Revenue.$
CostTotal Cost.$
ProfitRevenue minus Cost.$

2 Settings-specific outputs

This section includes the output files that GenX will print if corresponding function is specified in the Settings.

2.1 CapacityValue.csv

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.

2.3 Importcost.csv

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. –>

2.2 EnergyRevenue.csv

This file includes the energy revenue in $ earned by each generator through injecting into the grid. Only annual sum values are available.

2.3 ChargingCost.csv

This file includes the charging cost in $ of earned by each generator through withdrawing from the grid. Only annual sum values are available.

2.4 ReserveMargin.csv

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.

2.5 ReserveMarginRevenue.csv

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.

2.6 ESR_prices.csv

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.

2.7 ESR_Revenue.csv

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 $.

2.8 SubsidyRevenue.csv

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 $.

+Model Outputs · GenX.jl

GenX Outputs

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).

1 Default output files

1.1 capacity.csv

Reports optimal values of investment variables (except StartCap, which is an input)

Table 15: Structure of the capacity.csv file

OutputDescriptionUnits
StartCapInitial power capacity of each resource type in each zone; this is an inputMW
RetCapRetired power capacity of each resource type in each zoneMW
NewCapInstalled capacity of each resource type in each zoneMW
EndCapTotal power capacity of each resource type in each zoneMW
StartEnergyCapInitial energy capacity of each resource type in each zone; this is an input and applies only to storage tech.MWh
RetEnergyCapRetired energy capacity of each resource type in each zone; applies only to storage tech.MWh
NewEnergyCapInstalled energy capacity of each resource type in each zone; applies only to storage tech.MWh
EndEnergyCapTotal installed energy capacity of each resource type in each zone; applies only to storage tech.MWh
StartChargeCapInitial charging power capacity of STOR = 2 resource type in each zone; this is an inputMW
RetChargeCapRetired charging power capacity of STOR = 2 resource type in each zoneMW
NewChargeCapInstalled charging capacity of each resource type in each zoneMW
EndChargeCapTotal charging power capacity of each resource type in each zoneMW

1.2 costs.csv

Reports optimal objective function value and contribution of each term by zone.

Table 16: Structure of the costs.csv file

OutputDescriptionUnits
cTotalTotal objective function value$
cFixTotal annualized investment and fixed operating & maintainenance (FOM) costs associated with all resources$
cVarTotal annual variable cost associated with all resources; includes fuel costs for thermal plants$
cNSETotal annual cost of non-served energy$
cStartTotal annual cost of start-up of thermal power plants$
cUnmetRsvTotal annual cost of not meeting time-dependent operating reserve (spinning) requirements$
cNetworkExpTotal cost of network expansion$
cEmissionsRevenueTotal and zonal emissions revenue$
cEmissionsCostTotal an zonal emissions cost$

1.3 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.

Table 17: Structure of emission prices in the emissions.csv file

OutputDescriptionUnits
CO2\priceMarginal 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$/ tonne CO2.

1.4 nse.csv

Reports non-served energy for every model zone, time step and cost-segment.

1.5 power.csv

Reports power discharged by each resource (generation, storage, demand response) in each model time step.

1.6 reliability.csv

Reports dual variable of maximum non-served energy constraint (shadow price of reliability constraint) for each model zone and time step.

1.7 prices.csv

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.

1.8 status.csv

Reports computational performance of the model and objective function related information.

Table 18: Structure of the status.csv file

OutputDescriptionUnits
Statustermination criteria (optimal, timelimit etc.).
solveSolve time including time for pre-solveseconds
ObjvalOptimal objective function value$
ObjboundBest objective lower bound$
FinalMIPGapOptimality 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.Fraction

1.9 NetRevenue.csv

This file summarizes the cost, revenue and profit for each generation technology for each region.

Table 19: Stucture of the NetRevenue.csv file

OutputDescriptionUnits
Fixed_OM_cost_MWFixed Operation and Maintenance cost of the MW capacity.$
Fixed_OM_cost_MWhFixed Operation and Maintenance cost of the MWh capacity. Only applicable to energy storage.$
Var_OM_cost_outVariable Operation and Maintenance cost of the power generation or discharge.$
Var_OM_cost_inVariable Operation and Maintenance cost of the power charge/pumping. Only applicable to energy storage.$
Fuel_costFuel cost of the power generation. Only applicable to generation that burns fuel.$
Charge_costCost of charging power (due to the payment for electricity) Only applicable to energy storage.$
EmissionsCostCost of buying emission credit.$
StartCostCost of generator start-up.$
Inv_cost_MWCost of building MW capacity.$
Inv_cost_MWhCost of building MWh capacity.$
EnergyRevenueRevenue of generating power.$
SubsidyRevenueRevenue of Min_Cap subsidy.$
ReserveMarginRevenueRevenue earned from capacity reserve margin constraints.$
ESRRevenueRevenue selling renewable/clean energy credits.$
RevenueTotal Revenue.$
CostTotal Cost.$
ProfitRevenue minus Cost.$

2 Settings-specific outputs

This section includes the output files that GenX will print if corresponding function is specified in the Settings.

2.1 CapacityValue.csv

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.

2.3 Importcost.csv

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. –>

2.2 EnergyRevenue.csv

This file includes the energy revenue in $ earned by each generator through injecting into the grid. Only annual sum values are available.

2.3 ChargingCost.csv

This file includes the charging cost in $ of earned by each generator through withdrawing from the grid. Only annual sum values are available.

2.4 ReserveMargin.csv

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.

2.5 ReserveMarginRevenue.csv

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.

2.6 ESR_prices.csv

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.

2.7 ESR_Revenue.csv

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 $.

2.8 SubsidyRevenue.csv

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 $.

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

Multi-stage setup

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.

Perfect foresightMyopic
No. of optimization problems solved1Equal to number of investment stages
Objective function cost basisNet present valueAnnualized costs
Price/dual variable information available?NoYes

Additional inputs needed for multi-stage modeling

Input data files

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_MWMinimum 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_MWMinimum 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_MWMinimum charge capacity in MW that must retire in this planning stage.
LifetimeThe operational lifespan in years of this technology after which it must be retired.
Capital_Recovery_PeriodThe 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.
WACCThe 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_MWMinimum inverter capacity in MW AC that must retire in this plannig stage.
Min_Retired_Cap_Solar_MWMinimum solar PV capacity in MW DC that must retire in this plannig stage.
Min_Retired_Cap_Wind_MWMinimum wind capacity in MW AC that must retire in this plannig stage.
Min_Retired_Cap_DischargeDC\MWMinimum storage DC discharge capacity that must retire in this planning stage with STOR_DC_DISCHARGE = 2.
Min_Retired_Cap_ChargeDC\MWMinimum storage DC charge capacity that must retire in this planning stage with STOR_DC_CHARGE = 2.
Min_Retired_Cap_DischargeAC\MWMinimum storage AC discharge capacity that must retire in this planning stage with STOR_AC_DISCHARGE = 2.
Min_Retired_Cap_ChargeAC\MWMinimum storage AC charge capacity that must retire in this planning stage with STOR_AC_CHARGE = 2.
Capital_Recovery_Period_DCThe technology-specific period in years over which initial capital costs for the inverter component must be recovered.
Capital_Recovery_Period_SolarThe technology-specific period in years over which initial capital costs for the solar PV component must be recovered.
Capital_Recovery_Period_WindThe technology-specific period in years over which initial capital costs for the wind component must be recovered.
Capital_Recovery_PeriodDischargeDCThe 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_PeriodChargeDCThe 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_PeriodDischargeACThe 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_PeriodChargeACThe 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_DCThe line-specific weighted average cost of capital for the inverter component.
WACC_SolarThe line-specific weighted average cost of capital for the solar PV component.
WACC_WindThe line-specific weighted average cost of capital for the wind component.
WACC_Discharge_DCThe line-specific weighted average cost of capital for the discharging DC storage component with STOR_DC_DISCHARGE = 2.
WACC_Charge_DCThe line-specific weighted average cost of capital for the charging DC storage component with STOR_DC_CHARGE = 2.
WACC_Discharge_ACThe line-specific weighted average cost of capital for the discharging AC storage component with STOR_AC_DISCHARGE = 2.
WACC_Charge_ACThe line-specific weighted average cost of capital for the charging AC storage component with STOR_AC_CHARGE = 2.
Network.csv
Line_Max_Flow_Possible_MWThe 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_PeriodThe line-specific period in years over which initial capital costs must be recovered.
WACCThe 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.

  1. 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).
  2. By default, the model assumes that retrofitted capacity contributes to fulfilling minimum retirement requirements.
  3. 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).
  4. 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):

Thermal.csv
+Multi-stage Model · GenX.jl

Multi-stage setup

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.

Perfect foresightMyopic
No. of optimization problems solved1Equal to number of investment stages
Objective function cost basisNet present valueAnnualized costs
Price/dual variable information available?NoYes

Additional inputs needed for multi-stage modeling

Input data files

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_MWMinimum 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_MWMinimum 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_MWMinimum charge capacity in MW that must retire in this planning stage.
LifetimeThe operational lifespan in years of this technology after which it must be retired.
Capital_Recovery_PeriodThe 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.
WACCThe 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_MWMinimum inverter capacity in MW AC that must retire in this plannig stage.
Min_Retired_Cap_Solar_MWMinimum solar PV capacity in MW DC that must retire in this plannig stage.
Min_Retired_Cap_Wind_MWMinimum wind capacity in MW AC that must retire in this plannig stage.
Min_Retired_Cap_DischargeDC\MWMinimum storage DC discharge capacity that must retire in this planning stage with STOR_DC_DISCHARGE = 2.
Min_Retired_Cap_ChargeDC\MWMinimum storage DC charge capacity that must retire in this planning stage with STOR_DC_CHARGE = 2.
Min_Retired_Cap_DischargeAC\MWMinimum storage AC discharge capacity that must retire in this planning stage with STOR_AC_DISCHARGE = 2.
Min_Retired_Cap_ChargeAC\MWMinimum storage AC charge capacity that must retire in this planning stage with STOR_AC_CHARGE = 2.
Capital_Recovery_Period_DCThe technology-specific period in years over which initial capital costs for the inverter component must be recovered.
Capital_Recovery_Period_SolarThe technology-specific period in years over which initial capital costs for the solar PV component must be recovered.
Capital_Recovery_Period_WindThe technology-specific period in years over which initial capital costs for the wind component must be recovered.
Capital_Recovery_PeriodDischargeDCThe 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_PeriodChargeDCThe 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_PeriodDischargeACThe 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_PeriodChargeACThe 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_DCThe line-specific weighted average cost of capital for the inverter component.
WACC_SolarThe line-specific weighted average cost of capital for the solar PV component.
WACC_WindThe line-specific weighted average cost of capital for the wind component.
WACC_Discharge_DCThe line-specific weighted average cost of capital for the discharging DC storage component with STOR_DC_DISCHARGE = 2.
WACC_Charge_DCThe line-specific weighted average cost of capital for the charging DC storage component with STOR_DC_CHARGE = 2.
WACC_Discharge_ACThe line-specific weighted average cost of capital for the discharging AC storage component with STOR_AC_DISCHARGE = 2.
WACC_Charge_ACThe line-specific weighted average cost of capital for the charging AC storage component with STOR_AC_CHARGE = 2.
Network.csv
Line_Max_Flow_Possible_MWThe 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_PeriodThe line-specific period in years over which initial capital costs must be recovered.
WACCThe 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.

  1. 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).
  2. By default, the model assumes that retrofitted capacity contributes to fulfilling minimum retirement requirements.
  3. 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).
  4. 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):

Thermal.csv
 
 Resource          │ Zone  | Retrofit | Can_Retrofit | Retrofit_Id | Retrofit_Efficiency
 String            │ Int64 | Int64    | Int64        | Int64       | Float64
@@ -20,4 +20,4 @@
 ─────────────────-┼────────────────────┼──────────────────────────
 coal_1            │ 4500               │ 0
 20_NH3_retrofit_1 │ 0                  │ 0                         <---------
-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.

Settings Files

A separate settings.yml file includes a list of parameters to be specified to formulate the multi-stage planning model.

multi_stage_settings.yml
NumStagesThe number of model investment planning stages.
StageLengthsA 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.
Myopic0 = perfect foresight, 1 = myopic model (see above table)
ConvergenceToleranceThe relative optimality gap used for convergence of the dual dynamic programming algorithm. Only required when Myopic = 0
WACCRate used to discount non-technology-specific costs from stage to stage (i.e., the “social discount rate”).
time_domain_reduction_settings.yml
MultiStageConcatenateDesignates 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).
+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.

Settings Files

A separate settings.yml file includes a list of parameters to be specified to formulate the multi-stage planning model.

multi_stage_settings.yml
NumStagesThe number of model investment planning stages.
StageLengthsA 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.
Myopic0 = perfect foresight, 1 = myopic model (see above table)
ConvergenceToleranceThe relative optimality gap used for convergence of the dual dynamic programming algorithm. Only required when Myopic = 0
WACCRate used to discount non-technology-specific costs from stage to stage (i.e., the “social discount rate”).
time_domain_reduction_settings.yml
MultiStageConcatenateDesignates 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).
diff --git a/previews/PR662/User_Guide/running_TDR/index.html b/previews/PR662/User_Guide/running_TDR/index.html index 1fa74c2d52..271a443ac8 100644 --- a/previews/PR662/User_Guide/running_TDR/index.html +++ b/previews/PR662/User_Guide/running_TDR/index.html @@ -1,9 +1,9 @@ -Running the Time-domain Reduction · GenX

Running a case with Time Domain Reduction

There are two ways to run a case with a reduced (e.g. less than full-year) temporal resolution.

  1. Let GenX perform the time domain reduction before optimizing.
  2. Bring your own clustered data

It's also possible for GenX perform clustering separately from the optimization task.

Method 1: Let GenX perform the time domain reduction (clustering)

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:

..., Rep_Periods, Timesteps_per_Rep_Period, Sub_Weights, ...
+Running the Time-domain Reduction · GenX.jl

Running a case with Time Domain Reduction

There are two ways to run a case with a reduced (e.g. less than full-year) temporal resolution.

  1. Let GenX perform the time domain reduction before optimizing.
  2. Bring your own clustered data

It's also possible for GenX perform clustering separately from the optimization task.

Method 1: Let GenX perform the time domain reduction (clustering)

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:

..., Rep_Periods, Timesteps_per_Rep_Period, Sub_Weights, ...
                1,                     8760,        8760,

Method 2: Bring your own clustered data

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

..., Rep_Periods, Timesteps_per_Rep_Period, Sub_Weights, ...
                3,                      168,      4368.0,
                                                  2184.0,
                                                  2184.0,

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.

See also the Time-domain reduction.

Performing time domain reduction (TDR) separately from optimization

Added in 0.3.4

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.

+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.

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

Running the model

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

Running the model

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.

Slack Variables

To run a case with slack variables, check out the Policy Slack Variables section.

+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.

Slack Variables

To run a case with slack variables, check out the Policy Slack Variables section.

diff --git a/previews/PR662/User_Guide/slack_variables_overview/index.html b/previews/PR662/User_Guide/slack_variables_overview/index.html index f4ca935331..8c468b32fc 100644 --- a/previews/PR662/User_Guide/slack_variables_overview/index.html +++ b/previews/PR662/User_Guide/slack_variables_overview/index.html @@ -1,2 +1,2 @@ -Slack Variables for Policies · GenX

Policy Slack Variables

Added in 0.3.5

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.

Running cases with slack variables

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:

Capacity Reserve Margin

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.

CO2 Cap

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.

Energy Share Requirement

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.

Minimum Capacity Requirement

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.

Maximum Capacity Requirement

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.

Slack Variables Results Files

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.

Slack Variables Example

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.

+Slack Variables for Policies · GenX.jl

Policy Slack Variables

Added in 0.3.5

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.

Running cases with slack variables

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:

Capacity Reserve Margin

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.

CO2 Cap

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.

Energy Share Requirement

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.

Minimum Capacity Requirement

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.

Maximum Capacity Requirement

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.

Slack Variables Results Files

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.

Slack Variables Example

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.

diff --git a/previews/PR662/User_Guide/solver_configuration/index.html b/previews/PR662/User_Guide/solver_configuration/index.html index 688004b33c..82abec25f1 100644 --- a/previews/PR662/User_Guide/solver_configuration/index.html +++ b/previews/PR662/User_Guide/solver_configuration/index.html @@ -1,2 +1,2 @@ -Solver Configuration · GenX

Solver Configuration

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.

Solver settings parameters**

Settings ParameterDescription
MethodAlgorithm 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.
BarConvTolConvergence 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_TolAll 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_TolReduced 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_SolveControls the presolve level.
Gurobi: Presolve - Default = -1; See link for more specifications.
clp: PresolveType - Default = 5; See link for more specifications.
CrossoverDetermines 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.
NumericFocusControls 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.
TimeLimitTime 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.
MIPGapOptimality 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.
DualObjectiveLimitWhen 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.
MaximumIterationsTerminate after performing this number of simplex iterations.
clp: MaximumIterations - Default = 2147483647; See link for more specifications.
LogLevelSet 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.
InfeasibleReturnSet 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.
ScalingSets or unsets scaling; 0 -off, 1 equilibrium, 2 geometric, 3 auto, 4 dynamic(later).
clp: Scaling - Default = 3; See link for more specifications.
PerturbationPerturbs problem; Switch on perturbation (50), automatic (100), don't try perturbing (102).
clp: Perturbation - Default = 3; See link for more specifications.
maxSolutionsTerminate after this many feasible solutions have been found.
cbc: maxSolutions - Default = -1; See link for more specifications.
maxNodesTerminate after this many branch-and-bound nodes have been evaluated
cbc: maxNodes - Default = -1; See link for more specifications.
allowableGapTerminate after optimality gap is less than this value (on an absolute scale)
cbc: allowableGap - Default = -1; See link for more specifications.
ratioGapTerminate after optimality gap is smaller than this relative fraction.
cbc: ratioGap - Default = Inf; See link for more specifications.
threadsSet the number of threads to use for parallel branch & bound.
cbc: threads - Default = 1; See link for more specifications.
+Solver Configuration · GenX.jl

Solver Configuration

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.

Solver settings parameters**

Settings ParameterDescription
MethodAlgorithm 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.
BarConvTolConvergence 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_TolAll 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_TolReduced 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_SolveControls the presolve level.
Gurobi: Presolve - Default = -1; See link for more specifications.
clp: PresolveType - Default = 5; See link for more specifications.
CrossoverDetermines 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.
NumericFocusControls 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.
TimeLimitTime 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.
MIPGapOptimality 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.
DualObjectiveLimitWhen 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.
MaximumIterationsTerminate after performing this number of simplex iterations.
clp: MaximumIterations - Default = 2147483647; See link for more specifications.
LogLevelSet 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.
InfeasibleReturnSet 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.
ScalingSets or unsets scaling; 0 -off, 1 equilibrium, 2 geometric, 3 auto, 4 dynamic(later).
clp: Scaling - Default = 3; See link for more specifications.
PerturbationPerturbs problem; Switch on perturbation (50), automatic (100), don't try perturbing (102).
clp: Perturbation - Default = 3; See link for more specifications.
maxSolutionsTerminate after this many feasible solutions have been found.
cbc: maxSolutions - Default = -1; See link for more specifications.
maxNodesTerminate after this many branch-and-bound nodes have been evaluated
cbc: maxNodes - Default = -1; See link for more specifications.
allowableGapTerminate after optimality gap is less than this value (on an absolute scale)
cbc: allowableGap - Default = -1; See link for more specifications.
ratioGapTerminate after optimality gap is smaller than this relative fraction.
cbc: ratioGap - Default = Inf; See link for more specifications.
threadsSet the number of threads to use for parallel branch & bound.
cbc: threads - Default = 1; See link for more specifications.
diff --git a/previews/PR662/User_Guide/workflow/index.html b/previews/PR662/User_Guide/workflow/index.html index e0d7ee1804..9e95ddef76 100644 --- a/previews/PR662/User_Guide/workflow/index.html +++ b/previews/PR662/User_Guide/workflow/index.html @@ -1,8 +1,8 @@ -Overall workflow · GenX

User Guide

Introduction

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:

  1. Temporal resolution of time series data such as electricity demand and renewable energy availability;
  2. Power system operational detail and unit commitment constraints;
  3. 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.

Workflow

The flexibility of GenX is achieved through a modular and transparent code structure developed in Julia + JuMP. The software workflow includes two main steps:

  1. 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.

  2. 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:

  1. Model settings parameters: genx_settings.yml
  2. Solver Configuration: [solver_name]_settings.yml
  3. GenX Inputs
  4. Time-domain reduction: time_domain_reduction.yml (optional)
  5. Multi-stage setup: multi_stage_settings.yml (optional)
  6. Running the model
  7. GenX Outputs

Details of running a GenX case

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
+Overall workflow · GenX.jl

User Guide

Introduction

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:

  1. Temporal resolution of time series data such as electricity demand and renewable energy availability;
  2. Power system operational detail and unit commitment constraints;
  3. 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.

Workflow

The flexibility of GenX is achieved through a modular and transparent code structure developed in Julia + JuMP. The software workflow includes two main steps:

  1. 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.

  2. 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:

  1. Model settings parameters: genx_settings.yml
  2. Solver Configuration: [solver_name]_settings.yml
  3. GenX Inputs
  4. Time-domain reduction: time_domain_reduction.yml (optional)
  5. Multi-stage setup: multi_stage_settings.yml (optional)
  6. Running the model
  7. GenX Outputs

Details of running a GenX case

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:

run_genx_case!("<Location_of_the_case_study_data>", optimizer)

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:

run_genx_case_multistage!(case, mysetup, optimizer)

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

OPTIMIZER = configure_solver(settings_path, optimizer)

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:

outputs_path = get_default_output_folder(case)
-elapsed_time = @elapsed outputs_path = write_outputs(EP, outputs_path, mysetup, myinputs)

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.

Single and Multi-stage investment planning

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.

+elapsed_time = @elapsed outputs_path = write_outputs(EP, outputs_path, mysetup, myinputs)

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.

Single and Multi-stage investment planning

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.

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

Additional Third Party Extensions to GenX

pygenx: Python interface for 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.

Simple GenX Case Runner: For automated sequential batch run for GenX

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

+Third Party Extensions · GenX.jl

Additional Third Party Extensions to GenX

pygenx: Python interface for 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.

Simple GenX Case Runner: For automated sequential batch run for GenX

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

diff --git a/previews/PR662/developer_guide/index.html b/previews/PR662/developer_guide/index.html index 6f53571b71..b719ef132a 100644 --- a/previews/PR662/developer_guide/index.html +++ b/previews/PR662/developer_guide/index.html @@ -1,5 +1,5 @@ -Developer Docs · GenX

How to contribute to GenX

Introduction

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:

  1. Use of GitHub issues to report bugs and request new features
  2. Use of GitHub pull requests (PR) to submit code changes
Tip

We encourage every contributors to read this guide, which contains some guidelines on how to contribute to a collaborative project like GenX.

The following sections describe in more detail how to work with GenX resources and how to add a new resource to GenX.

GenX resources

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:

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_types Tuple 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.

Resource design principles

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
+Developer Docs · GenX.jl

How to contribute to GenX

Introduction

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:

  1. Use of GitHub issues to report bugs and request new features
  2. Use of GitHub pull requests (PR) to submit code changes
Tip

We encourage every contributors to read this guide, which contains some guidelines on how to contribute to a collaborative project like GenX.

The following sections describe in more detail how to work with GenX resources and how to add a new resource to GenX.

GenX resources

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:

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_types Tuple 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.

Resource design principles

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)

And then:

julia> attribute_1(new_res1)
 6.2
 julia> new_res1.attribute_1
-6.2

Utility functions to work with JuMP expressions in GenX

GenX.add_similar_to_expression!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.

source
GenX.add_term_to_expression!Method
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).

source
GenX.check_addable_to_exprMethod
check_addable_to_expr(C::DataType, T::DataType)

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.

source
GenX.check_sizes_matchMethod
check_sizes_match(expr1::AbstractArray{C, dim1}, expr2::AbstractArray{T, dim2}) where {C,T,dim1, dim2}

Check that two arrays have the same dimensions. If not, return an error message which includes the dimensions of both arrays.

source
GenX.create_empty_expression!Method
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.

source
GenX.fill_with_const!Method
fill_with_const!(arr::AbstractArray{GenericAffExpr{C,T}, dims}, con::Real) where {C,T,dims}

Fill an array of expressions with the specified constant, in-place.

In the future we could expand this to non AffExpr, using GenericAffExpr e.g. if we wanted to use Float32 instead of Float64

source
GenX.fill_with_zeros!Method
fill_with_zeros!(arr::AbstractArray{GenericAffExpr{C,T}, dims}) where {C,T,dims}

Fill an array of expressions with zeros in-place.

source
GenX.sum_expressionMethod
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.

source
+6.2

Utility functions to work with JuMP expressions in GenX

GenX.add_similar_to_expression!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.

source
GenX.add_term_to_expression!Method
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).

source
GenX.check_addable_to_exprMethod
check_addable_to_expr(C::DataType, T::DataType)

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.

source
GenX.check_sizes_matchMethod
check_sizes_match(expr1::AbstractArray{C, dim1}, expr2::AbstractArray{T, dim2}) where {C,T,dim1, dim2}

Check that two arrays have the same dimensions. If not, return an error message which includes the dimensions of both arrays.

source
GenX.create_empty_expression!Method
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.

source
GenX.fill_with_const!Method
fill_with_const!(arr::AbstractArray{GenericAffExpr{C,T}, dims}, con::Real) where {C,T,dims}

Fill an array of expressions with the specified constant, in-place.

In the future we could expand this to non AffExpr, using GenericAffExpr e.g. if we wanted to use Float32 instead of Float64

source
GenX.fill_with_zeros!Method
fill_with_zeros!(arr::AbstractArray{GenericAffExpr{C,T}, dims}) where {C,T,dims}

Fill an array of expressions with zeros in-place.

source
GenX.sum_expressionMethod
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.

source
diff --git a/previews/PR662/index.html b/previews/PR662/index.html index 958fd881ea..ad978832f4 100644 --- a/previews/PR662/index.html +++ b/previews/PR662/index.html @@ -1,3 +1,3 @@ -GenX: Introduction · GenX
-

Welcome to the GenX documentation!

What is GenX?

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.

The model was originally developed by Jesse D. Jenkins and Nestor A. Sepulveda at the Massachusetts Institute of Technology and is now jointly maintained by a team of contributors at the Princeton University ZERO Lab (led by Jenkins), MIT (led by Ruaridh MacDonald), and NYU (led by Dharik Mallapragada).

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.

Uses

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.

Roadmap of the Documentation: A Guide for the Users and Developers

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 Reference Public 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 Extension Additional 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 Docs How 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.

How to cite GenX

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.

Acknowledgement

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.

License

GenX is released under the General Public License, GPL-2.0

Index

+GenX: Introduction · GenX.jl
+

Welcome to the GenX documentation!

What is GenX?

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.

The model was originally developed by Jesse D. Jenkins and Nestor A. Sepulveda at the Massachusetts Institute of Technology and is now jointly maintained by a team of contributors at the Princeton University ZERO Lab (led by Jenkins), MIT (led by Ruaridh MacDonald), and NYU (led by Dharik Mallapragada).

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.

Uses

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.

Roadmap of the Documentation: A Guide for the Users and Developers

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 Reference Public 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 Extension Additional 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 Docs How 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.

How to cite GenX

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.

Acknowledgement

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.

License

GenX is released under the General Public License, GPL-2.0

Index

diff --git a/previews/PR662/installation/index.html b/previews/PR662/installation/index.html index fe3d33296c..fa2bb893c5 100644 --- a/previews/PR662/installation/index.html +++ b/previews/PR662/installation/index.html @@ -1,2 +1,2 @@ -Installation Guide · GenX

Installation Guide

This guide will walk you through the steps to install Julia, the GenX package, and the required dependencies to run GenX.

Installing Julia

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.

Downloading GenX and installing dependencies

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.

Creating the Julia environment and installing dependencies: Steps 2-4 Figure 1. Creating the Julia environment and installing dependencies from Project.toml file from inside the GenX folder.

Creating the Julia environment and installing dependencies: Step 5 Figure 2. Creating the Julia environment and installing dependencies from Project.toml file from inside the GenX folder: Step 5

Installing solvers

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:

  1. HiGHS for linear programming and MILP (default solver)
  2. Clp for linear programming (LP) problems
  3. Cbc for mixed integer linear programming (MILP) problems

We also provide the option to use one of these two commercial solvers:

  1. Gurobi
  2. CPLEX.
Note on commercial solvers

Using Gurobi and CPLEX requires a valid license on the host machine.

Notes on previous versions of GenX

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.

+Installation Guide · GenX.jl

Installation Guide

This guide will walk you through the steps to install Julia, the GenX package, and the required dependencies to run GenX.

Installing Julia

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.

Downloading GenX and installing dependencies

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.

Creating the Julia environment and installing dependencies: Steps 2-4 Figure 1. Creating the Julia environment and installing dependencies from Project.toml file from inside the GenX folder.

Creating the Julia environment and installing dependencies: Step 5 Figure 2. Creating the Julia environment and installing dependencies from Project.toml file from inside the GenX folder: Step 5

Installing solvers

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:

  1. HiGHS for linear programming and MILP (default solver)
  2. Clp for linear programming (LP) problems
  3. Cbc for mixed integer linear programming (MILP) problems

We also provide the option to use one of these two commercial solvers:

  1. Gurobi
  2. CPLEX.
Note on commercial solvers

Using Gurobi and CPLEX requires a valid license on the host machine.

Notes on previous versions of GenX

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.

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

Limitations of the GenX Model

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.

1. Time period

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.

2. Cost

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.

3.Market

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.

4. Technology

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.

5. Uncertainty

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.

6. Decision-making

GenX assumes rational decision making, with perfect information and perfect foresight, and simultaneously optimizes all decisions over the user-specified time horizon.

7. Demand

GenX assumes price-elastic demand segments that are represented using piece-wise approximation rather than an inverse demand curve to keep the model linear.

+Limitation of GenX · GenX.jl

Limitations of the GenX Model

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.

1. Time period

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.

2. Cost

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.

3.Market

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.

4. Technology

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.

5. Uncertainty

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.

6. Decision-making

GenX assumes rational decision making, with perfect information and perfect foresight, and simultaneously optimizes all decisions over the user-specified time horizon.

7. Demand

GenX assumes price-elastic demand segments that are represented using piece-wise approximation rather than an inverse demand curve to keep the model linear.

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

pygenx: Python interface for 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.

Simple GenX Case Runner: For automated sequential batch run for GenX

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

Bug and feature requests and contact info

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).

+Third Party Extensions · GenX.jl

pygenx: Python interface for 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.

Simple GenX Case Runner: For automated sequential batch run for GenX

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

Bug and feature requests and contact info

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).