openstudio-standards 0.6.3 → 0.7.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (119) hide show
  1. checksums.yaml +4 -4
  2. data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
  3. data/data/standards/manage_OpenStudio_Standards.rb +2 -49
  4. data/data/standards/openstudio_standards_duplicates_log.csv +1 -7962
  5. data/data/standards/test_performance_expected_dd_results.csv +2005 -97
  6. data/lib/openstudio-standards/create_typical/space_type_ratios.rb +47 -57
  7. data/lib/openstudio-standards/geometry/create.rb +8 -2
  8. data/lib/openstudio-standards/geometry/create_bar.rb +6 -3
  9. data/lib/openstudio-standards/geometry/create_shape.rb +1 -1
  10. data/lib/openstudio-standards/geometry/group.rb +1 -1
  11. data/lib/openstudio-standards/geometry/information.rb +1 -1
  12. data/lib/openstudio-standards/geometry/modify.rb +53 -1
  13. data/lib/openstudio-standards/infiltration/nist_infiltration.rb +1 -1
  14. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +11 -11
  15. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +11 -11
  16. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.hvac_systems.rb +2 -2
  17. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperTallBuilding.rb +44 -47
  18. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.TallBuilding.rb +43 -48
  19. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CentralAirSourceHeatPump.rb +1 -1
  20. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +44 -24
  21. data/lib/openstudio-standards/prototypes/common/objects/Prototype.refrigeration.rb +24 -24
  22. data/lib/openstudio-standards/schedules/information.rb +1 -1
  23. data/lib/openstudio-standards/schedules/parametric.rb +1 -1
  24. data/lib/openstudio-standards/service_water_heating/create_piping_losses.rb +152 -0
  25. data/lib/openstudio-standards/service_water_heating/create_water_heater.rb +544 -0
  26. data/lib/openstudio-standards/service_water_heating/create_water_heating_loop.rb +303 -0
  27. data/lib/openstudio-standards/service_water_heating/create_water_use.rb +95 -0
  28. data/lib/openstudio-standards/space/space.rb +1 -1
  29. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +65 -70
  30. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +12 -14
  31. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +16 -5
  32. data/lib/openstudio-standards/standards/Standards.Model.rb +2 -2
  33. data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +10 -2
  34. data/lib/openstudio-standards/{prototypes/common/objects/Prototype.Model.swh.rb → standards/Standards.ServiceWaterHeating.rb} +209 -139
  35. data/lib/openstudio-standards/standards/Standards.Surface.rb +1 -1
  36. data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +4 -8
  37. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Model.rb +2 -2
  38. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_properties.json +22251 -12963
  39. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_sets.json +91 -91
  40. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_properties.json +8981 -5228
  41. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_properties.json +8935 -5182
  42. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_properties.json +7281 -5391
  43. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_sets.json +91 -91
  44. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_properties.json +9005 -15215
  45. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_sets.json +136 -136
  46. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +1 -1
  47. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_properties.json +8717 -17168
  48. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_sets.json +136 -136
  49. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.constructions.json +1941 -651
  50. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.construction_properties.json +135 -135
  51. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.construction_properties.json +135 -135
  52. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.construction_properties.json +36 -36
  53. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.construction_properties.json +36 -36
  54. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +377 -99
  55. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.SpaceType.rb +2 -2
  56. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.Model.rb +3 -3
  57. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.construction_properties.json +6889 -4044
  58. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.prm_constructions.json +108 -108
  59. data/lib/openstudio-standards/standards/cbes/cbes_pre_1978/data/cbes_pre_1978.construction_properties.json +16 -16
  60. data/lib/openstudio-standards/standards/cbes/cbes_t24_1978/data/cbes_t24_1978.construction_properties.json +16 -16
  61. data/lib/openstudio-standards/standards/cbes/cbes_t24_1992/data/cbes_t24_1992.construction_properties.json +16 -16
  62. data/lib/openstudio-standards/standards/cbes/cbes_t24_2001/data/cbes_t24_2001.construction_properties.json +16 -16
  63. data/lib/openstudio-standards/standards/cbes/cbes_t24_2005/data/cbes_t24_2005.construction_properties.json +16 -16
  64. data/lib/openstudio-standards/standards/cbes/cbes_t24_2008/data/cbes_t24_2008.construction_properties.json +16 -16
  65. data/lib/openstudio-standards/standards/cbes/data/cbes.constructions.json +142 -142
  66. data/lib/openstudio-standards/standards/deer/data/deer.constructions.json +5 -1551
  67. data/lib/openstudio-standards/standards/deer/data/deer.materials.json +40 -0
  68. data/lib/openstudio-standards/standards/deer/deer_1985/data/deer_1985.motors.json +88 -8
  69. data/lib/openstudio-standards/standards/deer/deer_1996/data/deer_1996.motors.json +88 -8
  70. data/lib/openstudio-standards/standards/deer/deer_2003/data/deer_2003.motors.json +88 -8
  71. data/lib/openstudio-standards/standards/deer/deer_2007/data/deer_2007.motors.json +88 -8
  72. data/lib/openstudio-standards/standards/deer/deer_2011/data/deer_2011.motors.json +88 -8
  73. data/lib/openstudio-standards/standards/deer/deer_2014/data/deer_2014.motors.json +88 -8
  74. data/lib/openstudio-standards/standards/deer/deer_2015/data/deer_2015.motors.json +88 -8
  75. data/lib/openstudio-standards/standards/deer/deer_2017/data/deer_2017.motors.json +88 -8
  76. data/lib/openstudio-standards/standards/deer/deer_2020/data/deer_2020.motors.json +88 -8
  77. data/lib/openstudio-standards/standards/deer/deer_2025/data/deer_2025.motors.json +88 -8
  78. data/lib/openstudio-standards/standards/deer/deer_2030/data/deer_2030.motors.json +88 -8
  79. data/lib/openstudio-standards/standards/deer/deer_2035/data/deer_2035.motors.json +88 -8
  80. data/lib/openstudio-standards/standards/deer/deer_2040/data/deer_2040.motors.json +88 -8
  81. data/lib/openstudio-standards/standards/deer/deer_2045/data/deer_2045.motors.json +88 -8
  82. data/lib/openstudio-standards/standards/deer/deer_2050/data/deer_2050.motors.json +88 -8
  83. data/lib/openstudio-standards/standards/deer/deer_2055/data/deer_2055.motors.json +88 -8
  84. data/lib/openstudio-standards/standards/deer/deer_2060/data/deer_2060.motors.json +88 -8
  85. data/lib/openstudio-standards/standards/deer/deer_2065/data/deer_2065.motors.json +88 -8
  86. data/lib/openstudio-standards/standards/deer/deer_2070/data/deer_2070.motors.json +88 -8
  87. data/lib/openstudio-standards/standards/deer/deer_2075/data/deer_2075.motors.json +88 -8
  88. data/lib/openstudio-standards/standards/deer/deer_pre_1975/data/deer_pre_1975.motors.json +88 -8
  89. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/btap_pre1980.rb +17 -0
  90. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_systems.rb +2 -1
  91. data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +4 -4
  92. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +61 -88
  93. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +3 -2
  94. data/lib/openstudio-standards/standards/necb/NECB2011/data/boiler_fuel_type_sets.json +54 -0
  95. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPMidriseApartment.osm +1 -1
  96. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPMultiTower.osm +1 -1
  97. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPPointTower.osm +1 -1
  98. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPTownHouse.osm +1 -1
  99. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernEducation.osm +4 -4
  100. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernHealthCare.osm +4 -4
  101. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +32 -24
  102. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +89 -15
  103. data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +5 -1
  104. data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +22 -65
  105. data/lib/openstudio-standards/standards/necb/NECB2011/system_fuels.rb +19 -0
  106. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +56 -2
  107. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +3 -1
  108. data/lib/openstudio-standards/standards/necb/common/construction_defaults.osm +2 -2
  109. data/lib/openstudio-standards/standards/necb/docs/air_system_names_method.md +127 -0
  110. data/lib/openstudio-standards/thermal_zone/thermal_zone.rb +1 -1
  111. data/lib/openstudio-standards/utilities/template_measure/resources/BTAPMeasureHelper.rb +1 -1
  112. data/lib/openstudio-standards/version.rb +1 -1
  113. data/lib/openstudio-standards/weather/information.rb +61 -5
  114. data/lib/openstudio-standards/weather/modify.rb +1 -1
  115. data/lib/openstudio-standards.rb +5 -3
  116. metadata +12 -63
  117. data/data/standards/OpenStudio_Standards-deer.xlsx +0 -0
  118. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +0 -1100
  119. data/lib/openstudio-standards/service_water_heating/component.rb +0 -189
@@ -31,16 +31,17 @@ class Standard
31
31
  swh_fueltype = prototype_input['main_water_heater_fuel']
32
32
  # Add the main service water loop
33
33
  unless building_type == 'RetailStripmall' && template != 'NECB2011'
34
- main_swh_loop = model_add_swh_loop(model,
35
- 'Main Service Water Loop',
36
- water_heater_zone,
37
- OpenStudio.convert(prototype_input['main_service_water_temperature'], 'F', 'C').get,
38
- prototype_input['main_service_water_pump_head'].to_f,
39
- prototype_input['main_service_water_pump_motor_efficiency'],
40
- OpenStudio.convert(prototype_input['main_water_heater_capacity'], 'Btu/hr', 'W').get,
41
- OpenStudio.convert(prototype_input['main_water_heater_volume'], 'gal', 'm^3').get,
42
- swh_fueltype,
43
- OpenStudio.convert(prototype_input['main_service_water_parasitic_fuel_consumption_rate'], 'Btu/hr', 'W').get)
34
+ main_swh_loop = OpenstudioStandards::ServiceWaterHeating.create_service_water_heating_loop(model,
35
+ system_name: 'Main Service Water Loop',
36
+ service_water_temperature: OpenStudio.convert(prototype_input['main_service_water_temperature'], 'F', 'C').get,
37
+ service_water_pump_head: prototype_input['main_service_water_pump_head'].to_f,
38
+ service_water_pump_motor_efficiency: prototype_input['main_service_water_pump_motor_efficiency'],
39
+ water_heater_capacity: OpenStudio.convert(prototype_input['main_water_heater_capacity'], 'Btu/hr', 'W').get,
40
+ water_heater_volume: OpenStudio.convert(prototype_input['main_water_heater_volume'], 'gal', 'm^3').get,
41
+ water_heater_fuel: swh_fueltype,
42
+ on_cycle_parasitic_fuel_consumption_rate: OpenStudio.convert(prototype_input['main_service_water_parasitic_fuel_consumption_rate'], 'Btu/hr', 'W').get,
43
+ off_cycle_parasitic_fuel_consumption_rate: OpenStudio.convert(prototype_input['main_service_water_parasitic_fuel_consumption_rate'], 'Btu/hr', 'W').get,
44
+ water_heater_thermal_zone: water_heater_zone)
44
45
  end
45
46
 
46
47
  # Attach the end uses if specified in prototype inputs
@@ -52,25 +53,25 @@ class Standard
52
53
  # Only the core spaces have service water
53
54
  ['Core_bottom', 'Core_mid', 'Core_top'].sort.each do |space_name|
54
55
  # ['Mechanical_Bot_ZN_1','Mechanical_Mid_ZN_1','Mechanical_Top_ZN_1'].each do |space_name| # for new space type large office
55
- model_add_swh_end_uses(model,
56
- 'Main',
57
- main_swh_loop,
58
- OpenStudio.convert(prototype_input['main_service_water_peak_flowrate'], 'gal/min', 'm^3/s').get,
59
- prototype_input['main_service_water_flowrate_schedule'],
60
- OpenStudio.convert(prototype_input['main_water_use_temperature'], 'F', 'C').get,
61
- space_name)
56
+ OpenstudioStandards::ServiceWaterHeating.create_water_use(model,
57
+ name: 'Main',
58
+ flow_rate: OpenStudio.convert(prototype_input['main_service_water_peak_flowrate'], 'gal/min', 'm^3/s').get,
59
+ flow_rate_fraction_schedule: model_add_schedule(model, prototype_input['main_service_water_flowrate_schedule']),
60
+ water_use_temperature: OpenStudio.convert(prototype_input['main_water_use_temperature'], 'F', 'C').get,
61
+ service_water_loop: main_swh_loop,
62
+ space: model.getSpaceByName(space_name).get)
62
63
  end
63
64
  elsif building_type == 'LargeOfficeDetailed' && template != 'NECB2011'
64
65
 
65
66
  # Only mechanical rooms have service water
66
67
  ['Mechanical_Bot_ZN_1', 'Mechanical_Mid_ZN_1', 'Mechanical_Top_ZN_1'].sort.each do |space_name| # for new space type large office
67
- model_add_swh_end_uses(model,
68
- 'Main',
69
- main_swh_loop,
70
- OpenStudio.convert(prototype_input['main_service_water_peak_flowrate'], 'gal/min', 'm^3/s').get,
71
- prototype_input['main_service_water_flowrate_schedule'],
72
- OpenStudio.convert(prototype_input['main_water_use_temperature'], 'F', 'C').get,
73
- space_name)
68
+ OpenstudioStandards::ServiceWaterHeating.create_water_use(model,
69
+ name: 'Main',
70
+ flow_rate: OpenStudio.convert(prototype_input['main_service_water_peak_flowrate'], 'gal/min', 'm^3/s').get,
71
+ flow_rate_fraction_schedule: model_add_schedule(model, prototype_input['main_service_water_flowrate_schedule']),
72
+ water_use_temperature: OpenStudio.convert(prototype_input['main_water_use_temperature'], 'F', 'C').get,
73
+ service_water_loop: main_swh_loop,
74
+ space: model.getSpaceByName(space_name).get)
74
75
  end
75
76
  elsif building_type == 'RetailStripmall' && template != 'NECB2011'
76
77
 
@@ -87,38 +88,37 @@ class Standard
87
88
  # Loop through all spaces
88
89
  swh_space_names.zip(swh_sch_names).sort.each do |swh_space_name, swh_sch_name|
89
90
  swh_thermal_zone = model.getSpaceByName(swh_space_name).get.thermalZone.get
90
- main_swh_loop = model_add_swh_loop(model,
91
- "#{swh_thermal_zone.name} Service Water Loop",
92
- swh_thermal_zone,
93
- OpenStudio.convert(prototype_input['main_service_water_temperature'], 'F', 'C').get,
94
- prototype_input['main_service_water_pump_head'].to_f,
95
- prototype_input['main_service_water_pump_motor_efficiency'],
96
- OpenStudio.convert(prototype_input['main_water_heater_capacity'], 'Btu/hr', 'W').get,
97
- OpenStudio.convert(prototype_input['main_water_heater_volume'], 'gal', 'm^3').get,
98
- prototype_input['main_water_heater_fuel'],
99
- OpenStudio.convert(prototype_input['main_service_water_parasitic_fuel_consumption_rate'], 'Btu/hr', 'W').get)
100
-
101
- model_add_swh_end_uses(model,
102
- 'Main',
103
- main_swh_loop,
104
- rated_flow_rate_m3_per_s,
105
- swh_sch_name,
106
- OpenStudio.convert(prototype_input['main_water_use_temperature'], 'F', 'C').get,
107
- swh_space_name)
91
+ main_swh_loop = OpenstudioStandards::ServiceWaterHeating.create_service_water_heating_loop(model,
92
+ system_name: "#{swh_thermal_zone.name} Service Water Loop",
93
+ service_water_temperature: OpenStudio.convert(prototype_input['main_service_water_temperature'], 'F', 'C').get,
94
+ service_water_pump_head: prototype_input['main_service_water_pump_head'].to_f,
95
+ service_water_pump_motor_efficiency: prototype_input['main_service_water_pump_motor_efficiency'],
96
+ water_heater_capacity: OpenStudio.convert(prototype_input['main_water_heater_capacity'], 'Btu/hr', 'W').get,
97
+ water_heater_volume: OpenStudio.convert(prototype_input['main_water_heater_volume'], 'gal', 'm^3').get,
98
+ water_heater_fuel: prototype_input['main_water_heater_fuel'],
99
+ on_cycle_parasitic_fuel_consumption_rate: OpenStudio.convert(prototype_input['main_service_water_parasitic_fuel_consumption_rate'], 'Btu/hr', 'W').get,
100
+ off_cycle_parasitic_fuel_consumption_rate: OpenStudio.convert(prototype_input['main_service_water_parasitic_fuel_consumption_rate'], 'Btu/hr', 'W').get,
101
+ water_heater_thermal_zone: swh_thermal_zone)
102
+
103
+ OpenstudioStandards::ServiceWaterHeating.create_water_use(model,
104
+ name: 'Main',
105
+ flow_rate: rated_flow_rate_m3_per_s,
106
+ flow_rate_fraction_schedule: model_add_schedule(model, swh_sch_name),
107
+ water_use_temperature: OpenStudio.convert(prototype_input['main_water_use_temperature'], 'F', 'C').get,
108
+ service_water_loop: main_swh_loop,
109
+ space: model.getSpaceByName(swh_space_name).get)
108
110
  end
109
111
 
110
112
  elsif prototype_input['main_service_water_peak_flowrate']
111
113
  OpenStudio.logFree(OpenStudio::Debug, 'openstudio.model.Model', 'Adding shw by main_service_water_peak_flowrate')
112
114
 
113
115
  # Attaches the end uses if specified as a lump value in the prototype_input
114
- model_add_swh_end_uses(model,
115
- 'Main',
116
- main_swh_loop,
117
- OpenStudio.convert(prototype_input['main_service_water_peak_flowrate'], 'gal/min', 'm^3/s').get,
118
- prototype_input['main_service_water_flowrate_schedule'],
119
- OpenStudio.convert(prototype_input['main_water_use_temperature'], 'F', 'C').get,
120
- nil)
121
-
116
+ OpenstudioStandards::ServiceWaterHeating.create_water_use(model,
117
+ name: 'Main',
118
+ flow_rate: OpenStudio.convert(prototype_input['main_service_water_peak_flowrate'], 'gal/min', 'm^3/s').get,
119
+ flow_rate_fraction_schedule: model_add_schedule(model, prototype_input['main_service_water_flowrate_schedule']),
120
+ water_use_temperature: OpenStudio.convert(prototype_input['main_water_use_temperature'], 'F', 'C').get,
121
+ service_water_loop: main_swh_loop)
122
122
  else
123
123
  OpenStudio.logFree(OpenStudio::Debug, 'openstudio.model.Model', 'Adding shw by space_type_map')
124
124
 
@@ -161,8 +161,7 @@ class Standard
161
161
 
162
162
  water_fixture = model_add_swh_end_uses_by_space(model,
163
163
  main_swh_loop,
164
- space,
165
- space_multiplier)
164
+ space)
166
165
  unless water_fixture.nil?
167
166
  water_fixtures << water_fixture
168
167
  end
@@ -177,46 +176,44 @@ class Standard
177
176
  # for tall and super tall buildings, add main (multiple) and booster swh in model_custom_hvac_tweaks
178
177
  unless prototype_input['booster_water_heater_volume'].nil? || (building_type == 'TallBuilding' || building_type == 'SuperTallBuilding')
179
178
  # Add the booster water loop
180
- swh_booster_loop = model_add_swh_booster(model,
181
- main_swh_loop,
182
- OpenStudio.convert(prototype_input['booster_water_heater_capacity'], 'Btu/hr', 'W').get,
183
- OpenStudio.convert(prototype_input['booster_water_heater_volume'], 'gal', 'm^3').get,
184
- prototype_input['booster_water_heater_fuel'],
185
- OpenStudio.convert(prototype_input['booster_water_temperature'], 'F', 'C').get,
186
- 0,
187
- nil)
188
-
189
- # Attach the end uses
190
- model_add_booster_swh_end_uses(model,
191
- swh_booster_loop,
192
- OpenStudio.convert(prototype_input['booster_service_water_peak_flowrate'], 'gal/min', 'm^3/s').get,
193
- prototype_input['booster_service_water_flowrate_schedule'],
194
- OpenStudio.convert(prototype_input['booster_water_use_temperature'], 'F', 'C').get)
179
+ swh_booster_loop = OpenstudioStandards::ServiceWaterHeating.create_booster_water_heating_loop(model,
180
+ water_heater_capacity: OpenStudio.convert(prototype_input['booster_water_heater_capacity'], 'Btu/hr', 'W').get,
181
+ water_heater_volume: OpenStudio.convert(prototype_input['booster_water_heater_volume'], 'gal', 'm^3').get,
182
+ water_heater_fuel: prototype_input['booster_water_heater_fuel'],
183
+ service_water_temperature: OpenStudio.convert(prototype_input['booster_water_temperature'], 'F', 'C').get,
184
+ service_water_loop: main_swh_loop)
185
+
186
+ # add booster water use
187
+ OpenstudioStandards::ServiceWaterHeating.create_water_use(model,
188
+ name: 'Booster',
189
+ flow_rate: OpenStudio.convert(prototype_input['booster_service_water_peak_flowrate'], 'gal/min', 'm^3/s').get,
190
+ flow_rate_fraction_schedule: model_add_schedule(model, prototype_input['booster_service_water_flowrate_schedule']),
191
+ water_use_temperature: OpenStudio.convert(prototype_input['booster_water_use_temperature'], 'F', 'C').get,
192
+ service_water_loop: swh_booster_loop)
195
193
  end
196
194
 
197
195
  # Add the laundry water heater, if specified
198
196
  # for tall and super tall buildings, add laundry swh in model_custom_hvac_tweaks
199
197
  unless prototype_input['laundry_water_heater_volume'].nil? || (building_type == 'TallBuilding' || building_type == 'SuperTallBuilding')
200
198
  # Add the laundry service water heating loop
201
- laundry_swh_loop = model_add_swh_loop(model,
202
- 'Laundry Service Water Loop',
203
- nil,
204
- OpenStudio.convert(prototype_input['laundry_service_water_temperature'], 'F', 'C').get,
205
- prototype_input['laundry_service_water_pump_head'].to_f,
206
- prototype_input['laundry_service_water_pump_motor_efficiency'],
207
- OpenStudio.convert(prototype_input['laundry_water_heater_capacity'], 'Btu/hr', 'W').get,
208
- OpenStudio.convert(prototype_input['laundry_water_heater_volume'], 'gal', 'm^3').get,
209
- prototype_input['laundry_water_heater_fuel'],
210
- OpenStudio.convert(prototype_input['laundry_service_water_parasitic_fuel_consumption_rate'], 'Btu/hr', 'W').get)
199
+ laundry_swh_loop = OpenstudioStandards::ServiceWaterHeating.create_service_water_heating_loop(model,
200
+ system_name: 'Laundry Service Water Loop',
201
+ service_water_temperature: OpenStudio.convert(prototype_input['laundry_service_water_temperature'], 'F', 'C').get,
202
+ service_water_pump_head: prototype_input['laundry_service_water_pump_head'].to_f,
203
+ service_water_pump_motor_efficiency: prototype_input['laundry_service_water_pump_motor_efficiency'],
204
+ water_heater_capacity: OpenStudio.convert(prototype_input['laundry_water_heater_capacity'], 'Btu/hr', 'W').get,
205
+ water_heater_volume: OpenStudio.convert(prototype_input['laundry_water_heater_volume'], 'gal', 'm^3').get,
206
+ water_heater_fuel: prototype_input['laundry_water_heater_fuel'],
207
+ on_cycle_parasitic_fuel_consumption_rate: OpenStudio.convert(prototype_input['laundry_service_water_parasitic_fuel_consumption_rate'], 'Btu/hr', 'W').get,
208
+ off_cycle_parasitic_fuel_consumption_rate: OpenStudio.convert(prototype_input['laundry_service_water_parasitic_fuel_consumption_rate'], 'Btu/hr', 'W').get)
211
209
 
212
210
  # Attach the end uses if specified in prototype inputs
213
- model_add_swh_end_uses(model,
214
- 'Laundry',
215
- laundry_swh_loop,
216
- OpenStudio.convert(prototype_input['laundry_service_water_peak_flowrate'], 'gal/min', 'm^3/s').get,
217
- prototype_input['laundry_service_water_flowrate_schedule'],
218
- OpenStudio.convert(prototype_input['laundry_water_use_temperature'], 'F', 'C').get,
219
- nil)
211
+ OpenstudioStandards::ServiceWaterHeating.create_water_use(model,
212
+ name: 'Laundry',
213
+ flow_rate: OpenStudio.convert(prototype_input['laundry_service_water_peak_flowrate'], 'gal/min', 'm^3/s').get,
214
+ flow_rate_fraction_schedule: model_add_schedule(model, prototype_input['laundry_service_water_flowrate_schedule']),
215
+ water_use_temperature: OpenStudio.convert(prototype_input['laundry_water_use_temperature'], 'F', 'C').get,
216
+ service_water_loop: laundry_swh_loop)
220
217
  end
221
218
 
222
219
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding Service Water Heating')
@@ -305,27 +302,23 @@ class Standard
305
302
  peak_flow_rate_m3_per_s -= booster_peak_flow_rate_m3_per_s
306
303
 
307
304
  # Add booster water heater equipment and connections
308
- booster_water_use_equip = model_add_swh_end_uses(model,
309
- "Booster #{use_name}",
310
- loop = nil,
311
- booster_peak_flow_rate_m3_per_s,
312
- flow_rate_fraction_schedule.name.get,
313
- booster_water_temperature_c,
314
- space_name = nil,
315
- frac_sensible: service_water_fraction_sensible,
316
- frac_latent: service_water_fraction_latent)
305
+ booster_water_use_equip = OpenstudioStandards::ServiceWaterHeating.create_water_use(model,
306
+ name: "Booster #{use_name}",
307
+ flow_rate: booster_peak_flow_rate_m3_per_s,
308
+ flow_rate_fraction_schedule: flow_rate_fraction_schedule,
309
+ water_use_temperature: booster_water_temperature_c,
310
+ sensible_fraction: service_water_fraction_sensible,
311
+ latent_fraction: service_water_fraction_latent)
317
312
  end
318
313
 
319
314
  # Add water use equipment and connections
320
- water_use_equip = model_add_swh_end_uses(model,
321
- use_name,
322
- swh_loop = nil,
323
- peak_flow_rate_m3_per_s,
324
- flow_rate_fraction_schedule.name.get,
325
- service_water_temperature_c,
326
- space_name = nil,
327
- frac_sensible: service_water_fraction_sensible,
328
- frac_latent: service_water_fraction_latent)
315
+ water_use_equip = OpenstudioStandards::ServiceWaterHeating.create_water_use(model,
316
+ name: use_name,
317
+ flow_rate: peak_flow_rate_m3_per_s,
318
+ flow_rate_fraction_schedule: flow_rate_fraction_schedule,
319
+ water_use_temperature: service_water_temperature_c,
320
+ sensible_fraction: service_water_fraction_sensible,
321
+ latent_fraction: service_water_fraction_latent)
329
322
 
330
323
  # Water heater sizing
331
324
  case swh_system_type
@@ -357,21 +350,20 @@ class Standard
357
350
  pipe_insul_in = 0.0 if pipe_insul_in.nil?
358
351
 
359
352
  # Add service water loop with water heater
360
- swh_loop = model_add_swh_loop(model,
361
- system_name = "#{space_type.name} Service Water Loop",
362
- water_heater_thermal_zone = nil,
363
- service_water_temperature_c,
364
- service_water_pump_head = 0.01,
365
- service_water_pump_motor_efficiency = 1.0,
366
- water_heater_capacity_w,
367
- water_heater_volume_m3,
368
- water_heater_fuel,
369
- parasitic_fuel_consumption_rate_w = 0,
370
- add_pipe_losses = true,
371
- floor_area_served = OpenStudio.convert(950, 'ft^2', 'm^2').get,
372
- number_of_stories = 1,
373
- pipe_insulation_thickness = OpenStudio.convert(pipe_insul_in, 'in', 'm').get,
374
- num_water_heaters)
353
+ swh_loop = OpenstudioStandards::ServiceWaterHeating.create_service_water_heating_loop(model,
354
+ system_name: "#{space_type.name} Service Water Loop",
355
+ service_water_temperature: service_water_temperature_c,
356
+ service_water_pump_head: 0.01,
357
+ service_water_pump_motor_efficiency: 1.0,
358
+ water_heater_capacity: water_heater_capacity_w,
359
+ water_heater_volume: water_heater_volume_m3,
360
+ water_heater_fuel: water_heater_fuel,
361
+ number_of_water_heaters: num_water_heaters,
362
+ add_piping_losses: true,
363
+ pipe_insulation_thickness: OpenStudio.convert(pipe_insul_in, 'in', 'm').get,
364
+ floor_area: OpenStudio.convert(950, 'ft^2', 'm^2').get,
365
+ number_of_stories: 1)
366
+
375
367
  OpenStudio.logFree(OpenStudio::Warn, 'openstudio.Model.Model', "In model_add_typical, num_water_heaters = #{num_water_heaters}")
376
368
  # Add loop to list
377
369
  swh_systems << swh_loop
@@ -394,14 +386,10 @@ class Standard
394
386
 
395
387
  # Add service water booster loop with water heater
396
388
  # Note that booster water heaters are always assumed to be electric resistance
397
- swh_booster_loop = model_add_swh_booster(model,
398
- swh_loop,
399
- booster_water_heater_sizing[:water_heater_capacity],
400
- water_heater_volume_m3 = OpenStudio.convert(6, 'gal', 'm^3').get,
401
- water_heater_fuel = 'Electricity',
402
- booster_water_temperature_c,
403
- parasitic_fuel_consumption_rate_w = 0.0,
404
- booster_water_heater_thermal_zone = nil)
389
+ swh_booster_loop = OpenstudioStandards::ServiceWaterHeating.create_booster_water_heating_loop(model,
390
+ water_heater_capacity: booster_water_heater_sizing[:water_heater_capacity],
391
+ service_water_temperature: booster_water_temperature_c,
392
+ service_water_loop: swh_loop)
405
393
 
406
394
  # Rename the service water booster loop
407
395
  swh_booster_loop.setName("#{space_type.name} Service Water Booster Loop")
@@ -484,20 +472,18 @@ class Standard
484
472
  water_heater_volume_m3 = water_heater_sizing[:water_heater_volume]
485
473
 
486
474
  # Add a shared service water heating loop with water heater
487
- shared_swh_loop = model_add_swh_loop(model,
488
- "#{stds_bldg_type} Shared Service Water Loop",
489
- water_heater_thermal_zone = nil,
490
- water_heater_temp_c,
491
- service_water_pump_head_pa,
492
- service_water_pump_motor_efficiency,
493
- water_heater_capacity_w,
494
- water_heater_volume_m3,
495
- water_heater_fuel,
496
- parasitic_fuel_consumption_rate_w = 0,
497
- add_pipe_losses = true,
498
- floor_area_served = bldg_type_floor_area_m2,
499
- number_of_stories = num_stories,
500
- pipe_insulation_thickness = OpenStudio.convert(pipe_insul_in, 'in', 'm').get)
475
+ shared_swh_loop = OpenstudioStandards::ServiceWaterHeating.create_service_water_heating_loop(model,
476
+ system_name: "#{stds_bldg_type} Shared Service Water Loop",
477
+ service_water_temperature: water_heater_temp_c,
478
+ service_water_pump_head: service_water_pump_head_pa,
479
+ service_water_pump_motor_efficiency: service_water_pump_motor_efficiency,
480
+ water_heater_capacity: water_heater_capacity_w,
481
+ water_heater_volume: water_heater_volume_m3,
482
+ water_heater_fuel: water_heater_fuel,
483
+ add_piping_losses: true,
484
+ pipe_insulation_thickness: OpenStudio.convert(pipe_insul_in, 'in', 'm').get,
485
+ floor_area: bldg_type_floor_area_m2,
486
+ number_of_stories: num_stories)
501
487
 
502
488
  # Attach all water use equipment to the shared loop
503
489
  water_use_equipment_array.sort.each do |water_use_equip|
@@ -514,6 +500,90 @@ class Standard
514
500
  return swh_systems
515
501
  end
516
502
 
503
+ # This method will add a swh water fixture to the model for the space.
504
+ # It will return a water fixture object, or NIL if there is no water load at all.
505
+ #
506
+ # Adds a WaterUseEquipment object representing the SWH loads of the supplied Space.
507
+ # Attaches this WaterUseEquipment to the supplied PlantLoop via a new WaterUseConnections object.
508
+ #
509
+ # @param model [OpenStudio::Model::Model] OpenStudio model object
510
+ # @param swh_loop [OpenStudio::Model::PlantLoop] the SWH loop to connect the WaterUseEquipment to
511
+ # @param space [OpenStudio::Model::Space] the Space to add a WaterUseEquipment for
512
+ # @param is_flow_per_area [Boolean] if true, use the value in the 'service_water_heating_peak_flow_per_area'
513
+ # field of the space_types JSON. If false, use the value in the 'service_water_heating_peak_flow_rate' field.
514
+ # @return [OpenStudio::Model::WaterUseEquipment] the WaterUseEquipment for the
515
+ def model_add_swh_end_uses_by_space(model,
516
+ swh_loop,
517
+ space,
518
+ is_flow_per_area: true)
519
+ # SpaceType
520
+ if space.spaceType.empty?
521
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Model', "Space #{space.name} does not have a Space Type assigned, cannot add SWH end uses.")
522
+ return nil
523
+ end
524
+ space_type = space.spaceType.get
525
+
526
+ # Standards Building Type
527
+ if space_type.standardsBuildingType.empty?
528
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Model', "Space #{space.name}'s Space Type does not have a Standards Building Type assigned, cannot add SWH end uses.")
529
+ return nil
530
+ end
531
+ stds_bldg_type = space_type.standardsBuildingType.get
532
+ building_type = model_get_lookup_name(stds_bldg_type)
533
+
534
+ # Standards Space Type
535
+ if space_type.standardsSpaceType.empty?
536
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Model', "Space #{space.name}'s Space Type does not have a Standards Space Type assigned, cannot add SWH end uses.")
537
+ return nil
538
+ end
539
+ stds_spc_type = space_type.standardsSpaceType.get
540
+
541
+ # find the specific space_type properties from standard.json
542
+ search_criteria = {
543
+ 'template' => template,
544
+ 'building_type' => building_type,
545
+ 'space_type' => stds_spc_type
546
+ }
547
+ data = standards_lookup_table_first(table_name: 'space_types', search_criteria: search_criteria)
548
+ if data.nil?
549
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.Model.Model', "Could not find space type for: #{search_criteria}.")
550
+ return nil
551
+ end
552
+ space_area = OpenStudio.convert(space.floorArea, 'm^2', 'ft^2').get # ft2
553
+
554
+ # If there is no service hot water load.. Don't bother adding anything.
555
+ if data['service_water_heating_peak_flow_per_area'].to_f < 0.00001 && data['service_water_heating_peak_flow_rate'].to_f < 0.00001
556
+ return nil
557
+ end
558
+
559
+ # rated flow rate
560
+ rated_flow_rate_per_area = data['service_water_heating_peak_flow_per_area'].to_f # gal/h.ft2
561
+ rated_flow_rate_gal_per_hour = if is_flow_per_area
562
+ rated_flow_rate_per_area * space_area * space.multiplier # gal/h
563
+ else
564
+ data['service_water_heating_peak_flow_rate'].to_f
565
+ end
566
+ rated_flow_rate_gal_per_min = rated_flow_rate_gal_per_hour / 60 # gal/h to gal/min
567
+ rated_flow_rate_m3_per_s = OpenStudio.convert(rated_flow_rate_gal_per_min, 'gal/min', 'm^3/s').get
568
+
569
+ # target mixed water temperature
570
+ mixed_water_temp_f = data['service_water_heating_target_temperature']
571
+ mixed_water_temp_c = OpenStudio.convert(mixed_water_temp_f, 'F', 'C').get
572
+
573
+ # flow rate fraction schedule
574
+ flow_rate_fraction_schedule = model_add_schedule(model, data['service_water_heating_schedule'])
575
+
576
+ # create water use
577
+ water_fixture = OpenstudioStandards::ServiceWaterHeating.create_water_use(model,
578
+ name: "#{space.name}",
579
+ flow_rate: rated_flow_rate_m3_per_s,
580
+ flow_rate_fraction_schedule: flow_rate_fraction_schedule,
581
+ water_use_temperature: mixed_water_temp_c,
582
+ service_water_loop: swh_loop)
583
+
584
+ return water_fixture
585
+ end
586
+
517
587
  # Use rules from DOE Prototype Building documentation to determine water heater capacity,
518
588
  # volume, pipe dump losses, and pipe thermal losses.
519
589
  #
@@ -296,7 +296,7 @@ class Standard
296
296
  ua = u_eff * surface.netArea
297
297
  end
298
298
  else
299
- ua = surface.uFactor.get * surface.netArea
299
+ ua = surface.uFactor.get * surface.netArea if surface.uFactor.is_initialized
300
300
  end
301
301
 
302
302
  surface.subSurfaces.sort.each do |subsurface|
@@ -341,11 +341,7 @@ class Standard
341
341
  fan.setAvailabilitySchedule(avail_sch)
342
342
 
343
343
  # Clean name of zone HVAC
344
- equip_name_clean = zone_hvac.name.get.to_s.gsub(/\W/, '').delete('_')
345
- # If the name starts with a number, prepend with a letter
346
- if equip_name_clean[0] =~ /[0-9]/
347
- equip_name_clean = "EQUIP#{equip_name_clean}"
348
- end
344
+ equip_name_clean = ems_friendly_name(zone_hvac.name)
349
345
 
350
346
  # Sensors
351
347
  # Get existing OAT sensor if present
@@ -360,12 +356,12 @@ class Standard
360
356
 
361
357
  # Actuators
362
358
  avail_sch_act = OpenStudio::Model::EnergyManagementSystemActuator.new(avail_sch, 'Schedule:Constant', 'Schedule Value')
363
- avail_sch_act.setName("#{equip_name_clean}VestHtgAvailSch")
359
+ avail_sch_act.setName("#{equip_name_clean}_VestHtgAvailSch")
364
360
 
365
361
  # Programs
366
362
  htg_lim_f = 45
367
363
  vestibule_htg_prg = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
368
- vestibule_htg_prg.setName("#{equip_name_clean}VestHtgPrg")
364
+ vestibule_htg_prg.setName("#{equip_name_clean}_VestHtgPrg")
369
365
  vestibule_htg_prg_body = <<-EMS
370
366
  IF #{oat_db_c_sen.handle} > #{OpenStudio.convert(htg_lim_f, 'F', 'C').get}
371
367
  SET #{avail_sch_act.handle} = 0
@@ -375,7 +371,7 @@ class Standard
375
371
 
376
372
  # Program Calling Managers
377
373
  vestibule_htg_mgr = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
378
- vestibule_htg_mgr.setName("#{equip_name_clean}VestHtgMgr")
374
+ vestibule_htg_mgr.setName("#{equip_name_clean}_VestHtgMgr")
379
375
  vestibule_htg_mgr.setCallingPoint('BeginTimestepBeforePredictor')
380
376
  vestibule_htg_mgr.addProgram(vestibule_htg_prg)
381
377
 
@@ -14,7 +14,7 @@ class ASHRAE9012004 < ASHRAE901
14
14
  if intended_surface_type == 'ExteriorWindow' || intended_surface_type == 'GlassDoor'
15
15
  wwr = OpenstudioStandards::Geometry.model_get_exterior_window_to_wall_ratio(model)
16
16
  if wwr <= 0.1
17
- wwr_range['minimum_percent_of_surface'] = 1.0
17
+ wwr_range['minimum_percent_of_surface'] = 0.0
18
18
  wwr_range['maximum_percent_of_surface'] = 10.0
19
19
  elsif wwr <= 0.2
20
20
  wwr_range['minimum_percent_of_surface'] = 10.001
@@ -27,7 +27,7 @@ class ASHRAE9012004 < ASHRAE901
27
27
  wwr_range['maximum_percent_of_surface'] = 40
28
28
  else
29
29
  wwr_range['minimum_percent_of_surface'] = 40.001
30
- wwr_range['maximum_percent_of_surface'] = 100.0
30
+ wwr_range['maximum_percent_of_surface'] = 50.0
31
31
  end
32
32
  end
33
33
  return wwr_range