From c93d541e8087267c0da92776b137ad77bd546785 Mon Sep 17 00:00:00 2001 From: zolanaj Date: Tue, 8 Aug 2023 11:22:56 -0600 Subject: [PATCH 1/3] add get_existing_chiller_default_cop to exported functions --- src/REopt.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/REopt.jl b/src/REopt.jl index 05a7d7a84..8b6a1136e 100644 --- a/src/REopt.jl +++ b/src/REopt.jl @@ -50,7 +50,8 @@ export simulated_load, get_absorption_chiller_defaults, emissions_profiles, - easiur_data + easiur_data, + get_existing_chiller_default_cop import HTTP import JSON From 70ae2261d72288e8ac7dfb7d4fb8ac5ba112c00b Mon Sep 17 00:00:00 2001 From: zolanaj Date: Tue, 8 Aug 2023 11:46:18 -0600 Subject: [PATCH 2/3] convert load vectors to max loads in arguments to get_existing_chiller_default_cop --- src/core/heating_cooling_loads.jl | 22 +++++++++++----------- src/core/scenario.jl | 8 ++++---- test/test_with_xpress.jl | 2 +- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/src/core/heating_cooling_loads.jl b/src/core/heating_cooling_loads.jl index bb50a944a..aabea0b52 100644 --- a/src/core/heating_cooling_loads.jl +++ b/src/core/heating_cooling_loads.jl @@ -209,23 +209,23 @@ end """ function get_existing_chiller_default_cop(; existing_chiller_max_thermal_factor_on_peak_load=nothing, - loads_kw=nothing, - loads_kw_thermal=nothing) + max_load_kw=nothing, + max_load_kw_thermal=nothing) This function returns the default value for ExistingChiller.cop based on: 1. No information about load, returns average of lower and higher cop default values (`cop_unknown_thermal`) - 2. If the cooling electric `loads_kw` is known, we first guess the thermal load profile using `cop_unknown_thermal`, + 2. If the cooling electric `max_load_kw` is known, we first guess the thermal load profile using `cop_unknown_thermal`, and then we use the default logic to determine the `existing_chiller_cop` based on the peak thermal load with a thermal factor multiplier. - 3. If the cooling thermal `loads_kw_thermal` is known, same as 2. but we don't have to guess the cop to convert electric to thermal load first. + 3. If the cooling thermal `max_load_kw_thermal` is known, same as 2. but we don't have to guess the cop to convert electric to thermal load first. """ -function get_existing_chiller_default_cop(; existing_chiller_max_thermal_factor_on_peak_load=nothing, loads_kw=nothing, loads_kw_thermal=nothing) +function get_existing_chiller_default_cop(; existing_chiller_max_thermal_factor_on_peak_load=nothing, max_load_kw=nothing, max_load_kw_thermal=nothing) cop_less_than_100_ton = 4.40 cop_more_than_100_ton = 4.69 cop_unknown_thermal = (cop_less_than_100_ton + cop_more_than_100_ton) / 2.0 max_cooling_load_ton = nothing - if !isnothing(loads_kw_thermal) - max_cooling_load_ton = maximum(loads_kw_thermal) / KWH_THERMAL_PER_TONHOUR - elseif !isnothing(loads_kw) - max_cooling_load_ton = maximum(loads_kw) / KWH_THERMAL_PER_TONHOUR * cop_unknown_thermal + if !isnothing(max_load_kw_thermal) + max_cooling_load_ton = max_load_kw_thermal / KWH_THERMAL_PER_TONHOUR + elseif !isnothing(max_load_kw) + max_cooling_load_ton = max_load_kw / KWH_THERMAL_PER_TONHOUR * cop_unknown_thermal end if isnothing(max_cooling_load_ton) || isnothing(existing_chiller_max_thermal_factor_on_peak_load) return cop_unknown_thermal @@ -366,7 +366,7 @@ struct CoolingLoad elseif (!isempty(doe_reference_name) || !isempty(blended_doe_reference_names)) || isnothing(existing_chiller_cop) # Generated loads_kw (electric) above based on the building's default fraction of electric profile chiller_cop = get_existing_chiller_default_cop(;existing_chiller_max_thermal_factor_on_peak_load=existing_chiller_max_thermal_factor_on_peak_load, - loads_kw=loads_kw) + max_load_kw=maximum(loads_kw)) else chiller_cop = existing_chiller_cop end @@ -376,7 +376,7 @@ struct CoolingLoad # Now that cooling thermal loads_kw_thermal is known, update existing_chiller_cop if it was not input if isnothing(existing_chiller_cop) existing_chiller_cop = get_existing_chiller_default_cop(;existing_chiller_max_thermal_factor_on_peak_load=existing_chiller_max_thermal_factor_on_peak_load, - loads_kw_thermal=loads_kw_thermal) + max_load_kw_thermal=maximum(loads_kw_thermal)) end if length(loads_kw_thermal) < 8760*time_steps_per_hour diff --git a/src/core/scenario.jl b/src/core/scenario.jl index 904e07855..1048a42d6 100644 --- a/src/core/scenario.jl +++ b/src/core/scenario.jl @@ -288,14 +288,14 @@ function Scenario(d::Dict; flex_hvac_from_json=false) if haskey(d, "ExistingChiller") if !haskey(d["ExistingChiller"], "cop") d["ExistingChiller"]["cop"] = get_existing_chiller_default_cop(; existing_chiller_max_thermal_factor_on_peak_load=1.25, - loads_kw=nothing, - loads_kw_thermal=chiller_inputs[:loads_kw_thermal]) + max_load_kw=nothing, + max_load_kw_thermal=maximum(chiller_inputs[:loads_kw_thermal])) end chiller_inputs = merge(chiller_inputs, dictkeys_tosymbols(d["ExistingChiller"])) else chiller_inputs[:cop] = get_existing_chiller_default_cop(; existing_chiller_max_thermal_factor_on_peak_load=1.25, - loads_kw=nothing, - loads_kw_thermal=chiller_inputs[:loads_kw_thermal]) + max_load_kw=nothing, + max_load_kw_thermal=maximum(chiller_inputs[:loads_kw_thermal])) end existing_chiller = ExistingChiller(; chiller_inputs...) end diff --git a/test/test_with_xpress.jl b/test/test_with_xpress.jl index 7aaf7b9ad..13647f40a 100644 --- a/test/test_with_xpress.jl +++ b/test/test_with_xpress.jl @@ -799,7 +799,7 @@ end # When the user specifies inputs["ExistingChiller"]["cop"], this changes the **electric** consumption of the chiller to meet that cooling thermal load crb_cop = REopt.get_existing_chiller_default_cop(; existing_chiller_max_thermal_factor_on_peak_load=s.existing_chiller.max_thermal_factor_on_peak_load, - loads_kw_thermal=s.cooling_load.loads_kw_thermal) + max_load_kw_thermal=maximum(s.cooling_load.loads_kw_thermal)) cooling_thermal_load_tonhour_total = 1427329.0 * crb_cop / REopt.KWH_THERMAL_PER_TONHOUR # From CRB models, in heating_cooling_loads.jl, BuiltInCoolingLoad data for location (SanFrancisco Hospital) cooling_electric_load_total_mod_cop_kwh = cooling_thermal_load_tonhour_total / inputs.s.existing_chiller.cop * REopt.KWH_THERMAL_PER_TONHOUR From 8b2296809bbb20a70d148b5906018738b31c306b Mon Sep 17 00:00:00 2001 From: Alex Zolan Date: Tue, 8 Aug 2023 12:25:14 -0600 Subject: [PATCH 3/3] Update CHANGELOG.md --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ebcda882c..f8323ed0e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,9 @@ Classify the change according to the following categories: ### Deprecated ### Removed +## Develop 2023-08-08 +### Changed +- Updated `get_existing_chiller_cop` function to accept scalar values instead of vectors to allow for faster API transactions. ## v0.32.4 ### Changed - Consolidated PVWatts API calls to 1 call (previously 3 separate calls existed). API call occurs in `src/core/utils.jl/call_pvwatts_api()`. This function is called for PV in `src/core/production_factor.jl/get_production_factor(PV)` and for GHP in `src/core/scenario.jl`. If GHP and PV are evaluated together, the GHP PVWatts call for ambient temperature is also used to assign the pv.production_factor_series in Scenario.jl so that the PVWatts API does not get called again downstream in `get_production_factor(PV)`.