openstudio-standards 0.2.17.rc2 → 0.3.1.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (233) hide show
  1. checksums.yaml +4 -4
  2. data/data/geometry/ASHRAESuperMarket.json +29 -38
  3. data/data/standards/OpenStudio_Standards-deer-ALL-comstock(space_types).xlsx +0 -0
  4. data/data/standards/metadata_units_OpenStudio_Standards-deer-ALL-comstockspace_types.csv +172 -0
  5. data/data/standards/test_performance_expected_dd_results.csv +12 -12
  6. data/lib/openstudio-standards/btap/analysis.rb +389 -389
  7. data/lib/openstudio-standards/btap/bridging.rb +2099 -0
  8. data/lib/openstudio-standards/btap/btap.model.rb +717 -717
  9. data/lib/openstudio-standards/btap/btap.rb +33 -30
  10. data/lib/openstudio-standards/btap/economics.rb +1163 -1163
  11. data/lib/openstudio-standards/btap/envelope.rb +4 -4
  12. data/lib/openstudio-standards/btap/equest.rb +2524 -2524
  13. data/lib/openstudio-standards/btap/fileio.rb +9 -0
  14. data/lib/openstudio-standards/btap/measures.rb +1515 -1515
  15. data/lib/openstudio-standards/btap/mpc.rb +554 -554
  16. data/lib/openstudio-standards/btap/reporting.rb +287 -287
  17. data/lib/openstudio-standards/btap/simmanager.rb +759 -759
  18. data/lib/openstudio-standards/btap/spaceloads.rb +439 -439
  19. data/lib/openstudio-standards/btap/spacetypes.rb +113 -113
  20. data/lib/openstudio-standards/btap/utilities.rb +134 -134
  21. data/lib/openstudio-standards/hvac_sizing/Siz.AirLoopHVAC.rb +8 -83
  22. data/lib/openstudio-standards/hvac_sizing/Siz.CoilCoolingWater.rb +3 -99
  23. data/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb +81 -75
  24. data/lib/openstudio-standards/hvac_sizing/Siz.Model.rb +7 -306
  25. data/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb +70 -98
  26. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2016/ashrae_90_1_2016.Model.rb +41 -14
  27. data/lib/openstudio-standards/prototypes/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.Model.rb +40 -14
  28. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SuperMarket.rb +1 -23
  29. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.exterior_lights.rb +7 -7
  30. data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +5 -1
  31. data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +101 -4
  32. data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +16 -1
  33. data/lib/openstudio-standards/prototypes/common/objects/Prototype.refrigeration.rb +5 -4
  34. data/lib/openstudio-standards/prototypes/common/objects/Prototype.utilities.rb +24 -4
  35. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +18 -2
  36. data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +18 -0
  37. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +13 -10
  38. data/lib/openstudio-standards/standards/Standards.CoilDX.rb +5 -3
  39. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +11 -8
  40. data/lib/openstudio-standards/standards/Standards.Construction.rb +1 -1
  41. data/lib/openstudio-standards/standards/Standards.Model.rb +68 -52
  42. data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +2 -2
  43. data/lib/openstudio-standards/standards/Standards.Space.rb +16 -18
  44. data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +1 -1
  45. data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +5 -5
  46. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.ref_cases.json +510 -0
  47. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.refrigeration_compressors.json +18 -0
  48. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.refrigeration_walkins.json +410 -0
  49. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2004/data/ashrae_90_1_2004.spc_typ.json +2 -2
  50. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.ref_cases.json +510 -0
  51. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.refrigeration_compressors.json +18 -0
  52. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.refrigeration_walkins.json +410 -0
  53. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2007/data/ashrae_90_1_2007.spc_typ.json +2 -2
  54. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.ref_cases.json +510 -0
  55. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.refrigeration_compressors.json +18 -0
  56. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.refrigeration_walkins.json +410 -0
  57. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2010/data/ashrae_90_1_2010.spc_typ.json +2 -2
  58. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.ref_cases.json +510 -0
  59. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.refrigeration_compressors.json +18 -0
  60. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.refrigeration_walkins.json +410 -0
  61. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2013/data/ashrae_90_1_2013.spc_typ.json +2 -2
  62. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2016/data/ashrae_90_1_2016.spc_typ.json +2 -2
  63. data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/data/ashrae_90_1_2019.spc_typ.json +2 -2
  64. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.entryways.json +13 -2
  65. data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.parking.json +11 -2
  66. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +9 -0
  67. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +2 -0
  68. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.rb +4 -3
  69. data/lib/openstudio-standards/standards/deer/deer_1985/comstock_deer_1985/data/comstock_deer_1985.spc_typ.json +405 -405
  70. data/lib/openstudio-standards/standards/deer/deer_1996/comstock_deer_1996/data/comstock_deer_1996.spc_typ.json +405 -405
  71. data/lib/openstudio-standards/standards/deer/deer_2003/comstock_deer_2003/data/comstock_deer_2003.spc_typ.json +405 -405
  72. data/lib/openstudio-standards/standards/deer/deer_2003/deer_2003.ThermalZone.rb +21 -0
  73. data/lib/openstudio-standards/standards/deer/deer_2007/comstock_deer_2007/data/comstock_deer_2007.spc_typ.json +405 -405
  74. data/lib/openstudio-standards/standards/deer/deer_2007/deer_2007.ThermalZone.rb +21 -0
  75. data/lib/openstudio-standards/standards/deer/deer_2011/comstock_deer_2011/data/comstock_deer_2011.spc_typ.json +405 -405
  76. data/lib/openstudio-standards/standards/deer/deer_2011/deer_2011.ThermalZone.rb +21 -0
  77. data/lib/openstudio-standards/standards/deer/deer_2014/comstock_deer_2014/data/comstock_deer_2014.spc_typ.json +405 -405
  78. data/lib/openstudio-standards/standards/deer/deer_2014/deer_2014.ThermalZone.rb +21 -0
  79. data/lib/openstudio-standards/standards/deer/deer_2015/comstock_deer_2015/data/comstock_deer_2015.spc_typ.json +405 -405
  80. data/lib/openstudio-standards/standards/deer/deer_2015/deer_2015.ThermalZone.rb +21 -0
  81. data/lib/openstudio-standards/standards/deer/deer_2017/comstock_deer_2017/data/comstock_deer_2017.spc_typ.json +405 -405
  82. data/lib/openstudio-standards/standards/deer/deer_2017/deer_2017.ThermalZone.rb +21 -0
  83. data/lib/openstudio-standards/standards/deer/deer_2020/comstock_deer_2020/data/comstock_deer_2020.spc_typ.json +405 -405
  84. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.AirLoopHVAC.rb +8 -0
  85. data/lib/openstudio-standards/standards/deer/deer_2020/deer_2020.ThermalZone.rb +21 -0
  86. data/lib/openstudio-standards/standards/deer/deer_2025/comstock_deer_2025/data/comstock_deer_2025.spc_typ.json +405 -405
  87. data/lib/openstudio-standards/standards/deer/deer_2030/comstock_deer_2030/data/comstock_deer_2030.spc_typ.json +405 -405
  88. data/lib/openstudio-standards/standards/deer/deer_2035/comstock_deer_2035/data/comstock_deer_2035.spc_typ.json +405 -405
  89. data/lib/openstudio-standards/standards/deer/deer_2040/comstock_deer_2040/data/comstock_deer_2040.spc_typ.json +405 -405
  90. data/lib/openstudio-standards/standards/deer/deer_2045/comstock_deer_2045/data/comstock_deer_2045.spc_typ.json +405 -405
  91. data/lib/openstudio-standards/standards/deer/deer_2050/comstock_deer_2050/data/comstock_deer_2050.spc_typ.json +405 -405
  92. data/lib/openstudio-standards/standards/deer/deer_2055/comstock_deer_2055/data/comstock_deer_2055.spc_typ.json +405 -405
  93. data/lib/openstudio-standards/standards/deer/deer_2060/comstock_deer_2060/data/comstock_deer_2060.spc_typ.json +405 -405
  94. data/lib/openstudio-standards/standards/deer/deer_2065/comstock_deer_2065/data/comstock_deer_2065.spc_typ.json +405 -405
  95. data/lib/openstudio-standards/standards/deer/deer_2070/comstock_deer_2070/data/comstock_deer_2070.spc_typ.json +405 -405
  96. data/lib/openstudio-standards/standards/deer/deer_2075/comstock_deer_2075/data/comstock_deer_2075.spc_typ.json +405 -405
  97. data/lib/openstudio-standards/standards/deer/deer_pre_1975/comstock_deer_pre_1975/data/comstock_deer_pre_1975.spc_typ.json +405 -405
  98. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/btap_pre1980.rb +1 -1
  99. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_3_and_8_single_speed.rb +3 -1
  100. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_4.rb +3 -1
  101. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +2 -2
  102. data/lib/openstudio-standards/standards/necb/ECMS/data/curves.json +233 -0
  103. data/lib/openstudio-standards/standards/necb/ECMS/data/unitary_acs.json +180 -0
  104. data/lib/openstudio-standards/standards/necb/ECMS/ecms.rb +6 -1
  105. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +807 -258
  106. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +102 -66
  107. data/lib/openstudio-standards/standards/necb/NECB2011/data/fuel_type_sets.json +85 -8
  108. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/HighriseApartment.osm +2483 -992
  109. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/LowriseApartment.osm +4 -336
  110. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/MidriseApartment.osm +228 -231
  111. data/lib/openstudio-standards/standards/necb/NECB2011/data/heat_pumps_heating.json +12 -18
  112. data/lib/openstudio-standards/standards/necb/NECB2011/data/space_type_unit_definitions.txt +76 -0
  113. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_multi_speed.rb +6 -1
  114. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_single_speed.rb +111 -24
  115. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_2_and_5.rb +1 -0
  116. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +3 -1
  117. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +64 -16
  118. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +61 -17
  119. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +128 -0
  120. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +252 -23
  121. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +316 -20
  122. data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +1 -1
  123. data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +4 -6
  124. data/lib/openstudio-standards/standards/necb/NECB2011/system_fuels.rb +38 -0
  125. data/lib/openstudio-standards/standards/necb/NECB2015/data/heat_pumps_heating.json +16 -24
  126. data/lib/openstudio-standards/standards/necb/NECB2015/hvac_systems.rb +48 -25
  127. data/lib/openstudio-standards/standards/necb/NECB2020/building_envelope.rb +3 -3
  128. data/lib/openstudio-standards/standards/necb/NECB2020/data/chillers.json +36 -19
  129. data/lib/openstudio-standards/standards/necb/NECB2020/data/furnaces.json +19 -4
  130. data/lib/openstudio-standards/standards/necb/NECB2020/data/heat_pumps.json +20 -40
  131. data/lib/openstudio-standards/standards/necb/NECB2020/data/heat_pumps_heating.json +74 -36
  132. data/lib/openstudio-standards/standards/necb/NECB2020/necb_2020.rb +0 -2
  133. data/lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb +124 -57
  134. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +124 -2
  135. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +15 -2
  136. data/lib/openstudio-standards/standards/necb/common/necb_reference_runs.csv +1 -1
  137. data/lib/openstudio-standards/utilities/simulation.rb +1 -1
  138. data/lib/openstudio-standards/version.rb +1 -1
  139. data/lib/openstudio-standards/weather/Weather.Model.rb +5 -0
  140. data/lib/openstudio-standards/weather/Weather.stat_file.rb +33 -1
  141. data/lib/openstudio-standards.rb +1 -0
  142. metadata +14 -121
  143. data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
  144. data/data/weather/CAN_ON_Kingston.AP.718200_TMYx.2004-2018.ddy +0 -2342
  145. data/data/weather/CAN_ON_Kingston.AP.718200_TMYx.2004-2018.epw +0 -8768
  146. data/data/weather/CAN_ON_Kingston.AP.718200_TMYx.2004-2018.stat +0 -700
  147. data/data/weather/CAN_ON_Region.of.Waterloo.Intl.AP.713680_TMYx.2004-2018.ddy +0 -2342
  148. data/data/weather/CAN_ON_Region.of.Waterloo.Intl.AP.713680_TMYx.2004-2018.epw +0 -8768
  149. data/data/weather/CAN_ON_Region.of.Waterloo.Intl.AP.713680_TMYx.2004-2018.stat +0 -700
  150. data/data/weather/CAN_ON_Sarnia-Hadfield.AP.717040_TMYx.2004-2018.ddy +0 -2342
  151. data/data/weather/CAN_ON_Sarnia-Hadfield.AP.717040_TMYx.2004-2018.epw +0 -8768
  152. data/data/weather/CAN_ON_Sarnia-Hadfield.AP.717040_TMYx.2004-2018.stat +0 -700
  153. data/data/weather/CAN_QC_Gatineau.AP.716279_TMYx.2004-2018.ddy +0 -276
  154. data/data/weather/CAN_QC_Gatineau.AP.716279_TMYx.2004-2018.epw +0 -8768
  155. data/data/weather/CAN_QC_Gatineau.AP.716279_TMYx.2004-2018.stat +0 -611
  156. data/data/weather/CAN_QC_Granby.710367_TMYx.2004-2018.ddy +0 -276
  157. data/data/weather/CAN_QC_Granby.710367_TMYx.2004-2018.epw +0 -8768
  158. data/data/weather/CAN_QC_Granby.710367_TMYx.2004-2018.stat +0 -610
  159. data/data/weather/CAN_QC_Sherbrooke.AP.716100_TMYx.2004-2018.ddy +0 -2342
  160. data/data/weather/CAN_QC_Sherbrooke.AP.716100_TMYx.2004-2018.epw +0 -8768
  161. data/data/weather/CAN_QC_Sherbrooke.AP.716100_TMYx.2004-2018.stat +0 -700
  162. data/data/weather/CAN_QC_Trois.Rivieres.717240_TMYx.2004-2018.ddy +0 -2342
  163. data/data/weather/CAN_QC_Trois.Rivieres.717240_TMYx.2004-2018.epw +0 -8768
  164. data/data/weather/CAN_QC_Trois.Rivieres.717240_TMYx.2004-2018.stat +0 -700
  165. data/lib/openstudio-standards/hvac_sizing/Siz.AirConditionerVariableRefrigerantFlow.rb +0 -81
  166. data/lib/openstudio-standards/hvac_sizing/Siz.AirLoopHVACUnitaryHeatCoolVAVChngByp.rb +0 -27
  167. data/lib/openstudio-standards/hvac_sizing/Siz.AirLoopHVACUnitaryHeatPumpAirToAir.rb +0 -69
  168. data/lib/openstudio-standards/hvac_sizing/Siz.AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.rb +0 -178
  169. data/lib/openstudio-standards/hvac_sizing/Siz.AirLoopHVACUnitarySystem.rb +0 -27
  170. data/lib/openstudio-standards/hvac_sizing/Siz.AirTermSnglDuctConstVolCooledBeam.rb +0 -27
  171. data/lib/openstudio-standards/hvac_sizing/Siz.AirTermSnglDuctConstVolFourPipeInduction.rb +0 -27
  172. data/lib/openstudio-standards/hvac_sizing/Siz.AirTermSnglDuctConstVolReheat.rb +0 -27
  173. data/lib/openstudio-standards/hvac_sizing/Siz.AirTermSnglDuctParallelPIUReheat.rb +0 -67
  174. data/lib/openstudio-standards/hvac_sizing/Siz.AirTermSnglDuctSeriesPIUReheat.rb +0 -27
  175. data/lib/openstudio-standards/hvac_sizing/Siz.AirTermSnglDuctUncontrolled.rb +0 -30
  176. data/lib/openstudio-standards/hvac_sizing/Siz.AirTermSnglDuctVAVHeatAndCoolNoReheat.rb +0 -27
  177. data/lib/openstudio-standards/hvac_sizing/Siz.AirTermSnglDuctVAVHeatAndCoolReheat.rb +0 -27
  178. data/lib/openstudio-standards/hvac_sizing/Siz.AirTermSnglDuctVAVNoReheat.rb +0 -68
  179. data/lib/openstudio-standards/hvac_sizing/Siz.AirTermSnglDuctVAVReheat.rb +0 -68
  180. data/lib/openstudio-standards/hvac_sizing/Siz.BoilerHotWater.rb +0 -42
  181. data/lib/openstudio-standards/hvac_sizing/Siz.BoilerSteam.rb +0 -27
  182. data/lib/openstudio-standards/hvac_sizing/Siz.ChillerElectricEIR.rb +0 -58
  183. data/lib/openstudio-standards/hvac_sizing/Siz.CoilCoolingDXMultiSpeed.rb +0 -171
  184. data/lib/openstudio-standards/hvac_sizing/Siz.CoilCoolingDXSingleSpeed.rb +0 -56
  185. data/lib/openstudio-standards/hvac_sizing/Siz.CoilCoolingDXTwoSpeed.rb +0 -89
  186. data/lib/openstudio-standards/hvac_sizing/Siz.CoilCoolingDXVariableRefrigerantFlow.rb +0 -50
  187. data/lib/openstudio-standards/hvac_sizing/Siz.CoilCoolingWaterToAirHeatPumpEquationFit.rb +0 -69
  188. data/lib/openstudio-standards/hvac_sizing/Siz.CoilHeatingDXMultiSpeed.rb +0 -120
  189. data/lib/openstudio-standards/hvac_sizing/Siz.CoilHeatingDXSingleSpeed.rb +0 -56
  190. data/lib/openstudio-standards/hvac_sizing/Siz.CoilHeatingDXVariableRefrigerantFlow.rb +0 -41
  191. data/lib/openstudio-standards/hvac_sizing/Siz.CoilHeatingDesuperheater.rb +0 -27
  192. data/lib/openstudio-standards/hvac_sizing/Siz.CoilHeatingElectric.rb +0 -30
  193. data/lib/openstudio-standards/hvac_sizing/Siz.CoilHeatingGas.rb +0 -30
  194. data/lib/openstudio-standards/hvac_sizing/Siz.CoilHeatingGasMultiStage.rb +0 -68
  195. data/lib/openstudio-standards/hvac_sizing/Siz.CoilHeatingWater.rb +0 -61
  196. data/lib/openstudio-standards/hvac_sizing/Siz.CoilHeatingWaterToAirHeatPumpEquationFit.rb +0 -57
  197. data/lib/openstudio-standards/hvac_sizing/Siz.CoilWaterHeatingDesuperheater.rb +0 -27
  198. data/lib/openstudio-standards/hvac_sizing/Siz.ControllerOutdoorAir.rb +0 -59
  199. data/lib/openstudio-standards/hvac_sizing/Siz.ControllerWaterCoil.rb +0 -49
  200. data/lib/openstudio-standards/hvac_sizing/Siz.CoolingTowerSingleSpeed.rb +0 -90
  201. data/lib/openstudio-standards/hvac_sizing/Siz.CoolingTowerTwoSpeed.rb +0 -83
  202. data/lib/openstudio-standards/hvac_sizing/Siz.CoolingTowerVariableSpeed.rb +0 -57
  203. data/lib/openstudio-standards/hvac_sizing/Siz.DistrictCooling.rb +0 -27
  204. data/lib/openstudio-standards/hvac_sizing/Siz.DistrictHeating.rb +0 -27
  205. data/lib/openstudio-standards/hvac_sizing/Siz.EvaporativeCoolerDirectResearchSpecial.rb +0 -27
  206. data/lib/openstudio-standards/hvac_sizing/Siz.EvaporativeCoolerIndirectResearchSpecial.rb +0 -27
  207. data/lib/openstudio-standards/hvac_sizing/Siz.EvaporativeFluidCoolerSingleSpeed.rb +0 -27
  208. data/lib/openstudio-standards/hvac_sizing/Siz.FanConstantVolume.rb +0 -29
  209. data/lib/openstudio-standards/hvac_sizing/Siz.FanOnOff.rb +0 -27
  210. data/lib/openstudio-standards/hvac_sizing/Siz.FanVariableVolume.rb +0 -29
  211. data/lib/openstudio-standards/hvac_sizing/Siz.HeaderedPumpsConstantSpeed.rb +0 -55
  212. data/lib/openstudio-standards/hvac_sizing/Siz.HeaderedPumpsVariableSpeed.rb +0 -55
  213. data/lib/openstudio-standards/hvac_sizing/Siz.HeatExchangerAirToAirSensibleAndLatent.rb +0 -38
  214. data/lib/openstudio-standards/hvac_sizing/Siz.HeatExchangerFluidToFluid.rb +0 -27
  215. data/lib/openstudio-standards/hvac_sizing/Siz.HumidifierSteamElectric.rb +0 -27
  216. data/lib/openstudio-standards/hvac_sizing/Siz.PlantLoop.rb +0 -42
  217. data/lib/openstudio-standards/hvac_sizing/Siz.PumpConstantSpeed.rb +0 -59
  218. data/lib/openstudio-standards/hvac_sizing/Siz.PumpVariableSpeed.rb +0 -59
  219. data/lib/openstudio-standards/hvac_sizing/Siz.SizingSystem.rb +0 -48
  220. data/lib/openstudio-standards/hvac_sizing/Siz.WaterHeaterMixed.rb +0 -16
  221. data/lib/openstudio-standards/hvac_sizing/Siz.ZoneHVACBaseboardConvectiveElectric.rb +0 -27
  222. data/lib/openstudio-standards/hvac_sizing/Siz.ZoneHVACBaseboardConvectiveWater.rb +0 -27
  223. data/lib/openstudio-standards/hvac_sizing/Siz.ZoneHVACFourPipeFanCoil.rb +0 -27
  224. data/lib/openstudio-standards/hvac_sizing/Siz.ZoneHVACHighTemperatureRadiant.rb +0 -27
  225. data/lib/openstudio-standards/hvac_sizing/Siz.ZoneHVACIdealLoadsAirSystem.rb +0 -27
  226. data/lib/openstudio-standards/hvac_sizing/Siz.ZoneHVACLowTempRadiantConstFlow.rb +0 -27
  227. data/lib/openstudio-standards/hvac_sizing/Siz.ZoneHVACLowTempRadiantVarFlow.rb +0 -27
  228. data/lib/openstudio-standards/hvac_sizing/Siz.ZoneHVACLowTemperatureRadiantElectric.rb +0 -27
  229. data/lib/openstudio-standards/hvac_sizing/Siz.ZoneHVACPackagedTerminalAirConditioner.rb +0 -88
  230. data/lib/openstudio-standards/hvac_sizing/Siz.ZoneHVACPackagedTerminalHeatPump.rb +0 -88
  231. data/lib/openstudio-standards/hvac_sizing/Siz.ZoneHVACTerminalUnitVariableRefrigerantFlow.rb +0 -104
  232. data/lib/openstudio-standards/hvac_sizing/Siz.ZoneHVACUnitHeater.rb +0 -27
  233. data/lib/openstudio-standards/hvac_sizing/Siz.ZoneHVACWaterToAirHeatPump.rb +0 -27
@@ -1,2524 +1,2524 @@
1
- # *********************************************************************
2
- # * Copyright (c) 2008-2015, Natural Resources Canada
3
- # * All rights reserved.
4
- # *
5
- # * This library is free software; you can redistribute it and/or
6
- # * modify it under the terms of the GNU Lesser General Public
7
- # * License as published by the Free Software Foundation; either
8
- # * version 2.1 of the License, or (at your option) any later version.
9
- # *
10
- # * This library is distributed in the hope that it will be useful,
11
- # * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- # * Lesser General Public License for more details.
14
- # *
15
- # * You should have received a copy of the GNU Lesser General Public
16
- # * License along with this library; if not, write to the Free Software
17
- # * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
- # **********************************************************************/
19
-
20
-
21
-
22
- require "singleton"
23
-
24
-
25
- module BTAP
26
- module EQuest
27
- # Author:: Phylroy Lopez (mailto:plopez@nrcan.gc.ca)
28
- # Copyright:: Copyright (c) NRCan
29
- # License:: GNU Public Licence
30
- #This class contains encapsulates the generic interface for the DOE2.x command
31
- #set. It stores the u type, commands, and keyword pairs for each command. It also
32
- #stores the parent and child command relationships w.r.t. the building envelope
33
- #and the hvac systems. I have attempted to make the underlying storage of data
34
- #private so, if required, we could move to a database solution in the future
35
- #if required for web development..
36
-
37
- class DOECommand
38
-
39
- # Contains the user specified name
40
- attr_accessor :utype
41
- #Contains the u-value
42
- attr_accessor :uvalue
43
- # Contains the DOE-2 command name.
44
- attr_accessor :commandName
45
- # Contains the Keyword Pairs.
46
- attr_accessor :keywordPairs
47
- # Lists all ancestors in increasing order.
48
- attr_accessor :parents
49
- # An Array of all the children of this command.
50
- attr_accessor :children
51
- # The command type.
52
- attr_accessor :commandType
53
- # Flag to see if this component is exempt.
54
- attr_accessor :exempt
55
- # Comments. To be added to the command.
56
- attr_accessor :comments
57
- # A list of all the non_utype_commands.
58
- attr_accessor :non_utype_commands
59
- # A list of all the one line commands (no keyword pairs)
60
- attr_accessor :one_line_commands
61
- # Pointer to the building obj.
62
- attr_accessor :building
63
-
64
-
65
-
66
-
67
- def remove()
68
- #unlink children
69
- self.children.each {|item| item.remove}
70
- #unlink from parent.
71
- self.get_parents[0].children.delete(self)
72
- #remove from command array.
73
- @building.commands.delete(self)
74
- return self
75
- end
76
-
77
- def set_parent(parent)
78
- @parents.clear
79
- parent.get_parents().each {|parent| @parents << parent}
80
- @parents << parent
81
- end
82
-
83
- #This method will return the value of the keyword pair if available.
84
- #Example:
85
- #If you object has this data in it...
86
- #
87
- #"EL1 West Perim Spc (G.W4)" = SPACE
88
- #SHAPE = POLYGON
89
- #ZONE-TYPE = CONDITIONED
90
- #PEOPLE-SCHEDULE = "EL1 Bldg Occup Sch"
91
- #LIGHTING-SCHEDUL = ( "EL1 Bldg InsLt Sch" )
92
- #EQUIP-SCHEDULE = ( "EL1 Bldg Misc Sch" )
93
- #
94
- #
95
- #then calling
96
- #
97
- #get_keyword_value("ZONE-TYPE")
98
- #
99
- #will return the string
100
- #
101
- #"CONDITIONED".
102
- #
103
- #if the keyword does not exist, it will return a nil object.
104
- # Returns the value associated with the keyword.
105
- def get_keyword_value(string)
106
- return_string = String.new()
107
- found = false
108
- @keywordPairs.each do |pair|
109
- if pair[0] == string
110
- found = true
111
- return_string = pair[1]
112
- end
113
- end
114
- if found == false
115
- raise "Error: In the command #{@utype}:#{@command_name} Attempted to get a Keyword pair #{string} present in the command\n Is this keyword missing? \n#{output}"
116
- end
117
- return return_string
118
- end
119
-
120
- # Sets the keyword value.
121
- def set_keyword_value(keyword, value)
122
- found = false
123
- unless @keywordPairs.empty?
124
- @keywordPairs.each do |pair|
125
- if pair[0] == keyword
126
- pair[1] = value
127
- found = true
128
- end
129
- end
130
- if (found == false)
131
- @keywordPairs.push([keyword,value])
132
- end
133
- else
134
- #First in the array...
135
- add_keyword_pair(keyword,value)
136
- end
137
- end
138
-
139
- # Removes the keyword pair.
140
- def remove_keyword_pair(string)
141
- return_string = String.new()
142
- @keywordPairs.each do |pair|
143
- if pair[0] == string
144
- @keywordPairs.delete(pair)
145
- end
146
- end
147
- return return_string
148
- end
149
-
150
- def initialize()
151
- @utype = String.new()
152
- @commandName= String.new()
153
- @keywordPairs=Array.new()
154
- @parents = Array.new()
155
- @children = Array.new()
156
- @commandType = String.new()
157
- @exempt = false
158
- #HVAC Hierarchry
159
- @comments =Array.new()
160
- @hvacLevel = Array.new()
161
- @hvacLevel[0] =["SYSTEM"]
162
- @hvacLevel[1] =["ZONE"]
163
- #Envelope Hierachy
164
- @envelopeLevel = Array.new()
165
- @envelopeLevel[0] = ["FLOOR"]
166
- @envelopeLevel[1] = ["SPACE"]
167
-
168
- @envelopeLevel[2] = [
169
- "EXTERIOR-WALL",
170
- "INTERIOR-WALL",
171
- "UNDERGROUND-WALL",
172
- "ROOF"
173
- ]
174
-
175
- @envelopeLevel[3] = [
176
- "WINDOW",
177
- "DOOR"]
178
-
179
- @non_utype_commands = Array.new()
180
- @non_utype_commands = [
181
- "TITLE",
182
- "SITE-PARAMETERS",
183
- "BUILD-PARAMETER",
184
- "LOADS_REPORT",
185
- "SYSTEMS-REPORT",
186
- "MASTERS-METERS",
187
- "ECONOMICS-REPORT",
188
- "PLANT-REPORT",
189
- "LOADS-REPORT",
190
- "COMPLIANCE"
191
- ]
192
- @one_line_commands = Array.new()
193
- @one_line_commands = ["INPUT","RUN-PERIOD","DIAGNOSTIC","ABORT", "END", "COMPUTE", "STOP", "PROJECT-DATA"]
194
- end
195
-
196
- # Determines the DOE scope, either envelope or hvac (Window, Wall, Space Floor) or (System->Plant)
197
- # Hierarchy) this is required to determine parent/child relationships in the building.
198
- def doe_scope
199
- scope = "none"
200
- @envelopeLevel.each_index do |index|
201
- @envelopeLevel[index].each do |name|
202
- if (@commandName == name )
203
- scope = "envelope"
204
- end
205
- end
206
- end
207
-
208
- @hvacLevel.each_index do |index|
209
- @hvacLevel[index].each do |name|
210
- if (@commandName == name )
211
- scope = "hvac"
212
- end
213
- end
214
- end
215
- return scope
216
- end
217
- # Determines the DOE scope depth (Window, Wall, Space Floor) or (System->Plant) Hierarchy)
218
- def depth
219
- level = 0
220
- scopelist=[]
221
- if (doe_scope == "hvac")
222
- scopelist = @hvacLevel
223
- else
224
- scopelist = @envelopeLevel
225
- end
226
- scopelist.each_index do |index|
227
- scopelist[index].each do |name|
228
- if (@commandName == name )
229
- level = index
230
- end
231
- end
232
- end
233
- return level
234
- end
235
-
236
- #Outputs the command in DOE 2.2 format.
237
- def output
238
- return basic_output()
239
- end
240
-
241
- #Outputs the command in DOE 2.2 format.
242
- def basic_output()
243
- temp_string = String.new()
244
-
245
- if (@utype != "")
246
- temp_string = temp_string + "#{@utype} = "
247
- end
248
- temp_string = temp_string + @commandName
249
- temp_string = temp_string + "\n"
250
- @keywordPairs.each {|array| temp_string = temp_string + "\t#{array[0]} = #{array[1]}\n" }
251
- temp_string = temp_string + "..\n"
252
-
253
- temp_string = temp_string + "$Parents\n"
254
- @parents.each do |array|
255
- temp_string = temp_string + "$\t#{array.utype} = #{array.commandName}\n"
256
- end
257
- temp_string = temp_string + "..\n"
258
-
259
- temp_string = temp_string + "$Children\n"
260
- @children.each {|array| temp_string = temp_string + "$\t#{array.utype} = #{array.commandName}\n" }
261
- temp_string = temp_string + "..\n"
262
-
263
- end
264
-
265
- # Creates the command informantion based on DOE 2.2 syntax.
266
- def get_command_from_string(command_string)
267
- #Split the command based on the equal '=' sign.
268
- remove = ""
269
- keyword=""
270
- value=""
271
-
272
- if (command_string != "")
273
- #Get command and u-value
274
- if ( command_string.match(/(^\s*(\".*?\")\s*\=\s*(\S+)\s*)/) )
275
- @commandName=$3.strip
276
- @utype = $2.strip
277
- remove = Regexp.escape($1)
278
-
279
- else
280
- # if no u-value, get just the command.
281
- command_string.match(/(^\s*(\S*)\s)/ )
282
- remove = Regexp.escape($1)
283
- @commandName=$2.strip
284
- end
285
- #Remove command from string.
286
-
287
- command_string.sub!(/#{remove}/,"")
288
- command_string.strip!
289
-
290
-
291
- #Loop throught the keyword values.
292
- while ( command_string.length > 0 )
293
- #DOEMaterial, or SCHEDULES
294
- if ( command_string.match(/(^\s*(MATERIAL|DAY-SCHEDULES|WEEK-SCHEDULES)\s*(\=?)\s*(.*)\s*)/))
295
- #puts "Bracket"
296
- keyword = $2.strip
297
- value = $4.strip
298
- remove = Regexp.escape($1)
299
- #Stars
300
- elsif ( command_string.match(/(^\s*(\S*)\s*(\=?)\s*(\*.*?\*)\s*)/))
301
- #puts "Bracket"
302
- keyword = $2.strip
303
- value = $4.strip
304
- remove = Regexp.escape($1)
305
-
306
- #Brackets
307
- elsif ( command_string.match(/(^\s*(\S*)\s*(\=?)\s*(\(.*?\))\s*)/))
308
- #puts "Bracket"
309
- keyword = $2.strip
310
- value = $4.strip
311
- remove = Regexp.escape($1)
312
- #Quotes
313
- elsif ( command_string.match(/(^\s*(\S*)\s*(\=?)\s*(".*?")\s*)/) )
314
- #puts "Quotes"
315
- keyword = $2
316
- value = $4.strip
317
- remove = Regexp.escape($1)
318
- #single command
319
- elsif command_string.match(/(^\s*(\S*)\s*(\=?)\s*(\S+)\s*)/)
320
- #puts "Other"
321
- keyword = $2
322
- value = $4.strip
323
- remove = Regexp.escape($1)
324
- end
325
- #puts "DOE22::DOECommand: #{command_string}"
326
- #puts "K = #{keyword} V = #{value}\n"
327
- if (keyword != "")
328
- set_keyword_value(keyword,value)
329
- end
330
- command_string.sub!(/#{remove}/,"")
331
- end
332
- #puts "Keyword"
333
- #puts keywordPairs
334
- end
335
- end
336
-
337
- #Returns an array of the commands parents.
338
- def get_parents
339
- return @parents
340
- end
341
-
342
- #Returns an array of the commands children.
343
- def get_children
344
- return children
345
- end
346
-
347
- # Gets name.
348
- def get_name()
349
- return @utype
350
- end
351
-
352
- # Check if keyword exists.
353
- def check_keyword?(keyword)
354
- @keywordPairs.each do |pair|
355
- if pair[0] == keyword
356
- return true
357
- end
358
- end
359
- return false
360
- end
361
-
362
- # Gets the parent of command...if any.
363
- def get_parent(keyword)
364
-
365
- get_parents().each do |findcommand|
366
-
367
- if ( findcommand.commandName == keyword)
368
- return findcommand
369
- end
370
- end
371
- return nil
372
-
373
- end
374
-
375
- #Gets children of command, if any.
376
- def get_children_of_command(keyword)
377
- array = Array.new()
378
- children.each do |findcommand|
379
- if ( findcommand.commandName == keyword)
380
- array.push(findcommand)
381
- end
382
- end
383
- return array
384
- end
385
-
386
- def name()
387
- return utype
388
- end
389
-
390
- private
391
- def add_keyword_pair(keyword,pair)
392
- array = [keyword,pair]
393
- keywordPairs.push(array)
394
- end
395
- end
396
- class DOEZone < BTAP::EQuest::DOECommand
397
- attr_accessor :space
398
- # a vector of spaces used when the declaration of space is "combined"
399
- attr_accessor :space_uses
400
- # a lighting object which stores the lighting characteristics of each zone
401
- attr_accessor :lighting
402
- #defines the thermal mass characteristics of the zone.
403
- #could be a string object or a user defined object
404
- attr_accessor :thermal_mass
405
- # stores a constant floating value of the amount of air leakage,
406
- #accoriding to rule #4.3.5.9.
407
- attr_accessor :air_leakage
408
- # this will be a vector consisting of heat transfer objects,
409
- # which contains a pointer to the adjacent thermal block and a pointer
410
- # to the wall in between them
411
- attr_accessor :heat_transfers
412
- def initialize
413
- super()
414
- end
415
-
416
- def output
417
-
418
- temp_string = basic_output()
419
- if (@space == nil)
420
- temp_string = temp_string + "$ No space found to match zone!\n"
421
- else
422
- temp_string = temp_string + "$Space\n"
423
- temp_string = temp_string + "$\t#{@space.utype} = #{@space.commandName}\n"
424
- end
425
- return temp_string
426
- end
427
-
428
- # This method finds all the exterior surfaces, ie. Exterior Wall and Roof
429
- # Output => surfaces as an Array of commands
430
- def get_exterior_surfaces()
431
- surfaces = Array.new()
432
- @space.get_children().each do |child|
433
-
434
- if child.commandName == "EXTERIOR-WALL" ||
435
- child.commandName == "ROOF"
436
- surfaces.push(child)
437
- end
438
- end
439
- return surfaces
440
- end
441
-
442
- # This method returns all the children of the space
443
- def get_children()
444
- return @space.get_children()
445
- end
446
-
447
-
448
-
449
- # This method returns the area of the space
450
- def get_area()
451
- @space.get_area()
452
- end
453
-
454
-
455
-
456
-
457
- def convert_to_openstudio(model,runner = nil)
458
- if self.space.get_shape() == "NO-SHAPE"
459
- BTAP::runner_register("Info", "Thermal Zone contains a NO-SHAPE space named. OS does not support no shape spaces. Thermal Zone will not be created.",runner)
460
- else
461
- os_zone = OpenStudio::Model::ThermalZone.new(model)
462
- os_zone.setName(self.name)
463
- #set space to thermal zone
464
- OpenStudio::Model::getSpaceByName(model,self.space.name).get.setThermalZone(os_zone)
465
- BTAP::runner_register("Info", "\tThermalZone: " + self.name + " created",runner)
466
- end
467
- end
468
- end
469
-
470
-
471
- class DOESurface < DOECommand
472
- attr_accessor :construction
473
- attr_accessor :polygon
474
-
475
- def initialize
476
- super()
477
- @polygon = nil
478
- end
479
-
480
- def get_azimuth()
481
- #puts OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 0.0, 0.0), OpenStudio::Vector3d.new(1.0, 0.0, 0.0) ) )
482
- if check_keyword?("LOCATION")
483
- case get_keyword_value("LOCATION")
484
- when /SPACE-\s*V\s*(.*)/
485
- index = $1.strip.to_i - 1
486
- point0 = self.get_parent("SPACE").polygon.point_list[index]
487
- point1 = self.get_parent("SPACE").polygon.point_list[index + 1] ? get_parent("SPACE").polygon.point_list[index + 1] : get_parent("SPACE").polygon.point_list[0]
488
- edge = point1-point0
489
-
490
- sign = OpenStudio::Vector3d.new(1.0, 0.0, 0.0).dot(( edge )) > 0 ? 1 :-1
491
- angle = OpenStudio::radToDeg( sign * OpenStudio::getAngle(OpenStudio::Vector3d.new(1.0, 0.0, 0.0), ( point1 - point0 ) ) )
492
-
493
- #since get angle only get acute angles we need to get sign and completment for reflex angle
494
- angle = angle + 180 if edge.y < 0
495
- return angle
496
- when "FRONT"
497
- return OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("SPACE").polygon.point_list[1] - get_parent("SPACE").polygon.point_list[0] ) ) )
498
- when "RIGHT"
499
- return OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("SPACE").polygon.point_list[2] - get_parent("SPACE").polygon.point_list[1] ) ) )
500
- when "BACK"
501
- return OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("SPACE").polygon.point_list[3] - get_parent("SPACE").polygon.point_list[2] ) ) )
502
- when "LEFT"
503
- return OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("SPACE").polygon.point_list[0] - get_parent("SPACE").polygon.point_list[3] ) ) )
504
- end
505
- end
506
- return self.check_keyword?("AZIMUTH")? self.get_keyword_value("AZIMUTH").to_f : 0.0
507
- end
508
-
509
- def get_tilt()
510
- #puts OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 0.0, 0.0), OpenStudio::Vector3d.new(1.0, 0.0, 0.0) ) )
511
- if check_keyword?("LOCATION")
512
- case get_keyword_value("LOCATION")
513
- when "FRONT","BACK","LEFT","RIGHT",/SPACE-\s*V\s*(.*)/
514
- return 90.0
515
- when "TOP"
516
- return 0.0
517
- when "BOTTOM"
518
- return 180.0
519
- end
520
- end
521
- return self.check_keyword?("TILT")? self.get_keyword_value("TILT").to_f : 0.0
522
- end
523
-
524
-
525
-
526
-
527
- def get_origin()
528
- space_xref = self.check_keyword?("X")? self.get_keyword_value("X").to_f : 0.0
529
- space_yref = self.check_keyword?("Y")? self.get_keyword_value("Y").to_f : 0.0
530
- space_zref = self.check_keyword?("Z")? self.get_keyword_value("Z").to_f : 0.0
531
- return OpenStudio::Vector3d.new(space_xref,space_yref,space_zref)
532
- end
533
-
534
- def get_sub_surface_origin()
535
- height = ""
536
- BTAP::runner_register("Info", "geting origin",runner)
537
- origin = ""
538
- if self.check_keyword?("X") and self.check_keyword?("Y") and self.check_keyword?("Z")
539
- BTAP::runner_register("Info", "XYZ definition",runner)
540
- space_xref = self.get_keyword_value("X").to_f
541
- space_yref = self.get_keyword_value("Y").to_f
542
- space_zref = self.get_keyword_value("Z").to_f
543
- return OpenStudio::Vector3d.new(space_xref,space_yref,space_zref)
544
- end
545
- BTAP::runner_register("Info", get_name(),runner)
546
- array = Array.new()
547
- origin = ""
548
- floor = get_parent("FLOOR")
549
- space = get_parent("SPACE")
550
- case space.get_keyword_value("ZONE-TYPE")
551
- when "PLENUM"
552
- height = floor.get_keyword_value("FLOOR-HEIGHT").to_f - floor.get_keyword_value("SPACE-HEIGHT").to_f
553
- when "CONDITIONED","UNCONDITIONED"
554
- height = space.check_keyword?("HEIGHT") ? space.get_keyword_value("HEIGHT").to_f : floor.get_keyword_value("SPACE-HEIGHT").to_f
555
-
556
- end
557
- BTAP::runner_register("Info", "Space is #{space.get_shape}",runner)
558
- case space.get_shape
559
- when "BOX"
560
- BTAP::runner_register("Info", "Box Space Detected....",runner)
561
- #get height, width and depth of box.
562
- height = space.check_keyword?("HEIGHT").to_f ? space.check_keyword?("HEIGHT") : height
563
- width = space.get_keyword_value("WIDTH").to_f
564
- depth = space.get_keyword_value("DEPTH").to_f
565
-
566
- case get_keyword_value("LOCATION")
567
- when "TOP"
568
- BTAP::runner_register("Info", "Top of Box....",runner)
569
- #counter clockwise
570
- origin = OpenStudio::Point3d.new(0.0,0.0,height)
571
-
572
- when "BOTTOM"
573
- BTAP::runner_register("Info", "Bottom of Box....",runner)
574
- #counter clockwise
575
- origin = OpenStudio::Point3d.new( 0.0, 0.0, 0.0 )
576
- when "FRONT"
577
- BTAP::runner_register("Info", "Front of Box....",runner)
578
- #counter clockwise
579
- origin = OpenStudio::Point3d.new( 0.0, 0.0, 0.0 )
580
- when "RIGHT"
581
- BTAP::runner_register("Info", "Right of Box....",runner)
582
- #counter clockwise
583
- origin = OpenStudio::Point3d.new(width, 0.0, 0.0)
584
- when "BACK"
585
- BTAP::runner_register("Info", "Back of Box....",runner)
586
- #counter clockwise
587
- origin = OpenStudio::Point3d.new(width,depth,0.0)
588
- when "LEFT"
589
- BTAP::runner_register("Info", "Left of Box....",runner)
590
- #counter clockwise
591
- origin = OpenStudio::Point3d.new(0.0,depth,0.0)
592
-
593
- end
594
-
595
- when "POLYGON"
596
- #puts "Polygon Space definition detected..."
597
- if check_keyword?("LOCATION")
598
- #puts "LOCATION surface definition detected..."
599
- case get_keyword_value("LOCATION")
600
- when "BOTTOM"
601
- origin = OpenStudio::Vector3d.new(0.0,0.0, 0.0 )
602
- when "TOP"
603
- #puts "TOP surface definition detected..."
604
- #need to move floor polygon up to space height for top. Using Transformation.translation matrix for this.
605
-
606
- origin = OpenStudio::Vector3d.new(0.0,0.0, height ) #to-do!!!!!!!!!!!
607
- when /SPACE-\s*V\s*(.*)/
608
- #puts "SPACE-V#{$1} surface definition detected..."
609
- index = $1.strip.to_i - 1
610
- point0 = space.polygon.point_list[index]
611
- #counter clockwise
612
- origin = OpenStudio::Point3d.new( point0.x, point0.y, 0.0)
613
-
614
- end
615
- else
616
- #puts "CATCH-ALL for surface definition.."
617
- #nasty. The height is NOT defined if the height is the same as the space height...so gotta get it from it's parent space.
618
- space_height = space.check_keyword?("HEIGHT") ? space.get_keyword_value("HEIGHT").to_f : floor.get_keyword_value("SPACE-HEIGHT").to_f
619
- height = self.check_keyword?("HEIGHT") ? self.get_keyword_value("HEIGHT").to_f : space_height
620
- width = self.get_keyword_value("WIDTH").to_f
621
- #origin
622
- origin = OpenStudio::Point3d.new(width,0.0,0.0)
623
- end
624
- when "NO-SHAPE"
625
- raise("Using SHAPE = NO-SHAPE deifnition for space is not supported by open Studio")
626
- end
627
-
628
- origin = OpenStudio::Vector3d.new(origin.x,origin.y,origin.z)
629
- #puts "Surface origin vector is #{origin}"
630
- return origin
631
- end
632
-
633
-
634
-
635
- def get_transformation_matrix
636
- #Rotate points around z (azimuth) and x (Tilt)
637
- translation = OpenStudio::createTranslation(self.get_origin)
638
- e_a = OpenStudio::EulerAngles.new( OpenStudio::degToRad( self.get_tilt ), 0.0, OpenStudio::degToRad( 180.0 - self.get_azimuth ) )
639
- rotations = OpenStudio::Transformation::rotation(e_a)
640
- return translation * rotations
641
- end
642
-
643
- def get_3d_polygon()
644
- array = Array.new()
645
- origin = ""
646
- floor = get_parent("FLOOR")
647
- space = get_parent("SPACE")
648
- case space.get_keyword_value("ZONE-TYPE")
649
- when "PLENUM"
650
- height = floor.get_keyword_value("FLOOR-HEIGHT").to_f - floor.get_keyword_value("SPACE-HEIGHT").to_f
651
- when "CONDITIONED","UNCONDITIONED"
652
- height = space.check_keyword?("HEIGHT") ? space.get_keyword_value("HEIGHT").to_f : floor.get_keyword_value("SPACE-HEIGHT").to_f
653
- end
654
-
655
- #if the surface has been given a polygon. Then use it.
656
- if check_keyword?("POLYGON")
657
- # puts "Polygon Surface Detected...Doing a local transform.."
658
- #
659
- # puts "Point List"
660
- # puts self.polygon.point_list
661
- # puts "Origin"
662
- # puts self.get_origin
663
- # puts "azimuth"
664
- # puts self.get_azimuth
665
- # puts "tilt"
666
- # puts self.get_tilt
667
-
668
-
669
-
670
- #all other methods below create points relative to the space. This method however, need to be transformed.
671
- array = self.polygon.point_list
672
-
673
-
674
- #if surfaces are defined by shape of space.
675
- else
676
- case space.get_shape
677
- when "BOX"
678
- BTAP::runner_register("Info", "Box Space Detected....",runner)
679
- #get height, width and depth of box.
680
- height = space.check_keyword?("HEIGHT").to_f ? space.check_keyword?("HEIGHT") : height
681
- width = space.get_keyword_value("WIDTH").to_f
682
- depth = space.get_keyword_value("DEPTH").to_f
683
-
684
- case get_keyword_value("LOCATION")
685
- when "TOP"
686
- #puts "Top of Box...."
687
- #counter clockwise
688
- origin = OpenStudio::Point3d.new(0.0,0.0,height)
689
- p2 = OpenStudio::Point3d.new(width,0.0,height)
690
- p3 = OpenStudio::Point3d.new(width,depth,height)
691
- p4 = OpenStudio::Point3d.new(0.0,depth,height)
692
- array = [origin,p2,p3,p4]
693
- when "BOTTOM"
694
- #puts "Bottom of Box...."
695
- #counter clockwise
696
- origin = OpenStudio::Point3d.new( 0.0, 0.0, 0.0 )
697
- p2 = OpenStudio::Point3d.new( 0.0, depth, 0.0)
698
- p3 = OpenStudio::Point3d.new( width, depth, 0.0)
699
- p4 = OpenStudio::Point3d.new( width,0.0 ,0.0 )
700
- array = [origin,p2,p3,p4]
701
- when "FRONT"
702
- #puts "Front of Box...."
703
- #counter clockwise
704
- origin = OpenStudio::Point3d.new( 0.0, 0.0, 0.0 )
705
- p2 = OpenStudio::Point3d.new( width,0.0 ,0.0 )
706
- p3 = OpenStudio::Point3d.new( width, 0.0, height)
707
- p4 = OpenStudio::Point3d.new( 0.0, 0.0, height)
708
- array = [origin,p2,p3,p4]
709
- when "RIGHT"
710
- #puts "Right of Box...."
711
- #counter clockwise
712
- origin = OpenStudio::Point3d.new(width, 0.0, 0.0)
713
- p2 = OpenStudio::Point3d.new(width,depth, 0.0)
714
- p3 = OpenStudio::Point3d.new(width,depth,height)
715
- p4 = OpenStudio::Point3d.new(width,0.0,height)
716
- array = [origin,p2,p3,p4]
717
- when "BACK"
718
- #puts "Back of Box...."
719
- #counter clockwise
720
- origin = OpenStudio::Point3d.new(width,depth,0.0)
721
- p2 = OpenStudio::Point3d.new(0.0,depth,0.0)
722
- p3 = OpenStudio::Point3d.new(0.0,depth,height)
723
- p4 = OpenStudio::Point3d.new(width,depth,height)
724
- array = [origin,p2,p3,p4]
725
- when "LEFT"
726
- #puts "Left of Box...."
727
- #counter clockwise
728
- origin = OpenStudio::Point3d.new(0.0,depth,0.0)
729
- p2 = OpenStudio::Point3d.new( 0.0, 0.0, 0.0 )
730
- p3 = OpenStudio::Point3d.new(0.0, 0.0,height)
731
- p4 = OpenStudio::Point3d.new(0.0,depth,height)
732
- array = [origin,p2,p3,p4]
733
- end
734
-
735
- when "POLYGON"
736
- #puts "Polygon Space definition detected..."
737
- if check_keyword?("LOCATION")
738
- #puts "LOCATION surface definition detected..."
739
- case get_keyword_value("LOCATION")
740
- when "BOTTOM"
741
- #puts "BOTTOM surface definition detected..."
742
- #reverse array
743
- array = space.polygon.point_list.dup
744
- first = array.pop
745
- array.insert(0,first).reverse!
746
- when "TOP"
747
- #puts "TOP surface definition detected..."
748
- #need to move floor polygon up to space height for top. Using Transformation.translation matrix for this.
749
- array = OpenStudio::createTranslation(OpenStudio::Vector3d.new(0.0,0.0, height )) * space.polygon.point_list
750
- when /SPACE-\s*V\s*(.*)/
751
- #puts "SPACE-V#{$1} surface definition detected..."
752
- index = $1.strip.to_i - 1
753
- point0 = space.polygon.point_list[index]
754
- point1 = space.polygon.point_list[index + 1] ? space.polygon.point_list[index + 1] : space.polygon.point_list[0]
755
- #counter clockwise
756
- origin = OpenStudio::Point3d.new( point0.x, point0.y, 0.0)
757
- p2 = OpenStudio::Point3d.new( point1.x, point1.y, 0.0)
758
- p3 = OpenStudio::Point3d.new( point1.x, point1.y, height )
759
- p4 = OpenStudio::Point3d.new( point0.x, point0.y, height )
760
- array = [origin,p2,p3,p4]
761
- end
762
- else
763
- #puts "CATCH-ALL for surface definition.."
764
- #nasty. The height is NOT defined if the height is the same as the space height...so gotta get it from it's parent space.
765
- space_height = space.check_keyword?("HEIGHT") ? space.get_keyword_value("HEIGHT").to_f : floor.get_keyword_value("SPACE-HEIGHT").to_f
766
- height = self.check_keyword?("HEIGHT") ? self.get_keyword_value("HEIGHT").to_f : space_height
767
- width = self.get_keyword_value("WIDTH").to_f
768
- #counter clockwise
769
- origin = OpenStudio::Point3d.new(width,0.0,0.0)
770
- p2 = OpenStudio::Point3d.new( 0.0,0.0,0.0 )
771
- p3 = OpenStudio::Point3d.new(0.0,0.0,height)
772
- p4 = OpenStudio::Point3d.new(width,0.0,height)
773
- array = [p4, p3, p2, origin]
774
-
775
-
776
-
777
- end
778
- when "NO-SHAPE"
779
- raise("Using SHAPE = NO-SHAPE deifnition for space is not supported...yet")
780
- end
781
- end
782
- # if self.check_keyword?("AZIMUTH") or self.check_keyword?("TILT")
783
- # puts "Did a transform"
784
- # return get_transformation_matrix * array
785
- # else
786
- # return array
787
- # end
788
- return array
789
- end
790
-
791
-
792
- def get_windows()
793
- return self.get_children_of_command("WINDOW")
794
- end
795
-
796
- def get_doors()
797
- return self.get_children_of_command("DOOR")
798
- end
799
-
800
-
801
-
802
- # This method finds all the commands within the building that are "Construction"
803
- # and if the utype matches, it gets the construction
804
- def determine_user_defined_construction()
805
- constructions = @building.find_all_commands("CONSTRUCTION")
806
- constructions.each do |construction|
807
- if ( construction.utype == get_keyword_value("CONSTRUCTION") )
808
- @construction = construction
809
- end
810
- end
811
- return @construction
812
- end
813
-
814
- #This method will try to convert a DOE inp file to an openstudio file..
815
- def convert_to_openstudio(model,runner = nil)
816
- #Get 3d polygon of surface and tranform the points based on space origin and the floor origin since they each may use their own co-ordinate base system.
817
- total_transform = ""
818
- if self.check_keyword?("AZIMUTH") or self.check_keyword?("TILT")
819
- total_transform = get_parent("FLOOR").get_transformation_matrix() * get_parent("SPACE").get_transformation_matrix() * get_transformation_matrix()
820
- else
821
- total_transform = get_parent("FLOOR").get_transformation_matrix() * get_parent("SPACE").get_transformation_matrix()
822
- end
823
- surface_points = total_transform * self.get_3d_polygon()
824
- #Add the surface to the new openstudio model.
825
-
826
- os_surface = OpenStudio::Model::Surface.new(surface_points, model)
827
- #set the name of the surface.
828
- os_surface.setName(self.name)
829
- case self.commandName
830
- #Set the surface boundary condition if it is a ground surface.
831
-
832
- when "UNDERGROUND-WALL"
833
- BTAP::Geometry::Surfaces::set_surfaces_boundary_condition(model,os_surface, "Ground")
834
- when "EXTERIOR-WALL","ROOF"
835
- #this is needed since the surface constructor defaults to a Ground boundary and Floor Surface type
836
- #when a horizontal surface is initialized.
837
- if os_surface.outsideBoundaryCondition == "Ground" and os_surface.surfaceType == "Floor"
838
- os_surface.setSurfaceType("RoofCeiling")
839
- end
840
- BTAP::Geometry::Surfaces::set_surfaces_boundary_condition(model,os_surface, "Outdoors")
841
- when "INTERIOR-WALL"
842
- BTAP::Geometry::Surfaces::set_surfaces_boundary_condition(model,os_surface, "Surface")
843
- end
844
-
845
- #Add to parent space that was already created.
846
- os_surface.setSpace(OpenStudio::Model::getSpaceByName( model,get_parent("SPACE").name).get )
847
- #output to console for debugging.
848
- BTAP::runner_register("Info", "\tSurface: " + self.name + " created",runner)
849
- #check if we need to create a mirror surface in another space.
850
- if self.check_keyword?("NEXT-TO")
851
- #reverse the points.
852
- new_array = surface_points.dup
853
- first = new_array.pop
854
- new_array.insert(0,first).reverse!
855
- #...then add the reverse surface to the model and assign the name with a mirror suffix.
856
- os_surface_mirror = OpenStudio::Model::Surface.new(new_array, model)
857
- os_surface_mirror.setName(self.name + "-mirror" )
858
- #Assign the mirror surface to the parent space that is NEXT-TO
859
- os_surface_mirror.setSpace(OpenStudio::Model::getSpaceByName(model,get_keyword_value("NEXT-TO")).get)
860
- #output to console for debugging.
861
- BTAP::runner_register("Info", "\tSurface: " + self.name + "-mirror" + " created",runner)
862
- end #if statement
863
-
864
- #Some switches for debugging.
865
- convert_sub_surfaces = true
866
- convert_sub_surfaces_as_surfaces = false
867
-
868
- #
869
- if convert_sub_surfaces
870
- #convert subsurfaces
871
- self.get_children().each do |child|
872
- #Get height and width of subsurface
873
- height = child.get_keyword_value("HEIGHT").to_f
874
- width = child.get_keyword_value("WIDTH").to_f
875
-
876
-
877
- #Sum the origin of the surface and the translation of the window
878
- x = os_surface.vertices.first().x + ( child.check_keyword?("X")? child.get_keyword_value("X").to_f : 0.0 )
879
- y = os_surface.vertices.first().y + ( child.check_keyword?("Y")? child.get_keyword_value("Y").to_f : 0.0 )
880
- z = os_surface.vertices.first().z
881
-
882
- #counter clockwise
883
- origin = OpenStudio::Point3d.new( x, y , z )
884
- p2 = OpenStudio::Point3d.new(x + width , y, z )
885
- p3 = OpenStudio::Point3d.new(x + width , y + height , z )
886
- p4 = OpenStudio::Point3d.new(x, y + height, z )
887
- polygon = [origin,p2,p3,p4]
888
-
889
- #get floot and space rotations
890
- space_azi = 360.0 - get_parent("SPACE").get_azimuth()
891
- floor_azi = 360.0 - get_parent("FLOOR").get_azimuth()
892
-
893
-
894
- tilt_trans = OpenStudio::Transformation::rotation(os_surface.vertices.first(), OpenStudio::Vector3d.new(1.0,0.0,0.0), OpenStudio::degToRad( self.get_tilt ))
895
- azi_trans = OpenStudio::Transformation::rotation(os_surface.vertices.first(), OpenStudio::Vector3d.new(0.0,0.0,1.0), OpenStudio::degToRad( 360.0 - self.get_azimuth + space_azi + floor_azi ))
896
- surface_points = azi_trans * tilt_trans * polygon
897
- if convert_sub_surfaces_as_surfaces
898
- #Debug subsurface
899
- os_sub_surface = OpenStudio::Model::Surface.new(surface_points, model)
900
- #set the name of the surface.
901
- os_sub_surface.setName(child.name)
902
- #Add to parent space that was already created.
903
- os_sub_surface.setSpace(OpenStudio::Model::getSpaceByName( model,self.get_parent("SPACE").name).get )
904
- else
905
- #Add the subsurface to the new openstudio model.
906
- os_sub_surface = OpenStudio::Model::SubSurface.new(surface_points, model)
907
- #set the name of the surface.
908
- os_sub_surface.setName(child.name)
909
- #Add to parent space that was already created.
910
- os_sub_surface.setSurface(os_surface)
911
- #output to console for debugging.
912
- BTAP::runner_register("Info", "\tSubSurface: " + child.name + " created",runner)
913
- case child.commandName
914
- when "WINDOW"
915
- #By default it is a window.
916
- when "DOOR"
917
- os_sub_surface.setSubSurfaceType( "Door" )
918
- end #end case.
919
-
920
- # Add overhang for subsurface if required. Note this only supports overhangs of width the same as the window.
921
- if child.check_keyword?("OVERHANG-D") == true
922
- offset = 0.0
923
- offset = child.get_keyword_value("OVERHANG-O").to_f if child.check_keyword?("OVERHANG-O")
924
- depth = 0.0
925
- depth = child.get_keyword_value("OVERHANG-D").to_f
926
- os_sub_surface.addOverhang( depth , offset )
927
- end
928
-
929
- end
930
- end
931
- end
932
- end
933
-
934
- end
935
-
936
- #This class allows to manipulate a subsurface (window/door) in inherits from surface.
937
- class DOESubSurface < DOESurface
938
-
939
- def initialize
940
- #run the parent class initialization.
941
- super()
942
- end
943
-
944
- # This method returns the area of the window
945
- def get_area()
946
- unless check_keyword?("HEIGHT") and check_keyword?("WIDTH")
947
- raise "Error: In the command #{@utype}:#{@command_name} the area could not be evaluated. Either the HEIGHT or WIDTH is invalid.\n #{output}"
948
- end
949
- return get_keyword_value("WIDTH").to_f * get_keyword_value("HEIGHT").to_f
950
- end
951
-
952
- #Return the widow polygon with an origin of zero
953
- def get_3d_polygon()
954
- height = get_keyword_value("HEIGHT").to_f
955
- width = get_keyword_value("WIDTH").to_f
956
- x = self.check_keyword?("X")? self.get_keyword_value("X").to_f : 0.0
957
- y = self.check_keyword?("Y")? self.get_keyword_value("Y").to_f : 0.0
958
- #counter clockwise
959
- origin = OpenStudio::Point3d.new( x, y , 0.0 )
960
- p2 = OpenStudio::Point3d.new(x + width , y,0.0 )
961
- p3 = OpenStudio::Point3d.new(x + width , y + height , 0.0 )
962
- p4 = OpenStudio::Point3d.new(x, y + height,0.0 )
963
- return [origin,p2,p3,p4]
964
- end
965
-
966
- #Returns the origin relative to the parent surface.
967
- def get_origin()
968
- origin = get_parent_surface().get_sub_surface_origin()
969
- return origin
970
- end
971
-
972
- #Gets azimuth, based on parent surface.
973
- def get_azimuth()
974
- get_parent_surface().get_azimuth()
975
- end
976
-
977
- #gets tilt based on parent surface.
978
- def get_tilt()
979
- get_parent_surface().get_tilt()
980
- end
981
-
982
- #return the parent surface of the subsurface.
983
- def get_parent_surface()
984
- get_parents().each do |findcommand|
985
- [
986
- "EXTERIOR-WALL",
987
- "INTERIOR-WALL",
988
- "UNDERGROUND-WALL",
989
- "ROOF"
990
- ].each do |type|
991
-
992
- if ( findcommand.commandName == type)
993
- return findcommand
994
- end
995
- end
996
- end
997
- raise("#no parent surface defined!")
998
- end
999
-
1000
- #returns the translation matrix reletive to its parent ( the surface )
1001
- def get_transformation_matrix
1002
- return self.get_rotation_matrix() * self.get_translation_matrix()
1003
- end
1004
-
1005
- def get_rotation_matrix
1006
- #Rotate points around z (azimuth) and x (Tilt)
1007
- e_a = OpenStudio::EulerAngles.new( OpenStudio::degToRad( self.get_tilt ), 0.0, OpenStudio::degToRad( 0.0 ) )
1008
- rotations = OpenStudio::Transformation::rotation(e_a)
1009
- return rotations
1010
- end
1011
-
1012
- def get_translation_matrix
1013
- #Rotate points around z (azimuth) and x (Tilt)
1014
- translation = OpenStudio::createTranslation(self.get_origin)
1015
- return translation
1016
- end
1017
-
1018
-
1019
-
1020
-
1021
-
1022
- # this will translate the subsurface to the openstudio model.
1023
- def convert_to_openstudio(model)
1024
- end
1025
- end
1026
-
1027
- #an attempt to organize the BDLlibs...don't think it works well at all.
1028
- class DOEBDLlib
1029
-
1030
- attr_accessor :db, :materials
1031
-
1032
- include Singleton
1033
-
1034
-
1035
-
1036
-
1037
- # stores the name of the individual materials
1038
-
1039
- attr_accessor :commandList
1040
- # stores the name of the individual layers
1041
-
1042
-
1043
- def initialize
1044
- @commandList = Array.new()
1045
- @db = Sequel.sqlite
1046
- @db.create_table :materials do # Create a new table
1047
- primary_key :id, :integer, :auto_increment => true
1048
- column :command_name, :text
1049
- column :name, :text
1050
- column :type, :text
1051
- column :thickness, :float
1052
- column :conductivity, :float
1053
- column :resistance, :float
1054
- column :density, :float
1055
- column :spec_heat, :float
1056
- end
1057
- @materials = @db[:materials] # Create a dataset
1058
-
1059
- @db.create_table :layers do # Create a new table
1060
- primary_key :id, :integer, :auto_increment => true
1061
- column :command_name, :text
1062
- column :name, :text
1063
- column :material, :text
1064
- column :inside_film_res, :float
1065
- end
1066
- @layers = @db[:layers] # Create a dataset
1067
-
1068
-
1069
- store_material()
1070
- end
1071
-
1072
-
1073
-
1074
- def find_material(utype)
1075
- posts = @materials.filter(:name => utype)
1076
- record = posts.first()
1077
- #Create the new command object.
1078
- command = DOE2::DOECommand.new()
1079
- #Insert the collected information into the object.
1080
- command.commandName = "MATERIAL"
1081
- command.utype = record[:name]
1082
- command.set_keyword_value("TYPE", record[:type])
1083
- command.set_keyword_value("THICKNESS", record[:thickness])
1084
- command.set_keyword_value("CONDUCTIVITY", record[:conductivity])
1085
- command.set_keyword_value("DENSITY", record[:density])
1086
- command.set_keyword_value("SPECIFIC HEAT", record[:spec_heat])
1087
-
1088
- return command
1089
- end
1090
-
1091
-
1092
- def find_layer(utype)
1093
- posts = @layers.filter(:name => utype)
1094
- record = posts.first()
1095
- #Create the new command object.
1096
- command = DOE2::DOECommand.new()
1097
- #Insert the collected information into the object.
1098
- command.commandName = "LAYERS"
1099
- command.utype = record[:name]
1100
- command.set_keyword_value("MATERIAL", record[:material])
1101
- command.set_keyword_value("THICKNESS", record[:thickness])
1102
- command.set_keyword_value("CONDUCTIVITY", record[:conductivity])
1103
- command.set_keyword_value("DENSITY", record[:density])
1104
- command.set_keyword_value("SPECIFIC HEAT", record[:spec_heat])
1105
-
1106
- return command
1107
- end
1108
-
1109
-
1110
-
1111
-
1112
-
1113
- # stores the material information using keywordPairs into the command structure
1114
- # accessed using the find_command method
1115
- private
1116
- def store_material
1117
-
1118
- begin
1119
- f = File.open("../Resources/DOE2_2/bdllib.dat")
1120
- rescue
1121
- f = File.open("Resources/DOE2_2/bdllib.dat")
1122
- end
1123
-
1124
- lines = f.readlines
1125
- # Iterating through the file.
1126
- lines.each_index do |i|
1127
- command_string = ""
1128
- # If we find a material.
1129
- if lines[i].match(/\$LIBRARY-ENTRY\s(.{32})MAT .*/)
1130
- #Get the name strips the white space.
1131
- name = ("\""+$1.strip + "\"")
1132
-
1133
- #Is this the last line?
1134
- command_string = get_data(command_string, i, lines)
1135
- #Extract data for material type PROPERTIES.
1136
- if (match = command_string.match(/^\s*TYPE\s*=\s*(\S*)\s*TH\s*=\s*(\S*)\s*COND\s*=\s*(\S*)\s*DENS\s*=\s*(\S*)\s*S-H\s*=\s*(\S*)\s*$/) )
1137
- #Create the new command object.
1138
- command = DOE2::DOECommand.new()
1139
- #Insert the collected information into the object.
1140
- command.commandName = "MATERIAL"
1141
- command.utype = name
1142
- command.set_keyword_value("TYPE", $1.strip)
1143
- command.set_keyword_value("THICKNESS", $2.strip.to_f.to_s)
1144
- command.set_keyword_value("CONDUCTIVITY", $3.strip.to_f.to_s)
1145
- command.set_keyword_value("DENSITY", $4.strip.to_f.to_s)
1146
- command.set_keyword_value("SPECIFIC HEAT", $5.strip.to_f.to_s)
1147
- #Push the object into the array for storage.
1148
- @commandList.push(command)
1149
- @materials << {:name => name,
1150
- :command_name => 'MATERIAL',
1151
- :type => $1.strip,
1152
- :thickness => $2.strip.to_f.to_s,
1153
- :conductivity => $3.strip.to_f.to_s,
1154
- :density => $4.strip.to_f.to_s,
1155
- :spec_heat => $5.strip.to_f.to_s}
1156
-
1157
-
1158
-
1159
- #Extract data for material type RESISTANCE.
1160
- elsif (match = command_string.match(/^\s*TYPE\s*=\s*(\S*)\s*RES\s*=\s*(\S*)\s*$/) )
1161
- command = DOE2::DOECommand.new()
1162
- command.commandName = "MATERIAL"
1163
- command.utype = name
1164
- command.set_keyword_value("TYPE", $1.strip)
1165
- command.set_keyword_value("RESISTANCE", $2.strip.to_f.to_s)
1166
- #Push the object into the array for storage.
1167
- @materials << {:name => name,
1168
- :command_name => 'MATERIAL',
1169
- :type => $1.strip,
1170
- :resistance => $2.strip.to_f.to_s}
1171
-
1172
- @commandList.push(command)
1173
- else
1174
- raise("data not extracted")
1175
- end
1176
- end
1177
-
1178
- if lines[i].match(/\$LIBRARY-ENTRY\s(.{32})LA .*/)
1179
- #Get the name
1180
- name = ("\""+$1.strip + "\"")
1181
- #Is this the last line?
1182
- command_string = get_data(command_string, i, lines)
1183
- #Extract data into the command.
1184
- if (match = command_string.match(/^\s*MAT\s*=\s*(.*?)\s*I-F-R\s*=\s*(\S*)\s*$/) )
1185
- command = DOE2::DOECommand.new()
1186
- command.commandName = "LAYERS"
1187
- command.utype = name
1188
- command.set_keyword_value("MATERIAL",$1)
1189
- #Push the object into the array for storage.
1190
- @layers << {:name => name,
1191
- :command_name => 'LAYER',
1192
- :material => $1.strip,
1193
- :inside_film_res => $2.strip.to_f.to_s}
1194
- @commandList.push(command)
1195
- else
1196
- raise("data not extracted")
1197
- end
1198
- end
1199
- end
1200
- end
1201
-
1202
- private
1203
- # This method will get all the
1204
- def get_data(command_string, i, lines)
1205
- #Do this while this is NOT the last line of data.
1206
- while (! lines[i].match(/^(.*?)\.\.\s*(.{6})?\s*?(\d*)?/) )
1207
- #Grab all the data in between.
1208
- if ( lines[i].match(/^\$.*$/) )
1209
- elsif ( myarray = lines[i].match(/^(.*?)\s*(.{6})?\s*?(\d*)?\s*$/) )
1210
- command_string = command_string + $1.strip
1211
- end
1212
- #Increment counter.
1213
- i = i + 1
1214
- end
1215
- #Get the last line
1216
- lines[i].match(/^(.*?)\.\.\s*(.{6})?\s*?(\d*)?/)
1217
- command_string = command_string + $1.strip
1218
- if command_string == ""
1219
- raise("error")
1220
- end
1221
- i = i + 1
1222
- command_string
1223
- end
1224
- end
1225
-
1226
- #class that
1227
- class DOEExteriorWall < DOESurface
1228
-
1229
- def initialize
1230
- #call the parent class.
1231
- super()
1232
- end
1233
-
1234
- # This method finds the area of the exterior wall
1235
- def get_area()
1236
- OpenStudio::getArea(self.get_3d_polygon())
1237
- end
1238
-
1239
- #This method finds the floor parent
1240
- def get_floor()
1241
- get_parent("FLOOR")
1242
- end
1243
-
1244
- #This method finds the space parent command
1245
- def get_space()
1246
- get_parent("SPACE")
1247
- end
1248
-
1249
- #This method gets the construction command
1250
- def get_construction_name()
1251
- get_keyword_value("CONSTRUCTION")
1252
- end
1253
-
1254
- #This method returns the window area
1255
- def get_window_area()
1256
- get_children_area("WINDOW")
1257
- end
1258
-
1259
- #This method returns the door area
1260
- def get_door_area()
1261
- get_children_area("DOOR")
1262
- end
1263
-
1264
- # This method returns the difference between the wall area and the window
1265
- # and door
1266
- def get_opaque_area()
1267
- get_area.to_f - get_window_area().to_f - get_door_area().to_f
1268
- end
1269
-
1270
- # This method returns the fraction of the wall dominated by the window
1271
- def get_fwr()
1272
- get_window_area().to_f / get_area.to_f
1273
- end
1274
-
1275
- # This method returns the area of the children classes based on the given
1276
- # commandname.
1277
- # Input => A command_name as a String
1278
- # Output => Total area as a float
1279
- def get_children_area(scommand_name)
1280
- area = 0.0
1281
- @children.each do |child|
1282
-
1283
- if child.commandName == scommand_name
1284
- area = child.get_area() + area
1285
- end
1286
- end
1287
- return area
1288
- end
1289
-
1290
- # This method checks if the construction only has a defined U-value
1291
- def just_u_value?()
1292
- @construction.check_keyword?("U-VALUE")
1293
- end
1294
-
1295
-
1296
- end
1297
-
1298
-
1299
-
1300
-
1301
-
1302
-
1303
- #The interface for the roof command.. same as parent.
1304
- class DOERoof < DOECommand
1305
- def initialize
1306
- super()
1307
- end
1308
-
1309
- # This method finds the area of the roof
1310
- def get_area
1311
-
1312
- # Finds the floor and space parents and assigns them to @floor and @space
1313
- # variables to be used later
1314
- parent = get_parents
1315
- parent.each do |findcommand|
1316
- if ( findcommand.commandName == "FLOOR" )
1317
- @floor = findcommand
1318
- end
1319
- if ( findcommand.commandName == "SPACE")
1320
- @space = findcommand
1321
- end
1322
- end
1323
-
1324
- # Get the keyword value for location
1325
- begin
1326
- location = get_keyword_value("LOCATION")
1327
- rescue
1328
- end
1329
-
1330
- # Get the keyword value for polygon
1331
- begin
1332
- polygon_id = get_keyword_value("POLYGON")
1333
- rescue
1334
- end
1335
-
1336
- # if the polygon_id keyword value was nil and the location value was nil, then
1337
- # the height and width are directly defined within the "roof" command
1338
-
1339
-
1340
- if ( location == "BOTTOM" || location == "TOP") && (@space.get_shape != "BOX")
1341
- return @space.polygon.get_area
1342
-
1343
- elsif ( location == nil && polygon_id == nil )
1344
- height = get_keyword_value("HEIGHT")
1345
- width = get_keyword_value("WIDTH")
1346
- height = height.to_f
1347
- width = width.to_f
1348
- return height * width
1349
- elsif ( location == nil && polygon_id != nil)
1350
- return @space.polygon.get_area
1351
-
1352
-
1353
- # if the location was defined as "SPACE...", it is immediately followed by a
1354
- # vertex, upon which lies the width of the roof
1355
- elsif location.match(/SPACE.*/)
1356
- location = location.sub( /^(.{6})/, "")
1357
- width = @space.polygon.get_length(location)
1358
- height = @floor.get_space_height
1359
- return width * height
1360
- # if the shape was a box, the width and height would be taken from the
1361
- # "SPACE" object
1362
- elsif ( @space.get_shape == "BOX" )
1363
- width = @space.get_width
1364
- height = @space.get_height
1365
- return width * height
1366
- else
1367
- raise "The area could not be evaluated"
1368
- end
1369
- end
1370
-
1371
- #returns tilt of roof surface.
1372
- def get_tilt()
1373
- if check_keyword?("TILT") then return get_keyword_value("TILT").to_f
1374
- else
1375
- if check_keyword?("LOCATION")
1376
- location = get_keyword_value("LOCATION")
1377
- case location
1378
- when "TOP"
1379
- return 0.0
1380
- when "BOTTOM"
1381
- return 180.0
1382
- when "LEFT", "RIGHT", "BACK", "FRONT"
1383
- return 90.0
1384
- end
1385
- end
1386
- # If it is a polygon or not defined, set to DOE default = 0.0
1387
- return 0
1388
- end
1389
- end
1390
-
1391
- # This method returns the Azimuth value as a FLOAT if it exists
1392
- # It first checks if the azimuth keyword value is present within the roof
1393
- # command itself. If it does not find this, then it checks for the location
1394
- # keyword and assigns the correct azimuth depending on the azimuth of the parent
1395
- # space. However, if the shape of the parent space is defined as a polygon, then it
1396
- # searches for the location of the roof and uses the polygon's get-azimuth for the vertex
1397
- # to return the azimuth of the roof
1398
-
1399
- #NOTE: The FRONT is defined as 0, going clockwise, ie. RIGHT = 90 degrees
1400
-
1401
- #OUTPUT: Azimuth between the parent SPACE and the ROOF
1402
- def get_azimuth()
1403
- space = get_parent("SPACE")
1404
- if check_keyword?("AZIMUTH") then return get_keyword_value("AZIMUTH").to_f
1405
- else
1406
- if check_keyword?("LOCATION")
1407
- location = get_keyword_value("LOCATION")
1408
-
1409
- case location
1410
- when "TOP"
1411
- raise "Exception: Azimuth does not exist"
1412
- when "BOTTOM"
1413
- raise "Exception: Azimuth does not exist"
1414
- when "FRONT"
1415
- return 0.0 + space.get_azimuth
1416
- when "RIGHT"
1417
- return 90.0 + space.get_azimuth
1418
- when "BACK"
1419
- return 180.0 + space.get_azimuth
1420
- when "LEFT"
1421
- return 270.0 + space.get_azimuth
1422
- end
1423
- end
1424
- if space.get_keyword_value("SHAPE") == "POLYGON"
1425
- space_vertex = get_keyword_value("LOCATION")
1426
- space_vertex.match(/SPACE-(.*)/)
1427
- vertex = $1.strip
1428
- return space.polygon.get_azimuth(vertex)
1429
- end
1430
-
1431
- end
1432
- end
1433
-
1434
- # This method returns the Azimuth value as a FLOAT if it exists
1435
- # It first checks if the azimuth keyword value is present within the roof
1436
- # command itself. If it does not find this, then it checks for the location
1437
- # keyword and assigns the correct azimuth depending on the azimuth of the parent
1438
- # space. However, if the shape of the parent space is defined as a polygon, then it
1439
- # searches for the location of the roof and uses the polygon's get-azimuth for the vertex
1440
- # and adding it on to the overall azimuth to get the Absolute Azimuth from True North
1441
-
1442
- #NOTE: The FRONT is defined as 0, going clockwise, ie. RIGHT = 90 degrees
1443
-
1444
- #OUTPUT: Azimuth between ROOF and TRUE NORTH
1445
- def get_absolute_azimuth
1446
- space = get_parent("SPACE")
1447
- if check_keyword?("AZIMUTH")
1448
- azimuth = get_keyword_value("AZIMUTH").to_f
1449
- space_azimuth = space.get_absolute_azimuth
1450
- return azimuth + space_azimuth
1451
- else
1452
- if check_keyword?("LOCATION")
1453
- location = get_keyword_value("LOCATION")
1454
- case location
1455
- when "TOP"
1456
- raise "Exception: Azimuth does not exist"
1457
- when "BOTTOM"
1458
- raise "Exception: Azimuth does not exist"
1459
- when "FRONT"
1460
- return 0.0 + space.get_absolute_azimuth
1461
- when "RIGHT"
1462
- return 90.0 + space.get_absolute_azimuth
1463
- when "BACK"
1464
- return 180.0 + space.get_absolute_azimuth
1465
- when "LEFT"
1466
- return 270.0 + space.get_absolute_azimuth
1467
- end
1468
- end
1469
- if space.get_keyword_value("SHAPE") == "POLYGON"
1470
- space_vertex = get_keyword_value("LOCATION")
1471
- space_vertex.match(/SPACE-(.*)/)
1472
- vertex = $1.strip
1473
- return space.polygon.get_azimuth(vertex) + space.get_absolute_azimuth
1474
- end
1475
- end
1476
- end
1477
- end
1478
- #Interface for the DOESpace Command.
1479
- class DOESpace < DOECommand
1480
- attr_accessor :polygon
1481
- attr_accessor :zone
1482
- def initialize
1483
-
1484
- super()
1485
- end
1486
-
1487
- #this outputs the command to a string.
1488
- def output
1489
- temp_string = basic_output()
1490
- if @polygon != nil
1491
- temp_string = temp_string + "$Polygon\n"
1492
- temp_string = temp_string + "$\t#{@polygon.utype} = #{@polygon.commandName}\n"
1493
- end
1494
- if @zone != nil
1495
- temp_string = temp_string + "$Zone\n"
1496
- temp_string = temp_string + "$\t#{@zone.utype} = #{@zone.commandName}\n"
1497
- end
1498
- return temp_string
1499
- end
1500
-
1501
- # This method finds the area of the space
1502
- def get_area
1503
-
1504
- # get the keyword value of shape
1505
- shape = get_keyword_value("SHAPE")
1506
-
1507
- # if the shape value is nil, or it is defined as "NO-SHAPE", the get_area value
1508
- # would be defined, and would represent the get_area of the space
1509
- if ( shape == nil || shape == "NO-SHAPE")
1510
- area = get_keyword_value("AREA")
1511
- area = area.to_f
1512
- return area
1513
-
1514
- # if the shape value is "BOX", the height and width key values are given,
1515
- # and the get_area would be defined as their product
1516
- elsif ( shape == "BOX" )
1517
- height = get_keyword_value("HEIGHT")
1518
- width = get_keyword_value("WIDTH")
1519
- height = height.to_f
1520
- width = width.to_f
1521
- return height * width
1522
-
1523
- # if the shape value is defined as a polygon , the get_area of the polygon would
1524
- # represent the get_area of the space
1525
- elsif ( shape == "POLYGON")
1526
- return @polygon.get_area
1527
- else
1528
- raise "Error: The area could not be evaluated. Please check inputs\n "
1529
-
1530
- end
1531
- end
1532
-
1533
- # This method finds the volume of the space
1534
- def get_volume
1535
-
1536
- # get the keyword value of "SHAPE"
1537
- shape = get_keyword_value("SHAPE")
1538
-
1539
- # if the shape value returns nil, or is defined as "NO-SHAPE", the volume is
1540
- # given directly
1541
- if ( shape == nil || shape == "NO-SHAPE")
1542
- volume = get_keyword_value("VOLUME")
1543
- volume = volume.to_f
1544
- return volume
1545
-
1546
- # if the shape is defined as a "BOX", the values for height, width, and
1547
- # depth are given, from which you can get the volume
1548
- elsif ( shape == "BOX" )
1549
- height = get_keyword_value("HEIGHT")
1550
- width = get_keyword_value("WIDTH")
1551
- depth = get_keyword_value("DEPTH")
1552
- height = height.to_f
1553
- width = width.to_f
1554
- depth = depth.to_f
1555
- return height * width * depth
1556
-
1557
- # if the shape is defined as a "POLYGON", the get_area is defined as the area
1558
- # of the polygon, and the height is given by the value of "HEIGHT"
1559
- elsif ( shape == "POLYGON")
1560
- height = getKeywordvalue("HEIGHT")
1561
- temp = get_keyword_value("POLYGON")
1562
- height = height.to_f
1563
- @polygon.utype = temp
1564
- return @polygon.get_area * height
1565
- else
1566
- raise "Error: The volume could not be evaluated. Please check inputs\n "
1567
-
1568
- end
1569
-
1570
- end
1571
-
1572
- def get_height()
1573
- if check_keyword?("HEIGHT") then return get_keyword_value("HEIGHT").to_f end
1574
- return get_floor.get_keyword_value("SPACE-HEIGHT").to_f
1575
- end
1576
-
1577
- def get_width
1578
- width = get_keyword_value("WIDTH")
1579
- width = width.to_f
1580
- return width
1581
- end
1582
-
1583
- def get_depth
1584
- depth = get_keyword_value("DEPTH")
1585
- depth = depth.to_f
1586
- return depth
1587
- end
1588
-
1589
- def get_shape
1590
- return "NO-SHAPE" unless check_keyword?("SHAPE")
1591
- return get_keyword_value("SHAPE")
1592
- end
1593
-
1594
- def get_floor
1595
- get_parent("FLOOR")
1596
- end
1597
-
1598
-
1599
- def get_origin()
1600
- space_origin = nil
1601
- if check_keyword?("LOCATION") and ( not self.check_keyword?("X") or not self.check_keyword?("Y") or not self.check_keyword?("Z") )
1602
- zero = OpenStudio::Point3d.new( 0.0, 0.0, 0.0 )
1603
- case get_keyword_value("LOCATION")
1604
- when /FLOOR-\s*V\s*(.*)/
1605
- index = $1.strip.to_i - 1
1606
- surf_vector = get_parent("FLOOR").polygon.point_list[index] - zero
1607
- when "FRONT"
1608
- surf_vector = get_parent("FLOOR").polygon.point_list[0] - zero
1609
- when "RIGHT"
1610
- surf_vector = get_parent("FLOOR").polygon.point_list[1] - zero
1611
- when "BACK"
1612
- surf_vector = get_parent("FLOOR").polygon.point_list[2] - zero
1613
- when "LEFT"
1614
- surf_vector = get_parent("FLOOR").polygon.point_list[3] - zero
1615
- end
1616
- space_xref = self.check_keyword?("X")? self.get_keyword_value("X").to_f : 0.0
1617
- space_yref = self.check_keyword?("Y")? self.get_keyword_value("Y").to_f : 0.0
1618
- space_zref = self.check_keyword?("Z")? self.get_keyword_value("Z").to_f : 0.0
1619
- space_origin = OpenStudio::Vector3d.new(space_xref,space_yref,space_zref)
1620
- space_origin = surf_vector + space_origin
1621
- else
1622
- space_xref = self.check_keyword?("X")? self.get_keyword_value("X").to_f : 0.0
1623
- space_yref = self.check_keyword?("Y")? self.get_keyword_value("Y").to_f : 0.0
1624
- space_zref = self.check_keyword?("Z")? self.get_keyword_value("Z").to_f : 0.0
1625
- space_origin = OpenStudio::Vector3d.new(space_xref,space_yref,space_zref)
1626
- end
1627
- return space_origin
1628
- end
1629
-
1630
- def get_azimuth()
1631
- angle = 0.0
1632
- #puts OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 0.0, 0.0), OpenStudio::Vector3d.new(1.0, 0.0, 0.0) ) )
1633
- if check_keyword?("LOCATION") and not check_keyword?("AZIMUTH")
1634
- case get_keyword_value("LOCATION")
1635
- when /FLOOR-\s*V\s*(.*)/
1636
- index = $1.strip.to_i - 1
1637
- point0 = self.get_parent("FLOOR").polygon.point_list[index]
1638
- point1 = self.get_parent("FLOOR").polygon.point_list[index + 1] ? get_parent("FLOOR").polygon.point_list[index + 1] : get_parent("FLOOR").polygon.point_list[0]
1639
- edge = point1-point0
1640
-
1641
-
1642
- sign = 1.0# OpenStudio::Vector3d.new(1.0, 0.0, 0.0).dot(( edge )) > 0 ? 1 :-1
1643
- angle = OpenStudio::radToDeg( sign * OpenStudio::getAngle(OpenStudio::Vector3d.new(1.0, 0.0, 0.0), ( point1 - point0 ) ) )
1644
-
1645
- #since get angle only get acute angles we need to get sign and completment for reflex angle
1646
- if edge.y > 0.0
1647
- angle = -1.0 * angle
1648
- end
1649
-
1650
- when "FRONT"
1651
- angle = OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("FLOOR").polygon.point_list[1] - get_parent("FLOOR").polygon.point_list[0] ) ) )
1652
- when "RIGHT"
1653
- angle = OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("FLOOR").polygon.point_list[2] - get_parent("FLOOR").polygon.point_list[1] ) ) )
1654
- when "BACK"
1655
- angle = OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("FLOOR").polygon.point_list[3] - get_parent("FLOOR").polygon.point_list[2] ) ) )
1656
- when "LEFT"
1657
- angle = OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("FLOOR").polygon.point_list[0] - get_parent("FLOOR").polygon.point_list[3] ) ) )
1658
- end
1659
- else
1660
- angle = self.check_keyword?("AZIMUTH")? self.get_keyword_value("AZIMUTH").to_f : 0.0
1661
- end
1662
- return angle
1663
- end
1664
-
1665
-
1666
- def get_transformation_matrix()
1667
- #This will transform the space vertices to normal space co-ordinates using Sketchup/OS convention
1668
- return OpenStudio::createTranslation(self.get_origin) * OpenStudio::Transformation::rotation(OpenStudio::Vector3d.new(0.0, 0.0, 1.0), OpenStudio::degToRad(360.0 - self.get_azimuth()))
1669
- end
1670
-
1671
- def get_rotation_matrix()
1672
- return OpenStudio::Transformation::rotation(OpenStudio::Vector3d.new(0.0, 0.0, 1.0), OpenStudio::degToRad(360.0 - self.get_azimuth()))
1673
- end
1674
-
1675
- def convert_to_openstudio(model,runner = nil)
1676
- if self.get_keyword_value("SHAPE") == "NO-SHAPE"
1677
- BTAP::runner_register("Info", "OpenStudio does not support NO-SHAPE SPACE definitions currently. Not importing the space #{self.name}.",runner)
1678
- else
1679
- os_space = OpenStudio::Model::Space.new(model)
1680
- os_space.setName(self.name)
1681
- #set floor
1682
- os_space.setBuildingStory(OpenStudio::Model::getBuildingStoryByName(model,self.get_parent("FLOOR").name).get)
1683
- BTAP::runner_register("Info", "\tSpace: " + self.name + " created",runner)
1684
- #puts "\t\t Azimuth:#{self.get_azimuth}"
1685
- #puts "\t\t Azimuth:#{self.get_origin}"
1686
- end
1687
- end
1688
-
1689
- end
1690
- class DOEFloor < DOESurface
1691
- attr_accessor :polygon
1692
- # a string object which defines the type of roof (e.g. attic)
1693
- attr_accessor :type
1694
- # The absorptance of the exterior surface of the floor
1695
- # (see rule #4.3.5.3.(6)
1696
- attr_accessor :absorptance
1697
- # thermal insulation of floors
1698
- attr_accessor :thermal_insulation
1699
-
1700
- def initialize
1701
- super()
1702
- end
1703
-
1704
- #This method returns the floor area
1705
- def get_area
1706
-
1707
- # get the keyword for the shape of the floor
1708
- case get_keyword_value("SHAPE")
1709
-
1710
- # if the keyword value is "BOX", the width and depth values are defined
1711
- when "BOX"
1712
- return get_keyword_value("WIDTH").to_f * get_keyword_value("DEPTH").to_f
1713
-
1714
- # if the keyword value is "POLYGON", the get_area is defined as the area of the
1715
- # given polygon
1716
- when "POLYGON"
1717
- return @polygon.get_area
1718
-
1719
- # if the keyword value of the floor is "No-SHAPE", the get_area is given as the
1720
- # get_area keyword value
1721
- when "NO-SHAPE"
1722
- return get_keyword_value("AREA").to_f
1723
- else
1724
- raise "Error: The area could not be evaluated. Please check inputs\n "
1725
- end
1726
- end
1727
-
1728
- # This method returns the volume of the floor space
1729
- def get_volume
1730
- return get_floor_height.to_f * get_area.to_f
1731
- end
1732
-
1733
- # gets the height of the floor
1734
- def get_height
1735
- return get_keyword_value("FLOOR-HEIGHT").to_f
1736
- end
1737
-
1738
- # gets the space height
1739
- def get_space_height
1740
- return get_keyword_value("SPACE-HEIGHT").to_f
1741
- end
1742
-
1743
- def get_origin()
1744
- space_xref = self.check_keyword?("X")? self.get_keyword_value("X").to_f : 0.0
1745
- space_yref = self.check_keyword?("Y")? self.get_keyword_value("Y").to_f : 0.0
1746
- space_zref = self.check_keyword?("Z")? self.get_keyword_value("Z").to_f : 0.0
1747
- return OpenStudio::Vector3d.new(space_xref,space_yref,space_zref)
1748
- end
1749
-
1750
- def get_azimuth()
1751
- return self.check_keyword?("AZIMUTH")? self.get_keyword_value("AZIMUTH").to_f : 0.0
1752
- end
1753
-
1754
- def get_transformation_matrix()
1755
- return OpenStudio::createTranslation(self.get_origin) * OpenStudio::Transformation::rotation(OpenStudio::Vector3d.new(0.0, 0.0, 1.0), OpenStudio::degToRad(360.0 - self.get_azimuth()))
1756
- end
1757
-
1758
- def get_rotation_matrix()
1759
- return OpenStudio::Transformation::rotation(OpenStudio::Vector3d.new(0.0, 0.0, 1.0), OpenStudio::degToRad(360.0 - self.get_azimuth()))
1760
- end
1761
-
1762
- def convert_to_openstudio(model,runner = nil)
1763
- floor = OpenStudio::Model::BuildingStory.new(model)
1764
- floor.setName(self.name)
1765
- BTAP::runner_register("Info", "\tBuildingStory: " + self.name + " created",runner)
1766
- end
1767
-
1768
- end
1769
- #This class makes it easier to deal with DOE Polygons.
1770
- class DOEPolygon < DOECommand
1771
-
1772
- attr_accessor :point_list
1773
-
1774
- #The constructor.
1775
- def initialize
1776
- super()
1777
- @point_list = Array.new()
1778
- #Convert Keywork Pairs to points.
1779
-
1780
- end
1781
-
1782
- def create_point_list()
1783
-
1784
- #Convert Keywork Pairs to points.
1785
- @point_list.clear
1786
- @keywordPairs.each do |array|
1787
-
1788
- array[1].match(/\(\s*(\-?\d*\.?\d*)\s*\,\s*(\-?\d*\.?\d*)\s*\)/)
1789
- #puts array[1]
1790
-
1791
- point = OpenStudio::Point3d.new($1.to_f,$2.to_f,0.0)
1792
- @point_list.push(point)
1793
- end
1794
- # @point_list.each do |p|
1795
- # puts p.x.to_s + " " + p.y.to_s + " " + p.z.to_s + " "
1796
- # end
1797
- end
1798
-
1799
- # This method returns the area of the polygon.
1800
- def get_area
1801
- openstudio::getArea(@points_list)
1802
- end
1803
-
1804
-
1805
- # This method must determine the length of the given point to the next point
1806
- # in the polygon list. If the point is the last point, then it will be the
1807
- # distance from the last point to the first.
1808
- # point_name is the string named keyword in the keyword pair list.
1809
- # Example:
1810
- # "DOEPolygon 2" = POLYGON
1811
- # V1 = ( 0, 0 )
1812
- # V2 = ( 0, 1 )
1813
- # V3 = ( 2, 1 )
1814
- # V4 = ( 2 ,0 )
1815
- # get_length(3) should return "2"
1816
- # get_length(2) should return "1"
1817
-
1818
- def get_length(point_index)
1819
- if @points_list.size < pointindex + 2
1820
- return OpenStudio::getDistance(@point_list[0],@point_list.last)
1821
- else
1822
- return OpenStudio::getDistance(@point_list[point_index],@point_list[point_index + 1] )
1823
- end
1824
- end
1825
-
1826
-
1827
- def get_azimuth(point_index)
1828
- if @points_list.size < pointindex + 2
1829
- return OpenStudio::radToDeg(OpenStudio::getAngle(@point_list.last - @point_list[0] , openstudio::Vector3d( 1.0, 0.0, 0.0)))
1830
- else
1831
- return OpenStudio::radToDeg(OpenStudio::getAngle(@point_list[point_index + 1] - @point_list[point_index] , openstudio::Vector3d( 1.0, 0.0, 0.0)))
1832
- end
1833
- end
1834
-
1835
- end
1836
- class DOELayer < DOECommand
1837
- # type of material (see rule #4.3.5.2.(3))
1838
- attr_accessor :material
1839
- # the thickness of the material (see rule #4.3.5.2.(3))
1840
- attr_accessor :thickness
1841
- def initialize
1842
- super()
1843
- end
1844
- end
1845
- class DOEMaterial < DOECommand
1846
- # characteristics of the materials
1847
- attr_accessor :density
1848
- attr_accessor :specific_heat
1849
- attr_accessor :thermal_conductivity
1850
- def initialize
1851
- super()
1852
- end
1853
- end
1854
- class DOEConstruction < DOECommand
1855
-
1856
- def initialize
1857
- super()
1858
- end
1859
-
1860
- def get_materials()
1861
- bdllib = DOE2::DOEBDLlib.instance
1862
- materials = Array.new
1863
-
1864
- case self.get_keyword_value("TYPE")
1865
- when "LAYERS"
1866
- # finds the command associated with the layers keyword
1867
- layers_command = building.find_command_with_utype( self.get_keyword_value("LAYERS") )
1868
-
1869
- #if Layres command cannot be found in the inp file... find it in the bdl database.
1870
- layers_command = bdllib.find_layer(self.get_keyword_value("LAYERS")) unless layers_command.length == 1
1871
-
1872
- # if there ends up to be more than one command with the layers keyword
1873
- # raise an exception
1874
- raise "Layers was defined more than once " + self.get_keyword_value("LAYERS").to_s if layers_command.length > 1
1875
-
1876
- # get all the materials, separate it by the quotation marks and push it
1877
- # onto the materials array
1878
- layers_command[0].get_keyword_value("MATERIAL").scan(/(\".*?\")/).each do |material|
1879
- material_command = ""
1880
-
1881
- #Try to find material in doe model.
1882
- material_command_array = building.find_command_with_utype(material.to_s.strip)
1883
-
1884
- # if there ends up to be more than one, raise an exception
1885
- raise "Material was defined more than once #{material}" if material_command_array.length > 1
1886
-
1887
- # if the material cannot be found within the model, find it within the doe2 database
1888
- material_command = bdllib.find_material(material) if material_command_array.length < 1
1889
-
1890
- #If material was found then set it.
1891
- material_command = material_command_array[0] if material_command_array.length == 1
1892
-
1893
- materials.push(material_command)
1894
- end
1895
- return materials
1896
- when "U-VALUE"
1897
- return nil
1898
- end
1899
- end
1900
-
1901
- # This method finds the u-value of the given construction
1902
- # Output => total conductivity as a float
1903
- def get_u_value()
1904
- total_conductivity = 0.0
1905
- case self.get_keyword_value("TYPE")
1906
- when "LAYERS"
1907
- self.get_materials().each do |material_command|
1908
- case material_command.get_keyword_value("TYPE")
1909
- when "RESISTANCE"
1910
- conductivity = 1 / material_command.get_keyword_value("RESISTANCE").to_f
1911
- when "PROPERTIES"
1912
- conductivity = material_command.get_keyword_value("CONDUCTIVITY").to_f
1913
- else
1914
- raise "Error in material properties"
1915
- end
1916
- total_conductivity = total_conductivity + conductivity
1917
- end
1918
- return total_conductivity
1919
- when "U-VALUE"
1920
- return self.get_keyword_value("U-VALUE").to_f
1921
- end
1922
- end
1923
-
1924
-
1925
- end
1926
- class DOECommandFactory
1927
- def initialize
1928
-
1929
- end
1930
-
1931
- def DOECommandFactory.command_factory(command_string, building)
1932
-
1933
- command = ""
1934
- command_name = ""
1935
- if (command_string != "")
1936
- #Get command and u-value
1937
- if ( command_string.match(/(^\s*(\".*?\")\s*\=\s*(\S+)\s*)/) )
1938
- command_name=$3.strip
1939
- else
1940
- # if no u-value, get just the command.
1941
- command_string.match(/(^\s*(\S*)\s)/ )
1942
- @command_name=$2.strip
1943
-
1944
- end
1945
- end
1946
- case command_name
1947
- when "ZONE" then
1948
- command = DOEZone.new()
1949
- when "FLOOR" then
1950
- command = DOEFloor.new()
1951
- when "SPACE" then
1952
- command = DOESpace.new()
1953
- when "EXTERIOR-WALL" then
1954
- command = DOEExteriorWall.new()
1955
- when "INTERIOR-WALL" then
1956
- command = DOESurface.new()
1957
- when "UNDERGROUND-WALL" then
1958
- command = DOESurface.new()
1959
- when "ROOF" then
1960
- command = DOERoof.new()
1961
- when "WINDOW" then
1962
- command = DOESubSurface.new()
1963
- when "DOOR" then
1964
- command = DOESubSurface.new()
1965
- when "POLYGON" then
1966
- command = DOEPolygon.new()
1967
- when "LAYER" then
1968
- command = DOELayer.new()
1969
- when "MATERIAL" then
1970
- command = DOEMaterial.new()
1971
- when "CONSTRUCTION" then
1972
- command = DOEConstruction.new()
1973
- else
1974
- command = DOECommand.new()
1975
- end
1976
-
1977
- command.get_command_from_string(command_string)
1978
- command.building = building
1979
- return command
1980
- end
1981
- end
1982
-
1983
- # This is the main interface dealing with DOE inp files. You can load, save
1984
- # manipulate doe files with this interface at a command level.
1985
- class DOEBuilding
1986
-
1987
- #An array to contain all the DOE
1988
- attr_accessor :commands
1989
- #An array to contain the current parent when reading in the input files.
1990
- attr_accessor :parents
1991
-
1992
-
1993
- # This method makes a deep copy of the building object.
1994
- def clone
1995
- return Marshal::load(Marshal.dump(self))
1996
- end
1997
-
1998
- # The Constructor.
1999
- def initialize
2000
-
2001
- @commands=[]
2002
- @parents=[]
2003
- @commandList = Array.new()
2004
-
2005
- end
2006
-
2007
- # This method will find all Commands given the command name string.
2008
- # Example
2009
- # def find_all_Command("ZONE") will return an array of all the ZONE commands
2010
- # used in the building.
2011
- def find_all_commands (sCOMMAND)
2012
- array = Array.new()
2013
- @commands.each do |command|
2014
- if (command.commandName == sCOMMAND)
2015
- array.push(command)
2016
- end
2017
- end
2018
- return array
2019
- end
2020
-
2021
- # This method will find all Commands given the command name string.
2022
- # Example
2023
- # def find_all_Command("Default Construction") will return an array of all
2024
- # the commands with "Default Construction" as the u-type used in the building.
2025
- def find_command_with_utype (utype)
2026
- array = Array.new()
2027
- @commands.each do |command|
2028
- if (command.utype == utype)
2029
- array.push(command)
2030
- end
2031
- end
2032
- return array
2033
- end
2034
-
2035
-
2036
- # Same as find_all_commands except you can use regular expressions.
2037
- def find_all_regex(sCOMMAND)
2038
- array = Array.new()
2039
- search =/#{sCOMMAND}/
2040
- @commands.each do |command|
2041
- if (command.commandName.match(search) )
2042
- array.push(command)
2043
- end
2044
-
2045
- end
2046
- return array
2047
- end
2048
-
2049
- # Find a matching keyword value pair in from an array of commands.
2050
- # Example:
2051
- # find_keyword_value(building.commands, "TYPE", "CONDITIONED") will return
2052
- # all the commands that have the
2053
- # TYPE = CONDITIONED"
2054
- # Keyword pair.
2055
- def search_by_keyword_value( keyword, value)
2056
- returnarray = Array.new()
2057
- @commands.each do |command|
2058
- if ( command.keywordPairs[keyword] == value )
2059
- returnarray.push(command)
2060
- end
2061
- end
2062
- return returnarray
2063
- end
2064
-
2065
-
2066
- # Will read an input file into memory and store all the commands into the
2067
- # commands array.
2068
- # param filename
2069
- # param runner
2070
- def load_inp(filename,runner = nil)
2071
- BTAP::runner_register("Info", "loading file:" + filename, runner)
2072
- #Open the file.
2073
- #puts filename
2074
- iter = 0
2075
-
2076
-
2077
- File.exist?(filename)
2078
- f = File.open(filename, "r")
2079
-
2080
-
2081
-
2082
-
2083
- #Read the file into an array, line by line.
2084
- lines = f.readlines
2085
- #Set up the temp string.
2086
- command_string =""
2087
-
2088
- lines.each do|line|
2089
- iter = iter.next
2090
- #line.forced_encoding("US-ASCII")
2091
- #Ignore comments (To do!...strip from file as well as in-line comments.
2092
- if (!line.match(/\$.*/) )
2093
-
2094
- if (myarray = line.match(/(.*?)\.\./) )
2095
- #Add the last part of the command to the newline...may be blank."
2096
- command_string = command_string + myarray[1]
2097
- #Determine correct command class to create, then populates it."
2098
- command = DOECommandFactory.command_factory(command_string, self)
2099
- #Push the command into the command array."
2100
- @commands.push(command)
2101
- command_string = ""
2102
- else
2103
- myarray = line.match(/(.*)/)
2104
- command_string = command_string + myarray[1]
2105
- end
2106
- end
2107
- end
2108
-
2109
- organize_data()
2110
- BTAP::runner_register("Info","INP model contains:", runner)
2111
- #report number of things read in.
2112
- ["SPACE","ZONE","EXTERIOR-WALL","ROOF","INTERIOR-WALL","UNDERGROUND-WALL","WINDOW","DOOR","MATERIAL","CONSTRUCTION"].each do |item|
2113
- items = self.find_all_commands(item)
2114
- message = "\t#{item} = #{items.size}"
2115
- BTAP::runner_register("Info",message, runner)
2116
- end
2117
- BTAP::runner_register("Info", "\tFinished Loading File:" + filename,runner)
2118
- end
2119
-
2120
-
2121
-
2122
- # This will right a clean output file, meaning no comments. Good for doing
2123
- # diffs
2124
- def save_inp(string)
2125
- array = @commands
2126
- w = File.open(string, 'w')
2127
- array.each { |command| w.print command.output }
2128
- w.close
2129
- end
2130
-
2131
-
2132
-
2133
-
2134
-
2135
- #This routine organizes the hierarchy of the space <-> zones and the polygon
2136
- # associations that are not formally identified by the sequential relationship
2137
- # like the floor, walls, windows. It would seem that zones and spaces are 1 to
2138
- # one relationships. So each zone will have a reference to its space and vice versa.
2139
- # If there is a polygon command in the space or floor definition, a reference to the
2140
- # polygon class will be set.
2141
- def organize_data()
2142
- # set_envelope_hierarchy
2143
- # This method determines the current parents of the current command.
2144
- def determine_current_parents(new_command)
2145
- if @last_command.nil?
2146
- @last_command = new_command
2147
- end
2148
- #Check to see if scope (HVAC versus Envelope) has changed or the parent depth is undefined "0"
2149
- if (!@parents.empty? and (new_command.doe_scope != @parents.last.doe_scope or new_command.depth == 0 ))
2150
- @parents.clear
2151
- end
2152
- #no change in parent.
2153
- if ( (new_command.depth == @last_command.depth))
2154
- #no change
2155
- @last_command = new_command
2156
- #puts "#{new_command.commandName}"
2157
- end
2158
- #Parent depth added
2159
- if ( new_command.depth > @last_command.depth)
2160
- @parents.push(@last_command)
2161
- #puts "Added parent#{@last_command.commandName}"
2162
- @last_command = new_command
2163
- end
2164
- #parent depth removed.
2165
- if ( new_command.depth < @last_command.depth)
2166
- parent = @parents.pop
2167
- #puts "Removed parent #{parent}"
2168
- @last_command = new_command
2169
- end
2170
- array = Array.new(@parents)
2171
- return array
2172
- end
2173
-
2174
-
2175
- @commands.each do |command|
2176
- if command.doe_scope() == "envelope"
2177
- #Sets parents of command.
2178
- parents = determine_current_parents(command)
2179
- if (!parents.empty?)
2180
- command.parents = parents
2181
- end
2182
- #inserts current command into the parent's children.
2183
- if (!command.parents.empty?)
2184
- command.parents.last.children.push(command)
2185
- end
2186
- end
2187
- end
2188
- # Associating the polygons with the FLoor and spaces.
2189
- polygons = find_all_commands("POLYGON")
2190
- spaces = find_all_commands("SPACE")
2191
- floors = find_all_commands("FLOOR")
2192
- zones = find_all_commands("ZONE")
2193
- ext_walls = find_all_commands("EXTERIOR-WALL")
2194
- roof = find_all_commands("ROOF")
2195
- door = find_all_commands("DOOR")
2196
- int_walls = find_all_commands("INTERIOR-WALL")
2197
- underground_walls = find_all_commands("UNDERGROUND-WALL")
2198
- underground_floors = find_all_commands("UNDERGROUND-FLOOR")
2199
- constructions =find_all_commands("CONSTRUCTION")
2200
- surface_lists = [ ext_walls, roof, door, int_walls, underground_walls, underground_floors]
2201
-
2202
-
2203
- #Organize surface data.
2204
- surface_lists.each do |surfaces|
2205
- surfaces.each do |surface|
2206
- #Assign constructions to surface objects
2207
- constructions.each do |construction|
2208
- if ( construction.utype == surface.get_keyword_value("CONSTRUCTION") )
2209
- surface.construction = construction
2210
- end
2211
- end
2212
- #Find Polygons associated with surface.
2213
- polygons.each do |polygon|
2214
- if ( surface.check_keyword?("POLYGON") and polygon.utype == surface.get_keyword_value("POLYGON") )
2215
- surface.polygon = polygon
2216
- end
2217
- end
2218
- end
2219
- end
2220
-
2221
-
2222
-
2223
- #Organize polygon data for space and floors.
2224
- polygons.each do |polygon|
2225
- #set up point list in polygon objects
2226
- polygon.create_point_list()
2227
- #Find Polygons associated with floor and and reference to floor.
2228
- floors.each do |floor|
2229
- if ( polygon.utype == floor.get_keyword_value("POLYGON") )
2230
- floor.polygon = polygon
2231
- end
2232
- end
2233
- #Find Polygons for space and add reference to the space.
2234
- spaces.sort.each do |space|
2235
- if space.check_keyword?("POLYGON")
2236
- if ( polygon.utype == space.get_keyword_value("POLYGON") )
2237
- space.polygon = polygon
2238
- end
2239
- end
2240
- end
2241
- end
2242
-
2243
-
2244
-
2245
- # Find spaces that belong to the zone.
2246
- zones.each do |zone|
2247
- spaces.sort.each do |space|
2248
- if ( space.utype == zone.get_keyword_value("SPACE") )
2249
- space.zone = zone
2250
- zone.space = space
2251
- end
2252
- end
2253
- end
2254
- end
2255
-
2256
-
2257
-
2258
- def get_building_transformation_matrix()
2259
- build_params = self.find_all_commands("BUILD-PARAMETERS")[0]
2260
- building_xref = build_params.check_keyword?("X-REF")? build_params.get_keyword?("X-REF") : 0.0
2261
- building_yref = build_params.check_keyword?("Y-REF")? build_params.get_keyword?("Y-REF") : 0.0
2262
- building_origin = OpenStudio::Vector3d.new(building_xref,building_yref,0.0)
2263
- building_azimuth = build_params.check_keyword?("AZIMUTH")? build_params.get_keyword?("AZIMUTH") : 0.0
2264
- return OpenStudio::Transformation::rotation(OpenStudio::Vector3d(0.0, 0.0, 1.0), openstudio::degToRad(building_azimuth)) * OpenStudio::Transformation::translation(building_origin)
2265
- end
2266
-
2267
-
2268
-
2269
-
2270
- #this method will convert a DOE inp file to the OSM file.. This will return
2271
- # and openstudio model object.
2272
- def create_openstudio_model_new(runner = nil)
2273
- beginning_time = Time.now
2274
-
2275
- end_time = Time.now
2276
- BTAP::runner_register("Info", "Time elapsed #{(end_time - beginning_time)*1000} milliseconds",runner)
2277
- model = OpenStudio::Model::Model.new()
2278
- #add All Materials
2279
- # find_all_commands( "Materials" ).each do |doe_material|
2280
- # end
2281
- #
2282
- # find_all_commands( "Constructions" ).each do |doe_cons|
2283
- # end
2284
-
2285
- #this block will create OS story objects in the OS model.
2286
- BTAP::runner_register("Info", "Exporting DOE FLOORS to OS",runner)
2287
- find_all_commands("FLOOR").each do |doe_floor|
2288
- doe_floor.convert_to_openstudio(model)
2289
- end
2290
- BTAP::runner_register("Info", OpenStudio::Model::getBuildingStorys(model).size.to_s + " floors created",runner)
2291
-
2292
- #this block will create OS space objects in the OS model.
2293
- BTAP::runner_register("Info", "Exporting DOE SPACES to OS",runner)
2294
- find_all_commands("SPACE").each do |doe_space|
2295
- doe_space.convert_to_openstudio(model)
2296
- end
2297
- BTAP::runner_register("Info", OpenStudio::Model::getSpaces(model).size.to_s + " spaces created",runner)
2298
-
2299
- #this block will create OS space objects in the OS model.
2300
- BTAP::runner_register("Info", "Exporting DOE ZONES to OS",runner)
2301
- find_all_commands("ZONE").each do |doe_zone|
2302
- doe_zone.convert_to_openstudio(model)
2303
- end
2304
- BTAP::runner_register("Info", OpenStudio::Model::getThermalZones(model).size.to_s + " zones created",runner)
2305
-
2306
- #this block will create OS surface objects in the OS model.
2307
- BTAP::runner_register("Info", "Exporting DOE Surfaces to OS",runner)
2308
- all_surfaces = Array.new()
2309
- @commands.each do |command|
2310
- case command.commandName
2311
- when "EXTERIOR-WALL","INTERIOR-WALL","UNDERGROUND-WALL","ROOF"
2312
- all_surfaces.push(command)
2313
- end
2314
- end
2315
- all_surfaces.each do |doe_surface|
2316
- doe_surface.convert_to_openstudio(model)
2317
- end
2318
- BTAP::runner_register("Info", OpenStudio::Model::getSurfaces(model).size.to_s + " surfaces created",runner)
2319
- BTAP::runner_register("Info", OpenStudio::Model::getSubSurfaces(model).size.to_s + " sub_surfaces created",runner)
2320
- BTAP::runner_register("Info", "Setting Boundary Conditions for surfaces",runner)
2321
- BTAP::Geometry::match_surfaces(model)
2322
-
2323
- x_scale = y_scale = z_scale = 0.3048
2324
- BTAP::runner_register("Info", "scaling model from feet to meters",runner)
2325
- model.getPlanarSurfaces.sort.each do |surface|
2326
- new_vertices = OpenStudio::Point3dVector.new
2327
- surface.vertices.each do |vertex|
2328
- new_vertices << OpenStudio::Point3d.new(vertex.x * x_scale, vertex.y * y_scale, vertex.z * z_scale)
2329
- end
2330
- surface.setVertices(new_vertices)
2331
- end
2332
-
2333
- model.getPlanarSurfaceGroups.sort.each do |surface_group|
2334
- transformation = surface_group.transformation
2335
- translation = transformation.translation
2336
- euler_angles = transformation.eulerAngles
2337
- new_translation = OpenStudio::Vector3d.new(translation.x * x_scale, translation.y * y_scale, translation.z * z_scale)
2338
- #TODO these might be in the wrong order
2339
- new_transformation = OpenStudio::createRotation(euler_angles) * OpenStudio::createTranslation(new_translation)
2340
- surface_group.setTransformation(new_transformation)
2341
- end
2342
- BTAP::runner_register("Info", "DOE2.2 -> OS Geometry Conversion Complete",runner)
2343
- BTAP::runner_register("Info", "Summary of Conversion",runner)
2344
- BTAP::runner_register("Info", OpenStudio::Model::getBuildingStorys(model).size.to_s + " floors created",runner)
2345
- BTAP::runner_register("Info", OpenStudio::Model::getSpaces(model).size.to_s + " spaces created",runner)
2346
- BTAP::runner_register("Info", OpenStudio::Model::getThermalZones(model).size.to_s + " thermal zones created",runner)
2347
- BTAP::runner_register("Info", OpenStudio::Model::getSurfaces(model).size.to_s + " surfaces created",runner)
2348
- BTAP::runner_register("Info", OpenStudio::Model::getSubSurfaces(model).size.to_s + " sub_surfaces created",runner)
2349
- BTAP::runner_register("Info", "No Contruction were converted.",runner)
2350
- BTAP::runner_register("Info", "No Materials were converted",runner)
2351
- BTAP::runner_register("Info", "No HVAC components were converted",runner)
2352
- BTAP::runner_register("Info", "No Environment or Simulation setting were converted.",runner)
2353
-
2354
- end_time = Time.now
2355
- BTAP::runner_register("Info", "Time elapsed #{(end_time - beginning_time)} seconds",runner)
2356
- return model
2357
- end
2358
-
2359
-
2360
-
2361
-
2362
-
2363
- def get_materials()
2364
- BTAP::runner_register("Info", "Spaces",runner)
2365
- find_all_commands("SPACE").each do |space|
2366
- BTAP::runner_register("Info", space.get_azimuth(),runner)
2367
- end
2368
- BTAP::runner_register("Info", "Materials",runner)
2369
- find_all_commands("MATERIAL").each do |materials|
2370
- BTAP::runner_register("Info", materials.get_name(),runner)
2371
- end
2372
- BTAP::runner_register("Info", "Layers",runner)
2373
- find_all_commands("LAYERS").each do |materials|
2374
- BTAP::runner_register("Info", materials.get_name(),runner)
2375
- end
2376
- BTAP::runner_register("Info", "Constructions",runner)
2377
- find_all_commands("CONSTRUCTION").each do |materials|
2378
- BTAP::runner_register("Info", materials.get_name(),runner)
2379
- end
2380
-
2381
- end
2382
-
2383
-
2384
- end
2385
- # This class will manage all the layer information of the Reference components.
2386
- class LayerManager
2387
- include Singleton
2388
- class Layer
2389
-
2390
- attr_accessor :name
2391
- attr_accessor :thickness
2392
- attr_accessor :conductivity
2393
- attr_accessor :density
2394
- attr_accessor :specific_heat
2395
- attr_accessor :air_space
2396
- attr_accessor :resistance
2397
- def initialize
2398
- @air_space = false
2399
- end
2400
-
2401
- def set( thickness, conductivity, density, specific_heat)
2402
- @thickness, @conductivity, @density, @specific_heat = thickness, conductivity, density, specific_heat
2403
- @airspace = false
2404
- end
2405
-
2406
- def set_air_space(thickness, resistance)
2407
- @thickness, @resistance = thickness, resistance
2408
- @air_space = true
2409
- end
2410
-
2411
- def output
2412
- string = "Airspace = #{@air_space}\nThickness = #{@thickness}\nConductivity = #{@conductivity}\nResistance = #{@resistance}\nDensity = #{@density}\nSpecificHeat = #{@specific_heat}\n"
2413
- end
2414
- end
2415
- # Array of all the layers
2416
- attr_accessor :layers
2417
- def initialize
2418
- @layers = Array.new()
2419
- end
2420
-
2421
- #Add a layer. If the layer already exists. It will return the exi
2422
- def add_layer(new_layer)
2423
- #first determine if the layer already exists.
2424
- @layers.each do |current_layer|
2425
- if new_layer == current_layer
2426
- return current_layer
2427
- end
2428
- end
2429
- @layers.push(new_layer)
2430
- return @layers.last()
2431
- end
2432
-
2433
- private
2434
-
2435
- def clear()
2436
- @layers.clear()
2437
- end
2438
- end
2439
- #This class manages all of the constructions that are used in the simulation. It
2440
- #should remove any constructions that are doubly defined in the project.
2441
- class ConstructionManager
2442
- # An array containing all the constructions.
2443
- attr_accessor :constructions
2444
-
2445
- # The layer manager all the constructions.
2446
- attr_accessor :layer_manager
2447
- class Construction
2448
-
2449
- #The unique name for the construction.
2450
- attr_accessor :name
2451
- #The array which contains the material layers of the construction.
2452
- attr_accessor :layers
2453
-
2454
- def initialize
2455
- #Set up the array for the layers.
2456
- @layers = Array.new()
2457
- end
2458
-
2459
- #Adds a layer object to the construction.
2460
- # Must pass a Layer object as an arg.
2461
- def add_layer_object( object )
2462
- layers.push( object )
2463
- end
2464
-
2465
- #Adds a layer based on the physical properties list.
2466
- #All units are based on the simulators input.
2467
- def add_layer(thickness, conductivity, density, specific_heat)
2468
- layer = Layer.new()
2469
- # Make sure all the values are > 0.
2470
- layer.set(thickness, conductivity, density, specific_heat)
2471
- @layers.push(layer)
2472
- end
2473
-
2474
- # Adds an airspace to the construction based on the thickness and Resistances.
2475
- #All units are based on the simulators input.
2476
- def add_air_space(thickness, resistance )
2477
- layer = Layer.new()
2478
- layer.set_air_space(thickness, resistance)
2479
- @layers.push(layer)
2480
- end
2481
-
2482
- def output()
2483
- soutput = ""
2484
- @layers.each do|layer|
2485
- soutput = soutput + layer.output() + "\n"
2486
- end
2487
- soutput
2488
- end
2489
- end
2490
-
2491
-
2492
- def initialize
2493
- @constructions = Array.new()
2494
- @layer_manager = LayerManager.instance()
2495
- end
2496
-
2497
-
2498
- #Adds a new construction to the construction array.
2499
- #Arg must be a construction object.
2500
- def add_construction(new_construction)
2501
- #first determine if the layer already exists.
2502
- @constructions.each do |current_construction|
2503
- if new_construction == current_construction
2504
- return current_construction
2505
- end
2506
- end
2507
- new_construction.layers.each do |new_layer|
2508
- #If the new layer already exists...use the old one instead.
2509
- # it is the layerManager's job to decide this.
2510
- new_layer = @layer_manager.add_layer(new_layer)
2511
- end
2512
- @constructions.push(new_construction)
2513
- return @constructions.last()
2514
- end
2515
-
2516
- def clear()
2517
- @constructions.clear()
2518
- @layer_manager.clear()
2519
- end
2520
-
2521
- end
2522
- end
2523
- end
2524
-
1
+ # # *********************************************************************
2
+ # # * Copyright (c) 2008-2015, Natural Resources Canada
3
+ # # * All rights reserved.
4
+ # # *
5
+ # # * This library is free software; you can redistribute it and/or
6
+ # # * modify it under the terms of the GNU Lesser General Public
7
+ # # * License as published by the Free Software Foundation; either
8
+ # # * version 2.1 of the License, or (at your option) any later version.
9
+ # # *
10
+ # # * This library is distributed in the hope that it will be useful,
11
+ # # * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
+ # # * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
+ # # * Lesser General Public License for more details.
14
+ # # *
15
+ # # * You should have received a copy of the GNU Lesser General Public
16
+ # # * License along with this library; if not, write to the Free Software
17
+ # # * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
+ # # **********************************************************************/
19
+ #
20
+ #
21
+ #
22
+ # require "singleton"
23
+ #
24
+ #
25
+ # module BTAP
26
+ # module EQuest
27
+ # # Author:: Phylroy Lopez (mailto:plopez@nrcan.gc.ca)
28
+ # # Copyright:: Copyright (c) NRCan
29
+ # # License:: GNU Public Licence
30
+ # #This class contains encapsulates the generic interface for the DOE2.x command
31
+ # #set. It stores the u type, commands, and keyword pairs for each command. It also
32
+ # #stores the parent and child command relationships w.r.t. the building envelope
33
+ # #and the hvac systems. I have attempted to make the underlying storage of data
34
+ # #private so, if required, we could move to a database solution in the future
35
+ # #if required for web development..
36
+ #
37
+ # class DOECommand
38
+ #
39
+ # # Contains the user specified name
40
+ # attr_accessor :utype
41
+ # #Contains the u-value
42
+ # attr_accessor :uvalue
43
+ # # Contains the DOE-2 command name.
44
+ # attr_accessor :commandName
45
+ # # Contains the Keyword Pairs.
46
+ # attr_accessor :keywordPairs
47
+ # # Lists all ancestors in increasing order.
48
+ # attr_accessor :parents
49
+ # # An Array of all the children of this command.
50
+ # attr_accessor :children
51
+ # # The command type.
52
+ # attr_accessor :commandType
53
+ # # Flag to see if this component is exempt.
54
+ # attr_accessor :exempt
55
+ # # Comments. To be added to the command.
56
+ # attr_accessor :comments
57
+ # # A list of all the non_utype_commands.
58
+ # attr_accessor :non_utype_commands
59
+ # # A list of all the one line commands (no keyword pairs)
60
+ # attr_accessor :one_line_commands
61
+ # # Pointer to the building obj.
62
+ # attr_accessor :building
63
+ #
64
+ #
65
+ #
66
+ #
67
+ # def remove()
68
+ # #unlink children
69
+ # self.children.each {|item| item.remove}
70
+ # #unlink from parent.
71
+ # self.get_parents[0].children.delete(self)
72
+ # #remove from command array.
73
+ # @building.commands.delete(self)
74
+ # return self
75
+ # end
76
+ #
77
+ # def set_parent(parent)
78
+ # @parents.clear
79
+ # parent.get_parents().each {|parent| @parents << parent}
80
+ # @parents << parent
81
+ # end
82
+ #
83
+ # #This method will return the value of the keyword pair if available.
84
+ # #Example:
85
+ # #If you object has this data in it...
86
+ # #
87
+ # #"EL1 West Perim Spc (G.W4)" = SPACE
88
+ # #SHAPE = POLYGON
89
+ # #ZONE-TYPE = CONDITIONED
90
+ # #PEOPLE-SCHEDULE = "EL1 Bldg Occup Sch"
91
+ # #LIGHTING-SCHEDUL = ( "EL1 Bldg InsLt Sch" )
92
+ # #EQUIP-SCHEDULE = ( "EL1 Bldg Misc Sch" )
93
+ # #
94
+ # #
95
+ # #then calling
96
+ # #
97
+ # #get_keyword_value("ZONE-TYPE")
98
+ # #
99
+ # #will return the string
100
+ # #
101
+ # #"CONDITIONED".
102
+ # #
103
+ # #if the keyword does not exist, it will return a nil object.
104
+ # # Returns the value associated with the keyword.
105
+ # def get_keyword_value(string)
106
+ # return_string = String.new()
107
+ # found = false
108
+ # @keywordPairs.each do |pair|
109
+ # if pair[0] == string
110
+ # found = true
111
+ # return_string = pair[1]
112
+ # end
113
+ # end
114
+ # if found == false
115
+ # raise "Error: In the command #{@utype}:#{@command_name} Attempted to get a Keyword pair #{string} present in the command\n Is this keyword missing? \n#{output}"
116
+ # end
117
+ # return return_string
118
+ # end
119
+ #
120
+ # # Sets the keyword value.
121
+ # def set_keyword_value(keyword, value)
122
+ # found = false
123
+ # unless @keywordPairs.empty?
124
+ # @keywordPairs.each do |pair|
125
+ # if pair[0] == keyword
126
+ # pair[1] = value
127
+ # found = true
128
+ # end
129
+ # end
130
+ # if (found == false)
131
+ # @keywordPairs.push([keyword,value])
132
+ # end
133
+ # else
134
+ # #First in the array...
135
+ # add_keyword_pair(keyword,value)
136
+ # end
137
+ # end
138
+ #
139
+ # # Removes the keyword pair.
140
+ # def remove_keyword_pair(string)
141
+ # return_string = String.new()
142
+ # @keywordPairs.each do |pair|
143
+ # if pair[0] == string
144
+ # @keywordPairs.delete(pair)
145
+ # end
146
+ # end
147
+ # return return_string
148
+ # end
149
+ #
150
+ # def initialize()
151
+ # @utype = String.new()
152
+ # @commandName= String.new()
153
+ # @keywordPairs=Array.new()
154
+ # @parents = Array.new()
155
+ # @children = Array.new()
156
+ # @commandType = String.new()
157
+ # @exempt = false
158
+ # #HVAC Hierarchry
159
+ # @comments =Array.new()
160
+ # @hvacLevel = Array.new()
161
+ # @hvacLevel[0] =["SYSTEM"]
162
+ # @hvacLevel[1] =["ZONE"]
163
+ # #Envelope Hierachy
164
+ # @envelopeLevel = Array.new()
165
+ # @envelopeLevel[0] = ["FLOOR"]
166
+ # @envelopeLevel[1] = ["SPACE"]
167
+ #
168
+ # @envelopeLevel[2] = [
169
+ # "EXTERIOR-WALL",
170
+ # "INTERIOR-WALL",
171
+ # "UNDERGROUND-WALL",
172
+ # "ROOF"
173
+ # ]
174
+ #
175
+ # @envelopeLevel[3] = [
176
+ # "WINDOW",
177
+ # "DOOR"]
178
+ #
179
+ # @non_utype_commands = Array.new()
180
+ # @non_utype_commands = [
181
+ # "TITLE",
182
+ # "SITE-PARAMETERS",
183
+ # "BUILD-PARAMETER",
184
+ # "LOADS_REPORT",
185
+ # "SYSTEMS-REPORT",
186
+ # "MASTERS-METERS",
187
+ # "ECONOMICS-REPORT",
188
+ # "PLANT-REPORT",
189
+ # "LOADS-REPORT",
190
+ # "COMPLIANCE"
191
+ # ]
192
+ # @one_line_commands = Array.new()
193
+ # @one_line_commands = ["INPUT","RUN-PERIOD","DIAGNOSTIC","ABORT", "END", "COMPUTE", "STOP", "PROJECT-DATA"]
194
+ # end
195
+ #
196
+ # # Determines the DOE scope, either envelope or hvac (Window, Wall, Space Floor) or (System->Plant)
197
+ # # Hierarchy) this is required to determine parent/child relationships in the building.
198
+ # def doe_scope
199
+ # scope = "none"
200
+ # @envelopeLevel.each_index do |index|
201
+ # @envelopeLevel[index].each do |name|
202
+ # if (@commandName == name )
203
+ # scope = "envelope"
204
+ # end
205
+ # end
206
+ # end
207
+ #
208
+ # @hvacLevel.each_index do |index|
209
+ # @hvacLevel[index].each do |name|
210
+ # if (@commandName == name )
211
+ # scope = "hvac"
212
+ # end
213
+ # end
214
+ # end
215
+ # return scope
216
+ # end
217
+ # # Determines the DOE scope depth (Window, Wall, Space Floor) or (System->Plant) Hierarchy)
218
+ # def depth
219
+ # level = 0
220
+ # scopelist=[]
221
+ # if (doe_scope == "hvac")
222
+ # scopelist = @hvacLevel
223
+ # else
224
+ # scopelist = @envelopeLevel
225
+ # end
226
+ # scopelist.each_index do |index|
227
+ # scopelist[index].each do |name|
228
+ # if (@commandName == name )
229
+ # level = index
230
+ # end
231
+ # end
232
+ # end
233
+ # return level
234
+ # end
235
+ #
236
+ # #Outputs the command in DOE 2.2 format.
237
+ # def output
238
+ # return basic_output()
239
+ # end
240
+ #
241
+ # #Outputs the command in DOE 2.2 format.
242
+ # def basic_output()
243
+ # temp_string = String.new()
244
+ #
245
+ # if (@utype != "")
246
+ # temp_string = temp_string + "#{@utype} = "
247
+ # end
248
+ # temp_string = temp_string + @commandName
249
+ # temp_string = temp_string + "\n"
250
+ # @keywordPairs.each {|array| temp_string = temp_string + "\t#{array[0]} = #{array[1]}\n" }
251
+ # temp_string = temp_string + "..\n"
252
+ #
253
+ # temp_string = temp_string + "$Parents\n"
254
+ # @parents.each do |array|
255
+ # temp_string = temp_string + "$\t#{array.utype} = #{array.commandName}\n"
256
+ # end
257
+ # temp_string = temp_string + "..\n"
258
+ #
259
+ # temp_string = temp_string + "$Children\n"
260
+ # @children.each {|array| temp_string = temp_string + "$\t#{array.utype} = #{array.commandName}\n" }
261
+ # temp_string = temp_string + "..\n"
262
+ #
263
+ # end
264
+ #
265
+ # # Creates the command informantion based on DOE 2.2 syntax.
266
+ # def get_command_from_string(command_string)
267
+ # #Split the command based on the equal '=' sign.
268
+ # remove = ""
269
+ # keyword=""
270
+ # value=""
271
+ #
272
+ # if (command_string != "")
273
+ # #Get command and u-value
274
+ # if ( command_string.match(/(^\s*(\".*?\")\s*\=\s*(\S+)\s*)/) )
275
+ # @commandName=$3.strip
276
+ # @utype = $2.strip
277
+ # remove = Regexp.escape($1)
278
+ #
279
+ # else
280
+ # # if no u-value, get just the command.
281
+ # command_string.match(/(^\s*(\S*)\s)/ )
282
+ # remove = Regexp.escape($1)
283
+ # @commandName=$2.strip
284
+ # end
285
+ # #Remove command from string.
286
+ #
287
+ # command_string.sub!(/#{remove}/,"")
288
+ # command_string.strip!
289
+ #
290
+ #
291
+ # #Loop throught the keyword values.
292
+ # while ( command_string.length > 0 )
293
+ # #DOEMaterial, or SCHEDULES
294
+ # if ( command_string.match(/(^\s*(MATERIAL|DAY-SCHEDULES|WEEK-SCHEDULES)\s*(\=?)\s*(.*)\s*)/))
295
+ # #puts "Bracket"
296
+ # keyword = $2.strip
297
+ # value = $4.strip
298
+ # remove = Regexp.escape($1)
299
+ # #Stars
300
+ # elsif ( command_string.match(/(^\s*(\S*)\s*(\=?)\s*(\*.*?\*)\s*)/))
301
+ # #puts "Bracket"
302
+ # keyword = $2.strip
303
+ # value = $4.strip
304
+ # remove = Regexp.escape($1)
305
+ #
306
+ # #Brackets
307
+ # elsif ( command_string.match(/(^\s*(\S*)\s*(\=?)\s*(\(.*?\))\s*)/))
308
+ # #puts "Bracket"
309
+ # keyword = $2.strip
310
+ # value = $4.strip
311
+ # remove = Regexp.escape($1)
312
+ # #Quotes
313
+ # elsif ( command_string.match(/(^\s*(\S*)\s*(\=?)\s*(".*?")\s*)/) )
314
+ # #puts "Quotes"
315
+ # keyword = $2
316
+ # value = $4.strip
317
+ # remove = Regexp.escape($1)
318
+ # #single command
319
+ # elsif command_string.match(/(^\s*(\S*)\s*(\=?)\s*(\S+)\s*)/)
320
+ # #puts "Other"
321
+ # keyword = $2
322
+ # value = $4.strip
323
+ # remove = Regexp.escape($1)
324
+ # end
325
+ # #puts "DOE22::DOECommand: #{command_string}"
326
+ # #puts "K = #{keyword} V = #{value}\n"
327
+ # if (keyword != "")
328
+ # set_keyword_value(keyword,value)
329
+ # end
330
+ # command_string.sub!(/#{remove}/,"")
331
+ # end
332
+ # #puts "Keyword"
333
+ # #puts keywordPairs
334
+ # end
335
+ # end
336
+ #
337
+ # #Returns an array of the commands parents.
338
+ # def get_parents
339
+ # return @parents
340
+ # end
341
+ #
342
+ # #Returns an array of the commands children.
343
+ # def get_children
344
+ # return children
345
+ # end
346
+ #
347
+ # # Gets name.
348
+ # def get_name()
349
+ # return @utype
350
+ # end
351
+ #
352
+ # # Check if keyword exists.
353
+ # def check_keyword?(keyword)
354
+ # @keywordPairs.each do |pair|
355
+ # if pair[0] == keyword
356
+ # return true
357
+ # end
358
+ # end
359
+ # return false
360
+ # end
361
+ #
362
+ # # Gets the parent of command...if any.
363
+ # def get_parent(keyword)
364
+ #
365
+ # get_parents().each do |findcommand|
366
+ #
367
+ # if ( findcommand.commandName == keyword)
368
+ # return findcommand
369
+ # end
370
+ # end
371
+ # return nil
372
+ #
373
+ # end
374
+ #
375
+ # #Gets children of command, if any.
376
+ # def get_children_of_command(keyword)
377
+ # array = Array.new()
378
+ # children.each do |findcommand|
379
+ # if ( findcommand.commandName == keyword)
380
+ # array.push(findcommand)
381
+ # end
382
+ # end
383
+ # return array
384
+ # end
385
+ #
386
+ # def name()
387
+ # return utype
388
+ # end
389
+ #
390
+ # private
391
+ # def add_keyword_pair(keyword,pair)
392
+ # array = [keyword,pair]
393
+ # keywordPairs.push(array)
394
+ # end
395
+ # end
396
+ # class DOEZone < BTAP::EQuest::DOECommand
397
+ # attr_accessor :space
398
+ # # a vector of spaces used when the declaration of space is "combined"
399
+ # attr_accessor :space_uses
400
+ # # a lighting object which stores the lighting characteristics of each zone
401
+ # attr_accessor :lighting
402
+ # #defines the thermal mass characteristics of the zone.
403
+ # #could be a string object or a user defined object
404
+ # attr_accessor :thermal_mass
405
+ # # stores a constant floating value of the amount of air leakage,
406
+ # #accoriding to rule #4.3.5.9.
407
+ # attr_accessor :air_leakage
408
+ # # this will be a vector consisting of heat transfer objects,
409
+ # # which contains a pointer to the adjacent thermal block and a pointer
410
+ # # to the wall in between them
411
+ # attr_accessor :heat_transfers
412
+ # def initialize
413
+ # super()
414
+ # end
415
+ #
416
+ # def output
417
+ #
418
+ # temp_string = basic_output()
419
+ # if (@space == nil)
420
+ # temp_string = temp_string + "$ No space found to match zone!\n"
421
+ # else
422
+ # temp_string = temp_string + "$Space\n"
423
+ # temp_string = temp_string + "$\t#{@space.utype} = #{@space.commandName}\n"
424
+ # end
425
+ # return temp_string
426
+ # end
427
+ #
428
+ # # This method finds all the exterior surfaces, ie. Exterior Wall and Roof
429
+ # # Output => surfaces as an Array of commands
430
+ # def get_exterior_surfaces()
431
+ # surfaces = Array.new()
432
+ # @space.get_children().each do |child|
433
+ #
434
+ # if child.commandName == "EXTERIOR-WALL" ||
435
+ # child.commandName == "ROOF"
436
+ # surfaces.push(child)
437
+ # end
438
+ # end
439
+ # return surfaces
440
+ # end
441
+ #
442
+ # # This method returns all the children of the space
443
+ # def get_children()
444
+ # return @space.get_children()
445
+ # end
446
+ #
447
+ #
448
+ #
449
+ # # This method returns the area of the space
450
+ # def get_area()
451
+ # @space.get_area()
452
+ # end
453
+ #
454
+ #
455
+ #
456
+ #
457
+ # def convert_to_openstudio(model,runner = nil)
458
+ # if self.space.get_shape() == "NO-SHAPE"
459
+ # BTAP::runner_register("Info", "Thermal Zone contains a NO-SHAPE space named. OS does not support no shape spaces. Thermal Zone will not be created.",runner)
460
+ # else
461
+ # os_zone = OpenStudio::Model::ThermalZone.new(model)
462
+ # os_zone.setName(self.name)
463
+ # #set space to thermal zone
464
+ # OpenStudio::Model::getSpaceByName(model,self.space.name).get.setThermalZone(os_zone)
465
+ # BTAP::runner_register("Info", "\tThermalZone: " + self.name + " created",runner)
466
+ # end
467
+ # end
468
+ # end
469
+ #
470
+ #
471
+ # class DOESurface < DOECommand
472
+ # attr_accessor :construction
473
+ # attr_accessor :polygon
474
+ #
475
+ # def initialize
476
+ # super()
477
+ # @polygon = nil
478
+ # end
479
+ #
480
+ # def get_azimuth()
481
+ # #puts OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 0.0, 0.0), OpenStudio::Vector3d.new(1.0, 0.0, 0.0) ) )
482
+ # if check_keyword?("LOCATION")
483
+ # case get_keyword_value("LOCATION")
484
+ # when /SPACE-\s*V\s*(.*)/
485
+ # index = $1.strip.to_i - 1
486
+ # point0 = self.get_parent("SPACE").polygon.point_list[index]
487
+ # point1 = self.get_parent("SPACE").polygon.point_list[index + 1] ? get_parent("SPACE").polygon.point_list[index + 1] : get_parent("SPACE").polygon.point_list[0]
488
+ # edge = point1-point0
489
+ #
490
+ # sign = OpenStudio::Vector3d.new(1.0, 0.0, 0.0).dot(( edge )) > 0 ? 1 :-1
491
+ # angle = OpenStudio::radToDeg( sign * OpenStudio::getAngle(OpenStudio::Vector3d.new(1.0, 0.0, 0.0), ( point1 - point0 ) ) )
492
+ #
493
+ # #since get angle only get acute angles we need to get sign and completment for reflex angle
494
+ # angle = angle + 180 if edge.y < 0
495
+ # return angle
496
+ # when "FRONT"
497
+ # return OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("SPACE").polygon.point_list[1] - get_parent("SPACE").polygon.point_list[0] ) ) )
498
+ # when "RIGHT"
499
+ # return OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("SPACE").polygon.point_list[2] - get_parent("SPACE").polygon.point_list[1] ) ) )
500
+ # when "BACK"
501
+ # return OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("SPACE").polygon.point_list[3] - get_parent("SPACE").polygon.point_list[2] ) ) )
502
+ # when "LEFT"
503
+ # return OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("SPACE").polygon.point_list[0] - get_parent("SPACE").polygon.point_list[3] ) ) )
504
+ # end
505
+ # end
506
+ # return self.check_keyword?("AZIMUTH")? self.get_keyword_value("AZIMUTH").to_f : 0.0
507
+ # end
508
+ #
509
+ # def get_tilt()
510
+ # #puts OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 0.0, 0.0), OpenStudio::Vector3d.new(1.0, 0.0, 0.0) ) )
511
+ # if check_keyword?("LOCATION")
512
+ # case get_keyword_value("LOCATION")
513
+ # when "FRONT","BACK","LEFT","RIGHT",/SPACE-\s*V\s*(.*)/
514
+ # return 90.0
515
+ # when "TOP"
516
+ # return 0.0
517
+ # when "BOTTOM"
518
+ # return 180.0
519
+ # end
520
+ # end
521
+ # return self.check_keyword?("TILT")? self.get_keyword_value("TILT").to_f : 0.0
522
+ # end
523
+ #
524
+ #
525
+ #
526
+ #
527
+ # def get_origin()
528
+ # space_xref = self.check_keyword?("X")? self.get_keyword_value("X").to_f : 0.0
529
+ # space_yref = self.check_keyword?("Y")? self.get_keyword_value("Y").to_f : 0.0
530
+ # space_zref = self.check_keyword?("Z")? self.get_keyword_value("Z").to_f : 0.0
531
+ # return OpenStudio::Vector3d.new(space_xref,space_yref,space_zref)
532
+ # end
533
+ #
534
+ # def get_sub_surface_origin()
535
+ # height = ""
536
+ # BTAP::runner_register("Info", "geting origin",runner)
537
+ # origin = ""
538
+ # if self.check_keyword?("X") and self.check_keyword?("Y") and self.check_keyword?("Z")
539
+ # BTAP::runner_register("Info", "XYZ definition",runner)
540
+ # space_xref = self.get_keyword_value("X").to_f
541
+ # space_yref = self.get_keyword_value("Y").to_f
542
+ # space_zref = self.get_keyword_value("Z").to_f
543
+ # return OpenStudio::Vector3d.new(space_xref,space_yref,space_zref)
544
+ # end
545
+ # BTAP::runner_register("Info", get_name(),runner)
546
+ # array = Array.new()
547
+ # origin = ""
548
+ # floor = get_parent("FLOOR")
549
+ # space = get_parent("SPACE")
550
+ # case space.get_keyword_value("ZONE-TYPE")
551
+ # when "PLENUM"
552
+ # height = floor.get_keyword_value("FLOOR-HEIGHT").to_f - floor.get_keyword_value("SPACE-HEIGHT").to_f
553
+ # when "CONDITIONED","UNCONDITIONED"
554
+ # height = space.check_keyword?("HEIGHT") ? space.get_keyword_value("HEIGHT").to_f : floor.get_keyword_value("SPACE-HEIGHT").to_f
555
+ #
556
+ # end
557
+ # BTAP::runner_register("Info", "Space is #{space.get_shape}",runner)
558
+ # case space.get_shape
559
+ # when "BOX"
560
+ # BTAP::runner_register("Info", "Box Space Detected....",runner)
561
+ # #get height, width and depth of box.
562
+ # height = space.check_keyword?("HEIGHT").to_f ? space.check_keyword?("HEIGHT") : height
563
+ # width = space.get_keyword_value("WIDTH").to_f
564
+ # depth = space.get_keyword_value("DEPTH").to_f
565
+ #
566
+ # case get_keyword_value("LOCATION")
567
+ # when "TOP"
568
+ # BTAP::runner_register("Info", "Top of Box....",runner)
569
+ # #counter clockwise
570
+ # origin = OpenStudio::Point3d.new(0.0,0.0,height)
571
+ #
572
+ # when "BOTTOM"
573
+ # BTAP::runner_register("Info", "Bottom of Box....",runner)
574
+ # #counter clockwise
575
+ # origin = OpenStudio::Point3d.new( 0.0, 0.0, 0.0 )
576
+ # when "FRONT"
577
+ # BTAP::runner_register("Info", "Front of Box....",runner)
578
+ # #counter clockwise
579
+ # origin = OpenStudio::Point3d.new( 0.0, 0.0, 0.0 )
580
+ # when "RIGHT"
581
+ # BTAP::runner_register("Info", "Right of Box....",runner)
582
+ # #counter clockwise
583
+ # origin = OpenStudio::Point3d.new(width, 0.0, 0.0)
584
+ # when "BACK"
585
+ # BTAP::runner_register("Info", "Back of Box....",runner)
586
+ # #counter clockwise
587
+ # origin = OpenStudio::Point3d.new(width,depth,0.0)
588
+ # when "LEFT"
589
+ # BTAP::runner_register("Info", "Left of Box....",runner)
590
+ # #counter clockwise
591
+ # origin = OpenStudio::Point3d.new(0.0,depth,0.0)
592
+ #
593
+ # end
594
+ #
595
+ # when "POLYGON"
596
+ # #puts "Polygon Space definition detected..."
597
+ # if check_keyword?("LOCATION")
598
+ # #puts "LOCATION surface definition detected..."
599
+ # case get_keyword_value("LOCATION")
600
+ # when "BOTTOM"
601
+ # origin = OpenStudio::Vector3d.new(0.0,0.0, 0.0 )
602
+ # when "TOP"
603
+ # #puts "TOP surface definition detected..."
604
+ # #need to move floor polygon up to space height for top. Using Transformation.translation matrix for this.
605
+ #
606
+ # origin = OpenStudio::Vector3d.new(0.0,0.0, height ) #to-do!!!!!!!!!!!
607
+ # when /SPACE-\s*V\s*(.*)/
608
+ # #puts "SPACE-V#{$1} surface definition detected..."
609
+ # index = $1.strip.to_i - 1
610
+ # point0 = space.polygon.point_list[index]
611
+ # #counter clockwise
612
+ # origin = OpenStudio::Point3d.new( point0.x, point0.y, 0.0)
613
+ #
614
+ # end
615
+ # else
616
+ # #puts "CATCH-ALL for surface definition.."
617
+ # #nasty. The height is NOT defined if the height is the same as the space height...so gotta get it from it's parent space.
618
+ # space_height = space.check_keyword?("HEIGHT") ? space.get_keyword_value("HEIGHT").to_f : floor.get_keyword_value("SPACE-HEIGHT").to_f
619
+ # height = self.check_keyword?("HEIGHT") ? self.get_keyword_value("HEIGHT").to_f : space_height
620
+ # width = self.get_keyword_value("WIDTH").to_f
621
+ # #origin
622
+ # origin = OpenStudio::Point3d.new(width,0.0,0.0)
623
+ # end
624
+ # when "NO-SHAPE"
625
+ # raise("Using SHAPE = NO-SHAPE deifnition for space is not supported by open Studio")
626
+ # end
627
+ #
628
+ # origin = OpenStudio::Vector3d.new(origin.x,origin.y,origin.z)
629
+ # #puts "Surface origin vector is #{origin}"
630
+ # return origin
631
+ # end
632
+ #
633
+ #
634
+ #
635
+ # def get_transformation_matrix
636
+ # #Rotate points around z (azimuth) and x (Tilt)
637
+ # translation = OpenStudio::createTranslation(self.get_origin)
638
+ # e_a = OpenStudio::EulerAngles.new( OpenStudio::degToRad( self.get_tilt ), 0.0, OpenStudio::degToRad( 180.0 - self.get_azimuth ) )
639
+ # rotations = OpenStudio::Transformation::rotation(e_a)
640
+ # return translation * rotations
641
+ # end
642
+ #
643
+ # def get_3d_polygon()
644
+ # array = Array.new()
645
+ # origin = ""
646
+ # floor = get_parent("FLOOR")
647
+ # space = get_parent("SPACE")
648
+ # case space.get_keyword_value("ZONE-TYPE")
649
+ # when "PLENUM"
650
+ # height = floor.get_keyword_value("FLOOR-HEIGHT").to_f - floor.get_keyword_value("SPACE-HEIGHT").to_f
651
+ # when "CONDITIONED","UNCONDITIONED"
652
+ # height = space.check_keyword?("HEIGHT") ? space.get_keyword_value("HEIGHT").to_f : floor.get_keyword_value("SPACE-HEIGHT").to_f
653
+ # end
654
+ #
655
+ # #if the surface has been given a polygon. Then use it.
656
+ # if check_keyword?("POLYGON")
657
+ # # puts "Polygon Surface Detected...Doing a local transform.."
658
+ # #
659
+ # # puts "Point List"
660
+ # # puts self.polygon.point_list
661
+ # # puts "Origin"
662
+ # # puts self.get_origin
663
+ # # puts "azimuth"
664
+ # # puts self.get_azimuth
665
+ # # puts "tilt"
666
+ # # puts self.get_tilt
667
+ #
668
+ #
669
+ #
670
+ # #all other methods below create points relative to the space. This method however, need to be transformed.
671
+ # array = self.polygon.point_list
672
+ #
673
+ #
674
+ # #if surfaces are defined by shape of space.
675
+ # else
676
+ # case space.get_shape
677
+ # when "BOX"
678
+ # BTAP::runner_register("Info", "Box Space Detected....",runner)
679
+ # #get height, width and depth of box.
680
+ # height = space.check_keyword?("HEIGHT").to_f ? space.check_keyword?("HEIGHT") : height
681
+ # width = space.get_keyword_value("WIDTH").to_f
682
+ # depth = space.get_keyword_value("DEPTH").to_f
683
+ #
684
+ # case get_keyword_value("LOCATION")
685
+ # when "TOP"
686
+ # #puts "Top of Box...."
687
+ # #counter clockwise
688
+ # origin = OpenStudio::Point3d.new(0.0,0.0,height)
689
+ # p2 = OpenStudio::Point3d.new(width,0.0,height)
690
+ # p3 = OpenStudio::Point3d.new(width,depth,height)
691
+ # p4 = OpenStudio::Point3d.new(0.0,depth,height)
692
+ # array = [origin,p2,p3,p4]
693
+ # when "BOTTOM"
694
+ # #puts "Bottom of Box...."
695
+ # #counter clockwise
696
+ # origin = OpenStudio::Point3d.new( 0.0, 0.0, 0.0 )
697
+ # p2 = OpenStudio::Point3d.new( 0.0, depth, 0.0)
698
+ # p3 = OpenStudio::Point3d.new( width, depth, 0.0)
699
+ # p4 = OpenStudio::Point3d.new( width,0.0 ,0.0 )
700
+ # array = [origin,p2,p3,p4]
701
+ # when "FRONT"
702
+ # #puts "Front of Box...."
703
+ # #counter clockwise
704
+ # origin = OpenStudio::Point3d.new( 0.0, 0.0, 0.0 )
705
+ # p2 = OpenStudio::Point3d.new( width,0.0 ,0.0 )
706
+ # p3 = OpenStudio::Point3d.new( width, 0.0, height)
707
+ # p4 = OpenStudio::Point3d.new( 0.0, 0.0, height)
708
+ # array = [origin,p2,p3,p4]
709
+ # when "RIGHT"
710
+ # #puts "Right of Box...."
711
+ # #counter clockwise
712
+ # origin = OpenStudio::Point3d.new(width, 0.0, 0.0)
713
+ # p2 = OpenStudio::Point3d.new(width,depth, 0.0)
714
+ # p3 = OpenStudio::Point3d.new(width,depth,height)
715
+ # p4 = OpenStudio::Point3d.new(width,0.0,height)
716
+ # array = [origin,p2,p3,p4]
717
+ # when "BACK"
718
+ # #puts "Back of Box...."
719
+ # #counter clockwise
720
+ # origin = OpenStudio::Point3d.new(width,depth,0.0)
721
+ # p2 = OpenStudio::Point3d.new(0.0,depth,0.0)
722
+ # p3 = OpenStudio::Point3d.new(0.0,depth,height)
723
+ # p4 = OpenStudio::Point3d.new(width,depth,height)
724
+ # array = [origin,p2,p3,p4]
725
+ # when "LEFT"
726
+ # #puts "Left of Box...."
727
+ # #counter clockwise
728
+ # origin = OpenStudio::Point3d.new(0.0,depth,0.0)
729
+ # p2 = OpenStudio::Point3d.new( 0.0, 0.0, 0.0 )
730
+ # p3 = OpenStudio::Point3d.new(0.0, 0.0,height)
731
+ # p4 = OpenStudio::Point3d.new(0.0,depth,height)
732
+ # array = [origin,p2,p3,p4]
733
+ # end
734
+ #
735
+ # when "POLYGON"
736
+ # #puts "Polygon Space definition detected..."
737
+ # if check_keyword?("LOCATION")
738
+ # #puts "LOCATION surface definition detected..."
739
+ # case get_keyword_value("LOCATION")
740
+ # when "BOTTOM"
741
+ # #puts "BOTTOM surface definition detected..."
742
+ # #reverse array
743
+ # array = space.polygon.point_list.dup
744
+ # first = array.pop
745
+ # array.insert(0,first).reverse!
746
+ # when "TOP"
747
+ # #puts "TOP surface definition detected..."
748
+ # #need to move floor polygon up to space height for top. Using Transformation.translation matrix for this.
749
+ # array = OpenStudio::createTranslation(OpenStudio::Vector3d.new(0.0,0.0, height )) * space.polygon.point_list
750
+ # when /SPACE-\s*V\s*(.*)/
751
+ # #puts "SPACE-V#{$1} surface definition detected..."
752
+ # index = $1.strip.to_i - 1
753
+ # point0 = space.polygon.point_list[index]
754
+ # point1 = space.polygon.point_list[index + 1] ? space.polygon.point_list[index + 1] : space.polygon.point_list[0]
755
+ # #counter clockwise
756
+ # origin = OpenStudio::Point3d.new( point0.x, point0.y, 0.0)
757
+ # p2 = OpenStudio::Point3d.new( point1.x, point1.y, 0.0)
758
+ # p3 = OpenStudio::Point3d.new( point1.x, point1.y, height )
759
+ # p4 = OpenStudio::Point3d.new( point0.x, point0.y, height )
760
+ # array = [origin,p2,p3,p4]
761
+ # end
762
+ # else
763
+ # #puts "CATCH-ALL for surface definition.."
764
+ # #nasty. The height is NOT defined if the height is the same as the space height...so gotta get it from it's parent space.
765
+ # space_height = space.check_keyword?("HEIGHT") ? space.get_keyword_value("HEIGHT").to_f : floor.get_keyword_value("SPACE-HEIGHT").to_f
766
+ # height = self.check_keyword?("HEIGHT") ? self.get_keyword_value("HEIGHT").to_f : space_height
767
+ # width = self.get_keyword_value("WIDTH").to_f
768
+ # #counter clockwise
769
+ # origin = OpenStudio::Point3d.new(width,0.0,0.0)
770
+ # p2 = OpenStudio::Point3d.new( 0.0,0.0,0.0 )
771
+ # p3 = OpenStudio::Point3d.new(0.0,0.0,height)
772
+ # p4 = OpenStudio::Point3d.new(width,0.0,height)
773
+ # array = [p4, p3, p2, origin]
774
+ #
775
+ #
776
+ #
777
+ # end
778
+ # when "NO-SHAPE"
779
+ # raise("Using SHAPE = NO-SHAPE deifnition for space is not supported...yet")
780
+ # end
781
+ # end
782
+ # # if self.check_keyword?("AZIMUTH") or self.check_keyword?("TILT")
783
+ # # puts "Did a transform"
784
+ # # return get_transformation_matrix * array
785
+ # # else
786
+ # # return array
787
+ # # end
788
+ # return array
789
+ # end
790
+ #
791
+ #
792
+ # def get_windows()
793
+ # return self.get_children_of_command("WINDOW")
794
+ # end
795
+ #
796
+ # def get_doors()
797
+ # return self.get_children_of_command("DOOR")
798
+ # end
799
+ #
800
+ #
801
+ #
802
+ # # This method finds all the commands within the building that are "Construction"
803
+ # # and if the utype matches, it gets the construction
804
+ # def determine_user_defined_construction()
805
+ # constructions = @building.find_all_commands("CONSTRUCTION")
806
+ # constructions.each do |construction|
807
+ # if ( construction.utype == get_keyword_value("CONSTRUCTION") )
808
+ # @construction = construction
809
+ # end
810
+ # end
811
+ # return @construction
812
+ # end
813
+ #
814
+ # #This method will try to convert a DOE inp file to an openstudio file..
815
+ # def convert_to_openstudio(model,runner = nil)
816
+ # #Get 3d polygon of surface and tranform the points based on space origin and the floor origin since they each may use their own co-ordinate base system.
817
+ # total_transform = ""
818
+ # if self.check_keyword?("AZIMUTH") or self.check_keyword?("TILT")
819
+ # total_transform = get_parent("FLOOR").get_transformation_matrix() * get_parent("SPACE").get_transformation_matrix() * get_transformation_matrix()
820
+ # else
821
+ # total_transform = get_parent("FLOOR").get_transformation_matrix() * get_parent("SPACE").get_transformation_matrix()
822
+ # end
823
+ # surface_points = total_transform * self.get_3d_polygon()
824
+ # #Add the surface to the new openstudio model.
825
+ #
826
+ # os_surface = OpenStudio::Model::Surface.new(surface_points, model)
827
+ # #set the name of the surface.
828
+ # os_surface.setName(self.name)
829
+ # case self.commandName
830
+ # #Set the surface boundary condition if it is a ground surface.
831
+ #
832
+ # when "UNDERGROUND-WALL"
833
+ # BTAP::Geometry::Surfaces::set_surfaces_boundary_condition(model,os_surface, "Ground")
834
+ # when "EXTERIOR-WALL","ROOF"
835
+ # #this is needed since the surface constructor defaults to a Ground boundary and Floor Surface type
836
+ # #when a horizontal surface is initialized.
837
+ # if os_surface.outsideBoundaryCondition == "Ground" and os_surface.surfaceType == "Floor"
838
+ # os_surface.setSurfaceType("RoofCeiling")
839
+ # end
840
+ # BTAP::Geometry::Surfaces::set_surfaces_boundary_condition(model,os_surface, "Outdoors")
841
+ # when "INTERIOR-WALL"
842
+ # BTAP::Geometry::Surfaces::set_surfaces_boundary_condition(model,os_surface, "Surface")
843
+ # end
844
+ #
845
+ # #Add to parent space that was already created.
846
+ # os_surface.setSpace(OpenStudio::Model::getSpaceByName( model,get_parent("SPACE").name).get )
847
+ # #output to console for debugging.
848
+ # BTAP::runner_register("Info", "\tSurface: " + self.name + " created",runner)
849
+ # #check if we need to create a mirror surface in another space.
850
+ # if self.check_keyword?("NEXT-TO")
851
+ # #reverse the points.
852
+ # new_array = surface_points.dup
853
+ # first = new_array.pop
854
+ # new_array.insert(0,first).reverse!
855
+ # #...then add the reverse surface to the model and assign the name with a mirror suffix.
856
+ # os_surface_mirror = OpenStudio::Model::Surface.new(new_array, model)
857
+ # os_surface_mirror.setName(self.name + "-mirror" )
858
+ # #Assign the mirror surface to the parent space that is NEXT-TO
859
+ # os_surface_mirror.setSpace(OpenStudio::Model::getSpaceByName(model,get_keyword_value("NEXT-TO")).get)
860
+ # #output to console for debugging.
861
+ # BTAP::runner_register("Info", "\tSurface: " + self.name + "-mirror" + " created",runner)
862
+ # end #if statement
863
+ #
864
+ # #Some switches for debugging.
865
+ # convert_sub_surfaces = true
866
+ # convert_sub_surfaces_as_surfaces = false
867
+ #
868
+ # #
869
+ # if convert_sub_surfaces
870
+ # #convert subsurfaces
871
+ # self.get_children().each do |child|
872
+ # #Get height and width of subsurface
873
+ # height = child.get_keyword_value("HEIGHT").to_f
874
+ # width = child.get_keyword_value("WIDTH").to_f
875
+ #
876
+ #
877
+ # #Sum the origin of the surface and the translation of the window
878
+ # x = os_surface.vertices.first().x + ( child.check_keyword?("X")? child.get_keyword_value("X").to_f : 0.0 )
879
+ # y = os_surface.vertices.first().y + ( child.check_keyword?("Y")? child.get_keyword_value("Y").to_f : 0.0 )
880
+ # z = os_surface.vertices.first().z
881
+ #
882
+ # #counter clockwise
883
+ # origin = OpenStudio::Point3d.new( x, y , z )
884
+ # p2 = OpenStudio::Point3d.new(x + width , y, z )
885
+ # p3 = OpenStudio::Point3d.new(x + width , y + height , z )
886
+ # p4 = OpenStudio::Point3d.new(x, y + height, z )
887
+ # polygon = [origin,p2,p3,p4]
888
+ #
889
+ # #get floot and space rotations
890
+ # space_azi = 360.0 - get_parent("SPACE").get_azimuth()
891
+ # floor_azi = 360.0 - get_parent("FLOOR").get_azimuth()
892
+ #
893
+ #
894
+ # tilt_trans = OpenStudio::Transformation::rotation(os_surface.vertices.first(), OpenStudio::Vector3d.new(1.0,0.0,0.0), OpenStudio::degToRad( self.get_tilt ))
895
+ # azi_trans = OpenStudio::Transformation::rotation(os_surface.vertices.first(), OpenStudio::Vector3d.new(0.0,0.0,1.0), OpenStudio::degToRad( 360.0 - self.get_azimuth + space_azi + floor_azi ))
896
+ # surface_points = azi_trans * tilt_trans * polygon
897
+ # if convert_sub_surfaces_as_surfaces
898
+ # #Debug subsurface
899
+ # os_sub_surface = OpenStudio::Model::Surface.new(surface_points, model)
900
+ # #set the name of the surface.
901
+ # os_sub_surface.setName(child.name)
902
+ # #Add to parent space that was already created.
903
+ # os_sub_surface.setSpace(OpenStudio::Model::getSpaceByName( model,self.get_parent("SPACE").name).get )
904
+ # else
905
+ # #Add the subsurface to the new openstudio model.
906
+ # os_sub_surface = OpenStudio::Model::SubSurface.new(surface_points, model)
907
+ # #set the name of the surface.
908
+ # os_sub_surface.setName(child.name)
909
+ # #Add to parent space that was already created.
910
+ # os_sub_surface.setSurface(os_surface)
911
+ # #output to console for debugging.
912
+ # BTAP::runner_register("Info", "\tSubSurface: " + child.name + " created",runner)
913
+ # case child.commandName
914
+ # when "WINDOW"
915
+ # #By default it is a window.
916
+ # when "DOOR"
917
+ # os_sub_surface.setSubSurfaceType( "Door" )
918
+ # end #end case.
919
+ #
920
+ # # Add overhang for subsurface if required. Note this only supports overhangs of width the same as the window.
921
+ # if child.check_keyword?("OVERHANG-D") == true
922
+ # offset = 0.0
923
+ # offset = child.get_keyword_value("OVERHANG-O").to_f if child.check_keyword?("OVERHANG-O")
924
+ # depth = 0.0
925
+ # depth = child.get_keyword_value("OVERHANG-D").to_f
926
+ # os_sub_surface.addOverhang( depth , offset )
927
+ # end
928
+ #
929
+ # end
930
+ # end
931
+ # end
932
+ # end
933
+ #
934
+ # end
935
+ #
936
+ # #This class allows to manipulate a subsurface (window/door) in inherits from surface.
937
+ # class DOESubSurface < DOESurface
938
+ #
939
+ # def initialize
940
+ # #run the parent class initialization.
941
+ # super()
942
+ # end
943
+ #
944
+ # # This method returns the area of the window
945
+ # def get_area()
946
+ # unless check_keyword?("HEIGHT") and check_keyword?("WIDTH")
947
+ # raise "Error: In the command #{@utype}:#{@command_name} the area could not be evaluated. Either the HEIGHT or WIDTH is invalid.\n #{output}"
948
+ # end
949
+ # return get_keyword_value("WIDTH").to_f * get_keyword_value("HEIGHT").to_f
950
+ # end
951
+ #
952
+ # #Return the widow polygon with an origin of zero
953
+ # def get_3d_polygon()
954
+ # height = get_keyword_value("HEIGHT").to_f
955
+ # width = get_keyword_value("WIDTH").to_f
956
+ # x = self.check_keyword?("X")? self.get_keyword_value("X").to_f : 0.0
957
+ # y = self.check_keyword?("Y")? self.get_keyword_value("Y").to_f : 0.0
958
+ # #counter clockwise
959
+ # origin = OpenStudio::Point3d.new( x, y , 0.0 )
960
+ # p2 = OpenStudio::Point3d.new(x + width , y,0.0 )
961
+ # p3 = OpenStudio::Point3d.new(x + width , y + height , 0.0 )
962
+ # p4 = OpenStudio::Point3d.new(x, y + height,0.0 )
963
+ # return [origin,p2,p3,p4]
964
+ # end
965
+ #
966
+ # #Returns the origin relative to the parent surface.
967
+ # def get_origin()
968
+ # origin = get_parent_surface().get_sub_surface_origin()
969
+ # return origin
970
+ # end
971
+ #
972
+ # #Gets azimuth, based on parent surface.
973
+ # def get_azimuth()
974
+ # get_parent_surface().get_azimuth()
975
+ # end
976
+ #
977
+ # #gets tilt based on parent surface.
978
+ # def get_tilt()
979
+ # get_parent_surface().get_tilt()
980
+ # end
981
+ #
982
+ # #return the parent surface of the subsurface.
983
+ # def get_parent_surface()
984
+ # get_parents().each do |findcommand|
985
+ # [
986
+ # "EXTERIOR-WALL",
987
+ # "INTERIOR-WALL",
988
+ # "UNDERGROUND-WALL",
989
+ # "ROOF"
990
+ # ].each do |type|
991
+ #
992
+ # if ( findcommand.commandName == type)
993
+ # return findcommand
994
+ # end
995
+ # end
996
+ # end
997
+ # raise("#no parent surface defined!")
998
+ # end
999
+ #
1000
+ # #returns the translation matrix reletive to its parent ( the surface )
1001
+ # def get_transformation_matrix
1002
+ # return self.get_rotation_matrix() * self.get_translation_matrix()
1003
+ # end
1004
+ #
1005
+ # def get_rotation_matrix
1006
+ # #Rotate points around z (azimuth) and x (Tilt)
1007
+ # e_a = OpenStudio::EulerAngles.new( OpenStudio::degToRad( self.get_tilt ), 0.0, OpenStudio::degToRad( 0.0 ) )
1008
+ # rotations = OpenStudio::Transformation::rotation(e_a)
1009
+ # return rotations
1010
+ # end
1011
+ #
1012
+ # def get_translation_matrix
1013
+ # #Rotate points around z (azimuth) and x (Tilt)
1014
+ # translation = OpenStudio::createTranslation(self.get_origin)
1015
+ # return translation
1016
+ # end
1017
+ #
1018
+ #
1019
+ #
1020
+ #
1021
+ #
1022
+ # # this will translate the subsurface to the openstudio model.
1023
+ # def convert_to_openstudio(model)
1024
+ # end
1025
+ # end
1026
+ #
1027
+ # #an attempt to organize the BDLlibs...don't think it works well at all.
1028
+ # class DOEBDLlib
1029
+ #
1030
+ # attr_accessor :db, :materials
1031
+ #
1032
+ # include Singleton
1033
+ #
1034
+ #
1035
+ #
1036
+ #
1037
+ # # stores the name of the individual materials
1038
+ #
1039
+ # attr_accessor :commandList
1040
+ # # stores the name of the individual layers
1041
+ #
1042
+ #
1043
+ # def initialize
1044
+ # @commandList = Array.new()
1045
+ # @db = Sequel.sqlite
1046
+ # @db.create_table :materials do # Create a new table
1047
+ # primary_key :id, :integer, :auto_increment => true
1048
+ # column :command_name, :text
1049
+ # column :name, :text
1050
+ # column :type, :text
1051
+ # column :thickness, :float
1052
+ # column :conductivity, :float
1053
+ # column :resistance, :float
1054
+ # column :density, :float
1055
+ # column :spec_heat, :float
1056
+ # end
1057
+ # @materials = @db[:materials] # Create a dataset
1058
+ #
1059
+ # @db.create_table :layers do # Create a new table
1060
+ # primary_key :id, :integer, :auto_increment => true
1061
+ # column :command_name, :text
1062
+ # column :name, :text
1063
+ # column :material, :text
1064
+ # column :inside_film_res, :float
1065
+ # end
1066
+ # @layers = @db[:layers] # Create a dataset
1067
+ #
1068
+ #
1069
+ # store_material()
1070
+ # end
1071
+ #
1072
+ #
1073
+ #
1074
+ # def find_material(utype)
1075
+ # posts = @materials.filter(:name => utype)
1076
+ # record = posts.first()
1077
+ # #Create the new command object.
1078
+ # command = DOE2::DOECommand.new()
1079
+ # #Insert the collected information into the object.
1080
+ # command.commandName = "MATERIAL"
1081
+ # command.utype = record[:name]
1082
+ # command.set_keyword_value("TYPE", record[:type])
1083
+ # command.set_keyword_value("THICKNESS", record[:thickness])
1084
+ # command.set_keyword_value("CONDUCTIVITY", record[:conductivity])
1085
+ # command.set_keyword_value("DENSITY", record[:density])
1086
+ # command.set_keyword_value("SPECIFIC HEAT", record[:spec_heat])
1087
+ #
1088
+ # return command
1089
+ # end
1090
+ #
1091
+ #
1092
+ # def find_layer(utype)
1093
+ # posts = @layers.filter(:name => utype)
1094
+ # record = posts.first()
1095
+ # #Create the new command object.
1096
+ # command = DOE2::DOECommand.new()
1097
+ # #Insert the collected information into the object.
1098
+ # command.commandName = "LAYERS"
1099
+ # command.utype = record[:name]
1100
+ # command.set_keyword_value("MATERIAL", record[:material])
1101
+ # command.set_keyword_value("THICKNESS", record[:thickness])
1102
+ # command.set_keyword_value("CONDUCTIVITY", record[:conductivity])
1103
+ # command.set_keyword_value("DENSITY", record[:density])
1104
+ # command.set_keyword_value("SPECIFIC HEAT", record[:spec_heat])
1105
+ #
1106
+ # return command
1107
+ # end
1108
+ #
1109
+ #
1110
+ #
1111
+ #
1112
+ #
1113
+ # # stores the material information using keywordPairs into the command structure
1114
+ # # accessed using the find_command method
1115
+ # private
1116
+ # def store_material
1117
+ #
1118
+ # begin
1119
+ # f = File.open("../Resources/DOE2_2/bdllib.dat")
1120
+ # rescue
1121
+ # f = File.open("Resources/DOE2_2/bdllib.dat")
1122
+ # end
1123
+ #
1124
+ # lines = f.readlines
1125
+ # # Iterating through the file.
1126
+ # lines.each_index do |i|
1127
+ # command_string = ""
1128
+ # # If we find a material.
1129
+ # if lines[i].match(/\$LIBRARY-ENTRY\s(.{32})MAT .*/)
1130
+ # #Get the name strips the white space.
1131
+ # name = ("\""+$1.strip + "\"")
1132
+ #
1133
+ # #Is this the last line?
1134
+ # command_string = get_data(command_string, i, lines)
1135
+ # #Extract data for material type PROPERTIES.
1136
+ # if (match = command_string.match(/^\s*TYPE\s*=\s*(\S*)\s*TH\s*=\s*(\S*)\s*COND\s*=\s*(\S*)\s*DENS\s*=\s*(\S*)\s*S-H\s*=\s*(\S*)\s*$/) )
1137
+ # #Create the new command object.
1138
+ # command = DOE2::DOECommand.new()
1139
+ # #Insert the collected information into the object.
1140
+ # command.commandName = "MATERIAL"
1141
+ # command.utype = name
1142
+ # command.set_keyword_value("TYPE", $1.strip)
1143
+ # command.set_keyword_value("THICKNESS", $2.strip.to_f.to_s)
1144
+ # command.set_keyword_value("CONDUCTIVITY", $3.strip.to_f.to_s)
1145
+ # command.set_keyword_value("DENSITY", $4.strip.to_f.to_s)
1146
+ # command.set_keyword_value("SPECIFIC HEAT", $5.strip.to_f.to_s)
1147
+ # #Push the object into the array for storage.
1148
+ # @commandList.push(command)
1149
+ # @materials << {:name => name,
1150
+ # :command_name => 'MATERIAL',
1151
+ # :type => $1.strip,
1152
+ # :thickness => $2.strip.to_f.to_s,
1153
+ # :conductivity => $3.strip.to_f.to_s,
1154
+ # :density => $4.strip.to_f.to_s,
1155
+ # :spec_heat => $5.strip.to_f.to_s}
1156
+ #
1157
+ #
1158
+ #
1159
+ # #Extract data for material type RESISTANCE.
1160
+ # elsif (match = command_string.match(/^\s*TYPE\s*=\s*(\S*)\s*RES\s*=\s*(\S*)\s*$/) )
1161
+ # command = DOE2::DOECommand.new()
1162
+ # command.commandName = "MATERIAL"
1163
+ # command.utype = name
1164
+ # command.set_keyword_value("TYPE", $1.strip)
1165
+ # command.set_keyword_value("RESISTANCE", $2.strip.to_f.to_s)
1166
+ # #Push the object into the array for storage.
1167
+ # @materials << {:name => name,
1168
+ # :command_name => 'MATERIAL',
1169
+ # :type => $1.strip,
1170
+ # :resistance => $2.strip.to_f.to_s}
1171
+ #
1172
+ # @commandList.push(command)
1173
+ # else
1174
+ # raise("data not extracted")
1175
+ # end
1176
+ # end
1177
+ #
1178
+ # if lines[i].match(/\$LIBRARY-ENTRY\s(.{32})LA .*/)
1179
+ # #Get the name
1180
+ # name = ("\""+$1.strip + "\"")
1181
+ # #Is this the last line?
1182
+ # command_string = get_data(command_string, i, lines)
1183
+ # #Extract data into the command.
1184
+ # if (match = command_string.match(/^\s*MAT\s*=\s*(.*?)\s*I-F-R\s*=\s*(\S*)\s*$/) )
1185
+ # command = DOE2::DOECommand.new()
1186
+ # command.commandName = "LAYERS"
1187
+ # command.utype = name
1188
+ # command.set_keyword_value("MATERIAL",$1)
1189
+ # #Push the object into the array for storage.
1190
+ # @layers << {:name => name,
1191
+ # :command_name => 'LAYER',
1192
+ # :material => $1.strip,
1193
+ # :inside_film_res => $2.strip.to_f.to_s}
1194
+ # @commandList.push(command)
1195
+ # else
1196
+ # raise("data not extracted")
1197
+ # end
1198
+ # end
1199
+ # end
1200
+ # end
1201
+ #
1202
+ # private
1203
+ # # This method will get all the
1204
+ # def get_data(command_string, i, lines)
1205
+ # #Do this while this is NOT the last line of data.
1206
+ # while (! lines[i].match(/^(.*?)\.\.\s*(.{6})?\s*?(\d*)?/) )
1207
+ # #Grab all the data in between.
1208
+ # if ( lines[i].match(/^\$.*$/) )
1209
+ # elsif ( myarray = lines[i].match(/^(.*?)\s*(.{6})?\s*?(\d*)?\s*$/) )
1210
+ # command_string = command_string + $1.strip
1211
+ # end
1212
+ # #Increment counter.
1213
+ # i = i + 1
1214
+ # end
1215
+ # #Get the last line
1216
+ # lines[i].match(/^(.*?)\.\.\s*(.{6})?\s*?(\d*)?/)
1217
+ # command_string = command_string + $1.strip
1218
+ # if command_string == ""
1219
+ # raise("error")
1220
+ # end
1221
+ # i = i + 1
1222
+ # command_string
1223
+ # end
1224
+ # end
1225
+ #
1226
+ # #class that
1227
+ # class DOEExteriorWall < DOESurface
1228
+ #
1229
+ # def initialize
1230
+ # #call the parent class.
1231
+ # super()
1232
+ # end
1233
+ #
1234
+ # # This method finds the area of the exterior wall
1235
+ # def get_area()
1236
+ # OpenStudio::getArea(self.get_3d_polygon())
1237
+ # end
1238
+ #
1239
+ # #This method finds the floor parent
1240
+ # def get_floor()
1241
+ # get_parent("FLOOR")
1242
+ # end
1243
+ #
1244
+ # #This method finds the space parent command
1245
+ # def get_space()
1246
+ # get_parent("SPACE")
1247
+ # end
1248
+ #
1249
+ # #This method gets the construction command
1250
+ # def get_construction_name()
1251
+ # get_keyword_value("CONSTRUCTION")
1252
+ # end
1253
+ #
1254
+ # #This method returns the window area
1255
+ # def get_window_area()
1256
+ # get_children_area("WINDOW")
1257
+ # end
1258
+ #
1259
+ # #This method returns the door area
1260
+ # def get_door_area()
1261
+ # get_children_area("DOOR")
1262
+ # end
1263
+ #
1264
+ # # This method returns the difference between the wall area and the window
1265
+ # # and door
1266
+ # def get_opaque_area()
1267
+ # get_area.to_f - get_window_area().to_f - get_door_area().to_f
1268
+ # end
1269
+ #
1270
+ # # This method returns the fraction of the wall dominated by the window
1271
+ # def get_fwr()
1272
+ # get_window_area().to_f / get_area.to_f
1273
+ # end
1274
+ #
1275
+ # # This method returns the area of the children classes based on the given
1276
+ # # commandname.
1277
+ # # Input => A command_name as a String
1278
+ # # Output => Total area as a float
1279
+ # def get_children_area(scommand_name)
1280
+ # area = 0.0
1281
+ # @children.each do |child|
1282
+ #
1283
+ # if child.commandName == scommand_name
1284
+ # area = child.get_area() + area
1285
+ # end
1286
+ # end
1287
+ # return area
1288
+ # end
1289
+ #
1290
+ # # This method checks if the construction only has a defined U-value
1291
+ # def just_u_value?()
1292
+ # @construction.check_keyword?("U-VALUE")
1293
+ # end
1294
+ #
1295
+ #
1296
+ # end
1297
+ #
1298
+ #
1299
+ #
1300
+ #
1301
+ #
1302
+ #
1303
+ # #The interface for the roof command.. same as parent.
1304
+ # class DOERoof < DOECommand
1305
+ # def initialize
1306
+ # super()
1307
+ # end
1308
+ #
1309
+ # # This method finds the area of the roof
1310
+ # def get_area
1311
+ #
1312
+ # # Finds the floor and space parents and assigns them to @floor and @space
1313
+ # # variables to be used later
1314
+ # parent = get_parents
1315
+ # parent.each do |findcommand|
1316
+ # if ( findcommand.commandName == "FLOOR" )
1317
+ # @floor = findcommand
1318
+ # end
1319
+ # if ( findcommand.commandName == "SPACE")
1320
+ # @space = findcommand
1321
+ # end
1322
+ # end
1323
+ #
1324
+ # # Get the keyword value for location
1325
+ # begin
1326
+ # location = get_keyword_value("LOCATION")
1327
+ # rescue
1328
+ # end
1329
+ #
1330
+ # # Get the keyword value for polygon
1331
+ # begin
1332
+ # polygon_id = get_keyword_value("POLYGON")
1333
+ # rescue
1334
+ # end
1335
+ #
1336
+ # # if the polygon_id keyword value was nil and the location value was nil, then
1337
+ # # the height and width are directly defined within the "roof" command
1338
+ #
1339
+ #
1340
+ # if ( location == "BOTTOM" || location == "TOP") && (@space.get_shape != "BOX")
1341
+ # return @space.polygon.get_area
1342
+ #
1343
+ # elsif ( location == nil && polygon_id == nil )
1344
+ # height = get_keyword_value("HEIGHT")
1345
+ # width = get_keyword_value("WIDTH")
1346
+ # height = height.to_f
1347
+ # width = width.to_f
1348
+ # return height * width
1349
+ # elsif ( location == nil && polygon_id != nil)
1350
+ # return @space.polygon.get_area
1351
+ #
1352
+ #
1353
+ # # if the location was defined as "SPACE...", it is immediately followed by a
1354
+ # # vertex, upon which lies the width of the roof
1355
+ # elsif location.match(/SPACE.*/)
1356
+ # location = location.sub( /^(.{6})/, "")
1357
+ # width = @space.polygon.get_length(location)
1358
+ # height = @floor.get_space_height
1359
+ # return width * height
1360
+ # # if the shape was a box, the width and height would be taken from the
1361
+ # # "SPACE" object
1362
+ # elsif ( @space.get_shape == "BOX" )
1363
+ # width = @space.get_width
1364
+ # height = @space.get_height
1365
+ # return width * height
1366
+ # else
1367
+ # raise "The area could not be evaluated"
1368
+ # end
1369
+ # end
1370
+ #
1371
+ # #returns tilt of roof surface.
1372
+ # def get_tilt()
1373
+ # if check_keyword?("TILT") then return get_keyword_value("TILT").to_f
1374
+ # else
1375
+ # if check_keyword?("LOCATION")
1376
+ # location = get_keyword_value("LOCATION")
1377
+ # case location
1378
+ # when "TOP"
1379
+ # return 0.0
1380
+ # when "BOTTOM"
1381
+ # return 180.0
1382
+ # when "LEFT", "RIGHT", "BACK", "FRONT"
1383
+ # return 90.0
1384
+ # end
1385
+ # end
1386
+ # # If it is a polygon or not defined, set to DOE default = 0.0
1387
+ # return 0
1388
+ # end
1389
+ # end
1390
+ #
1391
+ # # This method returns the Azimuth value as a FLOAT if it exists
1392
+ # # It first checks if the azimuth keyword value is present within the roof
1393
+ # # command itself. If it does not find this, then it checks for the location
1394
+ # # keyword and assigns the correct azimuth depending on the azimuth of the parent
1395
+ # # space. However, if the shape of the parent space is defined as a polygon, then it
1396
+ # # searches for the location of the roof and uses the polygon's get-azimuth for the vertex
1397
+ # # to return the azimuth of the roof
1398
+ #
1399
+ # #NOTE: The FRONT is defined as 0, going clockwise, ie. RIGHT = 90 degrees
1400
+ #
1401
+ # #OUTPUT: Azimuth between the parent SPACE and the ROOF
1402
+ # def get_azimuth()
1403
+ # space = get_parent("SPACE")
1404
+ # if check_keyword?("AZIMUTH") then return get_keyword_value("AZIMUTH").to_f
1405
+ # else
1406
+ # if check_keyword?("LOCATION")
1407
+ # location = get_keyword_value("LOCATION")
1408
+ #
1409
+ # case location
1410
+ # when "TOP"
1411
+ # raise "Exception: Azimuth does not exist"
1412
+ # when "BOTTOM"
1413
+ # raise "Exception: Azimuth does not exist"
1414
+ # when "FRONT"
1415
+ # return 0.0 + space.get_azimuth
1416
+ # when "RIGHT"
1417
+ # return 90.0 + space.get_azimuth
1418
+ # when "BACK"
1419
+ # return 180.0 + space.get_azimuth
1420
+ # when "LEFT"
1421
+ # return 270.0 + space.get_azimuth
1422
+ # end
1423
+ # end
1424
+ # if space.get_keyword_value("SHAPE") == "POLYGON"
1425
+ # space_vertex = get_keyword_value("LOCATION")
1426
+ # space_vertex.match(/SPACE-(.*)/)
1427
+ # vertex = $1.strip
1428
+ # return space.polygon.get_azimuth(vertex)
1429
+ # end
1430
+ #
1431
+ # end
1432
+ # end
1433
+ #
1434
+ # # This method returns the Azimuth value as a FLOAT if it exists
1435
+ # # It first checks if the azimuth keyword value is present within the roof
1436
+ # # command itself. If it does not find this, then it checks for the location
1437
+ # # keyword and assigns the correct azimuth depending on the azimuth of the parent
1438
+ # # space. However, if the shape of the parent space is defined as a polygon, then it
1439
+ # # searches for the location of the roof and uses the polygon's get-azimuth for the vertex
1440
+ # # and adding it on to the overall azimuth to get the Absolute Azimuth from True North
1441
+ #
1442
+ # #NOTE: The FRONT is defined as 0, going clockwise, ie. RIGHT = 90 degrees
1443
+ #
1444
+ # #OUTPUT: Azimuth between ROOF and TRUE NORTH
1445
+ # def get_absolute_azimuth
1446
+ # space = get_parent("SPACE")
1447
+ # if check_keyword?("AZIMUTH")
1448
+ # azimuth = get_keyword_value("AZIMUTH").to_f
1449
+ # space_azimuth = space.get_absolute_azimuth
1450
+ # return azimuth + space_azimuth
1451
+ # else
1452
+ # if check_keyword?("LOCATION")
1453
+ # location = get_keyword_value("LOCATION")
1454
+ # case location
1455
+ # when "TOP"
1456
+ # raise "Exception: Azimuth does not exist"
1457
+ # when "BOTTOM"
1458
+ # raise "Exception: Azimuth does not exist"
1459
+ # when "FRONT"
1460
+ # return 0.0 + space.get_absolute_azimuth
1461
+ # when "RIGHT"
1462
+ # return 90.0 + space.get_absolute_azimuth
1463
+ # when "BACK"
1464
+ # return 180.0 + space.get_absolute_azimuth
1465
+ # when "LEFT"
1466
+ # return 270.0 + space.get_absolute_azimuth
1467
+ # end
1468
+ # end
1469
+ # if space.get_keyword_value("SHAPE") == "POLYGON"
1470
+ # space_vertex = get_keyword_value("LOCATION")
1471
+ # space_vertex.match(/SPACE-(.*)/)
1472
+ # vertex = $1.strip
1473
+ # return space.polygon.get_azimuth(vertex) + space.get_absolute_azimuth
1474
+ # end
1475
+ # end
1476
+ # end
1477
+ # end
1478
+ # #Interface for the DOESpace Command.
1479
+ # class DOESpace < DOECommand
1480
+ # attr_accessor :polygon
1481
+ # attr_accessor :zone
1482
+ # def initialize
1483
+ #
1484
+ # super()
1485
+ # end
1486
+ #
1487
+ # #this outputs the command to a string.
1488
+ # def output
1489
+ # temp_string = basic_output()
1490
+ # if @polygon != nil
1491
+ # temp_string = temp_string + "$Polygon\n"
1492
+ # temp_string = temp_string + "$\t#{@polygon.utype} = #{@polygon.commandName}\n"
1493
+ # end
1494
+ # if @zone != nil
1495
+ # temp_string = temp_string + "$Zone\n"
1496
+ # temp_string = temp_string + "$\t#{@zone.utype} = #{@zone.commandName}\n"
1497
+ # end
1498
+ # return temp_string
1499
+ # end
1500
+ #
1501
+ # # This method finds the area of the space
1502
+ # def get_area
1503
+ #
1504
+ # # get the keyword value of shape
1505
+ # shape = get_keyword_value("SHAPE")
1506
+ #
1507
+ # # if the shape value is nil, or it is defined as "NO-SHAPE", the get_area value
1508
+ # # would be defined, and would represent the get_area of the space
1509
+ # if ( shape == nil || shape == "NO-SHAPE")
1510
+ # area = get_keyword_value("AREA")
1511
+ # area = area.to_f
1512
+ # return area
1513
+ #
1514
+ # # if the shape value is "BOX", the height and width key values are given,
1515
+ # # and the get_area would be defined as their product
1516
+ # elsif ( shape == "BOX" )
1517
+ # height = get_keyword_value("HEIGHT")
1518
+ # width = get_keyword_value("WIDTH")
1519
+ # height = height.to_f
1520
+ # width = width.to_f
1521
+ # return height * width
1522
+ #
1523
+ # # if the shape value is defined as a polygon , the get_area of the polygon would
1524
+ # # represent the get_area of the space
1525
+ # elsif ( shape == "POLYGON")
1526
+ # return @polygon.get_area
1527
+ # else
1528
+ # raise "Error: The area could not be evaluated. Please check inputs\n "
1529
+ #
1530
+ # end
1531
+ # end
1532
+ #
1533
+ # # This method finds the volume of the space
1534
+ # def get_volume
1535
+ #
1536
+ # # get the keyword value of "SHAPE"
1537
+ # shape = get_keyword_value("SHAPE")
1538
+ #
1539
+ # # if the shape value returns nil, or is defined as "NO-SHAPE", the volume is
1540
+ # # given directly
1541
+ # if ( shape == nil || shape == "NO-SHAPE")
1542
+ # volume = get_keyword_value("VOLUME")
1543
+ # volume = volume.to_f
1544
+ # return volume
1545
+ #
1546
+ # # if the shape is defined as a "BOX", the values for height, width, and
1547
+ # # depth are given, from which you can get the volume
1548
+ # elsif ( shape == "BOX" )
1549
+ # height = get_keyword_value("HEIGHT")
1550
+ # width = get_keyword_value("WIDTH")
1551
+ # depth = get_keyword_value("DEPTH")
1552
+ # height = height.to_f
1553
+ # width = width.to_f
1554
+ # depth = depth.to_f
1555
+ # return height * width * depth
1556
+ #
1557
+ # # if the shape is defined as a "POLYGON", the get_area is defined as the area
1558
+ # # of the polygon, and the height is given by the value of "HEIGHT"
1559
+ # elsif ( shape == "POLYGON")
1560
+ # height = getKeywordvalue("HEIGHT")
1561
+ # temp = get_keyword_value("POLYGON")
1562
+ # height = height.to_f
1563
+ # @polygon.utype = temp
1564
+ # return @polygon.get_area * height
1565
+ # else
1566
+ # raise "Error: The volume could not be evaluated. Please check inputs\n "
1567
+ #
1568
+ # end
1569
+ #
1570
+ # end
1571
+ #
1572
+ # def get_height()
1573
+ # if check_keyword?("HEIGHT") then return get_keyword_value("HEIGHT").to_f end
1574
+ # return get_floor.get_keyword_value("SPACE-HEIGHT").to_f
1575
+ # end
1576
+ #
1577
+ # def get_width
1578
+ # width = get_keyword_value("WIDTH")
1579
+ # width = width.to_f
1580
+ # return width
1581
+ # end
1582
+ #
1583
+ # def get_depth
1584
+ # depth = get_keyword_value("DEPTH")
1585
+ # depth = depth.to_f
1586
+ # return depth
1587
+ # end
1588
+ #
1589
+ # def get_shape
1590
+ # return "NO-SHAPE" unless check_keyword?("SHAPE")
1591
+ # return get_keyword_value("SHAPE")
1592
+ # end
1593
+ #
1594
+ # def get_floor
1595
+ # get_parent("FLOOR")
1596
+ # end
1597
+ #
1598
+ #
1599
+ # def get_origin()
1600
+ # space_origin = nil
1601
+ # if check_keyword?("LOCATION") and ( not self.check_keyword?("X") or not self.check_keyword?("Y") or not self.check_keyword?("Z") )
1602
+ # zero = OpenStudio::Point3d.new( 0.0, 0.0, 0.0 )
1603
+ # case get_keyword_value("LOCATION")
1604
+ # when /FLOOR-\s*V\s*(.*)/
1605
+ # index = $1.strip.to_i - 1
1606
+ # surf_vector = get_parent("FLOOR").polygon.point_list[index] - zero
1607
+ # when "FRONT"
1608
+ # surf_vector = get_parent("FLOOR").polygon.point_list[0] - zero
1609
+ # when "RIGHT"
1610
+ # surf_vector = get_parent("FLOOR").polygon.point_list[1] - zero
1611
+ # when "BACK"
1612
+ # surf_vector = get_parent("FLOOR").polygon.point_list[2] - zero
1613
+ # when "LEFT"
1614
+ # surf_vector = get_parent("FLOOR").polygon.point_list[3] - zero
1615
+ # end
1616
+ # space_xref = self.check_keyword?("X")? self.get_keyword_value("X").to_f : 0.0
1617
+ # space_yref = self.check_keyword?("Y")? self.get_keyword_value("Y").to_f : 0.0
1618
+ # space_zref = self.check_keyword?("Z")? self.get_keyword_value("Z").to_f : 0.0
1619
+ # space_origin = OpenStudio::Vector3d.new(space_xref,space_yref,space_zref)
1620
+ # space_origin = surf_vector + space_origin
1621
+ # else
1622
+ # space_xref = self.check_keyword?("X")? self.get_keyword_value("X").to_f : 0.0
1623
+ # space_yref = self.check_keyword?("Y")? self.get_keyword_value("Y").to_f : 0.0
1624
+ # space_zref = self.check_keyword?("Z")? self.get_keyword_value("Z").to_f : 0.0
1625
+ # space_origin = OpenStudio::Vector3d.new(space_xref,space_yref,space_zref)
1626
+ # end
1627
+ # return space_origin
1628
+ # end
1629
+ #
1630
+ # def get_azimuth()
1631
+ # angle = 0.0
1632
+ # #puts OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 0.0, 0.0), OpenStudio::Vector3d.new(1.0, 0.0, 0.0) ) )
1633
+ # if check_keyword?("LOCATION") and not check_keyword?("AZIMUTH")
1634
+ # case get_keyword_value("LOCATION")
1635
+ # when /FLOOR-\s*V\s*(.*)/
1636
+ # index = $1.strip.to_i - 1
1637
+ # point0 = self.get_parent("FLOOR").polygon.point_list[index]
1638
+ # point1 = self.get_parent("FLOOR").polygon.point_list[index + 1] ? get_parent("FLOOR").polygon.point_list[index + 1] : get_parent("FLOOR").polygon.point_list[0]
1639
+ # edge = point1-point0
1640
+ #
1641
+ #
1642
+ # sign = 1.0# OpenStudio::Vector3d.new(1.0, 0.0, 0.0).dot(( edge )) > 0 ? 1 :-1
1643
+ # angle = OpenStudio::radToDeg( sign * OpenStudio::getAngle(OpenStudio::Vector3d.new(1.0, 0.0, 0.0), ( point1 - point0 ) ) )
1644
+ #
1645
+ # #since get angle only get acute angles we need to get sign and completment for reflex angle
1646
+ # if edge.y > 0.0
1647
+ # angle = -1.0 * angle
1648
+ # end
1649
+ #
1650
+ # when "FRONT"
1651
+ # angle = OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("FLOOR").polygon.point_list[1] - get_parent("FLOOR").polygon.point_list[0] ) ) )
1652
+ # when "RIGHT"
1653
+ # angle = OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("FLOOR").polygon.point_list[2] - get_parent("FLOOR").polygon.point_list[1] ) ) )
1654
+ # when "BACK"
1655
+ # angle = OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("FLOOR").polygon.point_list[3] - get_parent("FLOOR").polygon.point_list[2] ) ) )
1656
+ # when "LEFT"
1657
+ # angle = OpenStudio::radToDeg( OpenStudio::getAngle(OpenStudio::Vector3d.new(0.0, 1.0, 0.0), ( get_parent("FLOOR").polygon.point_list[0] - get_parent("FLOOR").polygon.point_list[3] ) ) )
1658
+ # end
1659
+ # else
1660
+ # angle = self.check_keyword?("AZIMUTH")? self.get_keyword_value("AZIMUTH").to_f : 0.0
1661
+ # end
1662
+ # return angle
1663
+ # end
1664
+ #
1665
+ #
1666
+ # def get_transformation_matrix()
1667
+ # #This will transform the space vertices to normal space co-ordinates using Sketchup/OS convention
1668
+ # return OpenStudio::createTranslation(self.get_origin) * OpenStudio::Transformation::rotation(OpenStudio::Vector3d.new(0.0, 0.0, 1.0), OpenStudio::degToRad(360.0 - self.get_azimuth()))
1669
+ # end
1670
+ #
1671
+ # def get_rotation_matrix()
1672
+ # return OpenStudio::Transformation::rotation(OpenStudio::Vector3d.new(0.0, 0.0, 1.0), OpenStudio::degToRad(360.0 - self.get_azimuth()))
1673
+ # end
1674
+ #
1675
+ # def convert_to_openstudio(model,runner = nil)
1676
+ # if self.get_keyword_value("SHAPE") == "NO-SHAPE"
1677
+ # BTAP::runner_register("Info", "OpenStudio does not support NO-SHAPE SPACE definitions currently. Not importing the space #{self.name}.",runner)
1678
+ # else
1679
+ # os_space = OpenStudio::Model::Space.new(model)
1680
+ # os_space.setName(self.name)
1681
+ # #set floor
1682
+ # os_space.setBuildingStory(OpenStudio::Model::getBuildingStoryByName(model,self.get_parent("FLOOR").name).get)
1683
+ # BTAP::runner_register("Info", "\tSpace: " + self.name + " created",runner)
1684
+ # #puts "\t\t Azimuth:#{self.get_azimuth}"
1685
+ # #puts "\t\t Azimuth:#{self.get_origin}"
1686
+ # end
1687
+ # end
1688
+ #
1689
+ # end
1690
+ # class DOEFloor < DOESurface
1691
+ # attr_accessor :polygon
1692
+ # # a string object which defines the type of roof (e.g. attic)
1693
+ # attr_accessor :type
1694
+ # # The absorptance of the exterior surface of the floor
1695
+ # # (see rule #4.3.5.3.(6)
1696
+ # attr_accessor :absorptance
1697
+ # # thermal insulation of floors
1698
+ # attr_accessor :thermal_insulation
1699
+ #
1700
+ # def initialize
1701
+ # super()
1702
+ # end
1703
+ #
1704
+ # #This method returns the floor area
1705
+ # def get_area
1706
+ #
1707
+ # # get the keyword for the shape of the floor
1708
+ # case get_keyword_value("SHAPE")
1709
+ #
1710
+ # # if the keyword value is "BOX", the width and depth values are defined
1711
+ # when "BOX"
1712
+ # return get_keyword_value("WIDTH").to_f * get_keyword_value("DEPTH").to_f
1713
+ #
1714
+ # # if the keyword value is "POLYGON", the get_area is defined as the area of the
1715
+ # # given polygon
1716
+ # when "POLYGON"
1717
+ # return @polygon.get_area
1718
+ #
1719
+ # # if the keyword value of the floor is "No-SHAPE", the get_area is given as the
1720
+ # # get_area keyword value
1721
+ # when "NO-SHAPE"
1722
+ # return get_keyword_value("AREA").to_f
1723
+ # else
1724
+ # raise "Error: The area could not be evaluated. Please check inputs\n "
1725
+ # end
1726
+ # end
1727
+ #
1728
+ # # This method returns the volume of the floor space
1729
+ # def get_volume
1730
+ # return get_floor_height.to_f * get_area.to_f
1731
+ # end
1732
+ #
1733
+ # # gets the height of the floor
1734
+ # def get_height
1735
+ # return get_keyword_value("FLOOR-HEIGHT").to_f
1736
+ # end
1737
+ #
1738
+ # # gets the space height
1739
+ # def get_space_height
1740
+ # return get_keyword_value("SPACE-HEIGHT").to_f
1741
+ # end
1742
+ #
1743
+ # def get_origin()
1744
+ # space_xref = self.check_keyword?("X")? self.get_keyword_value("X").to_f : 0.0
1745
+ # space_yref = self.check_keyword?("Y")? self.get_keyword_value("Y").to_f : 0.0
1746
+ # space_zref = self.check_keyword?("Z")? self.get_keyword_value("Z").to_f : 0.0
1747
+ # return OpenStudio::Vector3d.new(space_xref,space_yref,space_zref)
1748
+ # end
1749
+ #
1750
+ # def get_azimuth()
1751
+ # return self.check_keyword?("AZIMUTH")? self.get_keyword_value("AZIMUTH").to_f : 0.0
1752
+ # end
1753
+ #
1754
+ # def get_transformation_matrix()
1755
+ # return OpenStudio::createTranslation(self.get_origin) * OpenStudio::Transformation::rotation(OpenStudio::Vector3d.new(0.0, 0.0, 1.0), OpenStudio::degToRad(360.0 - self.get_azimuth()))
1756
+ # end
1757
+ #
1758
+ # def get_rotation_matrix()
1759
+ # return OpenStudio::Transformation::rotation(OpenStudio::Vector3d.new(0.0, 0.0, 1.0), OpenStudio::degToRad(360.0 - self.get_azimuth()))
1760
+ # end
1761
+ #
1762
+ # def convert_to_openstudio(model,runner = nil)
1763
+ # floor = OpenStudio::Model::BuildingStory.new(model)
1764
+ # floor.setName(self.name)
1765
+ # BTAP::runner_register("Info", "\tBuildingStory: " + self.name + " created",runner)
1766
+ # end
1767
+ #
1768
+ # end
1769
+ # #This class makes it easier to deal with DOE Polygons.
1770
+ # class DOEPolygon < DOECommand
1771
+ #
1772
+ # attr_accessor :point_list
1773
+ #
1774
+ # #The constructor.
1775
+ # def initialize
1776
+ # super()
1777
+ # @point_list = Array.new()
1778
+ # #Convert Keywork Pairs to points.
1779
+ #
1780
+ # end
1781
+ #
1782
+ # def create_point_list()
1783
+ #
1784
+ # #Convert Keywork Pairs to points.
1785
+ # @point_list.clear
1786
+ # @keywordPairs.each do |array|
1787
+ #
1788
+ # array[1].match(/\(\s*(\-?\d*\.?\d*)\s*\,\s*(\-?\d*\.?\d*)\s*\)/)
1789
+ # #puts array[1]
1790
+ #
1791
+ # point = OpenStudio::Point3d.new($1.to_f,$2.to_f,0.0)
1792
+ # @point_list.push(point)
1793
+ # end
1794
+ # # @point_list.each do |p|
1795
+ # # puts p.x.to_s + " " + p.y.to_s + " " + p.z.to_s + " "
1796
+ # # end
1797
+ # end
1798
+ #
1799
+ # # This method returns the area of the polygon.
1800
+ # def get_area
1801
+ # openstudio::getArea(@points_list)
1802
+ # end
1803
+ #
1804
+ #
1805
+ # # This method must determine the length of the given point to the next point
1806
+ # # in the polygon list. If the point is the last point, then it will be the
1807
+ # # distance from the last point to the first.
1808
+ # # point_name is the string named keyword in the keyword pair list.
1809
+ # # Example:
1810
+ # # "DOEPolygon 2" = POLYGON
1811
+ # # V1 = ( 0, 0 )
1812
+ # # V2 = ( 0, 1 )
1813
+ # # V3 = ( 2, 1 )
1814
+ # # V4 = ( 2 ,0 )
1815
+ # # get_length(3) should return "2"
1816
+ # # get_length(2) should return "1"
1817
+ #
1818
+ # def get_length(point_index)
1819
+ # if @points_list.size < pointindex + 2
1820
+ # return OpenStudio::getDistance(@point_list[0],@point_list.last)
1821
+ # else
1822
+ # return OpenStudio::getDistance(@point_list[point_index],@point_list[point_index + 1] )
1823
+ # end
1824
+ # end
1825
+ #
1826
+ #
1827
+ # def get_azimuth(point_index)
1828
+ # if @points_list.size < pointindex + 2
1829
+ # return OpenStudio::radToDeg(OpenStudio::getAngle(@point_list.last - @point_list[0] , openstudio::Vector3d( 1.0, 0.0, 0.0)))
1830
+ # else
1831
+ # return OpenStudio::radToDeg(OpenStudio::getAngle(@point_list[point_index + 1] - @point_list[point_index] , openstudio::Vector3d( 1.0, 0.0, 0.0)))
1832
+ # end
1833
+ # end
1834
+ #
1835
+ # end
1836
+ # class DOELayer < DOECommand
1837
+ # # type of material (see rule #4.3.5.2.(3))
1838
+ # attr_accessor :material
1839
+ # # the thickness of the material (see rule #4.3.5.2.(3))
1840
+ # attr_accessor :thickness
1841
+ # def initialize
1842
+ # super()
1843
+ # end
1844
+ # end
1845
+ # class DOEMaterial < DOECommand
1846
+ # # characteristics of the materials
1847
+ # attr_accessor :density
1848
+ # attr_accessor :specific_heat
1849
+ # attr_accessor :thermal_conductivity
1850
+ # def initialize
1851
+ # super()
1852
+ # end
1853
+ # end
1854
+ # class DOEConstruction < DOECommand
1855
+ #
1856
+ # def initialize
1857
+ # super()
1858
+ # end
1859
+ #
1860
+ # def get_materials()
1861
+ # bdllib = DOE2::DOEBDLlib.instance
1862
+ # materials = Array.new
1863
+ #
1864
+ # case self.get_keyword_value("TYPE")
1865
+ # when "LAYERS"
1866
+ # # finds the command associated with the layers keyword
1867
+ # layers_command = building.find_command_with_utype( self.get_keyword_value("LAYERS") )
1868
+ #
1869
+ # #if Layres command cannot be found in the inp file... find it in the bdl database.
1870
+ # layers_command = bdllib.find_layer(self.get_keyword_value("LAYERS")) unless layers_command.length == 1
1871
+ #
1872
+ # # if there ends up to be more than one command with the layers keyword
1873
+ # # raise an exception
1874
+ # raise "Layers was defined more than once " + self.get_keyword_value("LAYERS").to_s if layers_command.length > 1
1875
+ #
1876
+ # # get all the materials, separate it by the quotation marks and push it
1877
+ # # onto the materials array
1878
+ # layers_command[0].get_keyword_value("MATERIAL").scan(/(\".*?\")/).each do |material|
1879
+ # material_command = ""
1880
+ #
1881
+ # #Try to find material in doe model.
1882
+ # material_command_array = building.find_command_with_utype(material.to_s.strip)
1883
+ #
1884
+ # # if there ends up to be more than one, raise an exception
1885
+ # raise "Material was defined more than once #{material}" if material_command_array.length > 1
1886
+ #
1887
+ # # if the material cannot be found within the model, find it within the doe2 database
1888
+ # material_command = bdllib.find_material(material) if material_command_array.length < 1
1889
+ #
1890
+ # #If material was found then set it.
1891
+ # material_command = material_command_array[0] if material_command_array.length == 1
1892
+ #
1893
+ # materials.push(material_command)
1894
+ # end
1895
+ # return materials
1896
+ # when "U-VALUE"
1897
+ # return nil
1898
+ # end
1899
+ # end
1900
+ #
1901
+ # # This method finds the u-value of the given construction
1902
+ # # Output => total conductivity as a float
1903
+ # def get_u_value()
1904
+ # total_conductivity = 0.0
1905
+ # case self.get_keyword_value("TYPE")
1906
+ # when "LAYERS"
1907
+ # self.get_materials().each do |material_command|
1908
+ # case material_command.get_keyword_value("TYPE")
1909
+ # when "RESISTANCE"
1910
+ # conductivity = 1 / material_command.get_keyword_value("RESISTANCE").to_f
1911
+ # when "PROPERTIES"
1912
+ # conductivity = material_command.get_keyword_value("CONDUCTIVITY").to_f
1913
+ # else
1914
+ # raise "Error in material properties"
1915
+ # end
1916
+ # total_conductivity = total_conductivity + conductivity
1917
+ # end
1918
+ # return total_conductivity
1919
+ # when "U-VALUE"
1920
+ # return self.get_keyword_value("U-VALUE").to_f
1921
+ # end
1922
+ # end
1923
+ #
1924
+ #
1925
+ # end
1926
+ # class DOECommandFactory
1927
+ # def initialize
1928
+ #
1929
+ # end
1930
+ #
1931
+ # def DOECommandFactory.command_factory(command_string, building)
1932
+ #
1933
+ # command = ""
1934
+ # command_name = ""
1935
+ # if (command_string != "")
1936
+ # #Get command and u-value
1937
+ # if ( command_string.match(/(^\s*(\".*?\")\s*\=\s*(\S+)\s*)/) )
1938
+ # command_name=$3.strip
1939
+ # else
1940
+ # # if no u-value, get just the command.
1941
+ # command_string.match(/(^\s*(\S*)\s)/ )
1942
+ # @command_name=$2.strip
1943
+ #
1944
+ # end
1945
+ # end
1946
+ # case command_name
1947
+ # when "ZONE" then
1948
+ # command = DOEZone.new()
1949
+ # when "FLOOR" then
1950
+ # command = DOEFloor.new()
1951
+ # when "SPACE" then
1952
+ # command = DOESpace.new()
1953
+ # when "EXTERIOR-WALL" then
1954
+ # command = DOEExteriorWall.new()
1955
+ # when "INTERIOR-WALL" then
1956
+ # command = DOESurface.new()
1957
+ # when "UNDERGROUND-WALL" then
1958
+ # command = DOESurface.new()
1959
+ # when "ROOF" then
1960
+ # command = DOERoof.new()
1961
+ # when "WINDOW" then
1962
+ # command = DOESubSurface.new()
1963
+ # when "DOOR" then
1964
+ # command = DOESubSurface.new()
1965
+ # when "POLYGON" then
1966
+ # command = DOEPolygon.new()
1967
+ # when "LAYER" then
1968
+ # command = DOELayer.new()
1969
+ # when "MATERIAL" then
1970
+ # command = DOEMaterial.new()
1971
+ # when "CONSTRUCTION" then
1972
+ # command = DOEConstruction.new()
1973
+ # else
1974
+ # command = DOECommand.new()
1975
+ # end
1976
+ #
1977
+ # command.get_command_from_string(command_string)
1978
+ # command.building = building
1979
+ # return command
1980
+ # end
1981
+ # end
1982
+ #
1983
+ # # This is the main interface dealing with DOE inp files. You can load, save
1984
+ # # manipulate doe files with this interface at a command level.
1985
+ # class DOEBuilding
1986
+ #
1987
+ # #An array to contain all the DOE
1988
+ # attr_accessor :commands
1989
+ # #An array to contain the current parent when reading in the input files.
1990
+ # attr_accessor :parents
1991
+ #
1992
+ #
1993
+ # # This method makes a deep copy of the building object.
1994
+ # def clone
1995
+ # return Marshal::load(Marshal.dump(self))
1996
+ # end
1997
+ #
1998
+ # # The Constructor.
1999
+ # def initialize
2000
+ #
2001
+ # @commands=[]
2002
+ # @parents=[]
2003
+ # @commandList = Array.new()
2004
+ #
2005
+ # end
2006
+ #
2007
+ # # This method will find all Commands given the command name string.
2008
+ # # Example
2009
+ # # def find_all_Command("ZONE") will return an array of all the ZONE commands
2010
+ # # used in the building.
2011
+ # def find_all_commands (sCOMMAND)
2012
+ # array = Array.new()
2013
+ # @commands.each do |command|
2014
+ # if (command.commandName == sCOMMAND)
2015
+ # array.push(command)
2016
+ # end
2017
+ # end
2018
+ # return array
2019
+ # end
2020
+ #
2021
+ # # This method will find all Commands given the command name string.
2022
+ # # Example
2023
+ # # def find_all_Command("Default Construction") will return an array of all
2024
+ # # the commands with "Default Construction" as the u-type used in the building.
2025
+ # def find_command_with_utype (utype)
2026
+ # array = Array.new()
2027
+ # @commands.each do |command|
2028
+ # if (command.utype == utype)
2029
+ # array.push(command)
2030
+ # end
2031
+ # end
2032
+ # return array
2033
+ # end
2034
+ #
2035
+ #
2036
+ # # Same as find_all_commands except you can use regular expressions.
2037
+ # def find_all_regex(sCOMMAND)
2038
+ # array = Array.new()
2039
+ # search =/#{sCOMMAND}/
2040
+ # @commands.each do |command|
2041
+ # if (command.commandName.match(search) )
2042
+ # array.push(command)
2043
+ # end
2044
+ #
2045
+ # end
2046
+ # return array
2047
+ # end
2048
+ #
2049
+ # # Find a matching keyword value pair in from an array of commands.
2050
+ # # Example:
2051
+ # # find_keyword_value(building.commands, "TYPE", "CONDITIONED") will return
2052
+ # # all the commands that have the
2053
+ # # TYPE = CONDITIONED"
2054
+ # # Keyword pair.
2055
+ # def search_by_keyword_value( keyword, value)
2056
+ # returnarray = Array.new()
2057
+ # @commands.each do |command|
2058
+ # if ( command.keywordPairs[keyword] == value )
2059
+ # returnarray.push(command)
2060
+ # end
2061
+ # end
2062
+ # return returnarray
2063
+ # end
2064
+ #
2065
+ #
2066
+ # # Will read an input file into memory and store all the commands into the
2067
+ # # commands array.
2068
+ # # param filename
2069
+ # # param runner
2070
+ # def load_inp(filename,runner = nil)
2071
+ # BTAP::runner_register("Info", "loading file:" + filename, runner)
2072
+ # #Open the file.
2073
+ # #puts filename
2074
+ # iter = 0
2075
+ #
2076
+ #
2077
+ # File.exist?(filename)
2078
+ # f = File.open(filename, "r")
2079
+ #
2080
+ #
2081
+ #
2082
+ #
2083
+ # #Read the file into an array, line by line.
2084
+ # lines = f.readlines
2085
+ # #Set up the temp string.
2086
+ # command_string =""
2087
+ #
2088
+ # lines.each do|line|
2089
+ # iter = iter.next
2090
+ # #line.forced_encoding("US-ASCII")
2091
+ # #Ignore comments (To do!...strip from file as well as in-line comments.
2092
+ # if (!line.match(/\$.*/) )
2093
+ #
2094
+ # if (myarray = line.match(/(.*?)\.\./) )
2095
+ # #Add the last part of the command to the newline...may be blank."
2096
+ # command_string = command_string + myarray[1]
2097
+ # #Determine correct command class to create, then populates it."
2098
+ # command = DOECommandFactory.command_factory(command_string, self)
2099
+ # #Push the command into the command array."
2100
+ # @commands.push(command)
2101
+ # command_string = ""
2102
+ # else
2103
+ # myarray = line.match(/(.*)/)
2104
+ # command_string = command_string + myarray[1]
2105
+ # end
2106
+ # end
2107
+ # end
2108
+ #
2109
+ # organize_data()
2110
+ # BTAP::runner_register("Info","INP model contains:", runner)
2111
+ # #report number of things read in.
2112
+ # ["SPACE","ZONE","EXTERIOR-WALL","ROOF","INTERIOR-WALL","UNDERGROUND-WALL","WINDOW","DOOR","MATERIAL","CONSTRUCTION"].each do |item|
2113
+ # items = self.find_all_commands(item)
2114
+ # message = "\t#{item} = #{items.size}"
2115
+ # BTAP::runner_register("Info",message, runner)
2116
+ # end
2117
+ # BTAP::runner_register("Info", "\tFinished Loading File:" + filename,runner)
2118
+ # end
2119
+ #
2120
+ #
2121
+ #
2122
+ # # This will right a clean output file, meaning no comments. Good for doing
2123
+ # # diffs
2124
+ # def save_inp(string)
2125
+ # array = @commands
2126
+ # w = File.open(string, 'w')
2127
+ # array.each { |command| w.print command.output }
2128
+ # w.close
2129
+ # end
2130
+ #
2131
+ #
2132
+ #
2133
+ #
2134
+ #
2135
+ # #This routine organizes the hierarchy of the space <-> zones and the polygon
2136
+ # # associations that are not formally identified by the sequential relationship
2137
+ # # like the floor, walls, windows. It would seem that zones and spaces are 1 to
2138
+ # # one relationships. So each zone will have a reference to its space and vice versa.
2139
+ # # If there is a polygon command in the space or floor definition, a reference to the
2140
+ # # polygon class will be set.
2141
+ # def organize_data()
2142
+ # # set_envelope_hierarchy
2143
+ # # This method determines the current parents of the current command.
2144
+ # def determine_current_parents(new_command)
2145
+ # if @last_command.nil?
2146
+ # @last_command = new_command
2147
+ # end
2148
+ # #Check to see if scope (HVAC versus Envelope) has changed or the parent depth is undefined "0"
2149
+ # if (!@parents.empty? and (new_command.doe_scope != @parents.last.doe_scope or new_command.depth == 0 ))
2150
+ # @parents.clear
2151
+ # end
2152
+ # #no change in parent.
2153
+ # if ( (new_command.depth == @last_command.depth))
2154
+ # #no change
2155
+ # @last_command = new_command
2156
+ # #puts "#{new_command.commandName}"
2157
+ # end
2158
+ # #Parent depth added
2159
+ # if ( new_command.depth > @last_command.depth)
2160
+ # @parents.push(@last_command)
2161
+ # #puts "Added parent#{@last_command.commandName}"
2162
+ # @last_command = new_command
2163
+ # end
2164
+ # #parent depth removed.
2165
+ # if ( new_command.depth < @last_command.depth)
2166
+ # parent = @parents.pop
2167
+ # #puts "Removed parent #{parent}"
2168
+ # @last_command = new_command
2169
+ # end
2170
+ # array = Array.new(@parents)
2171
+ # return array
2172
+ # end
2173
+ #
2174
+ #
2175
+ # @commands.each do |command|
2176
+ # if command.doe_scope() == "envelope"
2177
+ # #Sets parents of command.
2178
+ # parents = determine_current_parents(command)
2179
+ # if (!parents.empty?)
2180
+ # command.parents = parents
2181
+ # end
2182
+ # #inserts current command into the parent's children.
2183
+ # if (!command.parents.empty?)
2184
+ # command.parents.last.children.push(command)
2185
+ # end
2186
+ # end
2187
+ # end
2188
+ # # Associating the polygons with the FLoor and spaces.
2189
+ # polygons = find_all_commands("POLYGON")
2190
+ # spaces = find_all_commands("SPACE")
2191
+ # floors = find_all_commands("FLOOR")
2192
+ # zones = find_all_commands("ZONE")
2193
+ # ext_walls = find_all_commands("EXTERIOR-WALL")
2194
+ # roof = find_all_commands("ROOF")
2195
+ # door = find_all_commands("DOOR")
2196
+ # int_walls = find_all_commands("INTERIOR-WALL")
2197
+ # underground_walls = find_all_commands("UNDERGROUND-WALL")
2198
+ # underground_floors = find_all_commands("UNDERGROUND-FLOOR")
2199
+ # constructions =find_all_commands("CONSTRUCTION")
2200
+ # surface_lists = [ ext_walls, roof, door, int_walls, underground_walls, underground_floors]
2201
+ #
2202
+ #
2203
+ # #Organize surface data.
2204
+ # surface_lists.each do |surfaces|
2205
+ # surfaces.each do |surface|
2206
+ # #Assign constructions to surface objects
2207
+ # constructions.each do |construction|
2208
+ # if ( construction.utype == surface.get_keyword_value("CONSTRUCTION") )
2209
+ # surface.construction = construction
2210
+ # end
2211
+ # end
2212
+ # #Find Polygons associated with surface.
2213
+ # polygons.each do |polygon|
2214
+ # if ( surface.check_keyword?("POLYGON") and polygon.utype == surface.get_keyword_value("POLYGON") )
2215
+ # surface.polygon = polygon
2216
+ # end
2217
+ # end
2218
+ # end
2219
+ # end
2220
+ #
2221
+ #
2222
+ #
2223
+ # #Organize polygon data for space and floors.
2224
+ # polygons.each do |polygon|
2225
+ # #set up point list in polygon objects
2226
+ # polygon.create_point_list()
2227
+ # #Find Polygons associated with floor and and reference to floor.
2228
+ # floors.each do |floor|
2229
+ # if ( polygon.utype == floor.get_keyword_value("POLYGON") )
2230
+ # floor.polygon = polygon
2231
+ # end
2232
+ # end
2233
+ # #Find Polygons for space and add reference to the space.
2234
+ # spaces.sort.each do |space|
2235
+ # if space.check_keyword?("POLYGON")
2236
+ # if ( polygon.utype == space.get_keyword_value("POLYGON") )
2237
+ # space.polygon = polygon
2238
+ # end
2239
+ # end
2240
+ # end
2241
+ # end
2242
+ #
2243
+ #
2244
+ #
2245
+ # # Find spaces that belong to the zone.
2246
+ # zones.each do |zone|
2247
+ # spaces.sort.each do |space|
2248
+ # if ( space.utype == zone.get_keyword_value("SPACE") )
2249
+ # space.zone = zone
2250
+ # zone.space = space
2251
+ # end
2252
+ # end
2253
+ # end
2254
+ # end
2255
+ #
2256
+ #
2257
+ #
2258
+ # def get_building_transformation_matrix()
2259
+ # build_params = self.find_all_commands("BUILD-PARAMETERS")[0]
2260
+ # building_xref = build_params.check_keyword?("X-REF")? build_params.get_keyword?("X-REF") : 0.0
2261
+ # building_yref = build_params.check_keyword?("Y-REF")? build_params.get_keyword?("Y-REF") : 0.0
2262
+ # building_origin = OpenStudio::Vector3d.new(building_xref,building_yref,0.0)
2263
+ # building_azimuth = build_params.check_keyword?("AZIMUTH")? build_params.get_keyword?("AZIMUTH") : 0.0
2264
+ # return OpenStudio::Transformation::rotation(OpenStudio::Vector3d(0.0, 0.0, 1.0), openstudio::degToRad(building_azimuth)) * OpenStudio::Transformation::translation(building_origin)
2265
+ # end
2266
+ #
2267
+ #
2268
+ #
2269
+ #
2270
+ # #this method will convert a DOE inp file to the OSM file.. This will return
2271
+ # # and openstudio model object.
2272
+ # def create_openstudio_model_new(runner = nil)
2273
+ # beginning_time = Time.now
2274
+ #
2275
+ # end_time = Time.now
2276
+ # BTAP::runner_register("Info", "Time elapsed #{(end_time - beginning_time)*1000} milliseconds",runner)
2277
+ # model = OpenStudio::Model::Model.new()
2278
+ # #add All Materials
2279
+ # # find_all_commands( "Materials" ).each do |doe_material|
2280
+ # # end
2281
+ # #
2282
+ # # find_all_commands( "Constructions" ).each do |doe_cons|
2283
+ # # end
2284
+ #
2285
+ # #this block will create OS story objects in the OS model.
2286
+ # BTAP::runner_register("Info", "Exporting DOE FLOORS to OS",runner)
2287
+ # find_all_commands("FLOOR").each do |doe_floor|
2288
+ # doe_floor.convert_to_openstudio(model)
2289
+ # end
2290
+ # BTAP::runner_register("Info", OpenStudio::Model::getBuildingStorys(model).size.to_s + " floors created",runner)
2291
+ #
2292
+ # #this block will create OS space objects in the OS model.
2293
+ # BTAP::runner_register("Info", "Exporting DOE SPACES to OS",runner)
2294
+ # find_all_commands("SPACE").each do |doe_space|
2295
+ # doe_space.convert_to_openstudio(model)
2296
+ # end
2297
+ # BTAP::runner_register("Info", OpenStudio::Model::getSpaces(model).size.to_s + " spaces created",runner)
2298
+ #
2299
+ # #this block will create OS space objects in the OS model.
2300
+ # BTAP::runner_register("Info", "Exporting DOE ZONES to OS",runner)
2301
+ # find_all_commands("ZONE").each do |doe_zone|
2302
+ # doe_zone.convert_to_openstudio(model)
2303
+ # end
2304
+ # BTAP::runner_register("Info", OpenStudio::Model::getThermalZones(model).size.to_s + " zones created",runner)
2305
+ #
2306
+ # #this block will create OS surface objects in the OS model.
2307
+ # BTAP::runner_register("Info", "Exporting DOE Surfaces to OS",runner)
2308
+ # all_surfaces = Array.new()
2309
+ # @commands.each do |command|
2310
+ # case command.commandName
2311
+ # when "EXTERIOR-WALL","INTERIOR-WALL","UNDERGROUND-WALL","ROOF"
2312
+ # all_surfaces.push(command)
2313
+ # end
2314
+ # end
2315
+ # all_surfaces.each do |doe_surface|
2316
+ # doe_surface.convert_to_openstudio(model)
2317
+ # end
2318
+ # BTAP::runner_register("Info", OpenStudio::Model::getSurfaces(model).size.to_s + " surfaces created",runner)
2319
+ # BTAP::runner_register("Info", OpenStudio::Model::getSubSurfaces(model).size.to_s + " sub_surfaces created",runner)
2320
+ # BTAP::runner_register("Info", "Setting Boundary Conditions for surfaces",runner)
2321
+ # BTAP::Geometry::match_surfaces(model)
2322
+ #
2323
+ # x_scale = y_scale = z_scale = 0.3048
2324
+ # BTAP::runner_register("Info", "scaling model from feet to meters",runner)
2325
+ # model.getPlanarSurfaces.sort.each do |surface|
2326
+ # new_vertices = OpenStudio::Point3dVector.new
2327
+ # surface.vertices.each do |vertex|
2328
+ # new_vertices << OpenStudio::Point3d.new(vertex.x * x_scale, vertex.y * y_scale, vertex.z * z_scale)
2329
+ # end
2330
+ # surface.setVertices(new_vertices)
2331
+ # end
2332
+ #
2333
+ # model.getPlanarSurfaceGroups.sort.each do |surface_group|
2334
+ # transformation = surface_group.transformation
2335
+ # translation = transformation.translation
2336
+ # euler_angles = transformation.eulerAngles
2337
+ # new_translation = OpenStudio::Vector3d.new(translation.x * x_scale, translation.y * y_scale, translation.z * z_scale)
2338
+ # #TODO these might be in the wrong order
2339
+ # new_transformation = OpenStudio::createRotation(euler_angles) * OpenStudio::createTranslation(new_translation)
2340
+ # surface_group.setTransformation(new_transformation)
2341
+ # end
2342
+ # BTAP::runner_register("Info", "DOE2.2 -> OS Geometry Conversion Complete",runner)
2343
+ # BTAP::runner_register("Info", "Summary of Conversion",runner)
2344
+ # BTAP::runner_register("Info", OpenStudio::Model::getBuildingStorys(model).size.to_s + " floors created",runner)
2345
+ # BTAP::runner_register("Info", OpenStudio::Model::getSpaces(model).size.to_s + " spaces created",runner)
2346
+ # BTAP::runner_register("Info", OpenStudio::Model::getThermalZones(model).size.to_s + " thermal zones created",runner)
2347
+ # BTAP::runner_register("Info", OpenStudio::Model::getSurfaces(model).size.to_s + " surfaces created",runner)
2348
+ # BTAP::runner_register("Info", OpenStudio::Model::getSubSurfaces(model).size.to_s + " sub_surfaces created",runner)
2349
+ # BTAP::runner_register("Info", "No Contruction were converted.",runner)
2350
+ # BTAP::runner_register("Info", "No Materials were converted",runner)
2351
+ # BTAP::runner_register("Info", "No HVAC components were converted",runner)
2352
+ # BTAP::runner_register("Info", "No Environment or Simulation setting were converted.",runner)
2353
+ #
2354
+ # end_time = Time.now
2355
+ # BTAP::runner_register("Info", "Time elapsed #{(end_time - beginning_time)} seconds",runner)
2356
+ # return model
2357
+ # end
2358
+ #
2359
+ #
2360
+ #
2361
+ #
2362
+ #
2363
+ # def get_materials()
2364
+ # BTAP::runner_register("Info", "Spaces",runner)
2365
+ # find_all_commands("SPACE").each do |space|
2366
+ # BTAP::runner_register("Info", space.get_azimuth(),runner)
2367
+ # end
2368
+ # BTAP::runner_register("Info", "Materials",runner)
2369
+ # find_all_commands("MATERIAL").each do |materials|
2370
+ # BTAP::runner_register("Info", materials.get_name(),runner)
2371
+ # end
2372
+ # BTAP::runner_register("Info", "Layers",runner)
2373
+ # find_all_commands("LAYERS").each do |materials|
2374
+ # BTAP::runner_register("Info", materials.get_name(),runner)
2375
+ # end
2376
+ # BTAP::runner_register("Info", "Constructions",runner)
2377
+ # find_all_commands("CONSTRUCTION").each do |materials|
2378
+ # BTAP::runner_register("Info", materials.get_name(),runner)
2379
+ # end
2380
+ #
2381
+ # end
2382
+ #
2383
+ #
2384
+ # end
2385
+ # # This class will manage all the layer information of the Reference components.
2386
+ # class LayerManager
2387
+ # include Singleton
2388
+ # class Layer
2389
+ #
2390
+ # attr_accessor :name
2391
+ # attr_accessor :thickness
2392
+ # attr_accessor :conductivity
2393
+ # attr_accessor :density
2394
+ # attr_accessor :specific_heat
2395
+ # attr_accessor :air_space
2396
+ # attr_accessor :resistance
2397
+ # def initialize
2398
+ # @air_space = false
2399
+ # end
2400
+ #
2401
+ # def set( thickness, conductivity, density, specific_heat)
2402
+ # @thickness, @conductivity, @density, @specific_heat = thickness, conductivity, density, specific_heat
2403
+ # @airspace = false
2404
+ # end
2405
+ #
2406
+ # def set_air_space(thickness, resistance)
2407
+ # @thickness, @resistance = thickness, resistance
2408
+ # @air_space = true
2409
+ # end
2410
+ #
2411
+ # def output
2412
+ # string = "Airspace = #{@air_space}\nThickness = #{@thickness}\nConductivity = #{@conductivity}\nResistance = #{@resistance}\nDensity = #{@density}\nSpecificHeat = #{@specific_heat}\n"
2413
+ # end
2414
+ # end
2415
+ # # Array of all the layers
2416
+ # attr_accessor :layers
2417
+ # def initialize
2418
+ # @layers = Array.new()
2419
+ # end
2420
+ #
2421
+ # #Add a layer. If the layer already exists. It will return the exi
2422
+ # def add_layer(new_layer)
2423
+ # #first determine if the layer already exists.
2424
+ # @layers.each do |current_layer|
2425
+ # if new_layer == current_layer
2426
+ # return current_layer
2427
+ # end
2428
+ # end
2429
+ # @layers.push(new_layer)
2430
+ # return @layers.last()
2431
+ # end
2432
+ #
2433
+ # private
2434
+ #
2435
+ # def clear()
2436
+ # @layers.clear()
2437
+ # end
2438
+ # end
2439
+ # #This class manages all of the constructions that are used in the simulation. It
2440
+ # #should remove any constructions that are doubly defined in the project.
2441
+ # class ConstructionManager
2442
+ # # An array containing all the constructions.
2443
+ # attr_accessor :constructions
2444
+ #
2445
+ # # The layer manager all the constructions.
2446
+ # attr_accessor :layer_manager
2447
+ # class Construction
2448
+ #
2449
+ # #The unique name for the construction.
2450
+ # attr_accessor :name
2451
+ # #The array which contains the material layers of the construction.
2452
+ # attr_accessor :layers
2453
+ #
2454
+ # def initialize
2455
+ # #Set up the array for the layers.
2456
+ # @layers = Array.new()
2457
+ # end
2458
+ #
2459
+ # #Adds a layer object to the construction.
2460
+ # # Must pass a Layer object as an arg.
2461
+ # def add_layer_object( object )
2462
+ # layers.push( object )
2463
+ # end
2464
+ #
2465
+ # #Adds a layer based on the physical properties list.
2466
+ # #All units are based on the simulators input.
2467
+ # def add_layer(thickness, conductivity, density, specific_heat)
2468
+ # layer = Layer.new()
2469
+ # # Make sure all the values are > 0.
2470
+ # layer.set(thickness, conductivity, density, specific_heat)
2471
+ # @layers.push(layer)
2472
+ # end
2473
+ #
2474
+ # # Adds an airspace to the construction based on the thickness and Resistances.
2475
+ # #All units are based on the simulators input.
2476
+ # def add_air_space(thickness, resistance )
2477
+ # layer = Layer.new()
2478
+ # layer.set_air_space(thickness, resistance)
2479
+ # @layers.push(layer)
2480
+ # end
2481
+ #
2482
+ # def output()
2483
+ # soutput = ""
2484
+ # @layers.each do|layer|
2485
+ # soutput = soutput + layer.output() + "\n"
2486
+ # end
2487
+ # soutput
2488
+ # end
2489
+ # end
2490
+ #
2491
+ #
2492
+ # def initialize
2493
+ # @constructions = Array.new()
2494
+ # @layer_manager = LayerManager.instance()
2495
+ # end
2496
+ #
2497
+ #
2498
+ # #Adds a new construction to the construction array.
2499
+ # #Arg must be a construction object.
2500
+ # def add_construction(new_construction)
2501
+ # #first determine if the layer already exists.
2502
+ # @constructions.each do |current_construction|
2503
+ # if new_construction == current_construction
2504
+ # return current_construction
2505
+ # end
2506
+ # end
2507
+ # new_construction.layers.each do |new_layer|
2508
+ # #If the new layer already exists...use the old one instead.
2509
+ # # it is the layerManager's job to decide this.
2510
+ # new_layer = @layer_manager.add_layer(new_layer)
2511
+ # end
2512
+ # @constructions.push(new_construction)
2513
+ # return @constructions.last()
2514
+ # end
2515
+ #
2516
+ # def clear()
2517
+ # @constructions.clear()
2518
+ # @layer_manager.clear()
2519
+ # end
2520
+ #
2521
+ # end
2522
+ # end
2523
+ # end
2524
+ #