openstudio-standards 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (378) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE.md +33 -0
  3. data/data/inventory/thermal_bridging.csv +90 -0
  4. data/data/standards/OpenStudio_Standards-deer-comstock.xlsx +0 -0
  5. data/data/standards/manage_OpenStudio_Standards.rb +1 -1
  6. data/data/standards/test_performance_expected_dd_results.csv +2014 -1891
  7. data/lib/openstudio-standards/btap/analysis.rb +8 -8
  8. data/lib/openstudio-standards/btap/bridging.rb +664 -645
  9. data/lib/openstudio-standards/btap/btap.model.rb +14 -14
  10. data/lib/openstudio-standards/btap/btap.rb +7 -7
  11. data/lib/openstudio-standards/btap/btap_result.rb +1 -1
  12. data/lib/openstudio-standards/btap/economics.rb +23 -23
  13. data/lib/openstudio-standards/btap/envelope.rb +8 -8
  14. data/lib/openstudio-standards/btap/equest.rb +1 -1
  15. data/lib/openstudio-standards/btap/geometry.rb +2 -2
  16. data/lib/openstudio-standards/btap/mpc.rb +7 -7
  17. data/lib/openstudio-standards/btap/schedules.rb +1 -1
  18. data/lib/openstudio-standards/btap/simmanager.rb +4 -4
  19. data/lib/openstudio-standards/btap/spaceloads.rb +26 -26
  20. data/lib/openstudio-standards/btap/utilities.rb +6 -6
  21. data/lib/openstudio-standards/btap/vintagizer.rb +1 -1
  22. data/lib/openstudio-standards/constructions/information.rb +83 -0
  23. data/lib/openstudio-standards/constructions/materials/modify.rb +72 -0
  24. data/lib/openstudio-standards/constructions/modify.rb +80 -0
  25. data/lib/openstudio-standards/create_typical/create_typical.rb +983 -0
  26. data/lib/openstudio-standards/create_typical/enumerations.rb +484 -0
  27. data/lib/openstudio-standards/create_typical/space_type_blend.rb +791 -0
  28. data/lib/openstudio-standards/create_typical/space_type_ratios.rb +494 -0
  29. data/lib/openstudio-standards/daylighting/space.rb +47 -0
  30. data/lib/openstudio-standards/geometry/create.rb +801 -0
  31. data/lib/openstudio-standards/geometry/create_bar.rb +2170 -0
  32. data/lib/openstudio-standards/geometry/information.rb +462 -0
  33. data/lib/openstudio-standards/geometry/modify.rb +48 -0
  34. data/lib/openstudio-standards/hvac/air_loop/information.rb +79 -0
  35. data/lib/openstudio-standards/hvac/cbecs_hvac.rb +616 -0
  36. data/lib/openstudio-standards/hvac/setpoint_managers/information.rb +91 -0
  37. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirTerminalSingleDuctVAVReheat.rb +1 -1
  38. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.AirTerminalSingleDuctVAVReheat.rb +1 -1
  39. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
  40. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.Model.rb +1 -1
  41. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
  42. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.Model.rb +2 -2
  43. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.hvac_systems.rb +1 -1
  44. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
  45. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +4 -36
  46. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.hvac_systems.rb +1 -1
  47. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
  48. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +4 -36
  49. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Space.rb +3 -3
  50. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.hvac_systems.rb +1 -1
  51. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.AirTerminalSingleDuctVAVReheat.rb +1 -1
  52. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.Model.elevators.rb +1 -1
  53. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirTerminalSingleDuctVAVReheat.rb +1 -1
  54. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.CoilHeatingGas.rb +1 -1
  55. data/lib/openstudio-standards/prototypes/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.Model.elevators.rb +1 -1
  56. data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
  57. data/lib/openstudio-standards/prototypes/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
  58. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.College.rb +7 -7
  59. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Courthouse.rb +8 -8
  60. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.FullServiceRestaurant.rb +14 -14
  61. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.HighRiseApartment.rb +9 -9
  62. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Hospital.rb +16 -16
  63. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Laboratory.rb +7 -7
  64. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeDataCenterHighITE.rb +8 -8
  65. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeDataCenterLowITE.rb +8 -8
  66. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeHotel.rb +11 -11
  67. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOffice.rb +7 -7
  68. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeOfficeDetailed.rb +9 -9
  69. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOffice.rb +8 -8
  70. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MediumOfficeDetailed.rb +11 -11
  71. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.MidriseApartment.rb +9 -9
  72. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Outpatient.rb +19 -19
  73. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.PrimarySchool.rb +10 -10
  74. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.QuickServiceRestaurant.rb +13 -13
  75. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.RetailStandalone.rb +6 -6
  76. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.RetailStripmall.rb +6 -6
  77. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SecondarySchool.rb +9 -9
  78. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallDataCenterHighITE.rb +8 -8
  79. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallDataCenterLowITE.rb +8 -8
  80. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallHotel.rb +8 -8
  81. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOffice.rb +8 -8
  82. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SmallOfficeDetailed.rb +11 -11
  83. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperMarket.rb +10 -10
  84. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperTallBuilding.rb +19 -19
  85. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.TallBuilding.rb +18 -18
  86. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Warehouse.rb +6 -6
  87. data/lib/openstudio-standards/prototypes/common/do_not_edit_metaclasses.rb +957 -957
  88. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirConditionerVariableRefrigerantFlow.rb +1 -1
  89. data/lib/openstudio-standards/prototypes/common/objects/Prototype.AirTerminalSingleDuctVAVReheat.rb +1 -1
  90. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilCoolingWaterToAirHeatPumpEquationFit.rb +84 -16
  91. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingDXSingleSpeed.rb +1 -1
  92. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingGas.rb +1 -1
  93. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoilHeatingWaterToAirHeatPumpEquationFit.rb +61 -10
  94. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ControllerWaterCoil.rb +1 -1
  95. data/lib/openstudio-standards/prototypes/common/objects/Prototype.CoolingTower.rb +1 -1
  96. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Fan.rb +1 -1
  97. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanConstantVolume.rb +1 -1
  98. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanOnOff.rb +1 -1
  99. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanVariableVolume.rb +1 -1
  100. data/lib/openstudio-standards/prototypes/common/objects/Prototype.FanZoneExhaust.rb +1 -1
  101. data/lib/openstudio-standards/prototypes/common/objects/Prototype.HeatExchangerAirToAirSensibleAndLatent.rb +2 -2
  102. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.exterior_lights.rb +4 -4
  103. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.hvac.rb +4 -4
  104. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +43 -30
  105. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.swh.rb +1 -1
  106. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +18 -11
  107. data/lib/openstudio-standards/prototypes/common/objects/Prototype.SizingSystem.rb +1 -1
  108. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +774 -117
  109. data/lib/openstudio-standards/prototypes/common/objects/Prototype.radiant_system_controls.rb +340 -481
  110. data/lib/openstudio-standards/prototypes/common/objects/Prototype.refrigeration.rb +3 -3
  111. data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +3 -3
  112. data/lib/openstudio-standards/prototypes/common/prototype_metaprogramming.rb +22 -22
  113. data/lib/openstudio-standards/prototypes/deer/deer.Model.rb +1 -1
  114. data/lib/openstudio-standards/qaqc/calibration.rb +131 -0
  115. data/lib/openstudio-standards/qaqc/create_results.rb +983 -0
  116. data/lib/openstudio-standards/qaqc/envelope.rb +399 -0
  117. data/lib/openstudio-standards/qaqc/eui.rb +213 -0
  118. data/lib/openstudio-standards/qaqc/hvac.rb +1943 -0
  119. data/lib/openstudio-standards/qaqc/internal_loads.rb +568 -0
  120. data/lib/openstudio-standards/qaqc/reporting.rb +141 -0
  121. data/lib/openstudio-standards/qaqc/schedules.rb +129 -0
  122. data/lib/openstudio-standards/qaqc/service_water_heating.rb +273 -0
  123. data/lib/openstudio-standards/qaqc/weather_files.rb +497 -0
  124. data/lib/openstudio-standards/qaqc/zone_conditions.rb +278 -0
  125. data/lib/openstudio-standards/schedules/create.rb +364 -0
  126. data/lib/openstudio-standards/schedules/information.rb +169 -0
  127. data/lib/openstudio-standards/schedules/modify.rb +445 -0
  128. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +110 -71
  129. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctParallelPIUReheat.rb +3 -3
  130. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctVAVReheat.rb +4 -4
  131. data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +2 -1
  132. data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +16 -10
  133. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +4 -4
  134. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +1 -1
  135. data/lib/openstudio-standards/standards/Standards.CoilCoolingWaterToAirHeatPumpEquationFit.rb +1 -1
  136. data/lib/openstudio-standards/standards/Standards.CoilDX.rb +4 -4
  137. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +1 -1
  138. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +5 -5
  139. data/lib/openstudio-standards/standards/Standards.CoilHeatingGas.rb +1 -1
  140. data/lib/openstudio-standards/standards/Standards.CoilHeatingGasMultiStage.rb +1 -1
  141. data/lib/openstudio-standards/standards/Standards.CoilHeatingWaterToAirHeatPumpEquationFit.rb +1 -1
  142. data/lib/openstudio-standards/standards/Standards.Construction.rb +17 -18
  143. data/lib/openstudio-standards/standards/Standards.CoolingTower.rb +6 -6
  144. data/lib/openstudio-standards/standards/Standards.CoolingTowerSingleSpeed.rb +1 -1
  145. data/lib/openstudio-standards/standards/Standards.CoolingTowerTwoSpeed.rb +1 -1
  146. data/lib/openstudio-standards/standards/Standards.CoolingTowerVariableSpeed.rb +1 -1
  147. data/lib/openstudio-standards/standards/Standards.Fan.rb +6 -12
  148. data/lib/openstudio-standards/standards/Standards.FanVariableVolume.rb +2 -2
  149. data/lib/openstudio-standards/standards/Standards.FluidCooler.rb +1 -1
  150. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsVariableSpeed.rb +1 -1
  151. data/lib/openstudio-standards/standards/Standards.HeatExchangerSensLat.rb +3 -3
  152. data/lib/openstudio-standards/standards/Standards.Model.rb +411 -261
  153. data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +2 -2
  154. data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +94 -29
  155. data/lib/openstudio-standards/standards/Standards.Pump.rb +2 -2
  156. data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +2 -2
  157. data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +14 -14
  158. data/lib/openstudio-standards/standards/Standards.Space.rb +37 -30
  159. data/lib/openstudio-standards/standards/Standards.SpaceType.rb +38 -29
  160. data/lib/openstudio-standards/standards/Standards.SubSurface.rb +7 -7
  161. data/lib/openstudio-standards/standards/Standards.Surface.rb +13 -13
  162. data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +109 -66
  163. data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +11 -4
  164. data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +6 -6
  165. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.AirLoopHVAC.rb +1 -1
  166. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.PlantLoop.rb +1 -1
  167. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/ashrae_90_1_2004.Space.rb +1 -1
  168. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/ashrae_90_1_2007.Space.rb +1 -1
  169. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirLoopHVAC.rb +4 -4
  170. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.AirTerminalSingleDuctVAVReheat.rb +1 -1
  171. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/ashrae_90_1_2010.Space.rb +4 -4
  172. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirLoopHVAC.rb +4 -4
  173. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.AirTerminalSingleDuctVAVReheat.rb +1 -1
  174. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.CoolingTowerVariableSpeed.rb +1 -1
  175. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.Model.rb +5 -21
  176. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.Space.rb +4 -4
  177. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.WaterHeaterMixed.rb +1 -1
  178. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/ashrae_90_1_2013.ZoneHVACComponent.rb +1 -1
  179. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirLoopHVAC.rb +36 -4
  180. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.AirTerminalSingleDuctVAVReheat.rb +1 -1
  181. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.CoolingTowerVariableSpeed.rb +1 -1
  182. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Space.rb +4 -4
  183. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.ZoneHVACComponent.rb +1 -1
  184. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/comstock_ashrae_90_1_2016/comstock_ashrae_90_1_2016.AirLoopHVAC.rb +26 -0
  185. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +53 -10
  186. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirTerminalSingleDuctVAVReheat.rb +1 -1
  187. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.CoolingTowerVariableSpeed.rb +1 -1
  188. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Space.rb +6 -6
  189. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.ZoneHVACComponent.rb +2 -2
  190. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/comstock_ashrae_90_1_2019/comstock_ashrae_90_1_2019.AirLoopHVAC.rb +26 -0
  191. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.curves.json +211 -211
  192. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/data/doe_ref_1980_2004.economizers.json +14 -14
  193. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.AirLoopHVAC.rb +4 -4
  194. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.Model.rb +1 -1
  195. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.PlantLoop.rb +1 -1
  196. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/data/doe_ref_pre_1980.economizers.json +14 -14
  197. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirLoopHVAC.rb +4 -4
  198. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.Model.rb +1 -1
  199. data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.PlantLoop.rb +1 -1
  200. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirLoopHVAC.rb +6 -6
  201. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.AirTerminalSingleDuctVAVReheat.rb +1 -1
  202. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.CoolingTowerVariableSpeed.rb +1 -1
  203. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.PlantLoop.rb +1 -1
  204. data/lib/openstudio-standards/standards/ashrae_90_1/nrel_zne_ready_2017/nrel_zne_ready_2017.Space.rb +4 -4
  205. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirLoopHVAC.rb +6 -6
  206. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.AirTerminalSingleDuctVAVReheat.rb +1 -1
  207. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.CoolingTowerVariableSpeed.rb +1 -1
  208. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.PlantLoop.rb +1 -1
  209. data/lib/openstudio-standards/standards/ashrae_90_1/ze_aedg_multifamily/ze_aedg_multifamily.Space.rb +4 -4
  210. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +22 -28
  211. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctParallelPIUReheat.rb +1 -1
  212. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirTerminalSingleDuctVAVReheat.rb +2 -2
  213. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.BoilerHotWater.rb +1 -74
  214. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ChillerElectricEIR.rb +7 -59
  215. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXSingleSpeed.rb +1 -1
  216. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilCoolingDXTwoSpeed.rb +1 -1
  217. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilDX.rb +1 -1
  218. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingDXSingleSpeed.rb +1 -1
  219. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoilHeatingGas.rb +1 -21
  220. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.DesignSpecificationOutdoorAir.rb +101 -0
  221. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanConstantVolume.rb +1 -1
  222. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanOnOff.rb +1 -1
  223. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.FanVariableVolume.rb +1 -1
  224. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.HeatExchangerSensLat.rb +1 -1
  225. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +643 -526
  226. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlanarSurface.rb +8 -2
  227. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +17 -77
  228. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Space.rb +74 -16
  229. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.SpaceType.rb +96 -44
  230. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Surface.rb +6 -6
  231. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ThermalZone.rb +18 -6
  232. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.ZoneHVACComponent.rb +1 -1
  233. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.rb +328 -74
  234. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.Model.rb +0 -118
  235. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/ashrae_90_1_prm_2019.rb +2 -1
  236. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm_2019/data/ashrae_90_1_prm_2019.heat_rejection.json +1 -1
  237. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/baseline_outdoor_air.md +35 -0
  238. data/lib/openstudio-standards/standards/ashrae_90_1_prm/docs/set_plug_load_measures.md +1 -1
  239. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/ashrae_90_1_prm.UserData.rb +228 -0
  240. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_enums.rb +131 -0
  241. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/userdata_space.csv +1 -1
  242. data/lib/openstudio-standards/standards/cbes/cbes.AirLoopHVAC.rb +5 -5
  243. data/lib/openstudio-standards/standards/cbes/cbes.Model.rb +1 -1
  244. data/lib/openstudio-standards/standards/cbes/cbes.PlantLoop.rb +1 -1
  245. data/lib/openstudio-standards/standards/cbes/cbes.Space.rb +1 -1
  246. data/lib/openstudio-standards/standards/cbes/cbes_t24_2005/cbes_t24_2005.Space.rb +1 -1
  247. data/lib/openstudio-standards/standards/cbes/cbes_t24_2008/cbes_t24_2008.Space.rb +1 -1
  248. data/lib/openstudio-standards/standards/deer/deer.AirLoopHVAC.rb +109 -27
  249. data/lib/openstudio-standards/standards/deer/deer.Space.rb +1 -1
  250. data/lib/openstudio-standards/standards/deer/deer_1985/data/deer_1985.economizers.json +246 -4
  251. data/lib/openstudio-standards/standards/deer/deer_1996/data/deer_1996.economizers.json +246 -4
  252. data/lib/openstudio-standards/standards/deer/deer_2003/data/deer_2003.economizers.json +246 -4
  253. data/lib/openstudio-standards/standards/deer/deer_2003/deer_2003.ThermalZone.rb +18 -18
  254. data/lib/openstudio-standards/standards/deer/deer_2007/data/deer_2007.economizers.json +246 -4
  255. data/lib/openstudio-standards/standards/deer/deer_2007/deer_2007.ThermalZone.rb +18 -18
  256. data/lib/openstudio-standards/standards/deer/deer_2011/data/deer_2011.economizers.json +246 -4
  257. data/lib/openstudio-standards/standards/deer/deer_2011/deer_2011.ThermalZone.rb +18 -18
  258. data/lib/openstudio-standards/standards/deer/deer_2014/data/deer_2014.economizers.json +248 -6
  259. data/lib/openstudio-standards/standards/deer/deer_2014/deer_2014.Space.rb +3 -3
  260. data/lib/openstudio-standards/standards/deer/deer_2014/deer_2014.ThermalZone.rb +18 -18
  261. data/lib/openstudio-standards/standards/deer/deer_2015/data/deer_2015.economizers.json +248 -6
  262. data/lib/openstudio-standards/standards/deer/deer_2015/deer_2015.Space.rb +3 -3
  263. data/lib/openstudio-standards/standards/deer/deer_2015/deer_2015.ThermalZone.rb +18 -18
  264. data/lib/openstudio-standards/standards/deer/deer_2017/data/deer_2017.economizers.json +248 -6
  265. data/lib/openstudio-standards/standards/deer/deer_2017/deer_2017.Space.rb +3 -3
  266. data/lib/openstudio-standards/standards/deer/deer_2017/deer_2017.ThermalZone.rb +18 -18
  267. data/lib/openstudio-standards/standards/deer/deer_2020/data/deer_2020.economizers.json +248 -6
  268. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.AirLoopHVAC.rb +18 -5
  269. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.FanVariableVolume.rb +1 -1
  270. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.Space.rb +3 -3
  271. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.ThermalZone.rb +18 -18
  272. data/lib/openstudio-standards/standards/deer/deer_2025/data/deer_2025.economizers.json +248 -6
  273. data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.AirLoopHVAC.rb +3 -3
  274. data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.FanVariableVolume.rb +1 -1
  275. data/lib/openstudio-standards/standards/deer/deer_2025/deer_2025.Space.rb +3 -3
  276. data/lib/openstudio-standards/standards/deer/deer_2030/data/deer_2030.economizers.json +248 -6
  277. data/lib/openstudio-standards/standards/deer/deer_2030/data/deer_2030.heat_pumps.json +2 -2
  278. data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.AirLoopHVAC.rb +3 -3
  279. data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.FanVariableVolume.rb +1 -1
  280. data/lib/openstudio-standards/standards/deer/deer_2030/deer_2030.Space.rb +3 -3
  281. data/lib/openstudio-standards/standards/deer/deer_2035/data/deer_2035.economizers.json +248 -6
  282. data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.AirLoopHVAC.rb +3 -3
  283. data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.FanVariableVolume.rb +1 -1
  284. data/lib/openstudio-standards/standards/deer/deer_2035/deer_2035.Space.rb +3 -3
  285. data/lib/openstudio-standards/standards/deer/deer_2040/data/deer_2040.economizers.json +248 -6
  286. data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.AirLoopHVAC.rb +3 -3
  287. data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.FanVariableVolume.rb +1 -1
  288. data/lib/openstudio-standards/standards/deer/deer_2040/deer_2040.Space.rb +3 -3
  289. data/lib/openstudio-standards/standards/deer/deer_2045/data/deer_2045.economizers.json +260 -0
  290. data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.AirLoopHVAC.rb +3 -3
  291. data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.FanVariableVolume.rb +1 -1
  292. data/lib/openstudio-standards/standards/deer/deer_2045/deer_2045.Space.rb +3 -3
  293. data/lib/openstudio-standards/standards/deer/deer_2050/data/deer_2050.economizers.json +248 -6
  294. data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.AirLoopHVAC.rb +3 -3
  295. data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.FanVariableVolume.rb +1 -1
  296. data/lib/openstudio-standards/standards/deer/deer_2050/deer_2050.Space.rb +3 -3
  297. data/lib/openstudio-standards/standards/deer/deer_2055/data/deer_2055.economizers.json +248 -6
  298. data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.AirLoopHVAC.rb +3 -3
  299. data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.FanVariableVolume.rb +1 -1
  300. data/lib/openstudio-standards/standards/deer/deer_2055/deer_2055.Space.rb +3 -3
  301. data/lib/openstudio-standards/standards/deer/deer_2060/data/deer_2060.economizers.json +248 -6
  302. data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.AirLoopHVAC.rb +3 -3
  303. data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.FanVariableVolume.rb +1 -1
  304. data/lib/openstudio-standards/standards/deer/deer_2060/deer_2060.Space.rb +3 -3
  305. data/lib/openstudio-standards/standards/deer/deer_2065/data/deer_2065.economizers.json +248 -6
  306. data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.AirLoopHVAC.rb +3 -3
  307. data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.FanVariableVolume.rb +1 -1
  308. data/lib/openstudio-standards/standards/deer/deer_2065/deer_2065.Space.rb +3 -3
  309. data/lib/openstudio-standards/standards/deer/deer_2070/data/deer_2070.economizers.json +248 -6
  310. data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.AirLoopHVAC.rb +3 -3
  311. data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.FanVariableVolume.rb +1 -1
  312. data/lib/openstudio-standards/standards/deer/deer_2070/deer_2070.Space.rb +3 -3
  313. data/lib/openstudio-standards/standards/deer/deer_2075/data/deer_2075.economizers.json +248 -6
  314. data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.AirLoopHVAC.rb +3 -3
  315. data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.FanVariableVolume.rb +1 -1
  316. data/lib/openstudio-standards/standards/deer/deer_2075/deer_2075.Space.rb +3 -3
  317. data/lib/openstudio-standards/standards/deer/deer_pre_1975/data/deer_pre_1975.economizers.json +246 -4
  318. data/lib/openstudio-standards/standards/necb/BTAP1980TO2010/data/space_types.json +447 -223
  319. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/building_envelope.rb +1 -1
  320. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/data/space_types.json +447 -223
  321. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_systems.rb +5 -2
  322. data/lib/openstudio-standards/standards/necb/ECMS/data/chiller_types.json +25 -0
  323. data/lib/openstudio-standards/standards/necb/ECMS/data/chillers.json +44 -0
  324. data/lib/openstudio-standards/standards/necb/ECMS/data/curves.json +225 -0
  325. data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +2 -2
  326. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +193 -73
  327. data/lib/openstudio-standards/standards/necb/ECMS/pv_ground.rb +1 -1
  328. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +10 -4
  329. data/lib/openstudio-standards/standards/necb/NECB2011/beps_compliance_path.rb +7 -7
  330. data/lib/openstudio-standards/standards/necb/NECB2011/building_envelope.rb +4 -5
  331. data/lib/openstudio-standards/standards/necb/NECB2011/data/chiller_types.json +32 -0
  332. data/lib/openstudio-standards/standards/necb/NECB2011/data/chillers.json +1 -1
  333. data/lib/openstudio-standards/standards/necb/NECB2011/data/constants.json +36 -0
  334. data/lib/openstudio-standards/standards/necb/NECB2011/data/fuel_type_sets.json +7 -7
  335. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernEducation.osm +47587 -0
  336. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/NorthernHealthCare.osm +49764 -0
  337. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/Warehouse.osm +283 -297
  338. data/lib/openstudio-standards/standards/necb/NECB2011/data/space_type_unit_definitions.txt +2 -1
  339. data/lib/openstudio-standards/standards/necb/NECB2011/data/space_types.json +447 -223
  340. data/lib/openstudio-standards/standards/necb/NECB2011/data/standards_data.rb +3 -3
  341. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_multi_speed.rb +1 -1
  342. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +49 -27
  343. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +400 -202
  344. data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +4 -4
  345. data/lib/openstudio-standards/standards/necb/NECB2015/data/space_types.json +637 -318
  346. data/lib/openstudio-standards/standards/necb/NECB2015/hvac_systems.rb +18 -1
  347. data/lib/openstudio-standards/standards/necb/NECB2015/necb_2015.rb +3 -3
  348. data/lib/openstudio-standards/standards/necb/NECB2017/data/space_types.json +637 -318
  349. data/lib/openstudio-standards/standards/necb/NECB2017/hvac_systems.rb +1 -1
  350. data/lib/openstudio-standards/standards/necb/NECB2017/necb_2017.rb +3 -3
  351. data/lib/openstudio-standards/standards/necb/NECB2020/building_envelope.rb +1 -1
  352. data/lib/openstudio-standards/standards/necb/NECB2020/data/space_types.json +615 -307
  353. data/lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb +4 -4
  354. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +10 -5
  355. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +1 -1
  356. data/lib/openstudio-standards/utilities/assertion.rb +128 -0
  357. data/lib/openstudio-standards/utilities/logging.rb +2 -3
  358. data/lib/openstudio-standards/utilities/object_info.rb +39 -18
  359. data/lib/openstudio-standards/utilities/schedule_translator.rb +8 -6
  360. data/lib/openstudio-standards/utilities/simulation.rb +24 -11
  361. data/lib/openstudio-standards/utilities/sqlfile.rb +10 -5
  362. data/lib/openstudio-standards/version.rb +1 -1
  363. data/lib/openstudio-standards/weather/Weather.Model.rb +8 -9
  364. data/lib/openstudio-standards/weather/Weather.stat_file.rb +3 -3
  365. data/lib/openstudio-standards/weather/information.rb +35 -0
  366. data/lib/openstudio-standards.rb +69 -5
  367. metadata +54 -18
  368. data/License.txt +0 -65
  369. data/data/standards/OpenStudio_Standards-deer-ALL-comstock(space_types).xlsx +0 -0
  370. data/lib/openstudio-standards/hvac_sizing/Siz.AirLoopHVAC.rb +0 -59
  371. data/lib/openstudio-standards/hvac_sizing/Siz.CoilCoolingWater.rb +0 -13
  372. data/lib/openstudio-standards/hvac_sizing/Siz.HVACComponent.rb +0 -36
  373. data/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb +0 -898
  374. data/lib/openstudio-standards/hvac_sizing/Siz.Model.rb +0 -126
  375. data/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb +0 -356
  376. data/lib/openstudio-standards/prototypes/ashrae_90_1/nrel_nze_ready_2017/nrel_zne_ready_2017.Model.rb +0 -35
  377. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTower.rb +0 -110
  378. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.CoolingTowerVariableSpeed.rb +0 -5
@@ -0,0 +1,801 @@
1
+ # Methods to create geometry
2
+ module OpenstudioStandards
3
+ module Geometry
4
+ # @!group Create
5
+
6
+ # method to create a point object at the center of a floor
7
+ #
8
+ # @param space [OpenStudio::Model::Space] OpenStudio Space object
9
+ # @param z_offset_m [Double] vertical offset in meters
10
+ # @return [OpenStudio::Point3d] point at the center of the space. return nil if point is not on floor in space.
11
+ def self.space_create_point_at_center_of_floor(space, z_offset_m)
12
+ # find floors
13
+ floor_surfaces = []
14
+ space.surfaces.each { |surface| floor_surfaces << surface if surface.surfaceType == 'Floor' }
15
+
16
+ # this method only works for flat (non-inclined) floors
17
+ bounding_box = OpenStudio::BoundingBox.new
18
+ floor_surfaces.each { |floor| bounding_box.addPoints(floor.vertices) }
19
+ xmin = bounding_box.minX.get
20
+ ymin = bounding_box.minY.get
21
+ zmin = bounding_box.minZ.get
22
+ xmax = bounding_box.maxX.get
23
+ ymax = bounding_box.maxY.get
24
+
25
+ x_pos = (xmin + xmax) / 2
26
+ y_pos = (ymin + ymax) / 2
27
+ z_pos = zmin + z_offset_m
28
+ point_on_floor = OpenstudioStandards::Geometry.surfaces_contain_point?(floor_surfaces, OpenStudio::Point3d.new(x_pos, y_pos, zmin))
29
+
30
+ if point_on_floor
31
+ new_point = OpenStudio::Point3d.new(x_pos, y_pos, z_pos)
32
+ else
33
+ # don't make point, it doesn't appear to be inside of the space
34
+ new_point = nil
35
+ end
36
+
37
+ return new_point
38
+ end
39
+
40
+ # method to create a point object from a sub surface
41
+ #
42
+ # @param sub_surface [OpenStudio::Model::SubSurface] OpenStudio SubSurface object
43
+ # @param reference_floor [OpenStudio::Model::SubSurface] OpenStudio SubSurface object
44
+ # @param distance_from_window_m [Double] distance in from the window, in meters
45
+ # @param height_above_subsurface_bottom_m [Double] height above the bottom of the subsurface, in meters
46
+ # @return [OpenStudio::Point3d] point at the center of the space. return nil if point is not on floor in space.
47
+ def self.sub_surface_create_point_at_specific_height(sub_surface, reference_floor, distance_from_window_m, height_above_subsurface_bottom_m)
48
+ window_outward_normal = sub_surface.outwardNormal
49
+ window_centroid = OpenStudio.getCentroid(sub_surface.vertices).get
50
+ window_outward_normal.setLength(distance_from_window_m)
51
+ vertex = window_centroid + window_outward_normal.reverseVector
52
+ vertex_on_floorplane = reference_floor.plane.project(vertex)
53
+ floor_outward_normal = reference_floor.outwardNormal
54
+ floor_outward_normal.setLength(height_above_subsurface_bottom_m)
55
+
56
+ floor_surfaces = []
57
+ space.surfaces.each { |surface| floor_surfaces << surface if surface.surfaceType == 'Floor' }
58
+
59
+ point_on_floor = OpenstudioStandards::Geometry.surfaces_contain_point?(floor_surfaces, vertex_on_floorplane)
60
+
61
+ if point_on_floor
62
+ new_point = vertex_on_floorplane + floor_outward_normal.reverseVector
63
+ else
64
+ # don't make point, it doesn't appear to be inside of the space
65
+ # nil
66
+ new_point = vertex_on_floorplane + floor_outward_normal.reverseVector
67
+ end
68
+
69
+ return new_point
70
+ end
71
+
72
+ # create core and perimeter polygons from length width and origin
73
+ #
74
+ # @param length [Double] length of building in meters
75
+ # @param width [Double] width of building in meters
76
+ # @param footprint_origin_point [OpenStudio::Point3d] Optional OpenStudio Point3d object for the new origin
77
+ # @param perimeter_zone_depth [Double] Optional perimeter zone depth in meters
78
+ # @return [Hash] Hash of point vectors that define the space geometry for each direction
79
+ def self.create_core_and_perimeter_polygons(length, width,
80
+ footprint_origin_point = OpenStudio::Point3d.new(0.0, 0.0, 0.0),
81
+ perimeter_zone_depth = OpenStudio.convert(15.0, 'ft', 'm').get)
82
+ # key is name, value is a hash, one item of which is polygon. Another could be space type.
83
+ hash_of_point_vectors = {}
84
+
85
+ # determine if core and perimeter zoning can be used
86
+ if !(length > perimeter_zone_depth * 2.5 && width > perimeter_zone_depth * 2.5)
87
+ # if any size is to small then just model floor as single zone, issue warning
88
+ perimeter_zone_depth = 0.0
89
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Geometry.Create', 'Due to the size of the building modeling each floor as a single zone.')
90
+ end
91
+
92
+ x_delta = footprint_origin_point.x - length / 2.0
93
+ y_delta = footprint_origin_point.y - width / 2.0
94
+ z = 0
95
+ nw_point = OpenStudio::Point3d.new(x_delta, y_delta + width, z)
96
+ ne_point = OpenStudio::Point3d.new(x_delta + length, y_delta + width, z)
97
+ se_point = OpenStudio::Point3d.new(x_delta + length, y_delta, z)
98
+ sw_point = OpenStudio::Point3d.new(x_delta, y_delta, z)
99
+
100
+ # Define polygons for a rectangular building
101
+ if perimeter_zone_depth > 0
102
+ perimeter_nw_point = nw_point + OpenStudio::Vector3d.new(perimeter_zone_depth, -perimeter_zone_depth, 0)
103
+ perimeter_ne_point = ne_point + OpenStudio::Vector3d.new(-perimeter_zone_depth, -perimeter_zone_depth, 0)
104
+ perimeter_se_point = se_point + OpenStudio::Vector3d.new(-perimeter_zone_depth, perimeter_zone_depth, 0)
105
+ perimeter_sw_point = sw_point + OpenStudio::Vector3d.new(perimeter_zone_depth, perimeter_zone_depth, 0)
106
+
107
+ west_polygon = OpenStudio::Point3dVector.new
108
+ west_polygon << sw_point
109
+ west_polygon << nw_point
110
+ west_polygon << perimeter_nw_point
111
+ west_polygon << perimeter_sw_point
112
+ hash_of_point_vectors['West Perimeter Space'] = {}
113
+ hash_of_point_vectors['West Perimeter Space'][:space_type] = nil # other methods being used by makeSpacesFromPolygons may have space types associated with each polygon but this doesn't.
114
+ hash_of_point_vectors['West Perimeter Space'][:polygon] = west_polygon
115
+
116
+ north_polygon = OpenStudio::Point3dVector.new
117
+ north_polygon << nw_point
118
+ north_polygon << ne_point
119
+ north_polygon << perimeter_ne_point
120
+ north_polygon << perimeter_nw_point
121
+ hash_of_point_vectors['North Perimeter Space'] = {}
122
+ hash_of_point_vectors['North Perimeter Space'][:space_type] = nil
123
+ hash_of_point_vectors['North Perimeter Space'][:polygon] = north_polygon
124
+
125
+ east_polygon = OpenStudio::Point3dVector.new
126
+ east_polygon << ne_point
127
+ east_polygon << se_point
128
+ east_polygon << perimeter_se_point
129
+ east_polygon << perimeter_ne_point
130
+ hash_of_point_vectors['East Perimeter Space'] = {}
131
+ hash_of_point_vectors['East Perimeter Space'][:space_type] = nil
132
+ hash_of_point_vectors['East Perimeter Space'][:polygon] = east_polygon
133
+
134
+ south_polygon = OpenStudio::Point3dVector.new
135
+ south_polygon << se_point
136
+ south_polygon << sw_point
137
+ south_polygon << perimeter_sw_point
138
+ south_polygon << perimeter_se_point
139
+ hash_of_point_vectors['South Perimeter Space'] = {}
140
+ hash_of_point_vectors['South Perimeter Space'][:space_type] = nil
141
+ hash_of_point_vectors['South Perimeter Space'][:polygon] = south_polygon
142
+
143
+ core_polygon = OpenStudio::Point3dVector.new
144
+ core_polygon << perimeter_sw_point
145
+ core_polygon << perimeter_nw_point
146
+ core_polygon << perimeter_ne_point
147
+ core_polygon << perimeter_se_point
148
+ hash_of_point_vectors['Core Space'] = {}
149
+ hash_of_point_vectors['Core Space'][:space_type] = nil
150
+ hash_of_point_vectors['Core Space'][:polygon] = core_polygon
151
+
152
+ # Minimal zones
153
+ else
154
+ whole_story_polygon = OpenStudio::Point3dVector.new
155
+ whole_story_polygon << sw_point
156
+ whole_story_polygon << nw_point
157
+ whole_story_polygon << ne_point
158
+ whole_story_polygon << se_point
159
+ hash_of_point_vectors['Whole Story Space'] = {}
160
+ hash_of_point_vectors['Whole Story Space'][:space_type] = nil
161
+ hash_of_point_vectors['Whole Story Space'][:polygon] = whole_story_polygon
162
+ end
163
+
164
+ return hash_of_point_vectors
165
+ end
166
+
167
+ # sliced bar multi creates and array of multiple sliced bar simple hashes
168
+ #
169
+ # @param space_types [Array<Hash>] Array of hashes with the space type and floor area
170
+ # @param length [Double] length of building in meters
171
+ # @param width [Double] width of building in meters
172
+ # @param footprint_origin_point [OpenStudio::Point3d] OpenStudio Point3d object for the new origin
173
+ # @param story_hash [Hash] A hash of building story information including space origin z value and space height
174
+ # @return [Hash] Hash of point vectors that define the space geometry for each direction
175
+ def self.create_sliced_bar_multi_polygons(space_types, length, width, footprint_origin_point, story_hash)
176
+ # total building floor area to calculate ratios from space type floor areas
177
+ total_floor_area = 0.0
178
+ target_per_space_type = {}
179
+ space_types.each do |space_type, space_type_hash|
180
+ total_floor_area += space_type_hash[:floor_area]
181
+ target_per_space_type[space_type] = space_type_hash[:floor_area]
182
+ end
183
+
184
+ # sort array by floor area, this hash will be altered to reduce floor area for each space type to 0
185
+ space_types_running_count = space_types.sort_by { |k, v| v[:floor_area] }
186
+
187
+ # array entry for each story
188
+ footprints = []
189
+
190
+ # variables for sliver check
191
+ # re-evaluate what the default should be
192
+ valid_bar_width_min_m = OpenStudio.convert(3.0, 'ft', 'm').get
193
+ # building width
194
+ bar_length = width
195
+ valid_bar_area_min_m2 = valid_bar_width_min_m * bar_length
196
+
197
+ # loop through stories to populate footprints
198
+ story_hash.each_with_index do |(k, v), i|
199
+ # update the length and width for partial floors
200
+ if i + 1 == story_hash.size
201
+ area_multiplier = v[:partial_story_multiplier]
202
+ edge_multiplier = Math.sqrt(area_multiplier)
203
+ length *= edge_multiplier
204
+ width *= edge_multiplier
205
+ end
206
+
207
+ # this will be populated for each building story
208
+ target_footprint_area = v[:multiplier] * length * width
209
+ current_footprint_area = 0.0
210
+ space_types_local_count = {}
211
+
212
+ space_types_running_count.each do |space_type, space_type_hash|
213
+ # next if floor area is full or space type is empty
214
+
215
+ tol_value = 0.0001
216
+ next if current_footprint_area + tol_value >= target_footprint_area
217
+ next if space_type_hash[:floor_area] <= tol_value
218
+
219
+ # special test for when total floor area is smaller than valid_bar_area_min_m2, just make bar smaller that valid min and warn user
220
+ if target_per_space_type[space_type] < valid_bar_area_min_m2
221
+ sliver_override = true
222
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Geometry.Create', "Floor area of #{space_type.name} results in a bar with smaller than target minimum width.")
223
+ else
224
+ sliver_override = false
225
+ end
226
+
227
+ # add entry for space type if it doesn't have one yet
228
+ if !space_types_local_count.key?(space_type)
229
+ if space_type_hash.key?(:children)
230
+ space_type = space_type_hash[:children][:default][:space_type] # will re-using space type create issue
231
+ space_types_local_count[space_type] = { floor_area: 0.0 }
232
+ space_types_local_count[space_type][:children] = space_type_hash[:children]
233
+ else
234
+ space_types_local_count[space_type] = { floor_area: 0.0 }
235
+ end
236
+ end
237
+
238
+ # if there is enough of this space type to fill rest of floor area
239
+ remaining_in_footprint = target_footprint_area - current_footprint_area
240
+ raw_footprint_area_used = [space_type_hash[:floor_area], remaining_in_footprint].min
241
+
242
+ # add to local hash
243
+ space_types_local_count[space_type][:floor_area] = raw_footprint_area_used / v[:multiplier].to_f
244
+
245
+ # adjust balance ot running and local counts
246
+ current_footprint_area += raw_footprint_area_used
247
+ space_type_hash[:floor_area] -= raw_footprint_area_used
248
+
249
+ # test if think sliver left on current floor.
250
+ # fix by moving smallest space type to next floor and and the same amount more of the sliver space type to this story
251
+ raw_footprint_area_used < valid_bar_area_min_m2 && sliver_override == false ? (test_a = true) : (test_a = false)
252
+
253
+ # test if what would be left of the current space type would result in a sliver on the next story.
254
+ # fix by removing some of this space type so their is enough left for the next story, and replace the removed amount with the largest space type in the model
255
+ (space_type_hash[:floor_area] < valid_bar_area_min_m2) && (space_type_hash[:floor_area] > tol_value) ? (test_b = true) : (test_b = false)
256
+
257
+ # identify very small slices and re-arrange spaces to different stories to avoid this
258
+ if test_a
259
+
260
+ # get first/smallest space type to move to another story
261
+ first_space = space_types_local_count.first
262
+
263
+ # adjustments running counter for space type being removed from this story
264
+ space_types_running_count.each do |k2, v2|
265
+ next if k2 != first_space[0]
266
+
267
+ v2[:floor_area] += first_space[1][:floor_area] * v[:multiplier]
268
+ end
269
+
270
+ # adjust running count for current space type
271
+ space_type_hash[:floor_area] -= first_space[1][:floor_area] * v[:multiplier]
272
+
273
+ # add to local count for current space type
274
+ space_types_local_count[space_type][:floor_area] += first_space[1][:floor_area]
275
+
276
+ # remove from local count for removed space type
277
+ space_types_local_count.shift
278
+
279
+ elsif test_b
280
+
281
+ # swap size
282
+ swap_size = valid_bar_area_min_m2 * 5.0 # currently equal to default perimeter zone depth of 15'
283
+ # this prevents too much area from being swapped resulting in a negative number for floor area
284
+ if swap_size > space_types_local_count[space_type][:floor_area] * v[:multiplier].to_f
285
+ swap_size = space_types_local_count[space_type][:floor_area] * v[:multiplier].to_f
286
+ end
287
+
288
+ # adjust running count for current space type
289
+ space_type_hash[:floor_area] += swap_size
290
+
291
+ # remove from local count for current space type
292
+ space_types_local_count[space_type][:floor_area] -= swap_size / v[:multiplier].to_f
293
+
294
+ # adjust footprint used
295
+ current_footprint_area -= swap_size
296
+
297
+ # the next larger space type will be brought down to fill out the footprint without any additional code
298
+ end
299
+ end
300
+
301
+ # creating footprint for story
302
+ footprints << OpenstudioStandards::Geometry.create_sliced_bar_simple_polygons(space_types_local_count, length, width, footprint_origin_point)
303
+ end
304
+ return footprints
305
+ end
306
+
307
+ # sliced bar simple creates a single sliced bar for space types passed in
308
+ # look at length and width to adjust slicing direction
309
+ #
310
+ # @param space_types [Array<Hash>] Array of hashes with the space type and floor area
311
+ # @param length [Double] length of building in meters
312
+ # @param width [Double] width of building in meters
313
+ # @param footprint_origin_point [OpenStudio::Point3d] Optional OpenStudio Point3d object for the new origin
314
+ # @param perimeter_zone_depth [Double] Optional perimeter zone depth in meters
315
+ # @return [Hash] Hash of point vectors that define the space geometry for each direction
316
+ def self.create_sliced_bar_simple_polygons(space_types, length, width,
317
+ footprint_origin_point = OpenStudio::Point3d.new(0.0, 0.0, 0.0),
318
+ perimeter_zone_depth = OpenStudio.convert(15.0, 'ft', 'm').get)
319
+ hash_of_point_vectors = {} # key is name, value is a hash, one item of which is polygon. Another could be space type
320
+
321
+ reverse_slice = false
322
+ if length < width
323
+ reverse_slice = true
324
+ # OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Geometry.Create', "Reverse typical slice direction for bar because of aspect ratio less than 1.0.")
325
+ end
326
+
327
+ # determine if core and perimeter zoning can be used
328
+ if !([length, width].min > perimeter_zone_depth * 2.5 && [length, width].min > perimeter_zone_depth * 2.5)
329
+ perimeter_zone_depth = 0 # if any size is to small then just model floor as single zone, issue warning
330
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Geometry.Create', 'Not modeling core and perimeter zones for some portion of the model.')
331
+ end
332
+
333
+ x_delta = footprint_origin_point.x - length / 2.0
334
+ y_delta = footprint_origin_point.y - width / 2.0
335
+ z = 0.0
336
+ # this represents the entire bar, not individual space type slices
337
+ nw_point = OpenStudio::Point3d.new(x_delta, y_delta + width, z)
338
+ sw_point = OpenStudio::Point3d.new(x_delta, y_delta, z)
339
+ # used when length is less than width
340
+ se_point = OpenStudio::Point3d.new(x_delta + length, y_delta, z)
341
+
342
+ # total building floor area to calculate ratios from space type floor areas
343
+ total_floor_area = 0.0
344
+ space_types.each do |space_type, space_type_hash|
345
+ total_floor_area += space_type_hash[:floor_area]
346
+ end
347
+
348
+ # sort array by floor area but shift largest object to front
349
+ space_types = space_types.sort_by { |k, v| v[:floor_area] }
350
+ space_types.insert(0, space_types.delete_at(space_types.size - 1)) # .to_h
351
+
352
+ # min and max bar end values
353
+ min_bar_end_multiplier = 0.75
354
+ max_bar_end_multiplier = 1.5
355
+
356
+ # sort_by results in arrays with two items , first is key, second is hash value
357
+ re_apply_largest_space_type_at_end = false
358
+ max_reduction = nil # used when looping through section_hash_for_space_type if first space type needs to also be at far end of bar
359
+ space_types.each do |space_type, space_type_hash|
360
+ # setup end perimeter zones if needed
361
+ start_perimeter_width_deduction = 0.0
362
+ end_perimeter_width_deduction = 0.0
363
+ if space_type == space_types.first[0]
364
+ if [length, width].max * space_type_hash[:floor_area] / total_floor_area > max_bar_end_multiplier * perimeter_zone_depth
365
+ start_perimeter_width_deduction = perimeter_zone_depth
366
+ end
367
+ # see if last space type is too small for perimeter. If it is then save some of this space type
368
+ if [length, width].max * space_types.last[1][:floor_area] / total_floor_area < perimeter_zone_depth * min_bar_end_multiplier
369
+ re_apply_largest_space_type_at_end = true
370
+ end
371
+ end
372
+ if space_type == space_types.last[0]
373
+ if [length, width].max * space_type_hash[:floor_area] / total_floor_area > max_bar_end_multiplier * perimeter_zone_depth
374
+ end_perimeter_width_deduction = perimeter_zone_depth
375
+ end
376
+ end
377
+ non_end_adjusted_width = ([length, width].max * space_type_hash[:floor_area] / total_floor_area) - start_perimeter_width_deduction - end_perimeter_width_deduction
378
+
379
+ # adjustment of end space type is too small and is replaced with largest space type
380
+ if (space_type == space_types.first[0]) && re_apply_largest_space_type_at_end
381
+ max_reduction = [perimeter_zone_depth, non_end_adjusted_width].min
382
+ non_end_adjusted_width -= max_reduction
383
+ end
384
+ if (space_type == space_types.last[0]) && re_apply_largest_space_type_at_end
385
+ end_perimeter_width_deduction = space_types.first[0]
386
+ end_b_flag = true
387
+ else
388
+ end_b_flag = false
389
+ end
390
+
391
+ # populate data for core and perimeter of slice
392
+ section_hash_for_space_type = {}
393
+ section_hash_for_space_type['end_a'] = start_perimeter_width_deduction
394
+ section_hash_for_space_type[''] = non_end_adjusted_width
395
+ section_hash_for_space_type['end_b'] = end_perimeter_width_deduction
396
+
397
+ # determine if this space+type is double loaded corridor, and if so what the perimeter zone depth should be based on building width
398
+ # look at reverse_slice to see if length or width should be used to determine perimeter depth
399
+ if space_type_hash.key?(:children)
400
+ core_ratio = space_type_hash[:children][:circ][:orig_ratio]
401
+ perim_ratio = space_type_hash[:children][:default][:orig_ratio]
402
+ core_ratio_adj = core_ratio / (core_ratio + perim_ratio)
403
+ perim_ratio_adj = perim_ratio / (core_ratio + perim_ratio)
404
+ core_space_type = space_type_hash[:children][:circ][:space_type]
405
+ perim_space_type = space_type_hash[:children][:default][:space_type]
406
+ if !reverse_slice
407
+ custom_cor_val = width * core_ratio_adj
408
+ custom_perim_val = (width - custom_cor_val) / 2.0
409
+ else
410
+ custom_cor_val = length * core_ratio_adj
411
+ custom_perim_val = (length - custom_cor_val) / 2.0
412
+ end
413
+ actual_perim = custom_perim_val
414
+ double_loaded_corridor = true
415
+ else
416
+ actual_perim = perimeter_zone_depth
417
+ double_loaded_corridor = false
418
+ end
419
+
420
+ # may overwrite
421
+ first_space_type_hash = space_types.first[1]
422
+ if end_b_flag && first_space_type_hash.key?(:children)
423
+ end_b_core_ratio = first_space_type_hash[:children][:circ][:orig_ratio]
424
+ end_b_perim_ratio = first_space_type_hash[:children][:default][:orig_ratio]
425
+ end_b_core_ratio_adj = end_b_core_ratio / (end_b_core_ratio + end_b_perim_ratio)
426
+ end_b_perim_ratio_adj = end_b_perim_ratio / (end_b_core_ratio + end_b_perim_ratio)
427
+ end_b_core_space_type = first_space_type_hash[:children][:circ][:space_type]
428
+ end_b_perim_space_type = first_space_type_hash[:children][:default][:space_type]
429
+ if !reverse_slice
430
+ end_b_custom_cor_val = width * end_b_core_ratio_adj
431
+ end_b_custom_perim_val = (width - end_b_custom_cor_val) / 2.0
432
+ else
433
+ end_b_custom_cor_val = length * end_b_core_ratio_adj
434
+ end_b_custom_perim_val = (length - end_b_custom_cor_val) / 2.0
435
+ end
436
+ end_b_actual_perim = end_b_custom_perim_val
437
+ end_b_double_loaded_corridor = true
438
+ else
439
+ end_b_actual_perim = perimeter_zone_depth
440
+ end_b_double_loaded_corridor = false
441
+ end
442
+
443
+ # loop through sections for space type (main and possibly one or two end perimeter sections)
444
+ section_hash_for_space_type.each do |k, slice|
445
+ # need to use different space type for end_b
446
+ if end_b_flag && k == 'end_b' && space_types.first[1].key?(:children)
447
+ slice = space_types.first[0]
448
+ actual_perim = end_b_actual_perim
449
+ double_loaded_corridor = end_b_double_loaded_corridor
450
+ core_ratio = end_b_core_ratio
451
+ perim_ratio = end_b_perim_ratio
452
+ core_ratio_adj = end_b_core_ratio_adj
453
+ perim_ratio_adj = end_b_perim_ratio_adj
454
+ core_space_type = end_b_core_space_type
455
+ perim_space_type = end_b_perim_space_type
456
+ end
457
+
458
+ if slice.class.to_s == 'OpenStudio::Model::SpaceType' || slice.class.to_s == 'OpenStudio::Model::Building'
459
+ space_type = slice
460
+ max_reduction = [perimeter_zone_depth, max_reduction].min
461
+ slice = max_reduction
462
+ end
463
+ if slice == 0
464
+ next
465
+ end
466
+
467
+ if !reverse_slice
468
+
469
+ ne_point = nw_point + OpenStudio::Vector3d.new(slice, 0, 0)
470
+ se_point = sw_point + OpenStudio::Vector3d.new(slice, 0, 0)
471
+
472
+ if actual_perim > 0 && (actual_perim * 2.0) < width
473
+ polygon_a = OpenStudio::Point3dVector.new
474
+ polygon_a << sw_point
475
+ polygon_a << sw_point + OpenStudio::Vector3d.new(0, actual_perim, 0)
476
+ polygon_a << se_point + OpenStudio::Vector3d.new(0, actual_perim, 0)
477
+ polygon_a << se_point
478
+ if double_loaded_corridor
479
+ hash_of_point_vectors["#{perim_space_type.name} A #{k}"] = {}
480
+ hash_of_point_vectors["#{perim_space_type.name} A #{k}"][:space_type] = perim_space_type
481
+ hash_of_point_vectors["#{perim_space_type.name} A #{k}"][:polygon] = polygon_a
482
+ else
483
+ hash_of_point_vectors["#{space_type.name} A #{k}"] = {}
484
+ hash_of_point_vectors["#{space_type.name} A #{k}"][:space_type] = space_type
485
+ hash_of_point_vectors["#{space_type.name} A #{k}"][:polygon] = polygon_a
486
+ end
487
+
488
+ polygon_b = OpenStudio::Point3dVector.new
489
+ polygon_b << sw_point + OpenStudio::Vector3d.new(0, actual_perim, 0)
490
+ polygon_b << nw_point + OpenStudio::Vector3d.new(0, - actual_perim, 0)
491
+ polygon_b << ne_point + OpenStudio::Vector3d.new(0, - actual_perim, 0)
492
+ polygon_b << se_point + OpenStudio::Vector3d.new(0, actual_perim, 0)
493
+ if double_loaded_corridor
494
+ hash_of_point_vectors["#{core_space_type.name} B #{k}"] = {}
495
+ hash_of_point_vectors["#{core_space_type.name} B #{k}"][:space_type] = core_space_type
496
+ hash_of_point_vectors["#{core_space_type.name} B #{k}"][:polygon] = polygon_b
497
+ else
498
+ hash_of_point_vectors["#{space_type.name} B #{k}"] = {}
499
+ hash_of_point_vectors["#{space_type.name} B #{k}"][:space_type] = space_type
500
+ hash_of_point_vectors["#{space_type.name} B #{k}"][:polygon] = polygon_b
501
+ end
502
+
503
+ polygon_c = OpenStudio::Point3dVector.new
504
+ polygon_c << nw_point + OpenStudio::Vector3d.new(0, - actual_perim, 0)
505
+ polygon_c << nw_point
506
+ polygon_c << ne_point
507
+ polygon_c << ne_point + OpenStudio::Vector3d.new(0, - actual_perim, 0)
508
+ if double_loaded_corridor
509
+ hash_of_point_vectors["#{perim_space_type.name} C #{k}"] = {}
510
+ hash_of_point_vectors["#{perim_space_type.name} C #{k}"][:space_type] = perim_space_type
511
+ hash_of_point_vectors["#{perim_space_type.name} C #{k}"][:polygon] = polygon_c
512
+ else
513
+ hash_of_point_vectors["#{space_type.name} C #{k}"] = {}
514
+ hash_of_point_vectors["#{space_type.name} C #{k}"][:space_type] = space_type
515
+ hash_of_point_vectors["#{space_type.name} C #{k}"][:polygon] = polygon_c
516
+ end
517
+ else
518
+ polygon_a = OpenStudio::Point3dVector.new
519
+ polygon_a << sw_point
520
+ polygon_a << nw_point
521
+ polygon_a << ne_point
522
+ polygon_a << se_point
523
+ hash_of_point_vectors["#{space_type.name} #{k}"] = {}
524
+ hash_of_point_vectors["#{space_type.name} #{k}"][:space_type] = space_type
525
+ hash_of_point_vectors["#{space_type.name} #{k}"][:polygon] = polygon_a
526
+ end
527
+
528
+ # update west points
529
+ nw_point = ne_point
530
+ sw_point = se_point
531
+
532
+ else
533
+
534
+ # create_bar at 90 degrees if aspect ration is less than 1.0
535
+ # typical order (sw,nw,ne,se)
536
+ # order used here (se,sw,nw,ne)
537
+
538
+ nw_point = sw_point + OpenStudio::Vector3d.new(0, slice, 0)
539
+ ne_point = se_point + OpenStudio::Vector3d.new(0, slice, 0)
540
+
541
+ if actual_perim > 0 && (actual_perim * 2.0) < length
542
+ polygon_a = OpenStudio::Point3dVector.new
543
+ polygon_a << se_point
544
+ polygon_a << se_point + OpenStudio::Vector3d.new(- actual_perim, 0, 0)
545
+ polygon_a << ne_point + OpenStudio::Vector3d.new(- actual_perim, 0, 0)
546
+ polygon_a << ne_point
547
+ if double_loaded_corridor
548
+ hash_of_point_vectors["#{perim_space_type.name} A #{k}"] = {}
549
+ hash_of_point_vectors["#{perim_space_type.name} A #{k}"][:space_type] = perim_space_type
550
+ hash_of_point_vectors["#{perim_space_type.name} A #{k}"][:polygon] = polygon_a
551
+ else
552
+ hash_of_point_vectors["#{space_type.name} A #{k}"] = {}
553
+ hash_of_point_vectors["#{space_type.name} A #{k}"][:space_type] = space_type
554
+ hash_of_point_vectors["#{space_type.name} A #{k}"][:polygon] = polygon_a
555
+ end
556
+
557
+ polygon_b = OpenStudio::Point3dVector.new
558
+ polygon_b << se_point + OpenStudio::Vector3d.new(- actual_perim, 0, 0)
559
+ polygon_b << sw_point + OpenStudio::Vector3d.new(actual_perim, 0, 0)
560
+ polygon_b << nw_point + OpenStudio::Vector3d.new(actual_perim, 0, 0)
561
+ polygon_b << ne_point + OpenStudio::Vector3d.new(- actual_perim, 0, 0)
562
+ if double_loaded_corridor
563
+ hash_of_point_vectors["#{core_space_type.name} B #{k}"] = {}
564
+ hash_of_point_vectors["#{core_space_type.name} B #{k}"][:space_type] = core_space_type
565
+ hash_of_point_vectors["#{core_space_type.name} B #{k}"][:polygon] = polygon_b
566
+ else
567
+ hash_of_point_vectors["#{space_type.name} B #{k}"] = {}
568
+ hash_of_point_vectors["#{space_type.name} B #{k}"][:space_type] = space_type
569
+ hash_of_point_vectors["#{space_type.name} B #{k}"][:polygon] = polygon_b
570
+ end
571
+
572
+ polygon_c = OpenStudio::Point3dVector.new
573
+ polygon_c << sw_point + OpenStudio::Vector3d.new(actual_perim, 0, 0)
574
+ polygon_c << sw_point
575
+ polygon_c << nw_point
576
+ polygon_c << nw_point + OpenStudio::Vector3d.new(actual_perim, 0, 0)
577
+ if double_loaded_corridor
578
+ hash_of_point_vectors["#{perim_space_type.name} C #{k}"] = {}
579
+ hash_of_point_vectors["#{perim_space_type.name} C #{k}"][:space_type] = perim_space_type
580
+ hash_of_point_vectors["#{perim_space_type.name} C #{k}"][:polygon] = polygon_c
581
+ else
582
+ hash_of_point_vectors["#{space_type.name} C #{k}"] = {}
583
+ hash_of_point_vectors["#{space_type.name} C #{k}"][:space_type] = space_type
584
+ hash_of_point_vectors["#{space_type.name} C #{k}"][:polygon] = polygon_c
585
+ end
586
+ else
587
+ polygon_a = OpenStudio::Point3dVector.new
588
+ polygon_a << se_point
589
+ polygon_a << sw_point
590
+ polygon_a << nw_point
591
+ polygon_a << ne_point
592
+ hash_of_point_vectors["#{space_type.name} #{k}"] = {}
593
+ hash_of_point_vectors["#{space_type.name} #{k}"][:space_type] = space_type
594
+ hash_of_point_vectors["#{space_type.name} #{k}"][:polygon] = polygon_a
595
+ end
596
+
597
+ # update west points
598
+ sw_point = nw_point
599
+ se_point = ne_point
600
+
601
+ end
602
+ end
603
+ end
604
+
605
+ return hash_of_point_vectors
606
+ end
607
+
608
+ # take diagram made by create_core_and_perimeter_polygons and make multi-story building
609
+ # @todo add option to create shading surfaces when using multiplier. Mainly important for non rectangular buildings where self shading would be an issue.
610
+ #
611
+ # @param model [OpenStudio::Model::Model] OpenStudio model object
612
+ # @param footprints [Hash] Array of footprint polygons that make up the spaces
613
+ # @param typical_story_height [Double] typical story height in meters
614
+ # @param effective_num_stories [Double] effective number of stories
615
+ # @param footprint_origin_point [OpenStudio::Point3d] Optional OpenStudio Point3d object for the new origin
616
+ # @param story_hash [Hash] A hash of building story information including space origin z value and space height
617
+ # If blank, this method will default to using information in the story_hash.
618
+ # @return [Array<OpenStudio::Model::Space>] Array of OpenStudio Space objects
619
+ def self.create_spaces_from_polygons(model, footprints, typical_story_height, effective_num_stories,
620
+ footprint_origin_point = OpenStudio::Point3d.new(0.0, 0.0, 0.0),
621
+ story_hash = {})
622
+ # default story hash is for three stories with mid-story multiplier, but user can pass in custom versions
623
+ if story_hash.empty?
624
+ if effective_num_stories > 2
625
+ story_hash['ground'] = { space_origin_z: footprint_origin_point.z, space_height: typical_story_height, multiplier: 1 }
626
+ story_hash['mid'] = { space_origin_z: footprint_origin_point.z + typical_story_height + typical_story_height * (effective_num_stories.ceil - 3) / 2.0, space_height: typical_story_height, multiplier: effective_num_stories - 2 }
627
+ story_hash['top'] = { space_origin_z: footprint_origin_point.z + typical_story_height * (effective_num_stories.ceil - 1), space_height: typical_story_height, multiplier: 1 }
628
+ elsif effective_num_stories > 1
629
+ story_hash['ground'] = { space_origin_z: footprint_origin_point.z, space_height: typical_story_height, multiplier: 1 }
630
+ story_hash['top'] = { space_origin_z: footprint_origin_point.z + typical_story_height * (effective_num_stories.ceil - 1), space_height: typical_story_height, multiplier: 1 }
631
+ else
632
+ # one story only
633
+ story_hash['ground'] = { space_origin_z: footprint_origin_point.z, space_height: typical_story_height, multiplier: 1 }
634
+ end
635
+ end
636
+
637
+ # hash of new spaces (only change boundary conditions for these)
638
+ new_spaces = []
639
+
640
+ # loop through story_hash and polygons to generate all of the spaces
641
+ story_hash.each_with_index do |(story_name, story_data), index|
642
+ # make new story unless story at requested height already exists.
643
+ story = nil
644
+ model.getBuildingStorys.sort.each do |ext_story|
645
+ if (ext_story.nominalZCoordinate.to_f - story_data[:space_origin_z].to_f).abs < 0.01
646
+ story = ext_story
647
+ end
648
+ end
649
+ if story.nil?
650
+ story = OpenStudio::Model::BuildingStory.new(model)
651
+ # not used for anything
652
+ story.setNominalFloortoFloorHeight(story_data[:space_height])
653
+ # not used for anything
654
+ story.setNominalZCoordinate(story_data[:space_origin_z])
655
+ story.setName("Story #{story_name}")
656
+ end
657
+
658
+ # multiplier values for adjacent stories to be altered below as needed
659
+ multiplier_story_above = 1
660
+ multiplier_story_below = 1
661
+
662
+ if index == 0 # bottom floor, only check above
663
+ if story_hash.size > 1
664
+ multiplier_story_above = story_hash.values[index + 1][:multiplier]
665
+ end
666
+ elsif index == story_hash.size - 1 # top floor, check only below
667
+ multiplier_story_below = story_hash.values[index + -1][:multiplier]
668
+ else # mid floor, check above and below
669
+ multiplier_story_above = story_hash.values[index + 1][:multiplier]
670
+ multiplier_story_below = story_hash.values[index + -1][:multiplier]
671
+ end
672
+
673
+ # if adjacent story has multiplier > 1 then make appropriate surfaces adiabatic
674
+ adiabatic_ceilings = false
675
+ adiabatic_floors = false
676
+ if story_data[:multiplier] > 1
677
+ adiabatic_ceilings = true
678
+ adiabatic_floors = true
679
+ elsif multiplier_story_above > 1
680
+ adiabatic_ceilings = true
681
+ elsif multiplier_story_below > 1
682
+ adiabatic_floors = true
683
+ end
684
+
685
+ # get the right collection of polygons to make up footprint for each building story
686
+ if index > footprints.size - 1
687
+ # use last footprint
688
+ target_footprint = footprints.last
689
+ else
690
+ target_footprint = footprints[index]
691
+ end
692
+ target_footprint.each do |name, space_data|
693
+ # gather options
694
+ options = {
695
+ 'name' => "#{name} - #{story.name}",
696
+ 'space_type' => space_data[:space_type],
697
+ 'story' => story,
698
+ 'make_thermal_zone' => true,
699
+ 'thermal_zone_multiplier' => story_data[:multiplier],
700
+ 'floor_to_floor_height' => story_data[:space_height]
701
+ }
702
+
703
+ # make space
704
+ space = OpenstudioStandards::Geometry.create_space_from_polygon(model, space_data[:polygon].first, space_data[:polygon], options)
705
+ new_spaces << space
706
+
707
+ # set z origin to proper position
708
+ space.setZOrigin(story_data[:space_origin_z])
709
+
710
+ # loop through celings and floors to hard asssign constructions and set boundary condition
711
+ if adiabatic_ceilings || adiabatic_floors
712
+ space.surfaces.each do |surface|
713
+ if adiabatic_floors && (surface.surfaceType == 'Floor')
714
+ if surface.construction.is_initialized
715
+ surface.setConstruction(surface.construction.get)
716
+ end
717
+ surface.setOutsideBoundaryCondition('Adiabatic')
718
+ end
719
+ if adiabatic_ceilings && (surface.surfaceType == 'RoofCeiling')
720
+ if surface.construction.is_initialized
721
+ surface.setConstruction(surface.construction.get)
722
+ end
723
+ surface.setOutsideBoundaryCondition('Adiabatic')
724
+ end
725
+ end
726
+ end
727
+ end
728
+
729
+ # @tofo in future add code to include plenums or raised floor to each/any story.
730
+ end
731
+ # any changes to wall boundary conditions will be handled by same code that calls this method.
732
+ # this method doesn't need to know about basements and party walls.
733
+ return new_spaces
734
+ end
735
+
736
+ # add def to create a space from input, optionally take a name, space type, story and thermal zone.
737
+ #
738
+ # @param model [OpenStudio::Model::Model] OpenStudio model object describing the space footprint polygon
739
+ # @param space_origin [OpenStudio::Point3d] origin point
740
+ # @param point_3d_vector [OpenStudio::Point3dVector] OpenStudio Point3dVector defining the space footprint
741
+ # @param options [Hash] Hash of options for additional arguments
742
+ # @option options [String] :name name of the space
743
+ # @option options [OpenStudio::Model::SpaceType] :space_type OpenStudio SpaceType object
744
+ # @option options [String] :story name name of the building story
745
+ # @option options [Boolean] :make_thermal_zone set to true to make an thermal zone object, defaults to true.
746
+ # @option options [OpenStudio::Model::ThermalZone] :thermal_zone attach a specific ThermalZone object to the space
747
+ # @option options [Integer] :thermal_zone_multiplier the thermal zone multiplier, defaults to 1.
748
+ # @option options [Double] :floor_to_floor_height floor to floor height in meters, defaults to 10 ft.
749
+ # @return [OpenStudio::Model::Space] OpenStudio Space object
750
+ def self.create_space_from_polygon(model, space_origin, point_3d_vector, options = {})
751
+ # set defaults to use if user inputs not passed in
752
+ defaults = {
753
+ 'name' => nil,
754
+ 'space_type' => nil,
755
+ 'story' => nil,
756
+ 'make_thermal_zone' => nil,
757
+ 'thermal_zone' => nil,
758
+ 'thermal_zone_multiplier' => 1,
759
+ 'floor_to_floor_height' => OpenStudio.convert(10.0, 'ft', 'm').get
760
+ }
761
+
762
+ # merge user inputs with defaults
763
+ options = defaults.merge(options)
764
+
765
+ # Identity matrix for setting space origins
766
+ m = OpenStudio::Matrix.new(4, 4, 0)
767
+ m[0, 0] = 1
768
+ m[1, 1] = 1
769
+ m[2, 2] = 1
770
+ m[3, 3] = 1
771
+
772
+ # make space from floor print
773
+ space = OpenStudio::Model::Space.fromFloorPrint(point_3d_vector, options['floor_to_floor_height'], model)
774
+ space = space.get
775
+ m[0, 3] = space_origin.x
776
+ m[1, 3] = space_origin.y
777
+ m[2, 3] = space_origin.z
778
+ space.changeTransformation(OpenStudio::Transformation.new(m))
779
+ space.setBuildingStory(options['story'])
780
+ if !options['name'].nil?
781
+ space.setName(options['name'])
782
+ end
783
+
784
+ if !options['space_type'].nil? && options['space_type'].class.to_s == 'OpenStudio::Model::SpaceType'
785
+ space.setSpaceType(options['space_type'])
786
+ end
787
+
788
+ # create thermal zone if requested and assign
789
+ if options['make_thermal_zone']
790
+ new_zone = OpenStudio::Model::ThermalZone.new(model)
791
+ new_zone.setMultiplier(options['thermal_zone_multiplier'])
792
+ space.setThermalZone(new_zone)
793
+ new_zone.setName("Zone #{space.name}")
794
+ else
795
+ if !options['thermal_zone'].nil? then space.setThermalZone(options['thermal_zone']) end
796
+ end
797
+
798
+ return space
799
+ end
800
+ end
801
+ end