openstudio-standards 0.2.12.rc4 → 0.2.13.rc3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (541) hide show
  1. checksums.yaml +4 -4
  2. data/data/geometry/ASHRAE90120162019HighriseApartment.json +1042 -0
  3. data/data/geometry/ASHRAE90120162019Hospital.json +199 -0
  4. data/data/geometry/ASHRAE90120162019LargeHotel.json +73 -0
  5. data/data/geometry/ASHRAE90120162019LargeOffice.json +109 -0
  6. data/data/geometry/ASHRAE90120162019SecondarySchool.json +205 -0
  7. data/data/geometry/ASHRAECourthouse.json +112 -0
  8. data/data/geometry/ASHRAECourthouse.osm +26470 -0
  9. data/data/geometry/ASHRAELargeHotel.osm +11 -1
  10. data/data/geometry/ASHRAELargeOffice.json +4 -0
  11. data/data/geometry/ASHRAESmallDataCenter.json +1 -1
  12. data/data/standards/OpenStudio_Standards-ashrae_90_1(space_types).xlsx +0 -0
  13. data/data/standards/OpenStudio_Standards-ashrae_90_1-ALL-comstock(space_types).xlsx +0 -0
  14. data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
  15. data/data/standards/exclude_list.csv +19 -0
  16. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.boilers.json +49 -0
  17. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.chillers.json +293 -0
  18. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_properties.json +25426 -0
  19. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_sets.json +1600 -0
  20. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.economizers.json +564 -0
  21. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.elevators.json +349 -0
  22. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.ext_ltg.json +164 -0
  23. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.ground_temperatures.json +10663 -0
  24. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_pumps.json +508 -0
  25. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_pumps_heating.json +156 -0
  26. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_rejection.json +44 -0
  27. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.motors.json +184 -0
  28. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.prototype_inputs.json +3094 -0
  29. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.ref_cases.json +829 -0
  30. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.ref_lnup.json +562 -0
  31. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.refrigeration_compressors.json +52 -0
  32. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.refrigeration_condenser.json +220 -0
  33. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.refrigeration_system.json +156 -0
  34. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.refrigeration_walkins.json +1316 -0
  35. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.spc_typ.json +21446 -0
  36. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.unitary_acs.json +554 -0
  37. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.water_heaters.json +68 -0
  38. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.water_source_heat_pumps.json +28 -0
  39. data/data/standards/export/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.water_source_heat_pumps_heating.json +12 -0
  40. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.boilers.json +49 -0
  41. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.chillers.json +293 -0
  42. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_properties.json +12487 -0
  43. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_sets.json +1600 -0
  44. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.economizers.json +564 -0
  45. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.elevators.json +349 -0
  46. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.ext_ltg.json +164 -0
  47. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.ground_temperatures.json +10663 -0
  48. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_pumps.json +466 -0
  49. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_pumps_heating.json +137 -0
  50. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_rejection.json +44 -0
  51. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.motors.json +184 -0
  52. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.prototype_inputs.json +3094 -0
  53. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.ref_cases.json +829 -0
  54. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.ref_lnup.json +562 -0
  55. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.refrigeration_compressors.json +52 -0
  56. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.refrigeration_condenser.json +220 -0
  57. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.refrigeration_system.json +156 -0
  58. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.refrigeration_walkins.json +1316 -0
  59. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.spc_typ.json +21380 -0
  60. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.unitary_acs.json +554 -0
  61. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.water_heaters.json +68 -0
  62. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.water_source_heat_pumps.json +28 -0
  63. data/data/standards/export/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.water_source_heat_pumps_heating.json +12 -0
  64. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.boilers.json +49 -0
  65. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.chillers.json +395 -0
  66. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_properties.json +12487 -0
  67. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_sets.json +1600 -0
  68. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.economizers.json +592 -0
  69. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.elevators.json +349 -0
  70. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.energy_recovery.json +550 -0
  71. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.ext_ltg.json +164 -0
  72. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.ground_temperatures.json +10663 -0
  73. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_pumps.json +466 -0
  74. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_pumps_heating.json +137 -0
  75. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_rejection.json +44 -0
  76. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.motors.json +238 -0
  77. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.prototype_inputs.json +3094 -0
  78. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.ref_cases.json +829 -0
  79. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.ref_lnup.json +562 -0
  80. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.refrigeration_compressors.json +52 -0
  81. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.refrigeration_condenser.json +220 -0
  82. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.refrigeration_system.json +156 -0
  83. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.refrigeration_walkins.json +1316 -0
  84. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.spc_typ.json +21548 -0
  85. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.unitary_acs.json +554 -0
  86. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.water_heaters.json +68 -0
  87. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.water_source_heat_pumps.json +28 -0
  88. data/data/standards/export/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.water_source_heat_pumps_heating.json +12 -0
  89. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.boilers.json +64 -0
  90. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.chillers.json +871 -0
  91. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_properties.json +12487 -0
  92. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_sets.json +1600 -0
  93. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.economizers.json +592 -0
  94. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.elevators.json +349 -0
  95. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.energy_recovery.json +1096 -0
  96. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.ext_ltg.json +164 -0
  97. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.ground_temperatures.json +10663 -0
  98. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_pumps.json +886 -0
  99. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_pumps_heating.json +194 -0
  100. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_rejection.json +44 -0
  101. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.motors.json +247 -0
  102. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.prototype_inputs.json +3094 -0
  103. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.ref_cases.json +829 -0
  104. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.ref_lnup.json +562 -0
  105. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.refrigeration_compressors.json +52 -0
  106. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.refrigeration_condenser.json +220 -0
  107. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.refrigeration_system.json +156 -0
  108. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.refrigeration_walkins.json +1316 -0
  109. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.spc_typ.json +22079 -0
  110. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.unitary_acs.json +994 -0
  111. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_heaters.json +68 -0
  112. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_source_heat_pumps.json +28 -0
  113. data/data/standards/export/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_source_heat_pumps_heating.json +12 -0
  114. data/data/standards/manage_OpenStudio_Standards.rb +87 -37
  115. data/data/standards/metadata_units_OpenStudio_Standards-ashrae_90_1-ALL-comstockspace_types.csv +236 -0
  116. data/data/standards/metadata_units_OpenStudio_Standards-ashrae_90_1.csv +622 -0
  117. data/data/standards/metadata_units_OpenStudio_Standards-ashrae_90_1space_types.csv +191 -0
  118. data/data/standards/openstudio_standards_duplicates_log.csv +17 -0
  119. data/data/standards/test_performance_expected_dd_results.csv +1971 -1171
  120. data/lib/openstudio-standards.rb +76 -18
  121. data/lib/openstudio-standards/btap/btap.model.rb +1 -1
  122. data/lib/openstudio-standards/btap/economics.rb +14 -11
  123. data/lib/openstudio-standards/btap/envelope.rb +185 -257
  124. data/lib/openstudio-standards/btap/fileio.rb +1 -0
  125. data/lib/openstudio-standards/btap/geometry.rb +21 -1
  126. data/lib/openstudio-standards/btap/measures.rb +12 -11
  127. data/lib/openstudio-standards/btap/schedules.rb +3 -12
  128. data/lib/openstudio-standards/hvac_sizing/Siz.AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.rb +178 -0
  129. data/lib/openstudio-standards/hvac_sizing/Siz.CoilCoolingDXMultiSpeed.rb +8 -8
  130. data/lib/openstudio-standards/hvac_sizing/Siz.Model.rb +3 -0
  131. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PumpVariableSpeed.rb +28 -0
  132. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.FanVariableVolume.rb +0 -1
  133. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.PumpVariableSpeed.rb +28 -0
  134. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.Model.rb +53 -2
  135. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.PumpVariableSpeed.rb +29 -0
  136. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.Model.rb +157 -2
  137. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.PumpVariableSpeed.rb +29 -0
  138. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +24 -0
  139. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.FanConstantVolume.rb +32 -0
  140. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.FanOnOff.rb +33 -0
  141. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.FanVariableVolume.rb +32 -0
  142. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.elevators.rb +25 -0
  143. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +366 -0
  144. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.PumpVariableSpeed.rb +144 -0
  145. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.hvac_systems.rb +11 -0
  146. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +24 -0
  147. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.FanConstantVolume.rb +32 -0
  148. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.FanOnOff.rb +33 -0
  149. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.FanVariableVolume.rb +32 -0
  150. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.elevators.rb +25 -0
  151. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +367 -0
  152. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.PumpVariableSpeed.rb +144 -0
  153. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.hvac_systems.rb +11 -0
  154. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.AirTerminalSingleDuctVAVReheat.rb +0 -1
  155. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirTerminalSingleDuctVAVReheat.rb +0 -1
  156. data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.HeatExchangerAirToAirSensibleAndLatent.rb +1 -1
  157. data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.Model.rb +1 -1
  158. data/lib/openstudio-standards/prototypes/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.HeatExchangerAirToAirSensibleAndLatent.rb +1 -1
  159. data/lib/openstudio-standards/prototypes/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.Model.rb +1 -1
  160. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.College.rb +3 -3
  161. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Courthouse.rb +74 -0
  162. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.FullServiceRestaurant.rb +46 -30
  163. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.HighRiseApartment.rb +23 -8
  164. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Hospital.rb +26 -15
  165. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Laboratory.rb +8 -11
  166. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeDataCenterHighITE.rb +54 -60
  167. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeDataCenterLowITE.rb +56 -60
  168. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeHotel.rb +38 -12
  169. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOffice.rb +218 -134
  170. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOfficeDetailed.rb +6 -2
  171. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOffice.rb +230 -134
  172. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOfficeDetailed.rb +60 -62
  173. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MidriseApartment.rb +25 -15
  174. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb +34 -22
  175. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.PrimarySchool.rb +31 -7
  176. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.QuickServiceRestaurant.rb +43 -28
  177. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.RetailStandalone.rb +48 -38
  178. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.RetailStripmall.rb +9 -5
  179. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SecondarySchool.rb +575 -345
  180. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallDataCenterHighITE.rb +13 -19
  181. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallDataCenterLowITE.rb +13 -17
  182. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallHotel.rb +9 -5
  183. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOffice.rb +79 -51
  184. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOfficeDetailed.rb +60 -60
  185. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperMarket.rb +2 -4
  186. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperTallBuilding.rb +133 -120
  187. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.TallBuilding.rb +124 -112
  188. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Warehouse.rb +138 -66
  189. data/lib/openstudio-standards/prototypes/common/do_not_edit_metaclasses.rb +7275 -199
  190. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirConditionerVariableRefrigerantFlow.rb +35 -35
  191. data/lib/openstudio-standards/prototypes/common/objects/Prototype.BoilerHotWater.rb +2 -2
  192. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CentralAirSourceHeatPump.rb +2 -2
  193. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXSingleSpeed.rb +3 -3
  194. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingDXTwoSpeed.rb +1 -1
  195. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWater.rb +2 -2
  196. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWaterToAirHeatPumpEquationFit.rb +2 -2
  197. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingDXSingleSpeed.rb +1 -1
  198. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingElectric.rb +2 -2
  199. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWater.rb +2 -2
  200. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWaterToAirHeatPumpEquationFit.rb +2 -2
  201. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoolingTower.rb +1 -1
  202. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Fan.rb +4 -3
  203. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanConstantVolume.rb +7 -8
  204. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanOnOff.rb +7 -8
  205. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanVariableVolume.rb +13 -14
  206. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanZoneExhaust.rb +7 -5
  207. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.elevators.rb +4 -1
  208. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.exterior_lights.rb +0 -1
  209. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.hvac.rb +25 -14
  210. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +474 -89
  211. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.swh.rb +35 -33
  212. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Pump.rb +3 -0
  213. data/lib/openstudio-standards/prototypes/common/objects/Prototype.PumpVariableSpeed.rb +72 -0
  214. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +120 -120
  215. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +142 -154
  216. data/lib/openstudio-standards/prototypes/common/objects/Prototype.radiant_system_controls.rb +9 -3
  217. data/lib/openstudio-standards/prototypes/common/objects/Prototype.refrigeration.rb +11 -5
  218. data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +26 -14
  219. data/lib/openstudio-standards/prototypes/common/prototype_metaprogramming.rb +270 -247
  220. data/lib/openstudio-standards/prototypes/deer/deer.Model.rb +1 -1
  221. data/lib/openstudio-standards/refs/references.rb +5 -2
  222. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +70 -51
  223. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctVAVReheat.rb +0 -1
  224. data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +0 -1
  225. data/lib/openstudio-standards/standards/Standards.BuildingStory.rb +1 -0
  226. data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +2 -4
  227. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXMultiSpeed.rb +91 -2
  228. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +4 -5
  229. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +0 -1
  230. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +1 -1
  231. data/lib/openstudio-standards/standards/Standards.CoilDX.rb +30 -9
  232. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +2 -1
  233. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +3 -1
  234. data/lib/openstudio-standards/standards/Standards.CoilHeatingGas.rb +0 -3
  235. data/lib/openstudio-standards/standards/Standards.CoilHeatingGasMultiStage.rb +37 -1
  236. data/lib/openstudio-standards/standards/Standards.CoilHeatingWaterToAirHeatPumpEquationFit.rb +1 -3
  237. data/lib/openstudio-standards/standards/Standards.Construction.rb +124 -118
  238. data/lib/openstudio-standards/standards/Standards.CoolingTower.rb +0 -1
  239. data/lib/openstudio-standards/standards/Standards.CoolingTowerSingleSpeed.rb +0 -1
  240. data/lib/openstudio-standards/standards/Standards.CoolingTowerTwoSpeed.rb +0 -1
  241. data/lib/openstudio-standards/standards/Standards.CoolingTowerVariableSpeed.rb +0 -1
  242. data/lib/openstudio-standards/standards/Standards.Fan.rb +0 -1
  243. data/lib/openstudio-standards/standards/Standards.FanConstantVolume.rb +0 -1
  244. data/lib/openstudio-standards/standards/Standards.FanOnOff.rb +0 -1
  245. data/lib/openstudio-standards/standards/Standards.FanVariableVolume.rb +2 -4
  246. data/lib/openstudio-standards/standards/Standards.FanZoneExhaust.rb +0 -1
  247. data/lib/openstudio-standards/standards/Standards.FluidCooler.rb +10 -3
  248. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsConstantSpeed.rb +0 -1
  249. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsVariableSpeed.rb +0 -1
  250. data/lib/openstudio-standards/standards/Standards.Model.rb +305 -247
  251. data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +2 -0
  252. data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +11 -9
  253. data/lib/openstudio-standards/standards/Standards.Pump.rb +0 -1
  254. data/lib/openstudio-standards/standards/Standards.PumpConstantSpeed.rb +0 -1
  255. data/lib/openstudio-standards/standards/Standards.PumpVariableSpeed.rb +0 -1
  256. data/lib/openstudio-standards/standards/Standards.ScheduleCompact.rb +0 -1
  257. data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +0 -1
  258. data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +103 -121
  259. data/lib/openstudio-standards/standards/Standards.Space.rb +42 -35
  260. data/lib/openstudio-standards/standards/Standards.SpaceType.rb +9 -17
  261. data/lib/openstudio-standards/standards/Standards.SubSurface.rb +25 -27
  262. data/lib/openstudio-standards/standards/Standards.Surface.rb +97 -52
  263. data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +76 -25
  264. data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +6 -7
  265. data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +85 -7
  266. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1.Standards.FanVariableVolume.rb +0 -1
  267. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirLoopHVAC.rb +10 -2
  268. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Model.rb +2 -2
  269. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/comstock_ashrae_90_1_2004/data/ashrae_90_1.schedules.json +63 -99
  270. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/comstock_ashrae_90_1_2004/data/comstock_ashrae_90_1_2004.ext_ltg.json +7 -7
  271. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.construction_properties.json +2420 -0
  272. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.economizers.json +32 -0
  273. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.heat_rejection.json +9 -0
  274. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.prototype_inputs.json +70 -40
  275. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.spc_typ.json +105 -40
  276. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.unitary_acs.json +15 -15
  277. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.AirLoopHVAC.rb +5 -1
  278. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/ashrae_90_1.schedules.json +63 -99
  279. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/comstock_ashrae_90_1_2007/data/comstock_ashrae_90_1_2007.ext_ltg.json +7 -7
  280. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.construction_properties.json +1460 -0
  281. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.economizers.json +32 -0
  282. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.heat_rejection.json +9 -0
  283. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.prototype_inputs.json +123 -39
  284. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.spc_typ.json +104 -17
  285. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.unitary_acs.json +15 -15
  286. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirLoopHVAC.rb +32 -15
  287. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.Space.rb +1 -1
  288. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/ashrae_90_1.schedules.json +63 -99
  289. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/comstock_ashrae_90_1_2010/data/comstock_ashrae_90_1_2010.ext_ltg.json +7 -7
  290. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.construction_properties.json +1460 -0
  291. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.economizers.json +64 -0
  292. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.energy_recovery.json +52 -0
  293. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.heat_rejection.json +9 -0
  294. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.prototype_inputs.json +123 -39
  295. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.spc_typ.json +112 -25
  296. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.unitary_acs.json +5 -5
  297. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirLoopHVAC.rb +37 -14
  298. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.WaterHeaterMixed.rb +1 -1
  299. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/ashrae_90_1.schedules.json +63 -99
  300. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/comstock_ashrae_90_1_2013/data/comstock_ashrae_90_1_2013.ext_ltg.json +7 -7
  301. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.boilers.json +1 -1
  302. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.chillers.json +2 -2
  303. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.construction_properties.json +1460 -0
  304. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.economizers.json +64 -0
  305. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.energy_recovery.json +104 -0
  306. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.heat_rejection.json +9 -0
  307. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.prototype_inputs.json +125 -41
  308. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.spc_typ.json +172 -55
  309. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.unitary_acs.json +15 -15
  310. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_heaters.json +4 -4
  311. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.water_source_heat_pumps_heating.json +1 -1
  312. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirLoopHVAC.rb +456 -0
  313. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +24 -0
  314. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTower.rb +19 -0
  315. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTowerSingleSpeed.rb +5 -0
  316. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTowerTwoSpeed.rb +5 -0
  317. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTowerVariableSpeed.rb +16 -0
  318. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.FanVariableVolume.rb +37 -0
  319. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Space.rb +189 -0
  320. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.ThermalZone.rb +57 -0
  321. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.ZoneHVACComponent.rb +22 -0
  322. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.rb +16 -0
  323. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.boilers.json +68 -0
  324. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.chillers.json +490 -0
  325. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_properties.json +21244 -0
  326. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.construction_sets.json +2111 -0
  327. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.economizers.json +676 -0
  328. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.elevators.json +372 -0
  329. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.energy_recovery.json +1096 -0
  330. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.ext_ltg.json +169 -0
  331. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.heat_pumps.json +532 -0
  332. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.heat_pumps_heating.json +164 -0
  333. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.heat_rejection.json +49 -0
  334. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.motors.json +274 -0
  335. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.prototype_inputs.json +3094 -0
  336. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.ref_cases.json +854 -0
  337. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.ref_lnup.json +562 -0
  338. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.refrigeration_compressors.json +58 -0
  339. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.refrigeration_condenser.json +238 -0
  340. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.refrigeration_system.json +12 -0
  341. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.refrigeration_walkins.json +1316 -0
  342. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.spc_typ.json +23067 -0
  343. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.unitary_acs.json +648 -0
  344. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.water_heaters.json +72 -0
  345. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.water_source_heat_pumps.json +31 -0
  346. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.water_source_heat_pumps_heating.json +13 -0
  347. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +456 -0
  348. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +24 -0
  349. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTower.rb +19 -0
  350. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTowerSingleSpeed.rb +5 -0
  351. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTowerTwoSpeed.rb +5 -0
  352. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTowerVariableSpeed.rb +16 -0
  353. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.FanVariableVolume.rb +37 -0
  354. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Space.rb +189 -0
  355. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.ThermalZone.rb +57 -0
  356. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.ZoneHVACComponent.rb +22 -0
  357. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.rb +16 -0
  358. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.boilers.json +68 -0
  359. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.chillers.json +490 -0
  360. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_properties.json +21244 -0
  361. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.construction_sets.json +2111 -0
  362. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.economizers.json +676 -0
  363. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.elevators.json +372 -0
  364. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.energy_recovery.json +1096 -0
  365. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.ext_ltg.json +169 -0
  366. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.heat_pumps.json +664 -0
  367. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.heat_pumps_heating.json +204 -0
  368. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.heat_rejection.json +49 -0
  369. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.motors.json +274 -0
  370. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.prototype_inputs.json +3094 -0
  371. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.ref_cases.json +854 -0
  372. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.ref_lnup.json +562 -0
  373. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.refrigeration_compressors.json +58 -0
  374. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.refrigeration_condenser.json +238 -0
  375. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.refrigeration_system.json +12 -0
  376. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.refrigeration_walkins.json +1316 -0
  377. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.spc_typ.json +23067 -0
  378. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.unitary_acs.json +671 -0
  379. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.water_heaters.json +72 -0
  380. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.water_source_heat_pumps.json +31 -0
  381. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.water_source_heat_pumps_heating.json +13 -0
  382. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.constructions.json +1662 -332
  383. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.fans.json +1 -1
  384. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.materials.json +4994 -234
  385. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.schedules.json +1743 -161
  386. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/ashrae_90_1.schedules.json +63 -99
  387. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/comstock_doe_ref_1980_2004/data/comstock_doe_ref_1980_2004.ext_ltg.json +11 -11
  388. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.heat_rejection.json +9 -0
  389. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.prototype_inputs.json +8 -8
  390. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.spc_typ.json +5967 -2727
  391. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.Model.rb +4 -4
  392. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/ashrae_90_1.schedules.json +63 -99
  393. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/comstock_doe_ref_pre_1980/data/comstock_doe_ref_pre_1980.ext_ltg.json +10 -10
  394. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.heat_rejection.json +9 -0
  395. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.prototype_inputs.json +7 -7
  396. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.spc_typ.json +5920 -2700
  397. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.Model.rb +4 -4
  398. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.heat_rejection.json +9 -0
  399. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/data/nrel_zne_ready_2017.spc_typ.json +2011 -1112
  400. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirLoopHVAC.rb +0 -1
  401. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.Model.rb +4 -4
  402. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.PlantLoop.rb +1 -1
  403. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.ZoneHVACComponent.rb +1 -1
  404. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.heat_rejection.json +9 -0
  405. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.spc_typ.json +1946 -1106
  406. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/data/ze_aedg_multifamily.water_heaters.json +2 -2
  407. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirLoopHVAC.rb +3 -6
  408. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.Model.rb +4 -4
  409. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.PlantLoop.rb +1 -1
  410. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.ZoneHVACComponent.rb +1 -1
  411. data/lib/openstudio-standards/standards/cbes/cbes.Model.rb +1 -3
  412. data/lib/openstudio-standards/standards/cbes/cbes.rb +1 -1
  413. data/lib/openstudio-standards/standards/deer/deer.AirLoopHVAC.rb +8 -13
  414. data/lib/openstudio-standards/standards/deer/deer.Model.rb +2 -2
  415. data/lib/openstudio-standards/standards/deer/deer.PlanarSurface.rb +2 -0
  416. data/lib/openstudio-standards/standards/deer/deer.Space.rb +1 -1
  417. data/lib/openstudio-standards/standards/deer/deer_2011/deer_2011.rb +0 -1
  418. data/lib/openstudio-standards/standards/deer/deer_2014/deer_2014.Space.rb +0 -1
  419. data/lib/openstudio-standards/standards/deer/deer_2014/deer_2014.rb +0 -1
  420. data/lib/openstudio-standards/standards/deer/deer_2015/deer_2015.Space.rb +0 -1
  421. data/lib/openstudio-standards/standards/deer/deer_2017/deer_2017.Space.rb +0 -1
  422. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.AirLoopHVAC.rb +1 -1
  423. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.FanVariableVolume.rb +1 -1
  424. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.Space.rb +0 -1
  425. data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.AirLoopHVAC.rb +1 -1
  426. data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.FanVariableVolume.rb +1 -1
  427. data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.Space.rb +0 -1
  428. data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.AirLoopHVAC.rb +1 -1
  429. data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.FanVariableVolume.rb +1 -1
  430. data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.Space.rb +0 -1
  431. data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.AirLoopHVAC.rb +1 -1
  432. data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.FanVariableVolume.rb +1 -1
  433. data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.Space.rb +0 -1
  434. data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.AirLoopHVAC.rb +1 -1
  435. data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.FanVariableVolume.rb +1 -1
  436. data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.Space.rb +0 -1
  437. data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.AirLoopHVAC.rb +1 -1
  438. data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.FanVariableVolume.rb +1 -1
  439. data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.Space.rb +0 -1
  440. data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.AirLoopHVAC.rb +1 -1
  441. data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.FanVariableVolume.rb +1 -1
  442. data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.Space.rb +0 -1
  443. data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.AirLoopHVAC.rb +1 -1
  444. data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.FanVariableVolume.rb +1 -1
  445. data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.Space.rb +0 -1
  446. data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.AirLoopHVAC.rb +1 -1
  447. data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.FanVariableVolume.rb +1 -1
  448. data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.Space.rb +0 -1
  449. data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.AirLoopHVAC.rb +1 -1
  450. data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.FanVariableVolume.rb +1 -1
  451. data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.Space.rb +0 -1
  452. data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.AirLoopHVAC.rb +1 -1
  453. data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.FanVariableVolume.rb +1 -1
  454. data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.Space.rb +0 -1
  455. data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.AirLoopHVAC.rb +1 -1
  456. data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.FanVariableVolume.rb +1 -1
  457. data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.Space.rb +0 -1
  458. data/lib/openstudio-standards/standards/icc_iecc/icc_iecc_2015/icc_iecc_2015.rb +0 -1
  459. data/lib/openstudio-standards/standards/necb/BTAP1980TO2010/btap_1980to2010.rb +2 -18
  460. data/lib/openstudio-standards/standards/necb/BTAP1980TO2010/data/space_types.json +1677 -1005
  461. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/btap_pre1980.rb +87 -15
  462. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/building_envelope.rb +31 -19
  463. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/curves.json +75 -0
  464. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/heat_pumps.json +16 -16
  465. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/space_types.json +1677 -1005
  466. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_3_and_8_single_speed.rb +16 -2
  467. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_4.rb +15 -0
  468. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +14 -0
  469. data/lib/openstudio-standards/standards/necb/ECMS/data/boiler_set.json +29 -0
  470. data/lib/openstudio-standards/standards/necb/ECMS/data/curves.json +913 -0
  471. data/lib/openstudio-standards/standards/necb/ECMS/data/equip_eff_lim.json +52 -0
  472. data/lib/openstudio-standards/standards/necb/ECMS/data/erv.json +109 -0
  473. data/lib/openstudio-standards/standards/necb/ECMS/data/furnace_set.json +23 -0
  474. data/lib/openstudio-standards/standards/necb/ECMS/data/heat_pumps.json +803 -0
  475. data/lib/openstudio-standards/standards/necb/ECMS/data/heat_pumps_heating.json +787 -0
  476. data/lib/openstudio-standards/standards/necb/ECMS/data/pv.json +112 -0
  477. data/lib/openstudio-standards/standards/necb/ECMS/data/shw_set.json +29 -0
  478. data/lib/openstudio-standards/standards/necb/ECMS/data/unitary_acs.json +50 -0
  479. data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +100 -0
  480. data/lib/openstudio-standards/standards/necb/ECMS/erv.rb +33 -0
  481. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +1729 -0
  482. data/lib/openstudio-standards/standards/necb/ECMS/nv.rb +189 -0
  483. data/lib/openstudio-standards/standards/necb/ECMS/pv_ground.rb +104 -0
  484. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +68 -33
  485. data/lib/openstudio-standards/standards/necb/NECB2011/beps_compliance_path.rb +24 -13
  486. data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +110 -99
  487. data/lib/openstudio-standards/standards/necb/NECB2011/data/constants.json +24 -24
  488. data/lib/openstudio-standards/standards/necb/NECB2011/data/curves.json +50 -0
  489. data/lib/openstudio-standards/standards/necb/NECB2011/data/erv.json +31 -0
  490. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LowriseApartment.osm +39278 -0
  491. data/lib/openstudio-standards/standards/necb/NECB2011/data/led_lighting_data.json +2028 -0
  492. data/lib/openstudio-standards/standards/necb/NECB2011/data/space_types.json +1745 -1297
  493. data/lib/openstudio-standards/standards/necb/NECB2011/daylighting_control.md +70 -0
  494. data/lib/openstudio-standards/standards/necb/NECB2011/demand_controlled_ventilation.md +46 -0
  495. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_multi_speed.rb +69 -107
  496. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_single_speed.rb +41 -2
  497. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_2_and_5.rb +15 -0
  498. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +139 -141
  499. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +38 -2
  500. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +13 -0
  501. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +12 -0
  502. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +492 -240
  503. data/lib/openstudio-standards/standards/necb/NECB2011/led_lighting.md +51 -0
  504. data/lib/openstudio-standards/standards/necb/NECB2011/lighting.rb +75 -9
  505. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +1229 -37
  506. data/lib/openstudio-standards/standards/necb/NECB2011/nv.md +74 -0
  507. data/lib/openstudio-standards/standards/necb/NECB2011/pv_ground.md +44 -0
  508. data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +11 -3
  509. data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/qaqc_resources/neb_end_use_prices.csv +39 -84
  510. data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +1 -1
  511. data/lib/openstudio-standards/standards/necb/NECB2015/data/led_lighting_data.json +2883 -0
  512. data/lib/openstudio-standards/standards/necb/NECB2015/data/space_types.json +2554 -1916
  513. data/lib/openstudio-standards/standards/necb/NECB2015/necb_2015.rb +32 -1
  514. data/lib/openstudio-standards/standards/necb/NECB2017/data/led_lighting_data.json +2883 -0
  515. data/lib/openstudio-standards/standards/necb/NECB2017/data/space_types.json +2554 -1916
  516. data/lib/openstudio-standards/standards/necb/NECB2017/necb_2017.rb +29 -0
  517. data/lib/openstudio-standards/standards/oeesc/oeesc_2014/oeesc_2014.rb +0 -1
  518. data/lib/openstudio-standards/standards/standard.rb +6 -5
  519. data/lib/openstudio-standards/utilities/Add_template_field_to_json.rb +3 -3
  520. data/lib/openstudio-standards/utilities/convert_surfaces_to_adiabatic_necb_8426.rb +54 -54
  521. data/lib/openstudio-standards/utilities/generate_prototype_database.rb +2 -2
  522. data/lib/openstudio-standards/utilities/generate_space_types.rb +3 -3
  523. data/lib/openstudio-standards/utilities/logging.rb +7 -7
  524. data/lib/openstudio-standards/utilities/necb_to_epw_map.rb +14 -14
  525. data/lib/openstudio-standards/utilities/os_sim_extract.rb +25 -25
  526. data/lib/openstudio-standards/utilities/rename_surfaces.rb +10 -13
  527. data/lib/openstudio-standards/utilities/round_surf_coords.rb +18 -20
  528. data/lib/openstudio-standards/utilities/sched_create.rb +39 -41
  529. data/lib/openstudio-standards/utilities/set_mult_to_adiabatic.rb +31 -31
  530. data/lib/openstudio-standards/utilities/simulation.rb +13 -21
  531. data/lib/openstudio-standards/utilities/speacetype_map_converter.rb +10 -11
  532. data/lib/openstudio-standards/utilities/sqlfile.rb +6 -8
  533. data/lib/openstudio-standards/utilities/template_measure/measure.rb +108 -0
  534. data/lib/openstudio-standards/utilities/template_measure/measure.xml +162 -0
  535. data/lib/openstudio-standards/utilities/template_measure/resources/BTAPMeasureHelper.rb +448 -0
  536. data/lib/openstudio-standards/utilities/template_measure/tests/test.rb +160 -0
  537. data/lib/openstudio-standards/utilities/weatherData1_xlsx_to_json.rb +23 -26
  538. data/lib/openstudio-standards/version.rb +1 -1
  539. data/lib/openstudio-standards/weather/Weather.Model.rb +112 -87
  540. data/lib/openstudio-standards/weather/Weather.stat_file.rb +17 -17
  541. metadata +236 -2
@@ -0,0 +1,51 @@
1
+ # High Performance LED Lighting Measure
2
+ This measure adds a new lighting definition regarding LED lighting in each space of the model,
3
+ and replace the existing lighting definition with the LED lighting definition in each space.
4
+
5
+ # Description
6
+ The workflow of this measure is as follows:
7
+ 1. Define a new LED lighting definition for each space.
8
+ 2. Use the new LED lighting definition instead of the existing lighting definition in each space.
9
+
10
+ # Approach
11
+ This measure follows the functions already existed in the BTAP environment with respect to setting lights in spaces.<br>
12
+ However, a new function called **set_lighting_per_area_led_lighting** has been created in necb_2011.rb to set lighting power density (LPD) for LED lighting.<br>
13
+ Moreover, the **apply_standard_lights** function (in lighting.rb) has been modified to set the three fields of
14
+ fraction radiant, fraction visible, and return air fraction for LED lighting.<br>
15
+ Furthermore, two variables have been added to the **apply_standard_lights** function:
16
+ (1) **lights_type** to specify which lighting type to be used in the model. The lighting types that a user can choose are: CFL, LED.
17
+ (2) **scale** to specify whether LPD default values are used or a fraction of LPD default values are used in the model.
18
+
19
+ # Testing Plan
20
+ * This measure has been called in the **apply_loads** function (in necb_2011.rb) -> **model_add_loads** function (in necb_2011.rb)
21
+ -> **space_type_apply_internal_loads** function (in beps_compliance_path.rb) -> **apply_standard_lights** function (in lighting.rb).
22
+ * This measure was tested for NECB 2011 full service restaurant archetype.
23
+ * Note that regarding atriums' heights, since none of the archetypes has atriums,
24
+ the testing procedure was performed for the space type including the "Dining" term and with some tweaks in the LPD equations.
25
+
26
+ # Waiting On
27
+ * There are four fields in the OS:Lights:Definition object that need to be updated in standards/lib/openstudio-standards/standards/necb/NECB2011/**data/led_lighting_data.json**, as follows:
28
+ 1. LPD (W/m<sup>2</sup>)
29
+ 2. Fraction Radiant
30
+ 3. Fraction Visible
31
+ 4. Return Air Fraction
32
+
33
+ * Note that three xlsx files (**led_lighting_data_necb2011.xlsx**, **led_lighting_data_necb2015.xlsx**, **led_lighting_data_necb2017.xlsx**)
34
+ should be updated as per Mike Lubun's xlsx files for lighting sets.
35
+ * To this end, openstudio-standards/lib/openstudio-standards/utilities/**LEDLightingData_xlsx_to_json.rb** can be used to convert the xlsx files to json format.
36
+ * Once the openstudio-standards/lib/openstudio-standards/**btap/led_lighting_data.json** file is generated using LEDLightingData_xlsx_to_json.rb,
37
+ openstudio-standards/lib/openstudio-standards/standards/necb/NECB2011/**data/led_lighting_data.json** should be updated manually (copy and paste from **btap/led_lighting_data.json**).
38
+
39
+ # Files Added/Modified
40
+ * Files have been modified:
41
+ * **necb_2011.rb**
42
+ * **beps_compliance_path.rb**
43
+ * **lighting.rb**
44
+ * Files have been added:
45
+ * **led_lighting.md**
46
+ * openstudio-standards/lib/openstudio-standards/utilities/**LEDLightingData_xlsx_to_json.rb**
47
+ * openstudio-standards/lib/openstudio-standards/btap/**led_lighting_data_necb2011.xlsx**
48
+ * openstudio-standards/lib/openstudio-standards/btap/**led_lighting_data_necb2015.xlsx**
49
+ * openstudio-standards/lib/openstudio-standards/btap/**led_lighting_data_necb2017.xlsx**
50
+ * openstudio-standards/lib/openstudio-standards/**btap/led_lighting_data.json**
51
+ * openstudio-standards/lib/openstudio-standards/standards/necb/NECB2011/**data/led_lighting_data.json**
@@ -1,5 +1,28 @@
1
1
  class NECB2011
2
- def apply_standard_lights(set_lights, space_type, space_type_properties)
2
+
3
+ def apply_standard_lights(set_lights: true,
4
+ space_type:,
5
+ space_type_properties:,
6
+ lights_type:,
7
+ lights_scale:)
8
+
9
+ ##### Remove leading or trailing whitespace in case users add them in inputs
10
+ if lights_scale.instance_of?(String)
11
+ lights_scale = lights_scale.strip
12
+ end
13
+
14
+ if lights_type.nil? || lights_type == 'none'
15
+ lights_type = 'NECB_Default'
16
+ end
17
+ if lights_scale.nil? || lights_scale == 'none' || lights_scale == 'NECB_Default'
18
+ lights_scale = 1.0
19
+ end
20
+
21
+ ##### Convert a string to a float
22
+ if lights_scale.instance_of?(String)
23
+ lights_scale = lights_scale.to_f
24
+ end
25
+
3
26
  lights_have_info = false
4
27
  lighting_per_area = space_type_properties['lighting_per_area'].to_f
5
28
  lighting_per_person = space_type_properties['lighting_per_person'].to_f
@@ -7,8 +30,27 @@ class NECB2011
7
30
  lights_frac_radiant = space_type_properties['lighting_fraction_radiant'].to_f
8
31
  lights_frac_visible = space_type_properties['lighting_fraction_visible'].to_f
9
32
  lights_frac_replaceable = space_type_properties['lighting_fraction_replaceable'].to_f
10
- lights_have_info = true unless lighting_per_area.zero?
11
- lights_have_info = true unless lighting_per_person.zero?
33
+ lights_have_info = true if !lighting_per_area.zero? or !lighting_per_person.zero?
34
+
35
+
36
+ ##### NOTE: Reference for LED lighting's return air, radiant, and visible fraction values is: page 142, NREL (2014), "Proven Energy-Saving Technologies for Commercial Properties", available at https://www.nrel.gov/docs/fy15osti/63807.pdf
37
+ if lights_type == 'LED'
38
+ led_lights_have_info = false
39
+ led_spacetype_data = @standards_data['tables']['led_lighting_data']['table']
40
+ standards_building_type = space_type.standardsBuildingType.is_initialized ? space_type.standardsBuildingType.get : nil
41
+ standards_space_type = space_type.standardsSpaceType.is_initialized ? space_type.standardsSpaceType.get : nil
42
+ led_space_type_properties = led_spacetype_data.detect { |s| (s['building_type'] == standards_building_type) && (s['space_type'] == standards_space_type) }
43
+ if led_space_type_properties.nil?
44
+ raise("#{standards_building_type} for #{standards_space_type} was not found please verify the led lighting database names match the space type names.")
45
+ end
46
+
47
+ lighting_per_area_led_lighting = led_space_type_properties['lighting_per_area'].to_f
48
+ lights_frac_to_return_air_led_lighting = led_space_type_properties['lighting_fraction_to_return_air'].to_f
49
+ lights_frac_radiant_led_lighting = led_space_type_properties['lighting_fraction_radiant'].to_f
50
+ lights_frac_visible_led_lighting = led_space_type_properties['lighting_fraction_visible'].to_f
51
+ led_lights_have_info = true unless lighting_per_area_led_lighting.zero?
52
+
53
+ end
12
54
 
13
55
  if set_lights && lights_have_info
14
56
 
@@ -16,9 +58,15 @@ class NECB2011
16
58
  instances = space_type.lights.sort
17
59
  if instances.size.zero?
18
60
  definition = OpenStudio::Model::LightsDefinition.new(space_type.model)
19
- definition.setName("#{space_type.name} Lights Definition")
61
+ if lights_type == 'NECB_Default'
62
+ definition.setName("#{space_type.name} Lights Definition")
63
+ elsif lights_type == 'LED'
64
+ definition.setName("#{space_type.name} Lights Definition - LED lighting")
65
+ end
66
+ # puts definition.name().to_s
20
67
  instance = OpenStudio::Model::Lights.new(definition)
21
68
  instance.setName("#{space_type.name} Lights")
69
+ # puts instance.name.to_s
22
70
  instance.setSpaceType(space_type)
23
71
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.SpaceType', "#{space_type.name} had no lights, one has been created.")
24
72
  instances << instance
@@ -34,20 +82,39 @@ class NECB2011
34
82
  space_type.lights.sort.each do |inst|
35
83
  definition = inst.lightsDefinition
36
84
  unless lighting_per_area.zero?
37
- set_lighting_per_area(space_type, definition, lighting_per_area)
85
+ if lights_type == 'NECB_Default'
86
+ set_lighting_per_area(space_type, definition, lighting_per_area)
87
+ elsif lights_type == 'LED'
88
+ set_lighting_per_area_led_lighting(space_type: space_type,
89
+ definition: definition,
90
+ lighting_per_area_led_lighting: lighting_per_area_led_lighting,
91
+ lights_scale: lights_scale)
92
+ end
38
93
  end
39
94
  unless lighting_per_person.zero?
40
95
  definition.setWattsperPerson(OpenStudio.convert(lighting_per_person.to_f, 'W/person', 'W/person').get)
41
96
  OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.SpaceType', "#{space_type.name} set lighting to #{lighting_per_person} W/person.")
42
97
  end
43
98
  unless lights_frac_to_return_air.zero?
44
- definition.setReturnAirFraction(lights_frac_to_return_air)
99
+ if lights_type == 'NECB_Default'
100
+ definition.setReturnAirFraction(lights_frac_to_return_air)
101
+ elsif lights_type == 'LED'
102
+ definition.setReturnAirFraction(lights_frac_to_return_air_led_lighting)
103
+ end
45
104
  end
46
105
  unless lights_frac_radiant.zero?
47
- definition.setFractionRadiant(lights_frac_radiant)
106
+ if lights_type == 'NECB_Default'
107
+ definition.setFractionRadiant(lights_frac_radiant)
108
+ elsif lights_type == 'LED'
109
+ definition.setFractionRadiant(lights_frac_radiant_led_lighting)
110
+ end
48
111
  end
49
112
  unless lights_frac_visible.zero?
50
- definition.setFractionVisible(lights_frac_visible)
113
+ if lights_type == 'NECB_Default'
114
+ definition.setFractionVisible(lights_frac_visible)
115
+ elsif lights_type == 'LED'
116
+ definition.setFractionVisible(lights_frac_visible_led_lighting)
117
+ end
51
118
  end
52
119
  # unless lights_frac_replaceable.zero?
53
120
  # definition.setFractionReplaceable(lights_frac_replaceable)
@@ -70,7 +137,6 @@ class NECB2011
70
137
  additional_lights.setName("#{space_type.name} Additional Lights")
71
138
  additional_lights.setSpaceType(space_type)
72
139
  end
73
-
74
140
  end
75
141
  end
76
142
 
@@ -8,6 +8,19 @@ class NECB2011 < Standard
8
8
  attr_accessor :space_type_map
9
9
  attr_accessor :space_multiplier_map
10
10
 
11
+ # This is a helper method to convert arguments that may support 'NECB_Default, and nils to convert to float'
12
+ def convert_arg_to_f(variable:,default:)
13
+ if variable.instance_of?(Numeric)
14
+ return variable
15
+ elsif variable.nil? or variable == 'NECB_Default'
16
+ return default
17
+ elsif variable.instance_of?(String)
18
+ variable = variable.strip
19
+ return variable.to_f
20
+ end
21
+ end
22
+
23
+
11
24
  def get_standards_table(table_name:)
12
25
  if @standards_data["tables"][table_name].nil?
13
26
  message = "Could not find table #{table_name} in database."
@@ -40,7 +53,7 @@ class NECB2011 < Standard
40
53
  else
41
54
  path = "#{File.dirname(__FILE__)}/../common/"
42
55
  raise ('Could not find common folder') unless Dir.exist?(path)
43
- files = Dir.glob("#{path}/*.json").select {|e| File.file? e}
56
+ files = Dir.glob("#{path}/*.json").select { |e| File.file? e }
44
57
  files.each do |file|
45
58
  data = JSON.parse(File.read(file))
46
59
  if not data["tables"].nil?
@@ -62,7 +75,7 @@ class NECB2011 < Standard
62
75
  end
63
76
  end
64
77
  else
65
- files = Dir.glob("#{File.dirname(__FILE__)}/data/*.json").select {|e| File.file? e}
78
+ files = Dir.glob("#{File.dirname(__FILE__)}/data/*.json").select { |e| File.file? e }
66
79
  files.each do |file|
67
80
  data = JSON.parse(File.read(file))
68
81
  if not data["tables"].nil?
@@ -117,7 +130,7 @@ class NECB2011 < Standard
117
130
  end
118
131
 
119
132
  def get_all_spacetype_names
120
- return @standards_data['space_types'].map {|space_types| [space_types['building_type'], space_types['space_type']]}
133
+ return @standards_data['space_types'].map { |space_types| [space_types['building_type'], space_types['space_type']] }
121
134
  end
122
135
 
123
136
  # Enter in [latitude, longitude] for each loc and this method will return the distance.
@@ -129,8 +142,8 @@ class NECB2011 < Standard
129
142
  dlat_rad = (loc2[0] - loc1[0]) * rad_per_deg # Delta, converted to rad
130
143
  dlon_rad = (loc2[1] - loc1[1]) * rad_per_deg
131
144
 
132
- lat1_rad, lon1_rad = loc1.map {|i| i * rad_per_deg}
133
- lat2_rad, lon2_rad = loc2.map {|i| i * rad_per_deg}
145
+ lat1_rad, lon1_rad = loc1.map { |i| i * rad_per_deg }
146
+ lat2_rad, lon2_rad = loc2.map { |i| i * rad_per_deg }
134
147
 
135
148
  a = Math.sin(dlat_rad / 2) ** 2 + Math.cos(lat1_rad) * Math.cos(lat2_rad) * Math.sin(dlon_rad / 2) ** 2
136
149
  c = 2 * Math::atan2(Math::sqrt(a), Math::sqrt(1 - a))
@@ -163,19 +176,101 @@ class NECB2011 < Standard
163
176
  end
164
177
 
165
178
 
166
- # This method is a wrapper to create the 16 archetypes easily.
179
+ # This method is a wrapper to create the 16 archetypes easily. # 37 args
167
180
  def model_create_prototype_model(template:,
168
181
  building_type:,
169
182
  epw_file:,
170
183
  debug: false,
171
184
  sizing_run_dir: Dir.pwd,
172
- primary_heating_fuel: 'DefaultFuel')
185
+ primary_heating_fuel: 'DefaultFuel',
186
+ dcv_type: 'NECB_Default',
187
+ lights_type: 'NECB_Default',
188
+ lights_scale: 1.0,
189
+ daylighting_type: 'NECB_Default',
190
+ ecm_system_name: 'NECB_Default',
191
+ erv_package: 'NECB_Default',
192
+ boiler_eff: nil,
193
+ unitary_cop: nil,
194
+ furnace_eff: nil,
195
+ shw_eff: nil,
196
+ ext_wall_cond: nil,
197
+ ext_floor_cond: nil,
198
+ ext_roof_cond: nil,
199
+ ground_wall_cond: nil,
200
+ ground_floor_cond: nil,
201
+ ground_roof_cond: nil,
202
+ door_construction_cond: nil,
203
+ fixed_window_cond: nil,
204
+ glass_door_cond: nil,
205
+ overhead_door_cond: nil,
206
+ skylight_cond: nil,
207
+ glass_door_solar_trans: nil,
208
+ fixed_wind_solar_trans: nil,
209
+ skylight_solar_trans: nil,
210
+ rotation_degrees: nil,
211
+ fdwr_set: -1.0,
212
+ srr_set: -1.0,
213
+ nv_type: nil,
214
+ nv_opening_fraction: nil,
215
+ nv_Tout_min: nil,
216
+ nv_Delta_Tin_Tout: nil,
217
+ scale_x: nil,
218
+ scale_y: nil,
219
+ scale_z: nil,
220
+ pv_ground_type: nil,
221
+ pv_ground_total_area_pv_panels_m2: nil,
222
+ pv_ground_tilt_angle: nil,
223
+ pv_ground_azimuth_angle: nil,
224
+ pv_ground_module_description: nil
225
+ )
226
+
173
227
 
174
228
  model = load_building_type_from_library(building_type: building_type)
175
229
  return model_apply_standard(model: model,
176
230
  epw_file: epw_file,
177
231
  sizing_run_dir: sizing_run_dir,
178
- primary_heating_fuel: primary_heating_fuel)
232
+ primary_heating_fuel: primary_heating_fuel,
233
+ dcv_type: dcv_type, # Four options: (1) 'NECB_Default', (2) 'No_DCV', (3) 'Occupancy_based_DCV' , (4) 'CO2_based_DCV'
234
+ lights_type: lights_type, # Two options: (1) 'NECB_Default', (2) 'LED'
235
+ lights_scale: lights_scale,
236
+ daylighting_type: daylighting_type, # Two options: (1) 'NECB_Default', (2) 'add_daylighting_controls'
237
+ ecm_system_name: ecm_system_name,
238
+ erv_package: erv_package,
239
+ boiler_eff: boiler_eff,
240
+ unitary_cop: unitary_cop,
241
+ furnace_eff: furnace_eff,
242
+ shw_eff: shw_eff,
243
+ ext_wall_cond: ext_wall_cond,
244
+ ext_floor_cond: ext_floor_cond,
245
+ ext_roof_cond: ext_roof_cond,
246
+ ground_wall_cond: ground_wall_cond,
247
+ ground_floor_cond: ground_floor_cond,
248
+ ground_roof_cond: ground_roof_cond,
249
+ door_construction_cond: door_construction_cond,
250
+ fixed_window_cond: fixed_window_cond,
251
+ glass_door_cond: glass_door_cond,
252
+ overhead_door_cond: overhead_door_cond,
253
+ skylight_cond: skylight_cond,
254
+ glass_door_solar_trans: glass_door_solar_trans,
255
+ fixed_wind_solar_trans: fixed_wind_solar_trans,
256
+ skylight_solar_trans: skylight_solar_trans,
257
+ rotation_degrees: rotation_degrees,
258
+ fdwr_set: fdwr_set,
259
+ srr_set: srr_set,
260
+ nv_type: 'NECB_Default', # Two options: (1) nil/none/false/'NECB_Default', (2) true
261
+ nv_opening_fraction: nv_opening_fraction, #options: (1) nil/none/false (2) 'NECB_Default' (i.e. 0.1)
262
+ nv_Tout_min: nv_Tout_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)
263
+ nv_Delta_Tin_Tout: nv_Delta_Tin_Tout, #options: (1) nil/none/false (2) 'NECB_Default' (i.e. 1.0 based on inputs from Michel Tardif re a real school in QC)
264
+ scale_x: scale_x,
265
+ scale_y: scale_y,
266
+ scale_z: scale_z,
267
+ pv_ground_type: 'NECB_Default', # Two options: (1) nil/none/false/'NECB_Default', (2) true
268
+ pv_ground_total_area_pv_panels_m2: pv_ground_total_area_pv_panels_m2, # Options: (1) nil/none/false, (2) 'NECB_Default' (i.e. building footprint), (3) area value (e.g. 50)
269
+ pv_ground_tilt_angle: pv_ground_tilt_angle, # Options: (1) nil/none/false, (2) 'NECB_Default' (i.e. latitude), (3) tilt angle value (e.g. 20)
270
+ pv_ground_azimuth_angle: pv_ground_azimuth_angle, # Options: (1) nil/none/false, (2) 'NECB_Default' (i.e. south), (3) azimuth angle value (e.g. 90)
271
+ pv_ground_module_description: pv_ground_module_description # Options: (1) nil/none/false, (2) 'NECB_Default' (i.e. Standard), (3) other options ('Standard', 'Premium', ThinFilm')
272
+ )
273
+
179
274
  end
180
275
 
181
276
  def load_building_type_from_library(building_type:)
@@ -191,25 +286,218 @@ class NECB2011 < Standard
191
286
  def model_apply_standard(model:,
192
287
  epw_file:,
193
288
  sizing_run_dir: Dir.pwd,
194
- primary_heating_fuel: 'DefaultFuel')
289
+ primary_heating_fuel: 'DefaultFuel',
290
+ dcv_type: 'NECB_Default',
291
+ lights_type: 'NECB_Default',
292
+ lights_scale: 'NECB_Default',
293
+ daylighting_type: 'NECB_Default',
294
+ ecm_system_name: 'NECB_Default',
295
+ erv_package: 'NECB_Default',
296
+ boiler_eff: nil,
297
+ furnace_eff: nil,
298
+ unitary_cop: nil,
299
+ shw_eff: nil,
300
+ ext_wall_cond: nil,
301
+ ext_floor_cond: nil,
302
+ ext_roof_cond: nil,
303
+ ground_wall_cond: nil,
304
+ ground_floor_cond: nil,
305
+ ground_roof_cond: nil,
306
+ door_construction_cond: nil,
307
+ fixed_window_cond: nil,
308
+ glass_door_cond: nil,
309
+ overhead_door_cond: nil,
310
+ skylight_cond: nil,
311
+ glass_door_solar_trans: nil,
312
+ fixed_wind_solar_trans: nil,
313
+ skylight_solar_trans: nil,
314
+ fdwr_set: nil,
315
+ srr_set: nil,
316
+ rotation_degrees: nil,
317
+ scale_x: nil,
318
+ scale_y: nil,
319
+ scale_z: nil,
320
+ nv_type: nil,
321
+ nv_opening_fraction: nil,
322
+ nv_Tout_min: nil,
323
+ nv_Delta_Tin_Tout: nil,
324
+ pv_ground_type: nil,
325
+ pv_ground_total_area_pv_panels_m2: nil ,
326
+ pv_ground_tilt_angle: nil,
327
+ pv_ground_azimuth_angle: nil,
328
+ pv_ground_module_description: nil
329
+ )
330
+ #clean model..
331
+ model = remove_all_HVAC(model)
332
+ model.getThermalZones.sort.each {|zone| zone.setUseIdealAirLoads(true)}
333
+ model.getZoneHVACPackagedTerminalAirConditioners.each(&:remove)
334
+ model.getCoilCoolingDXSingleSpeeds.each(&:remove)
335
+ model.getZoneHVACBaseboardConvectiveWaters.each(&:remove)
336
+ model.getAirLoopHVACZoneMixers.each(&:remove)
337
+ model.getAirLoopHVACZoneSplitters.each(&:remove)
338
+ model.getAirTerminalSingleDuctConstantVolumeNoReheats.each(&:remove)
339
+ model.getWaterUseEquipmentDefinitions.each(&:remove)
340
+ model.getWaterUseEquipments.each(&:remove)
341
+ model.getWaterUseConnectionss.each(&:remove)
342
+
343
+ rotation_degrees = convert_arg_to_f(variable: rotation_degrees,default: 0.0)
344
+ BTAP::Geometry::rotate_building(model: model,degrees: rotation_degrees) unless rotation_degrees == 0.0
345
+ scale_x = convert_arg_to_f(variable: scale_x,default: 1.0)
346
+ scale_y = convert_arg_to_f(variable: scale_y,default: 1.0)
347
+ scale_z = convert_arg_to_f(variable: scale_z,default: 1.0)
348
+ if scale_x != 1.0 || scale_y != 1.0 || scale_z != 1.0
349
+ BTAP::Geometry::scale_model(model, scale_x, scale_x, scale_x)
350
+ end
351
+
352
+
353
+ fdwr_set = convert_arg_to_f(variable: fdwr_set,default: -1)
354
+ srr_set = convert_arg_to_f(variable: srr_set,default: -1)
355
+
356
+
195
357
  apply_weather_data(model: model, epw_file: epw_file)
196
- apply_loads(model: model)
197
- apply_envelope(model: model)
198
- apply_fdwr_srr_daylighting(model: model)
199
- apply_auto_zoning(model: model, sizing_run_dir: sizing_run_dir)
200
- apply_systems(model: model, primary_heating_fuel: primary_heating_fuel, sizing_run_dir: sizing_run_dir)
201
- apply_standard_efficiencies(model: model, sizing_run_dir: sizing_run_dir)
202
- model = apply_loop_pump_power(model: model, sizing_run_dir: sizing_run_dir)
358
+ apply_loads(model: model, lights_type: lights_type, lights_scale: lights_scale)
359
+ apply_envelope(model: model,
360
+ ext_wall_cond: ext_wall_cond,
361
+ ext_floor_cond: ext_floor_cond,
362
+ ext_roof_cond: ext_roof_cond,
363
+ ground_wall_cond: ground_wall_cond,
364
+ ground_floor_cond: ground_floor_cond,
365
+ ground_roof_cond: ground_roof_cond,
366
+ door_construction_cond: door_construction_cond,
367
+ fixed_window_cond: fixed_window_cond,
368
+ glass_door_cond: glass_door_cond,
369
+ overhead_door_cond: overhead_door_cond,
370
+ skylight_cond: skylight_cond,
371
+ glass_door_solar_trans: glass_door_solar_trans,
372
+ fixed_wind_solar_trans: fixed_wind_solar_trans,
373
+ skylight_solar_trans: skylight_solar_trans)
374
+ apply_fdwr_srr_daylighting(model: model,
375
+ fdwr_set: fdwr_set,
376
+ srr_set: srr_set)
377
+ apply_auto_zoning(model: model,
378
+ sizing_run_dir: sizing_run_dir,
379
+ lights_type: lights_type,
380
+ lights_scale: lights_scale)
381
+ apply_systems_and_efficiencies(model: model,
382
+ primary_heating_fuel: primary_heating_fuel,
383
+ sizing_run_dir: sizing_run_dir,
384
+ dcv_type: dcv_type,
385
+ ecm_system_name: ecm_system_name,
386
+ erv_package: erv_package,
387
+ boiler_eff: boiler_eff,
388
+ unitary_cop: unitary_cop,
389
+ furnace_eff: furnace_eff,
390
+ shw_eff: shw_eff,
391
+ daylighting_type: daylighting_type,
392
+ nv_type: nv_type,
393
+ nv_opening_fraction: nv_opening_fraction,
394
+ nv_Tout_min: nv_Tout_min,
395
+ nv_Delta_Tin_Tout: nv_Delta_Tin_Tout,
396
+ pv_ground_type: pv_ground_type,
397
+ pv_ground_total_area_pv_panels_m2: pv_ground_total_area_pv_panels_m2,
398
+ pv_ground_tilt_angle: pv_ground_tilt_angle,
399
+ pv_ground_azimuth_angle: pv_ground_azimuth_angle,
400
+ pv_ground_module_description: pv_ground_module_description
401
+ )
402
+
203
403
  return model
204
404
  end
205
405
 
206
- def apply_loads(model:)
207
- raise('validation of model failed.') unless validate_initial_model(model)
208
- raise('validation of spacetypes failed.') unless validate_and_upate_space_types(model)
406
+
407
+ def apply_systems_and_efficiencies(model:,
408
+ primary_heating_fuel:,
409
+ sizing_run_dir:,
410
+ dcv_type: 'NECB_Default',
411
+ ecm_system_name: 'NECB_Default',
412
+ erv_package: 'NECB_Default',
413
+ boiler_eff: nil,
414
+ furnace_eff: nil,
415
+ unitary_cop: nil,
416
+ shw_eff: nil,
417
+ daylighting_type: 'NECB_Default',
418
+ nv_type: nil,
419
+ nv_opening_fraction: nil,
420
+ nv_Tout_min: nil,
421
+ nv_Delta_Tin_Tout:nil,
422
+ pv_ground_type:,
423
+ pv_ground_total_area_pv_panels_m2:,
424
+ pv_ground_tilt_angle:,
425
+ pv_ground_azimuth_angle:,
426
+ pv_ground_module_description:
427
+ )
428
+
429
+ # Create ECM object.
430
+ ecm = ECMS.new
431
+
432
+ # -------- Systems Layout-----------
433
+
434
+ # Create Default Systems.
435
+ apply_systems(model: model, primary_heating_fuel: primary_heating_fuel, sizing_run_dir: sizing_run_dir)
436
+
437
+ # Apply new ECM system. Overwrite standard as required.
438
+ ecm.apply_system_ecm(model: model, ecm_system_name: ecm_system_name, template_standard: self, primary_heating_fuel: primary_heating_fuel)
439
+
440
+ # Apply ERV equipment as required.
441
+ ecm.apply_erv_ecm(model: model, erv_package: erv_package)
442
+
443
+
444
+ # -------- Performace, Efficiencies, Controls and Sensors ------------
445
+ #
446
+ # Set code standard equipment charecteristics.
447
+ sql_db_vars_map = apply_standard_efficiencies(model: model, sizing_run_dir: sizing_run_dir)
448
+ # Apply System
449
+ ecm.apply_system_efficiencies_ecm(model: model, ecm_system_name: ecm_system_name)
450
+
451
+ # Apply ECM ERV charecteristics as required. Part 2 of above ECM.
452
+ ecm.apply_erv_ecm_efficiency(model: model, erv_package: erv_package)
453
+ # Apply DCV as required
454
+ model_enable_demand_controlled_ventilation(model, dcv_type)
455
+ # Apply Boiler Efficiency
456
+ ecm.modify_boiler_efficiency(model: model, boiler_eff: boiler_eff)
457
+ # Apply Furnace Efficiency
458
+ ecm.modify_furnace_efficiency(model: model, furnace_eff: furnace_eff)
459
+ # Apply Unitary efficiency
460
+ ecm.modify_unitary_cop(model: model,unitary_cop: unitary_cop,sql_db_vars_map: sql_db_vars_map)
461
+ # Apply SHW Efficiency
462
+ ecm.modify_shw_efficiency(model: model, shw_eff: shw_eff)
463
+ # Apply daylight controls.
464
+ model_add_daylighting_controls(model) if daylighting_type == 'add_daylighting_controls'
465
+
466
+
467
+ # -------Pump sizing required by some vintages----------------
468
+ # Apply Pump power as required.
469
+ apply_loop_pump_power(model: model, sizing_run_dir: sizing_run_dir)
470
+
471
+ # -------Natural ventilation----------------
472
+ # Apply natural ventilation using simplified method.
473
+ ecm.apply_nv(model: model,
474
+ nv_type: nv_type,
475
+ nv_opening_fraction: nv_opening_fraction,
476
+ nv_Tout_min: nv_Tout_min,
477
+ nv_Delta_Tin_Tout: nv_Delta_Tin_Tout)
478
+
479
+ # -------Ground-mounted PV panels---------------- #Sara
480
+ # Apply ground-mounted PV panels as required.
481
+ ecm.apply_pv_ground(model: model,
482
+ pv_ground_type: pv_ground_type,
483
+ pv_ground_total_area_pv_panels_m2: pv_ground_total_area_pv_panels_m2,
484
+ pv_ground_tilt_angle: pv_ground_tilt_angle,
485
+ pv_ground_azimuth_angle: pv_ground_azimuth_angle,
486
+ pv_ground_module_description: pv_ground_module_description)
487
+
488
+ end
489
+
490
+
491
+ def apply_loads(model:, lights_type: 'NECB_Default', lights_scale: 1.0, validate: true)
492
+ lights_scale = convert_arg_to_f(variable: lights_scale,default: 1.0)
493
+ if validate
494
+ raise('validation of model failed.') unless validate_initial_model(model)
495
+ raise('validation of spacetypes failed.') unless validate_and_upate_space_types(model)
496
+ end
209
497
  #this sets/stores the template version loads that the model uses.
210
498
  model.getBuilding.setStandardsTemplate(self.class.name)
211
499
  set_occ_sensor_spacetypes(model, @space_type_map)
212
- model_add_loads(model)
500
+ model_add_loads(model, lights_type, lights_scale)
213
501
  end
214
502
 
215
503
  def apply_weather_data(model:, epw_file:)
@@ -223,23 +511,44 @@ class NECB2011 < Standard
223
511
  end
224
512
 
225
513
  def apply_envelope(model:,
226
- properties: {
227
- 'outdoors_wall_conductance' => nil,
228
- 'outdoors_floor_conductance' => nil,
229
- 'outdoors_roofceiling_conductance' => nil,
230
- 'ground_wall_conductance' => nil,
231
- 'ground_floor_conductance' => nil,
232
- 'ground_roofceiling_conductance' => nil,
233
- 'outdoors_door_conductance' => nil,
234
- 'outdoors_fixedwindow_conductance' => nil
235
- })
514
+ ext_wall_cond: nil,
515
+ ext_floor_cond: nil,
516
+ ext_roof_cond: nil,
517
+ ground_wall_cond: nil,
518
+ ground_floor_cond: nil,
519
+ ground_roof_cond: nil,
520
+ door_construction_cond: nil,
521
+ fixed_window_cond: nil,
522
+ glass_door_cond: nil,
523
+ overhead_door_cond: nil,
524
+ skylight_cond: nil,
525
+ glass_door_solar_trans: nil,
526
+ fixed_wind_solar_trans: nil,
527
+ skylight_solar_trans: nil)
236
528
  raise('validation of model failed.') unless validate_initial_model(model)
237
529
  model_apply_infiltration_standard(model)
238
530
  model.getInsideSurfaceConvectionAlgorithm.setAlgorithm('TARP')
239
531
  model.getOutsideSurfaceConvectionAlgorithm.setAlgorithm('TARP')
240
532
  model_add_constructions(model)
241
- apply_standard_construction_properties(model: model, properties: properties)
533
+ apply_standard_construction_properties(model: model,
534
+ ext_wall_cond: ext_wall_cond,
535
+ ext_floor_cond: ext_floor_cond,
536
+ ext_roof_cond: ext_roof_cond,
537
+ ground_wall_cond: ground_wall_cond,
538
+ ground_floor_cond: ground_floor_cond,
539
+ ground_roof_cond: ground_roof_cond,
540
+ door_construction_cond: door_construction_cond,
541
+ fixed_window_cond: fixed_window_cond,
542
+ glass_door_cond: glass_door_cond,
543
+ overhead_door_cond: overhead_door_cond,
544
+ skylight_cond: skylight_cond,
545
+ glass_door_solar_trans: glass_door_solar_trans,
546
+ fixed_wind_solar_trans: fixed_wind_solar_trans,
547
+ skylight_solar_trans: skylight_solar_trans)
548
+
549
+
242
550
  model_create_thermal_zones(model, @space_multiplier_map)
551
+
243
552
  end
244
553
 
245
554
  # Thermal zones need to be set to determine conditioned spaces when applying fdwr and srr limits.
@@ -252,21 +561,75 @@ class NECB2011 < Standard
252
561
  # # <-3.1: Remove all the windows/skylights
253
562
  # # > 1: Do nothing
254
563
  def apply_fdwr_srr_daylighting(model:, fdwr_set: -1.0, srr_set: -1.0)
564
+ fdwr_set = -1.0 if fdwr_set == 'NECB_default' or fdwr_set.nil?
565
+ srr_set = -1.0 if srr_set == 'NECB_default' or srr_set.nil?
566
+ fdwr_set = fdwr_set.to_f
567
+ srr_set = srr_set.to_f
255
568
  apply_standard_window_to_wall_ratio(model: model, fdwr_set: fdwr_set)
256
569
  apply_standard_skylight_to_roof_ratio(model: model, srr_set: srr_set)
257
- model_add_daylighting_controls(model) # to be removed after refactor.
570
+ # model_add_daylighting_controls(model) # to be removed after refactor.
258
571
  end
259
572
 
260
- def apply_standard_efficiencies(model:, sizing_run_dir:)
573
+ def apply_standard_efficiencies(model:, sizing_run_dir:, dcv_type: 'NECB_Default')
261
574
  raise('validation of model failed.') unless validate_initial_model(model)
262
575
  climate_zone = 'NECB HDD Method'
263
576
  raise("sizing run 1 failed! check #{sizing_run_dir}") if model_run_sizing_run(model, "#{sizing_run_dir}/plant_loops") == false
264
577
  # This is needed for NECB2011 as a workaround for sizing the reheat boxes
265
- model.getAirTerminalSingleDuctVAVReheats.each {|iobj| air_terminal_single_duct_vav_reheat_set_heating_cap(iobj)}
578
+ model.getAirTerminalSingleDuctVAVReheats.each { |iobj| air_terminal_single_duct_vav_reheat_set_heating_cap(iobj) }
266
579
  # Apply the prototype HVAC assumptions
267
580
  model_apply_prototype_hvac_assumptions(model, nil, climate_zone)
268
581
  # Apply the HVAC efficiency standard
269
- model_apply_hvac_efficiency_standard(model, climate_zone)
582
+ sql_db_vars_map = {}
583
+ model_apply_hvac_efficiency_standard(model, climate_zone, sql_db_vars_map: sql_db_vars_map)
584
+ model_enable_demand_controlled_ventilation(model, dcv_type)
585
+ return sql_db_vars_map
586
+ end
587
+
588
+ # Shut off the system during unoccupied periods.
589
+ # During these times, systems will cycle on briefly
590
+ # if temperature drifts below setpoint. For systems
591
+ # with fan-powered terminals, the whole system
592
+ # (not just the terminal fans) will cycle on.
593
+ # Terminal-only night cycling is not used because the terminals cannot
594
+ # provide cooling, so terminal-only night cycling leads to excessive
595
+ # unmet cooling hours during unoccupied periods.
596
+ # If the system already has a schedule other than
597
+ # Always-On, no change will be made. If the system has
598
+ # an Always-On schedule assigned, a new schedule will be created.
599
+ # In this case, occupied is defined as the total percent
600
+ # occupancy for the loop for all zones served.
601
+ #
602
+ # @param min_occ_pct [Double] the fractional value below which
603
+ # the system will be considered unoccupied.
604
+ # @return [Bool] true if successful, false if not
605
+ def air_loop_hvac_enable_unoccupied_fan_shutoff(air_loop_hvac, min_occ_pct = 0.05)
606
+ # Set the system to night cycle
607
+ air_loop_hvac.setNightCycleControlType('CycleOnAny')
608
+
609
+ # Check if already using a schedule other than always on
610
+ avail_sch = air_loop_hvac.availabilitySchedule
611
+ unless avail_sch == air_loop_hvac.model.alwaysOnDiscreteSchedule
612
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "For #{air_loop_hvac.name}: Availability schedule is already set to #{avail_sch.name}. Will assume this includes unoccupied shut down; no changes will be made.")
613
+ return true
614
+ end
615
+
616
+ # Get the airloop occupancy schedule
617
+ loop_occ_sch = air_loop_hvac_get_occupancy_schedule(air_loop_hvac, occupied_percentage_threshold: min_occ_pct)
618
+ flh = schedule_ruleset_annual_equivalent_full_load_hrs(loop_occ_sch)
619
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "For #{air_loop_hvac.name}: Annual occupied hours = #{flh.round} hr/yr, assuming a #{min_occ_pct} occupancy threshold. This schedule will be used as the HVAC operation schedule.")
620
+
621
+ # Set HVAC availability schedule to follow occupancy
622
+ air_loop_hvac.setAvailabilitySchedule(loop_occ_sch)
623
+ air_loop_hvac.supplyComponents('OS:AirLoopHVAC:UnitaryHeatPump:AirToAir:MultiSpeed'.to_IddObjectType).each do |comp|
624
+ comp.to_AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.get.setAvailabilitySchedule(loop_occ_sch)
625
+ end
626
+
627
+ return true
628
+ end
629
+
630
+ # do not apply zone hvac ventilation control
631
+ def zone_hvac_component_occupancy_ventilation_control(zone_hvac_component)
632
+ return false
270
633
  end
271
634
 
272
635
  def apply_loop_pump_power(model:, sizing_run_dir:)
@@ -294,7 +657,7 @@ class NECB2011 < Standard
294
657
  #Now iterate though each vintage
295
658
  space_type_vintage_list.each do |template|
296
659
  #Create the standard object and get a list of all the spacetypes available for that vintage.
297
- standard_space_type_list = Standard.build(template).get_all_spacetype_names.map {|spacetype| [spacetype[0].to_s + '-' + spacetype[1].to_s]}
660
+ standard_space_type_list = Standard.build(template).get_all_spacetype_names.map { |spacetype| [spacetype[0].to_s + '-' + spacetype[1].to_s] }
298
661
  # set array to contain unknown spacetypes.
299
662
  unknown_spacetypes = []
300
663
  # iterate though all space types that the model is using
@@ -331,7 +694,7 @@ class NECB2011 < Standard
331
694
  bt_target_vintage_string = "#{self.class.name}_building_type"
332
695
  space_type_upgrade_map = @standards_data['space_type_upgrade_map']
333
696
  model.getSpaceTypes.sort.each do |st|
334
- space_type_map = space_type_upgrade_map.detect {|row| (row[st_model_vintage_string] == st.standardsSpaceType.get.to_s) && (row[bt_model_vintage_string] == st.standardsBuildingType.get.to_s)}
697
+ space_type_map = space_type_upgrade_map.detect { |row| (row[st_model_vintage_string] == st.standardsSpaceType.get.to_s) && (row[bt_model_vintage_string] == st.standardsBuildingType.get.to_s) }
335
698
  st.setStandardsBuildingType(space_type_map[bt_target_vintage_string].to_s.strip)
336
699
  raise('could not set buildingtype') unless st.setStandardsBuildingType(space_type_map[bt_target_vintage_string].to_s.strip)
337
700
  raise('could not set this') unless st.setStandardsSpaceType(space_type_map[st_target_vintage_string].to_s.strip)
@@ -518,4 +881,833 @@ class NECB2011 < Standard
518
881
  end
519
882
 
520
883
 
884
+ def model_add_daylighting_controls(model)
885
+
886
+ ##### Ask user's inputs for daylighting controls illuminance setpoint and number of stepped control steps.
887
+ ##### Note that the minimum number of stepped control steps is two steps as per NECB2011.
888
+ def daylighting_controls_settings(illuminance_setpoint: 500.0,
889
+ number_of_stepped_control_steps: 2)
890
+ return illuminance_setpoint, number_of_stepped_control_steps
891
+ end
892
+
893
+ ##### Find spaces with exterior fenestration including fixed window, operable window, and skylight.
894
+ daylight_spaces = []
895
+ model.getSpaces.sort.each do |space|
896
+ space.surfaces.sort.each do |surface|
897
+ surface.subSurfaces.sort.each do |subsurface|
898
+ if subsurface.outsideBoundaryCondition == "Outdoors" &&
899
+ (subsurface.subSurfaceType == "FixedWindow" ||
900
+ subsurface.subSurfaceType == "OperableWindow" ||
901
+ subsurface.subSurfaceType == "Skylight")
902
+ daylight_spaces << space
903
+ end #subsurface.outsideBoundaryCondition == "Outdoors" && (subsurface.subSurfaceType == "FixedWindow" || "OperableWindow")
904
+ end #surface.subSurfaces.each do |subsurface|
905
+ end #space.surfaces.each do |surface|
906
+ end #model.getSpaces.sort.each do |space|
907
+
908
+ ##### Remove duplicate spaces from the "daylight_spaces" array, as a daylighted space may have various fenestration types.
909
+ daylight_spaces = daylight_spaces.uniq
910
+ # puts daylight_spaces
911
+
912
+ ##### Create hashes for "Primary Sidelighted Areas", "Sidelighting Effective Aperture", "Daylighted Area Under Skylights",
913
+ ##### and "Skylight Effective Aperture" for the whole model.
914
+ ##### Each of these hashes will be used later in this function (i.e. model_add_daylighting_controls)
915
+ ##### to provide a dictionary of daylighted space names and the associated value (i.e. daylighted area or effective aperture).
916
+ primary_sidelighted_area_hash = {}
917
+ sidelighting_effective_aperture_hash = {}
918
+ daylighted_area_under_skylights_hash = {}
919
+ skylight_effective_aperture_hash = {}
920
+
921
+ ##### Calculate "Primary Sidelighted Areas" AND "Sidelighting Effective Aperture" as per NECB2011. #TODO: consider removing overlapped sidelighted area
922
+ daylight_spaces.sort.each do |daylight_space|
923
+ # puts daylight_space.name.to_s
924
+ primary_sidelighted_area = 0.0
925
+ area_weighted_vt_handle = 0.0
926
+ area_weighted_vt = 0.0
927
+ window_area_sum = 0.0
928
+
929
+ ##### Calculate floor area of the daylight_space and get floor vertices of the daylight_space (to be used for the calculation of daylight_space depth)
930
+ floor_surface = nil
931
+ floor_area = 0.0
932
+ floor_vertices = []
933
+ daylight_space.surfaces.sort.each do |surface|
934
+ if surface.surfaceType == "Floor"
935
+ floor_surface = surface
936
+ floor_area += surface.netArea
937
+ floor_vertices << surface.vertices
938
+ end
939
+ end
940
+
941
+ ##### Loop through the surfaces of each daylight_space to calculate primary_sidelighted_area and
942
+ ##### area-weighted visible transmittance and window_area_sum which are used to calculate sidelighting_effective_aperture
943
+ primary_sidelighted_area, area_weighted_vt_handle, window_area_sum =
944
+ get_parameters_sidelighting(daylight_space: daylight_space,
945
+ floor_surface: floor_surface,
946
+ floor_vertices: floor_vertices,
947
+ floor_area: floor_area,
948
+ primary_sidelighted_area: primary_sidelighted_area,
949
+ area_weighted_vt_handle: area_weighted_vt_handle,
950
+ window_area_sum: window_area_sum)
951
+
952
+ primary_sidelighted_area_hash[daylight_space.name.to_s] = primary_sidelighted_area
953
+
954
+ ##### Calculate area-weighted VT of glazing (this is used to calculate sidelighting effective aperture; see NECB2011: 4.2.2.10.).
955
+ area_weighted_vt = area_weighted_vt_handle / window_area_sum
956
+ sidelighting_effective_aperture_hash[daylight_space.name.to_s] = window_area_sum * area_weighted_vt / primary_sidelighted_area
957
+
958
+ end #daylight_spaces.each do |daylight_space|
959
+
960
+
961
+ ##### Calculate "Daylighted Area Under Skylights" AND "Skylight Effective Aperture"
962
+ daylight_spaces.sort.each do |daylight_space|
963
+ # puts daylight_space.name.to_s
964
+ skylight_area = 0.0
965
+ skylight_area_weighted_vt_handle = 0.0
966
+ skylight_area_weighted_vt = 0.0
967
+ skylight_area_sum = 0.0
968
+ daylighted_under_skylight_area = 0.0
969
+
970
+ ##### Loop through the surfaces of each daylight_space to calculate daylighted_area_under_skylights and skylight_effective_aperture for each daylight_space
971
+ daylighted_under_skylight_area, skylight_area_weighted_vt_handle, skylight_area_sum =
972
+ get_parameters_skylight(daylight_space: daylight_space,
973
+ skylight_area_weighted_vt_handle: skylight_area_weighted_vt_handle,
974
+ skylight_area_sum: skylight_area_sum,
975
+ daylighted_under_skylight_area: daylighted_under_skylight_area)
976
+
977
+ daylighted_area_under_skylights_hash[daylight_space.name.to_s] = daylighted_under_skylight_area
978
+
979
+ ##### Calculate skylight_effective_aperture as per NECB2011: 4.2.2.7.
980
+ ##### Note that it was assumed that the skylight is flush with the ceiling. Therefore, area-weighted average well factor (WF) was set to 0.9 in the below Equation.
981
+ skylight_area_weighted_vt = skylight_area_weighted_vt_handle / skylight_area_sum
982
+ skylight_effective_aperture_hash[daylight_space.name.to_s] = 0.85 * skylight_area_sum * skylight_area_weighted_vt * 0.9 / daylighted_under_skylight_area
983
+
984
+ end #daylight_spaces.each do |daylight_space|
985
+
986
+ # puts primary_sidelighted_area_hash
987
+ # puts sidelighting_effective_aperture_hash
988
+ # puts daylighted_area_under_skylights_hash
989
+ # puts skylight_effective_aperture_hash
990
+
991
+ ##### Find office spaces >= 25m2 among daylight_spaces
992
+ offices_larger_25m2 = []
993
+ daylight_spaces.sort.each do |daylight_space|
994
+
995
+ ## The following steps are for in case an office has multiple floors at various heights
996
+ ## 1. Calculate number of floors of each daylight_space
997
+ ## 2. Find the lowest z among all floors of each daylight_space
998
+ ## 3. Find lowest floors of each daylight_space (these floors are at the same level)
999
+ ## 4. Calculate 'daylight_space_area' as sum of area of all the lowest floors of each daylight_space, and gather the vertices of all the lowest floors of each daylight_space
1000
+
1001
+ ## 1. Calculate number of floors of daylight_space
1002
+ floor_vertices = []
1003
+ number_floor = 0
1004
+ daylight_space.surfaces.sort.each do |surface|
1005
+ if surface.surfaceType == 'Floor'
1006
+ floor_vertices << surface.vertices
1007
+ number_floor += 1
1008
+ end
1009
+ end
1010
+
1011
+ ## 2. Loop through all floors of daylight_space, and find the lowest z among all floors of daylight_space
1012
+ lowest_floor_z = []
1013
+ highest_floor_z = []
1014
+ for i in 0..number_floor - 1
1015
+ if i == 0
1016
+ lowest_floor_z = floor_vertices[i][0].z
1017
+ highest_floor_z = floor_vertices[i][0].z
1018
+ else
1019
+ if lowest_floor_z > floor_vertices[i][0].z
1020
+ lowest_floor_z = floor_vertices[i][0].z
1021
+ else
1022
+ lowest_floor_z = lowest_floor_z
1023
+ end
1024
+ if highest_floor_z < floor_vertices[i][0].z
1025
+ highest_floor_z = floor_vertices[i][0].z
1026
+ else
1027
+ highest_floor_z = highest_floor_z
1028
+ end
1029
+ end
1030
+ end
1031
+
1032
+ ## 3 and 4. Loop through all floors of daylight_space, and calculate the sum of area of all the lowest floors of daylight_space,
1033
+ ## and gather the vertices of all the lowest floors of daylight_space
1034
+ daylight_space_area = 0
1035
+ lowest_floors_vertices = []
1036
+ floor_vertices = []
1037
+ daylight_space.surfaces.sort.each do |surface|
1038
+ if surface.surfaceType == 'Floor'
1039
+ floor_vertices = surface.vertices
1040
+ if floor_vertices[0].z == lowest_floor_z
1041
+ lowest_floors_vertices << floor_vertices
1042
+ daylight_space_area = daylight_space_area + surface.netArea
1043
+ end
1044
+ end
1045
+ end
1046
+
1047
+ if daylight_space.spaceType.get.standardsSpaceType.get.to_s == "Office - enclosed" && daylight_space_area >= 25.0
1048
+ offices_larger_25m2 << daylight_space.name.to_s
1049
+ end
1050
+ end
1051
+
1052
+ ##### find daylight_spaces which do not need daylight sensor controls based on the primary_sidelighted_area as per NECB2011: 4.2.2.8.
1053
+ ##### Note: Office spaces >= 25m2 are excluded (i.e. they should have daylighting controls even if their primary_sidelighted_area <= 100m2), as per NECB2011: 4.2.2.2.
1054
+ daylight_spaces_exception = []
1055
+ primary_sidelighted_area_hash.sort.each do |key_daylight_space_name, value_primary_sidelighted_area|
1056
+ if value_primary_sidelighted_area <= 100.0 && [key_daylight_space_name].any? { |word| offices_larger_25m2.include?(word) } == false
1057
+ daylight_spaces_exception << key_daylight_space_name
1058
+ end
1059
+ end
1060
+
1061
+ ##### find daylight_spaces which do not need daylight sensor controls based on the sidelighting_effective_aperture as per NECB2011: 4.2.2.8.
1062
+ ##### Note: Office spaces >= 25m2 are excluded (i.e. they should have daylighting controls even if their sidelighting_effective_aperture <= 10%), as per NECB2011: 4.2.2.2.
1063
+ sidelighting_effective_aperture_hash.sort.each do |key_daylight_space_name, value_sidelighting_effective_aperture|
1064
+ if value_sidelighting_effective_aperture <= 0.1 && [key_daylight_space_name].any? { |word| offices_larger_25m2.include?(word) } == false
1065
+ daylight_spaces_exception << key_daylight_space_name
1066
+ end
1067
+ end
1068
+
1069
+ ##### find daylight_spaces which do not need daylight sensor controls based on the daylighted_area_under_skylights as per NECB2011: 4.2.2.4.
1070
+ ##### Note: Office spaces >= 25m2 are excluded (i.e. they should have daylighting controls even if their daylighted_area_under_skylights <= 400m2), as per NECB2011: 4.2.2.2.
1071
+ daylighted_area_under_skylights_hash.sort.each do |key_daylight_space_name, value_daylighted_area_under_skylights|
1072
+ if value_daylighted_area_under_skylights <= 400.0 && [key_daylight_space_name].any? { |word| offices_larger_25m2.include?(word) } == false
1073
+ daylight_spaces_exception << key_daylight_space_name
1074
+ end
1075
+ end
1076
+
1077
+ ##### find daylight_spaces which do not need daylight sensor controls based on the skylight_effective_aperture criterion as per NECB2011: 4.2.2.4.
1078
+ ##### Note: Office spaces >= 25m2 are excluded (i.e. they should have daylighting controls even if their skylight_effective_aperture <= 0.6%), as per NECB2011: 4.2.2.2.
1079
+ skylight_effective_aperture_hash.sort.each do |key_daylight_space_name, value_skylight_effective_aperture|
1080
+ if value_skylight_effective_aperture <= 0.006 && [key_daylight_space_name].any? { |word| offices_larger_25m2.include?(word) } == false
1081
+ daylight_spaces_exception << key_daylight_space_name
1082
+ end
1083
+ end
1084
+ # puts daylight_spaces_exception
1085
+
1086
+ ##### Loop through the daylight_spaces and exclude the daylight_spaces that do not meet the criteria (see above) as per NECB2011: 4.2.2.4. and 4.2.2.8.
1087
+ daylight_spaces_exception.sort.each do |daylight_space_exception|
1088
+ daylight_spaces.sort.each do |daylight_space|
1089
+ if daylight_space.name.to_s == daylight_space_exception
1090
+ daylight_spaces.delete(daylight_space)
1091
+ end
1092
+ end
1093
+ end
1094
+ # puts daylight_spaces
1095
+
1096
+ ##### Create one daylighting sensor and put it at the center of each daylight_space if the space area < 250m2;
1097
+ ##### otherwise, create two daylight sensors, divide the space into two parts and put each of the daylight sensors at the center of each part of the space.
1098
+ daylight_spaces.sort.each do |daylight_space|
1099
+ # puts daylight_space.name.to_s
1100
+ ##### 1. Calculate number of floors of each daylight_space
1101
+ ##### 2. Find the lowest z among all floors of each daylight_space
1102
+ ##### 3. Find lowest floors of each daylight_space (these floors are at the same level)
1103
+ ##### 4. Calculate 'daylight_space_area' as sum of area of all the lowest floors of each daylight_space, and gather the vertices of all the lowest floors of each daylight_space
1104
+ ##### 5. Find min and max of x and y among vertices of all the lowest floors of each daylight_space
1105
+
1106
+ ##### Calculate number of floors of daylight_space
1107
+ floor_vertices = []
1108
+ number_floor = 0
1109
+ daylight_space.surfaces.sort.each do |surface|
1110
+ if surface.surfaceType == 'Floor'
1111
+ floor_vertices << surface.vertices
1112
+ number_floor += 1
1113
+ end
1114
+ end
1115
+
1116
+ ##### Loop through all floors of daylight_space, and find the lowest z among all floors of daylight_space
1117
+ lowest_floor_z = []
1118
+ highest_floor_z = []
1119
+ for i in 0..number_floor - 1
1120
+ if i == 0
1121
+ lowest_floor_z = floor_vertices[i][0].z
1122
+ highest_floor_z = floor_vertices[i][0].z
1123
+ else
1124
+ if lowest_floor_z > floor_vertices[i][0].z
1125
+ lowest_floor_z = floor_vertices[i][0].z
1126
+ else
1127
+ lowest_floor_z = lowest_floor_z
1128
+ end
1129
+ if highest_floor_z < floor_vertices[i][0].z
1130
+ highest_floor_z = floor_vertices[i][0].z
1131
+ else
1132
+ highest_floor_z = highest_floor_z
1133
+ end
1134
+ end
1135
+ end
1136
+ # puts lowest_floor_z
1137
+
1138
+ ##### Loop through all floors of daylight_space, and calculate the sum of area of all the lowest floors of daylight_space,
1139
+ ##### and gather the vertices of all the lowest floors of daylight_space
1140
+ daylight_space_area = 0
1141
+ lowest_floors_vertices = []
1142
+ floor_vertices = []
1143
+ daylight_space.surfaces.sort.each do |surface|
1144
+ if surface.surfaceType == 'Floor'
1145
+ floor_vertices = surface.vertices
1146
+ if floor_vertices[0].z == lowest_floor_z
1147
+ lowest_floors_vertices << floor_vertices
1148
+ daylight_space_area = daylight_space_area + surface.netArea
1149
+ end
1150
+ end
1151
+ end
1152
+ # puts daylight_space.name.to_s
1153
+ # puts number_floor
1154
+ # puts lowest_floors_vertices
1155
+ # puts daylight_space_area
1156
+
1157
+ ##### Loop through all lowest floors of daylight_space and find the min and max of x and y among their vertices
1158
+ xmin = lowest_floors_vertices[0][0].x
1159
+ ymin = lowest_floors_vertices[0][0].y
1160
+ xmax = lowest_floors_vertices[0][0].x
1161
+ ymax = lowest_floors_vertices[0][0].y
1162
+ zmin = lowest_floor_z
1163
+ for i in 0..lowest_floors_vertices.count - 1 #this loops through each of the lowers floors of daylight_space
1164
+ for j in 0..lowest_floors_vertices[i].count - 1 #this loops through each of vertices of each of the lowers floors of daylight_space
1165
+
1166
+ if xmin > lowest_floors_vertices[i][j].x
1167
+ xmin = lowest_floors_vertices[i][j].x
1168
+ end
1169
+ if ymin > lowest_floors_vertices[i][j].y
1170
+ ymin = lowest_floors_vertices[i][j].y
1171
+ end
1172
+ if xmax < lowest_floors_vertices[i][j].x
1173
+ xmax = lowest_floors_vertices[i][j].x
1174
+ end
1175
+ if ymax < lowest_floors_vertices[i][j].y
1176
+ ymax = lowest_floors_vertices[i][j].y
1177
+ end
1178
+ end
1179
+ end
1180
+ # puts daylight_space.name.to_s
1181
+ # puts xmin
1182
+ # puts xmax
1183
+ # puts ymin
1184
+ # puts ymax
1185
+
1186
+ ##### Get the thermal zone of daylight_space (this is used later to assign daylighting sensor)
1187
+ zone = daylight_space.thermalZone
1188
+ if !zone.empty?
1189
+ zone = daylight_space.thermalZone.get
1190
+ ##### Get the floor of the daylight_space
1191
+ floors = []
1192
+ daylight_space.surfaces.sort.each do |surface|
1193
+ if surface.surfaceType == "Floor"
1194
+ floors << surface
1195
+ end
1196
+ end
1197
+
1198
+ ##### Get user's input for daylighting controls illuminance setpoint and number of stepped control steps
1199
+ illuminance_setpoint, number_of_stepped_control_steps = daylighting_controls_settings(illuminance_setpoint: 500.0, number_of_stepped_control_steps: 2)
1200
+
1201
+ ##### Create daylighting sensor control
1202
+ ##### NOTE: NECB2011 has some requirements on the number of sensors in spaces based on the area of the spaces.
1203
+ ##### However, EnergyPlus/OpenStudio allows to put maximum two built-in sensors in each thermal zone rather than in each space.
1204
+ ##### Since a thermal zone may include several spaces which are not next to each other on the same floor, or
1205
+ ##### a thermal zone may include spaces on different floors, a simplified method has been used to create a daylighting sensor.
1206
+ ##### So, in each thermal zone, only one daylighting sensor has been created even if the area of that thermal zone requires more than one daylighting sensor.
1207
+ ##### Also, it has been assumed that a thermal zone includes spaces which are next to each other and are on the same floor.
1208
+ ##### Furthermore, the one daylighting sensor in each thermal zone (where the thermal zone needs daylighting sensor),
1209
+ ##### the sensor has been put at the intersection of the minimum and maximum x and y of the lowest floor of that thermal zones.
1210
+ sensor = OpenStudio::Model::DaylightingControl.new(daylight_space.model)
1211
+ sensor.setName("#{daylight_space.name.to_s} daylighting control")
1212
+ sensor.setSpace(daylight_space)
1213
+ sensor.setIlluminanceSetpoint(illuminance_setpoint)
1214
+ sensor.setLightingControlType('Stepped')
1215
+ sensor.setNumberofSteppedControlSteps(number_of_stepped_control_steps)
1216
+ x_pos = (xmin + xmax) / 2.0
1217
+ y_pos = (ymin + ymax) / 2.0
1218
+ z_pos = zmin + 0.8 #put it 0.8 meter above the floor
1219
+ sensor_vertex = OpenStudio::Point3d.new(x_pos, y_pos, z_pos)
1220
+ sensor.setPosition(sensor_vertex)
1221
+ zone.setPrimaryDaylightingControl(sensor)
1222
+ zone.setFractionofZoneControlledbyPrimaryDaylightingControl(1.0)
1223
+
1224
+ end #if !zone.empty?
1225
+ end #daylight_spaces.each do |daylight_space|
1226
+ end
1227
+
1228
+ #def model_add_daylighting_controls(model)
1229
+
1230
+
1231
+ def model_enable_demand_controlled_ventilation(model, dcv_type = 'No_DCV') # Note: Values for dcv_type are: 'Occupancy_based_DCV', 'CO2_based_DCV', 'No_DCV', 'NECB_Default'
1232
+ if dcv_type != 'NECB_Default'
1233
+ if dcv_type == 'Occupancy_based_DCV' || dcv_type == 'CO2_based_DCV'
1234
+ #TODO: IMPORTANT: (upon other BTAP tasks) Set a value for the "Outdoor Air Flow per Person" field of the "OS:DesignSpecification:OutdoorAir" object
1235
+ # Note: The "Outdoor Air Flow per Person" field is required for occupancy-based DCV.
1236
+ # Note: The "Outdoor Air Flow per Person" values should be based on ASHRAE 62.1: Article 6.2.2.1.
1237
+ # Note: The "Outdoor Air Flow per Person" should be entered for "ventilation_per_person" in "lib/openstudio-standards/standards/necb/NECB2011/data/space_types.json"
1238
+
1239
+ ##### Define ScheduleTypeLimits for Any_Number_ppm
1240
+ ##### TODO: (upon other BTAP tasks) This function can be added to btap/schedules.rb > module StandardScheduleTypeLimits
1241
+ def self.get_any_number_ppm(model)
1242
+ name = 'Any_Number_ppm'
1243
+ any_number_ppm_schedule_type_limits = model.getScheduleTypeLimitsByName(name)
1244
+ if any_number_ppm_schedule_type_limits.empty?
1245
+ any_number_ppm_schedule_type_limits = OpenStudio::Model::ScheduleTypeLimits.new(model)
1246
+ any_number_ppm_schedule_type_limits.setName(name)
1247
+ any_number_ppm_schedule_type_limits.setNumericType('CONTINUOUS')
1248
+ any_number_ppm_schedule_type_limits.setUnitType('Dimensionless')
1249
+ any_number_ppm_schedule_type_limits.setLowerLimitValue(400.0)
1250
+ any_number_ppm_schedule_type_limits.setUpperLimitValue(1000.0)
1251
+ return any_number_ppm_schedule_type_limits
1252
+ else
1253
+ return any_number_ppm_schedule_type_limits.get
1254
+ end
1255
+ end
1256
+
1257
+ ##### Define indoor CO2 availability schedule (required for CO2-based DCV)
1258
+ ##### Reference: see page B.13 of PNNL (2017), "Impacts of Commercial Building Controls on Energy Savings and Peak Load Reduction", available a: https://www.energy.gov/eere/buildings/downloads/impacts-commercial-building-controls-energy-savings-and-peak-load-reduction
1259
+ ##### Note: the defined schedule here is redundant as the schedule says it is always on AND
1260
+ ##### the "ZoneControl:ContaminantController" object says that "If this field is left blank, the schedule has a value of 1 for all time periods".
1261
+ indoor_co2_availability_schedule = OpenStudio::Model::ScheduleCompact.new(model)
1262
+ indoor_co2_availability_schedule.setName('indoor_co2_availability_schedule')
1263
+ indoor_co2_availability_schedule.setScheduleTypeLimits(BTAP::Resources::Schedules::StandardScheduleTypeLimits::get_fraction(model))
1264
+ indoor_co2_availability_schedule.to_ScheduleCompact.get
1265
+ # indoor_co2_availability_schedule.setString(1,"indoor_co2_availability_schedule")
1266
+ indoor_co2_availability_schedule.setString(3, "Through: 12/31")
1267
+ indoor_co2_availability_schedule.setString(4, "For: Weekdays SummerDesignDay")
1268
+ indoor_co2_availability_schedule.setString(5, "Until: 07:00")
1269
+ indoor_co2_availability_schedule.setString(6, "0.0")
1270
+ indoor_co2_availability_schedule.setString(7, "Until: 22:00")
1271
+ indoor_co2_availability_schedule.setString(8, "1.0")
1272
+ indoor_co2_availability_schedule.setString(9, "Until: 24:00")
1273
+ indoor_co2_availability_schedule.setString(10, "0.0")
1274
+ indoor_co2_availability_schedule.setString(11, "For: Saturday WinterDesignDay")
1275
+ indoor_co2_availability_schedule.setString(12, "Until: 07:00")
1276
+ indoor_co2_availability_schedule.setString(13, "0.0")
1277
+ indoor_co2_availability_schedule.setString(14, "Until: 18:00")
1278
+ indoor_co2_availability_schedule.setString(15, "1.0")
1279
+ indoor_co2_availability_schedule.setString(16, "Until: 24:00")
1280
+ indoor_co2_availability_schedule.setString(17, "0.0")
1281
+ indoor_co2_availability_schedule.setString(18, "For: AllOtherDays")
1282
+ indoor_co2_availability_schedule.setString(19, "Until: 24:00")
1283
+ indoor_co2_availability_schedule.setString(20, "0.0")
1284
+
1285
+ ##### Define indoor CO2 setpoint schedule (required for CO2-based DCV)
1286
+ ##### Reference: see page B.13 of PNNL (2017), "Impacts of Commercial Building Controls on Energy Savings and Peak Load Reduction", available a: https://www.energy.gov/eere/buildings/downloads/impacts-commercial-building-controls-energy-savings-and-peak-load-reduction
1287
+ indoor_co2_setpoint_schedule = OpenStudio::Model::ScheduleCompact.new(model)
1288
+ indoor_co2_setpoint_schedule.setName('indoor_co2_setpoint_schedule')
1289
+ indoor_co2_setpoint_schedule.setScheduleTypeLimits(get_any_number_ppm(model))
1290
+ indoor_co2_setpoint_schedule.to_ScheduleCompact.get
1291
+ indoor_co2_setpoint_schedule.setString(3, "Through: 12/31")
1292
+ indoor_co2_setpoint_schedule.setString(4, "For: AllDays")
1293
+ indoor_co2_setpoint_schedule.setString(5, "Until: 24:00")
1294
+ indoor_co2_setpoint_schedule.setString(6, "1000.0")
1295
+ # indoor_co2_setpoint_schedule.setToConstantValue(1000.0) #1000 ppm
1296
+
1297
+
1298
+ ##### Define outdoor CO2 schedule (required for CO2-based DCV
1299
+ ##### Reference: see page B.13 of PNNL (2017), "Impacts of Commercial Building Controls on Energy Savings and Peak Load Reduction", available a: https://www.energy.gov/eere/buildings/downloads/impacts-commercial-building-controls-energy-savings-and-peak-load-reduction
1300
+ outdoor_co2_schedule = OpenStudio::Model::ScheduleCompact.new(model)
1301
+ outdoor_co2_schedule.setName('outdoor_co2_schedule')
1302
+ outdoor_co2_schedule.setScheduleTypeLimits(get_any_number_ppm(model))
1303
+ outdoor_co2_schedule.to_ScheduleCompact.get
1304
+ outdoor_co2_schedule.setString(3, "Through: 12/31")
1305
+ outdoor_co2_schedule.setString(4, "For: AllDays")
1306
+ outdoor_co2_schedule.setString(5, "Until: 24:00")
1307
+ outdoor_co2_schedule.setString(6, "400.0")
1308
+ # outdoor_co2_schedule.setToConstantValue(400.0) #400 ppm
1309
+
1310
+ ##### Define ZoneAirContaminantBalance (required for CO2-based DCV)
1311
+ zone_air_contaminant_balance = model.getZoneAirContaminantBalance()
1312
+ zone_air_contaminant_balance.setCarbonDioxideConcentration(true)
1313
+ zone_air_contaminant_balance.setOutdoorCarbonDioxideSchedule(outdoor_co2_schedule)
1314
+
1315
+ ##### Set CO2 controller in each space (required for CO2-based DCV)
1316
+ model.getSpaces.sort.each do |space|
1317
+ # puts space.name.to_s
1318
+ zone = space.thermalZone
1319
+ if !zone.empty?
1320
+ zone = space.thermalZone.get
1321
+ end
1322
+ zone_control_co2 = OpenStudio::Model::ZoneControlContaminantController.new(zone.model)
1323
+ zone_control_co2.setName("#{space.name.to_s} Zone Control Contaminant Controller")
1324
+ zone_control_co2.setCarbonDioxideControlAvailabilitySchedule(indoor_co2_availability_schedule)
1325
+ zone_control_co2.setCarbonDioxideSetpointSchedule(indoor_co2_setpoint_schedule)
1326
+ zone.setZoneControlContaminantController(zone_control_co2)
1327
+ end
1328
+
1329
+ end #if dcv_type == "Occupancy_based_DCV" || dcv_type == "CO2_based_DCV"
1330
+
1331
+ ##### Loop through AirLoopHVACs
1332
+ model.getAirLoopHVACs.sort.each do |air_loop|
1333
+ ##### Loop through AirLoopHVAC's supply nodes to:
1334
+ ##### (1) Find its AirLoopHVAC:OutdoorAirSystem using the supply node;
1335
+ ##### (2) Find Controller:OutdoorAir using AirLoopHVAC:OutdoorAirSystem;
1336
+ ##### (3) Get "Controller Mechanical Ventilation" from Controller:OutdoorAir.
1337
+ air_loop.supplyComponents.sort.each do |supply_component|
1338
+ ##### Find AirLoopHVAC:OutdoorAirSystem of AirLoopHVAC using the supply node.
1339
+ hvac_component = supply_component.to_AirLoopHVACOutdoorAirSystem
1340
+
1341
+ if !hvac_component.empty?
1342
+ ##### Find Controller:OutdoorAir using AirLoopHVAC:OutdoorAirSystem.
1343
+ hvac_component = hvac_component.get
1344
+ controller_oa = hvac_component.getControllerOutdoorAir
1345
+
1346
+ ##### Get "Controller Mechanical Ventilation" from Controller:OutdoorAir.
1347
+ controller_mv = controller_oa.controllerMechanicalVentilation
1348
+
1349
+ ##### Set "Demand Controlled Ventilation" to "Yes" or "No" in Controller:MechanicalVentilation depending on dcv_type.
1350
+ if (dcv_type == 'CO2_based_DCV') || (dcv_type == 'Occupancy_based_DCV') #Occupancy
1351
+ controller_mv.setDemandControlledVentilation(true)
1352
+ ##### Set the "System Outdoor Air Method" field based on dcv_type in the Controller:MechanicalVentilation object
1353
+ if dcv_type == 'CO2_based_DCV'
1354
+ controller_mv.setSystemOutdoorAirMethod('IndoorAirQualityProcedure')
1355
+ else #dcv_type == 'Occupancy_based_DCV'
1356
+ controller_mv.setSystemOutdoorAirMethod('ZoneSum')
1357
+ end
1358
+ elsif dcv_type == 'No_DCV'
1359
+ controller_mv.setDemandControlledVentilation(false)
1360
+ end
1361
+ # puts controller_mv
1362
+
1363
+ end #if !hvac_component.empty?
1364
+
1365
+ end #air_loop.supplyComponents.each do |supply_component|
1366
+ end #model.getAirLoopHVACs.each do |air_loop|
1367
+ end #if dcv_type != 'NECB_Default'
1368
+ end
1369
+
1370
+ #def model_enable_demand_controlled_ventilation
1371
+
1372
+
1373
+ def set_lighting_per_area_led_lighting(space_type:, definition:, lighting_per_area_led_lighting:, lights_scale:)
1374
+ # puts "#{space_type.name.to_s} - 'space_height' - #{space_height.to_s}"
1375
+ occ_sens_lpd_frac = 1.0
1376
+ # NECB2011 space types that require a reduction in the LPD to account for
1377
+ # the requirement of an occupancy sensor (8.4.4.6(3) and 4.2.2.2(2))
1378
+ reduce_lpd_spaces = ['Classroom/lecture/training', 'Conf./meet./multi-purpose', 'Lounge/recreation',
1379
+ 'Conf./meet./multi-purpose', 'Washroom-sch-A', 'Washroom-sch-B', 'Washroom-sch-C', 'Washroom-sch-D',
1380
+ 'Washroom-sch-E', 'Washroom-sch-F', 'Washroom-sch-G', 'Washroom-sch-H', 'Washroom-sch-I',
1381
+ 'Dress./fitt. - performance arts', 'Locker room', 'Locker room-sch-A', 'Locker room-sch-B',
1382
+ 'Locker room-sch-C', 'Locker room-sch-D', 'Locker room-sch-E', 'Locker room-sch-F', 'Locker room-sch-G',
1383
+ 'Locker room-sch-H', 'Locker room-sch-I', 'Retail - dressing/fitting']
1384
+ if reduce_lpd_spaces.include?(space_type.standardsSpaceType.get)
1385
+ # Note that "Storage area", "Storage area - refrigerated", "Hospital - medical supply" and "Office - enclosed"
1386
+ # LPD should only be reduced if their space areas are less than specific area values.
1387
+ # This is checked in a space loop after this function in the calling routine.
1388
+ occ_sens_lpd_frac = 0.9
1389
+ end
1390
+
1391
+ # ##### Since Atrium's LPD for LED lighting depends on atrium's height, the height of the atrium (if applicable) should be found.
1392
+ standards_space_type = space_type.standardsSpaceType.is_initialized ? space_type.standardsSpaceType.get : nil
1393
+ if standards_space_type.include? 'Atrium' #TODO: Note that since none of the archetypes has Atrium, this was tested for 'Dining'. #Atrium
1394
+ puts "#{standards_space_type} - has atrium" #space_type.name.to_s
1395
+ # Get the max height for the spacetype.
1396
+ max_space_height_for_spacetype = get_max_space_height_for_space_type(space_type: space_type)
1397
+ if max_space_height_for_spacetype < 12.0 #TODO: Note that since none of the archetypes has Atrium, this was tested for 'Dining' with the threshold of 5.0 m for space_height.
1398
+ # TODO: Regarding the below equations, identify which version of ASHRAE 90.1 was used in NECB2015.
1399
+ atrium_lpd_eq_smaller_12_intercept = 0
1400
+ atrium_lpd_eq_smaller_12_slope = 1.06
1401
+ atrium_lpd_eq_larger_12_intercept = 4.3
1402
+ atrium_lpd_eq_larger_12_slope = 1.06
1403
+ lighting_per_area_led_lighting_atrium = (atrium_lpd_eq_smaller_12_intercept + atrium_lpd_eq_smaller_12_slope * 12.0) * 0.092903 # W/ft2 TODO: Note that for NECB2011, a constant LPD is used for atrium based on NECB2015's equations. NECB2011's threshold for height is 13.0 m.
1404
+ elsif max_space_height_for_spacetype >= 12.0 && max_space_height_for_spacetype < 13.0
1405
+ lighting_per_area_led_lighting_atrium = (atrium_lpd_eq_larger_12_intercept + atrium_lpd_eq_larger_12_slope * 12.5) * 0.092903 # W/ft2
1406
+ else #i.e. space_height >= 13.0
1407
+ lighting_per_area_led_lighting_atrium = (atrium_lpd_eq_larger_12_intercept + atrium_lpd_eq_larger_12_slope * 13.0) * 0.092903 # W/ft2
1408
+ end
1409
+ puts "#{standards_space_type} - has lighting_per_area_led_lighting_atrium - #{lighting_per_area_led_lighting_atrium}"
1410
+ lighting_per_area_led_lighting = lighting_per_area_led_lighting_atrium
1411
+ end
1412
+ lighting_per_area_led_lighting = lighting_per_area_led_lighting * lights_scale
1413
+ definition.setWattsperSpaceFloorArea(OpenStudio.convert(lighting_per_area_led_lighting.to_f * occ_sens_lpd_frac, 'W/ft^2', 'W/m^2').get)
1414
+
1415
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.SpaceType', "#{space_type.name} set LPD to #{lighting_per_area_led_lighting} W/ft^2.")
1416
+ end
1417
+
1418
+ # Adds the loads and associated schedules for each space type
1419
+ # as defined in the OpenStudio_Standards_space_types.json file.
1420
+ # This includes lights, plug loads, occupants, ventilation rate requirements,
1421
+ # infiltration, gas equipment (for kitchens, etc.) and typical schedules for each.
1422
+ # Some loads are governed by the standard, others are typical values
1423
+ # pulled from sources such as the DOE Reference and DOE Prototype Buildings.
1424
+ #
1425
+ # @return [Bool] returns true if successful, false if not
1426
+ def model_add_loads(model, lights_type, lights_scale)
1427
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying space types (loads)')
1428
+
1429
+ # Loop through all the space types currently in the model,
1430
+ # which are placeholders, and give them appropriate loads and schedules
1431
+ model.getSpaceTypes.sort.each do |space_type|
1432
+ # Rendering color
1433
+ space_type_apply_rendering_color(space_type)
1434
+
1435
+ # Loads
1436
+ space_type_apply_internal_loads(space_type: space_type, lights_type: lights_type, lights_scale: lights_scale)
1437
+
1438
+ # Schedules
1439
+ space_type_apply_internal_load_schedules(space_type, true, true, true, true, true, true, true)
1440
+ end
1441
+
1442
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying space types (loads)')
1443
+
1444
+ return true
1445
+ end
1446
+
1447
+ ##### This method is needed to the space_type_apply_internal_loads space needed for the calculation of atriums' LPD when LED lighting is used in atriums. ***END***
1448
+ def get_max_space_height_for_space_type(space_type:)
1449
+ # initialize return value to zero.
1450
+ max_space_height_for_space_type = 0.0
1451
+ # Interate through all spaces in model.. not just ones that have space type defined.. Is this right sara?
1452
+ space_type.spaces.sort.each do |space|
1453
+ # Get only the wall type surfaces and iterate throught them.
1454
+ space.surfaces.sort.select(&:surfaceType == 'Wall').each do |wall_surface|
1455
+ # Find the vertex with the max z value.
1456
+ vertex_with_max_height = wall_surface.vertices.max_by(&:z)
1457
+ # replace max if this surface has something bigger.
1458
+ max_space_height_for_space_type = vertex_with_max_height.z if vertex_with_max_height.z > max_space_height_for_space_type
1459
+ end
1460
+ end
1461
+ return max_space_height_for_space_type
1462
+ end
1463
+
1464
+ ##### The below method is for the 'model_add_daylighting_controls' method
1465
+ def get_parameters_sidelighting(daylight_space:, floor_surface:, floor_vertices:, floor_area:, primary_sidelighted_area:, area_weighted_vt_handle:, window_area_sum:)
1466
+
1467
+ daylight_space.surfaces.sort.each do |surface|
1468
+
1469
+ ##### Get the vertices of each exterior wall of the daylight_space on the floor
1470
+ ##### (these vertices will be used to calculate daylight_space depth in relation to the exterior wall, and
1471
+ ##### the distance of the window to vertical walls on each side of the window)
1472
+ if surface.outsideBoundaryCondition == "Outdoors" && surface.surfaceType == "Wall"
1473
+ wall_vertices_x_on_floor = []
1474
+ wall_vertices_y_on_floor = []
1475
+ surface_z_min = [surface.vertices[0].z, surface.vertices[1].z, surface.vertices[2].z, surface.vertices[3].z].min
1476
+ surface.vertices.each do |vertex|
1477
+ # puts vertex.z
1478
+ if vertex.z == surface_z_min && surface_z_min == floor_vertices[0][0].z
1479
+ wall_vertices_x_on_floor << vertex.x
1480
+ wall_vertices_y_on_floor << vertex.y
1481
+ end
1482
+ end
1483
+ end
1484
+
1485
+ if surface.outsideBoundaryCondition == "Outdoors" && surface.surfaceType == "Wall" && surface_z_min == floor_vertices[0][0].z
1486
+
1487
+ ##### Calculate the daylight_space depth in relation to the considered exterior wall.
1488
+ ##### To calculate daylight_space depth, first get the floor vertices which are on the opposite side of the considered exterior wall.
1489
+ floor_vertices_x_wall_opposite = []
1490
+ floor_vertices_y_wall_opposite = []
1491
+ floor_vertices[0].each do |floor_vertex|
1492
+ if (floor_vertex.x != wall_vertices_x_on_floor[0] && floor_vertex.y != wall_vertices_y_on_floor[0]) || (floor_vertex.x != wall_vertices_x_on_floor[1] && floor_vertex.y != wall_vertices_y_on_floor[1])
1493
+ floor_vertices_x_wall_opposite << floor_vertex.x
1494
+ floor_vertices_y_wall_opposite << floor_vertex.y
1495
+ end
1496
+ end
1497
+
1498
+ ##### To calculate daylight_space depth, second calculate floor length on both sides: (1) exterior wall side, (2) on the opposite side of the exterior wall
1499
+ floor_width_wall_side = Math.sqrt((wall_vertices_x_on_floor[0] - wall_vertices_x_on_floor[1]) ** 2 + (wall_vertices_y_on_floor[0] - wall_vertices_y_on_floor[1]) ** 2)
1500
+ floor_width_wall_opposite = Math.sqrt((floor_vertices_x_wall_opposite[0] - floor_vertices_x_wall_opposite[1]) ** 2 + (floor_vertices_y_wall_opposite[0] - floor_vertices_y_wall_opposite[1]) ** 2)
1501
+
1502
+ ##### Now, daylight_space depth can be calculated using the floor area and two lengths of the floor (note that these two lengths are in parallel to each other).
1503
+ daylight_space_depth = 2 * floor_area / (floor_width_wall_side + floor_width_wall_opposite)
1504
+
1505
+ ##### Loop through the windows (including fixed and operable ones) to get window specification (width, height, area, visible transmittance (VT)), and area-weighted VT
1506
+ surface.subSurfaces.sort.each do |subsurface|
1507
+ # puts subsurface.name.to_s
1508
+ if subsurface.subSurfaceType == "FixedWindow" || subsurface.subSurfaceType == "OperableWindow"
1509
+ window_vt = subsurface.visibleTransmittance
1510
+ window_vt = window_vt.get
1511
+ window_area = subsurface.netArea
1512
+ window_area_sum += window_area
1513
+ area_weighted_vt_handle += window_area * window_vt
1514
+ window_vertices = subsurface.vertices
1515
+ if window_vertices[0].z.round(2) == window_vertices[1].z.round(2)
1516
+ window_width = Math.sqrt((window_vertices[0].x - window_vertices[1].x) ** 2.0 + (window_vertices[0].y - window_vertices[1].y) ** 2.0)
1517
+ else
1518
+ window_width = Math.sqrt((window_vertices[1].x - window_vertices[2].x) ** 2.0 + (window_vertices[1].y - window_vertices[2].y) ** 2.0)
1519
+ end
1520
+ window_head_height = [window_vertices[0].z, window_vertices[1].z, window_vertices[2].z, window_vertices[3].z].max.round(2)
1521
+ primary_sidelighted_area_depth = [window_head_height, daylight_space_depth].min #as per NECB2011: 4.2.2.9.
1522
+
1523
+ ##### Calculate the distance of the window to vertical walls on each side of the window (this is used to determine the sidelighted area's width).
1524
+ window_vertices_on_floor = []
1525
+ window_vertices.each do |vertex|
1526
+ window_vertices_on_floor << floor_surface.plane.project(vertex)
1527
+ end
1528
+ window_wall_distance_side1 = [Math.sqrt((wall_vertices_x_on_floor[0] - window_vertices_on_floor[0].x) ** 2.0 + (wall_vertices_y_on_floor[0] - window_vertices_on_floor[0].y) ** 2.0),
1529
+ Math.sqrt((wall_vertices_x_on_floor[0] - window_vertices_on_floor[2].x) ** 2.0 + (wall_vertices_y_on_floor[0] - window_vertices_on_floor[2].y) ** 2.0),
1530
+ 0.6].min # 0.6 m as per NECB2011: 4.2.2.9.
1531
+ window_wall_distance_side2 = [Math.sqrt((wall_vertices_x_on_floor[1] - window_vertices_on_floor[0].x) ** 2.0 + (wall_vertices_y_on_floor[1] - window_vertices_on_floor[0].y) ** 2.0),
1532
+ Math.sqrt((wall_vertices_x_on_floor[1] - window_vertices_on_floor[2].x) ** 2.0 + (wall_vertices_y_on_floor[1] - window_vertices_on_floor[2].y) ** 2.0),
1533
+ 0.6].min # 0.6 m as per NECB2011: 4.2.2.9.
1534
+ primary_sidelighted_area_width = window_wall_distance_side1 + window_width + window_wall_distance_side2
1535
+ primary_sidelighted_area = primary_sidelighted_area + primary_sidelighted_area_depth * primary_sidelighted_area_width
1536
+ end #if subsurface.subSurfaceType == "FixedWindow" || subsurface.subSurfaceType == "OperableWindow"
1537
+ end #surface.subSurfaces.each do |subsurface|
1538
+ end #if surface.outsideBoundaryCondition == "Outdoors" && surface.surfaceType == "Wall" && surface_z_min == floor_vertices[0][0].z
1539
+ end #daylight_space.surfaces.each do |surface|
1540
+
1541
+ return primary_sidelighted_area, area_weighted_vt_handle, window_area_sum
1542
+ end
1543
+
1544
+ ##### The below method is for the 'model_add_daylighting_controls' method
1545
+ def get_parameters_skylight(daylight_space:, skylight_area_weighted_vt_handle:, skylight_area_sum:, daylighted_under_skylight_area:)
1546
+
1547
+ daylight_space.surfaces.sort.each do |surface|
1548
+ ##### Get roof vertices
1549
+ if surface.outsideBoundaryCondition == "Outdoors" && surface.surfaceType == "RoofCeiling"
1550
+ roof_vertices = surface.vertices
1551
+ end
1552
+
1553
+ ##### Loop through each subsurafce to calculate daylighted_area_under_skylights and skylight_effective_aperture for each daylight_space
1554
+ surface.subSurfaces.sort.each do |subsurface|
1555
+ if subsurface.subSurfaceType == "Skylight"
1556
+ skylight_vt = subsurface.visibleTransmittance
1557
+ skylight_vt = skylight_vt.get
1558
+ skylight_area = subsurface.netArea
1559
+ skylight_area_sum += skylight_area
1560
+ skylight_area_weighted_vt_handle += skylight_area * skylight_vt
1561
+
1562
+ ##### Get skylight vertices
1563
+ skylight_vertices = subsurface.vertices
1564
+
1565
+ ##### Calculate skylight width and height
1566
+ skylight_width = Math.sqrt((skylight_vertices[0].x - skylight_vertices[1].x) ** 2.0 + (skylight_vertices[0].y - skylight_vertices[1].y) ** 2.0)
1567
+ skylight_length = Math.sqrt((skylight_vertices[0].x - skylight_vertices[3].x) ** 2.0 + (skylight_vertices[0].y - skylight_vertices[3].y) ** 2.0)
1568
+
1569
+ ##### Get ceiling height assuming the skylight is flush with the ceiling
1570
+ ceiling_height = skylight_vertices[0].z
1571
+
1572
+ ##### Calculate roof lengths
1573
+ ##### (Note: used OpenStudio BCL measure called "assign_ashrae_9012010_daylighting_controls" with some changes/correcctions)
1574
+ roof_length_0 = Math.sqrt((roof_vertices[0].x - roof_vertices[1].x) ** 2.0 + (roof_vertices[0].y - roof_vertices[1].y) ** 2.0)
1575
+ roof_length_1 = Math.sqrt((roof_vertices[1].x - roof_vertices[2].x) ** 2.0 + (roof_vertices[1].y - roof_vertices[2].y) ** 2.0)
1576
+ roof_length_2 = Math.sqrt((roof_vertices[2].x - roof_vertices[3].x) ** 2.0 + (roof_vertices[2].y - roof_vertices[3].y) ** 2.0)
1577
+ roof_length_3 = Math.sqrt((roof_vertices[3].x - roof_vertices[0].x) ** 2.0 + (roof_vertices[3].y - roof_vertices[0].y) ** 2.0)
1578
+
1579
+ ##### Find the skylight point that is the closest one to roof_vertex_0
1580
+ ##### (Note: used OpenStudio BCL measure called "assign_ashrae_9012010_daylighting_controls" with some changes/correcctions)
1581
+ roof_vertex_0_skylight_vertex_0 = Math.sqrt((roof_vertices[0].x - skylight_vertices[0].x) ** 2.0 + (roof_vertices[0].y - skylight_vertices[0].y) ** 2.0)
1582
+ roof_vertex_0_skylight_vertex_1 = Math.sqrt((roof_vertices[0].x - skylight_vertices[1].x) ** 2.0 + (roof_vertices[0].y - skylight_vertices[1].y) ** 2.0)
1583
+ roof_vertex_0_skylight_vertex_2 = Math.sqrt((roof_vertices[0].x - skylight_vertices[2].x) ** 2.0 + (roof_vertices[0].y - skylight_vertices[2].y) ** 2.0)
1584
+ roof_vertex_0_skylight_vertex_3 = Math.sqrt((roof_vertices[0].x - skylight_vertices[3].x) ** 2.0 + (roof_vertices[0].y - skylight_vertices[3].y) ** 2.0)
1585
+ roof_vertex_0_closest_distance = [roof_vertex_0_skylight_vertex_0, roof_vertex_0_skylight_vertex_1, roof_vertex_0_skylight_vertex_2, roof_vertex_0_skylight_vertex_3].min
1586
+ if roof_vertex_0_closest_distance == roof_vertex_0_skylight_vertex_0
1587
+ roof_vertex_0_closest_point = skylight_vertices[0]
1588
+ elsif roof_vertex_0_closest_distance == roof_vertex_0_skylight_vertex_1
1589
+ roof_vertex_0_closest_point = skylight_vertices[1]
1590
+ elsif roof_vertex_0_closest_distance == roof_vertex_0_skylight_vertex_2
1591
+ roof_vertex_0_closest_point = skylight_vertices[2]
1592
+ elsif roof_vertex_0_closest_distance == roof_vertex_0_skylight_vertex_3
1593
+ roof_vertex_0_closest_point = skylight_vertices[3]
1594
+ end
1595
+
1596
+ ##### Find the skylight point that is the closest one to roof_vertex_2
1597
+ ##### (Note: used OpenStudio BCL measure called "assign_ashrae_9012010_daylighting_controls" with some changes/correcctions)
1598
+ roof_vertex_2_skylight_vertex_0 = Math.sqrt((roof_vertices[2].x - skylight_vertices[0].x) ** 2.0 + (roof_vertices[2].y - skylight_vertices[0].y) ** 2.0)
1599
+ roof_vertex_2_skylight_vertex_1 = Math.sqrt((roof_vertices[2].x - skylight_vertices[1].x) ** 2.0 + (roof_vertices[2].y - skylight_vertices[1].y) ** 2.0)
1600
+ roof_vertex_2_skylight_vertex_2 = Math.sqrt((roof_vertices[2].x - skylight_vertices[2].x) ** 2.0 + (roof_vertices[2].y - skylight_vertices[2].y) ** 2.0)
1601
+ roof_vertex_2_skylight_vertex_3 = Math.sqrt((roof_vertices[2].x - skylight_vertices[3].x) ** 2.0 + (roof_vertices[2].y - skylight_vertices[3].y) ** 2.0)
1602
+ roof_vertex_2_closest_distance = [roof_vertex_2_skylight_vertex_0, roof_vertex_2_skylight_vertex_1, roof_vertex_2_skylight_vertex_2, roof_vertex_2_skylight_vertex_3].min
1603
+ if roof_vertex_2_closest_distance == roof_vertex_2_skylight_vertex_0
1604
+ roof_vertex_2_closest_point = skylight_vertices[0]
1605
+ elsif roof_vertex_2_closest_distance == roof_vertex_2_skylight_vertex_1
1606
+ roof_vertex_2_closest_point = skylight_vertices[1]
1607
+ elsif roof_vertex_2_closest_distance == roof_vertex_2_skylight_vertex_2
1608
+ roof_vertex_2_closest_point = skylight_vertices[2]
1609
+ elsif roof_vertex_2_closest_distance == roof_vertex_2_skylight_vertex_3
1610
+ roof_vertex_2_closest_point = skylight_vertices[3]
1611
+ end
1612
+
1613
+ ##### Calculate the vertical distance from the closest skylight points (projection onto the roof) to the wall (projection onto the roof) for roof_vertex_0 and roof_vertex_2
1614
+ ##### (Note: used OpenStudio BCL measure called "assign_ashrae_9012010_daylighting_controls" with some changes/correcctions)
1615
+ ##### For the calculation of each vertical distance: (1) first the area of the triangle is calculated knowing the cooridantes of its three corners;
1616
+ ##### (2) the vertical distance (i.e. triangle height) is calculated knowing the triangle area and the associated roof length.
1617
+ rv_0_triangle_0_area = 0.5 * (((roof_vertex_0_closest_point.x - roof_vertices[1].x) * (roof_vertex_0_closest_point.y - roof_vertices[0].y)) -
1618
+ ((roof_vertex_0_closest_point.x - roof_vertices[0].x) * (roof_vertex_0_closest_point.y - roof_vertices[1].y))).abs
1619
+ rv_0_distance_0 = (2.0 * rv_0_triangle_0_area) / roof_length_0
1620
+ rv_0_triangle_3_area = 0.5 * (((roof_vertex_0_closest_point.x - roof_vertices[3].x) * (roof_vertex_0_closest_point.y - roof_vertices[0].y)) -
1621
+ ((roof_vertex_0_closest_point.x - roof_vertices[0].x) * (roof_vertex_0_closest_point.y - roof_vertices[3].y))).abs
1622
+ rv_0_distance_3 = (2.0 * rv_0_triangle_3_area) / roof_length_3
1623
+
1624
+ rv_2_triangle_1_area = 0.5 * (((roof_vertex_2_closest_point.x - roof_vertices[1].x) * (roof_vertex_2_closest_point.y - roof_vertices[2].y)) -
1625
+ ((roof_vertex_2_closest_point.x - roof_vertices[2].x) * (roof_vertex_2_closest_point.y - roof_vertices[1].y))).abs
1626
+ rv_2_distance_1 = (2.0 * rv_2_triangle_1_area) / roof_length_1
1627
+ rv_2_triangle_2_area = 0.5 * (((roof_vertex_2_closest_point.x - roof_vertices[3].x) * (roof_vertex_2_closest_point.y - roof_vertices[2].y)) -
1628
+ ((roof_vertex_2_closest_point.x - roof_vertices[2].x) * (roof_vertex_2_closest_point.y - roof_vertices[3].y))).abs
1629
+ rv_2_distance_2 = (2.0 * rv_2_triangle_2_area) / roof_length_2
1630
+
1631
+ ##### Set the vertical distances from the closest skylight points (projection onto the roof) to the wall (projection onto the roof) for roof_vertex_0 and roof_vertex_2
1632
+ distance_1 = rv_0_distance_0
1633
+ distance_2 = rv_0_distance_3
1634
+ distance_3 = rv_2_distance_1
1635
+ distance_4 = rv_2_distance_2
1636
+
1637
+ ##### Calculate the width and length of the daylighted area under the skylight as per NECB2011: 4.2.2.5.
1638
+ ##### Note: In the below loops, if any exterior walls has window(s), the width and length of the daylighted area under the skylight are re-calculated as per NECB2011: 4.2.2.5.
1639
+ daylighted_under_skylight_width = skylight_width + [0.7 * ceiling_height, distance_1].min + [0.7 * ceiling_height, distance_4].min
1640
+ daylighted_under_skylight_length = skylight_length + [0.7 * ceiling_height, distance_2].min + [0.7 * ceiling_height, distance_3].min
1641
+
1642
+ ##### As noted above, the width and length of the daylighted area under the skylight are re-calculated (as per NECB2011: 4.2.2.5.), if any exterior walls has window(s).
1643
+ ##### To this end, the window_head_height should be calculated, as below:
1644
+ daylight_space.surfaces.sort.each do |surface|
1645
+ if surface.outsideBoundaryCondition == "Outdoors" && surface.surfaceType == "Wall"
1646
+ wall_vertices_on_floor_x = []
1647
+ wall_vertices_on_floor_y = []
1648
+ wall_vertices = surface.vertices
1649
+ if wall_vertices[0].z == wall_vertices[1].z
1650
+ wall_vertices_on_floor_x << wall_vertices[0].x
1651
+ wall_vertices_on_floor_x << wall_vertices[1].x
1652
+ wall_vertices_on_floor_y << wall_vertices[0].y
1653
+ wall_vertices_on_floor_y << wall_vertices[1].y
1654
+ elsif wall_vertices[0].z == wall_vertices[3].z
1655
+ wall_vertices_on_floor_x << wall_vertices[0].x
1656
+ wall_vertices_on_floor_x << wall_vertices[3].x
1657
+ wall_vertices_on_floor_y << wall_vertices[0].y
1658
+ wall_vertices_on_floor_y << wall_vertices[3].y
1659
+ end
1660
+ window_vertices = subsurface.vertices
1661
+ window_head_height = [window_vertices[0].z, window_vertices[1].z, window_vertices[2].z, window_vertices[3].z].max.round(2)
1662
+
1663
+ ##### Calculate the exterior wall length (on the floor)
1664
+ exterior_wall_length = Math.sqrt((wall_vertices_on_floor_x[0] - wall_vertices_on_floor_x[1]) ** 2.0 + (wall_vertices_on_floor_y[0] - wall_vertices_on_floor_y[1]) ** 2.0)
1665
+
1666
+ ##### Calculate the vertical distance of skylight_vertices[0] projection onto the roof/floor to the exterior wall
1667
+ skylight_vertex_0_triangle_area = 0.5 * (((wall_vertices_on_floor_x[0] - wall_vertices_on_floor_x[1]) * (wall_vertices_on_floor_y[0] - skylight_vertices[0].y)) -
1668
+ ((wall_vertices_on_floor_x[0] - skylight_vertices[0].x) * (wall_vertices_on_floor_y[0] - wall_vertices_on_floor_y[1]))).abs
1669
+ skylight_vertex_0_distance = (2.0 * skylight_vertex_0_triangle_area) / exterior_wall_length
1670
+
1671
+ ##### Calculate the vertical distance of skylight_vertices[1] projection onto the roof/floor to the exterior wall
1672
+ skylight_vertex_1_triangle_area = 0.5 * (((wall_vertices_on_floor_x[0] - wall_vertices_on_floor_x[1]) * (wall_vertices_on_floor_y[0] - skylight_vertices[1].y)) -
1673
+ ((wall_vertices_on_floor_x[0] - skylight_vertices[1].x) * (wall_vertices_on_floor_y[0] - wall_vertices_on_floor_y[1]))).abs
1674
+ skylight_vertex_1_distance = (2.0 * skylight_vertex_1_triangle_area) / exterior_wall_length
1675
+
1676
+ ##### Calculate the vertical distance of skylight_vertices[3] projection onto the roof/floor to the exterior wall
1677
+ skylight_vertex_3_triangle_area = 0.5 * (((wall_vertices_on_floor_x[0] - wall_vertices_on_floor_x[1]) * (wall_vertices_on_floor_y[0] - skylight_vertices[3].y)) -
1678
+ ((wall_vertices_on_floor_x[0] - skylight_vertices[3].x) * (wall_vertices_on_floor_y[0] - wall_vertices_on_floor_y[1]))).abs
1679
+ skylight_vertex_3_distance = (2.0 * skylight_vertex_3_triangle_area) / exterior_wall_length
1680
+
1681
+ ##### Loop through the subsurfaces that has exterior windows to re-calculate the width and length of the daylighted area under the skylight
1682
+ surface.subSurfaces.sort.each do |subsurface|
1683
+ if subsurface.subSurfaceType == "FixedWindow" || subsurface.subSurfaceType == "OperableWindow"
1684
+
1685
+ if skylight_vertex_0_distance == skylight_vertex_1_distance #skylight_01 is in parellel to the exterior wall
1686
+ if skylight_vertex_0_distance.round(2) == distance_2.round(2)
1687
+ daylighted_under_skylight_length = skylight_length + [0.7 * ceiling_height, distance_2, distance_2 - window_head_height].min + [0.7 * ceiling_height, distance_3].min
1688
+ elsif skylight_vertex_0_distance.round(2) == distance_3.round(2)
1689
+ daylighted_under_skylight_length = skylight_length + [0.7 * ceiling_height, distance_2].min + [0.7 * ceiling_height, distance_3, distance_3 - window_head_height].min
1690
+ end
1691
+ elsif skylight_vertex_0_distance == skylight_vertex_3_distance #skylight_03 is in parellel to the exterior wall
1692
+ if skylight_vertex_0_distance.round(2) == distance_1.round(2)
1693
+ daylighted_under_skylight_width = skylight_width + [0.7 * ceiling_height, distance_1, distance_1 - window_head_height].min + [0.7 * ceiling_height, distance_4].min
1694
+ elsif skylight_vertex_0_distance.round(2) == distance_4.round(2)
1695
+ daylighted_under_skylight_width = skylight_width + [0.7 * ceiling_height, distance_1].min + [0.7 * ceiling_height, distance_4, distance_4 - window_head_height].min
1696
+ end
1697
+ end #if skylight_vertex_0_distance == skylight_vertex_1_distance
1698
+
1699
+ daylighted_under_skylight_area += daylighted_under_skylight_length * daylighted_under_skylight_width
1700
+
1701
+ end #if subsurface.subSurfaceType == "FixedWindow" || subsurface.subSurfaceType == "OperableWindow"
1702
+ end #surface.subSurfaces.each do |subsurface|
1703
+ end #if surface.outsideBoundaryCondition == "Outdoors" && surface.surfaceType == "Wall"
1704
+ end #daylight_space.surfaces.each do |surface|
1705
+
1706
+ end #if subsurface.subSurfaceType == "Skylight"
1707
+ end #surface.subSurfaces.each do |subsurface|
1708
+ end #daylight_space.surfaces.each do |surface|
1709
+
1710
+ return daylighted_under_skylight_area, skylight_area_weighted_vt_handle, skylight_area_sum
1711
+ end
1712
+
521
1713
  end