Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scaler #667

Merged
merged 16 commits into from
Apr 3, 2024
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 16 additions & 13 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Added
- Add objective scaler (#667)

## [0.4.0] - 2024-03-18

### Added
- Feature CO2 and fuel module (#536)
Adds a fuel module which enables modeling of fuel usage via (1) a constant heat rate and (2)
piecewise-linear approximation of heat rate curves.
Adds a CO2 module that determines the CO2 emissions based on fuel consumption, CO2 capture
Adds a fuel module which enables modeling of fuel usage via (1) a constant heat rate and (2)
piecewise-linear approximation of heat rate curves.
Adds a CO2 module that determines the CO2 emissions based on fuel consumption, CO2 capture
fraction, and whether the feedstock is biomass.
- Enable thermal power plants to burn multiple fuels (#586)
- Enable thermal power plants to burn multiple fuels (#586)
- Feature electrolysis basic (#525)
Adds hydrogen electrolyzer model which enables the addition of hydrogen electrolyzer
demands along with optional clean supply constraints.
Expand All @@ -25,14 +28,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add PR template (#516)
- Validation ensures that resource flags (THERM, HYDRO, LDS etc) are self-consistent (#513).
- Maintenance formulation for thermal-commit plants (#556).
- Add new tests for GenX: three-zone, multi-stage, electrolyzer, VRE+storage,
- Add new tests for GenX: three-zone, multi-stage, electrolyzer, VRE+storage,
piecewise_fuel+CO2, and TDR (#563 and #578).
- Added a DC OPF method (#543) to calculate power flows across all lines
- Added write_operating_reserve_price_revenue.jl to compute annual operating reserve and regulation revenue.
Added the operating reserve and regulation revenue to net revenue (PR # 611)
- Add functions to compute conflicting constraints when model is infeasible if supported by the solver (#624).
- New settings parameter, VirtualChargeDischargeCost to test script and VREStor example case. The PR 608 attempts to
introduce this parameter as cost of virtual charging and discharging to avoid unusual results (#608).
- New settings parameter, VirtualChargeDischargeCost to test script and VREStor example case. The PR 608 attempts to
introduce this parameter as cost of virtual charging and discharging to avoid unusual results (#608).
- New settings parameter, StorageVirtualDischarge, to turn storage virtual charging and discharging off if desired by the user (#638).
- Add module to retrofit existing resources with new technologies (#600).

Expand Down Expand Up @@ -73,14 +76,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
This mitigates but does not fully fix (#576).
- Expressions of virtual charging and discharging costs in storage_all.jl and vre_stor.jl
- The input file `Generators_data.csv` has been split into different files, one for each type of generator.
The new files are: `Thermal.csv`, `Hydro.csv`, `Vre.csv`, `Storage.csv`, `Flex_demand.csv`, `Must_run.csv`,
`Electrolyzer.csv`, and `Vre_stor.csv`. The examples have been updated, and new tests have been added to
The new files are: `Thermal.csv`, `Hydro.csv`, `Vre.csv`, `Storage.csv`, `Flex_demand.csv`, `Must_run.csv`,
`Electrolyzer.csv`, and `Vre_stor.csv`. The examples have been updated, and new tests have been added to
check the new data format (#612).
- The settings parameter `Reserves` has been renamed to `OperationalReserves`, `Reserves.csv` to
- The settings parameter `Reserves` has been renamed to `OperationalReserves`, `Reserves.csv` to
`Operational_reserves.csv`, and the `.jl` files contain the word `reserves` have been renamed to
`operational_reserves` (#641).
- New folder structure for a GenX case. The input files are now organized in the following folders: `settings`,
`policies`, `resources` and `system`. The examples and tests have been updated to reflect this change.
- New folder structure for a GenX case. The input files are now organized in the following folders: `settings`,
`policies`, `resources` and `system`. The examples and tests have been updated to reflect this change.

### Deprecated
- The above `load` keys, which generally refer to electrical demand, are being deprecated.
Expand Down Expand Up @@ -135,7 +138,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Removed

- The settings key `OperationsWrapping`. Its functionality has now been folded into the
- The settings key `OperationsWrapping`. Its functionality has now been folded into the
`TimeDomainReduction` setting. Using the key now will print a gentle warning (#426).

## [0.3.4] - 2023-04-28
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

[![CI](https://github.com/GenXProject/GenX/actions/workflows/ci.yml/badge.svg)](https://github.com/GenXProject/GenX/actions/workflows/ci.yml)
[![Dev](https://img.shields.io/badge/docs-dev-blue.svg)](https://genxproject.github.io/GenX.jl/dev)
[![DOI](https://zenodo.org/badge/10814088.svg)](https://zenodo.org/badge/latestdoi/10814088)
[![DOI](https://zenodo.org/badge/368957308.svg)](https://zenodo.org/doi/10.5281/zenodo.10846069)
[![ColPrac: Contributor's Guide on Collaborative Practices for Community Packages](https://img.shields.io/badge/ColPrac-Contributor's%20Guide-blueviolet)](https://github.com/SciML/ColPrac)

## Overview
Expand Down Expand Up @@ -58,7 +58,7 @@ There are two ways to run GenX with either type of solver options (open-source f

## Documentation

Detailed documentation for GenX can be found [here](https://genxproject.github.io/GenX/dev).
Detailed documentation for GenX can be found [here](https://genxproject.github.io/GenX.jl/dev).
It includes details of each of GenX's methods, required and optional input files, and outputs.
Interested users may also want to browse through [prior publications](https://energy.mit.edu/genx/#publications) that have used GenX to understand the various features of the tool.

Expand Down
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,6 @@ deploydocs(;
devbranch = "main",
devurl = "dev",
push_preview=true,
versions = ["stable" => "v^", "v#.#"],
versions = ["stable" => "v^", "v#.#.#", "dev" => "dev"],
forcepush = false,
)
7 changes: 5 additions & 2 deletions docs/src/Model_Concept_Overview/objective_function.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ The objective function of GenX minimizes total annual electricity system costs o
& \sum_{y \in \mathcal{VS}^{sym,dc} \cup \mathcal{VS}^{asym,dc,dis}} \sum_{z \in \mathcal{Z}} \sum_{t \in \mathcal{T}} \left( \omega_{t}\times\pi^{VOM,dc,dis}_{y,z} \times\eta^{inverter}_{y,z} \times \Theta^{dc}_{y,z,t}\right) + \\
& \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)
& \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}
```

Expand Down Expand Up @@ -80,7 +80,7 @@ The eighteenth summation represents the variable O&M cost, $\pi^{VOM,wind}_{y,z}
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$.
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,
Expand All @@ -92,3 +92,6 @@ In summary, the objective function can be understood as the minimization of cost
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.

# Objective Scaling
Sometimes the model will be built into an ill form if some objective terms are quite large or small. To alleviate this problem, we could add a scaling factor to scale the objective function during solving while leaving all other expressions untouched. The default ```ObjScale``` is set to 1 which has no effect on objective. If you want to scale the objective, you can set the ```ObjScale``` to an appropriate value in the ```genx_settings.yml```. The objective function will be multiplied by the ```ObjScale``` value during the solving process.
5 changes: 3 additions & 2 deletions src/configure_settings/configure_settings.jl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ function default_settings()
"ResourcePoliciesFolder" => "policy_assignments",
"SystemFolder" => "system",
"PoliciesFolder" => "policies",
"ObjScale" => 1,
)
end

Expand Down Expand Up @@ -66,7 +67,7 @@ end
function validate_settings!(settings::Dict{Any,Any})
# Check for any settings combinations that are not allowed.
# If we find any then make a response and issue a note to the user.

# make WriteOutputs setting lowercase and check for valid value
settings["WriteOutputs"] = lowercase(settings["WriteOutputs"])
@assert settings["WriteOutputs"] ∈ ["annual", "full"]
Expand Down Expand Up @@ -144,7 +145,7 @@ function default_writeoutput()
end

function configure_writeoutput(output_settings_path::String, settings::Dict)

writeoutput = default_writeoutput()

# don't write files with hourly data if settings["WriteOutputs"] == "annual"
Expand Down
4 changes: 2 additions & 2 deletions src/model/generate_model.jl
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ function generate_model(setup::Dict,inputs::Dict,OPTIMIZER::MOI.OptimizerWithAtt

fuel!(EP, inputs, setup)

co2!(EP, inputs)
co2!(EP, inputs)

if setup["OperationalReserves"] > 0
operational_reserves!(EP, inputs, setup)
Expand Down Expand Up @@ -225,7 +225,7 @@ function generate_model(setup::Dict,inputs::Dict,OPTIMIZER::MOI.OptimizerWithAtt
end

## Define the objective function
@objective(EP,Min,EP[:eObj])
@objective(EP,Min, setup["ObjScale"] * EP[:eObj])

## Power balance constraints
# demand = generation + storage discharge - storage charge - demand deferral + deferred demand satisfaction - demand curtailment (NSE)
Expand Down