Skip to content

Commit ed8d332

Browse files
authored
Merge pull request #211 from NREL/develop
Add gen HHV, ERP bug fix, add to input descriptions, fix batt_roundtrip_efficiency calculation, push! not append() array in cost_curve.jl
2 parents 92c33ad + 49df6f0 commit ed8d332

20 files changed

+75
-46
lines changed

CHANGELOG.md

+10
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,16 @@ Classify the change according to the following categories:
2323
### Deprecated
2424
### Removed
2525

26+
## v0.30.0
27+
### Added
28+
- `Generator` input **fuel_higher_heating_value_kwh_per_gal**, which defaults to the constant KWH_PER_GAL_DIESEL
29+
### Changed
30+
- Added more description to **production_factor_series inputs**
31+
### Fixed
32+
- Fixed spelling of degradation_fraction
33+
- use push! instead of append() for array in core/cost_curve.jl
34+
- Fixed calculation of batt_roundtrip_efficiency in outage_simulator.jl
35+
2636
## v0.29.0
2737
### Added
2838
- Add `CHP` `FuelUsed` and `FuelCost` modeling/tracking for stochastic/multi-outages

Project.toml

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "REopt"
22
uuid = "d36ad4e8-d74a-4f7a-ace1-eaea049febf6"
33
authors = ["Nick Laws", "Hallie Dunham <[email protected]>", "Bill Becker <[email protected]>", "Bhavesh Rathod <[email protected]>", "Alex Zolan <[email protected]>", "Amanda Farthing <[email protected]>"]
4-
version = "0.29.0"
4+
version = "0.30.0"
55

66
[deps]
77
ArchGDAL = "c9ce4bd3-c3d5-55b8-8973-c0e20141b8c3"
@@ -36,5 +36,5 @@ LinDistFlow = "0.1, 0.2"
3636
MathOptInterface = "0.9, 0.10, 1"
3737
Requires = "1.3"
3838
Roots = "1.3, 2"
39-
TestEnv = "1.7"
39+
TestEnv = "1.7, 1.8, 1.9"
4040
julia = "1.4, 1.5, 1.6, 1.7, 1.8"

src/constraints/generator_constraints.jl

+5-4
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,17 @@
3030
function add_fuel_burn_constraints(m,p)
3131
fuel_slope_gal_per_kwhe, fuel_intercept_gal_per_hr = generator_fuel_slope_and_intercept(
3232
electric_efficiency_full_load=p.s.generator.electric_efficiency_full_load,
33-
electric_efficiency_half_load=p.s.generator.electric_efficiency_half_load
33+
electric_efficiency_half_load=p.s.generator.electric_efficiency_half_load,
34+
fuel_higher_heating_value_kwh_per_gal=p.s.generator.fuel_higher_heating_value_kwh_per_gal
3435
)
3536
@constraint(m, [t in p.techs.gen, ts in p.time_steps],
36-
m[:dvFuelUsage][t, ts] == (fuel_slope_gal_per_kwhe * KWH_PER_GAL_DIESEL *
37+
m[:dvFuelUsage][t, ts] == (fuel_slope_gal_per_kwhe * p.s.generator.fuel_higher_heating_value_kwh_per_gal *
3738
p.production_factor[t, ts] * p.hours_per_time_step * m[:dvRatedProduction][t, ts]) +
38-
(fuel_intercept_gal_per_hr * KWH_PER_GAL_DIESEL * p.hours_per_time_step * m[:binGenIsOnInTS][t, ts])
39+
(fuel_intercept_gal_per_hr * p.s.generator.fuel_higher_heating_value_kwh_per_gal * p.hours_per_time_step * m[:binGenIsOnInTS][t, ts])
3940
)
4041
@constraint(m,
4142
sum(m[:dvFuelUsage][t, ts] for t in p.techs.gen, ts in p.time_steps) <=
42-
p.s.generator.fuel_avail_gal * KWH_PER_GAL_DIESEL
43+
p.s.generator.fuel_avail_gal * p.s.generator.fuel_higher_heating_value_kwh_per_gal
4344
)
4445
end
4546

src/constraints/outage_constraints.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,8 @@ end
125125
function add_MG_Gen_fuel_burn_constraints(m,p)
126126
fuel_slope_gal_per_kwhe, fuel_intercept_gal_per_hr = generator_fuel_slope_and_intercept(
127127
electric_efficiency_full_load=p.s.generator.electric_efficiency_full_load,
128-
electric_efficiency_half_load=p.s.generator.electric_efficiency_half_load
128+
electric_efficiency_half_load=p.s.generator.electric_efficiency_half_load,
129+
fuel_higher_heating_value_kwh_per_gal=p.s.generator.fuel_higher_heating_value_kwh_per_gal
129130
)
130131
# Define dvMGFuelUsed by summing over outage time_steps.
131132
@constraint(m, [t in p.techs.gen, s in p.s.electric_utility.scenarios, tz in p.s.electric_utility.outage_start_time_steps],

src/core/bau_inputs.jl

+2-1
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,8 @@ function bau_outage_check(critical_loads_kw::AbstractArray, pv_kw_series::Abstra
340340
end
341341
fuel_slope_gal_per_kwhe, fuel_intercept_gal_per_hr = generator_fuel_slope_and_intercept(
342342
electric_efficiency_full_load=gen.electric_efficiency_full_load,
343-
electric_efficiency_half_load=gen.electric_efficiency_half_load
343+
electric_efficiency_half_load=gen.electric_efficiency_half_load,
344+
fuel_higher_heating_value_kwh_per_gal=gen.fuel_higher_heating_value_kwh_per_gal
344345
)
345346
for (i, (load, pv)) in enumerate(zip(critical_loads_kw, pv_kw_series))
346347
unmet = load - pv

src/core/cost_curve.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ end
4747

4848

4949
function insert_u_after_p_bp(xp_array_incent, yp_array_incent, region, u_xbp, u_ybp, p, p_cap, u_cap)
50-
xp_array_incent[region].append(u_xbp)
50+
push!(xp_array_incent[region], u_xbp)
5151
if p_cap == 0
5252
push!(yp_array_incent[region], u_ybp - (p * u_ybp + u_cap))
5353
else

src/core/generator.jl

+4
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
electric_efficiency_full_load::Real = 0.3233,
4141
electric_efficiency_half_load::Real = electric_efficiency_full_load,
4242
fuel_avail_gal::Real = off_grid_flag ? 1.0e9 : 660.0,
43+
fuel_higher_heating_value_kwh_per_gal::Real = 40.7,
4344
min_turn_down_fraction::Real = off_grid_flag ? 0.15 : 0.0,
4445
only_runs_during_grid_outage::Bool = true,
4546
sells_energy_back_to_grid::Bool = false,
@@ -88,6 +89,7 @@ struct Generator <: AbstractGenerator
8889
electric_efficiency_full_load
8990
electric_efficiency_half_load
9091
fuel_avail_gal
92+
fuel_higher_heating_value_kwh_per_gal
9193
min_turn_down_fraction
9294
only_runs_during_grid_outage
9395
sells_energy_back_to_grid
@@ -133,6 +135,7 @@ struct Generator <: AbstractGenerator
133135
electric_efficiency_full_load::Real = 0.3233,
134136
electric_efficiency_half_load::Real = electric_efficiency_full_load,
135137
fuel_avail_gal::Real = off_grid_flag ? 1.0e9 : 660.0,
138+
fuel_higher_heating_value_kwh_per_gal::Real = KWH_PER_GAL_DIESEL,
136139
min_turn_down_fraction::Real = off_grid_flag ? 0.15 : 0.0,
137140
only_runs_during_grid_outage::Bool = true,
138141
sells_energy_back_to_grid::Bool = false,
@@ -181,6 +184,7 @@ struct Generator <: AbstractGenerator
181184
electric_efficiency_full_load,
182185
electric_efficiency_half_load,
183186
fuel_avail_gal,
187+
fuel_higher_heating_value_kwh_per_gal,
184188
min_turn_down_fraction,
185189
only_runs_during_grid_outage,
186190
sells_energy_back_to_grid,

src/core/pv.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
acres_per_kw::Real=6e-3,
5353
inv_eff::Real=0.96,
5454
dc_ac_ratio::Real=1.2,
55-
production_factor_series::Union{Nothing, Array{<:Real,1}} = nothing,
55+
production_factor_series::Union{Nothing, Array{<:Real,1}} = nothing, # Optional user-defined production factors. Must be normalized to units of kW-AC/kW-DC nameplate. The series must be one year (January through December) of hourly, 30-minute, or 15-minute generation data.
5656
federal_itc_fraction::Real = 0.3,
5757
federal_rebate_per_kw::Real = 0.0,
5858
state_ibi_fraction::Real = 0.0,

src/core/reopt_inputs.jl

+6-5
Original file line numberDiff line numberDiff line change
@@ -593,11 +593,12 @@ function setup_gen_inputs(s::AbstractScenario, max_sizes, min_sizes, existing_si
593593
push!(techs.no_curtail, "Generator")
594594
end
595595
tech_renewable_energy_fraction["Generator"] = s.generator.fuel_renewable_energy_fraction
596-
tech_emissions_factors_CO2["Generator"] = s.generator.emissions_factor_lb_CO2_per_gal / KWH_PER_GAL_DIESEL # lb/gal * gal/kWh
597-
tech_emissions_factors_NOx["Generator"] = s.generator.emissions_factor_lb_NOx_per_gal / KWH_PER_GAL_DIESEL
598-
tech_emissions_factors_SO2["Generator"] = s.generator.emissions_factor_lb_SO2_per_gal / KWH_PER_GAL_DIESEL
599-
tech_emissions_factors_PM25["Generator"] = s.generator.emissions_factor_lb_PM25_per_gal / KWH_PER_GAL_DIESEL
600-
generator_fuel_cost_per_kwh = s.generator.fuel_cost_per_gallon / KWH_PER_GAL_DIESEL
596+
hhv_kwh_per_gal = s.generator.fuel_higher_heating_value_kwh_per_gal
597+
tech_emissions_factors_CO2["Generator"] = s.generator.emissions_factor_lb_CO2_per_gal / hhv_kwh_per_gal # lb/gal * gal/kWh
598+
tech_emissions_factors_NOx["Generator"] = s.generator.emissions_factor_lb_NOx_per_gal / hhv_kwh_per_gal
599+
tech_emissions_factors_SO2["Generator"] = s.generator.emissions_factor_lb_SO2_per_gal / hhv_kwh_per_gal
600+
tech_emissions_factors_PM25["Generator"] = s.generator.emissions_factor_lb_PM25_per_gal / hhv_kwh_per_gal
601+
generator_fuel_cost_per_kwh = s.generator.fuel_cost_per_gallon / hhv_kwh_per_gal
601602
fuel_cost_per_kwh["Generator"] = per_hour_value_to_time_series(generator_fuel_cost_per_kwh, s.settings.time_steps_per_hour, "Generator")
602603
return nothing
603604
end

src/core/utils.jl

+6-4
Original file line numberDiff line numberDiff line change
@@ -494,7 +494,8 @@ end
494494
"""
495495
generator_fuel_slope_and_intercept(;
496496
electric_efficiency_full_load::Real, [kWhe/kWht]
497-
electric_efficiency_half_load::Real [kWhe/kWht]
497+
electric_efficiency_half_load::Real, [kWhe/kWht]
498+
fuel_higher_heating_value_kwh_per_gal::Real
498499
)
499500
500501
return Tuple{<:Real,<:Real} where
@@ -503,14 +504,15 @@ return Tuple{<:Real,<:Real} where
503504
"""
504505
function generator_fuel_slope_and_intercept(;
505506
electric_efficiency_full_load::Real,
506-
electric_efficiency_half_load::Real
507+
electric_efficiency_half_load::Real,
508+
fuel_higher_heating_value_kwh_per_gal::Real
507509
)
508510
fuel_burn_full_load_kwht = 1.0 / electric_efficiency_full_load # [kWe_rated/(kWhe/kWht)]
509511
fuel_burn_half_load_kwht = 0.5 / electric_efficiency_half_load # [kWe_rated/(kWhe/kWht)]
510512
fuel_slope_kwht_per_kwhe = (fuel_burn_full_load_kwht - fuel_burn_half_load_kwht) / (1.0 - 0.5) # [kWht/kWhe]
511513
fuel_intercept_kwht_per_hr = fuel_burn_full_load_kwht - fuel_slope_kwht_per_kwhe * 1.0 # [kWht/hr]
512-
fuel_slope_gal_per_kwhe = fuel_slope_kwht_per_kwhe / KWH_PER_GAL_DIESEL # [gal/kWhe]
513-
fuel_intercept_gal_per_hr = fuel_intercept_kwht_per_hr / KWH_PER_GAL_DIESEL # [gal/hr]
514+
fuel_slope_gal_per_kwhe = fuel_slope_kwht_per_kwhe / fuel_higher_heating_value_kwh_per_gal # [gal/kWhe]
515+
fuel_intercept_gal_per_hr = fuel_intercept_kwht_per_hr / fuel_higher_heating_value_kwh_per_gal # [gal/hr]
514516

515517
return fuel_slope_gal_per_kwhe, fuel_intercept_gal_per_hr
516518
end

src/core/wind.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434
max_kw = 1.0e9,
3535
installed_cost_per_kw = nothing,
3636
om_cost_per_kw = 35.0,
37-
production_factor_series = nothing,
37+
production_factor_series = nothing, # Optional user-defined production factors. Must be normalized to units of kW-AC/kW-DC nameplate. The series must be one year (January through December) of hourly, 30-minute, or 15-minute generation data.
3838
size_class = "",
3939
wind_meters_per_sec = [],
4040
wind_direction_degrees = [],

src/mpc/inputs.jl

+1-1
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ end
164164
function setup_gen_inputs(s::MPCScenario, existing_sizes, production_factor, fuel_cost_per_kwh)
165165
existing_sizes["Generator"] = s.generator.size_kw
166166
production_factor["Generator", :] = ones(length(s.electric_load.loads_kw))
167-
generator_fuel_cost_per_kwh = s.generator.fuel_cost_per_gallon / KWH_PER_GAL_DIESEL
167+
generator_fuel_cost_per_kwh = s.generator.fuel_cost_per_gallon / s.generator.fuel_higher_heating_value_kwh_per_gal
168168
fuel_cost_per_kwh["Generator"] = per_hour_value_to_time_series(generator_fuel_cost_per_kwh, s.settings.time_steps_per_hour, "Generator")
169169
return nothing
170170
end

src/mpc/structs.jl

+4
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,7 @@ function MPCGenerator(;
284284
electric_efficiency_full_load::Real = 0.3233,
285285
electric_efficiency_half_load::Real = electric_efficiency_full_load,
286286
fuel_avail_gal::Real = 660.0,
287+
fuel_higher_heating_value_kwh_per_gal::Real = KWH_PER_GAL_DIESEL,
287288
min_turn_down_fraction::Real = 0.0, # TODO change this to non-zero value
288289
only_runs_during_grid_outage::Bool = true,
289290
sells_energy_back_to_grid::Bool = false,
@@ -298,6 +299,7 @@ struct MPCGenerator <: AbstractGenerator
298299
electric_efficiency_full_load
299300
electric_efficiency_half_load
300301
fuel_avail_gal
302+
fuel_higher_heating_value_kwh_per_gal
301303
min_turn_down_fraction
302304
only_runs_during_grid_outage
303305
sells_energy_back_to_grid
@@ -309,6 +311,7 @@ struct MPCGenerator <: AbstractGenerator
309311
electric_efficiency_full_load::Real = 0.3233,
310312
electric_efficiency_half_load::Real = electric_efficiency_full_load,
311313
fuel_avail_gal::Real = 660.0,
314+
fuel_higher_heating_value_kwh_per_gal::Real = KWH_PER_GAL_DIESEL,
312315
min_turn_down_fraction::Real = 0.0, # TODO change this to non-zero value
313316
only_runs_during_grid_outage::Bool = true,
314317
sells_energy_back_to_grid::Bool = false,
@@ -324,6 +327,7 @@ struct MPCGenerator <: AbstractGenerator
324327
electric_efficiency_full_load,
325328
electric_efficiency_half_load,
326329
fuel_avail_gal,
330+
fuel_higher_heating_value_kwh_per_gal,
327331
min_turn_down_fraction,
328332
only_runs_during_grid_outage,
329333
sells_energy_back_to_grid,

src/outagesim/backup_reliability.jl

+6-3
Original file line numberDiff line numberDiff line change
@@ -827,6 +827,7 @@ Return a dictionary of inputs required for backup reliability calculations.
827827
-generator_fuel_burn_rate_per_kwh::Union{Real, Vector{<:Real}} = 0.076 Amount of fuel used per kWh generated. Fuel units should be consistent with fuel_limit and generator_fuel_intercept_per_hr.
828828
"""
829829
function backup_reliability_reopt_inputs(;d::Dict, p::REoptInputs, r::Dict = Dict())::Dict
830+
830831
r2 = dictkeys_tosymbols(r)
831832
zero_array = zeros(length(p.time_steps))
832833
r2[:critical_loads_kw] = p.s.electric_load.critical_loads_kw
@@ -962,11 +963,13 @@ Dict{Any, Any} with 11 entries:
962963
```
963964
"""
964965
function backup_reliability_inputs(;r::Dict)::Dict
966+
965967
invalid_args = String[]
966968
r2 = dictkeys_tosymbols(r)
967969

968970
generator_inputs = [:generator_operational_availability, :generator_failure_to_start, :generator_mean_time_to_failure,
969-
:num_generators, :generator_size_kw, :fuel_limit, :generator_fuel_intercept_per_hr, :generator_fuel_burn_rate_per_kwh]
971+
:num_generators, :generator_size_kw, :fuel_limit, :fuel_limit_is_per_generator,
972+
:generator_fuel_intercept_per_hr, :generator_fuel_burn_rate_per_kwh]
970973
for g in generator_inputs
971974
if haskey(r2, g) && isa(r2[g], Array) && length(r2[g]) == 1
972975
r2[g] = r2[g][1]
@@ -1157,10 +1160,10 @@ function fuel_use(;
11571160
battery_charge_efficiency::Real = 0.948,
11581161
battery_discharge_efficiency::Real = 0.948,
11591162
time_steps_per_hour::Real = 1,
1160-
kwargs...)::Tuple{Matrix{Int}, Matrix{Float64}}
1163+
kwargs...
1164+
)::Tuple{Matrix{Int}, Matrix{Float64}}
11611165

11621166
t_max = length(net_critical_loads_kw)
1163-
11641167
fuel_limit = convert.(Float64, fuel_limit)
11651168
if isa(fuel_limit_is_per_generator, Bool)
11661169
if fuel_limit_is_per_generator

src/outagesim/outage_simulator.jl

+4-3
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,8 @@ Returns a dict
252252
```
253253
"""
254254
function simulate_outages(d::Dict, p::REoptInputs; microgrid_only::Bool=false)
255-
batt_roundtrip_efficiency = p.s.storage.attr["ElectricStorage"].charge_efficiency
256-
p.s.storage.attr["ElectricStorage"].discharge_efficiency
255+
batt_roundtrip_efficiency = (p.s.storage.attr["ElectricStorage"].charge_efficiency *
256+
p.s.storage.attr["ElectricStorage"].discharge_efficiency)
257257

258258
# TODO handle generic PV names
259259
pv_kw_ac_hourly = zeros(length(p.time_steps))
@@ -293,7 +293,8 @@ function simulate_outages(d::Dict, p::REoptInputs; microgrid_only::Bool=false)
293293

294294
fuel_slope_gal_per_kwhe, fuel_intercept_gal_per_hr = generator_fuel_slope_and_intercept(
295295
electric_efficiency_full_load=p.s.generator.electric_efficiency_full_load,
296-
electric_efficiency_half_load=p.s.generator.electric_efficiency_half_load
296+
electric_efficiency_half_load=p.s.generator.electric_efficiency_half_load,
297+
fuel_higher_heating_value_kwh_per_gal = p.s.generator.fuel_higher_heating_value_kwh_per_gal
297298
)
298299

299300
simulate_outages(;

src/results/financial.jl

+3-3
Original file line numberDiff line numberDiff line change
@@ -318,10 +318,10 @@ function calculate_lcoe(p::REoptInputs, tech_results::Dict, tech::AbstractTech)
318318
if tech.production_incentive_max_benefit > 0
319319
for yr in 1:years
320320
if yr < tech.production_incentive_years
321-
degredation_fraction = (1- degradation_fraction)^yr
321+
degradation_fraction = (1- degradation_fraction)^yr
322322
base_pbi = minimum([tech.production_incentive_per_kwh *
323-
(year_one_energy_produced - existing_energy_bau) * degredation_fraction,
324-
tech.production_incentive_max_benefit * degredation_fraction
323+
(year_one_energy_produced - existing_energy_bau) * degradation_fraction,
324+
tech.production_incentive_max_benefit * degradation_fraction
325325
])
326326
npv_pbi += base_pbi * (1.0/(1.0+discount_rate_fraction))^(yr+1)
327327
end

src/results/generator.jl

+2-2
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ function add_generator_results(m::JuMP.AbstractModel, p::REoptInputs, d::Dict; _
8787
)
8888
r["electric_to_load_series_kw"] = round.(value.(generatorToLoad), digits=3)
8989

90-
GeneratorFuelUsed = @expression(m, sum(m[:dvFuelUsage][t, ts] for t in p.techs.gen, ts in p.time_steps) / KWH_PER_GAL_DIESEL)
90+
GeneratorFuelUsed = @expression(m, sum(m[:dvFuelUsage][t, ts] for t in p.techs.gen, ts in p.time_steps) / p.s.generator.fuel_higher_heating_value_kwh_per_gal)
9191
r["annual_fuel_consumption_gal"] = round(value(GeneratorFuelUsed), digits=2)
9292

9393
AverageGenProd = @expression(m,
@@ -137,7 +137,7 @@ function add_generator_results(m::JuMP.AbstractModel, p::MPCInputs, d::Dict; _n=
137137
)
138138
r["to_load_series_kw"] = round.(value.(generatorToLoad), digits=3).data
139139

140-
GeneratorFuelUsed = @expression(m, sum(m[:dvFuelUsage][t, ts] for t in p.techs.gen, ts in p.time_steps) / KWH_PER_GAL_DIESEL)
140+
GeneratorFuelUsed = @expression(m, sum(m[:dvFuelUsage][t, ts] for t in p.techs.gen, ts in p.time_steps) / p.s.generator.fuel_higher_heating_value_kwh_per_gal)
141141
r["annual_fuel_consumption_gal"] = round(value(GeneratorFuelUsed), digits=2)
142142

143143
Year1GenProd = @expression(m,

src/results/proforma.jl

+5-5
Original file line numberDiff line numberDiff line change
@@ -337,14 +337,14 @@ function update_metrics(m::Metrics, p::REoptInputs, tech::AbstractTech, tech_nam
337337
year_one_energy = "year_one_energy_produced_kwh" in keys(results[tech_name]) ? results[tech_name]["year_one_energy_produced_kwh"] : results[tech_name]["annual_energy_produced_kwh"]
338338
for yr in range(0, stop=years-1)
339339
if yr < tech.production_incentive_years
340-
degredation_fraction = :degradation_fraction in fieldnames(typeof(tech)) ? (1 - tech.degradation_fraction)^yr : 1.0
340+
degradation_fraction = :degradation_fraction in fieldnames(typeof(tech)) ? (1 - tech.degradation_fraction)^yr : 1.0
341341
base_pbi = minimum([
342-
tech.production_incentive_per_kwh * (year_one_energy - existing_energy_bau) * degredation_fraction,
343-
tech.production_incentive_max_benefit * degredation_fraction
342+
tech.production_incentive_per_kwh * (year_one_energy - existing_energy_bau) * degradation_fraction,
343+
tech.production_incentive_max_benefit * degradation_fraction
344344
])
345345
base_pbi_bau = minimum([
346-
tech.production_incentive_per_kwh * get(results[tech_name], "year_one_energy_produced_kwh_bau", 0) * degredation_fraction,
347-
tech.production_incentive_max_benefit * degredation_fraction
346+
tech.production_incentive_per_kwh * get(results[tech_name], "year_one_energy_produced_kwh_bau", 0) * degradation_fraction,
347+
tech.production_incentive_max_benefit * degradation_fraction
348348
])
349349
push!(pbi_series, base_pbi)
350350
push!(pbi_series_bau, base_pbi_bau)

test/scenarios/erp_fuel_limit_inputs.json

+9-9
Original file line numberDiff line numberDiff line change
@@ -8762,15 +8762,15 @@
87628762
325.34919044525986,
87638763
321.34319845422783
87648764
],
8765-
"generator_operational_availability": 0.995,
8766-
"generator_failure_to_start": 0.0094,
8767-
"generator_mean_time_to_failure": 1100.0,
8768-
"num_generators": 1,
8769-
"generator_size_kw": 157.0,
8770-
"fuel_limit": 5000.0,
8771-
"fuel_limit_is_per_generator": false,
8772-
"generator_fuel_burn_rate_per_kwh": 0.072265,
8773-
"generator_fuel_intercept_per_hr": 0.0,
8765+
"generator_operational_availability": [0.995],
8766+
"generator_failure_to_start": [0.0094],
8767+
"generator_mean_time_to_failure": [1100.0],
8768+
"num_generators": [1],
8769+
"generator_size_kw": [157.0],
8770+
"fuel_limit": [5000.0],
8771+
"fuel_limit_is_per_generator": [true],
8772+
"generator_fuel_burn_rate_per_kwh": [0.072265],
8773+
"generator_fuel_intercept_per_hr": [0.0],
87748774
"pv_operational_availability": 1.0,
87758775
"pv_size_kw": 3635.0,
87768776
"pv_production_factor_series": [

test/scenarios/re_emissions_elec_only.json

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@
5454
"installed_cost_per_kw": 600.0,
5555
"utility_ibi_max": 0.0,
5656
"fuel_avail_gal": 0.0,
57+
"fuel_higher_heating_value_kwh_per_gal": 40.7,
5758
"min_turn_down_fraction": 0.0,
5859
"production_incentive_max_kw": 0.0,
5960
"utility_ibi_fraction": 0.0,

0 commit comments

Comments
 (0)