diff --git a/CHANGELOG.md b/CHANGELOG.md index e2387f92dc..3792d38e89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,15 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## Unreleased +### Added +- Add objective scaler for addressing problem ill-conditioning (#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. @@ -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). @@ -73,10 +76,10 @@ 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`, @@ -84,7 +87,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New folder structure implemented for `example_system`. This folder now consists of nine separate folders each pertaining to a different case study example, ranging from the ISONE three zones, with singlestage, multistage, electrolyzers, all the way to the 9 bus IEEE case for running DC-OPF. - ### Deprecated - The above `load` keys, which generally refer to electrical demand, are being deprecated. Users should update their case files. @@ -138,7 +140,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 diff --git a/README.md b/README.md index b24402102e..f4eb78ce22 100644 --- a/README.md +++ b/README.md @@ -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 diff --git a/docs/make.jl b/docs/make.jl index dfd0340287..eeaa501c5b 100644 --- a/docs/make.jl +++ b/docs/make.jl @@ -128,6 +128,6 @@ deploydocs(; devbranch = "main", devurl = "dev", push_preview=true, - versions = ["stable" => "v^", "v#.#"], + versions = ["stable" => "v^", "v#.#.#", "dev" => "dev"], forcepush = false, ) diff --git a/docs/src/Model_Concept_Overview/objective_function.md b/docs/src/Model_Concept_Overview/objective_function.md index 94308431f8..53a8a29ed1 100644 --- a/docs/src/Model_Concept_Overview/objective_function.md +++ b/docs/src/Model_Concept_Overview/objective_function.md @@ -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} ``` @@ -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, @@ -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. \ No newline at end of file diff --git a/src/configure_settings/configure_settings.jl b/src/configure_settings/configure_settings.jl index 5d59a8a91b..8706c20b96 100644 --- a/src/configure_settings/configure_settings.jl +++ b/src/configure_settings/configure_settings.jl @@ -32,6 +32,7 @@ function default_settings() "ResourcePoliciesFolder" => "policy_assignments", "SystemFolder" => "system", "PoliciesFolder" => "policies", + "ObjScale" => 1, ) end @@ -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"] @@ -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" diff --git a/src/model/generate_model.jl b/src/model/generate_model.jl index b834773188..677fc7b03d 100644 --- a/src/model/generate_model.jl +++ b/src/model/generate_model.jl @@ -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) @@ -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)