Skip to content

Commit

Permalink
Merge branch 'feature-docs' of github.com:lbonaldo/GenX into feature-…
Browse files Browse the repository at this point in the history
…docs
  • Loading branch information
sambuddhac committed Mar 13, 2024
2 parents 979fc21 + 9008d1e commit 52f1f4d
Show file tree
Hide file tree
Showing 15 changed files with 44 additions and 40 deletions.
4 changes: 2 additions & 2 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ pages = OrderedDict(
"Commertial solvers" => "Getting_Started/commercial_solvers.md",
],
"Tutorials" => [
"Tutorials Overview" => "Tutorials/tutorials_intro.md",
"Tutorials Overview" => "Tutorials/Tutorials_intro.md",
"Tutorial 1: Configuring Settings" => "Tutorials/Tutorial_1_configuring_settings.md",
"Tutorial 2: Network Visualization" => "Tutorials/Tutorial_2_network_visualization.md",
"Tutorial 3: K-Means and Time Domain Reduction" => "Tutorials/tutorial_3/Tutorial_3_K-means_time_domain_reduction.md",
"Tutorial 3: K-Means and Time Domain Reduction" => "Tutorials/Tutorial_3_K-means_time_domain_reduction.md",
"Tutorial 4: Model Generation" => "Tutorials/Tutorial_4_model_generation.md",
"Tutorial 5: Solving the Model" => "Tutorials/Tutorial_5_solve_model.md",
"Tutorial 6: Post Processing" => "Tutorials/Tutorial_6_solver_settings.md",
Expand Down
19 changes: 8 additions & 11 deletions docs/src/Tutorials/Tutorial_1_configuring_settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,7 @@ 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
Expand All @@ -57,7 +55,7 @@ genx_settings_SNE = YAML.load(open("example_systems/1_three_zones/settings/genx_
"MinCapReq" => 1
"CO2Cap" => 2
"WriteShadowPrices" => 1

```


Since all settings have defaults, you only need to specify the settings you would like to change. In fact, you can leave your settings file completely blank and it will still run! Let's try editing `genx_settings` in `SmallNewEngland/OneZone` to contain no parameters:
Expand All @@ -81,6 +79,7 @@ Now, we run GenX and output the file `capacity.csv` from the `Results` folder. T
include("example_systems/1_three_zones/Run.jl")
```

```
Configuring Settings
Configuring Solver
Loading Inputs
Expand All @@ -90,13 +89,11 @@ include("example_systems/1_three_zones/Run.jl")
Fuels_data.csv Successfully Read!
[ Info: Thermal.csv Successfully Read.
[ Info: Vre.csv Successfully Read.
[ Info: Storage.csv Successfully Read.
[ Info: Resource_minimum_capacity_requirement.csv Successfully Read.

[ Info: Thermal.csv Successfully Read.
[ Info: Vre.csv Successfully Read.
[ Info: Storage.csv Successfully Read.
[ Info: Resource_minimum_capacity_requirement.csv Successfully Read.

Summary of resources loaded into the model:
-------------------------------------------------------
Resource type Number of resources
Expand Down Expand Up @@ -124,7 +121,7 @@ include("example_systems/1_three_zones/Run.jl")
Storage Core Resources Module
Storage Resources with Symmetric Charge/Discharge Capacity Module
Thermal (No Unit Commitment) Resources Module

```


```julia
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ A good tool to reduce computation time of GenX is to use [Time Domain Reduction
* [Extreme Periods](#ExtPeriods)
* [Objective Values and Representative Periods](#ObjVals)

### Time Domain Reduction <a id="TDR"></a>
### Time Domain Reduction

To see how Time Domain Reduction works, let's look at the `Doad_data` in `example_systems/1_three_zones`:

Expand Down Expand Up @@ -55,6 +55,7 @@ When TDR is used, the file `time_domain_reduction_settings.yml` is called with a

```julia
time_domain_reduction_settings = YAML.load(open(joinpath(case,"settings/time_domain_reduction_settings.yml")))
```
```
Dict{Any, Any} with 15 entries:
"IterativelyAddPeriods" => 1
Expand All @@ -72,27 +73,28 @@ time_domain_reduction_settings = YAML.load(open(joinpath(case,"settings/time_dom
"ScalingMethod" => "S"
"ClusterMethod" => "kmeans"
"WeightTotal" => 8760
```

Important here to note are `MinPeriods` and `MaxPeriods`. As TDR is performed, it is required to keep the number of representative periods to be between the min and max specified in the settings. This is to ensure that computation time is actually decreased and that the k-means algorithm doesn't just form one large cluster of all points. Additionally, `TimestepsPerRepPeriod` is set to 168, the number of hours in a week (`WeightTotal` includes all 8,760 timesteps, the number of hours in a year.) By specifying the number of timesteps in each representative period to be a week, we form 52 clusters from which the algorithm will choose 8-11.

For descriptions of all settings, see [`cluster_inputs`](@ref) in the documentation.

Now back to pre-TDR. Below shows the load per timestep in megawatts for the entire dataset, i.e. with only one representative period of 8760 hours. This is done for Zone 1:


```julia
loads |>
@vlplot(:line,
x=:Time_Index, y=:Demand_MW_z1, title="MW Load per hour, No TDR",
width=600,height=400,linewidth=.01)
```

![svg](output_14_0.svg)
![svg](./files/output_14_0.svg)

As in Tutorial 1, we can open the `genx_settings.yml` file for `1_three_zones` to see how `TimeDomainReduction` is set. If it's set to 1, this means TDR is being used.
As in [Tutorial 1: Configuring Settings](@ref), we can open the `genx_settings.yml` file for `1_three_zones` to see how `TimeDomainReduction` is set. If it's set to 1, this means TDR is being used.

```julia
genx_settings_TZ = YAML.load(open((joinpath(case,"settings/genx_settings.yml"))))
```
```
Dict{Any, Any} with 19 entries:
"NetworkExpansion" => 1
Expand All @@ -114,7 +116,7 @@ genx_settings_TZ = YAML.load(open((joinpath(case,"settings/genx_settings.yml")))
"MinCapReq" => 1
"CO2Cap" => 2
"WriteShadowPrices" => 1

```

To visualize how TDR decreases computation time, let's start by running `SmallNewEngland/OneZone` without TDR. In the third section of this tutorial, we'll run the example again using TDR.

Expand Down Expand Up @@ -461,9 +463,9 @@ recon_noex[!,:MW] = convert.(Float64,recon_noex[!,:MW]);

### Objective Values and Representative Periods

Each time `Run.jl` is run, a `Results` folder is produced. This folder contains numerous .csv files with output variable from the GenX model. For more information on all outputs, see the documentation <a href="https://genxproject.github.io/GenX/dev/data_documentation/#Outputs" target="_blank">here</a>.
Each time `Run.jl` is run, a `Results` folder is produced. This folder contains numerous .csv files with output variable from the GenX model. For more information on all outputs, see the documentation [here](https://genxproject.github.io/GenX/dev/data_documentation/#Outputs).

This section focuses on the __objective value__ of the model. In optimization problems, the objective value is the main value minimized or maximized within the constraints of the model, according to the __objective function__ specified in the problem formulation. In the case of GenX, the objective function is the total annual electricity system cost. A detailed description of the optimization problem is <a href="https://genxproject.github.io/GenX/dev/objective_function/" target="_blank">here</a> in the documentation.
This section focuses on the __objective value__ of the model. In optimization problems, the objective value is the main value minimized or maximized within the constraints of the model, according to the __objective function__ specified in the problem formulation. In the case of GenX, the objective function is the total annual electricity system cost. A detailed description of the optimization problem is [here](https://genxproject.github.io/GenX/dev/objective_function/) in the documentation.

For the purpose of this tutorial, we focus on the objective value as a way to evaluate how well the representative periods actually "represent" the entire model. To see how well the objective value of representative periods aligns with that of the total period, we can run `SmallNewEngland/OneZone` with a variety of minimum and maximum total periods.

Expand Down
41 changes: 21 additions & 20 deletions docs/src/Tutorials/Tutorial_4_model_generation.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ Setup includes the settings from `genx_settings.yml` along with the default sett
genx_settings = GenX.get_settings_path(case, "genx_settings.yml") # Settings YAML file path
setup = GenX.configure_settings(genx_settings) # Combines genx_settings with defaults not specified in the file
```

```
Configuring Settings
Dict{Any, Any} with 24 entries:
"NetworkExpansion" => 0
Expand All @@ -187,7 +187,7 @@ setup = GenX.configure_settings(genx_settings) # Combines genx_settings with def
"StorageLosses" => 1
"IncludeLossesInESR" => 0
"UCommit" => 2

```
It's here that we create the folder `TDR_Results` before generating the model. This occurs if TimeDomainReduction is set to 1 in the setup.


Expand All @@ -205,7 +205,7 @@ if setup["TimeDomainReduction"] == 1
end
end
```

```
Clustering Time Series Data (Grouped)...
Reading Input CSV Files
Network.csv Successfully Read!
Expand All @@ -223,15 +223,15 @@ end
Dict{String, Any} with 9 entries:
"RMSE" => Dict("Load_MW_z1"=>1100.54, "NG"=>0.312319, "onshore_wind_…
"OutputDF" => [1m1848×9 DataFrame[0m[0m
"OutputDF" => DataFrame…
"ColToZoneMap" => Dict("Load_MW_z1"=>1, "battery_z1"=>1, "natural_gas_combin…
"ClusterObject" => KmeansResult{Matrix{Float64}, Float64, Int64}([-1.38728 -1…
"TDRsetup" => Dict{Any, Any}("IterativelyAddPeriods"=>1, "ExtremePeriods…
"Assignments" => [1, 1, 1, 1, 2, 2, 2, 2, 2, 3 … 6, 4, 3, 5, 5, 9, 10, 10…
"InputDF" => [1m672×49 DataFrame[0m[0m…
"InputDF" => [672×49 DataFrame
"Weights" => [673.846, 1010.77, 673.846, 842.308, 842.308, 1853.08, 185…
"Centers" => Any[1, 7, 12, 15, 23, 24, 28, 29, 48, 50, 51]

```


The optimizer argument is taken from setup:
Expand All @@ -256,7 +256,7 @@ The "inputs" argument is generated by the function `load_inputs` from the case i
```julia
inputs = GenX.load_inputs(setup, case)
```

```
Reading Input CSV Files
Network.csv Successfully Read!
Load_data.csv Successfully Read!
Expand All @@ -276,7 +276,7 @@ inputs = GenX.load_inputs(setup, case)
"LOSS_LINES" => [1]
"RET_CAP_CHARGE" => Int64[]
"pC_D_Curtail" => [50.0]
"dfGen" => [1m4×68 DataFrame[0m[0m…
"dfGen" => [4×68 DataFram
"pTrans_Max_Possible" => [2.95]
"pNet_Map" => [1.0;;]
"omega" => [4.01099, 4.01099, 4.01099, 4.01099, 4.01099, 4.0109…
Expand All @@ -298,7 +298,7 @@ inputs = GenX.load_inputs(setup, case)
"TRANS_LOSS_SEGS" => 1
"H" => 168
⋮ => ⋮

```

Now that we have our arguments, we're ready to generate the model itself.

Expand Down Expand Up @@ -343,10 +343,10 @@ Next, the dummy variable vZERO, the objective function, the power balance expres
# Initialize Total Generation per Zone
@expression(EP, eGenerationByZone[z=1:Z, t=1:T], 0)
```

```
1×1848 Matrix{Int64}:
0 0 0 0 0 0 0 0 0 0 0 0 0 … 0 0 0 0 0 0 0 0 0 0 0 0

```
Next, we go through some of the settings in setup and, if they've been set to be utilized (i.e. have a nonzero value), define expressions from their corresponding input files:


Expand All @@ -366,16 +366,17 @@ end
if setup["MaxCapReq"] == 1
@expression(EP, eMaxCapRes[maxcap = 1:inputs["NumberOfMaxCapReqs"]], 0)
end
```
```
3-element Vector{Int64}:
0
0
0

```

The other settings will be used later on.

Next, we define the model infrastructure using functions found in `src/core`. These take entries from inputs and setup to create more expressions in our model (EP). To see what the functions do in more detail, see the source code and <a href="https://genxproject.github.io/GenX/dev/core/#Discharge" target="_blank">core documentation</a>.
Next, we define the model infrastructure using functions found in `src/core`. These take entries from inputs and setup to create more expressions in our model (EP). To see what the functions do in more detail, see the source code and [core documentation](https://genxproject.github.io/GenX/dev/core/#Discharge).


```julia
Expand All @@ -400,13 +401,13 @@ if Z > 1
GenX.transmission!(EP, inputs, setup)
end
```

```
Discharge Module
Non-served Energy Module
Investment Discharge Module
Unit Commitment Module
Emissions Module (for CO2 Policy modularization

```

We then define variables and expressions based on the resources in the inputs and setup arguments. The details of these can be found in the `src/resources` folder and the "resources" folder under Model Function Reference in the documentation:

Expand Down Expand Up @@ -456,7 +457,7 @@ end

```

Finally, we define expressions and variables using policies outlined in the inputs. These functions can be found in `src/policies` and in the <a href="https://genxproject.github.io/GenX/dev/policies/" target="_blank">policies documentation</a>:
Finally, we define expressions and variables using policies outlined in the inputs. These functions can be found in `src/policies` and in the [policies documentation](https://genxproject.github.io/GenX/dev/policies/):


```julia
Expand Down Expand Up @@ -490,7 +491,7 @@ if setup["MaxCapReq"] == 1
end

```

```
Energy Share Requirement Policies Module
Capacity Reserve Margin Policies Module
Minimum Capacity Requirement Module
Expand All @@ -501,7 +502,7 @@ end
cZoneMaxCapReq[2] : -vRETCAP[3] + vCAP[3] ≤ 100
cZoneMaxCapReq[3] : -vRETCAP[4] + vCAP[4] ≤ 60

```

The expressions and variables for the model have all been defined! All that's left to do is define the constraints and objective function.

Expand All @@ -526,7 +527,7 @@ Our constraint is the [Power Balance](@ref), which is set here to have to meet t
@constraint(EP, cPowerBalance[t=1:T, z=1:Z], EP[:ePowerBalance][t,z] == inputs["pD"][t,z])

```

```
1848×1 Matrix{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}, ScalarShape}}:
cPowerBalance[1,1] : vP[2,1] + vP[3,1] + vP[4,1] + vNSE[1,1,1] - vCHARGE[4,1] = 11.162
cPowerBalance[2,1] : vP[2,2] + vP[3,2] + vP[4,2] + vNSE[1,2,1] - vCHARGE[4,2] = 10.556
Expand Down Expand Up @@ -554,7 +555,7 @@ Our constraint is the [Power Balance](@ref), which is set here to have to meet t
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.
File renamed without changes.
Binary file removed docs/src/Tutorials/files/Julia.png
Binary file not shown.
Binary file removed docs/src/Tutorials/files/addGenX.png
Binary file not shown.
Binary file removed docs/src/Tutorials/files/addIJulia.png
Binary file not shown.
Binary file removed docs/src/Tutorials/files/jupyter_screen.png
Binary file not shown.
Binary file removed docs/src/Tutorials/files/opennotebook.png
Binary file not shown.
File renamed without changes
Binary file removed docs/src/Tutorials/files/us_outline.png
Binary file not shown.
Binary file removed docs/src/Tutorials/files/usingIJulia.png
Binary file not shown.
Binary file removed docs/src/Tutorials/tutorial_3/output_14_0.png
Binary file not shown.
4 changes: 4 additions & 0 deletions docs/src/User_Guide/multi_stage_input.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ The table below summarizes the key differences in the two model setups.
| Objective function cost basis | Net present value | Annualized costs |
| Price/dual variable information available? | No | Yes |


### Additional inputs needed for multi-stage modeling

#### Input data files
Expand Down Expand Up @@ -58,6 +59,9 @@ Instead of one set of input files, there is one directory of input files that ne
| WACC | The line-specific weighted average cost of capital. |


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

Expand Down

0 comments on commit 52f1f4d

Please sign in to comment.