Skip to content

Commit

Permalink
Merge pull request #345 from NREL/obj-incentives
Browse files Browse the repository at this point in the history
Avoid modifying LCC with Obj Func Incentives
  • Loading branch information
adfarth authored Jan 25, 2024
2 parents b585ba0 + b0485a4 commit b528862
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 34 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ Classify the change according to the following categories:
### Deprecated
### Removed

## Develop 2024-01-16
### Fixed
- In `reopt.jl`, group objective function incentives (into **ObjectivePenalties**) and avoid directly modifying m[:Costs]. Previously, some of these were incorrectly included in the reported **Financial.lcc**.

## v0.39.1
### Changed
- Changed testing suite from using Xpress to using HiGHS, an open-source solver. This has led to a reduction in the number of tests due to incompatibility with indicator constraints.
Expand Down
41 changes: 12 additions & 29 deletions src/core/reopt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ function build_reopt!(m::JuMP.AbstractModel, p::REoptInputs)
m[:GHPOMCosts] = 0.0
m[:AvoidedCapexByGHP] = 0.0
m[:ResidualGHXCapCost] = 0.0
m[:ObjectivePenalties] = 0.0

if !isempty(p.techs.all)
add_tech_size_constraints(m, p)
Expand Down Expand Up @@ -441,12 +442,7 @@ function build_reopt!(m::JuMP.AbstractModel, p::REoptInputs)
m[:TotalElecBill] * (1 - p.s.financial.offtaker_tax_rate_fraction) -

# Subtract Incentives, which are taxable
m[:TotalProductionIncentive] * (1 - p.s.financial.owner_tax_rate_fraction) +

# Comfort limit violation costs
#TODO: add this to objective like SOC incentive below and
#don't then subtract out when setting lcc in results/financial.jl
m[:dvComfortLimitViolationCost] +
m[:TotalProductionIncentive] * (1 - p.s.financial.owner_tax_rate_fraction) +

# Additional annual costs, tax deductible for owner (only applies when `off_grid_flag` is true)
p.s.financial.offgrid_other_annual_costs * p.pwf_om * (1 - p.s.financial.owner_tax_rate_fraction) +
Expand All @@ -470,36 +466,23 @@ function build_reopt!(m::JuMP.AbstractModel, p::REoptInputs)
add_to_expression!(Costs, m[:Lifecycle_Emissions_Cost_Health])
end

@expression(m, Objective,
m[:Costs]
)
## Modify objective with incentives that are not part of the LCC
# 1. Comfort limit violation costs
m[:ObjectivePenalties] += m[:dvComfortLimitViolationCost]
# 2. Incentive to keep SOC high
if !(isempty(p.s.storage.types.elec)) && p.s.settings.add_soc_incentive
# Incentive to keep SOC high
add_to_expression!(
Objective,
- sum(
m[:ObjectivePenalties] += -1 * sum(
m[:dvStoredEnergy][b, ts] for b in p.s.storage.types.elec, ts in p.time_steps
) / (8760. / p.hours_per_time_step)
)
end
# 3. Incentive to minimize unserved load in each outage, not just the max over outage start times
if !isempty(p.s.electric_utility.outage_durations)
# Incentive to minimize unserved load in each outage, not just the max over outage start times
add_to_expression!(
Objective,
sum(sum(0.0001 * m[:dvUnservedLoad][s, tz, ts] for ts in 1:p.s.electric_utility.outage_durations[s]) for s in p.s.electric_utility.scenarios, tz in p.s.electric_utility.outage_start_time_steps)
)
m[:ObjectivePenalties] += sum(sum(0.0001 * m[:dvUnservedLoad][s, tz, ts] for ts in 1:p.s.electric_utility.outage_durations[s])
for s in p.s.electric_utility.scenarios, tz in p.s.electric_utility.outage_start_time_steps)
end

@objective(m, Min, m[:Objective])

# if !(isempty(p.s.storage.types.elec)) && p.s.settings.add_soc_incentive # Keep SOC high
# @objective(m, Min, m[:Costs] -
# sum(m[:dvStoredEnergy][b, ts] for b in p.s.storage.types.elec, ts in p.time_steps) /
# (8760. / p.hours_per_time_step)
# )

# end
# Set model objective
@objective(m, Min, m[:Costs] + m[:ObjectivePenalties] )

for b in p.s.storage.types.elec
if p.s.storage.attr[b].model_degradation
Expand Down
6 changes: 2 additions & 4 deletions src/results/financial.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,6 @@ calculated in combine_results function if BAU scenario is run:
"""
function add_financial_results(m::JuMP.AbstractModel, p::REoptInputs, d::Dict; _n="")
r = Dict{String, Float64}()
if !(Symbol("dvComfortLimitViolationCost"*_n) in keys(m.obj_dict))
m[Symbol("dvComfortLimitViolationCost"*_n)] = 0.0
end
if !(Symbol("TotalProductionIncentive"*_n) in keys(m.obj_dict)) # not currently included in multi-node modeling b/c these constraints require binary vars.
m[Symbol("TotalProductionIncentive"*_n)] = 0.0
end
Expand All @@ -54,7 +51,8 @@ function add_financial_results(m::JuMP.AbstractModel, p::REoptInputs, d::Dict; _
m[Symbol("GHPCapCosts"*_n)] = 0.0
end

r["lcc"] = value(m[Symbol("Costs"*_n)]) + 0.0001 * value(m[Symbol("MinChargeAdder"*_n)]) - value(m[Symbol("dvComfortLimitViolationCost"*_n)])
r["lcc"] = value(m[Symbol("Costs"*_n)]) + 0.0001 * value(m[Symbol("MinChargeAdder"*_n)])

r["lifecycle_om_costs_before_tax"] = value(m[Symbol("TotalPerUnitSizeOMCosts"*_n)] +
m[Symbol("TotalPerUnitProdOMCosts"*_n)] + m[Symbol("TotalPerUnitHourOMCosts"*_n)] + m[Symbol("GHPOMCosts"*_n)])

Expand Down
2 changes: 1 addition & 1 deletion test/test_with_xpress.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1479,7 +1479,7 @@ end
@test results["Site"]["total_renewable_energy_fraction_bau"] 0.132118 atol=1e-3 # 0.1354 atol=1e-3
# CO2 emissions - totals ≈ from grid, from fuelburn, ER, $/tCO2 breakeven
@test results["Site"]["lifecycle_emissions_reduction_CO2_fraction"] 0.8 atol=1e-3 # 0.8
@test results["Financial"]["breakeven_cost_of_emissions_reduction_per_tonne_CO2"] 373.9 atol=1e-1
@test results["Financial"]["breakeven_cost_of_emissions_reduction_per_tonne_CO2"] 374.0 atol=1e-1
@test results["Site"]["annual_emissions_tonnes_CO2"] 14.2 atol=1
@test results["Site"]["annual_emissions_tonnes_CO2_bau"] 70.99 atol=1
@test results["Site"]["annual_emissions_from_fuelburn_tonnes_CO2"] 0.0 atol=1 # 0.0
Expand Down

0 comments on commit b528862

Please sign in to comment.