openstudio-standards 0.8.3 → 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 (330) 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/common_paths.rb +81 -0
  33. data/lib/openstudio-standards/btap/common_resources/ConstructionProperties.csv +52 -0
  34. data/lib/openstudio-standards/btap/common_resources/Constructions.csv +37 -0
  35. data/lib/openstudio-standards/btap/common_resources/carbon_frame.csv +35 -0
  36. data/lib/openstudio-standards/btap/common_resources/carbon_glazing.csv +35 -0
  37. data/lib/openstudio-standards/btap/common_resources/carbon_opaque.csv +164 -0
  38. data/lib/openstudio-standards/btap/common_resources/construction_sets.csv +1270 -0
  39. data/lib/openstudio-standards/btap/common_resources/constructions_glazing.csv +121 -0
  40. data/lib/openstudio-standards/btap/common_resources/constructions_opaque.csv +2256 -0
  41. data/lib/openstudio-standards/btap/common_resources/costs.csv +1897 -0
  42. data/lib/openstudio-standards/btap/common_resources/costs_local_factors.csv +2315 -0
  43. data/lib/openstudio-standards/btap/common_resources/hvac_vent_ahu.csv +925 -0
  44. data/lib/openstudio-standards/btap/common_resources/lighting.csv +364 -0
  45. data/lib/openstudio-standards/btap/common_resources/lighting_sets.csv +2667 -0
  46. data/lib/openstudio-standards/btap/common_resources/locations.csv +75 -0
  47. data/lib/openstudio-standards/btap/common_resources/materials_glazing.csv +35 -0
  48. data/lib/openstudio-standards/btap/common_resources/materials_hvac.csv +1686 -0
  49. data/lib/openstudio-standards/btap/common_resources/materials_lighting.csv +267 -0
  50. data/lib/openstudio-standards/btap/common_resources/materials_opaque.csv +164 -0
  51. data/lib/openstudio-standards/btap/costing/README.md +502 -0
  52. data/lib/openstudio-standards/btap/costing/btap_costing.rb +469 -0
  53. data/lib/openstudio-standards/btap/costing/btap_measure_helper.rb +359 -0
  54. data/lib/openstudio-standards/btap/costing/btap_workflow.rb +117 -0
  55. data/lib/openstudio-standards/btap/costing/copy_test_results_files_to_expected_results.rb +11 -0
  56. data/lib/openstudio-standards/btap/costing/cost_building_from_file.rb +136 -0
  57. data/lib/openstudio-standards/btap/costing/costing_database_wrapper.rb +173 -0
  58. data/lib/openstudio-standards/btap/costing/daylighting_sensor_control_costing.rb +354 -0
  59. data/lib/openstudio-standards/btap/costing/dcv_costing.rb +314 -0
  60. data/lib/openstudio-standards/btap/costing/dummy.epw +8768 -0
  61. data/lib/openstudio-standards/btap/costing/dummy.osm +5320 -0
  62. data/lib/openstudio-standards/btap/costing/envelope_costing.rb +215 -0
  63. data/lib/openstudio-standards/btap/costing/heating_cooling_costing.rb +2584 -0
  64. data/lib/openstudio-standards/btap/costing/led_lighting_costing.rb +156 -0
  65. data/lib/openstudio-standards/btap/costing/lighting_costing.rb +209 -0
  66. data/lib/openstudio-standards/btap/costing/mech_sizing.json +502 -0
  67. data/lib/openstudio-standards/btap/costing/neb_end_use_prices.csv +42 -0
  68. data/lib/openstudio-standards/btap/costing/necb_2011_spacetype_info.csv +225 -0
  69. data/lib/openstudio-standards/btap/costing/necb_reference_runs.csv +28705 -0
  70. data/lib/openstudio-standards/btap/costing/nv_costing.rb +547 -0
  71. data/lib/openstudio-standards/btap/costing/parallel_tests.rb +92 -0
  72. data/lib/openstudio-standards/btap/costing/pv_ground_costing.rb +687 -0
  73. data/lib/openstudio-standards/btap/costing/shw_costing.rb +705 -0
  74. data/lib/openstudio-standards/btap/costing/test_list.txt +15 -0
  75. data/lib/openstudio-standards/btap/costing/test_run_all_test_locally.rb +27 -0
  76. data/lib/openstudio-standards/btap/costing/test_run_costing_tests.rb +80 -0
  77. data/lib/openstudio-standards/btap/costing/ventilation_costing.rb +2616 -0
  78. data/lib/openstudio-standards/btap/geometry.rb +86 -6
  79. data/lib/openstudio-standards/btap/structure.rb +657 -0
  80. data/lib/openstudio-standards/constructions/modify.rb +2 -1
  81. data/lib/openstudio-standards/create_typical/create_typical.rb +17 -33
  82. data/lib/openstudio-standards/create_typical/space_type_ratios.rb +36 -36
  83. data/lib/openstudio-standards/equipment/create_transformer.rb +104 -0
  84. data/lib/openstudio-standards/equipment/create_typical_equipment.rb +117 -0
  85. data/lib/openstudio-standards/equipment/data/electric_equipment_space_types.json +1514 -0
  86. data/lib/openstudio-standards/equipment/data/gas_equipment_space_types.json +227 -0
  87. data/lib/openstudio-standards/exterior_lighting/create.rb +22 -22
  88. data/lib/openstudio-standards/exterior_lighting/information.rb +3 -2
  89. data/lib/openstudio-standards/hvac/components/air_conditioner_vrf.rb +482 -0
  90. data/lib/openstudio-standards/hvac/components/air_terminal.rb +31 -0
  91. data/lib/openstudio-standards/hvac/components/boiler_hot_water.rb +163 -0
  92. data/lib/openstudio-standards/hvac/components/central_air_source_heat_pump.rb +220 -0
  93. data/lib/openstudio-standards/hvac/components/chiller.rb +25 -0
  94. data/lib/openstudio-standards/hvac/components/coil.rb +276 -0
  95. data/lib/openstudio-standards/hvac/components/coil_cooling_dx_multi_speed.rb +40 -0
  96. data/lib/openstudio-standards/hvac/components/coil_cooling_dx_single_speed.rb +300 -0
  97. data/lib/openstudio-standards/hvac/components/coil_cooling_dx_two_speed.rb +187 -0
  98. data/lib/openstudio-standards/hvac/components/coil_cooling_water.rb +80 -0
  99. data/lib/openstudio-standards/hvac/components/coil_cooling_water_to_air_heat_pump_equation_fit.rb +182 -0
  100. data/lib/openstudio-standards/hvac/components/coil_heating_dx_single_speed.rb +220 -0
  101. data/lib/openstudio-standards/hvac/components/coil_heating_electric.rb +56 -0
  102. data/lib/openstudio-standards/hvac/components/coil_heating_gas.rb +90 -0
  103. data/lib/openstudio-standards/hvac/components/coil_heating_gas_multi_stage.rb +33 -0
  104. data/lib/openstudio-standards/hvac/components/coil_heating_water.rb +98 -0
  105. data/lib/openstudio-standards/hvac/components/coil_heating_water_to_air_heat_pump_equation_fit.rb +147 -0
  106. data/lib/openstudio-standards/hvac/components/component.rb +39 -0
  107. data/lib/openstudio-standards/{standards/ashrae_90_1/data/ashrae_90_1.fans.json → hvac/components/data/fans.json} +6 -6
  108. data/lib/openstudio-standards/hvac/components/fan.rb +363 -0
  109. data/lib/openstudio-standards/hvac/components/heat_exchanger_air_to_air.rb +203 -0
  110. data/lib/openstudio-standards/hvac/components/pump.rb +181 -0
  111. data/lib/openstudio-standards/hvac/controls/radiant_system_controls.rb +594 -0
  112. data/lib/openstudio-standards/hvac/conversions.rb +222 -0
  113. data/lib/openstudio-standards/hvac/curves.rb +192 -0
  114. data/lib/openstudio-standards/hvac/helpers.rb +357 -0
  115. data/lib/openstudio-standards/hvac/setpoint_managers/information.rb +4 -4
  116. data/lib/openstudio-standards/interior_lighting/create_lights.rb +52 -0
  117. data/lib/openstudio-standards/interior_lighting/create_typical_interior_lighting.rb +254 -0
  118. data/lib/openstudio-standards/interior_lighting/data/convert_lighting_data.rb +249 -0
  119. data/lib/openstudio-standards/interior_lighting/data/lighting_space_types.csv +96 -0
  120. data/lib/openstudio-standards/interior_lighting/data/lighting_space_types.json +1429 -0
  121. data/lib/openstudio-standards/interior_lighting/data/lighting_technology.csv +46 -0
  122. data/lib/openstudio-standards/interior_lighting/data/lighting_technology.json +859 -0
  123. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
  124. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
  125. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
  126. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +4 -4
  127. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
  128. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +4 -4
  129. data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
  130. data/lib/openstudio-standards/prototypes/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
  131. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.HighRiseApartment.rb +6 -7
  132. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Hospital.rb +15 -15
  133. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeHotel.rb +4 -4
  134. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOffice.rb +5 -5
  135. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOffice.rb +6 -6
  136. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb +7 -7
  137. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.PrimarySchool.rb +4 -4
  138. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SecondarySchool.rb +6 -6
  139. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOfficeDetailed.rb +5 -1
  140. data/lib/openstudio-standards/prototypes/common/data/prototype_space_type_map.json +2594 -0
  141. data/lib/openstudio-standards/prototypes/common/data/thermostat_schedule_lookup.json +2108 -0
  142. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirTerminalSingleDuctVAVReheat.rb +33 -0
  143. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Fan.rb +0 -140
  144. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanConstantVolume.rb +1 -73
  145. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanOnOff.rb +1 -69
  146. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanVariableVolume.rb +0 -116
  147. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanZoneExhaust.rb +0 -61
  148. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.hvac.rb +2 -2
  149. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +128 -13
  150. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +606 -607
  151. data/lib/openstudio-standards/prototypes/common/prototype_space_type_map.rb +41 -0
  152. data/lib/openstudio-standards/prototypes/common/space_type_equipment_map.rb +184 -0
  153. data/lib/openstudio-standards/prototypes/common/space_type_thermostat_schedule_map.rb +116 -0
  154. data/lib/openstudio-standards/qaqc/hvac.rb +12 -12
  155. data/lib/openstudio-standards/refrigeration/create_compressor.rb +2 -5
  156. data/lib/openstudio-standards/refrigeration/data/refrigeration_compressors.csv +4 -4
  157. data/lib/openstudio-standards/service_water_heating/create_water_heater.rb +1 -2
  158. data/lib/openstudio-standards/service_water_heating/create_water_use.rb +5 -5
  159. data/lib/openstudio-standards/space_type/data/level_1_space_types.json +612 -0
  160. data/lib/openstudio-standards/space_type/standards_space_type.rb +53 -0
  161. data/lib/openstudio-standards/standards/Standards.AirConditionerVariableRefrigerantFlow.rb +8 -26
  162. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +13 -13
  163. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctVAVReheat.rb +0 -24
  164. data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +6 -43
  165. data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +7 -24
  166. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXMultiSpeed.rb +19 -44
  167. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +25 -50
  168. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +25 -33
  169. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +9 -22
  170. data/lib/openstudio-standards/standards/Standards.CoilDX.rb +15 -157
  171. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +2 -2
  172. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +18 -105
  173. data/lib/openstudio-standards/standards/Standards.CoilHeatingGas.rb +3 -23
  174. data/lib/openstudio-standards/standards/Standards.CoilHeatingGasMultiStage.rb +0 -24
  175. data/lib/openstudio-standards/standards/Standards.CoilHeatingWaterToAirHeatPumpEquationFit.rb +2 -86
  176. data/lib/openstudio-standards/standards/Standards.FanVariableVolume.rb +0 -107
  177. data/lib/openstudio-standards/standards/Standards.Model.rb +45 -20
  178. data/lib/openstudio-standards/standards/Standards.People.rb +113 -0
  179. data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +11 -11
  180. data/lib/openstudio-standards/standards/Standards.Pump.rb +2 -147
  181. data/lib/openstudio-standards/standards/Standards.PumpVariableSpeed.rb +57 -41
  182. data/lib/openstudio-standards/standards/Standards.SpaceType.rb +30 -153
  183. data/lib/openstudio-standards/standards/Standards.Ventilation.rb +74 -0
  184. data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +1 -1
  185. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PlantLoop.rb +4 -4
  186. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_pumps_heating.json +3 -3
  187. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.spc_typ.json +37 -112
  188. 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
  189. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_pumps_heating.json +3 -3
  190. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.spc_typ.json +37 -112
  191. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
  192. 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
  193. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_pumps_heating.json +6 -6
  194. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.spc_typ.json +37 -37
  195. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
  196. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.BoilerHotWater.rb +1 -1
  197. 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
  198. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_pumps_heating.json +6 -6
  199. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.spc_typ.json +37 -37
  200. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
  201. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.BoilerHotWater.rb +1 -1
  202. 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
  203. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.heat_pumps_heating.json +6 -6
  204. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.spc_typ.json +37 -37
  205. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +1 -1
  206. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
  207. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.BoilerHotWater.rb +1 -1
  208. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoilHeatingGas.rb +1 -1
  209. 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
  210. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.heat_pumps_heating.json +6 -6
  211. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.spc_typ.json +37 -37
  212. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.curves.json +0 -200
  213. 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
  214. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.spc_typ.json +37 -37
  215. 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
  216. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.spc_typ.json +37 -37
  217. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
  218. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.PlantLoop.rb +5 -5
  219. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
  220. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.PlantLoop.rb +5 -5
  221. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +1 -1
  222. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ChillerElectricEIR.rb +2 -2
  223. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXSingleSpeed.rb +2 -68
  224. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXTwoSpeed.rb +2 -35
  225. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilDX.rb +42 -0
  226. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingDXSingleSpeed.rb +5 -2
  227. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingGas.rb +2 -2
  228. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +2 -2
  229. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +3 -3
  230. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.SpaceType.rb +1 -1
  231. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.Model.rb +1 -0
  232. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019_WaterHeaterMixed.rb +2 -4
  233. data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.curves.json +0 -200
  234. data/lib/openstudio-standards/standards/ashrae_90_1_prm/data/ashrae_90_1_prm.fans.json +5 -5
  235. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/ashrae_90_1_prm.UserData.rb +7 -1
  236. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_enums.rb +0 -1
  237. data/lib/openstudio-standards/standards/cbes/data/cbes.curves.json +0 -200
  238. data/lib/openstudio-standards/standards/deer/data/deer.curves.json +0 -200
  239. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/btap_pre1980.rb +21 -37
  240. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/building_envelope.rb +12 -11
  241. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_3_and_8_single_speed.rb +68 -27
  242. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_4.rb +64 -25
  243. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +9 -14
  244. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_systems.rb +4 -4
  245. data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +1 -1
  246. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +115 -112
  247. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +637 -249
  248. data/lib/openstudio-standards/standards/necb/NECB2011/beps_compliance_path.rb +16 -12
  249. data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +799 -46
  250. data/lib/openstudio-standards/standards/necb/NECB2011/data/chillers.json +33 -51
  251. data/lib/openstudio-standards/standards/necb/NECB2011/data/constants.json +75 -7
  252. data/lib/openstudio-standards/standards/necb/NECB2011/data/fuel_type_sets.json +25 -1
  253. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/HighriseApartmentMult.osm +14272 -0
  254. data/lib/openstudio-standards/standards/necb/NECB2011/data/heat_pumps_heating.json +21 -15
  255. data/lib/openstudio-standards/standards/necb/NECB2011/data/necb_2015_table_c1.json +1 -1
  256. data/lib/openstudio-standards/standards/necb/NECB2011/data/space_types.json +437 -437
  257. data/lib/openstudio-standards/standards/necb/NECB2011/data/systems.json +516 -0
  258. data/lib/openstudio-standards/standards/necb/NECB2011/data/systems_including_sys5.json +588 -0
  259. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_namer.rb +489 -0
  260. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_single_speed.rb +18 -6
  261. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_2_and_5.rb +48 -5
  262. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +2 -2
  263. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +35 -27
  264. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +34 -23
  265. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +8 -6
  266. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +68 -150
  267. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +444 -134
  268. data/lib/openstudio-standards/standards/necb/NECB2011/system_fuels.rb +61 -1
  269. data/lib/openstudio-standards/standards/necb/NECB2015/data/heat_pumps_heating.json +10 -2
  270. data/lib/openstudio-standards/standards/necb/NECB2015/data/space_types.json +636 -636
  271. data/lib/openstudio-standards/standards/necb/NECB2015/data/unitary_acs.json +38 -38
  272. data/lib/openstudio-standards/standards/necb/NECB2015/hvac_systems.rb +17 -8
  273. data/lib/openstudio-standards/standards/necb/NECB2017/data/space_types.json +636 -636
  274. data/lib/openstudio-standards/standards/necb/NECB2020/data/chillers.json +71 -71
  275. data/lib/openstudio-standards/standards/necb/NECB2020/data/heat_pumps_heating.json +16 -6
  276. data/lib/openstudio-standards/standards/necb/NECB2020/data/unitary_acs.json +60 -61
  277. data/lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb +30 -30
  278. data/lib/openstudio-standards/standards/necb/README.md +343 -0
  279. data/lib/openstudio-standards/standards/necb/common/btap_analysis.rb +79 -0
  280. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +206 -32
  281. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +75 -43
  282. data/lib/openstudio-standards/standards/necb/common/eccc_electric_grid_intensity_20250311.csv +14 -0
  283. data/lib/openstudio-standards/standards/necb/common/nir_gas_grid_intensity_20250311.csv +14 -0
  284. data/lib/openstudio-standards/standards/necb/common/system_types.yaml +0 -0
  285. data/lib/openstudio-standards/thermal_zone/{thermal_zone.rb → information.rb} +12 -45
  286. data/lib/openstudio-standards/thermal_zone/thermostat_schedules.rb +152 -0
  287. data/lib/openstudio-standards/utilities/logging.rb +18 -14
  288. data/lib/openstudio-standards/version.rb +1 -1
  289. data/lib/openstudio-standards/weather/modify.rb +2 -2
  290. data/lib/openstudio-standards/weather/stat_file.rb +2 -2
  291. data/lib/openstudio-standards.rb +67 -38
  292. metadata +141 -50
  293. data/lib/openstudio-standards/hvac/components/create.rb +0 -169
  294. data/lib/openstudio-standards/hvac/components/modify.rb +0 -42
  295. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirConditionerVariableRefrigerantFlow.rb +0 -438
  296. data/lib/openstudio-standards/prototypes/common/objects/Prototype.BoilerHotWater.rb +0 -123
  297. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CentralAirSourceHeatPump.rb +0 -216
  298. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXSingleSpeed.rb +0 -273
  299. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXTwoSpeed.rb +0 -159
  300. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWater.rb +0 -77
  301. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWaterToAirHeatPumpEquationFit.rb +0 -154
  302. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingDXSingleSpeed.rb +0 -214
  303. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingElectric.rb +0 -53
  304. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingGas.rb +0 -72
  305. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWater.rb +0 -95
  306. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWaterToAirHeatPumpEquationFit.rb +0 -125
  307. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ControllerWaterCoil.rb +0 -17
  308. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.transformers.rb +0 -90
  309. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Pump.rb +0 -4
  310. data/lib/openstudio-standards/prototypes/common/objects/Prototype.PumpVariableSpeed.rb +0 -70
  311. data/lib/openstudio-standards/prototypes/common/objects/Prototype.radiant_system_controls.rb +0 -590
  312. data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +0 -901
  313. data/lib/openstudio-standards/standards/Standards.FanConstantVolume.rb +0 -5
  314. data/lib/openstudio-standards/standards/Standards.FanOnOff.rb +0 -5
  315. data/lib/openstudio-standards/standards/Standards.FanZoneExhaust.rb +0 -5
  316. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsConstantSpeed.rb +0 -5
  317. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsVariableSpeed.rb +0 -55
  318. data/lib/openstudio-standards/standards/Standards.PumpConstantSpeed.rb +0 -5
  319. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanConstantVolume.rb +0 -5
  320. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanOnOff.rb +0 -5
  321. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanZoneExhaust.rb +0 -5
  322. data/lib/openstudio-standards/standards/cbes/data/cbes.fans.json +0 -328
  323. data/lib/openstudio-standards/standards/deer/data/deer.fans.json +0 -328
  324. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PumpVariableSpeed.rb +0 -0
  325. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.PumpVariableSpeed.rb +0 -0
  326. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.PumpVariableSpeed.rb +0 -0
  327. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.PumpVariableSpeed.rb +0 -0
  328. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.PumpVariableSpeed.rb +0 -0
  329. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Pump.rb +0 -0
  330. /data/lib/openstudio-standards/{prototypes → standards}/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.PumpVariableSpeed.rb +0 -0
@@ -6,37 +6,52 @@ class NECB2011 < Standard
6
6
 
7
7
  @template = new.class.name
8
8
  register_standard(@template)
9
- attr_reader :tbd
10
9
  attr_reader :template
10
+ attr_reader :tbd
11
+ attr_reader :osut
12
+ attr_reader :activity
13
+ attr_reader :structure
11
14
  attr_accessor :standards_data
12
15
  attr_accessor :space_type_map
13
16
  attr_accessor :space_multiplier_map
14
17
  attr_accessor :fuel_type_set
15
18
 
16
- # This is a helper method to convert arguments that may support 'NECB_Default, and nils to convert to float'
19
+ # This is a helper method to convert arguments to float.
20
+ # If variable undefined set to the default
21
+ # If already a numeric then return it
22
+ # If variable is a string then convert to a float, using the default if 'NECB_Default'
23
+ # If that all fails then return the default.
17
24
  def convert_arg_to_f(variable:, default:)
25
+ return default if variable.nil?
18
26
  return variable if variable.kind_of?(Numeric)
19
- return default if variable.nil? || (variable.to_s == 'NECB_Default')
20
- return unless variable.kind_of?(String)
21
-
22
- variable = variable.strip
23
- return variable.to_f
27
+ if variable.is_a? String
28
+ return default if variable.to_s.downcase == 'necb_default'
29
+ variable = variable.strip
30
+ return variable.to_f
31
+ end
32
+ return default
24
33
  end
25
34
 
26
- # This method converts arguments to bool. Anything other than a bool false or string 'false' is converted
27
- # to a bool true. Bool false and case insesitive string false are turned into bool false.
35
+ # This method converts arguments to bool.
36
+ # If variable undefined set to the default
37
+ # If already a bool then return it
38
+ # If variable is a string then convert to a bool, using the default if 'NECB_Default'
39
+ # If that all fails then return the default.
28
40
  def convert_arg_to_bool(variable:, default:)
29
41
  return default if variable.nil?
42
+ return variable if variable.is_a?(TrueClass) || variable.is_a?(FalseClass)
30
43
  if variable.is_a? String
44
+ return default if variable.to_s.downcase == 'necb_default'
45
+ return false if variable.to_s.downcase == 'false'
31
46
  return true if variable.to_s.downcase == 'true'
32
- return false
33
47
  end
34
- return true if variable == true
35
48
  return default
36
49
  end
37
50
 
38
- # This method checks if a variable is a string. If it is anything but a string it returns the default. If it is a
39
- # string set to "NECB_Default" it return the default. Otherwise it returns the strirng set to it.
51
+ # This method checks if a variable is a string.
52
+ # If variable undefined set to the default
53
+ # If variable is a string then return it, using the default if 'NECB_Default'
54
+ # If that all fails then return the default.
40
55
  def convert_arg_to_string(variable:, default:)
41
56
  return default if variable.nil?
42
57
  if variable.is_a? String
@@ -148,6 +163,10 @@ class NECB2011 < Standard
148
163
  @standards_data = load_standards_database_new
149
164
  corrupt_standards_database
150
165
  @tbd = nil
166
+ @activity = nil
167
+ @structure = nil
168
+ @osut = {gra0: 0, graX: 0, status: 0, logs: []} # "gra": "gross roof area"
169
+
151
170
  # puts "loaded these tables..."
152
171
  # puts @standards_data.keys.size
153
172
  # raise("tables not all loaded in parent #{}") if @standards_data.keys.size < 24
@@ -179,6 +198,22 @@ class NECB2011 < Standard
179
198
  min_distance = 100000000000000.0
180
199
  necb_closest = nil
181
200
  weather_file_path = model.weatherFile.get.path.get.to_s
201
+
202
+ # Check if weather file exists at the specified path
203
+ unless File.exist?(weather_file_path)
204
+ # Try to find the file in the data/weather folder
205
+ weather_file_name = File.basename(weather_file_path)
206
+ data_weather_path = File.absolute_path(File.join(__FILE__, '..', '..', '..', '..', '..', '..', 'data', 'weather', weather_file_name))
207
+
208
+ if File.exist?(data_weather_path)
209
+ weather_file_path = data_weather_path
210
+ # Update the model's weather file path to point to the found file
211
+ OpenstudioStandards::Weather.model_set_building_location(model, weather_file_path: weather_file_path)
212
+ else
213
+ raise "Weather file not found at #{weather_file_path} or #{data_weather_path}"
214
+ end
215
+ end
216
+
182
217
  epw_file = model.weatherFile.get.file.get
183
218
  stat_file_path = weather_file_path.gsub('.epw', '.stat')
184
219
  stat_file = OpenstudioStandards::Weather::StatFile.new(stat_file_path)
@@ -210,10 +245,16 @@ class NECB2011 < Standard
210
245
  # This method is a wrapper to create the 16 archetypes easily. # 55 args
211
246
  def model_create_prototype_model(template:,
212
247
  building_type:,
248
+ construction_opt: '',
213
249
  epw_file:,
214
250
  custom_weather_folder: nil,
215
251
  debug: false,
216
252
  sizing_run_dir: Dir.pwd,
253
+ hvac_system_primary: nil,
254
+ hvac_system_dwelling_units: nil,
255
+ hvac_system_washrooms: nil,
256
+ hvac_system_corridor: nil,
257
+ hvac_system_storage: nil,
217
258
  primary_heating_fuel: 'Electricity',
218
259
  swh_fuel: nil,
219
260
  dcv_type: 'NECB_Default',
@@ -244,6 +285,7 @@ class NECB2011 < Standard
244
285
  rotation_degrees: nil,
245
286
  fdwr_set: -1.0,
246
287
  srr_set: -1.0,
288
+ srr_opt: '',
247
289
  nv_type: nil,
248
290
  nv_opening_fraction: nil,
249
291
  nv_temp_out_min: nil,
@@ -266,19 +308,26 @@ class NECB2011 < Standard
266
308
  output_meters: nil,
267
309
  airloop_economizer_type: nil,
268
310
  baseline_system_zones_map_option: nil,
269
- tbd_option: nil,
270
- tbd_interpolate: false,
311
+ tbd_option: 'none',
312
+ tbd_interpolate: true,
271
313
  necb_hdd: true,
272
314
  boiler_fuel: nil,
273
315
  boiler_cap_ratio: nil,
316
+ airloop_fancoils_heating: nil,
274
317
  oerd_utility_pricing: nil)
275
318
  model = load_building_type_from_library(building_type: building_type)
276
319
  return model_apply_standard(model: model,
320
+ construction_opt: construction_opt,
277
321
  tbd_option: tbd_option,
278
322
  tbd_interpolate: tbd_interpolate,
279
323
  epw_file: epw_file,
280
324
  custom_weather_folder: custom_weather_folder,
281
325
  sizing_run_dir: sizing_run_dir,
326
+ hvac_system_primary: nil,
327
+ hvac_system_dwelling_units: nil,
328
+ hvac_system_washrooms: nil,
329
+ hvac_system_corridor: nil,
330
+ hvac_system_storage: nil,
282
331
  primary_heating_fuel: primary_heating_fuel,
283
332
  swh_fuel: swh_fuel,
284
333
  dcv_type: dcv_type, # Four options: (1) 'NECB_Default', (2) 'No_DCV', (3) 'Occupancy_based_DCV' , (4) 'CO2_based_DCV'
@@ -309,6 +358,7 @@ class NECB2011 < Standard
309
358
  rotation_degrees: rotation_degrees,
310
359
  fdwr_set: fdwr_set,
311
360
  srr_set: srr_set,
361
+ srr_opt: srr_opt,
312
362
  nv_type: nv_type, # Two options: (1) nil/none/false/'NECB_Default', (2) 'add_nv'
313
363
  nv_opening_fraction: nv_opening_fraction, # options: (1) nil/none/false (2) 'NECB_Default' (i.e. 0.1), (3) opening fraction of windows, which can be a float number between 0.0 and 1.0
314
364
  nv_temp_out_min: nv_temp_out_min, # options: (1) nil/none/false(2) 'NECB_Default' (i.e. 13.0 based on inputs from Michel Tardif re a real school in QC), (3) minimum outdoor air temperature (in Celsius) below which natural ventilation is shut down
@@ -334,6 +384,7 @@ class NECB2011 < Standard
334
384
  necb_hdd: necb_hdd,
335
385
  boiler_fuel: boiler_fuel,
336
386
  boiler_cap_ratio: boiler_cap_ratio,
387
+ airloop_fancoils_heating: airloop_fancoils_heating,
337
388
  oerd_utility_pricing: oerd_utility_pricing
338
389
  )
339
390
  end
@@ -351,13 +402,20 @@ class NECB2011 < Standard
351
402
  # Created this method so that additional methods can be addded for bulding the prototype model in later
352
403
  # code versions without modifying the build_protoype_model method or copying it wholesale for a few changes.
353
404
  def model_apply_standard(model:,
354
- tbd_option: nil,
355
- tbd_interpolate: nil,
405
+ construction_opt: '',
406
+ tbd_option: 'none',
407
+ tbd_interpolate: true,
356
408
  epw_file:,
357
409
  custom_weather_folder: nil,
410
+ btap_weather: true,
358
411
  sizing_run_dir: Dir.pwd,
359
412
  necb_reference_hp: false,
360
413
  necb_reference_hp_supp_fuel: 'DefaultFuel',
414
+ hvac_system_primary: 'NECB_Default',
415
+ hvac_system_dwelling_units: 'NECB_Default',
416
+ hvac_system_washrooms: 'NECB_Default',
417
+ hvac_system_corridor: 'NECB_Default',
418
+ hvac_system_storage: 'NECB_Default',
361
419
  primary_heating_fuel: 'Electricity',
362
420
  swh_fuel: nil,
363
421
  dcv_type: 'NECB_Default',
@@ -387,6 +445,7 @@ class NECB2011 < Standard
387
445
  skylight_solar_trans: nil,
388
446
  fdwr_set: nil,
389
447
  srr_set: nil,
448
+ srr_opt: '',
390
449
  rotation_degrees: nil,
391
450
  scale_x: nil,
392
451
  scale_y: nil,
@@ -413,24 +472,43 @@ class NECB2011 < Standard
413
472
  necb_hdd: true,
414
473
  boiler_fuel: nil,
415
474
  boiler_cap_ratio: nil,
475
+ airloop_fancoils_heating: nil,
416
476
  oerd_utility_pricing: nil)
417
477
 
418
- apply_weather_data(model: model, epw_file: epw_file, custom_weather_folder: custom_weather_folder)
478
+ apply_weather_data(model: model,
479
+ epw_file: epw_file,
480
+ custom_weather_folder: custom_weather_folder,
481
+ btap_weather: btap_weather)
419
482
  primary_heating_fuel = validate_primary_heating_fuel(primary_heating_fuel: primary_heating_fuel, model: model)
420
483
  self.fuel_type_set = SystemFuels.new()
421
484
  self.fuel_type_set.set_defaults(standards_data: @standards_data, primary_heating_fuel: primary_heating_fuel)
422
485
  clean_and_scale_model(model: model, rotation_degrees: rotation_degrees, scale_x: scale_x, scale_y: scale_y, scale_z: scale_z)
423
486
  fdwr_set = convert_arg_to_f(variable: fdwr_set, default: -1)
424
487
  srr_set = convert_arg_to_f(variable: srr_set, default: -1)
488
+ srr_opt = convert_arg_to_string(variable: srr_opt, default: '')
489
+ construction_opt = convert_arg_to_string(variable: construction_opt, default: '')
490
+ massive = construction_opt == 'structure'
491
+ tbd_option = convert_arg_to_string(variable: tbd_option, default: 'none')
492
+ tbd_interpolate = convert_arg_to_bool(variable: tbd_interpolate, default: true)
425
493
  necb_hdd = convert_arg_to_bool(variable: necb_hdd, default: true)
426
494
  boiler_fuel = convert_arg_to_string(variable: boiler_fuel, default: nil)
427
495
  boiler_cap_ratio = convert_arg_to_string(variable: boiler_cap_ratio, default: nil)
428
496
  swh_fuel = convert_arg_to_string(variable: swh_fuel, default: nil)
497
+ airloop_fancoils_heating = convert_arg_to_bool(variable: airloop_fancoils_heating, default: false)
498
+
499
+ # Check if custom systems are assigned to dwelling units, washrooms, corridors, and storage rooms. If they are, set
500
+ # them to be the same as the primary system type. If no primary system type is defined then set them to be nil.
501
+ hvac_system_dwelling_units, hvac_system_corridor, hvac_system_storage, hvac_system_washrooms = reset_hvac_system_if_required(hvac_system_primary: hvac_system_primary,
502
+ hvac_system_dwelling_units: hvac_system_dwelling_units,
503
+ hvac_system_corridor: hvac_system_corridor,
504
+ hvac_system_storage: hvac_system_storage,
505
+ hvac_system_washrooms: hvac_system_washrooms)
429
506
  oerd_utility_pricing = convert_arg_to_bool(variable: oerd_utility_pricing, default: false)
430
507
 
431
508
  boiler_cap_ratios = set_boiler_cap_ratios(boiler_cap_ratio: boiler_cap_ratio, boiler_fuel: boiler_fuel) unless boiler_cap_ratio.nil? && boiler_fuel.nil?
432
509
  self.fuel_type_set.set_boiler_fuel(standards_data: @standards_data, boiler_fuel: boiler_fuel, boiler_cap_ratios: boiler_cap_ratios) unless boiler_fuel.nil?
433
510
  self.fuel_type_set.set_swh_fuel(swh_fuel: swh_fuel) unless swh_fuel.nil? || swh_fuel.to_s.downcase == 'defaultfuel'
511
+ self.fuel_type_set.set_airloop_fancoils_heating() if airloop_fancoils_heating
434
512
 
435
513
  # Ensure the volume calculation in all spaces is done automatically
436
514
  model.getSpaces.sort.each do |space|
@@ -439,6 +517,8 @@ class NECB2011 < Standard
439
517
 
440
518
  output_meters = check_output_meters(output_meters: output_meters) if oerd_utility_pricing
441
519
 
520
+ assign_building_activity(model: model)
521
+ assign_building_structure(model: model, activity: @activity, massive: massive)
442
522
  apply_loads(model: model,
443
523
  lights_type: lights_type,
444
524
  lights_scale: lights_scale,
@@ -446,6 +526,9 @@ class NECB2011 < Standard
446
526
  electrical_loads_scale: electrical_loads_scale,
447
527
  oa_scale: oa_scale)
448
528
  apply_envelope(model: model,
529
+ construction_opt: construction_opt,
530
+ bldg_category: @activity.category,
531
+ bldg_structure: @structure.structure,
449
532
  ext_wall_cond: ext_wall_cond,
450
533
  ext_floor_cond: ext_floor_cond,
451
534
  ext_roof_cond: ext_roof_cond,
@@ -465,20 +548,28 @@ class NECB2011 < Standard
465
548
  apply_fdwr_srr_daylighting(model: model,
466
549
  fdwr_set: fdwr_set,
467
550
  srr_set: srr_set,
551
+ srr_opt: srr_opt,
468
552
  necb_hdd: necb_hdd)
469
553
  apply_thermal_bridging(model: model,
470
- tbd_option: tbd_option,
471
- tbd_interpolate: tbd_interpolate,
472
- wall_U: ext_wall_cond,
473
- floor_U: ext_floor_cond,
474
- roof_U: ext_roof_cond)
554
+ necb_hdd: necb_hdd,
555
+ structure: @structure,
556
+ option: tbd_option,
557
+ interpolate: tbd_interpolate,
558
+ wallU: ext_wall_cond,
559
+ floorU: ext_floor_cond,
560
+ roofU: ext_roof_cond)
475
561
  apply_auto_zoning(model: model,
476
562
  sizing_run_dir: sizing_run_dir,
477
563
  lights_type: lights_type,
478
564
  lights_scale: lights_scale)
479
- apply_kiva_foundation(model)
565
+ apply_kiva_foundation(model, massive)
480
566
  apply_systems_and_efficiencies(model: model,
481
567
  sizing_run_dir: sizing_run_dir,
568
+ hvac_system_primary: hvac_system_primary,
569
+ hvac_system_dwelling_units: hvac_system_dwelling_units,
570
+ hvac_system_washrooms: hvac_system_washrooms,
571
+ hvac_system_corridor: hvac_system_corridor,
572
+ hvac_system_storage: hvac_system_storage,
482
573
  primary_heating_fuel: primary_heating_fuel,
483
574
  dcv_type: dcv_type,
484
575
  ecm_system_name: ecm_system_name,
@@ -512,7 +603,7 @@ class NECB2011 < Standard
512
603
  def clean_and_scale_model(model:, rotation_degrees: nil, scale_x: nil, scale_y: nil, scale_z: nil)
513
604
  # clean model..
514
605
  BTAP::Resources::Envelope::remove_all_envelope_information(model)
515
- model = remove_all_hvac(model)
606
+ model = OpenstudioStandards::HVAC.remove_all_hvac(model)
516
607
  model.getThermalZones.sort.each { |zone| zone.setUseIdealAirLoads(true) }
517
608
  model.getZoneHVACPackagedTerminalAirConditioners.each(&:remove)
518
609
  model.getCoilCoolingDXSingleSpeeds.each(&:remove)
@@ -551,6 +642,11 @@ class NECB2011 < Standard
551
642
 
552
643
  def apply_systems_and_efficiencies(model:,
553
644
  sizing_run_dir:,
645
+ hvac_system_primary: 'NECB_Default',
646
+ hvac_system_dwelling_units: 'NECB_Default',
647
+ hvac_system_washrooms: 'NECB_Default',
648
+ hvac_system_corridor: 'NECB_Default',
649
+ hvac_system_storage: 'NECB_Default',
554
650
  primary_heating_fuel:,
555
651
  dcv_type: 'NECB_Default',
556
652
  ecm_system_name: 'NECB_Default',
@@ -582,6 +678,11 @@ class NECB2011 < Standard
582
678
 
583
679
  # Create Default Systems.
584
680
  apply_systems(model: model,
681
+ hvac_system_primary: hvac_system_primary,
682
+ hvac_system_dwelling_units: hvac_system_dwelling_units,
683
+ hvac_system_washrooms: hvac_system_washrooms,
684
+ hvac_system_corridor: hvac_system_corridor,
685
+ hvac_system_storage: hvac_system_storage,
585
686
  sizing_run_dir: sizing_run_dir,
586
687
  shw_scale: shw_scale,
587
688
  baseline_system_zones_map_option: baseline_system_zones_map_option)
@@ -620,9 +721,9 @@ class NECB2011 < Standard
620
721
  ecm.add_airloop_economizer(model: model, airloop_economizer_type: airloop_economizer_type)
621
722
  # Perform a second sizing run if needed
622
723
  if (!unitary_cop.nil? && unitary_cop != 'NECB_Default') || !model.getPlantLoops.empty?
623
- if model_run_sizing_run(model, "#{sizing_run_dir}/SR2", true) == false
624
- raise('sizing run 2 failed!')
625
- end
724
+ # Do a sizing run
725
+ try_sizing_run(model: model, sizing_run_dir: sizing_run_dir, sizing_run_subdir: 'SR2')
726
+ #end
626
727
  end
627
728
  # apply unitary cop
628
729
  ecm.modify_unitary_cop(model: model, unitary_cop: unitary_cop, sizing_done: true, sql_db_vars_map: sql_db_vars_map)
@@ -661,9 +762,8 @@ class NECB2011 < Standard
661
762
  end
662
763
 
663
764
  # Rename air loop and plant loop nodes to accommodate coming OpenStudio version
664
- rename_air_loop_nodes(model)
665
- rename_plant_loop_nodes(model)
666
-
765
+ OpenstudioStandards::HVAC.rename_air_loop_nodes(model)
766
+ OpenstudioStandards::HVAC.rename_plant_loop_nodes(model)
667
767
  end
668
768
 
669
769
  def apply_loads(model:,
@@ -689,7 +789,7 @@ class NECB2011 < Standard
689
789
  ecm.scale_oa_loads(model: model, scale: oa_scale)
690
790
  end
691
791
 
692
- def apply_weather_data(model:, epw_file:, custom_weather_folder: nil)
792
+ def apply_weather_data(model:, epw_file:, custom_weather_folder: nil, btap_weather: true)
693
793
  # Create full path to weather file
694
794
  weather_files = File.absolute_path(File.join(__FILE__, '..', '..', '..', '..', '..' , '..', "data/weather"))
695
795
  weather_file = File.join(weather_files, epw_file)
@@ -699,7 +799,7 @@ class NECB2011 < Standard
699
799
  # Check if btap_batch transferred the weather file
700
800
  weather_transfer = check_datapoint_weather_folder(epw_file: epw_file, weather_folder: weather_files, custom_weather_folder: custom_weather_folder)
701
801
  # If btap_batch didn't transfer the weather file, download it.
702
- get_weather_file_from_repo(epw_file: epw_file) unless weather_transfer
802
+ get_weather_file_from_repo(epw_file: epw_file, btap_weather: btap_weather) unless weather_transfer
703
803
  end
704
804
 
705
805
  # Fix EMS references. Temporary workaround for OS issue #2598
@@ -711,6 +811,9 @@ class NECB2011 < Standard
711
811
  end
712
812
 
713
813
  def apply_envelope(model:,
814
+ construction_opt: '',
815
+ bldg_category: '',
816
+ bldg_structure: '',
714
817
  ext_wall_cond: nil,
715
818
  ext_floor_cond: nil,
716
819
  ext_roof_cond: nil,
@@ -734,29 +837,61 @@ class NECB2011 < Standard
734
837
  ecm.scale_infiltration_loads(model: model, scale: infiltration_scale)
735
838
  model.getInsideSurfaceConvectionAlgorithm.setAlgorithm('TARP')
736
839
  model.getOutsideSurfaceConvectionAlgorithm.setAlgorithm('TARP')
737
- model_add_constructions(model)
738
- apply_standard_construction_properties(model: model,
739
- ext_wall_cond: ext_wall_cond,
740
- ext_floor_cond: ext_floor_cond,
741
- ext_roof_cond: ext_roof_cond,
742
- ground_wall_cond: ground_wall_cond,
743
- ground_floor_cond: ground_floor_cond,
744
- ground_roof_cond: ground_roof_cond,
745
- door_construction_cond: door_construction_cond,
746
- fixed_window_cond: fixed_window_cond,
747
- glass_door_cond: glass_door_cond,
748
- overhead_door_cond: overhead_door_cond,
749
- skylight_cond: skylight_cond,
750
- glass_door_solar_trans: glass_door_solar_trans,
751
- fixed_wind_solar_trans: fixed_wind_solar_trans,
752
- skylight_solar_trans: skylight_solar_trans,
753
- necb_hdd: necb_hdd)
840
+
841
+ construction_opt = '' unless construction_opt.respond_to?(:to_sym)
842
+ bldg_structure = '' unless bldg_structure.respond_to?(:to_sym)
843
+ construction_opt = construction_opt.to_s.downcase
844
+ bldg_structure = bldg_structure.to_s.downcase.to_sym
845
+ bldg_structures = @structure.data[:structure].keys
846
+
847
+ if construction_opt == 'structure' && bldg_structures.include?(bldg_structure)
848
+ argh = {}
849
+ argh[:eWallU ] = ext_wall_cond if ext_wall_cond
850
+ argh[:eFloorU ] = ext_floor_cond if ext_floor_cond
851
+ argh[:eRoofU ] = ext_roof_cond if ext_roof_cond
852
+ argh[:gWallU ] = ground_wall_cond if ground_wall_cond
853
+ argh[:gFloorU ] = ground_floor_cond if ground_floor_cond
854
+ argh[:gRoofU ] = ground_roof_cond if ground_roof_cond
855
+ argh[:doorU ] = door_construction_cond if door_construction_cond
856
+ argh[:fenU ] = fixed_window_cond if fixed_window_cond
857
+ argh[:skyU ] = skylight_solar_trans if skylight_solar_trans
858
+ argh[:doorSHGC] = glass_door_solar_trans if glass_door_solar_trans
859
+ argh[:fenSHGC ] = fixed_wind_solar_trans if fixed_wind_solar_trans
860
+ argh[:skySHGC ] = skylight_solar_trans if skylight_solar_trans
861
+
862
+ assign_contruction_to_adiabatic_surfaces(model)
863
+ ok = add_construction_sets(model, necb_hdd, argh)
864
+
865
+ raise('NECB2011: Failed to assign default construction sets') unless ok
866
+ else
867
+ model_add_constructions(model)
868
+ apply_standard_construction_properties(model: model,
869
+ ext_wall_cond: ext_wall_cond,
870
+ ext_floor_cond: ext_floor_cond,
871
+ ext_roof_cond: ext_roof_cond,
872
+ ground_wall_cond: ground_wall_cond,
873
+ ground_floor_cond: ground_floor_cond,
874
+ ground_roof_cond: ground_roof_cond,
875
+ door_construction_cond: door_construction_cond,
876
+ fixed_window_cond: fixed_window_cond,
877
+ glass_door_cond: glass_door_cond,
878
+ overhead_door_cond: overhead_door_cond,
879
+ skylight_cond: skylight_cond,
880
+ glass_door_solar_trans: glass_door_solar_trans,
881
+ fixed_wind_solar_trans: fixed_wind_solar_trans,
882
+ skylight_solar_trans: skylight_solar_trans,
883
+ necb_hdd: necb_hdd)
884
+ end
885
+
754
886
  model_create_thermal_zones(model, @space_multiplier_map)
755
887
  end
756
888
 
757
- # apply the Kiva foundation model to floors and walls with ground boundary condition
889
+ # Apply Kiva foundation model to floors/walls with ground boundary condition.
758
890
  # created by: Kamel Haddad (kamel.haddad@nrcan-rncan.gc.ca)
759
- def apply_kiva_foundation(model)
891
+ # 'massive' edit: denis@rd2.ca
892
+ #
893
+ # @param massive [Boolean] whether opaque materials are standard (not massless)
894
+ def apply_kiva_foundation(model, massive = false)
760
895
  # define a Kiva model for the whole bldg that's used for the first floor in contact with ground in each zone
761
896
  bldg_kiva_model = OpenStudio::Model::FoundationKiva.new(model)
762
897
  bldg_kiva_model.setName("Bldg Kiva Foundation")
@@ -784,10 +919,21 @@ class NECB2011 < Standard
784
919
  kiva_model.setWallDepthBelowSlab(0.0)
785
920
  zone_kiva_models << kiva_model
786
921
  end
787
- # Kiva model only works with standard materials. Replace constructions massless materials with standard ones.
788
- replace_massless_material_with_std_material(model,gfloor)
789
- gfloor.setOutsideBoundaryCondition('Foundation')
790
- gfloor.setAdjacentFoundation(zone_kiva_models.last)
922
+ # Kiva model only works with standard materials. Replace constructions
923
+ # massless materials with standard ones.
924
+ # Kiva model only works with standard materials. Replace constructions
925
+ # massless materials with standard ones. Skip check if 'massive'.
926
+ if massive
927
+ c = gfloor.construction.get.to_LayeredConstruction.get
928
+ gfloor.setOutsideBoundaryCondition('Foundation')
929
+ gfloor.setAdjacentFoundation(zone_kiva_models.last)
930
+ gfloor.setConstruction(c)
931
+ else
932
+ replace_massless_material_with_std_material(model,gfloor)
933
+ gfloor.setOutsideBoundaryCondition('Foundation')
934
+ gfloor.setAdjacentFoundation(zone_kiva_models.last)
935
+ end
936
+
791
937
  # Set the exposed perimeter for space floors in contact with the ground.
792
938
  floor_exp_per = 0.0
793
939
  if !space_ground_walls.empty?
@@ -800,9 +946,16 @@ class NECB2011 < Standard
800
946
  # contact with the space floor in contact with ground 'gfloor'
801
947
  space_ground_walls.each do |gwall|
802
948
  if surfaces_are_in_contact?(gfloor,gwall)
803
- replace_massless_material_with_std_material(model,gwall)
804
- gwall.setOutsideBoundaryCondition('Foundation')
805
- gwall.setAdjacentFoundation(zone_kiva_models.last)
949
+ if massive
950
+ c = gwall.construction.get.to_LayeredConstruction.get
951
+ gwall.setOutsideBoundaryCondition('Foundation')
952
+ gwall.setAdjacentFoundation(zone_kiva_models.last)
953
+ gwall.setConstruction(c)
954
+ else
955
+ replace_massless_material_with_std_material(model,gwall)
956
+ gwall.setOutsideBoundaryCondition('Foundation')
957
+ gwall.setAdjacentFoundation(zone_kiva_models.last)
958
+ end
806
959
  end
807
960
  end
808
961
  end
@@ -973,84 +1126,99 @@ class NECB2011 < Standard
973
1126
  end
974
1127
 
975
1128
  # Thermal zones need to be set to determine conditioned spaces when applying fdwr and srr limits.
976
- # # fdwr_set/srr_set settings:
977
- # # 0-1: Remove all windows/skylights and add windows/skylights to match this fdwr/srr
978
- # # -1: Remove all windows/skylights and add windows/skylights to match max fdwr/srr from NECB
979
- # # -2: Do not apply any fdwr/srr changes, leave windows/skylights alone (also works for fdwr/srr > 1)
980
- # # -3: Use old method which reduces existing window/skylight size (if necessary) to meet maximum NECB fdwr/srr
981
- # # limit
982
- # # <-3.1: Remove all the windows/skylights
983
- # # > 1: Do nothing
984
- def apply_fdwr_srr_daylighting(model:, fdwr_set: -1.0, srr_set: -1.0, necb_hdd: true)
1129
+ #
1130
+ # fdwr_set/srr_set settings:
1131
+ # 0-1: Remove all windows/skylights and add windows/skylights to match this fdwr/srr
1132
+ # -1: Remove all windows/skylights and add windows/skylights to match max fdwr/srr from NECB
1133
+ # -2: Do not apply any fdwr/srr changes, leave windows/skylights alone (also works for fdwr/srr > 1)
1134
+ # -3: Use old method which reduces existing window/skylight size (if necessary) to meet maximum NECB fdwr/srr limit
1135
+ # <-3.1: Remove all the windows/skylights
1136
+ # > 1: Do nothing
1137
+ #
1138
+ # By default, :srr_opt is an empty string (" "). If set to "osut", SRR is
1139
+ # instead met using OSut's 'addSkylights' (:srr_set numeric values may apply).
1140
+ def apply_fdwr_srr_daylighting(model:, fdwr_set: -1.0, srr_set: -1.0, necb_hdd: true, srr_opt: '')
985
1141
  fdwr_set = -1.0 if (fdwr_set == 'NECB_default') || fdwr_set.nil?
986
1142
  srr_set = -1.0 if (srr_set == 'NECB_default') || srr_set.nil?
987
1143
  fdwr_set = fdwr_set.to_f
988
1144
  srr_set = srr_set.to_f
989
1145
  apply_standard_window_to_wall_ratio(model: model, fdwr_set: fdwr_set, necb_hdd: necb_hdd)
990
- apply_standard_skylight_to_roof_ratio(model: model, srr_set: srr_set)
1146
+ apply_standard_skylight_to_roof_ratio(model: model, srr_set: srr_set, srr_opt: srr_opt)
991
1147
  # model_add_daylighting_controls(model) # to be removed after refactor.
992
1148
  end
993
1149
 
994
- ##
995
- # Optionally uprates, then derates, envelope surfaces due to MAJOR thermal
996
- # bridges (e.g. roof parapets, corners, fenestration perimeters). See
997
- # lib/openstudio-standards/btap/bridging.rb, which relies on the Thermal
998
- # Bridging & Derating (TBD) gem.
1150
+ # Initiates a BTAP building ACTIVITY.
999
1151
  #
1000
- # @param model [OpenStudio::Model::Model] an OpenStudio model
1001
- # @param tbd_option [String] BTAP/TBD option
1152
+ # @param model [OpenStudio::Model::Model] a model
1002
1153
  #
1003
- # @return [Boolean] true if successful, e.g. no errors, compliant if uprated
1154
+ # @return [BTAP::Activity] a BTAP building ACTIVITY (see logs if failed)
1155
+ def assign_building_activity(model: nil)
1156
+ @activity = BTAP::Activity.new(model)
1157
+ end
1158
+
1159
+ # Initiates a BTAP building STRUCTURE.
1160
+ #
1161
+ # @param model [OpenStudio::Model::Model] a model
1162
+ # @param activity [BTAP::Activity] a BTAP building ACTIVITY object
1163
+ # @param massive [Boolean] whether requesting internal mass generation
1164
+ #
1165
+ # @return [BTAP::Structure] a BTAP building STRUCTURE (see logs if failed)
1166
+ def assign_building_structure(model: nil, activity: nil, massive: true)
1167
+ @structure = BTAP::Structure.new(model, activity, massive)
1168
+ end
1004
1169
 
1005
1170
  ##
1006
- # (Optionally) uprates, then derates, envelope surface constructions due to
1171
+ # (Optionally) uprates - then derates - envelope surface constructions due to
1007
1172
  # MAJOR thermal bridges (e.g. roof parapets, corners, fenestration
1008
1173
  # perimeters). See lib/openstudio-standards/btap/bridging.rb, which relies on
1009
1174
  # the Thermal Bridging & Derating (TBD) gem.
1010
1175
  #
1011
1176
  # @param model [OpenStudio::Model::Model] an OpenStudio model
1012
- # @param tbd_option [String] BTAP/TBD option
1013
- # @param tbd_interpolate [Boolean] true if TBD interpolates between costed Uo
1014
- # @param wall_U [Double] wall conductance in W/m2.K (nil by default)
1015
- # @param floor_U [Double] floor conductance in W/m2.K (nil by default)
1016
- # @param roof_U [Double] roof conductance in W/m2.K (nil by default)
1177
+ # @param necb_hdd [Boolean] whether to rely on BTAP to set HDD (vs stat file)
1178
+ # @param structure [BTAP::Structure] BTAP Structure object
1179
+ # @param option [#to_sym] BTAP/TBD option e.g. "uprate"
1180
+ # @param interpolate [Boolean] true if TBD interpolates among Uo (uprating)
1181
+ # @param wallU [Numeric] optional wall Ut in W/m2.K if uprating
1182
+ # @param floorU [Numeric] optional floor Ut in W/m2.K if uprating
1183
+ # @param roofU [Numeric] optional roof Ut in W/m2.K if uprating
1017
1184
  #
1018
1185
  # @return [Boolean] true if successful, e.g. no errors, compliant if uprated
1019
1186
  def apply_thermal_bridging(model: nil,
1020
- tbd_option: 'none',
1021
- tbd_interpolate: false,
1022
- wall_U: nil,
1023
- floor_U: nil,
1024
- roof_U: nil)
1025
- return false unless model.is_a?(OpenStudio::Model::Model)
1026
- return false unless tbd_option.respond_to?(:to_s)
1027
-
1028
- tbd_option = tbd_option.to_s
1029
- # 4x options:
1030
- # - 'none' (TBD is ignored)
1031
- # - derate using 'bad' PSI factors (BTAP-costed)
1032
- # - derate using 'good' PSI factors (BTAP-costed)
1033
- # - 'uprate' (then derate), i.e. iterative process (BTAP-costed)
1034
- ok = tbd_option == 'bad' || tbd_option == 'good' || tbd_option == 'uprate'
1035
- return true if tbd_option == 'none'
1036
- return false unless ok
1037
-
1038
- argh = {} # BTAP/TBD arguments
1039
- ok = tbd_interpolate == true || tbd_interpolate == false
1040
- argh[:interpolate] = tbd_interpolate if ok
1041
- argh[:interpolate] = false unless ok
1042
-
1043
- argh[:walls ] = { uo: wall_U }
1044
- argh[:floors] = { uo: floor_U }
1045
- argh[:roofs ] = { uo: roof_U }
1046
-
1047
- if tbd_option == 'uprate'
1048
- argh[:walls ][:ut] = wall_U
1049
- argh[:floors ][:ut] = floor_U
1050
- argh[:roofs ][:ut] = roof_U
1051
- elsif tbd_option == 'good'
1187
+ necb_hdd: true,
1188
+ structure: nil,
1189
+ option: 'none',
1190
+ interpolate: false,
1191
+ wallU: nil,
1192
+ floorU: nil,
1193
+ roofU: nil)
1194
+ necb_hdd = true unless [true, false].include?(necb_hdd)
1195
+ return true unless option.respond_to?(:to_sym)
1196
+ return true if option.to_s.downcase == 'none'
1197
+
1198
+ hdd = get_necb_hdd18(model: model, necb_hdd: necb_hdd)
1199
+ wallU = wallU ? wallU : max_u_necb("wall", "outdoors", hdd)
1200
+ floorU = floorU ? floorU : max_u_necb("floor", "outdoors", hdd)
1201
+ roofU = roofU ? roofU : max_u_necb("roofceiling", "outdoors", hdd)
1202
+
1203
+ argh = {}
1204
+ argh[:structure] = structure
1205
+ argh[:walls ] = { uo: wallU }
1206
+ argh[:floors ] = { uo: floorU }
1207
+ argh[:roofs ] = { uo: roofU }
1208
+
1209
+ case option.downcase
1210
+ when 'uprate'
1211
+ argh[:walls ][:ut] = wallU
1212
+ argh[:floors ][:ut] = floorU
1213
+ argh[:roofs ][:ut] = roofU
1214
+ when 'good'
1052
1215
  argh[:quality] = :good
1053
- end # default == :bad
1216
+ else
1217
+ argh[:quality] = :bad
1218
+ end
1219
+
1220
+ argh[:interpolate] = interpolate
1221
+ argh[:interpolate] = false unless [true, false].include?(interpolate)
1054
1222
 
1055
1223
  @tbd = BTAP::Bridging.new(model, argh)
1056
1224
 
@@ -1080,10 +1248,10 @@ class NECB2011 < Standard
1080
1248
 
1081
1249
  # @param necb_reference_hp [Boolean] if true, NECB reference model rules for heat pumps will be used.
1082
1250
  def apply_standard_efficiencies(model:, sizing_run_dir:, dcv_type: 'NECB_Default', necb_reference_hp: false)
1083
- raise('validation of model failed.') unless validate_initial_model(model)
1251
+ # Do a sizing run
1252
+ try_sizing_run(model: model, sizing_run_dir: sizing_run_dir, sizing_run_subdir: 'plant_loops')
1084
1253
 
1085
1254
  climate_zone = 'NECB HDD Method'
1086
- raise("sizing run 1 failed! check #{sizing_run_dir}") if model_run_sizing_run(model, "#{sizing_run_dir}/plant_loops", true) == false
1087
1255
 
1088
1256
  # This is needed for NECB2011 as a workaround for sizing the reheat boxes.
1089
1257
  model.getAirTerminalSingleDuctVAVReheats.each { |iobj| air_terminal_single_duct_vav_reheat_set_heating_cap(iobj) }
@@ -1962,7 +2130,8 @@ class NECB2011 < Standard
1962
2130
  space_type_apply_internal_loads(space_type: space_type, lights_type: lights_type, lights_scale: lights_scale)
1963
2131
 
1964
2132
  # Schedules
1965
- space_type_apply_internal_load_schedules(space_type, true, true, true, true, true, true)
2133
+ space_type_apply_internal_load_schedules(space_type)
2134
+ space_type_apply_thermostat_schedules(space_type)
1966
2135
  end
1967
2136
 
1968
2137
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying space types (loads)')
@@ -2286,28 +2455,42 @@ class NECB2011 < Standard
2286
2455
  return model
2287
2456
  end
2288
2457
 
2289
- # This method handles looking for the epw_file in the https://github.com/canmet-energy/btap_weather repository. It
2458
+ # This method handles looking for the epw_file in btap_weather or Climate.OneBuilding.Org. It
2290
2459
  # checks for the epw_file in the historical data first. If it is not there then it looks in the future weather data.
2291
2460
  # If it is not there either, it throws an error.
2292
- # epw_file (String): The name of the epw file. The different weather files all share the same name as the epw file,
2293
- # only the extension changes.
2294
- def get_weather_file_from_repo(epw_file:)
2461
+ # epw_file (String): The name of the epw file. The different weather files all share the same name as the epw file,
2462
+ # only the extension changes.
2463
+ # btap_weather (Boolean): Determines whether to download from the btap_weather repository or Climate.OneBuilding.Org.
2464
+ def get_weather_file_from_repo(epw_file:, btap_weather:)
2295
2465
  # Get just the weather file name without the extension
2296
2466
  weather_loc = epw_file[0..-5]
2297
2467
  # Get the url of the file containing the historical weather data file names in the repository and the repository
2298
2468
  # folder containing the files
2299
- historic_weather_files_loc = @standards_data['constants']['historic_weather_file_list']['value'].to_s
2300
- historic_git_folder = @standards_data['constants']['historic_weather_folder_url']['value'].to_s
2469
+ if btap_weather
2470
+ historic_weather_files_loc = @standards_data['constants']['historic_weather_file_list_btap']['value'].to_s
2471
+ historic_folder = @standards_data['constants']['historic_weather_folder_url_btap']['value'].to_s
2472
+ future_weather_files_loc = @standards_data['constants']['future_weather_file_list_btap']['value'].to_s
2473
+ future_folder = @standards_data['constants']['future_weather_folder_url_btap']['value'].to_s
2474
+ else
2475
+ historic_weather_files_loc = @standards_data['constants']['historic_weather_file_list']['value'].to_s
2476
+ historic_folder = @standards_data['constants']['historic_weather_folder_url']['value'].to_s
2477
+ future_weather_files_loc = @standards_data['constants']['future_weather_file_list']['value'].to_s
2478
+ future_folder = @standards_data['constants']['future_weather_folder_url']['value'].to_s
2479
+ end
2301
2480
  # Get the files from the repository
2302
- success_flag = download_and_save_file(weather_list_url: historic_weather_files_loc, weather_loc: weather_loc, git_folder: historic_git_folder)
2481
+ success_flag = download_and_save_file(weather_list_url: historic_weather_files_loc,
2482
+ weather_loc: weather_loc,
2483
+ download_folder: historic_folder,
2484
+ btap_weather: btap_weather)
2303
2485
  return if success_flag
2304
2486
  # If the file could not be found in the historical data look for it with the future weather data.
2305
2487
  puts "Could not find #{epw_file} in historical weather data files, looking in future weather data files."
2306
- future_weather_files_loc = @standards_data['constants']['future_weather_file_list']['value'].to_s
2307
- future_git_folder = @standards_data['constants']['future_weather_folder_url']['value'].to_s
2308
- success_flag = download_and_save_file(weather_list_url: future_weather_files_loc, weather_loc: weather_loc, git_folder: future_git_folder)
2488
+ success_flag = download_and_save_file(weather_list_url: future_weather_files_loc,
2489
+ weather_loc: weather_loc,
2490
+ download_folder: future_folder,
2491
+ btap_weather: btap_weather)
2309
2492
  return if success_flag
2310
- raise("Could not locate the following file in the canmet/btap_weather repository or could not extract the data: #{epw_file}. Please check the spelling of the file or visit https://github.com/canmet-energy/btap_weather to see if the file exists.")
2493
+ raise("Could not locate the following file in #{btap_weather ? "btap_weather" : "Climate.OneBuilding.Org"} or could not extract the data: #{epw_file} Please check the spelling of the file or visit #{btap_weather ? "https://github.com/canmet-energy/btap_weather" : "https://climate.onebuilding.org/WMO_Region_4_North_and_Central_America/"} to see if the file exists.")
2311
2494
  end
2312
2495
 
2313
2496
  # This method actually looks for and downloads the zip file from the https://github.com/canmet-energy/btap_weather
@@ -2321,7 +2504,8 @@ class NECB2011 < Standard
2321
2504
  # weather_loc (string): the name of the epw file we are looking for without the .epw extension
2322
2505
  # git_folder (string): the url of the folder containing the weather files. As of 2023-07-07 this this is either the
2323
2506
  # url of the historical weather data folder or the future weather data folder.
2324
- def download_and_save_file(weather_list_url:, weather_loc:, git_folder:)
2507
+ # btap_weather (Boolean): Determines whether to download from the btap_weather repository or Climate.OneBuilding.Org.
2508
+ def download_and_save_file(weather_list_url:, weather_loc:, download_folder:, btap_weather:)
2325
2509
  status = false
2326
2510
  attempt = 1
2327
2511
  # Try to download the list of weather files 5 times, waiting 5 seconds between each attempt.
@@ -2341,7 +2525,27 @@ class NECB2011 < Standard
2341
2525
  unless zip_name.nil?
2342
2526
  # Found the weather file on the list
2343
2527
  # Define the full url of the weather zip file we want to download
2344
- save_file_url = git_folder + zip_name
2528
+ if btap_weather
2529
+ save_file_url = download_folder + zip_name
2530
+ else
2531
+ # Used to resolve the Climate.OneBuilding.Org download link from using just the filename.
2532
+ abbreviation_map = {
2533
+ 'AB' => 'AB_Alberta/',
2534
+ 'BC' => 'BC_British_Columbia/',
2535
+ 'MB' => 'MB_Manitoba/',
2536
+ 'NB' => 'NB_New_Brunswick/',
2537
+ 'NL' => 'NL_Newfoundland_and_Labrador/',
2538
+ 'NS' => 'NS_Nova_Scotia/',
2539
+ 'NT' => 'NT_Northwest_Territories/',
2540
+ 'NU' => 'NU_Nunavut/',
2541
+ 'ON' => 'ON_Ontario/',
2542
+ 'PE' => 'PE_Prince_Edward_Island/',
2543
+ 'QC' => 'QC_Quebec/',
2544
+ 'SK' => 'SK_Saskatchewan/',
2545
+ 'YT' => 'YT_Yukon/'
2546
+ }
2547
+ save_file_url = download_folder + abbreviation_map[zip_name[4..5]] + zip_name
2548
+ end
2345
2549
  # Define the local location of where the weather zip file will be saved
2346
2550
  weather_dir = File.absolute_path(File.join(__FILE__, '..', '..', '..', '..', '..' , '..', "data/weather"))
2347
2551
  save_file = File.join(weather_dir, zip_name)
@@ -2417,6 +2621,9 @@ class NECB2011 < Standard
2417
2621
  def extract_weather_data(zipped_file:, weather_dir:)
2418
2622
  # Set a flag to check if the weather data is for future weather.
2419
2623
  future_file = false
2624
+
2625
+ # Data structure to determine if the weather file contains all necessary elements.
2626
+ checklist = {'.epw' => false, '.stat' => false, '.ddy' => false}
2420
2627
  # Start expanding the data.
2421
2628
  Zip::File.open(zipped_file) do |zip_file|
2422
2629
  puts "Expanding #{zipped_file}"
@@ -2429,7 +2636,7 @@ class NECB2011 < Standard
2429
2636
  # to just '.ddy'. This is so the rest of BTAP uses the _ASHRAE.ddy file.
2430
2637
  entry_name = entry.name.to_s
2431
2638
  if entry_name.length > 11
2432
- future_file = true if entry_name[-11..-1] == '_ASHRAE.ddy'
2639
+ future_file = true if entry_name.end_with?('_ASHRAE.ddy')
2433
2640
  end
2434
2641
  # entry.extract # This was required before but now it isn't. I'm confused so am saving this comment to
2435
2642
  # remind me if there are problems later.
@@ -2437,6 +2644,12 @@ class NECB2011 < Standard
2437
2644
  content = entry.get_input_stream.read
2438
2645
  # Save the data locally
2439
2646
  File.open(curr_save_file, 'wb') { |save_f| save_f.write(content) }
2647
+
2648
+ # Add the file extension of the current entry to the checklist.
2649
+ file_extension = entry_name[entry_name.rindex('.')..]
2650
+ if checklist.key?(file_extension)
2651
+ checklist[file_extension] = true
2652
+ end
2440
2653
  end
2441
2654
  end
2442
2655
  if future_file
@@ -2453,6 +2666,13 @@ class NECB2011 < Standard
2453
2666
  FileUtils.cp(orig_ddy_name, rev_ddy_name)
2454
2667
  FileUtils.cp(ashrae_ddy_name, orig_ddy_name)
2455
2668
  end
2669
+
2670
+ # Return false if not all files are present:
2671
+ if !checklist.values.all?()
2672
+ puts "Error: Not all files present in #{zipped_file}. Missing #{checklist.select { |k, v| v == false}.keys.join(", ") } file(s). Exiting..."
2673
+ exit(1)
2674
+ end
2675
+
2456
2676
  # Return true if everything worked out
2457
2677
  return true
2458
2678
  end
@@ -2521,6 +2741,24 @@ class NECB2011 < Standard
2521
2741
  return boiler_cap_ratios
2522
2742
  end
2523
2743
 
2744
+ # Until someone has time to allow dwelling units, washrooms, cooridors, and storage rooms can get their own custom
2745
+ # system types (beyond the default necb_system), this metod will set the system type for those rooms to either be
2746
+ # their default or to the primary system type (if one is defined and the other sytems are not set to default)
2747
+ def reset_hvac_system_if_required(hvac_system_primary: nil, hvac_system_dwelling_units: nil, hvac_system_corridor: nil, hvac_system_storage: nil, hvac_system_washrooms: nil)
2748
+ if hvac_system_primary.nil? || hvac_system_primary.to_s.downcase == "necb_default"
2749
+ hvac_system_dwelling_units = "NECB_Default"
2750
+ hvac_system_corridor = "NECB_Default"
2751
+ hvac_system_storage = "NECB_Default"
2752
+ hvac_system_washrooms = "NECB_Default"
2753
+ else
2754
+ hvac_system_dwelling_units = hvac_system_primary unless hvac_system_dwelling_units.nil? || hvac_system_dwelling_units.to_s.downcase == "necb_default"
2755
+ hvac_system_corridor = hvac_system_primary unless hvac_system_corridor.nil? || hvac_system_corridor.to_s.downcase == "necb_default"
2756
+ hvac_system_storage = hvac_system_primary unless hvac_system_storage.nil? || hvac_system_storage.to_s.downcase == "necb_default"
2757
+ hvac_system_washrooms = hvac_system_primary unless hvac_system_washrooms.nil? || hvac_system_washrooms.to_s.downcase == "necb_default"
2758
+ end
2759
+ return hvac_system_dwelling_units, hvac_system_corridor, hvac_system_storage, hvac_system_washrooms
2760
+ end
2761
+
2524
2762
  # This method checks if the output_meters argument contains a net electricity meter with 'timestep' frequency. If one
2525
2763
  # is then the method does nothing. If one is not then it is added. This is used in conjunction with the
2526
2764
  # 'oerd_utility_pricing' argument. If that argument is present then a net electricity meter with 'timestep' frequency
@@ -2531,17 +2769,89 @@ class NECB2011 < Standard
2531
2769
  {
2532
2770
  "name" => "ElectricityNet:Facility",
2533
2771
  "frequency" => "Hourly"
2772
+ },
2773
+ {
2774
+ "name" => "Heating:Electricity",
2775
+ "frequency" => "Hourly"
2776
+ },
2777
+ {
2778
+ "name" => "WaterSystems:Electricity",
2779
+ "frequency" => "Hourly"
2534
2780
  }
2535
2781
  ]
2536
2782
  else
2537
- electnet_facility = output_meters.select { |output_meter| (output_meter["name"].to_s.downcase == "electricitynet:facility") && (output_meter["frequency"].to_s.downcase == "zone timestep") }
2783
+ electnet_facility = output_meters.select { |output_meter| (output_meter["name"].to_s.downcase == "electricitynet:facility") && (output_meter["frequency"].to_s.downcase == "hourly") }
2538
2784
  if electnet_facility.empty?
2539
2785
  output_meters << {
2540
2786
  "name" => "ElectricityNet:Facility",
2541
2787
  "frequency" => "Hourly"
2542
2788
  }
2543
2789
  end
2790
+ heating_elec = output_meters.select { |output_meter| (output_meter["name"].to_s.downcase == "heating:electricity") && (output_meter["frequency"].to_s.downcase == "hourly") }
2791
+ if electnet_facility.empty?
2792
+ output_meters << {
2793
+ "name" => "Heating:Electricity",
2794
+ "frequency" => "Hourly"
2795
+ }
2796
+ end
2797
+ watersys_elec = output_meters.select { |output_meter| (output_meter["name"].to_s.downcase == "watersystems:electricity") && (output_meter["frequency"].to_s.downcase == "hourly") }
2798
+ if electnet_facility.empty?
2799
+ output_meters << {
2800
+ "name" => "WaterSystems:Electricity",
2801
+ "frequency" => "Hourly"
2802
+ }
2803
+ end
2544
2804
  end
2545
2805
  return output_meters
2546
2806
  end
2807
+
2808
+ # This method is used to do a sizing run on the model. It will return true if the sizing run was successful and
2809
+ # will generate an error if it was not. The method will also resize any DX heating coils that have a capacity less than 1.0 kW to
2810
+ # 1.0 kW and rerun the sizing run until it succeeds or the sizing run continues to fail.
2811
+ #
2812
+ # Arguments:
2813
+ # model (OpenStudio::Model::Model): The model to run the sizing run on.
2814
+ # sizing_run_dir (String): The directory where the sizing run files will be saved.
2815
+ def try_sizing_run(model:, sizing_run_dir:, sizing_run_subdir:)
2816
+ raise('validation of model failed.') unless validate_initial_model(model)
2817
+
2818
+ # Do a sizing run to determine the system capacities. If a sizing run fails, hard size any failing DX heating coils
2819
+ # to 1.0 kW and rerun the sizing run until it succeeds. If no DX heating coils are found, or none had a small
2820
+ # capacity then raise an error.
2821
+ loop do
2822
+ sizing_run_success = model_run_sizing_run(model, "#{sizing_run_dir}/#{sizing_run_subdir}", true)
2823
+ break if sizing_run_success
2824
+
2825
+ # Sizing run failed, check all DX heating coils and set their size to 1 if less than 1
2826
+ dx_coil_changed = false
2827
+
2828
+ model.getCoilHeatingDXSingleSpeeds.each do |coil|
2829
+ autosized_capacity = coil.autosizedRatedTotalHeatingCapacity
2830
+ if autosized_capacity.is_initialized && autosized_capacity.get < 1.0
2831
+ coil.setRatedTotalHeatingCapacity(1.0)
2832
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "DX Heating Coil #{coil.name.to_s} has a rated capacity less than 1.0 kW and has been resized to 1.0 kW to avoid sizing run failure.")
2833
+ puts "DX Heating Coil #{coil.name.to_s} has a rated capacity less than 1.0 kW and has been resized to 1.0 kW to avoid sizing run failure."
2834
+ dx_coil_changed = true
2835
+ end
2836
+ end
2837
+ model.getCoilHeatingDXMultiSpeeds.each do |coil|
2838
+ coil.stages.each do |stage|
2839
+ autosized_capacity = stage.autosizedGrossRatedHeatingCapacity
2840
+ if autosized_capacity.is_initialized && autosized_capacity.get < 1.0
2841
+ stage.setGrossRatedHeatingCapacity(1.0)
2842
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "A DX Heating Coil #{coil.name.to_s} stage has a rated capacity less than 1.0 kW and has been resized to 1.0 kW to avoid sizing run failure.")
2843
+ puts "A DX Heating Coil #{coil.name.to_s} stage has a rated capacity less than 1.0 kW and has been resized to 1.0 kW to avoid sizing run failure."
2844
+ dx_coil_changed = true
2845
+ end
2846
+ end
2847
+ end
2848
+
2849
+ # If no DX coil was changed, break loop and raise error
2850
+ if !dx_coil_changed
2851
+ raise("sizing run failed! check #{sizing_run_dir}/#{sizing_run_subdir} (DX coil sizes adjusted, but no further changes possible)")
2852
+ end
2853
+ puts "Rerunning sizing run after adjusting DX heating coil capacity to 1.0 kW."
2854
+ # Otherwise, loop will rerun sizing
2855
+ end
2856
+ end
2547
2857
  end