openstudio-standards 0.2.12.rc4 → 0.2.12.rc5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/data/standards/OpenStudio_Standards-ashrae_90_1(space_types).xlsx +0 -0
- data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
- data/data/standards/test_performance_expected_dd_results.csv +950 -950
- data/lib/openstudio-standards.rb +8 -1
- data/lib/openstudio-standards/btap/btap.model.rb +1 -1
- data/lib/openstudio-standards/btap/economics.rb +14 -11
- data/lib/openstudio-standards/btap/envelope.rb +185 -257
- data/lib/openstudio-standards/btap/fileio.rb +1 -0
- data/lib/openstudio-standards/btap/geometry.rb +21 -1
- data/lib/openstudio-standards/btap/measures.rb +12 -11
- data/lib/openstudio-standards/btap/schedules.rb +3 -12
- data/lib/openstudio-standards/hvac_sizing/Siz.AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.rb +178 -0
- data/lib/openstudio-standards/hvac_sizing/Siz.CoilCoolingDXMultiSpeed.rb +8 -8
- data/lib/openstudio-standards/hvac_sizing/Siz.Model.rb +3 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +3 -3
- data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +25 -23
- data/lib/openstudio-standards/standards/Standards.CoilCoolingDXMultiSpeed.rb +91 -0
- data/lib/openstudio-standards/standards/Standards.CoilDX.rb +20 -2
- data/lib/openstudio-standards/standards/Standards.CoilHeatingGasMultiStage.rb +39 -0
- data/lib/openstudio-standards/standards/Standards.Model.rb +29 -0
- data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +37 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.unitary_acs.json +15 -15
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.unitary_acs.json +15 -15
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.unitary_acs.json +5 -5
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.unitary_acs.json +15 -15
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.spc_typ.json +5963 -2723
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.spc_typ.json +5917 -2697
- data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.spc_typ.json +2011 -1112
- data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.spc_typ.json +1946 -1106
- data/lib/openstudio-standards/standards/necb/BTAP1980TO2010/btap_1980to2010.rb +2 -18
- data/lib/openstudio-standards/standards/necb/BTAP1980TO2010/data/space_types.json +1677 -1005
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/btap_pre1980.rb +64 -13
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/building_envelope.rb +31 -19
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/curves.json +75 -0
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/heat_pumps.json +16 -16
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/space_types.json +1677 -1005
- data/lib/openstudio-standards/standards/necb/ECMS/data/boiler_set.json +29 -0
- data/lib/openstudio-standards/standards/necb/ECMS/data/curves.json +913 -0
- data/lib/openstudio-standards/standards/necb/ECMS/data/equip_eff_lim.json +52 -0
- data/lib/openstudio-standards/standards/necb/ECMS/data/erv.json +105 -0
- data/lib/openstudio-standards/standards/necb/ECMS/data/furnace_set.json +23 -0
- data/lib/openstudio-standards/standards/necb/ECMS/data/heat_pumps.json +803 -0
- data/lib/openstudio-standards/standards/necb/ECMS/data/heat_pumps_heating.json +787 -0
- data/lib/openstudio-standards/standards/necb/ECMS/data/shw_set.json +29 -0
- data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +87 -0
- data/lib/openstudio-standards/standards/necb/ECMS/erv.rb +22 -0
- data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +1593 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +68 -33
- data/lib/openstudio-standards/standards/necb/NECB2011/beps_compliance_path.rb +24 -13
- data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +104 -99
- data/lib/openstudio-standards/standards/necb/NECB2011/data/constants.json +24 -24
- data/lib/openstudio-standards/standards/necb/NECB2011/data/curves.json +50 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/data/erv.json +31 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/data/led_lighting_data.json +2028 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/data/space_types.json +1745 -1297
- data/lib/openstudio-standards/standards/necb/NECB2011/daylighting_control.md +70 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/demand_controlled_ventilation.md +46 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_multi_speed.rb +69 -107
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_single_speed.rb +24 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +139 -141
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +24 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +344 -234
- data/lib/openstudio-standards/standards/necb/NECB2011/led_lighting.md +51 -0
- data/lib/openstudio-standards/standards/necb/NECB2011/lighting.rb +57 -9
- data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +1060 -34
- data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +9 -1
- data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2015/data/led_lighting_data.json +2883 -0
- data/lib/openstudio-standards/standards/necb/NECB2015/data/space_types.json +2554 -1916
- data/lib/openstudio-standards/standards/necb/NECB2015/necb_2015.rb +32 -1
- data/lib/openstudio-standards/standards/necb/NECB2017/data/led_lighting_data.json +2883 -0
- data/lib/openstudio-standards/standards/necb/NECB2017/data/space_types.json +2554 -1916
- data/lib/openstudio-standards/standards/necb/NECB2017/necb_2017.rb +29 -0
- data/lib/openstudio-standards/version.rb +1 -1
- metadata +21 -2
@@ -1,5 +1,29 @@
|
|
1
1
|
class NECB2011
|
2
2
|
|
3
|
+
def add_sys3and8_single_zone_packaged_rooftop_unit_with_baseboard_heating(model:,
|
4
|
+
zones:,
|
5
|
+
heating_coil_type:,
|
6
|
+
baseboard_type:,
|
7
|
+
hw_loop:,
|
8
|
+
new_auto_zoner: true,
|
9
|
+
multispeed: false)
|
10
|
+
if multispeed
|
11
|
+
add_sys3and8_single_zone_packaged_rooftop_unit_with_baseboard_heating_multi_speed(model: model,
|
12
|
+
zones: zones,
|
13
|
+
heating_coil_type: heating_coil_type,
|
14
|
+
baseboard_type: baseboard_type,
|
15
|
+
hw_loop: hw_loop,
|
16
|
+
new_auto_zoner: new_auto_zoner)
|
17
|
+
else
|
18
|
+
add_sys3and8_single_zone_packaged_rooftop_unit_with_baseboard_heating_single_speed(model: model,
|
19
|
+
zones: zones,
|
20
|
+
heating_coil_type: heating_coil_type,
|
21
|
+
baseboard_type: baseboard_type,
|
22
|
+
hw_loop: hw_loop,
|
23
|
+
new_auto_zoner: new_auto_zoner)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
3
27
|
# Some tests still require a simple way to set up a system without sizing.. so we are keeping the auto_zoner flag for this method.
|
4
28
|
#
|
5
29
|
def add_sys3and8_single_zone_packaged_rooftop_unit_with_baseboard_heating_single_speed(model:,
|
@@ -367,6 +367,34 @@ class NECB2011
|
|
367
367
|
return true
|
368
368
|
end
|
369
369
|
|
370
|
+
# Sets the minimum effectiveness of the heat exchanger per
|
371
|
+
# the standard.
|
372
|
+
def heat_exchanger_air_to_air_sensible_and_latent_apply_efficiency(heat_exchanger_air_to_air_sensible_and_latent, erv_name = nil)
|
373
|
+
# Assumed to be sensible and latent at all flow
|
374
|
+
# This will now get data of the erv from the json file instead of hardcoding it. Defaults to NECB2011 erv we have been using.
|
375
|
+
erv_name = 'Rotary-Minimum-Eff-Existing' if erv_name.nil?
|
376
|
+
erv_info = @standards_data['erv'].detect { |item| item['erv_name'] == erv_name }
|
377
|
+
|
378
|
+
raise("Could not find #{erv_name} in #{self.class.name} class' erv.json file or it's parents. The available ervs are #{@standards_data['erv'].map{|item| item['erv_name']}}") if erv_info.nil?
|
379
|
+
|
380
|
+
heat_exchanger_air_to_air_sensible_and_latent.setHeatExchangerType(erv_info['HeatExchangerType'])
|
381
|
+
heat_exchanger_air_to_air_sensible_and_latent.setSensibleEffectivenessat100HeatingAirFlow(erv_info['SensibleEffectivenessat100HeatingAirFlow'])
|
382
|
+
heat_exchanger_air_to_air_sensible_and_latent.setLatentEffectivenessat100HeatingAirFlow(erv_info['LatentEffectivenessat100HeatingAirFlow'])
|
383
|
+
heat_exchanger_air_to_air_sensible_and_latent.setSensibleEffectivenessat75HeatingAirFlow(erv_info['SensibleEffectivenessat75HeatingAirFlow'])
|
384
|
+
heat_exchanger_air_to_air_sensible_and_latent.setLatentEffectivenessat75HeatingAirFlow(erv_info['LatentEffectivenessat75HeatingAirFlow'])
|
385
|
+
heat_exchanger_air_to_air_sensible_and_latent.setSensibleEffectivenessat100CoolingAirFlow(erv_info['SensibleEffectivenessat100CoolingAirFlow'])
|
386
|
+
heat_exchanger_air_to_air_sensible_and_latent.setLatentEffectivenessat100CoolingAirFlow(erv_info['LatentEffectivenessat100CoolingAirFlow'])
|
387
|
+
heat_exchanger_air_to_air_sensible_and_latent.setSensibleEffectivenessat75CoolingAirFlow(erv_info['SensibleEffectivenessat75CoolingAirFlow'])
|
388
|
+
heat_exchanger_air_to_air_sensible_and_latent.setLatentEffectivenessat75CoolingAirFlow(erv_info['LatentEffectivenessat75CoolingAirFlow'])
|
389
|
+
heat_exchanger_air_to_air_sensible_and_latent.setSupplyAirOutletTemperatureControl(erv_info['SupplyAirOutletTemperatureControl'])
|
390
|
+
heat_exchanger_air_to_air_sensible_and_latent.setFrostControlType(erv_info['FrostControlType'])
|
391
|
+
heat_exchanger_air_to_air_sensible_and_latent.setEconomizerLockout(erv_info['EconomizerLockout'])
|
392
|
+
heat_exchanger_air_to_air_sensible_and_latent.setThresholdTemperature(erv_info['ThresholdTemperature'])
|
393
|
+
heat_exchanger_air_to_air_sensible_and_latent.setInitialDefrostTimeFraction(erv_info['InitialDefrostTimeFraction'])
|
394
|
+
return true
|
395
|
+
end
|
396
|
+
|
397
|
+
|
370
398
|
# Determine if demand control ventilation (DCV) is
|
371
399
|
# required for this air loop.
|
372
400
|
#
|
@@ -798,127 +826,118 @@ class NECB2011
|
|
798
826
|
# @return [Bool] true if successful, false if not
|
799
827
|
def coil_cooling_dx_multi_speed_apply_efficiency_and_curves(coil_cooling_dx_multi_speed, sql_db_vars_map)
|
800
828
|
successfully_set_all_properties = true
|
829
|
+
model = coil_cooling_dx_multi_speed.model
|
830
|
+
multi_speed_heat_pump = coil_cooling_dx_multi_speed.containingHVACComponent.get.to_AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.get
|
831
|
+
airloop = multi_speed_heat_pump.airLoopHVAC.get
|
801
832
|
|
802
|
-
# Define the criteria to find the
|
803
|
-
|
804
|
-
|
805
|
-
cooling_type = coil_cooling_dx_multi_speed.condenserType
|
806
|
-
search_criteria['cooling_type'] = cooling_type
|
807
|
-
|
808
|
-
# TODO: Standards - add split system vs single package to model
|
809
|
-
# For now, assume single package as default
|
810
|
-
sub_category = 'Single Package'
|
811
|
-
|
812
|
-
# Determine the heating type if unitary or zone hvac
|
813
|
-
heat_pump = false
|
814
|
-
heating_type = nil
|
815
|
-
containing_comp = nil
|
816
|
-
if coil_cooling_dx_multi_speed.airLoopHVAC.empty?
|
817
|
-
if coil_cooling_dx_multi_speed.containingHVACComponent.is_initialized
|
818
|
-
containing_comp = coil_cooling_dx_multi_speed.containingHVACComponent.get
|
819
|
-
if containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.is_initialized
|
820
|
-
htg_coil = containing_comp.to_AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.get.heatingCoil
|
821
|
-
if htg_coil.to_CoilHeatingDXMultiSpeed.is_initialized
|
822
|
-
heat_pump = true
|
823
|
-
heating_type = 'Electric Resistance or None'
|
824
|
-
elsif htg_coil.to_CoilHeatingGasMultiStage.is_initialized
|
825
|
-
heating_type = 'All Other'
|
826
|
-
end
|
827
|
-
end # TODO: Add other unitary systems
|
828
|
-
elsif coil_cooling_dx_multi_speed.containingZoneHVACComponent.is_initialized
|
829
|
-
containing_comp = coil_cooling_dx_multi_speed.containingZoneHVACComponent.get
|
830
|
-
if containing_comp.to_ZoneHVACPackagedTerminalAirConditioner.is_initialized
|
831
|
-
sub_category = 'PTAC'
|
832
|
-
htg_coil = containing_comp.to_ZoneHVACPackagedTerminalAirConditioner.get.heatingCoil
|
833
|
-
if htg_coil.to_CoilHeatingElectric.is_initialized
|
834
|
-
heating_type = 'Electric Resistance or None'
|
835
|
-
elsif htg_coil.to_CoilHeatingWater.is_initialized || htg_coil.to_CoilHeatingGas.is_initialized || htg_col.to_CoilHeatingGasMultiStage
|
836
|
-
heating_type = 'All Other'
|
837
|
-
end
|
838
|
-
end # TODO: Add other zone hvac systems
|
839
|
-
end
|
840
|
-
end
|
833
|
+
# Define the criteria to find the properties in the hvac standards data set
|
834
|
+
search_criteria = coil_dx_find_search_criteria(coil_cooling_dx_multi_speed)
|
835
|
+
capacity_w = coil_cooling_dx_multi_speed_find_capacity(coil_cooling_dx_multi_speed)
|
841
836
|
|
842
|
-
#
|
843
|
-
|
844
|
-
|
845
|
-
|
846
|
-
|
847
|
-
search_criteria['subcategory'] = sub_category
|
848
|
-
|
849
|
-
# Get the coil capacity
|
850
|
-
capacity_w = nil
|
851
|
-
clg_stages = stages
|
852
|
-
if clg_stages.last.grossRatedTotalCoolingCapacity.is_initialized
|
853
|
-
capacity_w = clg_stages.last.grossRatedTotalCoolingCapacity.get
|
854
|
-
elsif coil_cooling_dx_multi_speed.autosizedSpeed4GrossRatedTotalCoolingCapacity.is_initialized
|
855
|
-
capacity_w = coil_cooling_dx_multi_speed.autosizedSpeed4GrossRatedTotalCoolingCapacity.get
|
856
|
-
else
|
857
|
-
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilCoolingDXMultiSpeed', "For #{coil_cooling_dx_multi_speed.name} capacity is not available, cannot apply efficiency standard.")
|
858
|
-
successfully_set_all_properties = false
|
859
|
-
return successfully_set_all_properties
|
837
|
+
# Find design outside air flow rate and flow fraction
|
838
|
+
controller_oa = nil
|
839
|
+
if airloop.airLoopHVACOutdoorAirSystem.is_initialized
|
840
|
+
oa_system = airloop.airLoopHVACOutdoorAirSystem.get
|
841
|
+
controller_oa = oa_system.getControllerOutdoorAir
|
860
842
|
end
|
861
|
-
|
862
|
-
|
863
|
-
|
864
|
-
|
865
|
-
|
866
|
-
|
867
|
-
|
843
|
+
min_oa_flow_rate, oaf = 0.0,0.0
|
844
|
+
if controller_oa
|
845
|
+
min_oa_flow_rate = nil
|
846
|
+
if controller_oa.minimumOutdoorAirFlowRate.is_initialized
|
847
|
+
min_oa_flow_rate = controller_oa.minimumOutdoorAirFlowRate.get
|
848
|
+
elsif controller_oa.autosizedMinimumOutdoorAirFlowRate.is_initialized
|
849
|
+
min_oa_flow_rate = controller_oa.autosizedMinimumOutdoorAirFlowRate.get
|
850
|
+
end
|
851
|
+
if min_oa_flow_rate then oaf = min_oa_flow_rate.to_f / airloop.autosizedDesignSupplyAirFlowRate.to_f end
|
868
852
|
end
|
869
853
|
|
870
|
-
#
|
854
|
+
# Find required capacity of each stage and total number of stages based on NECB rules
|
855
|
+
# This implementation is limited to 4 stages only. The capacity of stages 1-3 is set to
|
856
|
+
# 66 kW as stipulated by NECB. The capacity of the 4th stage is then allowed to exceed 66 kW
|
857
|
+
# up to the design capacity.
|
871
858
|
stage_cap = []
|
872
859
|
num_stages = (capacity_w / (66.0 * 1000.0) + 0.5).round
|
873
|
-
|
874
|
-
|
860
|
+
max_cap = 66.0 * 1000.0 * num_stages
|
861
|
+
final_num_stages = num_stages
|
862
|
+
case num_stages
|
863
|
+
when 1
|
875
864
|
stage_cap[0] = capacity_w / 2.0
|
876
865
|
stage_cap[1] = 2.0 * stage_cap[0]
|
877
|
-
|
878
|
-
stage_cap[3] = stage_cap[2] + 0.1
|
866
|
+
final_num_stages = 2
|
879
867
|
else
|
880
868
|
stage_cap[0] = 66.0 * 1000.0
|
881
869
|
stage_cap[1] = 2.0 * stage_cap[0]
|
882
|
-
|
883
|
-
|
884
|
-
|
885
|
-
elsif num_stages == 3
|
870
|
+
case num_stages
|
871
|
+
when 2
|
872
|
+
when 3
|
886
873
|
stage_cap[2] = 3.0 * stage_cap[0]
|
887
|
-
|
888
|
-
|
874
|
+
else
|
875
|
+
final_num_stages = 4
|
889
876
|
stage_cap[2] = 3.0 * stage_cap[0]
|
890
|
-
stage_cap[3] =
|
877
|
+
stage_cap[3] = max_cap
|
891
878
|
end
|
892
879
|
end
|
893
|
-
|
894
|
-
|
895
|
-
|
896
|
-
|
880
|
+
|
881
|
+
# Set final number of cooling stages and create missing stages if needed
|
882
|
+
for istage in 2..final_num_stages-1
|
883
|
+
new_clg_stage = OpenStudio::Model::CoilCoolingDXMultiSpeedStageData.new(model)
|
884
|
+
coil_cooling_dx_multi_speed.addStage(new_clg_stage)
|
885
|
+
end
|
886
|
+
multi_speed_heat_pump.setNumberofSpeedsforCooling(final_num_stages)
|
887
|
+
|
888
|
+
# Set final capacities for each of the stages. The flow rate for each of the stages
|
889
|
+
# is maintained above the outside air flow rate
|
890
|
+
coil_cooling_dx_multi_speed.stages[0].setGrossRatedTotalCoolingCapacity(stage_cap[0])
|
891
|
+
coil_cooling_dx_multi_speed.stages[1].setGrossRatedTotalCoolingCapacity(stage_cap[1])
|
892
|
+
case coil_cooling_dx_multi_speed.stages.size
|
893
|
+
when 2
|
894
|
+
if (oaf > 0.5) then multi_speed_heat_pump.setSpeed1SupplyAirFlowRateDuringCoolingOperation(min_oa_flow_rate) end
|
895
|
+
when 3
|
896
|
+
coil_cooling_dx_multi_speed.stages[2].setGrossRatedTotalCoolingCapacity(stage_cap[2])
|
897
|
+
if (oaf > 0.333) && (oaf <= 0.666)
|
898
|
+
multi_speed_heat_pump.setSpeed1SupplyAirFlowRateDuringCoolingOperation(min_oa_flow_rate)
|
899
|
+
elsif (oaf > 0.666)
|
900
|
+
multi_speed_heat_pump.setSpeed1SupplyAirFlowRateDuringCoolingOperation(min_oa_flow_rate)
|
901
|
+
multi_speed_heat_pump.setSpeed2SupplyAirFlowRateDuringCoolingOperation(min_oa_flow_rate)
|
902
|
+
end
|
903
|
+
when 4
|
904
|
+
coil_cooling_dx_multi_speed.stages[2].setGrossRatedTotalCoolingCapacity(stage_cap[2])
|
905
|
+
coil_cooling_dx_multi_speed.stages[3].setGrossRatedTotalCoolingCapacity(stage_cap[3])
|
906
|
+
if (oaf > 0.25) && (oaf <= 0.5)
|
907
|
+
multi_speed_heat_pump.setSpeed1SupplyAirFlowRateDuringCoolingOperation(min_oa_flow_rate)
|
908
|
+
elsif (oaf > 0.5) && (oaf <= 0.75)
|
909
|
+
multi_speed_heat_pump.setSpeed1SupplyAirFlowRateDuringCoolingOperation(min_oa_flow_rate)
|
910
|
+
multi_speed_heat_pump.setSpeed2SupplyAirFlowRateDuringCoolingOperation(min_oa_flow_rate)
|
911
|
+
elsif (oaf > 0.75)
|
912
|
+
multi_speed_heat_pump.setSpeed1SupplyAirFlowRateDuringCoolingOperation(min_oa_flow_rate)
|
913
|
+
multi_speed_heat_pump.setSpeed2SupplyAirFlowRateDuringCoolingOperation(min_oa_flow_rate)
|
914
|
+
multi_speed_heat_pump.setSpeed3SupplyAirFlowRateDuringCoolingOperation(min_oa_flow_rate)
|
915
|
+
end
|
897
916
|
end
|
898
917
|
|
899
|
-
|
900
|
-
|
901
|
-
capacity_kbtu_per_hr = OpenStudio.convert(capacity_w, 'W', 'kBtu/hr').get
|
918
|
+
capacity_btu_per_hr = OpenStudio.convert(stage_cap.last, 'W', 'Btu/hr').get
|
919
|
+
capacity_kbtu_per_hr = OpenStudio.convert(stage_cap.last, 'W', 'kBtu/hr').get
|
902
920
|
|
903
921
|
# Lookup efficiencies depending on whether it is a unitary AC or a heat pump
|
904
922
|
ac_props = nil
|
905
|
-
|
906
|
-
|
907
|
-
ac_props = if heat_pump == true
|
908
|
-
model_find_object(heat_pump_table, search_criteria, capacity_btu_per_hr, Date.today)
|
923
|
+
ac_props = if coil_dx_heat_pump?(coil_cooling_dx_multi_speed)
|
924
|
+
model_find_object(standards_data['heat_pumps'], search_criteria, capacity_btu_per_hr, Date.today)
|
909
925
|
else
|
910
|
-
model_find_object(
|
926
|
+
model_find_object(standards_data['unitary_acs'], search_criteria, capacity_btu_per_hr, Date.today)
|
911
927
|
end
|
912
928
|
|
913
929
|
# Check to make sure properties were found
|
914
930
|
if ac_props.nil?
|
915
931
|
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilCoolingDXMultiSpeed', "For #{coil_cooling_dx_multi_speed.name}, cannot find efficiency info, cannot apply efficiency standard.")
|
916
932
|
successfully_set_all_properties = false
|
917
|
-
return
|
933
|
+
return sql_db_vars_map
|
918
934
|
end
|
919
935
|
|
936
|
+
# get clg stages
|
937
|
+
clg_stages = coil_cooling_dx_multi_speed.stages
|
938
|
+
|
920
939
|
# Make the COOL-CAP-FT curve
|
921
|
-
cool_cap_ft = model_add_curve(model, ac_props['cool_cap_ft']
|
940
|
+
cool_cap_ft = model_add_curve(model, ac_props['cool_cap_ft'])
|
922
941
|
if cool_cap_ft
|
923
942
|
clg_stages.each do |stage|
|
924
943
|
stage.setTotalCoolingCapacityFunctionofTemperatureCurve(cool_cap_ft)
|
@@ -926,10 +945,11 @@ class NECB2011
|
|
926
945
|
else
|
927
946
|
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilCoolingDXMultiSpeed', "For #{coil_cooling_dx_multi_speed.name}, cannot find cool_cap_ft curve, will not be set.")
|
928
947
|
successfully_set_all_properties = false
|
948
|
+
return sql_db_vars_map
|
929
949
|
end
|
930
950
|
|
931
951
|
# Make the COOL-CAP-FFLOW curve
|
932
|
-
cool_cap_fflow = model_add_curve(model, ac_props['cool_cap_fflow']
|
952
|
+
cool_cap_fflow = model_add_curve(model, ac_props['cool_cap_fflow'])
|
933
953
|
if cool_cap_fflow
|
934
954
|
clg_stages.each do |stage|
|
935
955
|
stage.setTotalCoolingCapacityFunctionofFlowFractionCurve(cool_cap_fflow)
|
@@ -937,10 +957,11 @@ class NECB2011
|
|
937
957
|
else
|
938
958
|
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilCoolingDXMultiSpeed', "For #{coil_cooling_dx_multi_speed.name}, cannot find cool_cap_fflow curve, will not be set.")
|
939
959
|
successfully_set_all_properties = false
|
960
|
+
return sql_db_vars_map
|
940
961
|
end
|
941
962
|
|
942
963
|
# Make the COOL-EIR-FT curve
|
943
|
-
cool_eir_ft = model_add_curve(model, ac_props['cool_eir_ft']
|
964
|
+
cool_eir_ft = model_add_curve(model, ac_props['cool_eir_ft'])
|
944
965
|
if cool_eir_ft
|
945
966
|
clg_stages.each do |stage|
|
946
967
|
stage.setEnergyInputRatioFunctionofTemperatureCurve(cool_eir_ft)
|
@@ -948,10 +969,11 @@ class NECB2011
|
|
948
969
|
else
|
949
970
|
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilCoolingDXMultiSpeed', "For #{coil_cooling_dx_multi_speed.name}, cannot find cool_eir_ft curve, will not be set.")
|
950
971
|
successfully_set_all_properties = false
|
972
|
+
return sql_db_vars_map
|
951
973
|
end
|
952
974
|
|
953
975
|
# Make the COOL-EIR-FFLOW curve
|
954
|
-
cool_eir_fflow = model_add_curve(model, ac_props['cool_eir_fflow']
|
976
|
+
cool_eir_fflow = model_add_curve(model, ac_props['cool_eir_fflow'])
|
955
977
|
if cool_eir_fflow
|
956
978
|
clg_stages.each do |stage|
|
957
979
|
stage.setEnergyInputRatioFunctionofFlowFractionCurve(cool_eir_fflow)
|
@@ -959,10 +981,11 @@ class NECB2011
|
|
959
981
|
else
|
960
982
|
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilCoolingDXMultiSpeed', "For #{coil_cooling_dx_multi_speed.name}, cannot find cool_eir_fflow curve, will not be set.")
|
961
983
|
successfully_set_all_properties = false
|
984
|
+
return sql_db_vars_map
|
962
985
|
end
|
963
986
|
|
964
987
|
# Make the COOL-PLF-FPLR curve
|
965
|
-
cool_plf_fplr = model_add_curve(model, ac_props['cool_plf_fplr']
|
988
|
+
cool_plf_fplr = model_add_curve(model, ac_props['cool_plf_fplr'])
|
966
989
|
if cool_plf_fplr
|
967
990
|
clg_stages.each do |stage|
|
968
991
|
stage.setPartLoadFractionCorrelationCurve(cool_plf_fplr)
|
@@ -970,128 +993,259 @@ class NECB2011
|
|
970
993
|
else
|
971
994
|
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilCoolingDXMultiSpeed', "For #{coil_cooling_dx_multi_speed.name}, cannot find cool_plf_fplr curve, will not be set.")
|
972
995
|
successfully_set_all_properties = false
|
996
|
+
return sql_db_vars_map
|
973
997
|
end
|
974
998
|
|
975
|
-
#
|
976
|
-
cop =
|
977
|
-
|
978
|
-
if coil_dx_subcategory(coil_cooling_dx_multi_speed) == 'PTAC'
|
979
|
-
ptac_eer_coeff_1 = ac_props['ptac_eer_coefficient_1']
|
980
|
-
ptac_eer_coeff_2 = ac_props['ptac_eer_coefficient_2']
|
981
|
-
capacity_btu_per_hr = 7000 if capacity_btu_per_hr < 7000
|
982
|
-
capacity_btu_per_hr = 15_000 if capacity_btu_per_hr > 15_000
|
983
|
-
ptac_eer = ptac_eer_coeff_1 + (ptac_eer_coeff_2 * capacity_btu_per_hr)
|
984
|
-
cop = eer_to_cop(ptac_eer)
|
985
|
-
# self.setName("#{self.name} #{capacity_kbtu_per_hr.round}kBtu/hr #{ptac_eer}EER")
|
986
|
-
new_comp_name = "#{coil_cooling_dx_multi_speed.name} #{capacity_kbtu_per_hr.round}kBtu/hr #{ptac_eer}EER"
|
987
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilCoolingDXMultiSpeed', "For #{template}: #{coil_cooling_dx_multi_speed.name}: #{cooling_type} #{heating_type} #{subcategory} Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; EER = #{ptac_eer}")
|
988
|
-
end
|
989
|
-
|
990
|
-
# If specified as SEER
|
991
|
-
unless ac_props['minimum_seasonal_energy_efficiency_ratio'].nil?
|
992
|
-
min_seer = ac_props['minimum_seasonal_energy_efficiency_ratio']
|
993
|
-
cop = seer_to_cop(min_seer)
|
994
|
-
new_comp_name = "#{coil_cooling_dx_multi_speed.name} #{capacity_kbtu_per_hr.round}kBtu/hr #{min_seer}SEER"
|
995
|
-
# self.setName("#{self.name} #{capacity_kbtu_per_hr.round}kBtu/hr #{min_seer}SEER")
|
996
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilCoolingDXMultiSpeed', "For #{template}: #{coil_cooling_dx_multi_speed.name}: #{cooling_type} #{heating_type} #{subcategory} Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; SEER = #{min_seer}")
|
997
|
-
end
|
998
|
-
|
999
|
-
# If specified as EER
|
1000
|
-
unless ac_props['minimum_energy_efficiency_ratio'].nil?
|
1001
|
-
min_eer = ac_props['minimum_energy_efficiency_ratio']
|
1002
|
-
cop = eer_to_cop(min_eer)
|
1003
|
-
new_comp_name = "#{coil_cooling_dx_multi_speed.name} #{capacity_kbtu_per_hr.round}kBtu/hr #{min_eer}EER"
|
1004
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilCoolingDXMultiSpeed', "For #{template}: #{coil_cooling_dx_multi_speed.name}: #{cooling_type} #{heating_type} #{subcategory} Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; EER = #{min_eer}")
|
1005
|
-
end
|
1006
|
-
|
1007
|
-
# if specified as SEER (heat pump)
|
1008
|
-
unless ac_props['minimum_seasonal_efficiency'].nil?
|
1009
|
-
min_seer = ac_props['minimum_seasonal_efficiency']
|
1010
|
-
cop = seer_to_cop(min_seer)
|
1011
|
-
new_comp_name = "#{coil_cooling_dx_multi_speed.name} #{capacity_kbtu_per_hr.round}kBtu/hr #{min_seer}SEER"
|
1012
|
-
# self.setName("#{self.name} #{capacity_kbtu_per_hr.round}kBtu/hr #{min_seer}SEER")
|
1013
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilCoolingDXMultiSpeed', "For #{template}: #{coil_cooling_dx_multi_speed.name}: #{cooling_type} #{heating_type} #{subcategory} Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; SEER = #{min_seer}")
|
1014
|
-
end
|
1015
|
-
|
1016
|
-
# If specified as EER (heat pump)
|
1017
|
-
unless ac_props['minimum_full_load_efficiency'].nil?
|
1018
|
-
min_eer = ac_props['minimum_full_load_efficiency']
|
1019
|
-
cop = eer_to_cop(min_eer)
|
1020
|
-
new_comp_name = "#{coil_cooling_dx_multi_speed.name} #{capacity_kbtu_per_hr.round}kBtu/hr #{min_eer}EER"
|
1021
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilCoolingDXMultiSpeed', "For #{template}: #{coil_cooling_dx_multi_speed.name}: #{cooling_type} #{heating_type} #{subcategory} Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; EER = #{min_eer}")
|
1022
|
-
end
|
1023
|
-
|
1024
|
-
sql_db_vars_map[new_comp_name] = name.to_s
|
1025
|
-
coil_cooling_dx_multi_speed.setName(new_comp_name)
|
1026
|
-
|
1027
|
-
# Set the efficiency values
|
1028
|
-
|
999
|
+
# Set the COP values
|
1000
|
+
cop, new_comp_name = coil_cooling_dx_multi_speed_standard_minimum_cop(coil_cooling_dx_multi_speed)
|
1029
1001
|
unless cop.nil?
|
1030
1002
|
clg_stages.each do |istage|
|
1031
1003
|
istage.setGrossRatedCoolingCOP(cop)
|
1032
1004
|
end
|
1033
1005
|
end
|
1006
|
+
sql_db_vars_map[new_comp_name] = coil_cooling_dx_multi_speed.name.to_s
|
1007
|
+
coil_cooling_dx_multi_speed.setName(new_comp_name)
|
1008
|
+
|
1009
|
+
# It was found that the heat pump OS object doesn't respond to the call to turn on from the
|
1010
|
+
# system availability manager night cycle. This EMS script is then implemented to check the status
|
1011
|
+
# of the system availability manager night cycle and force the heat pump to turn on when needed. The
|
1012
|
+
# heat pump is still turned on when its availability schedule calls for it.
|
1013
|
+
create_ems_to_turn_on_AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed_for_night_cycle(multi_speed_heat_pump)
|
1034
1014
|
|
1035
1015
|
return sql_db_vars_map
|
1016
|
+
|
1017
|
+
end
|
1018
|
+
|
1019
|
+
# Create EMS to turn on "AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed" in response to a call
|
1020
|
+
# from the night cycle availability manager of the air loop. It was found that this object
|
1021
|
+
# doesn't respond properly to this call from the night cycle
|
1022
|
+
def create_ems_to_turn_on_AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed_for_night_cycle(multi_speed_heat_pump)
|
1023
|
+
model = multi_speed_heat_pump.model
|
1024
|
+
avail_manager_name = nil
|
1025
|
+
if multi_speed_heat_pump.airLoopHVAC.is_initialized
|
1026
|
+
if not multi_speed_heat_pump.airLoopHVAC.get.availabilityManagers.empty?
|
1027
|
+
avail_manager_name = multi_speed_heat_pump.airLoopHVAC.get.availabilityManagers[0].name.to_s
|
1028
|
+
end
|
1029
|
+
end
|
1030
|
+
if avail_manager_name
|
1031
|
+
avail_manager_out_var_name = "Availability Manager Night Cycle Control Status"
|
1032
|
+
avail_manager_out_var = OpenStudio::Model::OutputVariable.new(avail_manager_out_var_name, model)
|
1033
|
+
avail_manager_out_var.setKeyValue(avail_manager_name)
|
1034
|
+
avail_manager_out_var.setReportingFrequency("Timestep")
|
1035
|
+
night_cycle_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, avail_manager_out_var)
|
1036
|
+
heat_pump_avail_sch = nil
|
1037
|
+
if multi_speed_heat_pump.availabilitySchedule.is_initialized
|
1038
|
+
heat_pump_avail_sch = multi_speed_heat_pump.availabilitySchedule.get
|
1039
|
+
elsif multi_speed_heat_pump.airLoopHVAC.get.availabilitySchedule.is_initialized
|
1040
|
+
heat_pump_avail_sch = multi_speed_heat_pump.airLoopHVAC.get.availabilitySchedule.get
|
1041
|
+
else
|
1042
|
+
heat_pump_avail_sch = OpenStudio::Model::ScheduleConstant.new(model)
|
1043
|
+
heat_pump_avail_sch.setValue(1.0)
|
1044
|
+
end
|
1045
|
+
heat_pump_avail_sch_var = OpenStudio::Model::OutputVariable.new("Schedule Value", model)
|
1046
|
+
heat_pump_avail_sch_var.setKeyValue(heat_pump_avail_sch.name.to_s)
|
1047
|
+
heat_pump_avail_sch_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, heat_pump_avail_sch_var)
|
1048
|
+
updated_heat_pump_avail_sch = OpenStudio::Model::ScheduleConstant.new(model)
|
1049
|
+
multi_speed_heat_pump.setAvailabilitySchedule(updated_heat_pump_avail_sch)
|
1050
|
+
heat_pump_avail_sch_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(updated_heat_pump_avail_sch, "Schedule:Constant", "Schedule Value")
|
1051
|
+
heat_pump_avail_sch_prog = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
|
1052
|
+
heat_pump_avail_sch_prog.setName("#{multi_speed_heat_pump.name.to_s.gsub(/[ +-.]/,'_')} Availability Schedule Program by Line")
|
1053
|
+
heat_pump_avail_sch_prog_body = <<-EMS
|
1054
|
+
IF #{heat_pump_avail_sch_sensor.handle} > 0.0
|
1055
|
+
SET #{heat_pump_avail_sch_actuator.handle} = #{heat_pump_avail_sch_sensor.handle}
|
1056
|
+
ELSEIF #{night_cycle_sensor.handle} == 2.0
|
1057
|
+
SET #{heat_pump_avail_sch_actuator.handle} = 1.0
|
1058
|
+
ELSE
|
1059
|
+
SET #{heat_pump_avail_sch_actuator.handle} = 0.0
|
1060
|
+
ENDIF
|
1061
|
+
EMS
|
1062
|
+
heat_pump_avail_sch_prog.setBody(heat_pump_avail_sch_prog_body)
|
1063
|
+
pcm = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
|
1064
|
+
pcm.setName("#{heat_pump_avail_sch_prog.name.to_s.gsub(/[ +-.]/,'_')} Calling Manager")
|
1065
|
+
pcm.setCallingPoint('InsideHVACSystemIterationLoop')
|
1066
|
+
pcm.addProgram(heat_pump_avail_sch_prog)
|
1067
|
+
end
|
1036
1068
|
end
|
1037
1069
|
|
1038
1070
|
# Applies the standard efficiency ratings and typical performance curves to this object.
|
1039
1071
|
#
|
1040
1072
|
# @return [Bool] true if successful, false if not
|
1041
|
-
def coil_heating_gas_multi_stage_apply_efficiency_and_curves(coil_heating_gas_multi_stage
|
1073
|
+
def coil_heating_gas_multi_stage_apply_efficiency_and_curves(coil_heating_gas_multi_stage)
|
1042
1074
|
successfully_set_all_properties = true
|
1075
|
+
model = coil_heating_gas_multi_stage.model
|
1076
|
+
|
1077
|
+
# get multi speed heat pump and air loop
|
1078
|
+
multi_speed_heat_pump = nil
|
1079
|
+
multi_speed_heat_pumps = model.getAirLoopHVACUnitaryHeatPumpAirToAirMultiSpeeds
|
1080
|
+
multi_speed_heat_pumps.each do |iheat_pump|
|
1081
|
+
htg_coil = iheat_pump.heatingCoil
|
1082
|
+
if htg_coil.name.to_s.strip == coil_heating_gas_multi_stage.name.to_s.strip
|
1083
|
+
multi_speed_heat_pump = iheat_pump
|
1084
|
+
break
|
1085
|
+
end
|
1086
|
+
end
|
1087
|
+
airloop = multi_speed_heat_pump.airLoopHVAC.get
|
1043
1088
|
|
1044
|
-
#
|
1045
|
-
|
1046
|
-
|
1047
|
-
|
1048
|
-
|
1049
|
-
|
1050
|
-
|
1051
|
-
|
1052
|
-
|
1053
|
-
|
1054
|
-
|
1089
|
+
# Define the criteria to find the properties in the hvac standards data set.
|
1090
|
+
search_criteria = coil_heating_gas_multi_stage_find_search_criteria(coil_heating_gas_multi_stage)
|
1091
|
+
fuel_type = search_criteria["fuel_type"]
|
1092
|
+
capacity_w = coil_heating_gas_multi_stage_find_capacity(coil_heating_gas_multi_stage)
|
1093
|
+
|
1094
|
+
# Find system design outside air flow rate and fraction
|
1095
|
+
controller_oa = nil
|
1096
|
+
if airloop.airLoopHVACOutdoorAirSystem.is_initialized
|
1097
|
+
oa_system = airloop.airLoopHVACOutdoorAirSystem.get
|
1098
|
+
controller_oa = oa_system.getControllerOutdoorAir
|
1099
|
+
end
|
1100
|
+
min_oa_flow_rate, oaf = 0.0,0.0
|
1101
|
+
if controller_oa
|
1102
|
+
min_oa_flow_rate = nil
|
1103
|
+
if controller_oa.minimumOutdoorAirFlowRate.is_initialized
|
1104
|
+
min_oa_flow_rate = controller_oa.minimumOutdoorAirFlowRate.get
|
1105
|
+
elsif controller_oa.autosizedMinimumOutdoorAirFlowRate.is_initialized
|
1106
|
+
min_oa_flow_rate = controller_oa.autosizedMinimumOutdoorAirFlowRate.get
|
1107
|
+
end
|
1108
|
+
if min_oa_flow_rate then oaf = min_oa_flow_rate.to_f / airloop.autosizedDesignSupplyAirFlowRate.to_f end
|
1055
1109
|
end
|
1056
1110
|
|
1057
|
-
#
|
1111
|
+
# Find capacities of each of the stages and the total number of stages required based on NECB rules.
|
1112
|
+
# This implementation is limited to 4 stages. The capacity of stages 1-3 is set to 66 kW as stipulated
|
1113
|
+
# by NECB. The capacity of the 4th stage can exceed 66 kW up to the design capacity.
|
1114
|
+
htg_stages = coil_heating_gas_multi_stage.stages
|
1058
1115
|
num_stages = (capacity_w / (66.0 * 1000.0) + 0.5).round
|
1059
|
-
|
1116
|
+
max_cap = 66.0 * 1000.0 * num_stages
|
1060
1117
|
stage_cap = []
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
stage_cap[
|
1065
|
-
stage_cap[3] = stage_cap[2] + 0.1
|
1118
|
+
final_num_stages = num_stages
|
1119
|
+
if capacity_w == 0.001
|
1120
|
+
final_num_stages = 1
|
1121
|
+
stage_cap[0] = capacity_w
|
1066
1122
|
else
|
1067
|
-
|
1068
|
-
|
1069
|
-
|
1070
|
-
stage_cap[
|
1071
|
-
|
1072
|
-
|
1073
|
-
stage_cap[
|
1074
|
-
stage_cap[
|
1075
|
-
|
1076
|
-
|
1077
|
-
|
1123
|
+
case num_stages
|
1124
|
+
when 1
|
1125
|
+
stage_cap[0] = capacity_w / 2.0
|
1126
|
+
stage_cap[1] = 2.0 * stage_cap[0]
|
1127
|
+
final_num_stages = 2
|
1128
|
+
else
|
1129
|
+
stage_cap[0] = 66.0 * 1000.0
|
1130
|
+
stage_cap[1] = 2.0 * stage_cap[0]
|
1131
|
+
case num_stages
|
1132
|
+
when 2
|
1133
|
+
when 3
|
1134
|
+
stage_cap[2] = 3.0 * stage_cap[0]
|
1135
|
+
else
|
1136
|
+
final_num_stages = 4
|
1137
|
+
stage_cap[2] = 3.0 * stage_cap[0]
|
1138
|
+
stage_cap[3] = max_cap
|
1139
|
+
end
|
1078
1140
|
end
|
1079
1141
|
end
|
1080
|
-
|
1081
|
-
|
1082
|
-
|
1142
|
+
|
1143
|
+
# Set final number of stages and create missing stages if needed
|
1144
|
+
for istage in 1..final_num_stages-1
|
1145
|
+
new_htg_stage = OpenStudio::Model::CoilHeatingGasMultiStageStageData.new(model)
|
1146
|
+
coil_heating_gas_multi_stage.addStage(new_htg_stage)
|
1147
|
+
end
|
1148
|
+
multi_speed_heat_pump.setNumberofSpeedsforHeating(final_num_stages)
|
1149
|
+
|
1150
|
+
# Set final capacities for each of the stages. The air flow rate for each of the stages
|
1151
|
+
# is maintained above the outside air flow rate
|
1152
|
+
coil_heating_gas_multi_stage.stages[0].setNominalCapacity(stage_cap[0])
|
1153
|
+
case coil_heating_gas_multi_stage.stages.size
|
1154
|
+
when 2
|
1155
|
+
coil_heating_gas_multi_stage.stages[1].setNominalCapacity(stage_cap[1])
|
1156
|
+
if (oaf > 0.5) then multi_speed_heat_pump.setSpeed1SupplyAirFlowRateDuringHeatingOperation(min_oa_flow_rate) end
|
1157
|
+
when 3
|
1158
|
+
coil_heating_gas_multi_stage.stages[1].setNominalCapacity(stage_cap[1])
|
1159
|
+
coil_heating_gas_multi_stage.stages[2].setNominalCapacity(stage_cap[2])
|
1160
|
+
if (oaf > 0.333) && (oaf <= 0.666)
|
1161
|
+
multi_speed_heat_pump.setSpeed1SupplyAirFlowRateDuringHeatingOperation(min_oa_flow_rate)
|
1162
|
+
elsif (oaf > 0.666)
|
1163
|
+
multi_speed_heat_pump.setSpeed1SupplyAirFlowRateDuringHeatingOperation(min_oa_flow_rate)
|
1164
|
+
multi_speed_heat_pump.setSpeed2SupplyAirFlowRateDuringHeatingOperation(min_oa_flow_rate)
|
1165
|
+
end
|
1166
|
+
when 4
|
1167
|
+
coil_heating_gas_multi_stage.stages[1].setNominalCapacity(stage_cap[1])
|
1168
|
+
coil_heating_gas_multi_stage.stages[2].setNominalCapacity(stage_cap[2])
|
1169
|
+
coil_heating_gas_multi_stage.stages[3].setNominalCapacity(stage_cap[3])
|
1170
|
+
if (oaf > 0.25) && (oaf <= 0.5)
|
1171
|
+
multi_speed_heat_pump.setSpeed1SupplyAirFlowRateDuringHeatingOperation(min_oa_flow_rate)
|
1172
|
+
elsif (oaf > 0.5) && (oaf <= 0.75)
|
1173
|
+
multi_speed_heat_pump.setSpeed1SupplyAirFlowRateDuringHeatingOperation(min_oa_flow_rate)
|
1174
|
+
multi_speed_heat_pump.setSpeed2SupplyAirFlowRateDuringHeatingOperation(min_oa_flow_rate)
|
1175
|
+
elsif (oaf > 0.75)
|
1176
|
+
multi_speed_heat_pump.setSpeed1SupplyAirFlowRateDuringHeatingOperation(min_oa_flow_rate)
|
1177
|
+
multi_speed_heat_pump.setSpeed2SupplyAirFlowRateDuringHeatingOperation(min_oa_flow_rate)
|
1178
|
+
multi_speed_heat_pump.setSpeed3SupplyAirFlowRateDuringHeatingOperation(min_oa_flow_rate)
|
1179
|
+
end
|
1180
|
+
end
|
1181
|
+
|
1182
|
+
# Convert capacity to Btu/hr
|
1183
|
+
capacity_btu_per_hr = OpenStudio.convert(stage_cap.last, 'W', 'Btu/hr').get
|
1184
|
+
capacity_kbtu_per_hr = OpenStudio.convert(stage_cap.last, 'W', 'kBtu/hr').get
|
1185
|
+
|
1186
|
+
# Lookup efficiencies
|
1187
|
+
heater_props = nil
|
1188
|
+
heater_props = model_find_object(standards_data['furnaces'], search_criteria, capacity_btu_per_hr, Date.today)
|
1189
|
+
|
1190
|
+
# Check to make sure properties were found
|
1191
|
+
if heater_props.nil?
|
1192
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingGasMultiSpeed', "For #{coil_heating_gas_multi_stage.name}, cannot find efficiency info, cannot apply efficiency standard.")
|
1193
|
+
successfully_set_all_properties = false
|
1194
|
+
return successfully_set_all_properties
|
1083
1195
|
end
|
1084
|
-
# PLF vs PLR curve
|
1085
|
-
furnace_plffplr_curve_name = 'FURNACE-EFFPLR-NECB2011'
|
1086
1196
|
|
1087
|
-
#
|
1088
|
-
|
1089
|
-
if
|
1090
|
-
coil_heating_gas_multi_stage.setPartLoadFractionCorrelationCurve(
|
1197
|
+
# Make the EFFPLR curve
|
1198
|
+
efffplr = model_add_curve(coil_heating_gas_multi_stage.model, heater_props['efffplr'])
|
1199
|
+
if efffplr
|
1200
|
+
coil_heating_gas_multi_stage.setPartLoadFractionCorrelationCurve(efffplr)
|
1091
1201
|
else
|
1092
|
-
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingGasMultiStage', "For #{coil_heating_gas_multi_stage.name}, cannot find
|
1202
|
+
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.CoilHeatingGasMultiStage', "For #{coil_heating_gas_multi_stage.name}, cannot find efffplr curve, will not be set.")
|
1093
1203
|
successfully_set_all_properties = false
|
1204
|
+
return successfully_set_all_properties
|
1094
1205
|
end
|
1206
|
+
|
1207
|
+
# Get the minimum efficiency standards
|
1208
|
+
thermal_eff = nil
|
1209
|
+
|
1210
|
+
# If specified as AFUE
|
1211
|
+
unless heater_props['minimum_annual_fuel_utilization_efficiency'].nil?
|
1212
|
+
min_afue = heater_props['minimum_annual_fuel_utilization_efficiency']
|
1213
|
+
thermal_eff = afue_to_thermal_eff(min_afue)
|
1214
|
+
new_comp_name = "#{coil_heating_gas_multi_stage.name} #{capacity_kbtu_per_hr.round}kBtu/hr #{min_afue} AFUE"
|
1215
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilHeatingGasMultiStage', "For #{template}: #{coil_heating_gas_multi_stage.name}: #{fuel_type} Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; AFUE = #{min_afue}")
|
1216
|
+
end
|
1217
|
+
|
1218
|
+
# If specified as thermal efficiency
|
1219
|
+
unless heater_props['minimum_thermal_efficiency'].nil?
|
1220
|
+
thermal_eff = heater_props['minimum_thermal_efficiency']
|
1221
|
+
new_comp_name = "#{coil_heating_gas_multi_stage.name} #{capacity_kbtu_per_hr.round}kBtu/hr #{thermal_eff} Thermal Eff"
|
1222
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.CoilHeatingGasMultiStage', "For #{template}: #{coil_heating_gas_multi_stage.name}: #{fuel_type} Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; Thermal Efficiency = #{thermal_eff}")
|
1223
|
+
end
|
1224
|
+
|
1225
|
+
# If specified as combustion efficiency
|
1226
|
+
unless heater_props['minimum_combustion_efficiency'].nil?
|
1227
|
+
min_comb_eff = heater_props['minimum_combustion_efficiency']
|
1228
|
+
thermal_eff = combustion_eff_to_thermal_eff(min_comb_eff)
|
1229
|
+
new_comp_name = "#{coil_heating_gas_multi_stage.name} #{capacity_kbtu_per_hr.round}kBtu/hr #{min_comb_eff} Combustion Eff"
|
1230
|
+
OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.BoilerHotWater', "For #{template}: #{coil_heating_gas_multi_stage.name}: #{fuel_type} Capacity = #{capacity_kbtu_per_hr.round}kBtu/hr; Combustion Efficiency = #{min_comb_eff}")
|
1231
|
+
end
|
1232
|
+
coil_heating_gas_multi_stage.setName(new_comp_name)
|
1233
|
+
|
1234
|
+
# Set the name
|
1235
|
+
coil_heating_gas_multi_stage.setName(new_comp_name)
|
1236
|
+
|
1237
|
+
# Get heating stages
|
1238
|
+
htg_stages = coil_heating_gas_multi_stage.stages
|
1239
|
+
|
1240
|
+
# Set the efficiency values
|
1241
|
+
unless thermal_eff.nil?
|
1242
|
+
htg_stages.each do |stage|
|
1243
|
+
stage.setGasBurnerEfficiency(thermal_eff)
|
1244
|
+
end
|
1245
|
+
end
|
1246
|
+
|
1247
|
+
return successfully_set_all_properties
|
1248
|
+
|
1095
1249
|
end
|
1096
1250
|
|
1097
1251
|
# Determines the baseline fan impeller efficiency
|
@@ -1139,7 +1293,7 @@ class NECB2011
|
|
1139
1293
|
# Assuming all fan motors are 4-pole ODP
|
1140
1294
|
motor_use = 'FAN'
|
1141
1295
|
motor_type = ''
|
1142
|
-
if fan.class.name == 'OpenStudio::Model::FanConstantVolume'
|
1296
|
+
if (fan.class.name == 'OpenStudio::Model::FanConstantVolume') || (fan.class.name == 'OpenStudio::Model::FanOnOff')
|
1143
1297
|
motor_type = 'CONSTANT'
|
1144
1298
|
elsif fan.class.name == 'OpenStudio::Model::FanVariableVolume'
|
1145
1299
|
# Is this a return or supply fan
|
@@ -1560,51 +1714,7 @@ class NECB2011
|
|
1560
1714
|
|
1561
1715
|
return clg_tower
|
1562
1716
|
end
|
1563
|
-
|
1564
|
-
|
1565
|
-
# Creates thermal zones to contain each space, as defined for each building in the
|
1566
|
-
# system_to_space_map inside the Prototype.building_name
|
1567
|
-
# e.g. (Prototype.secondary_school.rb) file.
|
1568
|
-
#
|
1569
|
-
# @param (see #add_constructions)
|
1570
|
-
# @return [Bool] returns true if successful, false if not
|
1571
|
-
def model_create_thermal_zones(model,
|
1572
|
-
space_multiplier_map = nil)
|
1573
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started creating thermal zones')
|
1574
|
-
space_multiplier_map = {} if space_multiplier_map.nil?
|
1575
|
-
|
1576
|
-
# Remove any Thermal zones assigned
|
1577
|
-
model.getThermalZones.each(&:remove)
|
1578
|
-
|
1579
|
-
# Create a thermal zone for each space in the self
|
1580
|
-
model.getSpaces.sort.each do |space|
|
1581
|
-
zone = OpenStudio::Model::ThermalZone.new(model)
|
1582
|
-
zone.setName("#{space.name} ZN")
|
1583
|
-
unless space_multiplier_map[space.name.to_s].nil? || (space_multiplier_map[space.name.to_s] == 1)
|
1584
|
-
zone.setMultiplier(space_multiplier_map[space.name.to_s])
|
1585
|
-
end
|
1586
|
-
space.setThermalZone(zone)
|
1587
|
-
|
1588
|
-
# Skip thermostat for spaces with no space type
|
1589
|
-
next if space.spaceType.empty?
|
1590
|
-
|
1591
|
-
# Add a thermostat
|
1592
|
-
space_type_name = space.spaceType.get.name.get
|
1593
|
-
thermostat_name = space_type_name + ' Thermostat'
|
1594
|
-
thermostat = model.getThermostatSetpointDualSetpointByName(thermostat_name)
|
1595
|
-
if thermostat.empty?
|
1596
|
-
OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "Thermostat #{thermostat_name} not found for space name: #{space.name}")
|
1597
|
-
else
|
1598
|
-
thermostat_clone = thermostat.get.clone(model).to_ThermostatSetpointDualSetpoint.get
|
1599
|
-
zone.setThermostatSetpointDualSetpoint(thermostat_clone)
|
1600
|
-
# Set Ideal loads to thermal zone for sizing for NECB needs. We need this for sizing.
|
1601
|
-
ideal_loads = OpenStudio::Model::ZoneHVACIdealLoadsAirSystem.new(model)
|
1602
|
-
ideal_loads.addToThermalZone(zone)
|
1603
|
-
end
|
1604
|
-
end
|
1605
|
-
|
1606
|
-
OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished creating thermal zones')
|
1607
|
-
end
|
1717
|
+
|
1608
1718
|
|
1609
1719
|
# This method cycles through the spaces in a thermal zone and then sorts them by story. The method then cycles
|
1610
1720
|
# through the spaces on a story and then calculates the centroid of the spaces in the thermal zone on that floor. The
|