Skip to content

Commit

Permalink
Merge pull request #391 from NREL/fix-ghp-storage-dispatch
Browse files Browse the repository at this point in the history
Fix ghp-to-storage dispatch
  • Loading branch information
zolanaj committed May 9, 2024
2 parents 6c39421 + 4283794 commit 9fd9f9a
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 8 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

## Develop 2024-05-09
### Changed
- Updated the GHP testset .json `./test/scenarios/ghp_inputs.json` to include a nominal HotThermalStorage and ColdThermalStorage system.
### Fixed
- Fixed a bug in which the model fails to build when both GHP and either Hot or Cold Thermal Storage are present.

## v. 0.46.0
### Added
- In `src/core/absorption_chiller.jl` struct, added field **heating_load_input** to the AbsorptionChiller struct
Expand Down
16 changes: 15 additions & 1 deletion src/constraints/storage_constraints.jl
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,7 @@ function add_hot_thermal_storage_dispatch_constraints(m, p, b; _n="")
if !isempty(p.techs.chp)
if !isempty(p.techs.steam_turbine) && p.s.chp.can_supply_steam_turbine
@constraint(m, CHPTechProductionFlowCon[b in p.s.storage.types.hot, t in p.techs.chp, q in p.heating_loads, ts in p.time_steps],
m[Symbol("dvHeatToStorage"*_n)][b,tq,ts] + m[Symbol("dvProductionToWaste"*_n)][t,q,ts] + m[Symbol("dvThermalToSteamTurbine"*_n)][t,q,ts] <=
m[Symbol("dvHeatToStorage"*_n)][b,t,q,ts] + m[Symbol("dvProductionToWaste"*_n)][t,q,ts] + m[Symbol("dvThermalToSteamTurbine"*_n)][t,q,ts] <=
m[Symbol("dvHeatingProduction"*_n)][t,q,ts]
)
else
Expand Down Expand Up @@ -181,6 +181,13 @@ function add_hot_thermal_storage_dispatch_constraints(m, p, b; _n="")
sum(m[Symbol("dvHeatFromStorage"*_n)][b,q,ts] for q in p.heating_loads)
)

#Do not allow GHP to charge storage
if !isempty(p.techs.ghp)
for b in p.s.storage.types.hot, t in p.techs.ghp, q in p.heating_loads, ts in p.time_steps
fix(m[Symbol("dvHeatToStorage"*_n)][b,t,q,ts], 0.0, force=true)
end
end

end

function add_cold_thermal_storage_dispatch_constraints(m, p, b; _n="")
Expand All @@ -207,6 +214,13 @@ function add_cold_thermal_storage_dispatch_constraints(m, p, b; _n="")
m[Symbol("dvStoragePower"*_n)][b] >= m[Symbol("dvDischargeFromStorage"*_n)][b,ts] +
sum(m[Symbol("dvProductionToStorage"*_n)][b,t,ts] for t in p.techs.cooling)
)

#Do not allow GHP to charge storage
if !isempty(p.techs.ghp)
for b in p.s.storage.types.cold, t in p.techs.ghp, ts in p.time_steps
fix(m[Symbol("dvProductionToStorage"*_n)][b,t,ts], 0.0, force=true)
end
end
end

function add_storage_sum_constraints(m, p; _n="")
Expand Down
14 changes: 7 additions & 7 deletions src/core/reopt.jl
Original file line number Diff line number Diff line change
Expand Up @@ -216,19 +216,19 @@ function build_reopt!(m::JuMP.AbstractModel, p::REoptInputs)
elseif b in p.s.storage.types.hot
@constraint(m, [q in q in setdiff(p.heating_loads, p.heating_loads_served_by_tes[b]), ts in p.time_steps], m[:dvHeatFromStorage][b,q,ts] == 0)
if "DomesticHotWater" in p.heating_loads_served_by_tes[b]
@constraint(m, [t in setdiff(p.heating_techs, p.techs_can_serve_dhw), ts in p.time_steps], m[:dvHeatToStorage][b,"DomesticHotWater",ts] == 0)
@constraint(m, [t in setdiff(p.heating_techs, p.techs_can_serve_dhw), ts in p.time_steps], m[:dvHeatToStorage][b,t,"DomesticHotWater",ts] == 0)
else
@constraint(m, [t in p.heating_techs, ts in p.time_steps], m[:dvHeatToStorage][b,"DomesticHotWater",ts] == 0)
@constraint(m, [t in p.heating_techs, ts in p.time_steps], m[:dvHeatToStorage][b,t,"DomesticHotWater",ts] == 0)
end
if "SpaceHeating" in p.heating_loads_served_by_tes[b]
@constraint(m, [t in setdiff(p.heating_techs, p.techs_can_serve_space_heating), ts in p.time_steps], m[:dvHeatToStorage][b,"SpaceHeating",ts] == 0)
@constraint(m, [t in setdiff(p.heating_techs, p.techs_can_serve_space_heating), ts in p.time_steps], m[:dvHeatToStorage][b,t,"SpaceHeating",ts] == 0)
else
@constraint(m, [t in p.heating_techs, ts in p.time_steps], m[:dvHeatToStorage][b,"SpaceHeating",ts] == 0)
@constraint(m, [t in p.heating_techs, ts in p.time_steps], m[:dvHeatToStorage][b,t,"SpaceHeating",ts] == 0)
end
if "ProcessHeat" in p.heating_loads_served_by_tes[b]
@constraint(m, [t in setdiff(p.heating_techs, p.techs_can_serve_process_heat), ts in p.time_steps], m[:dvHeatToStorage][b,"ProcessHeat",ts] == 0)
@constraint(m, [t in setdiff(p.heating_techs, p.techs_can_serve_process_heat), ts in p.time_steps], m[:dvHeatToStorage][b,t,"ProcessHeat",ts] == 0)
else
@constraint(m, [t in p.heating_techs, ts in p.time_steps], m[:dvHeatToStorage][b,"ProcessHeat",ts] == 0)
@constraint(m, [t in p.heating_techs, ts in p.time_steps], m[:dvHeatToStorage][b,t,"ProcessHeat",ts] == 0)
end
end
else
Expand Down Expand Up @@ -584,7 +584,7 @@ function add_variables!(m::JuMP.AbstractModel, p::REoptInputs)
dvGridPurchase[p.time_steps, 1:p.s.electric_tariff.n_energy_tiers] >= 0 # Power from grid dispatched to meet electrical load [kW]
dvRatedProduction[p.techs.all, p.time_steps] >= 0 # Rated production of technology t [kW]
dvCurtail[p.techs.all, p.time_steps] >= 0 # [kW]
dvProductionToStorage[p.s.storage.types.all, p.techs.all, p.time_steps] >= 0 # Power from technology t used to charge storage system b [kW]
dvProductionToStorage[p.s.storage.types.all, union(p.techs.ghp,p.techs.all), p.time_steps] >= 0 # Power from technology t used to charge storage system b [kW]
dvDischargeFromStorage[p.s.storage.types.all, p.time_steps] >= 0 # Power discharged from storage system b [kW]
dvGridToStorage[p.s.storage.types.elec, p.time_steps] >= 0 # Electrical power delivered to storage by the grid [kW]
dvStoredEnergy[p.s.storage.types.all, 0:p.time_steps[end]] >= 0 # State of charge of storage system b
Expand Down
3 changes: 3 additions & 0 deletions src/core/steam_turbine.jl
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@
can_wholesale::Bool = false
can_export_beyond_nem_limit::Bool = false
can_curtail::Bool = false
can_serve_dhw::Bool = true
can_serve_space_heating::Bool = true
can_serve_process_heat::Bool = true
macrs_option_years::Int = 0
macrs_bonus_fraction::Float64 = 0.0
Expand Down
10 changes: 10 additions & 0 deletions test/scenarios/ghp_inputs.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,5 +55,15 @@
"ElectricStorage": {
"max_kw": 0.0,
"max_kwh": 0.0
},
"ColdThermalStorage": {
"min_gal": 10,
"max_gal": 10,
"thermal_decay_rate_fraction": 0.0
},
"HotThermalStorage": {
"min_gal": 10,
"max_gal": 10,
"thermal_decay_rate_fraction": 0.0
}
}

0 comments on commit 9fd9f9a

Please sign in to comment.