openstudio-standards 0.8.5 → 0.8.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. checksums.yaml +4 -4
  2. data/data/standards/test_performance_expected_dd_results.csv +90 -90
  3. data/lib/openstudio-standards/btap/activity.rb +858 -61
  4. data/lib/openstudio-standards/btap/attributes.rb +297 -103
  5. data/lib/openstudio-standards/btap/bridging.rb +1335 -593
  6. data/lib/openstudio-standards/btap/btap.rb +60 -181
  7. data/lib/openstudio-standards/btap/carbon/btap_carbon.rb +199 -142
  8. data/lib/openstudio-standards/btap/common/constructions.json +1275 -0
  9. data/lib/openstudio-standards/btap/common/costs.csv +1969 -0
  10. data/lib/openstudio-standards/btap/common/costs_local_factors.csv +2315 -0
  11. data/lib/openstudio-standards/btap/common/materials_glazing.csv +61 -0
  12. data/lib/openstudio-standards/btap/{common_resources → common}/materials_hvac.csv +1685 -1685
  13. data/lib/openstudio-standards/btap/{common_resources → common}/materials_lighting.csv +266 -266
  14. data/lib/openstudio-standards/btap/common/materials_opaque.csv +214 -0
  15. data/lib/openstudio-standards/btap/common/necb_building_types.csv +35 -0
  16. data/lib/openstudio-standards/btap/common/necb_space_types.csv +110 -0
  17. data/lib/openstudio-standards/btap/common/thermal_bridging.csv +73 -0
  18. data/lib/openstudio-standards/btap/costing/btap_costing.rb +346 -429
  19. data/lib/openstudio-standards/btap/costing/database.rb +104 -0
  20. data/lib/openstudio-standards/btap/costing/daylighting_sensor_control_costing.rb +356 -344
  21. data/lib/openstudio-standards/btap/costing/dcv_costing.rb +282 -296
  22. data/lib/openstudio-standards/btap/costing/envelope_costing.rb +179 -192
  23. data/lib/openstudio-standards/btap/costing/heating_cooling_costing.rb +2477 -2316
  24. data/lib/openstudio-standards/btap/costing/led_lighting_costing.rb +127 -142
  25. data/lib/openstudio-standards/btap/costing/lighting_costing.rb +216 -198
  26. data/lib/openstudio-standards/btap/costing/nv_costing.rb +522 -523
  27. data/lib/openstudio-standards/btap/costing/pv_ground_costing.rb +649 -649
  28. data/lib/openstudio-standards/btap/costing/shw_costing.rb +626 -625
  29. data/lib/openstudio-standards/btap/costing/thermal_bridging_costing.rb +72 -0
  30. data/lib/openstudio-standards/btap/costing/ventilation_costing.rb +2363 -2361
  31. data/lib/openstudio-standards/btap/deprecated.rb +1033 -0
  32. data/lib/openstudio-standards/btap/envelope.rb +313 -572
  33. data/lib/openstudio-standards/btap/fileio.rb +152 -1070
  34. data/lib/openstudio-standards/btap/geometry.rb +486 -766
  35. data/lib/openstudio-standards/btap/linear_regression.rb +130 -0
  36. data/lib/openstudio-standards/btap/paths.rb +46 -0
  37. data/lib/openstudio-standards/btap/qaqc/analysis.rb +163 -0
  38. data/lib/openstudio-standards/btap/qaqc/data.rb +2293 -0
  39. data/lib/openstudio-standards/btap/qaqc/datapoint.rb +641 -0
  40. data/lib/openstudio-standards/btap/schedules.rb +11 -611
  41. data/lib/openstudio-standards/btap/structure.rb +574 -189
  42. data/lib/openstudio-standards/constructions/materials/information.rb +1 -1
  43. data/lib/openstudio-standards/create_typical/create_typical.rb +1 -1
  44. data/lib/openstudio-standards/exterior_lighting/create.rb +135 -85
  45. data/lib/openstudio-standards/exterior_lighting/data/typical_exterior_lighting.json +20 -0
  46. data/lib/openstudio-standards/exterior_lighting/information.rb +23 -2
  47. data/lib/openstudio-standards/geometry/create.rb +7 -3
  48. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +3 -2
  49. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +3 -2
  50. data/lib/openstudio-standards/prototypes/common/data/thermostat_schedule_lookup.json +84 -84
  51. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +4 -4
  52. data/lib/openstudio-standards/refrigeration/create_walkin.rb +45 -5
  53. data/lib/openstudio-standards/refrigeration/data/refrigerated_walkins.csv +75 -75
  54. data/lib/openstudio-standards/schedules/parametric.rb +6 -0
  55. data/lib/openstudio-standards/service_water_heating/create_typical.rb +10 -3
  56. data/lib/openstudio-standards/service_water_heating/create_water_heating_loop.rb +30 -14
  57. data/lib/openstudio-standards/service_water_heating/information.rb +4 -1
  58. data/lib/openstudio-standards/sql_file/unmet_hours.rb +2 -1
  59. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +3 -1
  60. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +3 -1
  61. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.boilers.json +12 -0
  62. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_properties.json +18432 -3072
  63. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.boilers.json +26 -0
  64. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_properties.json +8532 -1422
  65. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.boilers.json +26 -0
  66. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_properties.json +8532 -1422
  67. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.boilers.json +16 -0
  68. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.computer_room_acs.json +30 -30
  69. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_properties.json +7560 -1260
  70. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.PumpVariableSpeed.rb +1 -2
  71. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.boilers.json +16 -0
  72. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_properties.json +7560 -1260
  73. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +3 -3
  74. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.PumpVariableSpeed.rb +1 -2
  75. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.boilers.json +22 -0
  76. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_properties.json +7236 -1206
  77. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.furnaces.json +223 -19
  78. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.schedules.json +37 -1
  79. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.boilers.json +3 -0
  80. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.construction_properties.json +6900 -1150
  81. data/lib/openstudio-standards/standards/cbes/data/cbes.schedules.json +1 -1
  82. data/lib/openstudio-standards/standards/deer/data/deer.schedules.json +1 -1
  83. data/lib/openstudio-standards/standards/necb/BTAP1980TO2010/data/surface_thermal_transmittance.json +76 -40
  84. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/surface_thermal_transmittance.json +76 -40
  85. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +6 -4
  86. data/lib/openstudio-standards/standards/necb/NECB2011/NECB2011_QAQC.json +2988 -0
  87. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +25 -3
  88. data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +672 -534
  89. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/Hospital.osm +1791 -1792
  90. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPMultiTower.osm +7 -1
  91. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LEEPTownHouse.osm +7 -1
  92. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LargeHotel.osm +5 -6
  93. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LargeOffice.osm +8 -9
  94. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernEducation.osm +10 -4
  95. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernHealthCare.osm +14 -15
  96. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/Outpatient.osm +7 -1
  97. data/lib/openstudio-standards/standards/necb/NECB2011/data/surface_thermal_transmittance.json +76 -40
  98. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +14 -6
  99. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +542 -130
  100. data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +30 -63
  101. data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +7 -2
  102. data/lib/openstudio-standards/standards/necb/NECB2015/data/surface_thermal_transmittance.json +90 -0
  103. data/lib/openstudio-standards/standards/necb/NECB2015/necb_2015.rb +8 -6
  104. data/lib/openstudio-standards/standards/necb/NECB2017/data/surface_thermal_transmittance.json +76 -40
  105. data/lib/openstudio-standards/standards/necb/NECB2017/necb_2017.rb +2 -1
  106. data/lib/openstudio-standards/standards/necb/NECB2020/building_envelope.rb +0 -117
  107. data/lib/openstudio-standards/standards/necb/NECB2020/data/surface_thermal_transmittance.json +76 -45
  108. data/lib/openstudio-standards/standards/necb/NECB2020/necb_2020.rb +218 -0
  109. data/lib/openstudio-standards/standards/necb/common/construction_defaults.osm +12 -7
  110. data/lib/openstudio-standards/standards/standard.rb +1 -1
  111. data/lib/openstudio-standards/version.rb +1 -1
  112. data/lib/openstudio-standards.rb +9 -4
  113. metadata +59 -66
  114. data/data/inventory/thermal_bridging.csv +0 -90
  115. data/data/standards/OpenStudio_Standards-ashrae_90_1-ALL-comstock(space_types).xlsx +0 -0
  116. data/data/standards/openstudio_standards_duplicates_log.csv +0 -7962
  117. data/lib/openstudio-standards/btap/NECB_building_types.csv +0 -35
  118. data/lib/openstudio-standards/btap/NECB_space_types.csv +0 -109
  119. data/lib/openstudio-standards/btap/WeatherData1.json +0 -2110
  120. data/lib/openstudio-standards/btap/WeatherData1.xlsx +0 -0
  121. data/lib/openstudio-standards/btap/btap_result.rb +0 -1144
  122. data/lib/openstudio-standards/btap/btap_test_helper.rb +0 -86
  123. data/lib/openstudio-standards/btap/common_paths.rb +0 -81
  124. data/lib/openstudio-standards/btap/common_resources/ConstructionProperties.csv +0 -52
  125. data/lib/openstudio-standards/btap/common_resources/Constructions.csv +0 -37
  126. data/lib/openstudio-standards/btap/common_resources/construction_sets.csv +0 -1270
  127. data/lib/openstudio-standards/btap/common_resources/constructions_glazing.csv +0 -121
  128. data/lib/openstudio-standards/btap/common_resources/constructions_opaque.csv +0 -2256
  129. data/lib/openstudio-standards/btap/common_resources/costs.csv +0 -1897
  130. data/lib/openstudio-standards/btap/common_resources/costs_local_factors.csv +0 -2315
  131. data/lib/openstudio-standards/btap/common_resources/materials_glazing.csv +0 -35
  132. data/lib/openstudio-standards/btap/common_resources/materials_opaque.csv +0 -164
  133. data/lib/openstudio-standards/btap/costing/btap_measure_helper.rb +0 -359
  134. data/lib/openstudio-standards/btap/costing/btap_workflow.rb +0 -117
  135. data/lib/openstudio-standards/btap/costing/copy_test_results_files_to_expected_results.rb +0 -11
  136. data/lib/openstudio-standards/btap/costing/cost_building_from_file.rb +0 -136
  137. data/lib/openstudio-standards/btap/costing/costing_database_wrapper.rb +0 -173
  138. data/lib/openstudio-standards/btap/costing/dummy.epw +0 -8768
  139. data/lib/openstudio-standards/btap/costing/dummy.osm +0 -5320
  140. data/lib/openstudio-standards/btap/costing/neb_end_use_prices.csv +0 -42
  141. data/lib/openstudio-standards/btap/costing/necb_2011_spacetype_info.csv +0 -225
  142. data/lib/openstudio-standards/btap/costing/necb_reference_runs.csv +0 -28705
  143. data/lib/openstudio-standards/btap/costing/parallel_tests.rb +0 -92
  144. data/lib/openstudio-standards/btap/costing/test_list.txt +0 -15
  145. data/lib/openstudio-standards/btap/costing/test_run_all_test_locally.rb +0 -27
  146. data/lib/openstudio-standards/btap/costing/test_run_costing_tests.rb +0 -80
  147. data/lib/openstudio-standards/btap/necb_2011_spacetype_info.csv +0 -225
  148. data/lib/openstudio-standards/btap/utilities/Add_template_field_to_json.rb +0 -22
  149. data/lib/openstudio-standards/btap/utilities/convert_surfaces_to_adiabatic_necb_8426.rb +0 -204
  150. data/lib/openstudio-standards/btap/utilities/generate_space_types.rb +0 -8
  151. data/lib/openstudio-standards/btap/utilities/necb_to_epw_map.rb +0 -50
  152. data/lib/openstudio-standards/btap/utilities/os_sim_extract.rb +0 -48
  153. data/lib/openstudio-standards/btap/utilities/rename_surfaces.rb +0 -24
  154. data/lib/openstudio-standards/btap/utilities/round_surf_coords.rb +0 -32
  155. data/lib/openstudio-standards/btap/utilities/sched_create.rb +0 -145
  156. data/lib/openstudio-standards/btap/utilities/set_mult_to_adiabatic.rb +0 -53
  157. data/lib/openstudio-standards/btap/utilities/space_type.rb +0 -78
  158. data/lib/openstudio-standards/btap/utilities/weatherData1_xlsx_to_json.rb +0 -56
  159. data/lib/openstudio-standards/btap/vintagizer.rb +0 -161
  160. data/lib/openstudio-standards/btap/visualization.rb +0 -72
  161. data/lib/openstudio-standards/standards/necb/NECB2011/data/necb_2011_spacetype_info.csv +0 -225
  162. data/lib/openstudio-standards/standards/necb/common/btap_analysis.rb +0 -79
  163. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +0 -2656
  164. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +0 -653
  165. data/lib/openstudio-standards/standards/necb/common/necb_reference_runs.csv +0 -28705
  166. data/lib/openstudio-standards/standards/necb/common/utility_pricing_2025-02-20.csv +0 -92
  167. /data/lib/openstudio-standards/btap/{common_resources → common}/carbon_frame.csv +0 -0
  168. /data/lib/openstudio-standards/btap/{common_resources → common}/carbon_glazing.csv +0 -0
  169. /data/lib/openstudio-standards/btap/{common_resources → common}/carbon_opaque.csv +0 -0
  170. /data/lib/openstudio-standards/btap/{common_resources → common}/hvac_vent_ahu.csv +0 -0
  171. /data/lib/openstudio-standards/btap/{common_resources → common}/lighting.csv +0 -0
  172. /data/lib/openstudio-standards/btap/{common_resources → common}/lighting_sets.csv +0 -0
  173. /data/lib/openstudio-standards/btap/{common_resources → common}/locations.csv +0 -0
  174. /data/lib/openstudio-standards/btap/{costing → common}/mech_sizing.json +0 -0
@@ -28,7 +28,7 @@ module OpenstudioStandards
28
28
  # Gas
29
29
  # Convert C to K
30
30
  temperature_k = temperature + 273.0
31
- conductance = material.to_Gas.get.getThermalConductivity(temperature_k) unless material.to_Gas.empty?
31
+ conductance = material.to_Gas.get.getThermalConductance(temperature_k) unless material.to_Gas.empty?
32
32
  conductance = material.to_GasMixture.get.getThermalConductance(temperature_k) unless material.to_GasMixture.empty?
33
33
 
34
34
  if conductance.nil?
@@ -992,7 +992,7 @@ module OpenstudioStandards
992
992
  end
993
993
 
994
994
  # set climate zone
995
- os_climate_zone = climate_zone.gsub('ASHRAE 169-2013-', '')
995
+ os_climate_zone = climate_zone.gsub(/ASHRAE .*-.*-/, '')
996
996
  # trim off letter from climate zone 7 or 8
997
997
  if (os_climate_zone[0] == '7') || (os_climate_zone[0] == '8')
998
998
  os_climate_zone = os_climate_zone[0]
@@ -178,26 +178,45 @@ module OpenstudioStandards
178
178
  end
179
179
 
180
180
  # create exterior lights
181
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power.round(2)} W/ft^2 of lighting for #{multiplier} ft^2 of parking area.")
182
- ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
183
- name: 'Parking Areas and Drives',
184
- power: power,
185
- units: 'W/ft^2',
186
- multiplier: multiplier,
187
- schedule: ext_lights_sch_other,
188
- control_option: control_option)
189
- exterior_lights << ext_lights
190
- installed_power += power * multiplier
181
+ if power > 0
182
+ ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
183
+ name: 'Parking Areas and Drives',
184
+ power: power,
185
+ units: 'W/ft^2',
186
+ multiplier: multiplier,
187
+ schedule: ext_lights_sch_other,
188
+ control_option: control_option)
189
+ exterior_lights << ext_lights
190
+ installed_power += power * multiplier
191
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power.round(2)} W/ft^2 of lighting for #{multiplier} ft^2 of parking area.")
192
+ else
193
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "No lighting added for parking area, as power is 0 W/ft^2.")
194
+ end
191
195
  end
192
196
 
193
197
  # add exterior lights for facades
194
- if !area_length_count_hash[:building_facades].nil? && area_length_count_hash[:building_facades] > 0
195
- # lighting values
196
- multiplier = area_length_count_hash[:building_facades]
197
-
198
- # get power
199
- if exterior_lighting_properties.key?('building_facades')
198
+ if !area_length_count_hash[:building_facades_area].nil? && area_length_count_hash[:building_facades_area] > 0
199
+ # determine power and multiplier based on available data
200
+ # use per permimter values if available, otherwise fall back to area based values
201
+ if exterior_lighting_properties.key?('building_facades_per_perimeter') &&
202
+ !area_length_count_hash[:building_perimeter].nil? && area_length_count_hash[:building_perimeter] > 0
203
+ # perimeter-based approach with building-type differentiation
204
+ perimeter_rates = exterior_lighting_properties['building_facades_per_perimeter']
205
+ bldg_type = area_length_count_hash[:largest_building_type]
206
+ power = if !bldg_type.nil? && perimeter_rates.key?(bldg_type)
207
+ perimeter_rates[bldg_type]
208
+ else
209
+ perimeter_rates['default']
210
+ end
211
+ multiplier = area_length_count_hash[:building_perimeter]
212
+ units = 'W/ft'
213
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power.round(2)} W/ft of lighting for #{multiplier.round(1)} ft of building perimeter (building type: #{bldg_type}).")
214
+ elsif exterior_lighting_properties.key?('building_facades')
215
+ # area-based fallback
200
216
  power = exterior_lighting_properties['building_facades']
217
+ multiplier = area_length_count_hash[:building_facades_area]
218
+ units = 'W/ft^2'
219
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power.round(2)} W/ft^2 of lighting for #{multiplier} ft^2 of building facade area.")
201
220
  else
202
221
  search_criteria = {
203
222
  'template' => lookup_key,
@@ -207,19 +226,26 @@ module OpenstudioStandards
207
226
  }
208
227
  exterior_lighting_facade_req = standard.standards_lookup_table_first(table_name: 'exterior_lighting', search_criteria: search_criteria)
209
228
  power = exterior_lighting_facade_req['allowance']
229
+ multiplier = area_length_count_hash[:building_facades_area]
230
+ units = 'W/ft^2'
231
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power.round(2)} W/ft^2 of lighting for #{multiplier} ft^2 of building facade area.")
210
232
  end
211
233
 
212
234
  # create exterior lights
213
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power.round(2)} W/ft^2 of lighting for #{multiplier} ft^2 of building facade area.")
214
- ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
215
- name: 'Building Facades',
216
- power: power,
217
- units: 'W/ft^2',
218
- multiplier: multiplier,
219
- schedule: ext_lights_sch_facade_and_landscape,
220
- control_option: 'ScheduleNameOnly')
221
- exterior_lights << ext_lights
222
- installed_power += power * multiplier
235
+ if power > 0
236
+ ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
237
+ name: 'Building Facades',
238
+ power: power,
239
+ units: units,
240
+ multiplier: multiplier,
241
+ schedule: ext_lights_sch_facade_and_landscape,
242
+ control_option: 'ScheduleNameOnly')
243
+ exterior_lights << ext_lights
244
+ installed_power += power * multiplier
245
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power.round(2)} #{units} of lighting for #{multiplier} #{units == 'W/ft' ? 'ft perimeter' : 'ft^2 area'} of building facade.")
246
+ else
247
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "No lighting added for building facades, as power is 0 #{units}.")
248
+ end
223
249
  end
224
250
 
225
251
  # add exterior lights for main entries
@@ -250,16 +276,20 @@ module OpenstudioStandards
250
276
  end
251
277
 
252
278
  # create exterior lights
253
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power.round(2)} W/ft of lighting for #{multiplier} ft of main entry length.")
254
- ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
255
- name: 'Main Entries',
256
- power: power,
257
- units: 'W/ft',
258
- multiplier: multiplier,
259
- schedule: ext_lights_sch_other,
260
- control_option: control_option)
261
- exterior_lights << ext_lights
262
- installed_power += power * multiplier
279
+ if power > 0
280
+ ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
281
+ name: 'Main Entries',
282
+ power: power,
283
+ units: 'W/ft',
284
+ multiplier: multiplier,
285
+ schedule: ext_lights_sch_other,
286
+ control_option: control_option)
287
+ exterior_lights << ext_lights
288
+ installed_power += power * multiplier
289
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power.round(2)} W/ft of lighting for #{multiplier} ft of main entry length.")
290
+ else
291
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "No lighting added for main entries, as power is 0 W/ft.")
292
+ end
263
293
  end
264
294
 
265
295
  # add exterior lights for other doors
@@ -290,16 +320,20 @@ module OpenstudioStandards
290
320
  end
291
321
 
292
322
  # create exterior lights
293
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power.round(2)} W/ft of lighting for #{multiplier} ft of other doors.")
294
- ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
295
- name: 'Other Doors',
296
- power: power,
297
- units: 'W/ft',
298
- multiplier: multiplier,
299
- schedule: ext_lights_sch_other,
300
- control_option: control_option)
301
- exterior_lights << ext_lights
302
- installed_power += power * multiplier
323
+ if power > 0
324
+ ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
325
+ name: 'Other Doors',
326
+ power: power,
327
+ units: 'W/ft',
328
+ multiplier: multiplier,
329
+ schedule: ext_lights_sch_other,
330
+ control_option: control_option)
331
+ exterior_lights << ext_lights
332
+ installed_power += power * multiplier
333
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power.round(2)} W/ft of lighting for #{multiplier} ft of other doors.")
334
+ else
335
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "No lighting added for other doors, as power is 0 W/ft.")
336
+ end
303
337
  end
304
338
 
305
339
  # add exterior lights for entry canopies
@@ -330,16 +364,20 @@ module OpenstudioStandards
330
364
  end
331
365
 
332
366
  # create exterior lights
333
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power} W/ft^2 of lighting for #{multiplier} ft^2 of building entry canopies.")
334
- ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
335
- name: 'Entry Canopies',
336
- power: power,
337
- units: 'W/ft^2',
338
- multiplier: multiplier,
339
- schedule: ext_lights_sch_other,
340
- control_option: control_option)
341
- exterior_lights << ext_lights
342
- installed_power += power * multiplier
367
+ if power > 0
368
+ ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
369
+ name: 'Entry Canopies',
370
+ power: power,
371
+ units: 'W/ft^2',
372
+ multiplier: multiplier,
373
+ schedule: ext_lights_sch_other,
374
+ control_option: control_option)
375
+ exterior_lights << ext_lights
376
+ installed_power += power * multiplier
377
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power} W/ft^2 of lighting for #{multiplier} ft^2 of building entry canopies.")
378
+ else
379
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "No lighting added for entry canopies, as power is 0 W/ft^2.")
380
+ end
343
381
  end
344
382
 
345
383
  # add exterior lights for emergency canopies
@@ -361,16 +399,20 @@ module OpenstudioStandards
361
399
  end
362
400
 
363
401
  # create exterior lights
364
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power} W/ft^2 of lighting for #{multiplier} ft^2 of building emergency canopies.")
365
- ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
366
- name: 'Emergency Canopies',
367
- power: power,
368
- units: 'W/ft^2',
369
- multiplier: multiplier,
370
- schedule: ext_lights_sch_other,
371
- control_option: control_option)
372
- exterior_lights << ext_lights
373
- installed_power += power * multiplier
402
+ if power > 0
403
+ ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
404
+ name: 'Emergency Canopies',
405
+ power: power,
406
+ units: 'W/ft^2',
407
+ multiplier: multiplier,
408
+ schedule: ext_lights_sch_other,
409
+ control_option: control_option)
410
+ exterior_lights << ext_lights
411
+ installed_power += power * multiplier
412
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power} W/ft^2 of lighting for #{multiplier} ft^2 of building emergency canopies.")
413
+ else
414
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "No lighting added for emergency canopies, as power is 0 W/ft^2.")
415
+ end
374
416
  end
375
417
 
376
418
  # add exterior lights for drive through windows
@@ -392,16 +434,20 @@ module OpenstudioStandards
392
434
  end
393
435
 
394
436
  # create exterior lights
395
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power} W/drive through window of lighting for #{multiplier} drive through windows.")
396
- ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
397
- name: 'Drive Through Windows',
398
- power: power,
399
- units: 'W/ft^2',
400
- multiplier: multiplier,
401
- schedule: ext_lights_sch_other,
402
- control_option: control_option)
403
- exterior_lights << ext_lights
404
- installed_power += power * multiplier
437
+ if power > 0
438
+ ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
439
+ name: 'Drive Through Windows',
440
+ power: power,
441
+ units: 'W/ft^2',
442
+ multiplier: multiplier,
443
+ schedule: ext_lights_sch_other,
444
+ control_option: control_option)
445
+ exterior_lights << ext_lights
446
+ installed_power += power * multiplier
447
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power} W/drive through window of lighting for #{multiplier} drive through windows.")
448
+ else
449
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "No lighting added for drive through windows, as power is 0 W/ft^2.")
450
+ end
405
451
  end
406
452
 
407
453
  # add base site allowance
@@ -437,15 +483,19 @@ module OpenstudioStandards
437
483
  end
438
484
 
439
485
  # create exterior lights
440
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power} W of non landscape tradable exterior lighting. Will follow occupancy setback reduction.")
441
- ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
442
- name: 'Base Site Allowance',
443
- power: power,
444
- units: 'W',
445
- multiplier: 1.0,
446
- schedule: ext_lights_sch_other,
447
- control_option: control_option)
448
- exterior_lights << ext_lights
486
+ if power > 0
487
+ ext_lights = OpenstudioStandards::ExteriorLighting.model_create_exterior_lights(model,
488
+ name: 'Base Site Allowance',
489
+ power: power,
490
+ units: 'W',
491
+ multiplier: 1.0,
492
+ schedule: ext_lights_sch_other,
493
+ control_option: control_option)
494
+ exterior_lights << ext_lights
495
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "Added #{power} W of non landscape tradable exterior lighting. Will follow occupancy setback reduction.")
496
+ else
497
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.ExteriorLighting', "No base site allowance lighting added, as power is 0 W.")
498
+ end
449
499
  end
450
500
 
451
501
  return exterior_lights
@@ -24,6 +24,26 @@
24
24
  "outdoor_sales_street_frontage_for_vehicle_sales": 10.0,
25
25
  "building_facades": 0.15,
26
26
  "building_facades_alt_perim": 3.75,
27
+ "building_facades_per_perimeter": {
28
+ "SmallOffice": 0.84,
29
+ "MediumOffice": 0.84,
30
+ "LargeOffice": 0.84,
31
+ "RetailStandalone": 0.81,
32
+ "RetailStripmall": 0.81,
33
+ "Warehouse": 0.97,
34
+ "FullServiceRestaurant": 1.93,
35
+ "QuickServiceRestaurant": 1.93,
36
+ "PrimarySchool": 0.74,
37
+ "SecondarySchool": 0.74,
38
+ "Supermarket": 1.19,
39
+ "Hospital": 0.54,
40
+ "Outpatient": 0.54,
41
+ "SmallHotel": 1.05,
42
+ "LargeHotel": 1.05,
43
+ "MidriseApartment": 0.51,
44
+ "HighriseApartment": 0.51,
45
+ "default": 1.0
46
+ },
27
47
  "automated_teller_machines_per_location": 270.0,
28
48
  "automated_teller_machines_per_machine": 90.0,
29
49
  "entries_and_gates": 0.75,
@@ -76,6 +76,9 @@ module OpenstudioStandards
76
76
  canopy_entry_area = 0.0
77
77
  canopy_emergency_area = 0.0
78
78
  ground_story_ext_wall_area = 0.0
79
+ building_perimeter_ft = 0.0
80
+ largest_building_type = nil
81
+ largest_building_type_area = 0.0
79
82
 
80
83
  # temporary std for model_effective_num_stories method
81
84
  std = Standard.build('90.1-2013')
@@ -155,7 +158,23 @@ module OpenstudioStandards
155
158
  # determine effective number of stories to find first above grade story exterior wall area
156
159
  ground_story = effective_num_stories[:story_hash].keys[effective_num_stories[:below_grade]]
157
160
  ground_story_ext_wall_area_m2 = effective_num_stories[:story_hash][ground_story][:ext_wall_area]
158
- ground_story_ext_wall_area += OpenStudio.convert(ground_story_ext_wall_area_m2, 'm^2', 'ft^2').get
161
+ this_story_ext_wall_area_ft2 = OpenStudio.convert(ground_story_ext_wall_area_m2, 'm^2', 'ft^2').get
162
+ ground_story_ext_wall_area += this_story_ext_wall_area_ft2
163
+
164
+ # compute perimeter from exterior wall area divided by floor-to-floor height
165
+ story_height_m = if ground_story.nominalFloortoFloorHeight.is_initialized
166
+ ground_story.nominalFloortoFloorHeight.get
167
+ else
168
+ 4.0 # default 4m (~13 ft) for commercial buildings
169
+ end
170
+ story_height_ft = OpenStudio.convert(story_height_m, 'm', 'ft').get
171
+ building_perimeter_ft += this_story_ext_wall_area_ft2 / story_height_ft
172
+
173
+ # track dominant building type by floor area
174
+ if hash[:floor_area] > largest_building_type_area
175
+ largest_building_type = building_type
176
+ largest_building_type_area = hash[:floor_area]
177
+ end
159
178
  end
160
179
 
161
180
  # no source for width of different entry types
@@ -175,7 +194,9 @@ module OpenstudioStandards
175
194
  area_length_count_hash[:drive_through_windows] = drive_through_windows
176
195
  area_length_count_hash[:canopy_entry_area] = canopy_entry_area
177
196
  area_length_count_hash[:canopy_emergency_area] = canopy_emergency_area
178
- area_length_count_hash[:building_facades] = ground_story_ext_wall_area
197
+ area_length_count_hash[:building_facades_area] = ground_story_ext_wall_area
198
+ area_length_count_hash[:building_perimeter] = building_perimeter_ft
199
+ area_length_count_hash[:largest_building_type] = largest_building_type
179
200
 
180
201
  return area_length_count_hash
181
202
  end
@@ -256,7 +256,9 @@ module OpenstudioStandards
256
256
  (space_type_hash[:floor_area] < valid_bar_area_min_m2) && (space_type_hash[:floor_area] > tol_value) ? (test_b = true) : (test_b = false)
257
257
 
258
258
  # identify very small slices and re-arrange spaces to different stories to avoid this
259
- if test_a
259
+ # only apply test_a when there is more than one space type on this story; if there is only one,
260
+ # shifting it out would leave space_types_local_count empty and crash create_sliced_bar_simple_polygons
261
+ if test_a && space_types_local_count.size > 1
260
262
 
261
263
  # get first/smallest space type to move to another story
262
264
  first_space = space_types_local_count.first
@@ -348,6 +350,8 @@ module OpenstudioStandards
348
350
 
349
351
  # sort array by floor area but shift largest object to front
350
352
  space_types = space_types.sort_by { |k, v| v[:floor_area] }
353
+ # guard against empty space_types (e.g. when all space types were slivers removed by caller)
354
+ return hash_of_point_vectors if space_types.empty?
351
355
  space_types.insert(0, space_types.delete_at(space_types.size - 1)) # .to_h
352
356
 
353
357
  # min and max bar end values
@@ -362,11 +366,11 @@ module OpenstudioStandards
362
366
  start_perimeter_width_deduction = 0.0
363
367
  end_perimeter_width_deduction = 0.0
364
368
  if space_type == space_types.first[0]
365
- if [length, width].max * space_type_hash[:floor_area] / total_floor_area > max_bar_end_multiplier * perimeter_zone_depth
369
+ if ([length, width].max * space_type_hash[:floor_area] / total_floor_area) > (max_bar_end_multiplier * perimeter_zone_depth)
366
370
  start_perimeter_width_deduction = perimeter_zone_depth
367
371
  end
368
372
  # see if last space type is too small for perimeter. If it is then save some of this space type
369
- if [length, width].max * space_types.last[1][:floor_area] / total_floor_area < perimeter_zone_depth * min_bar_end_multiplier
373
+ if ([length, width].max * space_types.last[1][:floor_area] / total_floor_area )< (perimeter_zone_depth * min_bar_end_multiplier)
370
374
  re_apply_largest_space_type_at_end = true
371
375
  end
372
376
  end
@@ -323,10 +323,11 @@ class ASHRAE9012016 < ASHRAE901
323
323
  light_id += 1
324
324
  # EnergyPlus v9.4 name change for EMS actuators
325
325
  # https://github.com/NREL/OpenStudio/pull/4104
326
+ # Space is passed as the last argument since Lights is a SpaceLoadInstance
326
327
  if model.version < OpenStudio::VersionString.new('3.1.0')
327
- light_x_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(light_x, 'Lights', 'Electric Power Level')
328
+ light_x_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(light_x, 'Lights', 'Electric Power Level', space)
328
329
  else
329
- light_x_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(light_x, 'Lights', 'Electricity Rate')
330
+ light_x_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(light_x, 'Lights', 'Electricity Rate', space)
330
331
  end
331
332
  light_x_actuator_name_ems = "#{OpenstudioStandards::HVAC.ems_friendly_name(key_name)}_Light#{light_id}_Actuator"
332
333
  light_x_actuator.setName(light_x_actuator_name_ems)
@@ -323,10 +323,11 @@ class ASHRAE9012019 < ASHRAE901
323
323
  light_id += 1
324
324
  # EnergyPlus v9.4 name change for EMS actuators
325
325
  # https://github.com/NREL/OpenStudio/pull/4104
326
+ # Space is passed as the last argument since Lights is a SpaceLoadInstance
326
327
  if model.version < OpenStudio::VersionString.new('3.1.0')
327
- light_x_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(light_x, 'Lights', 'Electric Power Level')
328
+ light_x_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(light_x, 'Lights', 'Electric Power Level', space)
328
329
  else
329
- light_x_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(light_x, 'Lights', 'Electricity Rate')
330
+ light_x_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(light_x, 'Lights', 'Electricity Rate', space)
330
331
  end
331
332
  light_x_actuator_name_ems = "#{OpenstudioStandards::HVAC.ems_friendly_name(key_name)}_Light#{light_id}_Actuator"
332
333
  light_x_actuator.setName(light_x_actuator_name_ems)