openstudio-standards 0.8.4 → 0.8.5.rc1

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 (289) hide show
  1. checksums.yaml +4 -4
  2. data/data/geometry/ASHRAECollege.osm +30 -30
  3. data/data/geometry/ASHRAECourthouse.osm +22 -22
  4. data/data/geometry/ASHRAESmallOfficeDetailed.osm +2 -2
  5. data/data/geometry/DEER_Asm.osm +1 -1
  6. data/data/geometry/DEER_ECC.osm +1 -1
  7. data/data/geometry/DEER_EPr.osm +1 -1
  8. data/data/geometry/DEER_ERC.osm +1 -1
  9. data/data/geometry/DEER_ESe.osm +1 -1
  10. data/data/geometry/DEER_EUn.osm +1 -1
  11. data/data/geometry/DEER_Hsp.osm +1 -1
  12. data/data/geometry/DEER_Htl.osm +1 -1
  13. data/data/geometry/DEER_MBT.osm +1 -1
  14. data/data/geometry/DEER_MFm.osm +1 -1
  15. data/data/geometry/DEER_Nrs.osm +1 -1
  16. data/data/geometry/DEER_OfL.osm +1 -1
  17. data/data/geometry/DEER_OfS.osm +1 -1
  18. data/data/geometry/DEER_RFF.osm +1 -1
  19. data/data/geometry/DEER_RSD.osm +1 -1
  20. data/data/geometry/DEER_Rt3.osm +1 -1
  21. data/data/geometry/DEER_RtS.osm +1 -1
  22. data/data/standards/export_OpenStudio_libraries.rb +2 -3
  23. data/data/standards/test_performance_expected_dd_results.csv +42 -42
  24. data/lib/openstudio-standards/btap/NECB_building_types.csv +35 -0
  25. data/lib/openstudio-standards/btap/NECB_space_types.csv +109 -0
  26. data/lib/openstudio-standards/btap/activity.rb +480 -0
  27. data/lib/openstudio-standards/btap/attributes.rb +166 -0
  28. data/lib/openstudio-standards/btap/bridging.rb +561 -1402
  29. data/lib/openstudio-standards/btap/btap.rb +4 -2
  30. data/lib/openstudio-standards/btap/btap_test_helper.rb +86 -0
  31. data/lib/openstudio-standards/btap/carbon/btap_carbon.rb +177 -0
  32. data/lib/openstudio-standards/btap/{costing/common_paths.rb → common_paths.rb} +14 -11
  33. data/lib/openstudio-standards/btap/common_resources/carbon_frame.csv +35 -0
  34. data/lib/openstudio-standards/btap/common_resources/carbon_glazing.csv +35 -0
  35. data/lib/openstudio-standards/btap/common_resources/carbon_opaque.csv +164 -0
  36. data/lib/openstudio-standards/btap/common_resources/constructions_glazing.csv +121 -0
  37. data/lib/openstudio-standards/btap/common_resources/costs.csv +1897 -0
  38. data/lib/openstudio-standards/btap/{costing/common_resources → common_resources}/lighting.csv +59 -59
  39. data/lib/openstudio-standards/btap/{costing/common_resources → common_resources}/materials_hvac.csv +1019 -1032
  40. data/lib/openstudio-standards/btap/costing/btap_costing.rb +3 -7
  41. data/lib/openstudio-standards/btap/costing/costing_database_wrapper.rb +1 -5
  42. data/lib/openstudio-standards/btap/costing/daylighting_sensor_control_costing.rb +5 -4
  43. data/lib/openstudio-standards/btap/costing/dcv_costing.rb +1 -1
  44. data/lib/openstudio-standards/btap/costing/envelope_costing.rb +112 -181
  45. data/lib/openstudio-standards/btap/costing/heating_cooling_costing.rb +4 -4
  46. data/lib/openstudio-standards/btap/costing/led_lighting_costing.rb +2 -1
  47. data/lib/openstudio-standards/btap/costing/lighting_costing.rb +3 -3
  48. data/lib/openstudio-standards/btap/costing/test_list.txt +15 -17
  49. data/lib/openstudio-standards/btap/costing/test_run_all_test_locally.rb +10 -9
  50. data/lib/openstudio-standards/btap/geometry.rb +86 -6
  51. data/lib/openstudio-standards/btap/structure.rb +657 -0
  52. data/lib/openstudio-standards/create_typical/create_typical.rb +17 -33
  53. data/lib/openstudio-standards/create_typical/space_type_ratios.rb +36 -36
  54. data/lib/openstudio-standards/equipment/create_transformer.rb +104 -0
  55. data/lib/openstudio-standards/equipment/create_typical_equipment.rb +117 -0
  56. data/lib/openstudio-standards/equipment/data/electric_equipment_space_types.json +1514 -0
  57. data/lib/openstudio-standards/equipment/data/gas_equipment_space_types.json +227 -0
  58. data/lib/openstudio-standards/exterior_lighting/create.rb +22 -22
  59. data/lib/openstudio-standards/exterior_lighting/information.rb +3 -2
  60. data/lib/openstudio-standards/hvac/components/air_conditioner_vrf.rb +482 -0
  61. data/lib/openstudio-standards/hvac/components/air_terminal.rb +31 -0
  62. data/lib/openstudio-standards/hvac/components/boiler_hot_water.rb +163 -0
  63. data/lib/openstudio-standards/hvac/components/central_air_source_heat_pump.rb +220 -0
  64. data/lib/openstudio-standards/hvac/components/chiller.rb +25 -0
  65. data/lib/openstudio-standards/hvac/components/coil.rb +276 -0
  66. data/lib/openstudio-standards/hvac/components/coil_cooling_dx_multi_speed.rb +40 -0
  67. data/lib/openstudio-standards/hvac/components/coil_cooling_dx_single_speed.rb +300 -0
  68. data/lib/openstudio-standards/hvac/components/coil_cooling_dx_two_speed.rb +187 -0
  69. data/lib/openstudio-standards/hvac/components/coil_cooling_water.rb +80 -0
  70. data/lib/openstudio-standards/hvac/components/coil_cooling_water_to_air_heat_pump_equation_fit.rb +182 -0
  71. data/lib/openstudio-standards/hvac/components/coil_heating_dx_single_speed.rb +220 -0
  72. data/lib/openstudio-standards/hvac/components/coil_heating_electric.rb +56 -0
  73. data/lib/openstudio-standards/hvac/components/coil_heating_gas.rb +90 -0
  74. data/lib/openstudio-standards/hvac/components/coil_heating_gas_multi_stage.rb +33 -0
  75. data/lib/openstudio-standards/hvac/components/coil_heating_water.rb +98 -0
  76. data/lib/openstudio-standards/hvac/components/coil_heating_water_to_air_heat_pump_equation_fit.rb +147 -0
  77. data/lib/openstudio-standards/hvac/components/component.rb +39 -0
  78. data/lib/openstudio-standards/{standards/ashrae_90_1/data/ashrae_90_1.fans.json → hvac/components/data/fans.json} +6 -6
  79. data/lib/openstudio-standards/hvac/components/fan.rb +363 -0
  80. data/lib/openstudio-standards/hvac/components/heat_exchanger_air_to_air.rb +203 -0
  81. data/lib/openstudio-standards/hvac/components/pump.rb +181 -0
  82. data/lib/openstudio-standards/hvac/controls/radiant_system_controls.rb +594 -0
  83. data/lib/openstudio-standards/hvac/conversions.rb +222 -0
  84. data/lib/openstudio-standards/hvac/curves.rb +192 -0
  85. data/lib/openstudio-standards/hvac/helpers.rb +357 -0
  86. data/lib/openstudio-standards/hvac/setpoint_managers/information.rb +4 -4
  87. data/lib/openstudio-standards/interior_lighting/create_lights.rb +52 -0
  88. data/lib/openstudio-standards/interior_lighting/create_typical_interior_lighting.rb +254 -0
  89. data/lib/openstudio-standards/interior_lighting/data/convert_lighting_data.rb +249 -0
  90. data/lib/openstudio-standards/interior_lighting/data/lighting_space_types.csv +96 -0
  91. data/lib/openstudio-standards/interior_lighting/data/lighting_space_types.json +1429 -0
  92. data/lib/openstudio-standards/interior_lighting/data/lighting_technology.csv +46 -0
  93. data/lib/openstudio-standards/interior_lighting/data/lighting_technology.json +859 -0
  94. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
  95. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
  96. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
  97. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +4 -4
  98. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
  99. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +4 -4
  100. data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
  101. data/lib/openstudio-standards/prototypes/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
  102. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.HighRiseApartment.rb +6 -7
  103. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Hospital.rb +15 -15
  104. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeHotel.rb +4 -4
  105. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOffice.rb +5 -5
  106. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOffice.rb +6 -6
  107. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb +7 -7
  108. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.PrimarySchool.rb +4 -4
  109. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SecondarySchool.rb +6 -6
  110. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOfficeDetailed.rb +5 -1
  111. data/lib/openstudio-standards/prototypes/common/data/prototype_space_type_map.json +2594 -0
  112. data/lib/openstudio-standards/prototypes/common/data/thermostat_schedule_lookup.json +2108 -0
  113. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirTerminalSingleDuctVAVReheat.rb +33 -0
  114. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Fan.rb +0 -140
  115. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanConstantVolume.rb +1 -73
  116. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanOnOff.rb +1 -69
  117. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanVariableVolume.rb +0 -116
  118. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanZoneExhaust.rb +0 -61
  119. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.hvac.rb +2 -2
  120. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +128 -13
  121. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +606 -607
  122. data/lib/openstudio-standards/prototypes/common/prototype_space_type_map.rb +41 -0
  123. data/lib/openstudio-standards/prototypes/common/space_type_equipment_map.rb +184 -0
  124. data/lib/openstudio-standards/prototypes/common/space_type_thermostat_schedule_map.rb +116 -0
  125. data/lib/openstudio-standards/qaqc/hvac.rb +12 -12
  126. data/lib/openstudio-standards/refrigeration/create_compressor.rb +2 -5
  127. data/lib/openstudio-standards/refrigeration/data/refrigeration_compressors.csv +4 -4
  128. data/lib/openstudio-standards/service_water_heating/create_water_heater.rb +1 -2
  129. data/lib/openstudio-standards/service_water_heating/create_water_use.rb +5 -5
  130. data/lib/openstudio-standards/space_type/data/level_1_space_types.json +612 -0
  131. data/lib/openstudio-standards/space_type/standards_space_type.rb +53 -0
  132. data/lib/openstudio-standards/standards/Standards.AirConditionerVariableRefrigerantFlow.rb +8 -26
  133. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +13 -13
  134. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctVAVReheat.rb +0 -24
  135. data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +6 -43
  136. data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +7 -24
  137. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXMultiSpeed.rb +19 -44
  138. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +25 -50
  139. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +25 -33
  140. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +9 -22
  141. data/lib/openstudio-standards/standards/Standards.CoilDX.rb +15 -157
  142. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +2 -2
  143. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +18 -105
  144. data/lib/openstudio-standards/standards/Standards.CoilHeatingGas.rb +3 -23
  145. data/lib/openstudio-standards/standards/Standards.CoilHeatingGasMultiStage.rb +0 -24
  146. data/lib/openstudio-standards/standards/Standards.CoilHeatingWaterToAirHeatPumpEquationFit.rb +2 -86
  147. data/lib/openstudio-standards/standards/Standards.FanVariableVolume.rb +0 -107
  148. data/lib/openstudio-standards/standards/Standards.Model.rb +6 -11
  149. data/lib/openstudio-standards/standards/Standards.People.rb +113 -0
  150. data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +11 -11
  151. data/lib/openstudio-standards/standards/Standards.Pump.rb +2 -147
  152. data/lib/openstudio-standards/standards/Standards.PumpVariableSpeed.rb +57 -41
  153. data/lib/openstudio-standards/standards/Standards.SpaceType.rb +30 -153
  154. data/lib/openstudio-standards/standards/Standards.Ventilation.rb +74 -0
  155. data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +1 -1
  156. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PlantLoop.rb +4 -4
  157. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_pumps_heating.json +3 -3
  158. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.spc_typ.json +37 -112
  159. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/comstock_ashrae_90_1_2007.spc_typ.json +37 -102
  160. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_pumps_heating.json +3 -3
  161. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.spc_typ.json +37 -112
  162. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
  163. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/comstock_ashrae_90_1_2010.spc_typ.json +37 -37
  164. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_pumps_heating.json +6 -6
  165. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.spc_typ.json +37 -37
  166. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
  167. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.BoilerHotWater.rb +1 -1
  168. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/comstock_ashrae_90_1_2013.spc_typ.json +37 -102
  169. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_pumps_heating.json +6 -6
  170. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.spc_typ.json +37 -37
  171. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
  172. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.BoilerHotWater.rb +1 -1
  173. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/comstock_ashrae_90_1_2016/data/comstock_ashrae_90_1_2016.spc_typ.json +45 -109
  174. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.heat_pumps_heating.json +6 -6
  175. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.spc_typ.json +37 -37
  176. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +1 -1
  177. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
  178. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.BoilerHotWater.rb +1 -1
  179. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoilHeatingGas.rb +1 -1
  180. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/comstock_ashrae_90_1_2019/data/comstock_ashrae_90_1_2019.spc_typ.json +45 -109
  181. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.heat_pumps_heating.json +6 -6
  182. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.spc_typ.json +37 -37
  183. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.curves.json +0 -200
  184. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/comstock_doe_ref_1980_2004.spc_typ.json +37 -37
  185. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.spc_typ.json +37 -37
  186. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/comstock_doe_ref_pre_1980.spc_typ.json +37 -37
  187. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.spc_typ.json +37 -37
  188. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
  189. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.PlantLoop.rb +5 -5
  190. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
  191. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.PlantLoop.rb +5 -5
  192. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +1 -1
  193. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ChillerElectricEIR.rb +2 -2
  194. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXSingleSpeed.rb +2 -68
  195. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXTwoSpeed.rb +2 -35
  196. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilDX.rb +42 -0
  197. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingDXSingleSpeed.rb +5 -2
  198. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingGas.rb +2 -2
  199. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +3 -3
  200. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.SpaceType.rb +1 -1
  201. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.Model.rb +1 -0
  202. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019_WaterHeaterMixed.rb +2 -4
  203. data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.curves.json +0 -200
  204. data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.fans.json +5 -5
  205. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/ashrae_90_1_prm.UserData.rb +1 -0
  206. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_enums.rb +0 -1
  207. data/lib/openstudio-standards/standards/cbes/data/cbes.curves.json +0 -200
  208. data/lib/openstudio-standards/standards/deer/data/deer.curves.json +0 -200
  209. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/btap_pre1980.rb +19 -10
  210. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/building_envelope.rb +12 -11
  211. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_systems.rb +4 -4
  212. data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +1 -1
  213. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +69 -92
  214. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +2 -1
  215. data/lib/openstudio-standards/standards/necb/NECB2011/beps_compliance_path.rb +16 -12
  216. data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +799 -46
  217. data/lib/openstudio-standards/standards/necb/NECB2011/data/chillers.json +33 -51
  218. data/lib/openstudio-standards/standards/necb/NECB2011/data/constants.json +32 -0
  219. data/lib/openstudio-standards/standards/necb/NECB2011/data/fuel_type_sets.json +18 -0
  220. data/lib/openstudio-standards/standards/necb/NECB2011/data/heat_pumps_heating.json +21 -15
  221. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_namer.rb +5 -5
  222. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_single_speed.rb +2 -0
  223. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +30 -141
  224. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +233 -112
  225. data/lib/openstudio-standards/standards/necb/NECB2015/data/heat_pumps_heating.json +10 -2
  226. data/lib/openstudio-standards/standards/necb/NECB2015/hvac_systems.rb +2 -2
  227. data/lib/openstudio-standards/standards/necb/NECB2020/data/heat_pumps_heating.json +16 -6
  228. data/lib/openstudio-standards/standards/necb/NECB2020/data/unitary_acs.json +60 -61
  229. data/lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb +30 -30
  230. data/lib/openstudio-standards/standards/necb/common/btap_analysis.rb +79 -0
  231. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +16 -4
  232. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +65 -42
  233. data/lib/openstudio-standards/thermal_zone/{thermal_zone.rb → information.rb} +12 -45
  234. data/lib/openstudio-standards/thermal_zone/thermostat_schedules.rb +152 -0
  235. data/lib/openstudio-standards/version.rb +1 -1
  236. data/lib/openstudio-standards/weather/stat_file.rb +2 -2
  237. data/lib/openstudio-standards.rb +55 -38
  238. metadata +106 -66
  239. data/lib/openstudio-standards/btap/costing/common_resources/constructions_glazing.csv +0 -61
  240. data/lib/openstudio-standards/btap/costing/common_resources/costs.csv +0 -1904
  241. data/lib/openstudio-standards/hvac/components/create.rb +0 -169
  242. data/lib/openstudio-standards/hvac/components/modify.rb +0 -42
  243. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirConditionerVariableRefrigerantFlow.rb +0 -438
  244. data/lib/openstudio-standards/prototypes/common/objects/Prototype.BoilerHotWater.rb +0 -123
  245. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CentralAirSourceHeatPump.rb +0 -216
  246. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXSingleSpeed.rb +0 -273
  247. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXTwoSpeed.rb +0 -159
  248. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWater.rb +0 -77
  249. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWaterToAirHeatPumpEquationFit.rb +0 -154
  250. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingDXSingleSpeed.rb +0 -214
  251. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingElectric.rb +0 -53
  252. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingGas.rb +0 -72
  253. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWater.rb +0 -95
  254. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWaterToAirHeatPumpEquationFit.rb +0 -125
  255. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ControllerWaterCoil.rb +0 -17
  256. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.transformers.rb +0 -90
  257. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Pump.rb +0 -4
  258. data/lib/openstudio-standards/prototypes/common/objects/Prototype.PumpVariableSpeed.rb +0 -70
  259. data/lib/openstudio-standards/prototypes/common/objects/Prototype.radiant_system_controls.rb +0 -590
  260. data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +0 -901
  261. data/lib/openstudio-standards/standards/Standards.FanConstantVolume.rb +0 -5
  262. data/lib/openstudio-standards/standards/Standards.FanOnOff.rb +0 -5
  263. data/lib/openstudio-standards/standards/Standards.FanZoneExhaust.rb +0 -5
  264. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsConstantSpeed.rb +0 -5
  265. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsVariableSpeed.rb +0 -55
  266. data/lib/openstudio-standards/standards/Standards.PumpConstantSpeed.rb +0 -5
  267. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanConstantVolume.rb +0 -5
  268. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanOnOff.rb +0 -5
  269. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanZoneExhaust.rb +0 -5
  270. data/lib/openstudio-standards/standards/cbes/data/cbes.fans.json +0 -328
  271. data/lib/openstudio-standards/standards/deer/data/deer.fans.json +0 -328
  272. /data/lib/openstudio-standards/btap/{costing/common_resources → common_resources}/ConstructionProperties.csv +0 -0
  273. /data/lib/openstudio-standards/btap/{costing/common_resources → common_resources}/Constructions.csv +0 -0
  274. /data/lib/openstudio-standards/btap/{costing/common_resources → common_resources}/construction_sets.csv +0 -0
  275. /data/lib/openstudio-standards/btap/{costing/common_resources → common_resources}/constructions_opaque.csv +0 -0
  276. /data/lib/openstudio-standards/btap/{costing/common_resources → common_resources}/costs_local_factors.csv +0 -0
  277. /data/lib/openstudio-standards/btap/{costing/common_resources → common_resources}/hvac_vent_ahu.csv +0 -0
  278. /data/lib/openstudio-standards/btap/{costing/common_resources → common_resources}/lighting_sets.csv +0 -0
  279. /data/lib/openstudio-standards/btap/{costing/common_resources → common_resources}/locations.csv +0 -0
  280. /data/lib/openstudio-standards/btap/{costing/common_resources → common_resources}/materials_glazing.csv +0 -0
  281. /data/lib/openstudio-standards/btap/{costing/common_resources → common_resources}/materials_lighting.csv +0 -0
  282. /data/lib/openstudio-standards/btap/{costing/common_resources → common_resources}/materials_opaque.csv +0 -0
  283. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PumpVariableSpeed.rb +0 -0
  284. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.PumpVariableSpeed.rb +0 -0
  285. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.PumpVariableSpeed.rb +0 -0
  286. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.PumpVariableSpeed.rb +0 -0
  287. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.PumpVariableSpeed.rb +0 -0
  288. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Pump.rb +0 -0
  289. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.PumpVariableSpeed.rb +0 -0
@@ -160,26 +160,29 @@ class NECB2011
160
160
 
161
161
  # Reduces the SRR to the values specified by the PRM. SRR reduction
162
162
  # will be done by shrinking vertices toward the centroid.
163
- #
164
- def apply_standard_skylight_to_roof_ratio(model:, srr_set: -1.0)
163
+ def apply_standard_skylight_to_roof_ratio(model:, srr_set: -1.0, srr_opt: '')
165
164
  # If srr_set is between 1.0 and 1.2 set it to the maximum allowed by the NECB. If srr_set is between 0.0 and 1.0
166
165
  # apply whatever was passed. If srr_set >= 1.2 then set the existing srr of the building to be the necb maximum
167
166
  # only if the the srr exceeds this maximum (otherwise leave it to be whatever was modeled).
168
-
167
+ #
169
168
  # srr_set settings:
170
- # 0-1: Remove all skylights and add skylights to match this srr
171
- # -1: Remove all skylights and add skylights to match max srr from NECB
172
- # -2: Do not apply any srr changes, leave skylights alone (also works for srr > 1)
173
- # -3: Use old method which reduces existing skylight size (if necessary) to meet maximum NECB skylight limit
169
+ # 0-1: Remove all skylights and add skylights to match this srr
170
+ # -1: Remove all skylights and add skylights to match max srr from NECB
171
+ # -2: Do not apply any srr changes, leave skylights alone (also works for srr > 1)
172
+ # -3: Use old method which reduces existing skylight size (if necessary) to meet maximum NECB skylight limit
174
173
  # <-3.1: Remove all skylights
175
- # > 1: Do nothing
176
-
174
+ # > 1: Do nothing
175
+ #
176
+ # By default, :srr_opt is an empty string (" "). If set to "osut", SRR is
177
+ # instead met using OSut's addSkylights (:srr_set numeric values may apply).
177
178
  return if srr_set.to_f > 1.0
178
- return apply_max_srr_nrcan(model: model, srr_lim: srr_set.to_f) if srr_set.to_f >= 0.0 && srr_set.to_f <= 1.0
179
+ return apply_max_srr_nrcan(model: model, srr_lim: srr_set.to_f, srr_opt: srr_opt) if srr_set.to_f >= 0.0 && srr_set.to_f <= 1.0
180
+
179
181
  # Get the maximum NECB srr
180
- return apply_max_srr_nrcan(model: model, srr_lim: get_standards_constant('skylight_to_roof_ratio_max_value').to_f) if srr_set.to_f >= -1.1 && srr_set.to_f <= -0.9
182
+ return apply_max_srr_nrcan(model: model, srr_lim: get_standards_constant('skylight_to_roof_ratio_max_value').to_f, srr_opt: srr_opt) if srr_set.to_f >= -1.1 && srr_set.to_f <= -0.9
183
+
181
184
  return if srr_set.to_f >= -2.1 && srr_set.to_f <= -1.9
182
- return apply_max_srr_nrcan(model: model, srr_lim: srr_set.to_f) if srr_set.to_f < -3.1
185
+ return apply_max_srr_nrcan(model: model, srr_lim: srr_set.to_f, srr_opt: srr_opt) if srr_set.to_f < -3.1
183
186
  return unless srr_set.to_f >= -3.1 && srr_set.to_f <= -2.9
184
187
 
185
188
  # SRR limit
@@ -197,6 +200,7 @@ class NECB2011
197
200
  sh_sky_m2 = 0
198
201
  total_roof_m2 = 0.001
199
202
  total_subsurface_m2 = 0
203
+
200
204
  model.getSpaces.sort.each do |space|
201
205
  # Loop through all surfaces in this space
202
206
  wall_area_m2 = 0
@@ -288,6 +292,680 @@ class NECB2011
288
292
  return eval(get_standards_formula('fdwr_formula'))
289
293
  end
290
294
 
295
+ ##
296
+ # Returns NECB-required U-factor, based on surface type, outside boundary
297
+ # condition, heating-degree-days (18C) and NECB edition (template). The bulk
298
+ # of this should be a CSV file.
299
+ #
300
+ # @author denis@rd2.ca
301
+ #
302
+ # @param stype [#to_s] surface type, e.g. "roofceiling"
303
+ # @param condition [#to_s] outside boundary condition, e.g. "outdoors"
304
+ # @param hdd [#to_f] heating-degree-days 18C
305
+ #
306
+ # @return [Float] required U-factor, defaults to 0.110 W/m2.K.
307
+ def max_u_necb(stype = "roofceiling", condition = "outdoors", hdd = 8000)
308
+ hdd = hdd.respond_to?(:to_f) ? hdd.to_f : 8000
309
+
310
+ # Admissible surface types.
311
+ stypes = ["wall", "roofceiling", "floor", "window", "skylight", "door"]
312
+ stype = stype.respond_to?(:to_s) ? stype.to_s.downcase : "roofceiling"
313
+ stype = stypes.include?(stype) ? stype : "roofceiling"
314
+
315
+ # Admissible outside boundary conditions.
316
+ conditions = ["outdoors", "ground"]
317
+ condition = condition.respond_to?(:to_s) ? condition.to_s.downcase : "outdoors"
318
+ condition = conditions.include?(condition) ? condition : "outdoors"
319
+
320
+ templates = ["NECB2011", "NECB2015", "NECB2017", "NECB2020"]
321
+
322
+ data = {}
323
+
324
+ # Initialize data.
325
+ templates.each do |tp|
326
+ data[tp] = {}
327
+
328
+ conditions.each do |cd|
329
+ data[tp][cd] = {}
330
+
331
+ stypes.each { |st| data[tp][cd][st] = {} }
332
+ end
333
+ end
334
+
335
+ # From NECB Part 3 tables. Moving away from BTAP formulas. Should be CSV.
336
+ data["NECB2011"]["outdoors"]["wall" ][3000] = 0.315
337
+ data["NECB2011"]["outdoors"]["wall" ][4000] = 0.278
338
+ data["NECB2011"]["outdoors"]["wall" ][5000] = 0.247
339
+ data["NECB2011"]["outdoors"]["wall" ][6000] = 0.210
340
+ data["NECB2011"]["outdoors"]["wall" ][7000] = 0.210
341
+ data["NECB2011"]["outdoors"]["wall" ][9999] = 0.183
342
+ data["NECB2011"]["outdoors"]["roofceiling"][3000] = 0.227
343
+ data["NECB2011"]["outdoors"]["roofceiling"][4000] = 0.183
344
+ data["NECB2011"]["outdoors"]["roofceiling"][5000] = 0.183
345
+ data["NECB2011"]["outdoors"]["roofceiling"][6000] = 0.162
346
+ data["NECB2011"]["outdoors"]["roofceiling"][7000] = 0.162
347
+ data["NECB2011"]["outdoors"]["roofceiling"][9999] = 0.142
348
+ data["NECB2011"]["outdoors"]["floor" ][3000] = 0.227
349
+ data["NECB2011"]["outdoors"]["floor" ][4000] = 0.183
350
+ data["NECB2011"]["outdoors"]["floor" ][5000] = 0.183
351
+ data["NECB2011"]["outdoors"]["floor" ][6000] = 0.162
352
+ data["NECB2011"]["outdoors"]["floor" ][7000] = 0.162
353
+ data["NECB2011"]["outdoors"]["floor" ][9999] = 0.142
354
+ data["NECB2011"]["outdoors"]["window" ][3000] = 2.400
355
+ data["NECB2011"]["outdoors"]["window" ][4000] = 2.200
356
+ data["NECB2011"]["outdoors"]["window" ][5000] = 2.200
357
+ data["NECB2011"]["outdoors"]["window" ][6000] = 2.200
358
+ data["NECB2011"]["outdoors"]["window" ][7000] = 2.200
359
+ data["NECB2011"]["outdoors"]["window" ][9999] = 1.600
360
+ data["NECB2011"]["outdoors"]["skylight" ][3000] = 2.400
361
+ data["NECB2011"]["outdoors"]["skylight" ][4000] = 2.200
362
+ data["NECB2011"]["outdoors"]["skylight" ][5000] = 2.200
363
+ data["NECB2011"]["outdoors"]["skylight" ][6000] = 2.200
364
+ data["NECB2011"]["outdoors"]["skylight" ][7000] = 2.200
365
+ data["NECB2011"]["outdoors"]["skylight" ][9999] = 1.600
366
+ data["NECB2011"]["outdoors"]["door" ][3000] = 2.400
367
+ data["NECB2011"]["outdoors"]["door" ][4000] = 2.200
368
+ data["NECB2011"]["outdoors"]["door" ][5000] = 2.200
369
+ data["NECB2011"]["outdoors"]["door" ][6000] = 2.200
370
+ data["NECB2011"]["outdoors"]["door" ][7000] = 2.200
371
+ data["NECB2011"]["outdoors"]["door" ][9999] = 1.600
372
+ data["NECB2011"]["ground" ]["wall" ][3000] = 0.568
373
+ data["NECB2011"]["ground" ]["wall" ][4000] = 0.379
374
+ data["NECB2011"]["ground" ]["wall" ][5000] = 0.284
375
+ data["NECB2011"]["ground" ]["wall" ][6000] = 0.284
376
+ data["NECB2011"]["ground" ]["wall" ][7000] = 0.284
377
+ data["NECB2011"]["ground" ]["wall" ][9999] = 0.210
378
+ data["NECB2011"]["ground" ]["roofceiling"][3000] = 0.568
379
+ data["NECB2011"]["ground" ]["roofceiling"][4000] = 0.379
380
+ data["NECB2011"]["ground" ]["roofceiling"][5000] = 0.284
381
+ data["NECB2011"]["ground" ]["roofceiling"][6000] = 0.284
382
+ data["NECB2011"]["ground" ]["roofceiling"][7000] = 0.284
383
+ data["NECB2011"]["ground" ]["roofceiling"][9999] = 0.210
384
+ data["NECB2011"]["ground" ]["floor" ][3000] = 0.757
385
+ data["NECB2011"]["ground" ]["floor" ][4000] = 0.757
386
+ data["NECB2011"]["ground" ]["floor" ][5000] = 0.757
387
+ data["NECB2011"]["ground" ]["floor" ][6000] = 0.757
388
+ data["NECB2011"]["ground" ]["floor" ][7000] = 0.757
389
+ data["NECB2011"]["ground" ]["floor" ][9999] = 0.379
390
+
391
+ data["NECB2015"]["outdoors"]["wall" ][3000] = 0.315
392
+ data["NECB2015"]["outdoors"]["wall" ][4000] = 0.278
393
+ data["NECB2015"]["outdoors"]["wall" ][5000] = 0.247
394
+ data["NECB2015"]["outdoors"]["wall" ][6000] = 0.210
395
+ data["NECB2015"]["outdoors"]["wall" ][7000] = 0.210
396
+ data["NECB2015"]["outdoors"]["wall" ][9999] = 0.183
397
+ data["NECB2015"]["outdoors"]["roofceiling"][3000] = 0.227
398
+ data["NECB2015"]["outdoors"]["roofceiling"][4000] = 0.183
399
+ data["NECB2015"]["outdoors"]["roofceiling"][5000] = 0.183
400
+ data["NECB2015"]["outdoors"]["roofceiling"][6000] = 0.162
401
+ data["NECB2015"]["outdoors"]["roofceiling"][7000] = 0.162
402
+ data["NECB2015"]["outdoors"]["roofceiling"][9999] = 0.142
403
+ data["NECB2015"]["outdoors"]["floor" ][3000] = 0.227
404
+ data["NECB2015"]["outdoors"]["floor" ][4000] = 0.183
405
+ data["NECB2015"]["outdoors"]["floor" ][5000] = 0.183
406
+ data["NECB2015"]["outdoors"]["floor" ][6000] = 0.162
407
+ data["NECB2015"]["outdoors"]["floor" ][7000] = 0.162
408
+ data["NECB2015"]["outdoors"]["floor" ][9999] = 0.142
409
+ data["NECB2015"]["outdoors"]["window" ][3000] = 2.400
410
+ data["NECB2015"]["outdoors"]["window" ][4000] = 2.200
411
+ data["NECB2015"]["outdoors"]["window" ][5000] = 2.200
412
+ data["NECB2015"]["outdoors"]["window" ][6000] = 2.200
413
+ data["NECB2015"]["outdoors"]["window" ][7000] = 2.200
414
+ data["NECB2015"]["outdoors"]["window" ][9999] = 1.600
415
+ data["NECB2015"]["outdoors"]["skylight" ][3000] = 2.400
416
+ data["NECB2015"]["outdoors"]["skylight" ][4000] = 2.200
417
+ data["NECB2015"]["outdoors"]["skylight" ][5000] = 2.200
418
+ data["NECB2015"]["outdoors"]["skylight" ][6000] = 2.200
419
+ data["NECB2015"]["outdoors"]["skylight" ][7000] = 2.200
420
+ data["NECB2015"]["outdoors"]["skylight" ][9999] = 1.600
421
+ data["NECB2015"]["outdoors"]["door" ][3000] = 2.400
422
+ data["NECB2015"]["outdoors"]["door" ][4000] = 2.200
423
+ data["NECB2015"]["outdoors"]["door" ][5000] = 2.200
424
+ data["NECB2015"]["outdoors"]["door" ][6000] = 2.200
425
+ data["NECB2015"]["outdoors"]["door" ][7000] = 2.200
426
+ data["NECB2015"]["outdoors"]["door" ][9999] = 1.600
427
+ data["NECB2015"]["ground" ]["wall" ][3000] = 0.568
428
+ data["NECB2015"]["ground" ]["wall" ][4000] = 0.379
429
+ data["NECB2015"]["ground" ]["wall" ][5000] = 0.284
430
+ data["NECB2015"]["ground" ]["wall" ][6000] = 0.284
431
+ data["NECB2015"]["ground" ]["wall" ][7000] = 0.284
432
+ data["NECB2015"]["ground" ]["wall" ][9999] = 0.210
433
+ data["NECB2015"]["ground" ]["roofceiling"][3000] = 0.568
434
+ data["NECB2015"]["ground" ]["roofceiling"][4000] = 0.379
435
+ data["NECB2015"]["ground" ]["roofceiling"][5000] = 0.284
436
+ data["NECB2015"]["ground" ]["roofceiling"][6000] = 0.284
437
+ data["NECB2015"]["ground" ]["roofceiling"][7000] = 0.284
438
+ data["NECB2015"]["ground" ]["roofceiling"][9999] = 0.210
439
+ data["NECB2015"]["ground" ]["floor" ][3000] = 0.757
440
+ data["NECB2015"]["ground" ]["floor" ][4000] = 0.757
441
+ data["NECB2015"]["ground" ]["floor" ][5000] = 0.757
442
+ data["NECB2015"]["ground" ]["floor" ][6000] = 0.757
443
+ data["NECB2015"]["ground" ]["floor" ][7000] = 0.757
444
+ data["NECB2015"]["ground" ]["floor" ][9999] = 0.379
445
+
446
+ data["NECB2017"]["outdoors"]["wall" ][3000] = 0.315
447
+ data["NECB2017"]["outdoors"]["wall" ][4000] = 0.278
448
+ data["NECB2017"]["outdoors"]["wall" ][5000] = 0.247
449
+ data["NECB2017"]["outdoors"]["wall" ][6000] = 0.210
450
+ data["NECB2017"]["outdoors"]["wall" ][7000] = 0.210
451
+ data["NECB2017"]["outdoors"]["wall" ][9999] = 0.183
452
+ data["NECB2017"]["outdoors"]["roofceiling"][3000] = 0.193
453
+ data["NECB2017"]["outdoors"]["roofceiling"][4000] = 0.156
454
+ data["NECB2017"]["outdoors"]["roofceiling"][5000] = 0.156
455
+ data["NECB2017"]["outdoors"]["roofceiling"][6000] = 0.138
456
+ data["NECB2017"]["outdoors"]["roofceiling"][7000] = 0.138
457
+ data["NECB2017"]["outdoors"]["roofceiling"][9999] = 0.121
458
+ data["NECB2017"]["outdoors"]["floor" ][3000] = 0.227
459
+ data["NECB2017"]["outdoors"]["floor" ][4000] = 0.183
460
+ data["NECB2017"]["outdoors"]["floor" ][5000] = 0.183
461
+ data["NECB2017"]["outdoors"]["floor" ][6000] = 0.162
462
+ data["NECB2017"]["outdoors"]["floor" ][7000] = 0.162
463
+ data["NECB2017"]["outdoors"]["floor" ][9999] = 0.142
464
+ data["NECB2017"]["outdoors"]["window" ][3000] = 2.100
465
+ data["NECB2017"]["outdoors"]["window" ][4000] = 1.900
466
+ data["NECB2017"]["outdoors"]["window" ][5000] = 1.900
467
+ data["NECB2017"]["outdoors"]["window" ][6000] = 1.900
468
+ data["NECB2017"]["outdoors"]["window" ][7000] = 1.900
469
+ data["NECB2017"]["outdoors"]["window" ][9999] = 1.400
470
+ data["NECB2017"]["outdoors"]["skylight" ][3000] = 2.100
471
+ data["NECB2017"]["outdoors"]["skylight" ][4000] = 1.900
472
+ data["NECB2017"]["outdoors"]["skylight" ][5000] = 1.900
473
+ data["NECB2017"]["outdoors"]["skylight" ][6000] = 1.900
474
+ data["NECB2017"]["outdoors"]["skylight" ][7000] = 1.900
475
+ data["NECB2017"]["outdoors"]["skylight" ][9999] = 1.400
476
+ data["NECB2017"]["outdoors"]["door" ][3000] = 2.100
477
+ data["NECB2017"]["outdoors"]["door" ][4000] = 1.900
478
+ data["NECB2017"]["outdoors"]["door" ][5000] = 1.900
479
+ data["NECB2017"]["outdoors"]["door" ][6000] = 1.900
480
+ data["NECB2017"]["outdoors"]["door" ][7000] = 1.900
481
+ data["NECB2017"]["outdoors"]["door" ][9999] = 1.400
482
+ data["NECB2017"]["ground" ]["wall" ][3000] = 0.568
483
+ data["NECB2017"]["ground" ]["wall" ][4000] = 0.379
484
+ data["NECB2017"]["ground" ]["wall" ][5000] = 0.284
485
+ data["NECB2017"]["ground" ]["wall" ][6000] = 0.284
486
+ data["NECB2017"]["ground" ]["wall" ][7000] = 0.284
487
+ data["NECB2017"]["ground" ]["wall" ][9999] = 0.210
488
+ data["NECB2017"]["ground" ]["roofceiling"][3000] = 0.568
489
+ data["NECB2017"]["ground" ]["roofceiling"][4000] = 0.379
490
+ data["NECB2017"]["ground" ]["roofceiling"][5000] = 0.284
491
+ data["NECB2017"]["ground" ]["roofceiling"][6000] = 0.284
492
+ data["NECB2017"]["ground" ]["roofceiling"][7000] = 0.284
493
+ data["NECB2017"]["ground" ]["roofceiling"][9999] = 0.210
494
+ data["NECB2017"]["ground" ]["floor" ][3000] = 0.757
495
+ data["NECB2017"]["ground" ]["floor" ][4000] = 0.757
496
+ data["NECB2017"]["ground" ]["floor" ][5000] = 0.757
497
+ data["NECB2017"]["ground" ]["floor" ][6000] = 0.757
498
+ data["NECB2017"]["ground" ]["floor" ][7000] = 0.757
499
+ data["NECB2017"]["ground" ]["floor" ][9999] = 0.379
500
+
501
+ data["NECB2020"]["outdoors"]["wall" ][3000] = 0.290
502
+ data["NECB2020"]["outdoors"]["wall" ][4000] = 0.265
503
+ data["NECB2020"]["outdoors"]["wall" ][5000] = 0.240
504
+ data["NECB2020"]["outdoors"]["wall" ][6000] = 0.215
505
+ data["NECB2020"]["outdoors"]["wall" ][7000] = 0.190
506
+ data["NECB2020"]["outdoors"]["wall" ][9999] = 0.165
507
+ data["NECB2020"]["outdoors"]["roofceiling"][3000] = 0.164
508
+ data["NECB2020"]["outdoors"]["roofceiling"][4000] = 0.156
509
+ data["NECB2020"]["outdoors"]["roofceiling"][5000] = 0.138
510
+ data["NECB2020"]["outdoors"]["roofceiling"][6000] = 0.121
511
+ data["NECB2020"]["outdoors"]["roofceiling"][7000] = 0.117
512
+ data["NECB2020"]["outdoors"]["roofceiling"][9999] = 0.110
513
+ data["NECB2020"]["outdoors"]["floor" ][3000] = 0.193
514
+ data["NECB2020"]["outdoors"]["floor" ][4000] = 0.175
515
+ data["NECB2020"]["outdoors"]["floor" ][5000] = 0.156
516
+ data["NECB2020"]["outdoors"]["floor" ][6000] = 0.138
517
+ data["NECB2020"]["outdoors"]["floor" ][7000] = 0.121
518
+ data["NECB2020"]["outdoors"]["floor" ][9999] = 0.117
519
+ data["NECB2020"]["outdoors"]["window" ][3000] = 1.900
520
+ data["NECB2020"]["outdoors"]["window" ][4000] = 1.900
521
+ data["NECB2020"]["outdoors"]["window" ][5000] = 1.730
522
+ data["NECB2020"]["outdoors"]["window" ][6000] = 1.730
523
+ data["NECB2020"]["outdoors"]["window" ][7000] = 1.440
524
+ data["NECB2020"]["outdoors"]["window" ][9999] = 1.440
525
+ data["NECB2020"]["outdoors"]["skylight" ][3000] = 2.690
526
+ data["NECB2020"]["outdoors"]["skylight" ][4000] = 2.690
527
+ data["NECB2020"]["outdoors"]["skylight" ][5000] = 2.410
528
+ data["NECB2020"]["outdoors"]["skylight" ][6000] = 2.410
529
+ data["NECB2020"]["outdoors"]["skylight" ][7000] = 2.010
530
+ data["NECB2020"]["outdoors"]["skylight" ][9999] = 2.010
531
+ data["NECB2020"]["outdoors"]["door" ][3000] = 2.120
532
+ data["NECB2020"]["outdoors"]["door" ][4000] = 1.900
533
+ data["NECB2020"]["outdoors"]["door" ][5000] = 1.900
534
+ data["NECB2020"]["outdoors"]["door" ][6000] = 1.900
535
+ data["NECB2020"]["outdoors"]["door" ][7000] = 1.900
536
+ data["NECB2020"]["outdoors"]["door" ][9999] = 1.440
537
+ data["NECB2020"]["ground" ]["wall" ][3000] = 0.568
538
+ data["NECB2020"]["ground" ]["wall" ][4000] = 0.379
539
+ data["NECB2020"]["ground" ]["wall" ][5000] = 0.284
540
+ data["NECB2020"]["ground" ]["wall" ][6000] = 0.284
541
+ data["NECB2020"]["ground" ]["wall" ][7000] = 0.284
542
+ data["NECB2020"]["ground" ]["wall" ][9999] = 0.210
543
+ data["NECB2020"]["ground" ]["roofceiling"][3000] = 0.568
544
+ data["NECB2020"]["ground" ]["roofceiling"][4000] = 0.379
545
+ data["NECB2020"]["ground" ]["roofceiling"][5000] = 0.284
546
+ data["NECB2020"]["ground" ]["roofceiling"][6000] = 0.284
547
+ data["NECB2020"]["ground" ]["roofceiling"][7000] = 0.284
548
+ data["NECB2020"]["ground" ]["roofceiling"][9999] = 0.210
549
+ data["NECB2020"]["ground" ]["floor" ][3000] = 0.757
550
+ data["NECB2020"]["ground" ]["floor" ][4000] = 0.757
551
+ data["NECB2020"]["ground" ]["floor" ][5000] = 0.757
552
+ data["NECB2020"]["ground" ]["floor" ][6000] = 0.757
553
+ data["NECB2020"]["ground" ]["floor" ][7000] = 0.757
554
+ data["NECB2020"]["ground" ]["floor" ][9999] = 0.379
555
+
556
+ # Return required U-factor if provided HDD < stored HDD.
557
+ data[@template][condition][stype].each { |hdd18, u| return u if hdd < hdd18 }
558
+
559
+ 0.110
560
+ end
561
+
562
+ ##
563
+ # Adds default construction sets, based on building 'category' & 'structure'
564
+ # selections. This is an alternative method to 'model_apply_construction'
565
+ # & 'apply_standard_construction_properties' methods.
566
+ #
567
+ # @author denis@rd2.ca
568
+ #
569
+ # @param model [OpenStudio::Model::Model] a model
570
+ # @param necb_hdd [Boolean] whether to rely on BTAP to set HDD (vs stat file)
571
+ # @param a [Hash] optional U & SHGC overrides
572
+ # @option a [Hash] eWallU exposed wall Uo (or Ut)
573
+ # @option a [Hash] eFloorU exposed floor Uo (or Ut)
574
+ # @option a [Hash] eRoofU exposed roof Uo (or Ut)
575
+ # @option a [Hash] gWallU ground wall Uo (or Ut)
576
+ # @option a [Hash] gFloorU ground floor Uo (or Ut)
577
+ # @option a [Hash] gRoofU ground roof Uo (or Ut)
578
+ # @option a [Hash] doorU opaque door U
579
+ # @option a [Hash] fenU fenestration U (e.g. fixe, operable, glass door)
580
+ # @option a [Hash] skyU skylight U
581
+ # @option a [Hash] doorSHGC opaque door SHGC
582
+ # @option a [Hash] fenSHGC fenestration SHGC
583
+ # @option a [Hash] skySHGC skylight SHGC
584
+ #
585
+ # @return [Boolean] whether default constructions were successfully added.
586
+ def add_construction_sets(model, necb_hdd, a)
587
+ return false unless model.is_a?(OpenStudio::Model::Model)
588
+ return false unless a.is_a?(Hash)
589
+
590
+ btp = BTAP::Resources::Envelope::Constructions # alias
591
+ necb_hdd = true unless [true, false].include?(necb_hdd)
592
+
593
+ # Validate argh options (limited to either U or SHGC)
594
+ a.each do |k, v|
595
+ return false unless v.is_a?(Numeric)
596
+ return false unless v.round(3) > 0
597
+
598
+ if k.to_s[-1].downcase == "u"
599
+ return false unless v.between?(btp::uMIN, btp::uMAX)
600
+ else
601
+ return false unless v.between?(0.05, 0.95)
602
+ end
603
+ end
604
+
605
+ tag = "space_conditioning_category"
606
+ bldg = model.getBuilding
607
+ hdd = get_necb_hdd18(model: model, necb_hdd: necb_hdd)
608
+
609
+ # Reset constructions.
610
+ model.getPlanarSurfaces.sort.each(&:resetConstruction)
611
+
612
+ # Fetch NECB-required U-factors (or provided as arguments).
613
+ eWallU = a[:eWallU ] ? a[:eWallU ] : max_u_necb("wall", "outdoors", hdd)
614
+ eRoofU = a[:eRoofU ] ? a[:eRoofU ] : max_u_necb("roofceiling", "outdoors", hdd)
615
+ eFloorU = a[:eFloorU] ? a[:eFloorU] : max_u_necb("floor", "outdoors", hdd)
616
+ gWallU = a[:gWallU ] ? a[:gWallU ] : max_u_necb("wall", "ground", hdd)
617
+ gFloorU = a[:gFloorU] ? a[:gFloorU] : max_u_necb("floor", "ground", hdd)
618
+ gRoofU = a[:gRoofU ] ? a[:gRoofU ] : max_u_necb("roofceiling", "ground", hdd)
619
+ doorU = a[:doorU ] ? a[:doorU ] : max_u_necb("door", "outdoors", hdd)
620
+ fenU = a[:fenU ] ? a[:fenU ] : max_u_necb("window", "outdoors", hdd)
621
+ skyU = a[:skyU ] ? a[:skyU ] : max_u_necb("skylight", "outdoors", hdd)
622
+
623
+ # FYI: Excerpt of the 'SimpleGlazing' material generated using BTAP:
624
+ #
625
+ # SimpleGlazing:U=0.220 SHGC=0.600, !- Name
626
+ # 2.2, !- U-Factor {W/m2-K}
627
+ # 0.6, !- Solar Heat Gain Coefficient
628
+ # 0.21; !- Visible Transmittance
629
+ #
630
+ # 1. Identifier 'U=0.220' for an NFRC-rated U-factor of 2.2 W/m2.K ?
631
+ # 2. VT is almost always higher than SHGC - not the other way around. VT
632
+ # should be set here based on a reasonable LSG ratio:
633
+ # - eta-publications.lbl.gov/sites/default/files/femp-spec-sel-low-e.pdf
634
+ # - www.wbdg.org/resources/windows-and-glazing
635
+ #
636
+ # ... for the moment, sticking to SHGC 60%, yet keeping default VT.
637
+ doorSHGC = a[:doorSHGC] ? a[:doorSHGC] : 0.60
638
+ fenSHGC = a[:fenSHGC ] ? a[:fenSHGC ] : 0.60
639
+ skySHGC = a[:skySHGC ] ? a[:skySHGC ] : 0.60
640
+
641
+ # Fetch corresponding BTAP structure parameters.
642
+ category = @structure.category
643
+ structure = @structure.structure
644
+ framing = @structure.framing
645
+ cladding = @structure.cladding
646
+ finish = @structure.finish
647
+
648
+ # Uninsulated slab-on-grade, except if HDD > 6999 (Uo = 0.379 W/m2.K).
649
+ # If HDD < 7000, slab-on-grade insulation is instead only required along
650
+ # perimeter. Perimeter insulation requires special treatment, à la KIVA. The
651
+ # vast majority of models do not have full-height basements. Exceptions:
652
+ # - LargeOffice
653
+ # - LargeHotel
654
+ # - Hospital
655
+ #
656
+ # The solution is temporarily OK, yet a more nuanced treatment is required
657
+ # for full-height basement cases. This would likely require a space-by-space
658
+ # treatment, based on Z-axis grade-vs-floor height difference - @todo.
659
+ specs = {}
660
+ specs[:type ] = :slab
661
+ specs[:uo ] = nil
662
+ specs[:uo ] = gFloorU if hdd > 6999
663
+ specs[:frame ] = :none unless hdd > 6999
664
+ specs[:finish] = :none if category == "robust"
665
+ specs[:finish] = :none if category == "industry"
666
+ gFloor = TBD.genConstruction(model, specs)
667
+ insulation = TBD.insulatingLayer(gFloor)
668
+
669
+ # Ensure insulating layer uniqueness for each insulated construction.
670
+ lyr = TBD.insulatingLayer(gFloor)
671
+ TBD.assignUniqueMaterial(gFloor, lyr[:index]) if lyr[:index]
672
+
673
+ # Insulated basement wall. A more nuanced treatment is necessary for
674
+ # multiple basement stories - no insulation required below 2.4m from grade.
675
+ specs = {}
676
+ specs[:type ] = :basement
677
+ specs[:uo ] = gWallU
678
+ gWall = TBD.genConstruction(model, specs)
679
+
680
+ lyr = TBD.insulatingLayer(gWall)
681
+ TBD.assignUniqueMaterial(gWall, lyr[:index]) if lyr[:index]
682
+
683
+ # Insulated basement roof. Again, a more nuanced approach is necessary if
684
+ # the basement roof is below 1.2m from grade (e.g. a tunnel).
685
+ specs = {}
686
+ specs[:type ] = :roof
687
+ specs[:uo ] = gRoofU
688
+ specs[:frame ] = :medium
689
+ specs[:finish] = :heavy
690
+ gRoof = TBD.genConstruction(model, specs)
691
+
692
+ lyr = TBD.insulatingLayer(gRoof)
693
+ TBD.assignUniqueMaterial(gRoof, lyr[:index]) if lyr[:index]
694
+
695
+ # Outdoor-facing wall.
696
+ specs = {}
697
+ specs[:type ] = :wall
698
+ specs[:uo ] = eWallU
699
+ specs[:frame ] = :medium
700
+ specs[:clad ] = :heavy if category == "robust"
701
+ specs[:finish] = :medium if category == "robust"
702
+ specs[:finish] = :medium if framing == :cmu
703
+ eWall = TBD.genConstruction(model, specs)
704
+
705
+ lyr = TBD.insulatingLayer(eWall)
706
+ TBD.assignUniqueMaterial(eWall, lyr[:index]) if lyr[:index]
707
+
708
+ # Outdoor-facing roof.
709
+ specs = {}
710
+ specs[:type ] = :roof
711
+ specs[:uo ] = eRoofU
712
+ specs[:clad ] = :medium if category == "housing" && structure == :concrete
713
+ specs[:clad ] = :medium if category == "lodging" && structure == :concrete
714
+ specs[:frame ] = :medium
715
+ specs[:frame ] = :heavy if framing == :wood
716
+ specs[:finish] = :medium if category == "robust"
717
+ specs[:finish] = :heavy if category == "housing" && structure == :concrete
718
+ specs[:finish] = :heavy if category == "lodging" && structure == :concrete
719
+ eRoof = TBD.genConstruction(model, specs)
720
+
721
+ lyr = TBD.insulatingLayer(eRoof)
722
+ TBD.assignUniqueMaterial(eRoof, lyr[:index]) if lyr[:index]
723
+
724
+ # Outdoor-facing floor.
725
+ specs = {}
726
+ specs[:type ] = :floor
727
+ specs[:uo ] = eFloorU
728
+ specs[:finish] = :medium unless framing == :wood
729
+ specs[:finish] = :heavy if category == "housing" && structure == :concrete
730
+ specs[:finish] = :heavy if category == "lodging" && structure == :concrete
731
+ eFloor = TBD.genConstruction(model, specs)
732
+
733
+ lyr = TBD.insulatingLayer(eFloor)
734
+ TBD.assignUniqueMaterial(eFloor, lyr[:index]) if lyr[:index]
735
+
736
+ # Outdoor-facing, opaque door.
737
+ specs = {}
738
+ specs[:type ] = :door
739
+ specs[:uo ] = doorU
740
+ door = TBD.genConstruction(model, specs)
741
+
742
+ # Outdoor-facing, vertical fenestration.
743
+ specs = {}
744
+ specs[:type ] = :window
745
+ specs[:uo ] = fenU
746
+ specs[:shgc ] = fenSHGC
747
+ fen = TBD.genConstruction(model, specs)
748
+
749
+ # Outdoor-facing, horizontal skylight.
750
+ specs = {}
751
+ specs[:type ] = :skylight
752
+ specs[:uo ] = skyU
753
+ specs[:shgc ] = skySHGC
754
+ sky = TBD.genConstruction(model, specs)
755
+
756
+ # Interzone/partition wall.
757
+ specs = {}
758
+ specs[:type ] = :partition
759
+ iWall = TBD.genConstruction(model, specs)
760
+
761
+ # Interzone roof/ceiling & floor.
762
+ specs = {}
763
+ specs[:type ] = :partition
764
+ specs[:frame ] = :medium unless framing == :wood
765
+ specs[:frame ] = :heavy if category == "housing" && structure == :concrete
766
+ specs[:frame ] = :heavy if category == "lodging" && structure == :concrete
767
+ specs[:frame ] = :heavy if category == "robust"
768
+ specs[:clad ] = :none if category == "robust"
769
+ specs[:finish] = :none if category == "robust"
770
+ iRoof = TBD.genConstruction(model, specs)
771
+ iFloor = TBD.genConstruction(model, specs)
772
+
773
+ # Shading material.
774
+ specs = {type: :shading}
775
+ shading = TBD.genConstruction(model, specs)
776
+
777
+ # Building-wide, default constructions.
778
+ intBLDG = OpenStudio::Model::DefaultSurfaceConstructions.new(model)
779
+ solBLDG = OpenStudio::Model::DefaultSurfaceConstructions.new(model)
780
+ extBLDG = OpenStudio::Model::DefaultSurfaceConstructions.new(model)
781
+ subBLDG = OpenStudio::Model::DefaultSubSurfaceConstructions.new(model)
782
+ intBLDG.setName("BTAP interior constructions BLDG")
783
+ solBLDG.setName("BTAP ground constructions BLDG")
784
+ extBLDG.setName("BTAP exterior constructions BLDG")
785
+ subBLDG.setName("BTAP subsurface constructions BLDG")
786
+ intBLDG.setWallConstruction(iWall)
787
+ intBLDG.setFloorConstruction(iFloor)
788
+ intBLDG.setRoofCeilingConstruction(iRoof)
789
+ solBLDG.setWallConstruction(gWall)
790
+ solBLDG.setFloorConstruction(gFloor)
791
+ solBLDG.setRoofCeilingConstruction(gRoof)
792
+ extBLDG.setWallConstruction(eWall)
793
+ extBLDG.setFloorConstruction(eFloor)
794
+ extBLDG.setRoofCeilingConstruction(eRoof)
795
+ subBLDG.setFixedWindowConstruction(fen)
796
+ subBLDG.setOperableWindowConstruction(fen)
797
+ subBLDG.setGlassDoorConstruction(fen)
798
+ subBLDG.setSkylightConstruction(sky)
799
+ subBLDG.setTubularDaylightDomeConstruction(sky)
800
+ subBLDG.setTubularDaylightDiffuserConstruction(sky)
801
+ subBLDG.setDoorConstruction(door)
802
+ subBLDG.setOverheadDoorConstruction(door)
803
+
804
+ setBLDG = OpenStudio::Model::DefaultConstructionSet.new(model)
805
+ setBLDG.setName("BTAP construction set BLDG")
806
+ setBLDG.setDefaultInteriorSurfaceConstructions(intBLDG)
807
+ setBLDG.setDefaultGroundContactSurfaceConstructions(solBLDG)
808
+ setBLDG.setDefaultExteriorSurfaceConstructions(extBLDG)
809
+ setBLDG.setDefaultExteriorSubSurfaceConstructions(subBLDG)
810
+ setBLDG.setInteriorPartitionConstruction(iWall)
811
+ setBLDG.setSpaceShadingConstruction(shading)
812
+ setBLDG.setBuildingShadingConstruction(shading)
813
+ setBLDG.setSiteShadingConstruction(shading)
814
+ setBLDG.setAdiabaticSurfaceConstruction(iWall)
815
+
816
+ bldg.setDefaultConstructionSet(setBLDG)
817
+
818
+ # Unconditioned, unoccupied spaces (e.g. attics) inherit their own
819
+ # default construction set. Indirectly-conditioned, unoccupied spaces
820
+ # (e.g. plenums) also inherit their own construction set.
821
+ attics = []
822
+ plenums = []
823
+
824
+ model.getSpaces.each do |space|
825
+ prop = space.additionalProperties.getFeatureAsString(tag)
826
+ next if prop.empty?
827
+ next if space.partofTotalFloorArea
828
+
829
+ prop = prop.get.downcase
830
+ attics << space if prop == "unconditioned"
831
+ plenums << space if prop == "nonresconditioned"
832
+ end
833
+
834
+ # None of the outdoor-facing surfaces of attics are required to be
835
+ # insulated. All attic interzone surfaces are required to be insulated.
836
+ unless attics.empty?
837
+ specs = {}
838
+ specs[:type ] = :slab
839
+ specs[:uo ] = nil
840
+ specs[:frame ] = :none
841
+ specs[:finish] = :none
842
+ gAtticFloor = TBD.genConstruction(model, specs)
843
+
844
+ specs = {}
845
+ specs[:type ] = :basement
846
+ specs[:clad ] = :none
847
+ specs[:finish] = :none
848
+ gAtticWall = TBD.genConstruction(model, specs)
849
+
850
+ specs = {}
851
+ specs[:type ] = :roof
852
+ specs[:uo ] = nil
853
+ specs[:clad ] = :none
854
+ specs[:finish] = :heavy
855
+ gAtticRoof = TBD.genConstruction(model, specs)
856
+
857
+ specs = {}
858
+ specs[:type ] = :wall
859
+ specs[:uo ] = nil
860
+ specs[:clad ] = :none
861
+ specs[:finish] = :none
862
+ eAtticWall = TBD.genConstruction(model, specs)
863
+
864
+ specs = {}
865
+ specs[:type ] = :roof
866
+ specs[:uo ] = nil
867
+ specs[:clad ] = :none
868
+ eAtticRoof = TBD.genConstruction(model, specs)
869
+
870
+ specs = {}
871
+ specs[:type ] = :floor
872
+ specs[:uo ] = nil
873
+ specs[:finish] = :none
874
+ eAtticFloor = TBD.genConstruction(model, specs)
875
+
876
+ specs = {}
877
+ specs[:type ] = :partition
878
+ specs[:uo ] = eWallU
879
+ iAtticWall = TBD.genConstruction(model, specs)
880
+
881
+ lyr = TBD.insulatingLayer(iAtticWall)
882
+ TBD.assignUniqueMaterial(iAtticWall, lyr[:index]) if lyr[:index]
883
+
884
+ specs = {}
885
+ specs[:type ] = :floor
886
+ specs[:uo ] = eFloorU
887
+ specs[:frame ] = :heavy
888
+ specs[:finish] = :none
889
+ specs[:finish] = :heavy if structure == :concrete
890
+ iAtticFloor = TBD.genConstruction(model, specs)
891
+
892
+ lyr = TBD.insulatingLayer(iAtticFloor)
893
+ TBD.assignUniqueMaterial(iAtticFloor, lyr[:index]) if lyr[:index]
894
+
895
+ specs = {}
896
+ specs[:type ] = :floor
897
+ specs[:uo ] = eRoofU
898
+ specs[:frame ] = :light
899
+ specs[:frame ] = :heavy if framing == :wood
900
+ specs[:clad ] = :none
901
+ specs[:clad ] = :heavy if category == "robust"
902
+ iAtticRoof = TBD.genConstruction(model, specs)
903
+
904
+ lyr = TBD.insulatingLayer(iAtticRoof)
905
+ TBD.assignUniqueMaterial(iAtticRoof, lyr[:index]) if lyr[:index]
906
+
907
+ intATTIC = OpenStudio::Model::DefaultSurfaceConstructions.new(model)
908
+ solATTIC = OpenStudio::Model::DefaultSurfaceConstructions.new(model)
909
+ extATTIC = OpenStudio::Model::DefaultSurfaceConstructions.new(model)
910
+ intATTIC.setName("BTAP interior constructions ATTIC")
911
+ solATTIC.setName("BTAP ground constructions ATTIC")
912
+ extATTIC.setName("BTAP exterior constructions ATTIC")
913
+ intATTIC.setWallConstruction(iAtticWall)
914
+ intATTIC.setFloorConstruction(iAtticFloor)
915
+ intATTIC.setRoofCeilingConstruction(iAtticRoof)
916
+ solATTIC.setWallConstruction(gAtticWall)
917
+ solATTIC.setFloorConstruction(gAtticFloor)
918
+ solATTIC.setRoofCeilingConstruction(gAtticRoof)
919
+ extATTIC.setWallConstruction(eAtticWall)
920
+ extATTIC.setFloorConstruction(eAtticFloor)
921
+ extATTIC.setRoofCeilingConstruction(eAtticRoof)
922
+
923
+ setATTIC = OpenStudio::Model::DefaultConstructionSet.new(model)
924
+ setATTIC.setName("BTAP construction set ATTIC")
925
+ setATTIC.setDefaultInteriorSurfaceConstructions(intATTIC)
926
+ setATTIC.setDefaultGroundContactSurfaceConstructions(solATTIC)
927
+ setATTIC.setDefaultExteriorSurfaceConstructions(extATTIC)
928
+
929
+ attics.each { |attic| attic.setDefaultConstructionSet(setATTIC) }
930
+ end
931
+
932
+ # No change for outdoor-facing surfaces (vs BLDG default construction set).
933
+ # Treat interzone 'plenum' floors as uninsulated ceiling tiles.
934
+ unless plenums.empty?
935
+ specs = {}
936
+ specs[:type ] = :partition
937
+ specs[:uo ] = nil
938
+ specs[:clad ] = :none
939
+ specs[:finish] = :none
940
+ iPlenumFloor = TBD.genConstruction(model, specs)
941
+
942
+ intPLENUM = OpenStudio::Model::DefaultSurfaceConstructions.new(model)
943
+ intPLENUM.setName("BTAP interior constructions PLENUM")
944
+ intPLENUM.setFloorConstruction(iPlenumFloor)
945
+
946
+ setPLENUM = OpenStudio::Model::DefaultConstructionSet.new(model)
947
+ setPLENUM.setName("BTAP construction set PLENUM")
948
+ setPLENUM.setDefaultInteriorSurfaceConstructions(intPLENUM)
949
+
950
+ plenums.each { |plenum| plenum.setDefaultConstructionSet(setPLENUM) }
951
+ end
952
+
953
+ # The above solution should work well for prototype models distributed with
954
+ # OpenStudio-Standards. However, the solution may assign odd construction
955
+ # choices for some 3rd-party models, e.g. underfloor plenums or 'sandwiched'
956
+ # unconditioned spaces. It is quite feasible to introduce a final safeguard
957
+ # check that would loop through all surfaces to:
958
+ # - check if insulated when required
959
+ # - ensure uninsulated assemblies unless required
960
+ # - hard assign constructions if either case
961
+ #
962
+ # Future upgrades could include adding story- or space-specific default
963
+ # construction sets (e.g. CMU walls of a school gym in an otherwise
964
+ # steel-framed school). @todo
965
+
966
+ true
967
+ end
968
+
291
969
  # Go through the default construction sets and hard-assigned
292
970
  # constructions. Clone the existing constructions and set their
293
971
  # intended surface type and standards construction type per
@@ -480,7 +1158,8 @@ class NECB2011
480
1158
  # Make a construction set for each space type, if one is specified
481
1159
  # apply_default_constructionsets_to_spacetypes(climate_zone, model)
482
1160
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying constructions')
483
- return true
1161
+
1162
+ true
484
1163
  end
485
1164
 
486
1165
  def apply_building_default_constructionset(model)
@@ -724,44 +1403,118 @@ class NECB2011
724
1403
  return true
725
1404
  end
726
1405
 
727
- # This method is similar to the 'apply_max_fdwr' method above but applies the maximum skylight to roof area ratio to a
728
- # building as per NECB 2011 8.4.4.3 and 3.2.1.4 (or equivalent in other versions of the NECB). It first checks for all
729
- # exterior roofs adjacent to conditioned spaces. It distinguishes between plenums and other conditioned spaces. It
730
- # uses only the non-plenum roof area to calculate the maximum skylight area to be applied to the building.
731
- def apply_max_srr_nrcan(model:, srr_lim:)
732
- # First determine which roof surfaces are adjacent to heated spaces (both plenum and non-plenum).
733
- exp_surf_info = find_exposed_conditioned_roof_surfaces(model)
734
- # If the non-plenum roof area is very small raise a warning. It may be perfectly fine but it is probably a good
735
- # idea to warn the user.
736
- if exp_surf_info['exp_nonplenum_roof_area_m2'] < 0.1
737
- OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'This building has no exposed ceilings adjacent to spaces that are not attics or plenums. No skylights will be added.')
738
- return false
739
- end
1406
+ # This method is similar to the 'apply_max_fdwr' method above, but applies a maximum skylight-to-roof-area-ratio (SRR)
1407
+ # to a building model, as per NECB 2011 8.4.4.3 and 3.2.1.4 (or equivalent in other NECB vintages). There are 2 options:
1408
+ #
1409
+ # OPTION A: Default, initial BTAP solution. It first checks for all exterior roofs adjacent to conditioned spaces.
1410
+ # It distinguishes between plenums and other conditioned spaces. It uses only the non-plenum roof area to
1411
+ # calculate the maximum skylight area to be applied to the building.
1412
+ #
1413
+ # OPTION B: Selected if srr_opt == 'osut'. OSut's 'addSkylights' attempts to meet the requested SRR% target, even if
1414
+ # occupied spaces to toplight are under unoccupied plenums or attics - skylight wells are added if needed.
1415
+ # With attics, skylight well walls are considered part of the 'building envelope' (and therefore insulated
1416
+ # like exterior walls). The method returns a building 'gross roof area' (see attr_reader :osut), which
1417
+ # excludes the area of attic roof overhangs.
1418
+ def apply_max_srr_nrcan(model:, srr_lim:, srr_opt: '')
1419
+ construct_set = model.getBuilding.defaultConstructionSet.get
1420
+ skylight_construct_set = construct_set.defaultExteriorSubSurfaceConstructions.get.skylightConstruction.get
740
1421
 
741
- # If the SRR is greater than one something is seriously wrong so raise an error. If it is less than 0.001 assume
742
- # all the skylights should go.
743
- if srr_lim > 1
744
- OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'This building requires a larger skylight area than there is roof area.')
745
- return false
746
- elsif srr_lim < 0.001
747
- exp_surf_info['exp_nonplenum_roofs'].sort.each do |exp_surf|
748
- exp_surf.subSurfaces.sort.each(&:remove)
1422
+ unless srr_opt.to_s.downcase == 'osut' # OPTION A
1423
+ # First determine which roof surfaces are adjacent to heated spaces (both plenum and non-plenum).
1424
+ exp_surf_info = find_exposed_conditioned_roof_surfaces(model)
1425
+ # If the non-plenum roof area is very small raise a warning. It may be perfectly fine but it is probably a good
1426
+ # idea to warn the user.
1427
+ if exp_surf_info['exp_nonplenum_roof_area_m2'] < 0.1
1428
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'This building has no exposed ceilings adjacent to spaces that are not attics or plenums. No skylights will be added.')
1429
+ return false
749
1430
  end
750
- return true
751
- end
752
1431
 
753
- construct_set = model.getBuilding.defaultConstructionSet.get
754
- skylight_construct_set = construct_set.defaultExteriorSubSurfaceConstructions.get.skylightConstruction.get
1432
+ # If the SRR is greater than one something is seriously wrong so raise an error. If it is less than 0.001 assume
1433
+ # all the skylights should go.
1434
+ if srr_lim > 1
1435
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'This building requires a larger skylight area than there is roof area.')
1436
+ return false
1437
+ elsif srr_lim < 0.001
1438
+ exp_surf_info['exp_nonplenum_roofs'].sort.each do |exp_surf|
1439
+ exp_surf.subSurfaces.sort.each(&:remove)
1440
+ end
1441
+ return true
1442
+ end
755
1443
 
756
- # Go through all of exposed roofs adjacent to heated, non-plenum spaces, remove any existing subsurfaces, and add
757
- # a skylight in the centroid of the surface, with the same shape of the surface, only scaled to be the area
758
- # determined by the SRR. The name of the skylight will be the surface name with the subsurface type attached
759
- # ('skylight' in this case). Note that this method will only work if the surface does not fold into itself (like an
760
- # L or a V).
761
- exp_surf_info['exp_nonplenum_roofs'].sort.each do |roof|
762
- # sub_surface_create_centered_subsurface_from_scaled_surface(roof, srr_lim, model)
763
- sub_surface_create_scaled_subsurfaces_from_surface(surface: roof, area_fraction: srr_lim, construction: skylight_construct_set)
1444
+ # Go through all of exposed roofs adjacent to heated, non-plenum spaces, remove any existing subsurfaces, and add
1445
+ # a skylight in the centroid of the surface, with the same shape of the surface, only scaled to be the area
1446
+ # determined by the SRR. The name of the skylight will be the surface name with the subsurface type attached
1447
+ # ('skylight' in this case). Note that this method will only work if the surface does not fold into itself (like an
1448
+ # L or a V).
1449
+ exp_surf_info['exp_nonplenum_roofs'].sort.each do |roof|
1450
+ # sub_surface_create_centered_subsurface_from_scaled_surface(roof, srr_lim, model)
1451
+ sub_surface_create_scaled_subsurfaces_from_surface(surface: roof, area_fraction: srr_lim, construction: skylight_construct_set)
1452
+ end
1453
+ else # OPTION B
1454
+ TBD.clean!
1455
+ spaces = model.getSpaces
1456
+ types = model.getSpaceTypes
1457
+ roofs = TBD.facets(spaces, "Outdoors", "RoofCeiling")
1458
+
1459
+ # A model's 'nominal' gross roof area (gra0) may be greater than its
1460
+ # 'effective' gross roof area (graX). For instance, the "SmallOffice"
1461
+ # prototype model has (unconditioned) attic roof overhangs that end up
1462
+ # tallied as a gross roof area in OpenStudio and EnergyPlus. See:
1463
+ #
1464
+ # github.com/rd2/osut/blob/117c7dceb59fd8aab771da8ba672c14c97d23bd0
1465
+ # /lib/osut/utils.rb#L6268
1466
+ #
1467
+ gra0 = roofs.sum(&:grossArea) # nominal gross roof area
1468
+ graX = TBD.grossRoofArea(spaces) # effective gross roof area
1469
+
1470
+ unless gra0.round > 0
1471
+ msg = 'Invalid nominal gross roof area. No skylights will be added.'
1472
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', msg)
1473
+ return false
1474
+ end
1475
+
1476
+ unless graX.round > 0
1477
+ msg = 'Invalid effective gross roof area. No skylights will be added.'
1478
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', msg)
1479
+ return false
1480
+ end
1481
+
1482
+ self.osut[:gra0] = gra0
1483
+ self.osut[:graX] = graX
1484
+
1485
+ # Relying on the total area of attic roof surfaces (for SRR%) exagerrates
1486
+ # the requested skylight area, often by 10% to 15%. This makes it unfair
1487
+ # for NECBs, and more challenging when dealing with skylight wells. This
1488
+ # issue only applies with attics - not plenums. Trim down SRR if required.
1489
+ target = srr_lim * graX
1490
+
1491
+ # Filtering out tiny roof surfaces, twisty corridors, etc.
1492
+ types = types.reject { |tp| tp.nameString.downcase.include?("undefined") }
1493
+ types = types.reject { |tp| tp.nameString.downcase.include?("mech" ) }
1494
+ types = types.reject { |tp| tp.nameString.downcase.include?("elec" ) }
1495
+ types = types.reject { |tp| tp.nameString.downcase.include?("toilet" ) }
1496
+ types = types.reject { |tp| tp.nameString.downcase.include?("locker" ) }
1497
+ types = types.reject { |tp| tp.nameString.downcase.include?("shower" ) }
1498
+ types = types.reject { |tp| tp.nameString.downcase.include?("washroom" ) }
1499
+ types = types.reject { |tp| tp.nameString.downcase.include?("corr" ) }
1500
+ types = types.reject { |tp| tp.nameString.downcase.include?("stair" ) }
1501
+
1502
+ spaces = spaces.reject { |sp| sp.spaceType.empty? }
1503
+ spaces = spaces.select { |sp| types.include?(sp.spaceType.get) }
1504
+
1505
+ TBD.addSkyLights(spaces, {area: target})
1506
+ self.osut[:logs] = TBD.logs
1507
+
1508
+ skys = TBD.facets(model.getSpaces, "Outdoors", "Skylight")
1509
+ skm2 = skys.sum(&:grossArea)
1510
+
1511
+ unless skm2.round == target.round
1512
+ msg = "Skylights m2: failed to meet #{target.round} (vs #{skm2.round})"
1513
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', msg)
1514
+ return false
1515
+ end
764
1516
  end
1517
+
765
1518
  return true
766
1519
  end
767
1520
  end