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

Feat 13 welfare #147

Merged
merged 14 commits into from
May 31, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
Binary file added docs/e4st-website-2023-05-31.zip
Binary file not shown.
3 changes: 2 additions & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ makedocs(
],
"Results" => Any[
"Overview" => "results/overview.md",
"Aggregation" => "results/aggregation.md",
"Formulas" => "results/formulas.md",
"Results Modifications" => "results/modifications.md",
"Plotting" => "results/plotting.md",
],
"Abstract Types"=>Any[
Expand Down
16 changes: 0 additions & 16 deletions docs/src/results/aggregation.md

This file was deleted.

19 changes: 19 additions & 0 deletions docs/src/results/formulas.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
Results Formulas
================
E4ST.jl produces a lot of data to comb through. There are often some complex calculations for welfare that we may want to compute in different ways over different regions without necessarily storing every possible combination of every calculation. The goal of the results formula is to give E4ST a way to calculate different results so that they can be calculated quickly on demand rather than always be calculated for every run. It also provides a way to specify custom result calculations that might not be standard to E4ST.

```@docs
setup_results_formulas!
summarize_table(::Val{:results_formulas})
filter_results_formulas!
add_results_formula!
get_results_formulas
get_results_formula
compute_result
ResultsFormula
Sum
SumYearly
SumHourly
MinHourly
AverageYearly
```
6 changes: 6 additions & 0 deletions docs/src/results/modifications.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Results Modifications
===================
```@docs
AggregationTemplate
YearlyTable
```
8 changes: 8 additions & 0 deletions docs/src/results/overview.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
Results Overview
================
After optimizing the model, the following things happen:
* [`parse_results!`](@ref) is called, gathering all values and shadow prices from the JuMP Model into `data[:raw]`. The model is then emptied to free up memory. After running this, raw results can be accessed with:
* [`get_raw_result`](@ref) and [`get_raw_results`](@ref)
* results can now be computed using [`compute_result`](@ref)
* [`process_results!`](@ref) is called, which in turn calls [`modify_results!(mod, config, data)`] for each [`Modification`](@ref) in the config. Here are a couple of [`Modification`](@ref)s that write some handy results:
* [`YearlyTable`](@ref)
* [`AggregationTemplate`](@ref)


```@docs
parse_results!
Expand Down
3 changes: 3 additions & 0 deletions src/E4ST.jl
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ include("types/modifications/AggregationTemplate.jl")
include("types/modifications/GenerationConstraint.jl")
include("types/modifications/GenerationStandard.jl")
include("types/modifications/YearlyTable.jl")
include("types/modifications/WelfareTable.jl")
include("types/modifications/CCUS.jl")
include("types/modifications/Storage.jl")
include("types/modifications/Adjust.jl")
Expand Down Expand Up @@ -91,6 +92,8 @@ include("model/util.jl")
include("results/parse.jl")
include("results/process.jl")
include("results/aggregate.jl")
include("results/formulas.jl")
include("results/welfare.jl")
include("results/util.jl")


Expand Down
1 change: 1 addition & 0 deletions src/io/config.jl
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ function summarize_config()
(:summary_table_file, false, nothing, "a file for giving information about additional columns not specified in [`summarize_table`](@ref)"),
(:save_data, false, true, "A boolean specifying whether or not to save the loaded data to file for later use (i.e. by specifying a `data_file` for future simulations)."),
(:data_file, false, nothing, "The filepath (relative or absolute) to the data file (a serialized julia object). If this is provided, it will use this instead of loading data from all the other files."),
(:results_formulas_file, false, nothing, "The filepath (relative or absolute) to the results formulas file. See [`summarize_table(::Val{:results_formulas})`](@ref)"),
(:save_model_presolve, false, false, "A boolean specifying whether or not to save the model before solving it, for later use (i.e. by specifying a `model_presolve_file` for future sims). Defaults to `false`"),
(:model_presolve_file, false, nothing, "The filepath (relative or absolute) to the unsolved model. If this is provided, it will use this instead of creating a new model."),
(:save_data_parsed, false, true, "A boolean specifying whether or not to save the raw results after solving the model. This could be useful for calling [`process_results!(config)`](@ref) in the future. Defaults to `true`"),
Expand Down
9 changes: 7 additions & 2 deletions src/io/data.jl
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ function read_data!(config, data)
setup_data!(config, data)
modify_setup_data!(config, data)

setup_results_formulas!(config, data)
setup_welfare!(config, data)

# Save the data to file as specified.
if get(config, :save_data, true)
serialize(get_out_path(config, "data.jls"), data)
Expand Down Expand Up @@ -426,6 +429,8 @@ function setup_table!(config, data, ::Val{:gen})

# Set the pcap_max to be equal to pcap0 for built generators
gen.pcap_max = map(row->isbuilt(row) ? row.pcap0 : row.pcap_max, eachrow(gen))
gen.pcap0 = map(row->isbuilt(row) ? row.pcap0 : 0.0, eachrow(gen))


### Create new gens and add to the gen table
if haskey(config, :build_gen_file)
Expand Down Expand Up @@ -658,7 +663,7 @@ function summarize_table(::Val{:gen})
(:vom, Float64, DollarsPerMWhGenerated, true, "Variable operation and maintenance cost per MWh of generation"),
(:fuel_price, Float64, DollarsPerMMBtu, false, "Fuel cost per MMBtu of fuel used. `heat_rate` column also necessary when supplying `fuel_price`"),
(:heat_rate, Float64, MMBtuPerMWhGenerated, false, "Heat rate, or MMBtu of fuel consumed per MWh electricity generated (0 for generators that don't use combustion)"),
(:fom, Float64, DollarsPerMWCapacity, true, "Hourly fixed operation and maintenance cost for a MW of generation capacity"),
(:fom, Float64, DollarsPerMWCapacityPerHour, true, "Hourly fixed operation and maintenance cost for a MW of generation capacity"),
(:capex, Float64, DollarsPerMWBuiltCapacity, false, "Hourly capital expenditures for a MW of generation capacity"),
(:cf_min, Float64, MWhGeneratedPerMWhCapacity, false, "The minimum capacity factor, or operable ratio of power generation to capacity for the generator to operate. Take care to ensure this is not above the hourly availability factor in any of the hours, or else the model may be infeasible. Set to zero by default."),
(:cf_max, Float64, MWhGeneratedPerMWhCapacity, false, "The maximum capacity factor, or operable ratio of power generation to capacity for the generator to operate"),
Expand Down Expand Up @@ -756,7 +761,7 @@ function summarize_table(::Val{:build_gen})
(:pcap_max, Float64, MWCapacity, true, "Maximum nameplate power generation capacity of the generator"),
(:vom, Float64, DollarsPerMWhGenerated, true, "Variable operation and maintenance cost per MWh of generation"),
(:fuel_price, Float64, DollarsPerMMBtu, false, "Fuel cost per MMBtu of fuel used. `heat_rate` column also necessary when supplying `fuel_price`"),
(:fom, Float64, DollarsPerMWCapacity, true, "Hourly fixed operation and maintenance cost for a MW of generation capacity"),
(:fom, Float64, DollarsPerMWCapacityPerHour, true, "Hourly fixed operation and maintenance cost for a MW of generation capacity"),
(:capex, Float64, DollarsPerMWBuiltCapacity, false, "Hourly capital expenditures for a MW of generation capacity"),
(:cf_min, Float64, MWhGeneratedPerMWhCapacity, false, "The minimum capacity factor, or operable ratio of power generation to capacity for the generator to operate. Take care to ensure this is not above the hourly availability factor in any of the hours, or else the model may be infeasible. Set to zero by default."),
(:cf_max, Float64, MWhGeneratedPerMWhCapacity, false, "The maximum capacity factor, or operable ratio of power generation to capacity for the generator to operate"),
Expand Down
13 changes: 13 additions & 0 deletions src/io/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -606,4 +606,17 @@ function sum0(f, itr)
return sum(f, itr)
end

function sum0(itr)
isempty(itr) && return 0.0
return sum(itr)
end

"""
anyany(f, v::AbstractVector{<:AbstractArray}) -> ::Bool

Returns whether any f(x) holds true for any value of each element of v.
"""
function anyany(f, v)
any(x->any(f, x), v)
end
export anyany
2 changes: 1 addition & 1 deletion src/model/dcopf.jl
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ function setup_dcopf!(config, data, model)
add_obj_term!(data, model, PerMWhGen(), :vom, oper = +)

# Only add fuel cost if included and non-zero.
if hasproperty(gen, :fuel_price) && any(gen.fuel_price[yr_idx, hr_idx] != 0 for yr_idx in 1:nyear, hr_idx in 1:nhour)
if hasproperty(gen, :fuel_price) && anyany(!=(0), gen.fuel_price)
add_obj_term!(data, model, PerMMBtu(), :fuel_price, oper = +)
end

Expand Down
2 changes: 1 addition & 1 deletion src/model/util.jl
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ function add_build_constraints!(data, model, table_name::Symbol, pcap_name::Symb
)
)
],
pcap[row_idx, yr_idx] == table.pcap0[row_idx]
pcap[row_idx, yr_idx] == table.pcap_max[row_idx]
)
end

Expand Down
Loading