Skip to content

Commit

Permalink
Merge branch 'develop' into outages-results
Browse files Browse the repository at this point in the history
  • Loading branch information
Bill-Becker committed Sep 23, 2023
2 parents 5dbfb71 + a098439 commit 23b2967
Show file tree
Hide file tree
Showing 9 changed files with 166,843 additions and 100 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ Classify the change according to the following categories:
### Deprecated
### Removed

## v0.33.0
### Added
- Functionality to evaluate scenarios with Wind can in the ERP (`backup_reliability`)
### Changed
- Updated REopt license

## v0.32.7
### Fixed
- Bugs in EASIUR health cost calcs
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "REopt"
uuid = "d36ad4e8-d74a-4f7a-ace1-eaea049febf6"
authors = ["Nick Laws", "Hallie Dunham <[email protected]>", "Bill Becker <[email protected]>", "Bhavesh Rathod <[email protected]>", "Alex Zolan <[email protected]>", "Amanda Farthing <[email protected]>"]
version = "0.32.6"
version = "0.33.0"

[deps]
ArchGDAL = "c9ce4bd3-c3d5-55b8-8973-c0e20141b8c3"
Expand Down
3 changes: 2 additions & 1 deletion src/core/utils.jl
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,8 @@ function dictkeys_tosymbols(d::Dict)
"emissions_factor_series_lb_SO2_per_kwh",
"emissions_factor_series_lb_PM25_per_kwh",
#for ERP
"pv_production_factor_series", "battery_starting_soc_series_fraction",
"pv_production_factor_series", "wind_production_factor_series",
"battery_starting_soc_series_fraction",
"monthly_mmbtu", "monthly_tonhour"
] && !isnothing(v)
try
Expand Down
151 changes: 106 additions & 45 deletions src/outagesim/backup_reliability.jl

Large diffs are not rendered by default.

10 changes: 5 additions & 5 deletions src/results/wind.jl
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,18 @@ function add_wind_results(m::JuMP.AbstractModel, p::REoptInputs, d::Dict; _n="")
r["year_one_om_cost_before_tax"] = round(value(per_unit_size_om) / (p.pwf_om * p.third_party_factor), digits=0)

if !isempty(p.s.storage.types.elec)
WindToStorage = @expression(m, [ts in p.time_steps],
sum(m[:dvProductionToStorage][b, t, ts] for b in p.s.storage.types.elec))
WindToStorage = (sum(m[:dvProductionToStorage][b, t, ts] for b in p.s.storage.types.elec) for ts in p.time_steps)
PVtoBatt = (sum(m[Symbol("dvProductionToStorage"*_n)][b, t, ts] for b in p.s.storage.types.elec) for ts in p.time_steps)

else
WindToStorage = zeros(length(p.time_steps))
end
r["electric_to_storage_series_kw"] = round.(value.(WindToStorage), digits=3)

r["annual_energy_exported_kwh"] = 0.0
if !isempty(p.s.electric_tariff.export_bins)
WindToGrid = @expression(m, [ts in p.time_steps],
sum(m[:dvProductionToGrid][t, u, ts] for u in p.export_bins_by_tech[t]))
r["electric_to_grid_series_kw"] = round.(value.(WindToGrid), digits=3).data
WindToGrid = (sum(m[:dvProductionToGrid][t, u, ts] for u in p.export_bins_by_tech[t]) for ts in p.time_steps)
r["electric_to_grid_series_kw"] = round.(value.(WindToGrid), digits=3)
r["annual_energy_exported_kwh"] = round(
sum(r["electric_to_grid_series_kw"]) * p.hours_per_time_step, digits=0)
else
Expand Down
28 changes: 17 additions & 11 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -340,7 +340,6 @@ else # run HiGHS tests
"battery_operational_availability" => 1.0,
"battery_minimum_soc_fraction" => 0.0,
"battery_starting_soc_series_fraction" => results["ElectricStorage"]["soc_series_fraction"],
"pv_operational_availability" => 1.0,
"critical_loads_kw" => results["ElectricLoad"]["critical_load_series_kw"]#4000*ones(8760)#p.s.electric_load.critical_loads_kw
)
reliability_results = backup_reliability(reliability_inputs)
Expand All @@ -352,7 +351,7 @@ else # run HiGHS tests
@test simresults["probs_of_surviving"][i] reliability_results["mean_fuel_survival_by_duration"][i] atol=0.01
end

# Second, gen, PV, battery
# Second, gen, PV, Wind, battery
reopt_inputs = JSON.parsefile("./scenarios/backup_reliability_reopt_inputs.json")
reopt_inputs["ElectricLoad"]["annual_kwh"] = 4*reopt_inputs["ElectricLoad"]["annual_kwh"]
p = REoptInputs(reopt_inputs)
Expand All @@ -370,6 +369,7 @@ else # run HiGHS tests
"battery_operational_availability" => 1.0,
"battery_minimum_soc_fraction" => 0.0,
"pv_operational_availability" => 1.0,
"wind_operational_availability" => 1.0
)
reliability_results = backup_reliability(results, p, reliability_inputs)
for i = 1:min(length(simresults["probs_of_surviving"]), reliability_inputs["max_outage_duration"])
Expand Down Expand Up @@ -488,33 +488,39 @@ else # run HiGHS tests
reliability_results = backup_reliability(input_dict)
@test reliability_results["unlimited_fuel_mean_cumulative_survival_by_duration"][24] (0.99^20)*(0.9*0.98) atol=0.00001

#More realistic case of hospital load with 2 generators, PV, and battery
#More complex case of hospital load with 2 generators, PV, wind, and battery
reliability_inputs = JSON.parsefile("./scenarios/backup_reliability_inputs.json")
reliability_results = backup_reliability(reliability_inputs)
@test reliability_results["unlimited_fuel_cumulative_survival_final_time_step"][1] 0.858756 atol=0.0001
@test reliability_results["cumulative_survival_final_time_step"][1] 0.858756 atol=0.0001
@test reliability_results["mean_cumulative_survival_final_time_step"] 0.904242 atol=0.0001#0.833224


# Test gens+pv+wind+batt with 3 arg version of backup_reliability
# Attention! REopt optimization results are presaved in erp_gens_batt_pv_wind_reopt_results.json
# If you modify backup_reliability_reopt_inputs.json, you must add this before JSON.parsefile:
# results = run_reopt(model, p)
# open("scenarios/erp_gens_batt_pv_wind_reopt_results.json","w") do f
# JSON.print(f, results, 4)
# end
for input_key in [
"generator_size_kw",
"battery_size_kw",
"battery_size_kwh",
"pv_size_kw",
"wind_size_kw",
"critical_loads_kw",
"pv_production_factor_series"
"pv_production_factor_series",
"wind_production_factor_series"
]
delete!(reliability_inputs, input_key)
end

model = Model(optimizer_with_attributes(HiGHS.Optimizer,
"output_flag" => false, "log_to_console" => false)
)
# note: the wind prod series in backup_reliability_reopt_inputs.json is actually a PV profile (to in order to test a wind scenario that should give same results as an existing PV one)
p = REoptInputs("./scenarios/backup_reliability_reopt_inputs.json")
results = run_reopt(model, p)
results = JSON.parsefile("./scenarios/erp_gens_batt_pv_wind_reopt_results.json")
reliability_results = backup_reliability(results, p, reliability_inputs)

@test reliability_results["unlimited_fuel_cumulative_survival_final_time_step"][1] 0.802997 atol=0.0001
@test reliability_results["cumulative_survival_final_time_step"][1] 0.802997 atol=0.0001
@test reliability_results["mean_cumulative_survival_final_time_step"] 0.817586 atol=0.0001
@test reliability_results["mean_cumulative_survival_final_time_step"] 0.817586 atol=0.001
end
end
Loading

0 comments on commit 23b2967

Please sign in to comment.