The REoptInputs structure
The REoptInputs structure uses the Scenario to build all of the data necessary to construct the JuMP mathematical model.
REoptInputs
REopt.REoptInputs — TypeREoptInputsThe data structure for all the inputs necessary to construct the JuMP model.
struct REoptInputs <: AbstractInputs
s::ScenarioType
techs::Techs
min_sizes::Dict{String, <:Real} # (techs)
max_sizes::Dict{String, <:Real} # (techs)
existing_sizes::Dict{String, <:Real} # (techs)
cap_cost_slope::Dict{String, Any} # (techs)
om_cost_per_kw::Dict{String, <:Real} # (techs)
cop::Dict{String, <:Real} # (techs.cooling)
thermal_cop::Dict{String, <:Real} # (techs.absorption_chiller)
time_steps::UnitRange
time_steps_with_grid::Array{Int, 1}
time_steps_without_grid::Array{Int, 1}
hours_per_time_step::Real
months::UnitRange
production_factor::DenseAxisArray{<:Real, 2} # (techs, time_steps)
levelization_factor::Dict{String, <:Real,} # (techs)
value_of_lost_load_per_kwh::Array{<:Real, 1}
pwf_e::Real
pwf_om::Real
pwf_fuel::Dict{String, <:Real}
pwf_emissions_cost::Dict{String, Float64} # Cost of emissions present worth factors for grid and onsite fuelburn emissions [unitless]
pwf_grid_emissions::Dict{String, Float64} # Emissions [lbs] present worth factors for grid emissions [unitless]
pwf_offtaker::Real
pwf_owner::Real
third_party_factor::Real
pvlocations::Array{Symbol, 1}
maxsize_pv_locations::DenseAxisArray{<:Real, 1} # indexed on pvlocations
pv_to_location::Dict{String, Dict{Symbol, Int64}} # (techs.pv, pvlocations)
ratchets::UnitRange
techs_by_exportbin::Dict{Symbol, AbstractArray} # keys can include [:NEM, :WHL, :CUR]
export_bins_by_tech::Dict
n_segs_by_tech::Dict{String, Int}
seg_min_size::Dict{String, Dict{Int, <:Real}}
seg_max_size::Dict{String, Dict{Int, <:Real}}
seg_yint::Dict{String, Dict{Int, <:Real}}
pbi_pwf::Dict{String, Any} # (pbi_techs)
pbi_max_benefit::Dict{String, Any} # (pbi_techs)
pbi_max_kw::Dict{String, Any} # (pbi_techs)
pbi_benefit_per_kwh::Dict{String, Any} # (pbi_techs)
boiler_efficiency::Dict{String, <:Real}
fuel_cost_per_kwh::Dict{String, AbstractArray} # Fuel cost array for all time_steps
ghp_options::UnitRange{Int64} # Range of the number of GHP options
require_ghp_purchase::Int64 # 0/1 binary if GHP purchase is forced/required
ghp_heating_thermal_load_served_kw::Array{Float64,2} # Array of heating load (thermal!) profiles served by GHP
ghp_cooling_thermal_load_served_kw::Array{Float64,2} # Array of cooling load profiles served by GHP
space_heating_thermal_load_reduction_with_ghp_kw::Array{Float64,2} # Array of heating load reduction (thermal!) profile from GHP retrofit
cooling_thermal_load_reduction_with_ghp_kw::Array{Float64,2} # Array of cooling load reduction (thermal!) profile from GHP retrofit
ghp_electric_consumption_kw::Array{Float64,2} # Array of electric load profiles consumed by GHP
ghp_installed_cost::Array{Float64,1} # Array of installed cost for GHP options
ghp_om_cost_year_one::Array{Float64,1} # Array of O&M cost for GHP options
tech_renewable_energy_fraction::Dict{String, <:Real} # (techs)
tech_emissions_factors_CO2::Dict{String, <:Real} # (techs)
tech_emissions_factors_NOx::Dict{String, <:Real} # (techs)
tech_emissions_factors_SO2::Dict{String, <:Real} # (techs)
tech_emissions_factors_PM25::Dict{String, <:Real} # (techs)
techs_operating_reserve_req_fraction::Dict{String, <:Real} # (techs.all)
heating_cop::Dict{String, <:Real} # (techs.electric_heater)
unavailability::Dict{String, Array{Float64,1}} # Dict by tech of unavailability profile
endREopt.REoptInputs — MethodREoptInputs(fp::String)Use fp to load in JSON scenario:
function REoptInputs(fp::String)
s = Scenario(JSON.parsefile(fp))
REoptInputs(s)
endUseful if you want to manually modify REoptInputs before solving the model.
REopt.REoptInputs — MethodREoptInputs(s::AbstractScenario)Constructor for REoptInputs. Translates the Scenario into all the data necessary for building the JuMP model.
Design Concepts for REoptInputs
At a high level the REoptInputs constructor does the following tasks:
- build index sets for the JuMP model decision variables,
- create maps from one set to another set,
- and generate coefficient arrays necessary for model constraints.
Index Sets
There are a few String[] that are built by REoptInputs that are then used as index sets in the model constraints. The primary index set is the techs.all array of strings, which contains all the technolgy names that are being modeled. With the techs.all array we can easily apply a constraint over all technolgies. For example:
@constraint(m, [t in p.techs.all],
m[Symbol("dvSize"*_n)][t] <= p.max_sizes[t]
)where p is the REoptInputs struct. There are a couple things to note from this last example:
- The decision variable
dvSizeis accessed in the JuMP.Modelmusing theSymbolnotation so that this constraint can be used in the multi-node case in addition to the single node case. The_ninput value is an empty string by default and in the case of a multi-node model the_nstring will be set by theSite.nodeinteger. For example, ifSite.nodeis3then_nis "_3". - The
p.max_sizesarray is also indexed onp.techs.all. Themax_sizesis built in the REoptInputs constructor by using all the technologies in theScenariothat havemax_kwvalues greater than zero.
Besides the techs.all array the are many sub-sets, such as techs.pv, techs.gen, techs.elec, p.techs.segmented, techs.no_curtail, that allow us to apply constraints to those sets. For example:
for t in p.techs.no_curtail
for ts in p.time_steps
fix(m[Symbol("dvCurtail"*_n)][t, ts] , 0.0, force=true)
end
endSet maps
The set maps are best explained with an example. The techs_by_exportbin map uses each technology'sattributes (eg. PV) to map each technology to which export bins that technology can access. The export bins include:
:NEM(Net Energy Metering):WHL(Wholesale):EXC(Excess, beyond NEM))
The bins that a technology can access are determined by the technologies attributes can_net_meter, can_wholesale, and can_export_beyond_nem_limit. So if PV.can_net_meter = true, Wind.can_net_meter = true and all the other attributes are false then the techs_by_exportbin will only have one non-empty key:
techs_by_exportbin = Dict(
:NEM => ["PV", "Wind"],
:WHL => [],
:EXC => []
)A use-case example for the techs_by_exportbin map is defining the net metering benefit:
NEM_benefit = @expression(m, p.pwf_e * p.hours_per_time_step *
sum( sum(p.s.electric_tariff.export_rates[:NEM][ts] * m[Symbol("dvProductionToGrid"*_n)][t, :NEM, ts]
for t in p.techs_by_exportbin[:NEM]) for ts in p.time_steps)
)Other set maps include: export_bins_by_tech and n_segs_by_tech. The latter tells how many cost curve segments each technology has.
Coefficient Arrays
The JuMP model costs are formulated in net present value terms, accounting for all benefits (production, capacity, and investment incentives) and the total cost over the analysis_period. The REoptInputs constructor translates the raw input parameters, such as the operations and maintenance costs, into present value terms using the provided discount rate. For example, the pwf_e is the present worth factor for electricity that accounts for the elec_cost_escalation_rate_fraction, the analysis_period, and the offtaker_discount_rate_fraction. Note that tax benefits are applied directly in the JuMP model for clarity on which costs are tax-deductible and which are not.
Besides econimic parameters, the REoptInputs constructor also puts together the important production_factor array. The production_factor array is simple for continuously variable generators (such as the Generator), for which the production_factor is 1 in all time steps. However, for variable generators (such as Wind and PV) the production_factor varies by time step. If the user does not provide the PV production factor, for example, then the REoptInputs constructor uses the PVWatts API to download the location specific PV production factor. REoptInputs also accounts for the PV.degradation_fraction in building the production_factor array.