Skip to content

Commit

Permalink
Merge pull request #680 from sambuddhac/release/0.4.0
Browse files Browse the repository at this point in the history
Refined DF Calculation in DDP for more general Expression for addressing variable length stages
  • Loading branch information
sambuddhac authored May 5, 2024
2 parents 21b4885 + 5f02720 commit 13cbfa4
Show file tree
Hide file tree
Showing 3 changed files with 19 additions and 5 deletions.
7 changes: 5 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
non-zero in multi-stage GenX (#666)
- Added condition number scaling added to objective function (#667)
- Added versioned doc-pages for v0.3.6 and v0.4.0

- Added a warning message in write_costs_multistage mentioning th approximate value of costs currently.

### Fixed
- Add constraint in mga to compute total capacity in each zone from a given technology type (#681)
- New settings parameter MGAAnnualGeneration to switch between different MGA formulations (#681)
- Add validation for `Can_Retire` column in multi-stage GenX since the current implementation
Expand All @@ -51,8 +55,6 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Add writing of multistage stats during optimization with foresight (#687)
- Fix docstring in operational_reserves.jl (#690)
- Fix docstring in energy_share_requirement.jl (#692)

### Fixed
- Set MUST_RUN=1 for RealSystemExample/small_hydro plants (#517).
Previously these plants had no resource flag set, and so they did not contribute to the power balance.
As these plants are now useful, the objective in these cases is slightly lower.
Expand All @@ -73,6 +75,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Fixed outputting capital recovery cost to 0 if the remaining number of years is 0 (#666)
- Updated the docstring for the initialize_cost_to_go function and adjusted the formula for the discount factor to reflect the code implementation (#672).
- Fix write_multi_stage_cost.jl: add discount with OPEX multipliers to cUnmetPolicyPenalty (#679)
- Fix DF calculation in DDP to make it more generic for variable length stages (#680)
- Fix write_power_balance.jl: add additional two columns ("VRE_Storage_Discharge" and "VRE_Storage_Charge") for VRE_STOR

### Changed
Expand Down
8 changes: 6 additions & 2 deletions src/multi_stage/dual_dynamic_programming.jl
Original file line number Diff line number Diff line change
Expand Up @@ -560,7 +560,7 @@ The updated objective function $OBJ^{*}$ returned by this method takes the form:
where $OBJ$ is the original objective function. $OBJ$ is scaled by two terms. The first is a discount factor (applied only in the non-myopic case), which discounts costs associated with the model stage $p$ to year-0 dollars:
```math
\begin{aligned}
DF = \frac{1}{(1+WACC)^{L_{p}*(p-1)}}
DF = \frac{1}{(1+WACC)^{\sum^{(p-1)}_{k=0}L_{k}}}
\end{aligned}
```
where $WACC$ is the weighted average cost of capital, and $L_{p}$ is the length of each stage in years (both set in multi\_stage\_settings.yml)
Expand All @@ -584,6 +584,10 @@ returns: JuMP model with updated objective function.
"""
function initialize_cost_to_go(settings_d::Dict, EP::Model, inputs::Dict)
cur_stage = settings_d["CurStage"] # Current DDP Investment Planning Stage
cum_years = 0
for stage_count in 1:(cur_stage-1)
cum_years += settings_d["StageLengths"][stage_count]
end
stage_len = settings_d["StageLengths"][cur_stage]
wacc = settings_d["WACC"] # Interest Rate and also the discount rate unless specified other wise
myopic = settings_d["Myopic"] == 1 # 1 if myopic (only one forward pass), 0 if full DDP
Expand All @@ -596,7 +600,7 @@ function initialize_cost_to_go(settings_d::Dict, EP::Model, inputs::Dict)
### No discount factor or OPEX multiplier applied in myopic case as costs are left annualized.
@objective(EP, Min, EP[:eObj])
else
DF = 1 / (1 + wacc)^(stage_len * (cur_stage - 1)) # Discount factor applied all to costs in each stage ###
DF = 1 / (1 + wacc)^(cum_years) # Discount factor applied all to costs in each stage ###
# Initialize the cost-to-go variable
@variable(EP, vALPHA>=0)
@objective(EP, Min, DF * OPEXMULT * EP[:eObj]+vALPHA)
Expand Down
9 changes: 8 additions & 1 deletion src/multi_stage/write_multi_stage_costs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,13 @@ function write_multi_stage_costs(outpath::String, settings_d::Dict, inputs_dict:
if myopic
DF = 1 # DF=1 because we do not apply discount factor in myopic case
else
DF = 1 / (1 + wacc)^(stage_lens[p] * (p - 1)) # Discount factor applied to ALL costs in each stage
cum_stage_length = 0
if p > 1
for stage_counter in 1:(p - 1)
cum_stage_length += stage_lens[stage_counter]
end
end
DF = 1 / (1 + wacc)^(cum_stage_length) # Discount factor applied to ALL costs in each stage
end
df_costs[!, Symbol("TotalCosts_p$p")] = DF .* costs_d[p][!, Symbol("Total")]
end
Expand All @@ -45,6 +51,7 @@ function write_multi_stage_costs(outpath::String, settings_d::Dict, inputs_dict:

# Remove "cTotal" from results (as this includes Cost-to-Go)
df_costs = df_costs[df_costs[!, :Costs] .!= "cTotal", :]
@warn("The cost calculation of the multi-stage GenX is approximate currently, and we will be refining it more in one of the future releases.")

CSV.write(joinpath(outpath, "costs_multi_stage.csv"), df_costs)
end

0 comments on commit 13cbfa4

Please sign in to comment.