urbanopt-cli 0.4.1 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (944) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/CHANGELOG.md +59 -0
  4. data/CMakeLists.txt +17 -17
  5. data/FindOpenStudioSDK.cmake +12 -7
  6. data/Gemfile +8 -10
  7. data/LICENSE.md +11 -1
  8. data/README.md +1 -0
  9. data/Rakefile +16 -6
  10. data/example_files/Gemfile +25 -9
  11. data/example_files/example_project.json +35 -20
  12. data/example_files/example_project_combined.json +100 -5
  13. data/example_files/example_project_with_electric_network.json +2116 -0
  14. data/example_files/mappers/Baseline.rb +111 -51
  15. data/example_files/mappers/CreateBar.rb +19 -7
  16. data/example_files/mappers/EvCharging.rb +141 -0
  17. data/example_files/mappers/Floorspace.rb +29 -17
  18. data/example_files/mappers/HighEfficiency.rb +20 -8
  19. data/example_files/mappers/HighEfficiencyCreateBar.rb +19 -8
  20. data/example_files/mappers/HighEfficiencyFloorspace.rb +19 -8
  21. data/example_files/mappers/ThermalStorage.rb +16 -6
  22. data/example_files/mappers/base_workflow.osw +26 -1
  23. data/example_files/mappers/floorspace_workflow.osw +9 -0
  24. data/example_files/measures/BuildResidentialModel/measure.rb +249 -134
  25. data/example_files/reopt/base_assumptions.json +2 -2
  26. data/example_files/reopt/multiPV_assumptions.json +4 -3
  27. data/example_files/residential/clothes_dryer.tsv +7 -7
  28. data/example_files/residential/clothes_washer.tsv +2 -2
  29. data/example_files/residential/cooling_system.tsv +42 -22
  30. data/example_files/residential/dishwasher.tsv +1 -1
  31. data/example_files/residential/exhaust.tsv +3 -0
  32. data/example_files/residential/heat_pump.tsv +62 -40
  33. data/example_files/residential/water_heater.tsv +1 -1
  34. data/example_files/resources/hpxml-measures/.github/pull_request_template.md +14 -0
  35. data/example_files/resources/hpxml-measures/.github/workflows/config.yml +116 -0
  36. data/example_files/resources/hpxml-measures/.gitignore +1 -8
  37. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.rb +1088 -1329
  38. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.xml +1819 -1383
  39. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/constants.rb +0 -8
  40. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb +450 -362
  41. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules.rb +165 -112
  42. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_config.json +388 -0
  43. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_config.md +43 -0
  44. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_weekday_state_and_monthly_schedule_shift.csv +613 -0
  45. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_weekend_state_and_monthly_schedule_shift.csv +613 -0
  46. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-coal.osw +56 -82
  47. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{base-appliances-dehumidifier-ief.osw → base-appliances-dehumidifier-ief-portable.osw} +57 -83
  48. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{base-appliances-dehumidifier-50percent.osw → base-appliances-dehumidifier-ief-whole-home.osw} +59 -85
  49. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-dehumidifier.osw +56 -82
  50. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-gas.osw +56 -82
  51. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-modified.osw +56 -82
  52. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-none.osw +61 -87
  53. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-oil.osw +56 -82
  54. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-propane.osw +56 -82
  55. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-wood.osw +56 -82
  56. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-flat.osw +56 -82
  57. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-radiant-barrier.osw +56 -82
  58. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-unvented-insulated-roof.osw +56 -82
  59. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-vented.osw +56 -82
  60. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-boiler-only-baseboard.osw +341 -0
  61. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-boiler-only-fan-coil.osw +341 -0
  62. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-mechvent-shared-preconditioning.osw → base-bldgtype-multifamily-shared-mechvent-preconditioning.osw} +70 -95
  63. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-mechvent-shared.osw → base-bldgtype-multifamily-shared-mechvent.osw} +70 -95
  64. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-pv.osw +341 -0
  65. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-water-heater.osw +341 -0
  66. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily.osw +341 -0
  67. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{base-single-family-attached.osw → base-bldgtype-single-family-attached.osw} +59 -85
  68. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-combi-tankless-outside.osw +56 -82
  69. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-combi-tankless.osw +56 -82
  70. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-dwhr.osw +56 -82
  71. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect-outside.osw +56 -82
  72. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect-standbyloss.osw +56 -82
  73. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect-with-solar-fraction.osw +56 -82
  74. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect.osw +56 -82
  75. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-electric.osw +56 -82
  76. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-gas.osw +56 -82
  77. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-hpwh.osw +56 -82
  78. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-indirect.osw +56 -82
  79. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-low-flow-fixtures.osw +56 -82
  80. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-none.osw +57 -83
  81. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-demand.osw +56 -82
  82. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-manual.osw +56 -82
  83. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-nocontrol.osw +56 -82
  84. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-temperature.osw +56 -82
  85. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-timer.osw +56 -82
  86. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-direct-evacuated-tube.osw +56 -82
  87. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-direct-flat-plate.osw +56 -82
  88. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-direct-ics.osw +56 -82
  89. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-fraction.osw +56 -82
  90. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-indirect-flat-plate.osw +56 -82
  91. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-thermosyphon-flat-plate.osw +56 -82
  92. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-coal.osw +56 -82
  93. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-elec-uef.osw +338 -0
  94. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-gas-outside.osw +56 -82
  95. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-gas-uef.osw +338 -0
  96. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-gas.osw +56 -82
  97. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-outside.osw +56 -82
  98. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-uef.osw +338 -0
  99. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-with-solar-fraction.osw +56 -82
  100. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-with-solar.osw +56 -82
  101. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump.osw +56 -82
  102. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-oil.osw +56 -82
  103. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-wood.osw +56 -82
  104. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-electric-outside.osw +56 -83
  105. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-electric-uef.osw +337 -0
  106. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-electric.osw +56 -82
  107. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas-uef.osw +337 -0
  108. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas-with-solar-fraction.osw +56 -82
  109. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas-with-solar.osw +56 -82
  110. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas.osw +56 -82
  111. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-propane.osw +56 -82
  112. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-2stories-garage.osw +56 -82
  113. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-2stories.osw +56 -82
  114. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-1.osw +56 -82
  115. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-2.osw +56 -82
  116. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-4.osw +56 -82
  117. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-5.osw +56 -82
  118. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-garage.osw +56 -82
  119. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-ach-house-pressure.osw +56 -82
  120. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-cfm-house-pressure.osw +56 -82
  121. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-cfm50.osw +56 -82
  122. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-flue.osw +56 -82
  123. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-natural-ach.osw +57 -83
  124. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-overhangs.osw +57 -83
  125. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-windows-none.osw +56 -82
  126. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-ambient.osw +56 -82
  127. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-conditioned-basement-slab-insulation.osw +56 -82
  128. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-slab.osw +56 -82
  129. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unconditioned-basement-assembly-r.osw +55 -81
  130. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unconditioned-basement-wall-insulation.osw +55 -81
  131. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unconditioned-basement.osw +55 -81
  132. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unvented-crawlspace.osw +55 -81
  133. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-vented-crawlspace.osw +55 -81
  134. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-1-speed-cooling-only.osw +337 -0
  135. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-1-speed-heating-only.osw +337 -0
  136. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-1-speed.osw +56 -82
  137. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-2-speed.osw +56 -82
  138. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-var-speed.osw +56 -82
  139. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-coal-only.osw +56 -82
  140. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-elec-only.osw +56 -82
  141. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-gas-central-ac-1-speed.osw +56 -82
  142. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-gas-only.osw +56 -82
  143. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-oil-only.osw +56 -82
  144. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-propane-only.osw +56 -82
  145. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-wood-only.osw +56 -82
  146. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-only-1-speed.osw +56 -82
  147. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-only-2-speed.osw +56 -82
  148. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-only-var-speed.osw +56 -82
  149. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.osw +56 -82
  150. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-electric.osw +55 -81
  151. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.osw +55 -81
  152. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.osw +55 -81
  153. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.osw +55 -81
  154. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-mini-split-heat-pump-ducted.osw +56 -82
  155. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ducts-leakage-percent.osw +56 -82
  156. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-elec-resistance-only.osw +56 -82
  157. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-evap-cooler-furnace-gas.osw +56 -82
  158. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-evap-cooler-only-ducted.osw +57 -83
  159. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-evap-cooler-only.osw +56 -82
  160. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-fireplace-wood-only.osw +56 -82
  161. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-fixed-heater-gas-only.osw +57 -83
  162. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-floor-furnace-propane-only.osw +56 -82
  163. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-coal-only.osw +337 -0
  164. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-elec-central-ac-1-speed.osw +56 -82
  165. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-elec-only.osw +56 -82
  166. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-central-ac-2-speed.osw +56 -82
  167. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-central-ac-var-speed.osw +56 -82
  168. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-only.osw +56 -82
  169. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-room-ac.osw +56 -82
  170. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-oil-only.osw +56 -82
  171. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-propane-only.osw +56 -82
  172. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-wood-only.osw +56 -82
  173. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ground-to-air-heat-pump-cooling-only.osw +336 -0
  174. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ground-to-air-heat-pump-heating-only.osw +336 -0
  175. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ground-to-air-heat-pump.osw +56 -84
  176. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-airflow-defect-furnace-gas-central-ac-1-speed.osw +339 -0
  177. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-air-to-air-heat-pump-1-speed.osw +339 -0
  178. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-air-to-air-heat-pump-2-speed.osw +339 -0
  179. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-air-to-air-heat-pump-var-speed.osw +339 -0
  180. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-central-ac-1-speed.osw +340 -0
  181. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-central-ac-2-speed.osw +340 -0
  182. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-central-ac-var-speed.osw +340 -0
  183. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-only.osw +338 -0
  184. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-ground-to-air-heat-pump.osw +338 -0
  185. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-mini-split-air-conditioner-only-ducted.osw +338 -0
  186. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-mini-split-heat-pump-ducted.osw +339 -0
  187. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-charge-defect-furnace-gas-central-ac-1-speed.osw +338 -0
  188. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-none-furnace-gas-central-ac-1-speed.osw +340 -0
  189. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-air-conditioner-only-ducted.osw +56 -82
  190. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-air-conditioner-only-ductless.osw +56 -82
  191. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ducted-cooling-only.osw +56 -82
  192. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ducted-heating-only.osw +56 -82
  193. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ducted.osw +57 -83
  194. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ductless.osw +57 -83
  195. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-none.osw +56 -82
  196. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-portable-heater-gas-only.osw +57 -83
  197. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-programmable-thermostat-detailed.osw +337 -0
  198. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-room-ac-only-33percent.osw +56 -82
  199. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-room-ac-only.osw +56 -82
  200. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-setpoints.osw +56 -82
  201. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-stove-oil-only.osw +56 -82
  202. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-stove-wood-pellets-only.osw +56 -82
  203. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-undersized.osw +56 -82
  204. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-wall-furnace-elec-only.osw +56 -82
  205. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-lighting-ceiling-fans.osw +57 -83
  206. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-lighting-detailed.osw +56 -82
  207. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-AMY-2012.osw +56 -82
  208. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-baltimore-md.osw +64 -90
  209. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-dallas-tx.osw +56 -82
  210. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-duluth-mn.osw +69 -95
  211. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-helena-mt.osw +337 -0
  212. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-honolulu-hi.osw +337 -0
  213. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-miami-fl.osw +56 -82
  214. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-phoenix-az.osw +337 -0
  215. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-portland-or.osw +337 -0
  216. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-balanced.osw +56 -82
  217. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-bath-kitchen-fans.osw +64 -92
  218. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-cfis-evap-cooler-only-ducted.osw +57 -83
  219. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-cfis.osw +56 -82
  220. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-erv-atre-asre.osw +56 -82
  221. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-erv.osw +56 -82
  222. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-exhaust-rated-flow-rate.osw +337 -0
  223. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-exhaust.osw +56 -82
  224. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-hrv-asre.osw +56 -82
  225. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-hrv.osw +56 -82
  226. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-supply.osw +56 -82
  227. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-whole-house-fan.osw +56 -82
  228. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-defaults.osw +57 -83
  229. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-loads-large-uncommon.osw +60 -86
  230. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-loads-large-uncommon2.osw +60 -86
  231. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-neighbor-shading.osw +56 -82
  232. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-shielding-of-home.osw +337 -0
  233. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-usage-multiplier.osw +52 -78
  234. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-pv.osw +52 -78
  235. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-vacancy-6-months.osw → base-schedules-stochastic-vacant.osw} +59 -85
  236. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-schedules-stochastic.osw +56 -82
  237. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-schedules-user-specified.osw +56 -82
  238. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-calendar-year-custom.osw +56 -82
  239. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-daylight-saving-custom.osw +56 -82
  240. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-daylight-saving-disabled.osw +56 -82
  241. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-runperiod-1-month.osw +56 -82
  242. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-timestep-10-mins.osw +56 -82
  243. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base.osw +56 -82
  244. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/build_residential_hpxml_test.rb +71 -57
  245. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-auto.osw +56 -82
  246. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-double-exterior.osw +341 -0
  247. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-double-loaded-interior.osw +341 -0
  248. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-eaves.osw +341 -0
  249. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-single-exterior-front.osw +341 -0
  250. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-double-loaded-interior.osw +341 -0
  251. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-bottom-double-loaded-interior.osw +341 -0
  252. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-bottom.osw +341 -0
  253. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-middle-double-loaded-interior.osw +341 -0
  254. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-middle.osw +341 -0
  255. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-top-double-loaded-interior.osw +341 -0
  256. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-top.osw +341 -0
  257. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-bottom-double-loaded-interior.osw +341 -0
  258. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-bottom.osw +341 -0
  259. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-middle-double-loaded-interior.osw +341 -0
  260. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-middle.osw +341 -0
  261. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-top-double-loaded-interior.osw +341 -0
  262. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-top.osw +341 -0
  263. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-bottom-double-loaded-interior.osw +341 -0
  264. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-bottom.osw +341 -0
  265. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-middle-double-loaded-interior.osw +341 -0
  266. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-middle.osw +341 -0
  267. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-top-double-loaded-interior.osw +341 -0
  268. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-top.osw +341 -0
  269. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab.osw +341 -0
  270. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-double-loaded-interior.osw +341 -0
  271. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-bottom-double-loaded-interior.osw +341 -0
  272. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-bottom.osw +341 -0
  273. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-middle-double-loaded-interior.osw +341 -0
  274. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-middle.osw +341 -0
  275. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-top-double-loaded-interior.osw +341 -0
  276. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-top.osw +341 -0
  277. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-bottom-double-loaded-interior.osw +341 -0
  278. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-bottom.osw +341 -0
  279. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-middle-double-loaded-interior.osw +341 -0
  280. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-middle.osw +341 -0
  281. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-top-double-loaded-interior.osw +341 -0
  282. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-top.osw +341 -0
  283. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-bottom-double-loaded-interior.osw +341 -0
  284. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-bottom.osw +341 -0
  285. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-middle-double-loaded-interior.osw +341 -0
  286. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-middle.osw +341 -0
  287. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-top-double-loaded-interior.osw +341 -0
  288. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-top.osw +341 -0
  289. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace.osw +341 -0
  290. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-double-loaded-interior.osw +341 -0
  291. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-bottom-double-loaded-interior.osw +341 -0
  292. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-bottom.osw +341 -0
  293. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-middle-double-loaded-interior.osw +341 -0
  294. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-middle.osw +341 -0
  295. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-top-double-loaded-interior.osw +341 -0
  296. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-top.osw +341 -0
  297. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-bottom-double-loaded-interior.osw +341 -0
  298. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-bottom.osw +341 -0
  299. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-middle-double-loaded-interior.osw +341 -0
  300. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-middle.osw +341 -0
  301. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-top-double-loaded-interior.osw +341 -0
  302. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-top.osw +341 -0
  303. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-bottom-double-loaded-interior.osw +341 -0
  304. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-bottom.osw +341 -0
  305. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-middle-double-loaded-interior.osw +341 -0
  306. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-middle.osw +341 -0
  307. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-top-double-loaded-interior.osw +341 -0
  308. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-top.osw +341 -0
  309. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace.osw +341 -0
  310. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-atticroof-conditioned-eaves-gable.osw +339 -0
  311. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-atticroof-conditioned-eaves-hip.osw +339 -0
  312. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-atticroof-flat.osw +339 -0
  313. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-pv-shared.osw → extra-bldgtype-single-family-attached-double-exterior.osw} +62 -89
  314. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-double-loaded-interior.osw +339 -0
  315. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-dhw-shared-water-heater.osw → extra-bldgtype-single-family-attached-single-exterior-front.osw} +60 -86
  316. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-slab-middle.osw +339 -0
  317. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-slab-right.osw +339 -0
  318. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-slab.osw +339 -0
  319. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unconditioned-basement-middle.osw +339 -0
  320. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unconditioned-basement-right.osw +339 -0
  321. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{base-multifamily.osw → extra-bldgtype-single-family-attached-unconditioned-basement.osw} +64 -91
  322. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unvented-crawlspace-middle.osw +339 -0
  323. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unvented-crawlspace-right.osw +339 -0
  324. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unvented-crawlspace.osw +339 -0
  325. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-vented-crawlspace-middle.osw +339 -0
  326. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-vented-crawlspace-right.osw +339 -0
  327. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-vented-crawlspace.osw +339 -0
  328. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-dhw-solar-latitude.osw +56 -82
  329. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-atticroof-conditioned-eaves-gable.osw +337 -0
  330. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-atticroof-conditioned-eaves-hip.osw +337 -0
  331. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-garage-atticroof-conditioned.osw +337 -0
  332. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-garage-partially-protruded.osw +56 -82
  333. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-windows-shading.osw +339 -0
  334. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-gas-hot-tub-heater-with-zero-kwh.osw +337 -0
  335. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-gas-pool-heater-with-zero-kwh.osw +337 -0
  336. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-pv-roofpitch.osw +56 -82
  337. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-schedules-random-seed.osw +338 -0
  338. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-boiler-to-heat-pump.osw +336 -0
  339. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-boiler-to-heating-system.osw +337 -0
  340. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-fireplace-to-heat-pump.osw +337 -0
  341. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-second-heating-system-fireplace.osw → extra-second-heating-system-fireplace-to-heating-system.osw} +58 -84
  342. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-portable-heater-to-heat-pump.osw +337 -0
  343. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-second-heating-system-portable-heater.osw → extra-second-heating-system-portable-heater-to-heating-system.osw} +56 -82
  344. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-refrigerator.osw +56 -82
  345. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-clothes-washer-kwh.osw +337 -0
  346. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-dishwasher-kwh.osw +337 -0
  347. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-extra-refrigerator-kwh.osw +337 -0
  348. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-freezer-kwh.osw +337 -0
  349. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-refrigerator-kwh.osw +337 -0
  350. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/conditioned-attic-with-floor-insulation.osw +59 -85
  351. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/conditioned-attic-with-one-floor-above-grade.osw +337 -0
  352. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/conditioned-basement-with-ceiling-insulation.osw +56 -82
  353. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/cooling-system-and-heat-pump.osw +56 -82
  354. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/dhw-indirect-without-boiler.osw +56 -82
  355. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/ducts-location-and-areas-not-same-type.osw +56 -82
  356. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/foundation-wall-insulation-greater-than-height.osw +337 -0
  357. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/heating-system-and-heat-pump.osw +56 -82
  358. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multifamily-bottom-crawlspace-zero-foundation-height.osw +64 -89
  359. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multifamily-bottom-slab-non-zero-foundation-height.osw +64 -89
  360. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multifamily-no-building-orientation.osw +63 -88
  361. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{base-hvac-programmable-thermostat.osw → invalid_files/multipliers-without-fuel-loads.osw} +54 -80
  362. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-other-plug-loads.osw +337 -0
  363. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-tv-plug-loads.osw +337 -0
  364. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{base-dhw-uef.osw → invalid_files/multipliers-without-vehicle-plug-loads.osw} +58 -84
  365. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-well-pump-plug-loads.osw +337 -0
  366. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/non-electric-heat-pump-water-heater.osw +56 -82
  367. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/non-integer-ceiling-fan-quantity.osw +56 -82
  368. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/non-integer-geometry-num-bathrooms.osw +56 -82
  369. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/second-heating-system-but-no-primary-heating.osw +337 -0
  370. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/second-heating-system-serves-majority-heat.osw +56 -82
  371. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/second-heating-system-serves-total-heat-load.osw +337 -0
  372. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-attached-ambient.osw +58 -84
  373. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-attached-no-building-orientation.osw +58 -84
  374. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-detached-finished-basement-zero-foundation-height.osw +56 -82
  375. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-detached-slab-non-zero-foundation-height.osw +56 -82
  376. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-detached-with-shared-system.osw +337 -0
  377. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/slab-non-zero-foundation-height-above-grade.osw +56 -82
  378. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/unconditioned-basement-with-wall-and-ceiling-insulation.osw +56 -82
  379. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/unvented-attic-with-floor-and-roof-insulation.osw +56 -82
  380. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/unvented-crawlspace-with-wall-and-ceiling-insulation.osw +59 -85
  381. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/vented-attic-with-floor-and-roof-insulation.osw +58 -84
  382. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/vented-crawlspace-with-wall-and-ceiling-insulation.osw +56 -82
  383. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/zero-number-of-bedrooms.osw +337 -0
  384. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/schedules/vacant.csv +8761 -0
  385. data/example_files/resources/hpxml-measures/Changelog.md +249 -0
  386. data/example_files/resources/hpxml-measures/Gemfile +2 -5
  387. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb +404 -1357
  388. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml +247 -171
  389. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/BaseElements.xsd +11 -101
  390. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/EPvalidator.xml +824 -301
  391. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/HPXMLDataTypes.xsd +18 -35
  392. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/HPXMLvalidator.xml +526 -0
  393. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb +135 -207
  394. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constants.rb +14 -186
  395. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb +549 -93
  396. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/energyplus.rb +12 -15
  397. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/generator.rb +78 -0
  398. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb +413 -15
  399. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb +48 -37
  400. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb +1627 -1227
  401. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_defaults.rb +1192 -434
  402. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb +1555 -1616
  403. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb +1436 -1479
  404. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb +3 -2
  405. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/location.rb +22 -10
  406. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/meta_measure.rb +85 -19
  407. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/minitest_helper.rb +4 -26
  408. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb +22 -46
  409. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/pv.rb +22 -21
  410. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb +51 -14
  411. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/simcontrols.rb +24 -7
  412. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/unit_conversions.rb +2 -0
  413. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/validator.rb +80 -19
  414. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb +9 -2
  415. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb +106 -75
  416. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb +109 -34
  417. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb +22 -36
  418. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_defaults.rb +1565 -768
  419. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_enclosure.rb +151 -0
  420. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_generator.rb +101 -0
  421. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb +9 -18
  422. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac.rb +316 -28
  423. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb +53 -0
  424. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb +4 -2
  425. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_location.rb +13 -11
  426. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb +4 -2
  427. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_pv.rb +5 -3
  428. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_simcontrols.rb +13 -11
  429. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb +102 -62
  430. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_water_heater.rb +189 -35
  431. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/util.rb +26 -0
  432. data/example_files/resources/hpxml-measures/README.md +5 -5
  433. data/example_files/resources/hpxml-measures/Rakefile +2 -10
  434. data/example_files/resources/hpxml-measures/SimulationOutputReport/measure.rb +416 -299
  435. data/example_files/resources/hpxml-measures/SimulationOutputReport/measure.xml +364 -481
  436. data/example_files/resources/hpxml-measures/SimulationOutputReport/resources/constants.rb +1 -2
  437. data/example_files/resources/hpxml-measures/SimulationOutputReport/tests/output_report_test.rb +327 -320
  438. data/example_files/resources/hpxml-measures/docs/source/build_residential_hpxml.rst +3 -3
  439. data/example_files/resources/hpxml-measures/docs/source/conf.py +11 -5
  440. data/example_files/resources/hpxml-measures/docs/source/getting_started.rst +6 -6
  441. data/example_files/resources/hpxml-measures/docs/source/index.rst +2 -2
  442. data/example_files/resources/hpxml-measures/docs/source/intro.rst +7 -109
  443. data/example_files/resources/hpxml-measures/docs/source/nstatic/stylesheet.css +13 -1
  444. data/example_files/resources/hpxml-measures/docs/source/workflow_inputs.rst +2482 -0
  445. data/example_files/resources/hpxml-measures/docs/source/workflow_outputs.rst +282 -0
  446. data/example_files/resources/hpxml-measures/tasks.rb +2494 -1248
  447. data/example_files/resources/hpxml-measures/weather/USA_AZ_Phoenix-Sky.Harbor.Intl.AP.722780_TMY3-cache.csv +35 -0
  448. data/example_files/resources/hpxml-measures/weather/USA_AZ_Phoenix-Sky.Harbor.Intl.AP.722780_TMY3.epw +8768 -0
  449. data/example_files/resources/hpxml-measures/weather/USA_CO_Denver.Intl.AP.725650_TMY3-cache.csv +10 -10
  450. data/example_files/resources/hpxml-measures/weather/USA_HI_Honolulu.Intl.AP.911820_TMY3-cache.csv +35 -0
  451. data/example_files/resources/hpxml-measures/weather/USA_HI_Honolulu.Intl.AP.911820_TMY3.epw +8768 -0
  452. data/example_files/resources/hpxml-measures/weather/USA_MT_Helena.Rgnl.AP.727720_TMY3-cache.csv +35 -0
  453. data/example_files/resources/hpxml-measures/weather/USA_MT_Helena.Rgnl.AP.727720_TMY3.epw +8768 -0
  454. data/example_files/resources/hpxml-measures/weather/USA_OR_Portland.Intl.AP.726980_TMY3-cache.csv +35 -0
  455. data/example_files/resources/hpxml-measures/weather/USA_OR_Portland.Intl.AP.726980_TMY3.epw +8768 -0
  456. data/example_files/resources/hpxml-measures/workflow/run_simulation.rb +96 -21
  457. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-coal.xml +558 -559
  458. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-appliances-dehumidifier-ief.xml → base-appliances-dehumidifier-ief-portable.xml} +8 -7
  459. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-appliances-dehumidifier-50percent.xml → base-appliances-dehumidifier-ief-whole-home.xml} +10 -9
  460. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-multiple.xml +535 -0
  461. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier.xml +525 -524
  462. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-gas.xml +558 -559
  463. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-modified.xml +564 -565
  464. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-none.xml +513 -513
  465. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil.xml +558 -559
  466. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane.xml +558 -559
  467. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-wood.xml +558 -559
  468. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-cathedral.xml +565 -566
  469. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-conditioned.xml +633 -634
  470. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-flat.xml +531 -532
  471. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-radiant-barrier.xml +517 -518
  472. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-unvented-insulated-roof.xml +562 -563
  473. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-vented.xml +565 -566
  474. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-enclosure-other-multifamily-buffer-space.xml → base-bldgtype-multifamily-adjacent-to-multifamily-buffer-space.xml} +34 -62
  475. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multiple.xml +554 -0
  476. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-enclosure-other-non-freezing-space.xml → base-bldgtype-multifamily-adjacent-to-non-freezing-space.xml} +34 -62
  477. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-enclosure-other-heated-space.xml → base-bldgtype-multifamily-adjacent-to-other-heated-space.xml} +34 -62
  478. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-enclosure-other-housing-unit.xml → base-bldgtype-multifamily-adjacent-to-other-housing-unit.xml} +34 -62
  479. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-baseboard.xml +425 -0
  480. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil-ducted.xml +457 -0
  481. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil.xml +427 -0
  482. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-water-loop-heat-pump.xml +479 -0
  483. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-cooling-tower-water-loop-heat-pump.xml +474 -0
  484. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-baseboard.xml +408 -0
  485. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-ducted.xml +439 -0
  486. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-eae.xml +406 -0
  487. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil.xml +409 -0
  488. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-water-loop-heat-pump.xml +457 -0
  489. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-baseboard.xml +407 -0
  490. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil-ducted.xml +438 -0
  491. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil.xml +408 -0
  492. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-water-loop-heat-pump.xml +456 -0
  493. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-cooling-tower-only-water-loop-heat-pump.xml +451 -0
  494. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-generator.xml +460 -0
  495. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-ground-loop-ground-to-air-heat-pump.xml +451 -0
  496. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-laundry-room.xml +466 -0
  497. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-mechvent-shared-multiple.xml → base-bldgtype-multifamily-shared-mechvent-multiple.xml} +43 -415
  498. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-preconditioning.xml +489 -0
  499. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent.xml +473 -0
  500. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-pv.xml +465 -0
  501. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater-recirc.xml +458 -0
  502. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater.xml +451 -0
  503. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily.xml +448 -0
  504. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-single-family-attached.xml +619 -0
  505. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless-outside.xml +516 -519
  506. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless.xml +516 -519
  507. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-2-speed.xml +550 -551
  508. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-gshp.xml +7 -9
  509. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-hpwh.xml +563 -564
  510. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-tankless.xml +548 -549
  511. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-var-speed.xml +550 -551
  512. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater.xml +550 -551
  513. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-dwhr.xml +567 -568
  514. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-dse.xml +517 -520
  515. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-outside.xml +517 -520
  516. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-standbyloss.xml +518 -521
  517. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-with-solar-fraction.xml +525 -528
  518. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect.xml +517 -520
  519. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-electric.xml +567 -568
  520. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-gas.xml +568 -569
  521. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-hpwh.xml +566 -567
  522. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-indirect.xml +522 -525
  523. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-low-flow-fixtures.xml +562 -563
  524. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-multiple.xml +575 -578
  525. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-none.xml +497 -497
  526. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-demand.xml +565 -566
  527. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-manual.xml +565 -566
  528. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-nocontrol.xml +565 -566
  529. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-temperature.xml +565 -566
  530. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-timer.xml +565 -566
  531. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-evacuated-tube.xml +577 -578
  532. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-flat-plate.xml +577 -578
  533. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-ics.xml +577 -578
  534. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-fraction.xml +570 -571
  535. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-indirect-flat-plate.xml +577 -578
  536. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-thermosyphon-flat-plate.xml +577 -578
  537. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-coal.xml +563 -564
  538. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-elec-uef.xml +564 -0
  539. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-outside.xml +563 -564
  540. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef.xml +565 -0
  541. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas.xml +563 -564
  542. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-outside.xml +561 -562
  543. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-uef.xml +564 -0
  544. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar-fraction.xml +569 -570
  545. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar.xml +576 -577
  546. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump.xml +561 -562
  547. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-oil.xml +563 -564
  548. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-wood.xml +563 -564
  549. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-outside.xml +561 -562
  550. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-uef.xml +561 -0
  551. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric.xml +560 -561
  552. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-uef.xml +561 -0
  553. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar-fraction.xml +568 -569
  554. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar.xml +575 -576
  555. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas.xml +560 -561
  556. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-propane.xml +560 -561
  557. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories-garage.xml +661 -664
  558. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories.xml +575 -576
  559. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-1.xml +562 -563
  560. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-2.xml +562 -563
  561. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-4.xml +562 -563
  562. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-5.xml +562 -563
  563. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-garage.xml +636 -639
  564. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-ach-house-pressure.xml +562 -563
  565. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm-house-pressure.xml +562 -563
  566. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm50.xml +562 -563
  567. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-flue.xml +565 -566
  568. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-natural-ach.xml +561 -562
  569. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-overhangs.xml +582 -578
  570. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-rooftypes.xml +590 -591
  571. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-shading.xml +601 -0
  572. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights.xml +590 -591
  573. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-level.xml +517 -0
  574. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces.xml +2474 -2493
  575. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces2.xml +2475 -0
  576. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-walltypes.xml +754 -755
  577. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-none.xml +504 -505
  578. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-enclosure-windows-interior-shading.xml → base-enclosure-windows-shading.xml} +23 -9
  579. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-ambient.xml +498 -497
  580. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-basement-garage.xml +644 -0
  581. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-complex.xml +724 -729
  582. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-slab-insulation.xml +562 -563
  583. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-wall-interior-insulation.xml +562 -563
  584. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-multiple.xml +685 -688
  585. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-slab.xml +516 -517
  586. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-above-grade.xml +609 -610
  587. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-assembly-r.xml +558 -559
  588. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-wall-insulation.xml +573 -574
  589. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement.xml +573 -574
  590. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unvented-crawlspace.xml +573 -574
  591. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-vented-crawlspace.xml +576 -577
  592. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-walkout-basement.xml +627 -628
  593. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-autosize.xml → base-hvac-air-to-air-heat-pump-1-speed-cooling-only.xml} +8 -12
  594. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-air-to-air-heat-pump-1-speed-autosize-manual-s-oversize-allowances.xml → base-hvac-air-to-air-heat-pump-1-speed-heating-only.xml} +9 -9
  595. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed.xml +561 -562
  596. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-2-speed.xml +561 -562
  597. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed.xml +561 -562
  598. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-cooling-only.xml +553 -0
  599. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-air-to-air-heat-pump-1-speed-autosize.xml → base-hvac-autosize-air-to-air-heat-pump-1-speed-heating-only.xml} +5 -6
  600. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-manual-s-oversize-allowances.xml +561 -0
  601. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed.xml +558 -0
  602. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-air-to-air-heat-pump-2-speed-autosize-manual-s-oversize-allowances.xml → base-hvac-autosize-air-to-air-heat-pump-2-speed-manual-s-oversize-allowances.xml} +4 -5
  603. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-air-to-air-heat-pump-2-speed-autosize.xml → base-hvac-autosize-air-to-air-heat-pump-2-speed.xml} +4 -5
  604. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-air-to-air-heat-pump-var-speed-autosize-manual-s-oversize-allowances.xml → base-hvac-autosize-air-to-air-heat-pump-var-speed-manual-s-oversize-allowances.xml} +4 -5
  605. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-air-to-air-heat-pump-var-speed-autosize.xml → base-hvac-autosize-air-to-air-heat-pump-var-speed.xml} +4 -5
  606. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-boiler-elec-only-autosize.xml → base-hvac-autosize-boiler-elec-only.xml} +2 -5
  607. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-boiler-gas-central-ac-1-speed-autosize.xml → base-hvac-autosize-boiler-gas-central-ac-1-speed.xml} +4 -6
  608. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-boiler-gas-only-autosize.xml → base-hvac-autosize-boiler-gas-only.xml} +2 -5
  609. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-central-ac-only-1-speed-autosize.xml → base-hvac-autosize-central-ac-only-1-speed.xml} +547 -548
  610. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-central-ac-only-2-speed-autosize.xml → base-hvac-autosize-central-ac-only-2-speed.xml} +4 -5
  611. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-central-ac-only-var-speed-autosize.xml → base-hvac-autosize-central-ac-only-var-speed.xml} +4 -5
  612. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-central-ac-plus-air-to-air-heat-pump-heating-autosize.xml → base-hvac-autosize-central-ac-plus-air-to-air-heat-pump-heating.xml} +570 -571
  613. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-air-to-air-heat-pump-1-speed.xml +559 -0
  614. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-dual-fuel-mini-split-heat-pump-ducted-autosize.xml → base-hvac-autosize-dual-fuel-mini-split-heat-pump-ducted.xml} +557 -558
  615. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-elec-resistance-only-autosize.xml → base-hvac-autosize-elec-resistance-only.xml} +2 -5
  616. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-evap-cooler-furnace-gas-autosize.xml → base-hvac-autosize-evap-cooler-furnace-gas.xml} +4 -5
  617. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-floor-furnace-propane-only-autosize.xml → base-hvac-autosize-floor-furnace-propane-only.xml} +5 -6
  618. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-furnace-elec-only-autosize.xml → base-hvac-autosize-furnace-elec-only.xml} +4 -5
  619. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-furnace-gas-central-ac-2-speed-autosize.xml → base-hvac-autosize-furnace-gas-central-ac-2-speed.xml} +4 -5
  620. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-furnace-gas-central-ac-var-speed-autosize.xml → base-hvac-autosize-furnace-gas-central-ac-var-speed.xml} +4 -5
  621. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-furnace-gas-only-autosize.xml → base-hvac-autosize-furnace-gas-only.xml} +4 -6
  622. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-furnace-gas-room-ac-autosize.xml → base-hvac-autosize-furnace-gas-room-ac.xml} +4 -5
  623. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-cooling-only.xml +555 -0
  624. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-heating-only.xml +560 -0
  625. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-ground-to-air-heat-pump-autosize-manual-s-oversize-allowances.xml → base-hvac-autosize-ground-to-air-heat-pump-manual-s-oversize-allowances.xml} +4 -6
  626. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-ground-to-air-heat-pump-autosize.xml → base-hvac-autosize-ground-to-air-heat-pump.xml} +4 -6
  627. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-air-conditioner-only-ducted.xml +547 -0
  628. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-mini-split-heat-pump-ducted-cooling-only-autosize.xml → base-hvac-autosize-mini-split-heat-pump-ducted-cooling-only.xml} +551 -552
  629. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-mini-split-heat-pump-ducted-heating-only-autosize.xml → base-hvac-autosize-mini-split-heat-pump-ducted-heating-only.xml} +556 -557
  630. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-manual-s-oversize-allowances.xml +560 -0
  631. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-mini-split-heat-pump-ducted-autosize.xml → base-hvac-autosize-mini-split-heat-pump-ducted.xml} +556 -557
  632. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-room-ac-only-autosize.xml → base-hvac-autosize-room-ac-only.xml} +2 -5
  633. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-stove-oil-only-autosize.xml → base-hvac-autosize-stove-oil-only.xml} +5 -6
  634. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-wall-furnace-elec-only-autosize.xml → base-hvac-autosize-wall-furnace-elec-only.xml} +5 -6
  635. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-autosize.xml → base-hvac-autosize.xml} +4 -5
  636. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-coal-only.xml +518 -521
  637. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-elec-only.xml +518 -521
  638. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-central-ac-1-speed.xml +571 -573
  639. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-only.xml +519 -522
  640. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-oil-only.xml +518 -521
  641. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-propane-only.xml +518 -521
  642. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-wood-only.xml +518 -521
  643. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed.xml +548 -549
  644. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-2-speed.xml +548 -549
  645. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-var-speed.xml +548 -549
  646. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.xml +575 -576
  647. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dse.xml +532 -535
  648. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-electric.xml +562 -563
  649. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.xml +562 -563
  650. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.xml +562 -563
  651. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.xml +562 -563
  652. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-mini-split-heat-pump-ducted.xml +561 -562
  653. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-percent.xml +562 -563
  654. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-elec-resistance-only.xml +509 -512
  655. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-furnace-gas.xml +555 -555
  656. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only-ducted.xml +536 -528
  657. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only.xml +503 -505
  658. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fireplace-wood-only.xml +6 -7
  659. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fixed-heater-gas-only.xml +6 -57
  660. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-floor-furnace-propane-only.xml +6 -7
  661. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-coal-only.xml +549 -0
  662. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-central-ac-1-speed.xml +562 -563
  663. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-only.xml +548 -549
  664. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-2-speed.xml +562 -563
  665. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-var-speed.xml +562 -563
  666. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only.xml +5 -7
  667. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-room-ac.xml +560 -561
  668. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-oil-only.xml +548 -549
  669. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-propane-only.xml +548 -549
  670. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-wood-only.xml +548 -549
  671. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-x3-dse.xml +576 -579
  672. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-cooling-only.xml +557 -0
  673. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-heating-only.xml +563 -0
  674. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump.xml +7 -9
  675. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-flowrate.xml → base-hvac-install-quality-airflow-defect-furnace-gas-central-ac-1-speed.xml} +8 -9
  676. data/example_files/resources/hpxml-measures/workflow/sample_files/{invalid_files/heat-pump-mixed-fixed-and-autosize-capacities2.xml → base-hvac-install-quality-all-air-to-air-heat-pump-1-speed.xml} +13 -8
  677. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-air-to-air-heat-pump-2-speed.xml +567 -0
  678. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-air-to-air-heat-pump-var-speed.xml +567 -0
  679. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-furnace-gas-central-ac-1-speed.xml +572 -0
  680. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-furnace-gas-central-ac-2-speed.xml +572 -0
  681. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-furnace-gas-central-ac-var-speed.xml +572 -0
  682. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-furnace-gas-only.xml +553 -0
  683. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-ground-to-air-heat-pump.xml +566 -0
  684. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-mini-split-air-conditioner-only-ducted-autosize.xml → base-hvac-install-quality-all-mini-split-air-conditioner-only-ducted.xml} +10 -5
  685. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-mini-split-heat-pump-ducted-autosize-manual-s-oversize-allowances.xml → base-hvac-install-quality-all-mini-split-heat-pump-ducted.xml} +13 -8
  686. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-blower-efficiency-furnace-gas-central-ac-1-speed.xml +569 -0
  687. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-misc-shelter-coefficient.xml → base-hvac-install-quality-charge-defect-furnace-gas-central-ac-1-speed.xml} +9 -10
  688. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-none-furnace-gas-central-ac-1-speed.xml +570 -0
  689. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ducted.xml +547 -548
  690. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ductless.xml +508 -511
  691. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-cooling-only.xml +554 -555
  692. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-heating-only.xml +560 -561
  693. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted.xml +560 -561
  694. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless.xml +515 -518
  695. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple.xml +21 -13
  696. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-none.xml +486 -489
  697. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-portable-heater-gas-only.xml +6 -57
  698. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-programmable-thermostat-detailed.xml +567 -0
  699. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-programmable-thermostat.xml +570 -571
  700. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-33percent.xml +508 -511
  701. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only.xml +508 -511
  702. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints.xml +562 -563
  703. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-oil-only.xml +6 -7
  704. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-wood-pellets-only.xml +6 -7
  705. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized-allow-increased-fixed-capacities.xml +565 -566
  706. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized.xml +562 -563
  707. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-wall-furnace-elec-only.xml +6 -7
  708. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-ceiling-fans.xml +573 -574
  709. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-detailed.xml +585 -586
  710. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-none.xml +488 -489
  711. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-AMY-2012.xml +562 -563
  712. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-baltimore-md.xml +573 -563
  713. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-dallas-tx.xml +516 -517
  714. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-duluth-mn.xml +573 -563
  715. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-helena-mt.xml +563 -0
  716. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-honolulu-hi.xml +517 -0
  717. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-miami-fl.xml +516 -517
  718. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-phoenix-az.xml +517 -0
  719. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-portland-or.xml +577 -0
  720. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-balanced.xml +574 -575
  721. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-bath-kitchen-fans.xml +590 -591
  722. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-dse.xml +545 -548
  723. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-evap-cooler-only-ducted.xml +549 -541
  724. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis.xml +575 -576
  725. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv-atre-asre.xml +576 -577
  726. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv.xml +576 -577
  727. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust-rated-flow-rate.xml +574 -575
  728. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust.xml +574 -575
  729. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv-asre.xml +575 -576
  730. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv.xml +575 -576
  731. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-multiple.xml +796 -795
  732. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-supply.xml +574 -575
  733. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-whole-house-fan.xml +572 -573
  734. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-defaults.xml +478 -495
  735. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators.xml +579 -0
  736. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon.xml +758 -833
  737. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon2.xml +749 -820
  738. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-none.xml +550 -559
  739. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-neighbor-shading.xml +575 -576
  740. data/example_files/resources/hpxml-measures/workflow/sample_files/{invalid_files/invalid-calendar-year.xml → base-misc-shielding-of-home.xml} +7 -8
  741. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-usage-multiplier.xml +728 -725
  742. data/example_files/resources/hpxml-measures/workflow/sample_files/base-multiple-buildings.xml +1657 -0
  743. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv.xml +6 -7
  744. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-stochastic-vacant.xml +564 -0
  745. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-stochastic.xml +6 -7
  746. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-user-specified.xml +6 -7
  747. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-calendar-year-custom.xml +563 -564
  748. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-custom.xml +569 -570
  749. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-disabled.xml +565 -566
  750. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-runperiod-1-month.xml +566 -567
  751. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins.xml +562 -563
  752. data/example_files/resources/hpxml-measures/workflow/sample_files/base.xml +562 -563
  753. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/boiler-invalid-afue.xml +519 -0
  754. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/cfis-with-hydronic-distribution.xml +532 -535
  755. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/clothes-dryer-location.xml +562 -563
  756. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/clothes-washer-location.xml +562 -563
  757. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/cooking-range-location.xml +562 -563
  758. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dehumidifier-fraction-served.xml +535 -0
  759. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dehumidifier-setpoints.xml +535 -0
  760. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dhw-frac-load-served.xml +575 -578
  761. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-dhw-uef.xml → invalid_files/dhw-invalid-ef-tank.xml} +7 -8
  762. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dhw-invalid-uef-tank-heat-pump.xml +564 -0
  763. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dishwasher-location.xml +562 -563
  764. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-leakage-cfm25.xml +563 -0
  765. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-leakage-percent.xml +563 -0
  766. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-location-unconditioned-space.xml +562 -563
  767. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-location.xml +562 -563
  768. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duplicate-id.xml +562 -563
  769. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-attic-missing-roof.xml +546 -547
  770. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-basement-missing-exterior-foundation-wall.xml +543 -544
  771. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-basement-missing-slab.xml +546 -545
  772. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-floor-area-exceeds-cfa.xml +563 -0
  773. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-floor-area-exceeds-cfa2.xml +448 -0
  774. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-garage-missing-exterior-wall.xml +613 -616
  775. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-garage-missing-roof-ceiling.xml +626 -629
  776. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-garage-missing-slab.xml +610 -611
  777. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-living-missing-ceiling-roof.xml +550 -551
  778. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-living-missing-exterior-wall.xml +472 -473
  779. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-living-missing-floor-slab.xml +488 -534
  780. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-sensible-fuel-load.xml +760 -0
  781. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-sensible-plug-load.xml +759 -0
  782. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-total-fuel-load.xml +761 -0
  783. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-total-plug-load.xml +759 -0
  784. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/furnace-invalid-afue.xml +563 -0
  785. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/generator-number-of-bedrooms-served.xml +460 -0
  786. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/generator-output-greater-than-consumption.xml +579 -0
  787. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/heat-pump-mixed-fixed-and-autosize-capacities.xml +559 -560
  788. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-distribution-multiple-attached-cooling.xml +21 -13
  789. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-distribution-multiple-attached-heating.xml +21 -13
  790. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-distribution-return-duct-leakage-missing.xml +528 -534
  791. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-dse-multiple-attached-cooling.xml +546 -549
  792. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-dse-multiple-attached-heating.xml +546 -549
  793. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-frac-load-served.xml +21 -13
  794. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-inconsistent-fan-powers.xml +569 -0
  795. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-invalid-distribution-system-type.xml +570 -571
  796. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-shared-negative-seer-eq.xml +407 -0
  797. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-assembly-effective-rvalue.xml +563 -0
  798. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-datatype-boolean.xml +563 -0
  799. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-datatype-float.xml +563 -0
  800. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-datatype-integer.xml +563 -0
  801. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-daylight-saving.xml +569 -567
  802. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-distribution-cfa-served.xml +562 -563
  803. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-epw-filepath.xml +562 -563
  804. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-facility-type-equipment.xml +466 -0
  805. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-facility-type-surfaces.xml +644 -0
  806. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/{appliances-location-unconditioned-space.xml → invalid-foundation-wall-properties.xml} +39 -29
  807. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-id.xml +591 -0
  808. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-id2.xml +591 -0
  809. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-infiltration-volume.xml +563 -0
  810. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-input-parameters.xml +565 -0
  811. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-neighbor-shading-azimuth.xml +575 -576
  812. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-number-of-bedrooms-served.xml +465 -0
  813. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/{slab-zero-exposed-perimeter.xml → invalid-number-of-conditioned-floors.xml} +7 -8
  814. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-number-of-units-served.xml +451 -0
  815. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-relatedhvac-desuperheater.xml +550 -551
  816. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-relatedhvac-dhw-indirect.xml +517 -520
  817. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-runperiod.xml +564 -565
  818. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-schema-version.xml +563 -0
  819. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-shared-vent-in-unit-flowrate.xml +473 -0
  820. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-timestep.xml +562 -563
  821. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-window-height.xml +582 -578
  822. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/lighting-fractions.xml +562 -563
  823. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/missing-duct-location.xml +21 -13
  824. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/missing-elements.xml +560 -561
  825. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-appliance.xml +562 -563
  826. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-duct.xml +562 -563
  827. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-surface.xml +575 -566
  828. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-water-heater.xml +562 -563
  829. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-buildings-without-building-id.xml +1657 -0
  830. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-buildings-wrong-building-id.xml +1657 -0
  831. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-shared-cooling-systems.xml +432 -0
  832. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-shared-heating-systems.xml +434 -0
  833. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/net-area-negative-roof.xml +590 -591
  834. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/net-area-negative-wall.xml +562 -563
  835. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/num-bedrooms-exceeds-limit.xml +563 -0
  836. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/orphaned-hvac-distribution.xml +546 -547
  837. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/refrigerator-location.xml +562 -563
  838. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/refrigerators-multiple-primary.xml +568 -569
  839. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/refrigerators-no-primary.xml +568 -569
  840. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/repeated-relatedhvac-desuperheater.xml +563 -564
  841. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/repeated-relatedhvac-dhw-indirect.xml +526 -529
  842. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-fraction-one.xml +571 -0
  843. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-thermal-system-with-combi-tankless.xml +531 -534
  844. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-thermal-system-with-desuperheater.xml +565 -566
  845. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-thermal-system-with-dhw-indirect.xml +531 -534
  846. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-cfis.xml +575 -576
  847. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-door.xml +562 -563
  848. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-hvac-distribution.xml +562 -563
  849. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-shared-clothes-washer-water-heater.xml +465 -827
  850. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-shared-dishwasher-water-heater.xml +465 -827
  851. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-skylight.xml +590 -591
  852. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-solar-thermal-system.xml +577 -578
  853. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-window.xml +562 -563
  854. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/water-heater-location-other.xml +562 -563
  855. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/water-heater-location.xml +562 -563
  856. data/example_files/resources/hpxml-measures/workflow/template.osw +5 -1
  857. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AC.xml +6 -17
  858. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AL.xml +6 -17
  859. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AC.xml +6 -17
  860. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AL.xml +6 -17
  861. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AC.xml +6 -17
  862. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AL.xml +6 -17
  863. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AC.xml +6 -17
  864. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AL.xml +6 -17
  865. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AC.xml +6 -17
  866. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AL.xml +6 -17
  867. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AC.xml +6 -17
  868. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AL.xml +6 -17
  869. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AC.xml +6 -17
  870. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AL.xml +6 -17
  871. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AC.xml +6 -17
  872. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AL.xml +6 -17
  873. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AC.xml +6 -17
  874. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AL.xml +6 -17
  875. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AC.xml +6 -17
  876. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AL.xml +6 -17
  877. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AC.xml +6 -17
  878. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AL.xml +6 -17
  879. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L302XC.xml +6 -19
  880. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L304XC.xml +6 -19
  881. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L322XC.xml +6 -19
  882. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L324XC.xml +6 -19
  883. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results.csv +294 -0
  884. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_ashrae_140.csv +27 -0
  885. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_hvac_sizing.csv +294 -0
  886. data/example_files/resources/hpxml-measures/workflow/tests/compare.rb +130 -0
  887. data/example_files/resources/hpxml-measures/workflow/tests/hpxml_translator_test.rb +522 -527
  888. data/example_files/{measures/BuildResidentialModel/resources → resources}/measure-info.json +0 -0
  889. data/example_files/{measures/BuildResidentialModel/resources → resources}/meta_measure.rb +53 -44
  890. data/example_files/validation_schema.yaml +149 -0
  891. data/example_files/visualization/input_visualization_feature.html +213 -56
  892. data/example_files/visualization/input_visualization_scenario.html +92 -30
  893. data/lib/uo_cli.rb +406 -128
  894. data/lib/uo_cli/version.rb +17 -7
  895. data/requirements.txt +2 -0
  896. data/scripts/setup-env-gitbash.sh +5 -5
  897. data/scripts/setup-env-unix.sh +4 -4
  898. data/scripts/setup-env.bat +14 -11
  899. data/scripts/setup-env.ps1 +13 -10
  900. data/uo_cli.gemspec +10 -8
  901. metadata +390 -130
  902. data/developer_nrel_key.rb +0 -31
  903. data/example_files/measures/ResidentialGeometryCreateMultifamily/measure.rb +0 -1005
  904. data/example_files/measures/ResidentialGeometryCreateMultifamily/measure.xml +0 -326
  905. data/example_files/measures/ResidentialGeometryCreateMultifamily/tests/create_residential_multifamily_geometry_test.rb +0 -477
  906. data/example_files/measures/ResidentialGeometryCreateSingleFamilyAttached/measure.rb +0 -1039
  907. data/example_files/measures/ResidentialGeometryCreateSingleFamilyAttached/measure.xml +0 -393
  908. data/example_files/measures/ResidentialGeometryCreateSingleFamilyAttached/tests/create_residential_single_family_attached_geometry_test.rb +0 -456
  909. data/example_files/measures/ResidentialGeometryCreateSingleFamilyDetached/measure.rb +0 -979
  910. data/example_files/measures/ResidentialGeometryCreateSingleFamilyDetached/measure.xml +0 -388
  911. data/example_files/measures/ResidentialGeometryCreateSingleFamilyDetached/tests/create_residential_single_family_detached_geometry_test.rb +0 -704
  912. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/location.rb +0 -24
  913. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_config.yml +0 -61
  914. data/example_files/resources/hpxml-measures/docs/source/hpxml_to_openstudio.rst +0 -1386
  915. data/example_files/resources/hpxml-measures/docs/source/simulation_output_report.rst +0 -252
  916. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-shared-laundry-room.xml +0 -828
  917. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-shared-water-heater-recirc.xml +0 -820
  918. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-shared-water-heater.xml +0 -813
  919. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-attached-multifamily.xml +0 -810
  920. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-common-surfaces.xml +0 -928
  921. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ideal-air.xml +0 -501
  922. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple2.xml +0 -838
  923. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-chiller-baseboard.xml +0 -777
  924. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-chiller-fan-coil-ducted.xml +0 -808
  925. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-chiller-fan-coil.xml +0 -780
  926. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-chiller-water-loop-heat-pump.xml +0 -820
  927. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-cooling-tower-water-loop-heat-pump.xml +0 -815
  928. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-only-baseboard.xml +0 -760
  929. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-only-fan-coil-ducted.xml +0 -790
  930. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-only-fan-coil-eae.xml +0 -759
  931. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-only-fan-coil.xml +0 -762
  932. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-only-water-loop-heat-pump.xml +0 -796
  933. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-chiller-only-baseboard.xml +0 -759
  934. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-chiller-only-fan-coil-ducted.xml +0 -789
  935. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-chiller-only-fan-coil.xml +0 -761
  936. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-chiller-only-water-loop-heat-pump.xml +0 -796
  937. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-cooling-tower-only-water-loop-heat-pump.xml +0 -791
  938. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-ground-loop-ground-to-air-heat-pump.xml +0 -814
  939. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-shared-preconditioning.xml +0 -851
  940. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-shared.xml +0 -835
  941. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-shared.xml +0 -827
  942. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/coal-for-non-boiler-heating.xml +0 -514
  943. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-facility-type.xml +0 -828
  944. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-window-interior-shading.xml +0 -564
@@ -0,0 +1,249 @@
1
+ ## OpenStudio-HPXML v1.2.0 (Pending)
2
+
3
+ __New Features__
4
+ - Updates to OpenStudio 3.2.0/EnergyPlus 9.5.0.
5
+ - **Breaking change**: Heating/cooling component loads no longer calculated by default for faster performance; use `--add-component-loads` argument if desired.
6
+ - **Breaking change**: Replaces `Site/extension/ShelterCoefficient` with `Site/ShieldingofHome`.
7
+ - **Breaking change**: `AirDistributionType` is now required for all air distribution systems.
8
+ - Allows additional fuel types for generators.
9
+ - Allows `DuctLeakageMeasurement` & `ConditionedFloorAreaServed` to not be specified for ductless fan coil systems.
10
+ - Allows `Slab/ExposedPerimeter` to be zero.
11
+ - Removes `ClothesDryer/ControlType` from being a required input, it is not used.
12
+ - Switches room air conditioner model to use Cutler performance curves.
13
+ - Adds an `--ep-input-format` argument to run_simulation.rb to choose epJSON as the EnergyPlus input file format instead of IDF.
14
+ - Relaxes tolerance for duct leakage to outside warning when ducts solely in conditioned space.
15
+ - Moves additional error-checking from the ruby measure to the schematron validator.
16
+
17
+ __Bugfixes__
18
+ - Improves ground reflectance when there is shading of windows/skylights.
19
+ - Fixes room air conditioner performance curve.
20
+ - Fixes ruby error if elements (e.g., `SystemIdentifier`) exist without the proper 'id'/'idref' attribute.
21
+ - Fixes error if boiler/GSHP pump power is zero
22
+ - Fixes possible "Electricity category end uses do not sum to total" error due to boiler pump energy.
23
+ - Fixes possible "Construction R-value ... does not match Assembly R-value" error for highly insulated enclosure elements.
24
+ - Adds error-checking for negative SEEReq results for shared cooling systems.
25
+ - Adds more detail to error messages regarding the wrong data type in the HPXML file.
26
+ - Prevents a solar hot water system w/ SolarFraction=1.
27
+
28
+ ## OpenStudio-HPXML v1.1.0
29
+
30
+ __New Features__
31
+ - **Breaking change**: `Type` is now a required input for dehumidifiers; can be "portable" or "whole-home".
32
+ - **Breaking change**: `Location` is now a required input for dehumidifiers; must be "living space" as dehumidifiers are currently modeled as located in living space.
33
+ - **Breaking change**: `Type` is now a required input for Pool, PoolPump, HotTub, and HotTubPump.
34
+ - **Breaking change**: Both supply and return duct leakage to outside are now required inputs for AirDistribution systems.
35
+ - **Breaking change**: Simplifies inputs for fan coils and water loop heat pumps by A) removing HydronicAndAirDistribution element and B) moving WLHP inputs from extension elements to HeatPump element.
36
+ - Allows modeling airflow/charge defects for air conditioners, heat pumps, and furnaces (RESNET Standard 310).
37
+ - Allows modeling *multiple* dehumidifiers (previously only one allowed).
38
+ - Allows modeling generators (generic on-site power production).
39
+ - Allows detailed heating/cooling setpoints to be specified: 24-hour weekday & weekend values.
40
+ - Allows modeling window/skylight *exterior* shading via summer/winter shading coefficients.
41
+ - Allows JSON annual/timeseries output files to be generated instead of CSV. **Breaking change**: For CSV outputs, the first two sections in the results_annual.csv file are now prefixed with "Fuel Use:" and "End Use:", respectively.
42
+ - Allows more defaulting (optional inputs) for a variety of HPXML elements.
43
+ - Allows requesting timeseries unmet heating/cooling loads.
44
+ - Allows skipping schema/schematron validation (for speed); should only be used if the HPXML was already validated upstream.
45
+ - Allows HPXML files w/ multiple `Building` elements; requires providing the ID of the single building to be simulated.
46
+ - Includes hot water loads (in addition to heating/cooling loads) when timeseries total loads are requested.
47
+ - The `in.xml` HPXML file is now always produced for inspection of default values (e.g., autosized HVAC capacities). **Breaking change**: The `output_dir` HPXMLtoOpenStudio measure argument is now required.
48
+ - Overhauls documentation to be more comprehensive and standardized.
49
+ - `run_simulation.rb` now returns exit code 1 if not successful (i.e., either invalid inputs or simulation fails).
50
+
51
+ __Bugfixes__
52
+ - Improved modeling of window/skylight interior shading -- better reflects shading coefficient inputs.
53
+ - Adds error-checking on the HPXML schemaVersion.
54
+ - Adds various error-checking to the schematron validator.
55
+ - Adds error-checking for empty IDs in the HPXML file.
56
+ - Fixes heat pump water heater fan energy not included in SimulationOutputReport outputs.
57
+ - Fixes possibility of incorrect "A neighbor building has an azimuth (XXX) not equal to the azimuth of any wall" error.
58
+ - Fixes possibility of errors encountered before schematron validation has occurred.
59
+ - Small bugfixes related to basement interior surface solar absorptances.
60
+ - Allows NumberofConditionedFloors/NumberofConditionedFloorsAboveGrade to be non-integer values per the HPXML schema.
61
+ - HVAC sizing design load improvements for floors above crawlspaces/basements, walls, ducts, and heat pumps.
62
+ - Now recognizes Type="none" to prevent modeling of pools and hot tubs (pumps and heaters).
63
+ - Fixes error for overhangs with zero depth.
64
+ - Fixes possible error where the normalized flue height for the AIM-2 infiltration model is negative.
65
+ - Slight adjustment of default water heater recovery efficiency equation to prevent errors from values being too high.
66
+ - Fixes schematron file not being valid per ISO Schematron standard.
67
+
68
+ ## OpenStudio-HPXML v1.0.0
69
+
70
+ __New Features__
71
+ - Updates to OpenStudio 3.1.0/EnergyPlus 9.4.0.
72
+ - **Breaking change**: Deprecates `WeatherStation/WMO` HPXML input, use `WeatherStation/extension/EPWFilePath` instead; also removes `weather_dir` argument from HPXMLtoOpenStudio measure.
73
+ - Implements water heater Uniform Energy Factor (UEF) model; replaces RESNET UEF->EF regression. **Breaking change**: `FirstHourRating` is now a required input for storage water heaters when UEF is provided.
74
+ - Adds optional HPXML fan power inputs for most HVAC system types. **Breaking change**: Removes ElectricAuxiliaryEnergy input for non-boiler heating systems.
75
+ - Uses air-source heat pump cooling performance curves for central air conditioners.
76
+ - Updates rated fan power assumption for mini-split heat pump models.
77
+ - Allows coal fuel type for non-boiler heating systems.
78
+ - Accommodates common walls adjacent to unconditioned space by using HPXML surfaces where InteriorAdjacentTo == ExteriorAdjacentTo.
79
+ - Adds optional HPXML inputs to define whether a clothes dryer is vented and its ventilation rate.
80
+ - Adds optional HPXML input for `SimulationControl/CalendarYear` for TMY weather files.
81
+ - Schematron validation improvements.
82
+ - Adds some HPXML XSD schema validation and additional error-checking.
83
+ - Various small updates to ASHRAE 140 test files.
84
+ - Reduces number of EnergyPlus output files produced by using new OutputControlFiles object.
85
+ - Release packages now include ASHRAE 140 test files/results.
86
+
87
+ __Bugfixes__
88
+ - EnergyPlus 9.4.0 fix for negative window solar absorptances at certain hours.
89
+ - Fixes airflow timeseries outputs to be averaged instead of summed.
90
+ - Updates HVAC sizing methodology for slab-on-grade foundation types.
91
+ - Fixes an error that could prevent schematron validation errors from being produced.
92
+ - Skips weather caching if filesystem is read only.
93
+
94
+ ## OpenStudio-HPXML v0.11.0 Beta
95
+
96
+ __New Features__
97
+ - New [Schematron](http://schematron.com) validation (EPvalidator.xml) replaces custom ruby validation (EPvalidator.rb)
98
+ - **[Breaking Change]** `BuildingConstruction/ResidentialFacilityType` ("single-family detached", "single-family attached", "apartment unit", or "manufactured home") is a required input
99
+ - Ability to model shared systems for Attached/Multifamily dwelling units
100
+ - Shared HVAC systems (cooling towers, chillers, central boilers, water loop heat pumps, fan coils, ground source heat pumps on shared hydronic circulation loops)
101
+ - Shared water heaters serving either A) multiple dwelling units' service hot water or B) a shared laundry/equipment room, as well as hot water recirculation systems
102
+ - Shared appliances (e.g., clothes dryer in a shared laundry room)
103
+ - Shared hot water recirculation systems
104
+ - Shared ventilation systems (optionally with preconditioning equipment and recirculation)
105
+ - Shared PV systems
106
+ - **[Breaking Change]** Appliances located in MF spaces (i.e., "other") must now be specified in more detail (i.e., "other heated space", "other non-freezing space", "other multifamily buffer space", or "other housing unit")
107
+ - Enclosure
108
+ - New optional inputs: `Roof/RoofType`, `Wall/Siding`, and `RimJoist/Siding`
109
+ - New optional inputs: `Skylight/InteriorShading/SummerShadingCoefficient` and `Skylight/InteriorShading/SummerShadingCoefficient`
110
+ - New optional inputs: `Roof/RoofColor`, `Wall/Color`, and `RimJoist/Color` can be provided instead of `SolarAbsorptance`
111
+ - New optional input to specify presence of flue/chimney, which results in increased infiltration
112
+ - Allows adobe wall type
113
+ - Allows `AirInfiltrationMeasurement/HousePressure` to be any value (previously required to be 50 Pa)
114
+ - **[Breaking Change]** `Roof/RadiantBarrierGrade` input now required when there is a radiant barrier
115
+ - HVAC
116
+ - Adds optional high-level HVAC autosizing controls
117
+ - `AllowIncreasedFixedCapacities`: Describes how HVAC equipment with fixed capacities are handled. If true, the maximum of the user-specified fixed capacity and the heating/cooling design load will be used to reduce potential for unmet loads. Defaults to false.
118
+ - `UseMaxLoadForHeatPumps`: Describes how autosized heat pumps are handled. If true, heat pumps are sized based on the maximum of heating and cooling design loads. If false, heat pumps are sized per ACCA Manual J/S based on cooling design loads with some oversizing allowances for heating design loads. Defaults to true.
119
+ - Additional HVAC types: mini-split air conditioners and fixed (non-portable) space heaters
120
+ - Adds optional inputs for ground-to-air heat pumps: `extension/PumpPowerWattsPerTon` and `extension/FanPowerWattsPerCFM`
121
+ - Ventilation
122
+ - Allows _multiple_ whole-home ventilation, spot ventilation, and/or whole house fans
123
+ - Appliances & Plug Loads
124
+ - Allows _multiple_ `Refrigerator` and `Freezer`
125
+ - Allows `Pool`, `HotTub`, `PlugLoad` of type "electric vehicle charging" and "well pump", and `FuelLoad` of type "grill", "lighting", and "fireplace"
126
+ - **[Breaking Change]** "other" and "TV other" plug loads now required
127
+ - Lighting
128
+ - Allows lighting schedules and holiday lighting
129
+ - **[Breaking Change]** For hydronic distributions, `HydronicDistributionType` is now required
130
+ - **[Breaking Change]** For DSE distributions, `AnnualHeatingDistributionSystemEfficiency` and `AnnualCoolingDistributionSystemEfficiency` are both always required
131
+ - Allows more HPXML fuel types to be used for HVAC, water heating, appliances, etc.
132
+ - New inputs to define Daylight Saving period; defaults to enabled
133
+ - Adds more reporting of warnings/errors to run.log
134
+
135
+ __Bugfixes__
136
+ - Fixes pump energy for boilers and ground source heat pumps
137
+ - Fixes incorrect gallons of hot water use reported when there are multiple water heaters
138
+ - No longer report unmet load for buildings where the HVAC system only meets part of the load (e.g., room AC serving 33% of the load)
139
+ - Schedule bugfix for leap years
140
+
141
+ ## OpenStudio-HPXML v0.10.0 Beta
142
+
143
+ __New Features__
144
+ - Dwelling units of single-family attached/multifamily buildings:
145
+ - Adds new generic space types "other heated space", "other multifamily buffer space", and "other non-freezing space" for surface `ExteriorAdjacentTo` elements. "other housing unit", i.e. adiabatic surfaces, was already supported.
146
+ - **[Breaking Change]** For `FrameFloors`, replaces "other housing unit above" and "other housing unit below" enumerations with "other housing unit". All four "other ..." spaces must have an `extension/OtherSpaceAboveOrBelow` property set to either "above" or "below".
147
+ - Allows ducts and water heaters to be located in all "other ..." spaces.
148
+ - Allows all appliances to be located in "other", in which internal gains are neglected.
149
+ - Allows `Fireplace` and `FloorFurnace` for heating system types.
150
+ - Allows "exterior wall", "under slab", and "roof deck" for `DuctLocation`.
151
+ - Allows "wood" and "wood pellets" as fuel types for additional HVAC systems, water heaters, and appliances.
152
+ - Allows `Location` to be provided for `Dishwasher` and `CookingRange`.
153
+ - Allows `BuildingSummary/Site/SiteType` ("urban", "suburban", or "rural") to be provided.
154
+ - Allows user-specified `Refrigerator` and `CookingRange` schedules to be provided.
155
+ - HVAC capacity elements are no longer required; if not provided, ACCA Manual J autosizing calculations will be used (-1 can continue to be used for capacity elements but is discouraged).
156
+ - Duct locations/areas can be defaulted by specifying supply/return `Duct` elements without `DuctSurfaceArea` and `DuctLocation`. `HVACDistribution/DistributionSystemType/AirDistribution/NumberofReturnRegisters` can be optionally provided to inform the default duct area calculations.
157
+ - **[Breaking Change]** Lighting inputs now use `LightingType[LightEmittingDiode | CompactFluorescent | FluorescentTube]` instead of `ThirdPartyCertification="ERI Tier I" or ThirdPartyCertification="ERI Tier II"`.
158
+ - **[Breaking Change]** `HVACDistribution/ConditionedFloorAreaServed` is now required for air distribution systems.
159
+ - **[Breaking Change]** Infiltration and attic ventilation specified using natural air changes per hour now uses `ACHnatural` instead of `extension/ConstantACHnatural`.
160
+ - **[Breaking Change]** The optional `PerformanceAdjustment` input for instantaneous water heaters is now treated as a performance multiplier (e.g., 0.92) instead of derate (e.g., 0.08).
161
+ - Adds ASHRAE 140 Class II test files.
162
+ - SimulationOutputReport reporting measure:
163
+ - New optional timeseries outputs: airflows (e.g., infiltration, mechanical ventilation, natural ventilation, whole house fan) and weather (e.g., temperatures, wind speed, solar).
164
+ - Timeseries frequency can now be set to 'none' as an alternative to setting all include_timeseries_foo variables to false.
165
+ - **[Breaking Change]** Renames "Wood" to "Wood Cord" to better distinguish from "Wood Pellets".
166
+ - Modeling improvements:
167
+ - Improved calculation for infiltration height
168
+ - Infiltration & mechanical ventilation now combined using ASHRAE 62.2 Normative Appendix C.
169
+ - Runtime improvements:
170
+ - Optimized ruby require calls.
171
+ - Skip ViewFactor calculations when not needed (i.e., no conditioned basement).
172
+ - Error-checking:
173
+ - Adds more space type-specific error checking of adjacent surfaces.
174
+ - Adds additional HPXML datatype checks.
175
+ - Adds a warning if a `HVACDistribution` system has ducts entirely within conditioned space and non-zero leakage to the outside.
176
+ - Adds warnings if appliance inputs may be inappropriate and result in negative energy or hot water use.
177
+
178
+ __Bugfixes__
179
+ - Fixes error if there's a `FoundationWall` whose height is less than 0.5 ft.
180
+ - Fixes HVAC defrost control in EnergyPlus model to use "Timed" instead of "OnDemand".
181
+ - Fixes exterior air film and wind exposure for a `FrameFloor` over ambient conditions.
182
+ - Fixes air films for a `FrameFloor` ceiling.
183
+ - Fixes error if there are additional `LightingGroup` elements beyond the ones required.
184
+ - Fixes vented attic ventilation rate.
185
+ - Reported unmet heating/cooling load now correctly excludes latent energy.
186
+ - Ground-source heat pump backup fuel is now correctly honored instead of always using electricity.
187
+
188
+ ## OpenStudio-HPXML v0.9.0 Beta
189
+
190
+ __New Features__
191
+ - **[Breaking Change]** Updates to OpenStudio v3.0.0 and EnergyPlus 9.3
192
+ - Numerous HPXML inputs are now optional with built-in defaulting, particularly for water heating, appliances, and PV. Set the `debug` argument to true to output a in.xml HPXML file with defaults applied for inspection. See the documentation for defaulting equations/assumptions/references.
193
+ - **[Breaking Change]** If clothes washer efficiency inputs are provided, `LabelUsage` is now required.
194
+ - **[Breaking Change]** If dishwasher efficiency inputs are provided, `LabelElectricRate`, `LabelGasRate`, `LabelAnnualGasCost`, and `LabelUsage` are now required.
195
+ - Adds optional specification of simulation controls including timestep and begin/end dates.
196
+ - Adds optional `extension/UsageMultiplier` inputs for appliances, plug loads, lighting, and water fixtures. Can be used to, e.g., reflect high/low usage occupants.
197
+ - Adds ability to model a dehumidifier.
198
+ - Adds ability to model kitchen/bath fans (spot ventilation).
199
+ - Improved desuperheater model; desuperheater can now be connected to heat pump water heaters.
200
+ - Updated clothes washer/dryer and dishwasher models per ANSI/RESNET/ICC 301-2019 Addendum A.
201
+ - Solar thermal systems modeled with `SolarFraction` can now be connected to combi water heating systems.
202
+ - **[Breaking Change]** Replaces optional `epw_output_path` and `osm_output_path` arguments with a single optional `output_dir` argument; adds an optional `debug` argument.
203
+ - **[Breaking Change]** Replaces optional `BuildingConstruction/extension/FractionofOperableWindowArea` with optional `Window/FractionOperable`.
204
+ - **[Breaking Change]** Replaces optional `extension/EPWFileName` with optional `extension/EPWFilePath` to allow absolute paths to be provided as an alternative to just the file name.
205
+ - Replaces REXML xml library with Oga for better runtime performance.
206
+ - Additional error-checking.
207
+ - SimulationOutputReport reporting measure:
208
+ - Now reports wood and wood pellets
209
+ - Can report monthly timeseries values if requested
210
+ - Adds hot water outputs (gallons) for clothes washer, dishwasher, fixtures, and distribution waste.
211
+ - Small improvement to calculation of component loads
212
+
213
+ __Bugfixes__
214
+ - Fixes possible simulation error for buildings with complex HVAC/duct systems.
215
+ - Fixes handling of infiltration induced by duct leakage imbalance (i.e., supply leakage != return leakage). Only affects ducts located in a vented crawlspace or vented attic.
216
+ - Fixes an unsuccessful simulation for buildings where the sum of multiple HVAC systems' fraction load served was slightly above 1 due to rounding.
217
+ - Small fix for interior partition wall thermal mass model.
218
+ - Skip building surfaces with areas that are extremely small.
219
+
220
+ ## OpenStudio-HPXML v0.8.0 Beta
221
+
222
+ __Breaking Changes__
223
+ - Weather cache files are now in .csv instead of .cache format.
224
+ - `extension/StandbyLoss` changed to `StandbyLoss` for indirect water heaters.
225
+ - `Site/extension/DisableNaturalVentilation` changed to `BuildingConstruction/extension/FractionofOperableWindowArea` for more granularity.
226
+
227
+ __New Features__
228
+ - Adds a SimulationOutputReport reporting measure that provides a variety of annual/timeseries outputs in CSV format.
229
+ - Allows modeling of whole-house fans to address cooling.
230
+ - Improved natural ventilation algorithm that reduces the potential for incurring additional heating energy.
231
+ - Optional `HotWaterTemperature` input for water heaters.
232
+ - Optional `CompressorType` input for air conditioners and air-source heat pumps.
233
+ - Allows specifying the EnergyPlus simulation timestep.
234
+ - Runtime performance improvements.
235
+ - Additional HPXML error-checking.
236
+
237
+ __Bugfixes__
238
+ - Fix for central fan integrated supply (CFIS) fan energy.
239
+ - Fix simulation error when `FractionHeatLoadServed` (or `FractionCoolLoadServed`) sums to slightly greater than 1.
240
+ - Fix for running simulations on a different drive (either local or remote network).
241
+ - Fix for HVAC sizing error when latitude is exactly 64 (Big Delta, Alaska).
242
+ - Fixes running simulations when there is no weather cache file.
243
+ - Fixes view factors when conditioned basement foundation walls have a window/door.
244
+ - Fixes weather file download.
245
+ - Allow a building with ceiling fans and without lighting.
246
+
247
+ ## OpenStudio-HPXML v0.7.0 Beta
248
+
249
+ - Initial beta release
@@ -4,11 +4,8 @@ source 'http://rubygems.org'
4
4
 
5
5
  gem 'nokogiri', '~> 1.10'
6
6
  gem 'oga'
7
- gem 'schematron-nokogiri', git: 'http://github.com/shorowit/schematron.git', branch: 'return_context_path'
7
+ gem 'schematron-nokogiri'
8
8
  gem 'rake'
9
9
  gem 'minitest', '~> 5.9'
10
- gem 'ci_reporter_minitest', '~> 1.0.0'
11
- gem 'simplecov'
12
- gem 'codecov'
13
10
  gem 'minitest-reporters'
14
- gem 'minitest-ci' # For CircleCI Automatic test metadata collection
11
+ gem 'parallel'
@@ -3,7 +3,6 @@
3
3
  # Require all gems up front; this is much faster than multiple resource
4
4
  # files lazy loading as needed, as it prevents multiple lookups for the
5
5
  # same gem.
6
- require 'openstudio'
7
6
  require 'pathname'
8
7
  require 'csv'
9
8
  require 'oga'
@@ -11,6 +10,7 @@ require_relative 'resources/airflow'
11
10
  require_relative 'resources/constants'
12
11
  require_relative 'resources/constructions'
13
12
  require_relative 'resources/energyplus'
13
+ require_relative 'resources/generator'
14
14
  require_relative 'resources/geometry'
15
15
  require_relative 'resources/hotwater_appliances'
16
16
  require_relative 'resources/hpxml'
@@ -61,17 +61,34 @@ class HPXMLtoOpenStudio < OpenStudio::Measure::ModelMeasure
61
61
  arg.setDescription('Absolute/relative path of the HPXML file.')
62
62
  args << arg
63
63
 
64
- arg = OpenStudio::Measure::OSArgument.makeStringArgument('output_dir', false)
64
+ arg = OpenStudio::Measure::OSArgument.makeStringArgument('output_dir', true)
65
65
  arg.setDisplayName('Directory for Output Files')
66
66
  arg.setDescription('Absolute/relative path for the output files directory.')
67
67
  args << arg
68
68
 
69
69
  arg = OpenStudio::Measure::OSArgument.makeBoolArgument('debug', false)
70
70
  arg.setDisplayName('Debug Mode?')
71
- arg.setDescription('If enabled: 1) Writes in.osm file, 2) Writes in.xml HPXML file with defaults populated, and 3) Generates additional log output. Any files written will be in the output path specified above.')
71
+ arg.setDescription('If true: 1) Writes in.osm file, 2) Generates additional log output, and 3) Creates all EnergyPlus output files.')
72
72
  arg.setDefaultValue(false)
73
73
  args << arg
74
74
 
75
+ arg = OpenStudio::Measure::OSArgument.makeBoolArgument('add_component_loads', false)
76
+ arg.setDisplayName('Add component loads?')
77
+ arg.setDescription('If true, adds the calculation of heating/cooling component loads (not enabled by default for faster performance).')
78
+ arg.setDefaultValue(false)
79
+ args << arg
80
+
81
+ arg = OpenStudio::Measure::OSArgument.makeBoolArgument('skip_validation', false)
82
+ arg.setDisplayName('Skip Validation?')
83
+ arg.setDescription('If true, bypasses HPXML input validation for faster performance. WARNING: This should only be used if the supplied HPXML file has already been validated against the Schema & Schematron documents.')
84
+ arg.setDefaultValue(false)
85
+ args << arg
86
+
87
+ arg = OpenStudio::Measure::OSArgument.makeStringArgument('building_id', false)
88
+ arg.setDisplayName('BuildingID')
89
+ arg.setDescription('The ID of the HPXML Building. Only required if there are multiple Building elements in the HPXML file.')
90
+ args << arg
91
+
75
92
  return args
76
93
  end
77
94
 
@@ -84,14 +101,17 @@ class HPXMLtoOpenStudio < OpenStudio::Measure::ModelMeasure
84
101
  return false
85
102
  end
86
103
 
87
- tear_down_model(model, runner)
104
+ Geometry.tear_down_model(model, runner)
88
105
 
89
106
  Version.check_openstudio_version()
90
107
 
91
108
  # assign the user inputs to variables
92
109
  hpxml_path = runner.getStringArgumentValue('hpxml_path', user_arguments)
93
- output_dir = runner.getOptionalStringArgumentValue('output_dir', user_arguments)
110
+ output_dir = runner.getStringArgumentValue('output_dir', user_arguments)
111
+ add_component_loads = runner.getBoolArgumentValue('add_component_loads', user_arguments)
94
112
  debug = runner.getBoolArgumentValue('debug', user_arguments)
113
+ skip_validation = runner.getBoolArgumentValue('skip_validation', user_arguments)
114
+ building_id = runner.getOptionalStringArgumentValue('building_id', user_arguments)
95
115
 
96
116
  unless (Pathname.new hpxml_path).absolute?
97
117
  hpxml_path = File.expand_path(File.join(File.dirname(__FILE__), hpxml_path))
@@ -100,25 +120,41 @@ class HPXMLtoOpenStudio < OpenStudio::Measure::ModelMeasure
100
120
  fail "'#{hpxml_path}' does not exist or is not an .xml file."
101
121
  end
102
122
 
103
- if output_dir.is_initialized
104
- output_dir = output_dir.get
105
- unless (Pathname.new output_dir).absolute?
106
- output_dir = File.expand_path(File.join(File.dirname(__FILE__), output_dir))
107
- end
123
+ unless (Pathname.new output_dir).absolute?
124
+ output_dir = File.expand_path(File.join(File.dirname(__FILE__), output_dir))
125
+ end
126
+
127
+ if building_id.is_initialized
128
+ building_id = building_id.get
108
129
  else
109
- output_dir = nil
130
+ building_id = nil
110
131
  end
111
132
 
112
133
  begin
113
- hpxml = HPXML.new(hpxml_path: hpxml_path)
114
-
115
- if not validate_hpxml(runner, hpxml_path, hpxml)
116
- return false
134
+ if skip_validation
135
+ stron_paths = []
136
+ else
137
+ stron_paths = [File.join(File.dirname(__FILE__), 'resources', 'HPXMLvalidator.xml'),
138
+ File.join(File.dirname(__FILE__), 'resources', 'EPvalidator.xml')]
139
+ end
140
+ hpxml = HPXML.new(hpxml_path: hpxml_path, schematron_validators: stron_paths, building_id: building_id)
141
+ hpxml.errors.each do |error|
142
+ runner.registerError(error)
143
+ end
144
+ hpxml.warnings.each do |warning|
145
+ runner.registerWarning(warning)
117
146
  end
147
+ return false unless hpxml.errors.empty?
118
148
 
119
- epw_path, cache_path = process_weather(hpxml, runner, model, output_dir, hpxml_path)
149
+ epw_path, cache_path = process_weather(hpxml, runner, model, hpxml_path)
120
150
 
121
- OSModel.create(hpxml, runner, model, hpxml_path, epw_path, cache_path, output_dir, debug)
151
+ if debug
152
+ epw_output_path = File.join(output_dir, 'in.epw')
153
+ FileUtils.cp(epw_path, epw_output_path)
154
+ end
155
+
156
+ OSModel.create(hpxml, runner, model, hpxml_path, epw_path, cache_path, output_dir,
157
+ add_component_loads, building_id, debug)
122
158
  rescue Exception => e
123
159
  runner.registerError("#{e.message}\n#{e.backtrace.join("\n")}")
124
160
  return false
@@ -127,49 +163,7 @@ class HPXMLtoOpenStudio < OpenStudio::Measure::ModelMeasure
127
163
  return true
128
164
  end
129
165
 
130
- def tear_down_model(model, runner)
131
- # Tear down the existing model if it exists
132
- has_existing_objects = (model.getThermalZones.size > 0)
133
- handles = OpenStudio::UUIDVector.new
134
- model.objects.each do |obj|
135
- handles << obj.handle
136
- end
137
- model.removeObjects(handles)
138
- if has_existing_objects
139
- runner.registerWarning('The model contains existing objects and is being reset.')
140
- end
141
- end
142
-
143
- def validate_hpxml(runner, hpxml_path, hpxml)
144
- schemas_dir = File.join(File.dirname(__FILE__), 'resources')
145
-
146
- is_valid = true
147
-
148
- # Validate input HPXML against schema
149
- XMLHelper.validate(hpxml.doc.to_xml, File.join(schemas_dir, 'HPXML.xsd'), runner).each do |error|
150
- runner.registerError("#{hpxml_path}: #{error}")
151
- is_valid = false
152
- end
153
-
154
- # Validate input HPXML against EnergyPlus Use Case
155
- stron_path = File.join(File.dirname(__FILE__), 'resources', 'EPvalidator.xml')
156
- errors = Validator.run_validator(hpxml.doc, stron_path)
157
- errors.each do |error|
158
- runner.registerError("#{hpxml_path}: #{error}")
159
- is_valid = false
160
- end
161
-
162
- # Check for additional errors
163
- errors = hpxml.check_for_errors()
164
- errors.each do |error|
165
- runner.registerError("#{hpxml_path}: #{error}")
166
- is_valid = false
167
- end
168
-
169
- return is_valid
170
- end
171
-
172
- def process_weather(hpxml, runner, model, output_dir, hpxml_path)
166
+ def process_weather(hpxml, runner, model, hpxml_path)
173
167
  epw_path = hpxml.climate_and_risk_zones.weather_station_epw_filepath
174
168
 
175
169
  if not File.exist? epw_path
@@ -180,6 +174,10 @@ class HPXMLtoOpenStudio < OpenStudio::Measure::ModelMeasure
180
174
  test_epw_path = File.join(File.dirname(__FILE__), '..', 'weather', epw_path)
181
175
  epw_path = test_epw_path if File.exist? test_epw_path
182
176
  end
177
+ if not File.exist? epw_path
178
+ test_epw_path = File.join(File.dirname(__FILE__), '..', '..', 'weather', epw_path)
179
+ epw_path = test_epw_path if File.exist? test_epw_path
180
+ end
183
181
  if not File.exist?(epw_path)
184
182
  fail "'#{epw_path}' could not be found."
185
183
  end
@@ -205,7 +203,8 @@ class HPXMLtoOpenStudio < OpenStudio::Measure::ModelMeasure
205
203
  end
206
204
 
207
205
  class OSModel
208
- def self.create(hpxml, runner, model, hpxml_path, epw_path, cache_path, output_dir, debug)
206
+ def self.create(hpxml, runner, model, hpxml_path, epw_path, cache_path, output_dir,
207
+ add_component_loads, building_id, debug)
209
208
  @hpxml = hpxml
210
209
  @debug = debug
211
210
 
@@ -216,19 +215,18 @@ class OSModel
216
215
  @apply_ashrae140_assumptions = @hpxml.header.apply_ashrae140_assumptions # Hidden feature
217
216
  @apply_ashrae140_assumptions = false if @apply_ashrae140_assumptions.nil?
218
217
 
219
- @schedules_file = nil
220
- if not @hpxml.header.schedules_path.nil?
221
- @schedules_file = SchedulesFile.new(runner: runner, model: model, schedules_path: @hpxml.header.schedules_path, col_names: ScheduleGenerator.col_names)
222
- end
223
-
224
218
  # Init
225
219
 
226
220
  weather, epw_file = Location.apply_weather_file(model, runner, epw_path, cache_path)
227
- check_for_errors()
228
- set_defaults_and_globals(runner, output_dir, epw_file)
229
- weather = Location.apply(model, runner, weather, epw_file, @hpxml)
221
+ set_defaults_and_globals(runner, output_dir, epw_file, weather)
222
+ Location.apply(model, runner, weather, epw_file, @hpxml)
230
223
  add_simulation_params(model)
231
224
 
225
+ @schedules_file = nil
226
+ unless @hpxml.header.schedules_path.nil?
227
+ @schedules_file = SchedulesFile.new(runner: runner, model: model, schedules_path: @hpxml.header.schedules_path, col_names: ScheduleGenerator.col_names.keys)
228
+ end
229
+
232
230
  # Conditioned space/zone
233
231
 
234
232
  spaces = {}
@@ -242,25 +240,24 @@ class OSModel
242
240
  add_rim_joists(runner, model, spaces)
243
241
  add_frame_floors(runner, model, spaces)
244
242
  add_foundation_walls_slabs(runner, model, spaces)
245
- add_interior_shading_schedule(runner, model, weather)
243
+ add_shading_schedule(runner, model, weather)
246
244
  add_windows(runner, model, spaces, weather)
247
245
  add_doors(runner, model, spaces)
248
246
  add_skylights(runner, model, spaces, weather)
249
247
  add_conditioned_floor_area(runner, model, spaces)
250
248
  add_thermal_mass(runner, model, spaces)
251
249
  update_conditioned_basement(runner, model, spaces)
252
- set_zone_volumes(runner, model, spaces)
253
- explode_surfaces(runner, model)
250
+ Geometry.set_zone_volumes(runner, model, spaces, @hpxml, @apply_ashrae140_assumptions)
251
+ Geometry.explode_surfaces(runner, model, @hpxml, @walls_top)
254
252
  add_num_occupants(model, runner, spaces)
255
253
 
256
254
  # HVAC
257
255
 
258
- update_shared_hvac_systems()
259
256
  add_ideal_system(runner, model, spaces, epw_path)
260
257
  add_cooling_system(runner, model, spaces)
261
258
  add_heating_system(runner, model, spaces)
262
259
  add_heat_pump(runner, model, weather, spaces)
263
- add_dehumidifier(runner, model, spaces)
260
+ add_dehumidifiers(runner, model, spaces)
264
261
  add_residual_ideal_system(runner, model, spaces)
265
262
  add_ceiling_fans(runner, model, weather, spaces)
266
263
 
@@ -280,97 +277,32 @@ class OSModel
280
277
  # Other
281
278
 
282
279
  add_airflow(runner, model, weather, spaces)
283
- add_hvac_sizing(runner, model, weather, spaces)
284
- add_furnace_eae(runner, model)
285
280
  add_photovoltaics(runner, model)
286
- add_additional_properties(runner, model, hpxml_path)
287
- add_component_loads_output(runner, model, spaces)
281
+ add_generators(runner, model)
282
+ add_additional_properties(runner, model, hpxml_path, building_id)
283
+
284
+ # Output
285
+
286
+ add_loads_output(runner, model, spaces, add_component_loads)
287
+ add_output_control_files(runner, model)
288
+ # Uncomment to debug EMS
289
+ # add_ems_debug_output(runner, model)
288
290
 
289
291
  # Vacancy
290
- set_vacancy(runner, model)
292
+ unless @schedules_file.nil?
293
+ @schedules_file.set_vacancy
294
+ end
291
295
 
292
- if debug && (not output_dir.nil?)
296
+ if debug
293
297
  osm_output_path = File.join(output_dir, 'in.osm')
294
298
  File.write(osm_output_path, model.to_s)
295
299
  runner.registerInfo("Wrote file: #{osm_output_path}")
296
300
  end
297
-
298
- # Uncomment to debug EMS
299
- # oems = model.getOutputEnergyManagementSystem
300
- # oems.setActuatorAvailabilityDictionaryReporting('Verbose')
301
- # oems.setInternalVariableAvailabilityDictionaryReporting('Verbose')
302
- # oems.setEMSRuntimeLanguageDebugOutputLevel('Verbose')
303
301
  end
304
302
 
305
303
  private
306
304
 
307
- def self.check_for_errors()
308
- # Conditioned space
309
- location = HPXML::LocationLivingSpace
310
- if (@hpxml.roofs.select { |s| s.interior_adjacent_to == location }.size +
311
- @hpxml.frame_floors.select { |s| s.is_ceiling && (s.interior_adjacent_to == location) }.size) == 0
312
- fail 'There must be at least one ceiling/roof adjacent to conditioned space.'
313
- end
314
- if @hpxml.walls.select { |s| (s.interior_adjacent_to == location) && s.is_exterior }.size == 0
315
- fail 'There must be at least one exterior wall adjacent to conditioned space.'
316
- end
317
- if (@hpxml.slabs.select { |s| [location, HPXML::LocationBasementConditioned].include? s.interior_adjacent_to }.size +
318
- @hpxml.frame_floors.select { |s| s.is_floor && (s.interior_adjacent_to == location) }.size) == 0
319
- fail 'There must be at least one floor/slab adjacent to conditioned space.'
320
- end
321
-
322
- # Basement/Crawlspace
323
- [HPXML::LocationBasementConditioned,
324
- HPXML::LocationBasementUnconditioned,
325
- HPXML::LocationCrawlspaceVented,
326
- HPXML::LocationCrawlspaceUnvented].each do |location|
327
- next unless @hpxml.has_space_type(location)
328
-
329
- if location != HPXML::LocationBasementConditioned # HPXML file doesn't need to have FrameFloor between living and conditioned basement
330
- if @hpxml.frame_floors.select { |s| s.is_floor && (s.interior_adjacent_to == HPXML::LocationLivingSpace) && (s.exterior_adjacent_to == location) }.size == 0
331
- fail "There must be at least one ceiling adjacent to #{location}."
332
- end
333
- end
334
- if @hpxml.foundation_walls.select { |s| (s.interior_adjacent_to == location) && s.is_exterior }.size == 0
335
- fail "There must be at least one exterior foundation wall adjacent to #{location}."
336
- end
337
- if @hpxml.slabs.select { |s| s.interior_adjacent_to == location }.size == 0
338
- fail "There must be at least one slab adjacent to #{location}."
339
- end
340
- end
341
-
342
- # Garage
343
- location = HPXML::LocationGarage
344
- if @hpxml.has_space_type(location)
345
- if (@hpxml.roofs.select { |s| s.interior_adjacent_to == location }.size +
346
- @hpxml.frame_floors.select { |s| [s.interior_adjacent_to, s.exterior_adjacent_to].include? location }.size) == 0
347
- fail "There must be at least one roof/ceiling adjacent to #{location}."
348
- end
349
- if (@hpxml.walls.select { |s| (s.interior_adjacent_to == location) && s.is_exterior }.size +
350
- @hpxml.foundation_walls.select { |s| [s.interior_adjacent_to, s.exterior_adjacent_to].include?(location) && s.is_exterior }.size) == 0
351
- fail "There must be at least one exterior wall/foundation wall adjacent to #{location}."
352
- end
353
- if @hpxml.slabs.select { |s| s.interior_adjacent_to == location }.size == 0
354
- fail "There must be at least one slab adjacent to #{location}."
355
- end
356
- end
357
-
358
- # Attic
359
- [HPXML::LocationAtticVented,
360
- HPXML::LocationAtticUnvented].each do |location|
361
- next unless @hpxml.has_space_type(location)
362
-
363
- if @hpxml.roofs.select { |s| s.interior_adjacent_to == location }.size == 0
364
- fail "There must be at least one roof adjacent to #{location}."
365
- end
366
-
367
- if @hpxml.frame_floors.select { |s| s.is_ceiling && [s.interior_adjacent_to, s.exterior_adjacent_to].include?(location) }.size == 0
368
- fail "There must be at least one floor adjacent to #{location}."
369
- end
370
- end
371
- end
372
-
373
- def self.set_defaults_and_globals(runner, output_dir, epw_file)
305
+ def self.set_defaults_and_globals(runner, output_dir, epw_file, weather)
374
306
  # Initialize
375
307
  @remaining_heat_load_frac = 1.0
376
308
  @remaining_cool_load_frac = 1.0
@@ -383,207 +315,40 @@ class OSModel
383
315
  @ncfl = @hpxml.building_construction.number_of_conditioned_floors
384
316
  @ncfl_ag = @hpxml.building_construction.number_of_conditioned_floors_above_grade
385
317
  @nbeds = @hpxml.building_construction.number_of_bedrooms
386
- @min_neighbor_distance = get_min_neighbor_distance()
387
318
  @default_azimuths = get_default_azimuths()
388
- @has_uncond_bsmnt = @hpxml.has_space_type(HPXML::LocationBasementUnconditioned)
389
-
390
- if @hpxml.building_construction.use_only_ideal_air_system.nil?
391
- @hpxml.building_construction.use_only_ideal_air_system = false
392
- end
393
319
 
394
320
  # Apply defaults to HPXML object
395
- HPXMLDefaults.apply(@hpxml, @cfa, @nbeds, @ncfl, @ncfl_ag, @has_uncond_bsmnt, @eri_version, epw_file, runner)
321
+ HPXMLDefaults.apply(@hpxml, @eri_version, weather, epw_file: epw_file)
396
322
 
397
323
  @frac_windows_operable = @hpxml.fraction_of_windows_operable()
398
324
 
399
- if @debug && (not output_dir.nil?)
400
- # Write updated HPXML object to file
401
- hpxml_defaults_path = File.join(output_dir, 'in.xml')
402
- XMLHelper.write_file(@hpxml.to_oga, hpxml_defaults_path)
403
- runner.registerInfo("Wrote file: #{hpxml_defaults_path}")
404
- end
405
- end
325
+ # Write updated HPXML object (w/ defaults) to file for inspection
326
+ hpxml_defaults_path = File.join(output_dir, 'in.xml')
327
+ XMLHelper.write_file(@hpxml.to_oga, hpxml_defaults_path)
406
328
 
407
- def self.add_simulation_params(model)
408
- SimControls.apply(model, @hpxml.header)
329
+ # Now that we've written in.xml, ensure that no capacities/airflows
330
+ # are zero in order to prevent potential E+ errors.
331
+ HVAC.ensure_nonzero_sizing_values(@hpxml)
409
332
  end
410
333
 
411
- def self.set_zone_volumes(runner, model, spaces)
412
- # Living space
413
- spaces[HPXML::LocationLivingSpace].thermalZone.get.setVolume(UnitConversions.convert(@hpxml.building_construction.conditioned_building_volume, 'ft^3', 'm^3'))
414
-
415
- # Basement, crawlspace, garage
416
- spaces.keys.each do |space_type|
417
- next unless [HPXML::LocationBasementUnconditioned, HPXML::LocationCrawlspaceUnvented, HPXML::LocationCrawlspaceVented, HPXML::LocationGarage].include? space_type
418
-
419
- floor_area = @hpxml.slabs.select { |s| s.interior_adjacent_to == space_type }.map { |s| s.area }.sum(0.0)
420
- if space_type == HPXML::LocationGarage
421
- height = 8.0
422
- else
423
- height = @hpxml.foundation_walls.select { |w| w.interior_adjacent_to == space_type }.map { |w| w.height }.max
424
- end
425
-
426
- spaces[space_type].thermalZone.get.setVolume(UnitConversions.convert(floor_area * height, 'ft^3', 'm^3'))
427
- end
428
-
429
- # Attic
430
- spaces.keys.each do |space_type|
431
- next unless [HPXML::LocationAtticUnvented, HPXML::LocationAtticVented].include? space_type
432
-
433
- floor_area = @hpxml.frame_floors.select { |f| [f.interior_adjacent_to, f.exterior_adjacent_to].include? space_type }.map { |s| s.area }.sum(0.0)
434
- roofs = @hpxml.roofs.select { |r| r.interior_adjacent_to == space_type }
435
- avg_pitch = roofs.map { |r| r.pitch }.sum(0.0) / roofs.size
436
-
437
- # Assume square hip roof for volume calculations; energy results are very insensitive to actual volume
438
- length = floor_area**0.5
439
- height = 0.5 * Math.sin(Math.atan(avg_pitch / 12.0)) * length
440
- volume = [floor_area * height / 3.0, 0.01].max
441
-
442
- spaces[space_type].thermalZone.get.setVolume(UnitConversions.convert(volume, 'ft^3', 'm^3'))
443
- end
334
+ def self.add_simulation_params(model)
335
+ SimControls.apply(model, @hpxml)
444
336
  end
445
337
 
446
- def self.explode_surfaces(runner, model)
447
- # Re-position surfaces so as to not shade each other and to make it easier to visualize the building.
448
- # FUTURE: Might be able to use the new self-shading options in E+ 8.9 ShadowCalculation object instead?
449
-
450
- gap_distance = UnitConversions.convert(10.0, 'ft', 'm') # distance between surfaces of the same azimuth
451
- rad90 = UnitConversions.convert(90, 'deg', 'rad')
452
-
453
- # Determine surfaces to shift and distance with which to explode surfaces horizontally outward
454
- surfaces = []
455
- azimuth_lengths = {}
456
- model.getSurfaces.sort.each do |surface|
457
- next unless ['wall', 'roofceiling'].include? surface.surfaceType.downcase
458
- next unless ['outdoors', 'foundation'].include? surface.outsideBoundaryCondition.downcase
459
- next if surface.additionalProperties.getFeatureAsDouble('Tilt').get <= 0 # skip flat roofs
460
-
461
- surfaces << surface
462
- azimuth = surface.additionalProperties.getFeatureAsInteger('Azimuth').get
463
- if azimuth_lengths[azimuth].nil?
464
- azimuth_lengths[azimuth] = 0.0
465
- end
466
- azimuth_lengths[azimuth] += surface.additionalProperties.getFeatureAsDouble('Length').get + gap_distance
467
- end
468
- max_azimuth_length = azimuth_lengths.values.max
469
-
470
- # Using the max length for a given azimuth, calculate the apothem (radius of the incircle) of a regular
471
- # n-sided polygon to create the smallest polygon possible without self-shading. The number of polygon
472
- # sides is defined by the minimum difference between two azimuths.
473
- min_azimuth_diff = 360
474
- azimuths_sorted = azimuth_lengths.keys.sort
475
- azimuths_sorted.each_with_index do |az, idx|
476
- diff1 = (az - azimuths_sorted[(idx + 1) % azimuths_sorted.size]).abs
477
- diff2 = 360.0 - diff1 # opposite direction
478
- if diff1 < min_azimuth_diff
479
- min_azimuth_diff = diff1
480
- end
481
- if diff2 < min_azimuth_diff
482
- min_azimuth_diff = diff2
483
- end
484
- end
485
- if min_azimuth_diff > 0
486
- nsides = [(360.0 / min_azimuth_diff).ceil, 4].max # assume rectangle at the minimum
487
- else
488
- nsides = 4
489
- end
490
- explode_distance = max_azimuth_length / (2.0 * Math.tan(UnitConversions.convert(180.0 / nsides, 'deg', 'rad')))
491
-
492
- add_neighbors(runner, model, max_azimuth_length)
493
-
494
- # Initial distance of shifts at 90-degrees to horizontal outward
495
- azimuth_side_shifts = {}
496
- azimuth_lengths.keys.each do |azimuth|
497
- azimuth_side_shifts[azimuth] = max_azimuth_length / 2.0
498
- end
499
-
500
- # Explode neighbors
501
- model.getShadingSurfaceGroups.each do |shading_surface_group|
502
- next if shading_surface_group.name.to_s != Constants.ObjectNameNeighbors
503
-
504
- shading_surface_group.shadingSurfaces.each do |shading_surface|
505
- azimuth = shading_surface.additionalProperties.getFeatureAsInteger('Azimuth').get
506
- azimuth_rad = UnitConversions.convert(azimuth, 'deg', 'rad')
507
- distance = shading_surface.additionalProperties.getFeatureAsDouble('Distance').get
508
-
509
- unless azimuth_lengths.keys.include? azimuth
510
- fail "A neighbor building has an azimuth (#{azimuth}) not equal to the azimuth of any wall."
511
- end
512
-
513
- # Push out horizontally
514
- distance += explode_distance
515
- transformation = get_surface_transformation(distance, Math::sin(azimuth_rad), Math::cos(azimuth_rad), 0)
516
-
517
- shading_surface.setVertices(transformation * shading_surface.vertices)
518
- end
519
- end
520
-
521
- # Explode walls, windows, doors, roofs, and skylights
522
- surfaces_moved = []
523
-
524
- surfaces.sort.each do |surface|
525
- next if surface.additionalProperties.getFeatureAsDouble('Tilt').get <= 0 # skip flat roofs
526
-
527
- if surface.adjacentSurface.is_initialized
528
- next if surfaces_moved.include? surface.adjacentSurface.get
529
- end
530
-
531
- azimuth = surface.additionalProperties.getFeatureAsInteger('Azimuth').get
532
- azimuth_rad = UnitConversions.convert(azimuth, 'deg', 'rad')
533
-
534
- # Push out horizontally
535
- distance = explode_distance
536
-
537
- if surface.surfaceType.downcase == 'roofceiling'
538
- # Ensure pitched surfaces are positioned outward justified with walls, etc.
539
- tilt = surface.additionalProperties.getFeatureAsDouble('Tilt').get
540
- width = surface.additionalProperties.getFeatureAsDouble('Width').get
541
- distance -= 0.5 * Math.cos(Math.atan(tilt)) * width
542
- end
543
- transformation = get_surface_transformation(distance, Math::sin(azimuth_rad), Math::cos(azimuth_rad), 0)
544
-
545
- surface.setVertices(transformation * surface.vertices)
546
- if surface.adjacentSurface.is_initialized
547
- surface.adjacentSurface.get.setVertices(transformation * surface.adjacentSurface.get.vertices)
548
- end
549
- surface.subSurfaces.each do |subsurface|
550
- subsurface.setVertices(transformation * subsurface.vertices)
551
- next unless subsurface.subSurfaceType.downcase == 'fixedwindow'
552
-
553
- subsurface.shadingSurfaceGroups.each do |overhang_group|
554
- overhang_group.shadingSurfaces.each do |overhang|
555
- overhang.setVertices(transformation * overhang.vertices)
556
- end
557
- end
558
- end
559
-
560
- # Shift at 90-degrees to previous transformation
561
- azimuth_side_shifts[azimuth] -= surface.additionalProperties.getFeatureAsDouble('Length').get / 2.0
562
- transformation_shift = get_surface_transformation(azimuth_side_shifts[azimuth], Math::sin(azimuth_rad + rad90), Math::cos(azimuth_rad + rad90), 0)
338
+ def self.update_conditioned_basement(runner, model, spaces)
339
+ return if @cond_bsmnt_surfaces.empty?
563
340
 
564
- surface.setVertices(transformation_shift * surface.vertices)
565
- if surface.adjacentSurface.is_initialized
566
- surface.adjacentSurface.get.setVertices(transformation_shift * surface.adjacentSurface.get.vertices)
567
- end
568
- surface.subSurfaces.each do |subsurface|
569
- subsurface.setVertices(transformation_shift * subsurface.vertices)
570
- next unless subsurface.subSurfaceType.downcase == 'fixedwindow'
341
+ # Update @cond_bsmnt_surfaces to include subsurfaces
342
+ new_cond_bsmnt_surfaces = @cond_bsmnt_surfaces.dup
343
+ @cond_bsmnt_surfaces.each do |cond_bsmnt_surface|
344
+ next if cond_bsmnt_surface.is_a? OpenStudio::Model::InternalMassDefinition
345
+ next if cond_bsmnt_surface.subSurfaces.empty?
571
346
 
572
- subsurface.shadingSurfaceGroups.each do |overhang_group|
573
- overhang_group.shadingSurfaces.each do |overhang|
574
- overhang.setVertices(transformation_shift * overhang.vertices)
575
- end
576
- end
347
+ cond_bsmnt_surface.subSurfaces.each do |ss|
348
+ new_cond_bsmnt_surfaces << ss
577
349
  end
578
-
579
- azimuth_side_shifts[azimuth] -= (surface.additionalProperties.getFeatureAsDouble('Length').get / 2.0 + gap_distance)
580
-
581
- surfaces_moved << surface
582
350
  end
583
- end
584
-
585
- def self.update_conditioned_basement(runner, model, spaces)
586
- return if @cond_bsmnt_surfaces.empty?
351
+ @cond_bsmnt_surfaces = new_cond_bsmnt_surfaces.dup
587
352
 
588
353
  update_solar_absorptances(runner, model)
589
354
  assign_view_factors(runner, model, spaces)
@@ -592,7 +357,19 @@ class OSModel
592
357
  def self.update_solar_absorptances(runner, model)
593
358
  # modify conditioned basement surface properties
594
359
  # zero out interior solar absorptance in conditioned basement
360
+
595
361
  @cond_bsmnt_surfaces.each do |cond_bsmnt_surface|
362
+ # skip windows because windows don't have such property to change.
363
+ next if cond_bsmnt_surface.is_a?(OpenStudio::Model::SubSurface) && (cond_bsmnt_surface.subSurfaceType.downcase == 'fixedwindow')
364
+
365
+ adj_surface = nil
366
+ if not cond_bsmnt_surface.is_a? OpenStudio::Model::InternalMassDefinition
367
+ if not cond_bsmnt_surface.is_a? OpenStudio::Model::SubSurface
368
+ adj_surface = cond_bsmnt_surface.adjacentSurface.get if cond_bsmnt_surface.adjacentSurface.is_initialized
369
+ else
370
+ adj_surface = cond_bsmnt_surface.adjacentSubSurface.get if cond_bsmnt_surface.adjacentSubSurface.is_initialized
371
+ end
372
+ end
596
373
  const = cond_bsmnt_surface.construction.get
597
374
  layered_const = const.to_LayeredConstruction.get
598
375
  innermost_material = layered_const.layers[layered_const.numLayers() - 1].to_StandardOpaqueMaterial.get
@@ -622,6 +399,13 @@ class OSModel
622
399
  innermost_material = layered_const.layers[layered_const.numLayers() - 1].to_StandardOpaqueMaterial.get
623
400
  innermost_material.setSolarAbsorptance(0.0)
624
401
  innermost_material.setVisibleAbsorptance(0.0)
402
+ next if adj_surface.nil?
403
+
404
+ # Create new construction in case of shared construciton.
405
+ layered_const_adj = OpenStudio::Model::Construction.new(model)
406
+ layered_const_adj.setName(cond_bsmnt_surface.construction.get.name.get + ' Reversed Bsmnt')
407
+ adj_surface.setConstruction(layered_const_adj)
408
+ layered_const_adj.setLayers(cond_bsmnt_surface.construction.get.to_LayeredConstruction.get.layers.reverse())
625
409
  end
626
410
  end
627
411
 
@@ -643,8 +427,7 @@ class OSModel
643
427
 
644
428
  all_surfaces.each do |surface|
645
429
  if @cond_bsmnt_surfaces.include?(surface) ||
646
- ((@cond_bsmnt_surfaces.include? surface.internalMassDefinition) if surface.is_a? OpenStudio::Model::InternalMass) ||
647
- ((@cond_bsmnt_surfaces.include? surface.surface.get) if surface.is_a? OpenStudio::Model::SubSurface)
430
+ ((@cond_bsmnt_surfaces.include? surface.internalMassDefinition) if surface.is_a? OpenStudio::Model::InternalMass)
648
431
  cond_base_surfaces << surface
649
432
  else
650
433
  lv_surfaces << surface
@@ -669,7 +452,7 @@ class OSModel
669
452
  else
670
453
  vf = vf_map_cb[from_surface][to_surface]
671
454
  end
672
- next if vf < 0.01
455
+ next if vf < 0.05 # Skip small view factors to reduce runtime
673
456
 
674
457
  os_vf = OpenStudio::Model::ViewFactor.new(from_surface, to_surface, vf.round(10))
675
458
  zone_prop.addViewFactor(os_vf)
@@ -759,160 +542,26 @@ class OSModel
759
542
  return vf_map
760
543
  end
761
544
 
762
- # FUTURE: Move this method and many below to geometry.rb
763
- def self.create_space_and_zone(model, spaces, space_type)
764
- if not spaces.keys.include? space_type
765
- thermal_zone = OpenStudio::Model::ThermalZone.new(model)
766
- thermal_zone.setName(space_type)
767
-
768
- space = OpenStudio::Model::Space.new(model)
769
- space.setName(space_type)
770
-
771
- st = OpenStudio::Model::SpaceType.new(model)
772
- st.setStandardsSpaceType(space_type)
773
- space.setSpaceType(st)
774
-
775
- space.setThermalZone(thermal_zone)
776
- spaces[space_type] = space
777
- end
778
- end
779
-
780
- def self.get_surface_transformation(offset, x, y, z)
781
- x = UnitConversions.convert(x, 'ft', 'm')
782
- y = UnitConversions.convert(y, 'ft', 'm')
783
- z = UnitConversions.convert(z, 'ft', 'm')
784
-
785
- m = OpenStudio::Matrix.new(4, 4, 0)
786
- m[0, 0] = 1
787
- m[1, 1] = 1
788
- m[2, 2] = 1
789
- m[3, 3] = 1
790
- m[0, 3] = x * offset
791
- m[1, 3] = y * offset
792
- m[2, 3] = z.abs * offset
793
-
794
- return OpenStudio::Transformation.new(m)
795
- end
796
-
797
- def self.add_floor_polygon(x, y, z)
798
- x = UnitConversions.convert(x, 'ft', 'm')
799
- y = UnitConversions.convert(y, 'ft', 'm')
800
- z = UnitConversions.convert(z, 'ft', 'm')
801
-
802
- vertices = OpenStudio::Point3dVector.new
803
- vertices << OpenStudio::Point3d.new(0 - x / 2, 0 - y / 2, z)
804
- vertices << OpenStudio::Point3d.new(0 - x / 2, y / 2, z)
805
- vertices << OpenStudio::Point3d.new(x / 2, y / 2, z)
806
- vertices << OpenStudio::Point3d.new(x / 2, 0 - y / 2, z)
807
-
808
- return vertices
809
- end
810
-
811
- def self.add_wall_polygon(x, y, z, azimuth = 0, offsets = [0] * 4, subsurface_area = 0)
812
- x = UnitConversions.convert(x, 'ft', 'm')
813
- y = UnitConversions.convert(y, 'ft', 'm')
814
- z = UnitConversions.convert(z, 'ft', 'm')
815
-
816
- vertices = OpenStudio::Point3dVector.new
817
- vertices << OpenStudio::Point3d.new(0 - (x / 2) - offsets[1], 0, z - offsets[0])
818
- vertices << OpenStudio::Point3d.new(0 - (x / 2) - offsets[1], 0, z + y + offsets[2])
819
- if subsurface_area > 0
820
- subsurface_area = UnitConversions.convert(subsurface_area, 'ft^2', 'm^2')
821
- sub_length = x / 10.0
822
- sub_height = subsurface_area / sub_length
823
- if sub_height >= y
824
- sub_height = y - 0.1
825
- sub_length = subsurface_area / sub_height
826
- end
827
- vertices << OpenStudio::Point3d.new(x - (x / 2) + offsets[3] - sub_length, 0, z + y + offsets[2])
828
- vertices << OpenStudio::Point3d.new(x - (x / 2) + offsets[3] - sub_length, 0, z + y + offsets[2] - sub_height)
829
- vertices << OpenStudio::Point3d.new(x - (x / 2) + offsets[3], 0, z + y + offsets[2] - sub_height)
830
- else
831
- vertices << OpenStudio::Point3d.new(x - (x / 2) + offsets[3], 0, z + y + offsets[2])
832
- end
833
- vertices << OpenStudio::Point3d.new(x - (x / 2) + offsets[3], 0, z - offsets[0])
834
-
835
- # Rotate about the z axis
836
- azimuth_rad = UnitConversions.convert(azimuth, 'deg', 'rad')
837
- m = OpenStudio::Matrix.new(4, 4, 0)
838
- m[0, 0] = Math::cos(-azimuth_rad)
839
- m[1, 1] = Math::cos(-azimuth_rad)
840
- m[0, 1] = -Math::sin(-azimuth_rad)
841
- m[1, 0] = Math::sin(-azimuth_rad)
842
- m[2, 2] = 1
843
- m[3, 3] = 1
844
- transformation = OpenStudio::Transformation.new(m)
845
-
846
- return transformation * vertices
847
- end
848
-
849
- def self.add_roof_polygon(x, y, z, azimuth = 0, tilt = 0.5)
850
- x = UnitConversions.convert(x, 'ft', 'm')
851
- y = UnitConversions.convert(y, 'ft', 'm')
852
- z = UnitConversions.convert(z, 'ft', 'm')
853
-
854
- vertices = OpenStudio::Point3dVector.new
855
- vertices << OpenStudio::Point3d.new(x / 2, -y / 2, 0)
856
- vertices << OpenStudio::Point3d.new(x / 2, y / 2, 0)
857
- vertices << OpenStudio::Point3d.new(-x / 2, y / 2, 0)
858
- vertices << OpenStudio::Point3d.new(-x / 2, -y / 2, 0)
859
-
860
- # Rotate about the x axis
861
- m = OpenStudio::Matrix.new(4, 4, 0)
862
- m[0, 0] = 1
863
- m[1, 1] = Math::cos(Math::atan(tilt))
864
- m[1, 2] = -Math::sin(Math::atan(tilt))
865
- m[2, 1] = Math::sin(Math::atan(tilt))
866
- m[2, 2] = Math::cos(Math::atan(tilt))
867
- m[3, 3] = 1
868
- transformation = OpenStudio::Transformation.new(m)
869
- vertices = transformation * vertices
870
-
871
- # Rotate about the z axis
872
- azimuth_rad = UnitConversions.convert(azimuth, 'deg', 'rad')
873
- rad180 = UnitConversions.convert(180, 'deg', 'rad')
874
- m = OpenStudio::Matrix.new(4, 4, 0)
875
- m[0, 0] = Math::cos(rad180 - azimuth_rad)
876
- m[1, 1] = Math::cos(rad180 - azimuth_rad)
877
- m[0, 1] = -Math::sin(rad180 - azimuth_rad)
878
- m[1, 0] = Math::sin(rad180 - azimuth_rad)
879
- m[2, 2] = 1
880
- m[3, 3] = 1
881
- transformation = OpenStudio::Transformation.new(m)
882
- vertices = transformation * vertices
883
-
884
- # Shift up by z
885
- new_vertices = OpenStudio::Point3dVector.new
886
- vertices.each do |vertex|
887
- new_vertices << OpenStudio::Point3d.new(vertex.x, vertex.y, vertex.z + z)
888
- end
889
-
890
- return new_vertices
891
- end
892
-
893
- def self.add_ceiling_polygon(x, y, z)
894
- return OpenStudio::reverse(add_floor_polygon(x, y, z))
895
- end
896
-
897
545
  def self.add_num_occupants(model, runner, spaces)
898
546
  # Occupants
899
547
  num_occ = @hpxml.building_occupancy.number_of_residents
900
- if num_occ > 0
901
- occ_gain, hrs_per_day, sens_frac, lat_frac = Geometry.get_occupancy_default_values()
902
- weekday_sch = Schedule.OccupantsWeekdayFractions
903
- weekday_sch_sum = weekday_sch.split(',').map(&:to_f).sum(0.0)
904
- if (weekday_sch_sum - hrs_per_day).abs > 0.1
905
- fail 'Occupancy schedule inconsistent with hrs_per_day.'
906
- end
548
+ return if num_occ <= 0
907
549
 
908
- weekend_sch = Schedule.OccupantsWeekendFractions
909
- monthly_sch = Schedule.OccupantsMonthlyMultipliers
910
-
911
- Geometry.process_occupants(model, num_occ, occ_gain, sens_frac, lat_frac, weekday_sch, weekend_sch, monthly_sch, @cfa, @nbeds, spaces[HPXML::LocationLivingSpace], @schedules_file)
912
- end
550
+ Geometry.apply_occupants(model, num_occ, @cfa, spaces[HPXML::LocationLivingSpace], @schedules_file)
913
551
  end
914
552
 
915
553
  def self.get_default_azimuths()
554
+ def self.sanitize_azimuth(azimuth)
555
+ # Ensure 0 <= orientation < 360
556
+ while azimuth < 0
557
+ azimuth += 360
558
+ end
559
+ while azimuth >= 360
560
+ azimuth -= 360
561
+ end
562
+ return azimuth
563
+ end
564
+
916
565
  # Returns a list of four azimuths (facing each direction). Determined based
917
566
  # on the primary azimuth, as defined by the azimuth with the largest surface
918
567
  # area, plus azimuths that are offset by 90/180/270 degrees. Used for
@@ -937,33 +586,22 @@ class OSModel
937
586
  sanitize_azimuth(primary_azimuth + 270)].sort
938
587
  end
939
588
 
940
- def self.sanitize_azimuth(azimuth)
941
- # Ensure 0 <= orientation < 360
942
- while azimuth < 0
943
- azimuth += 360
944
- end
945
- while azimuth >= 360
946
- azimuth -= 360
947
- end
948
- return azimuth
949
- end
950
-
951
589
  def self.create_or_get_space(model, spaces, spacetype)
952
590
  if spaces[spacetype].nil?
953
- create_space_and_zone(model, spaces, spacetype)
591
+ Geometry.create_space_and_zone(model, spaces, spacetype)
954
592
  end
955
593
  return spaces[spacetype]
956
594
  end
957
595
 
958
596
  def self.add_roofs(runner, model, spaces)
959
597
  @hpxml.roofs.each do |roof|
960
- next if roof.net_area < 0.1 # skip modeling net surface area for surfaces comprised entirely of subsurface area
598
+ next if roof.net_area < 1.0 # skip modeling net surface area for surfaces comprised entirely of subsurface area
961
599
 
962
600
  if roof.azimuth.nil?
963
601
  if roof.pitch > 0
964
602
  azimuths = @default_azimuths # Model as four directions for average exterior incident solar
965
603
  else
966
- azimuths = [90] # Arbitrary azimuth for flat roof
604
+ azimuths = [@default_azimuths[0]] # Arbitrary azimuth for flat roof
967
605
  end
968
606
  else
969
607
  azimuths = [roof.azimuth]
@@ -977,7 +615,8 @@ class OSModel
977
615
  tilt = roof.pitch / 12.0
978
616
  z_origin = @walls_top + 0.5 * Math.sin(Math.atan(tilt)) * width
979
617
 
980
- surface = OpenStudio::Model::Surface.new(add_roof_polygon(length, width, z_origin, azimuth, tilt), model)
618
+ vertices = Geometry.create_roof_vertices(length, width, z_origin, azimuth, tilt)
619
+ surface = OpenStudio::Model::Surface.new(vertices, model)
981
620
  surfaces << surface
982
621
  surface.additionalProperties.setFeature('Length', length)
983
622
  surface.additionalProperties.setFeature('Width', width)
@@ -1003,6 +642,7 @@ class OSModel
1003
642
  if has_radiant_barrier
1004
643
  radiant_barrier_grade = roof.radiant_barrier_grade
1005
644
  end
645
+ # FUTURE: Create Constructions.get_air_film(surface) method; use in measure.rb and hpxml_translator_test.rb
1006
646
  inside_film = Material.AirFilmRoof(Geometry.get_roof_pitch([surfaces[0]]))
1007
647
  outside_film = Material.AirFilmOutside
1008
648
  mat_roofing = Material.RoofMaterial(roof.roof_type, emitt, solar_abs)
@@ -1016,14 +656,14 @@ class OSModel
1016
656
 
1017
657
  if roof.is_thermal_boundary
1018
658
  constr_sets = [
659
+ WoodStudConstructionSet.new(Material.Stud2x(8.0), 0.07, 20.0, 0.75, 0.5, mat_roofing), # 2x8, 24" o.c. + R20
1019
660
  WoodStudConstructionSet.new(Material.Stud2x(8.0), 0.07, 10.0, 0.75, 0.5, mat_roofing), # 2x8, 24" o.c. + R10
1020
- WoodStudConstructionSet.new(Material.Stud2x(8.0), 0.07, 5.0, 0.75, 0.5, mat_roofing), # 2x8, 24" o.c. + R5
1021
661
  WoodStudConstructionSet.new(Material.Stud2x(8.0), 0.07, 0.0, 0.75, 0.5, mat_roofing), # 2x8, 24" o.c.
1022
662
  WoodStudConstructionSet.new(Material.Stud2x6, 0.07, 0.0, 0.75, 0.5, mat_roofing), # 2x6, 24" o.c.
1023
663
  WoodStudConstructionSet.new(Material.Stud2x4, 0.07, 0.0, 0.5, 0.5, mat_roofing), # 2x4, 16" o.c.
1024
664
  WoodStudConstructionSet.new(Material.Stud2x4, 0.01, 0.0, 0.0, 0.0, mat_roofing), # Fallback
1025
665
  ]
1026
- match, constr_set, cavity_r = pick_wood_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, roof.id)
666
+ match, constr_set, cavity_r = Constructions.pick_wood_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, roof.id)
1027
667
 
1028
668
  Constructions.apply_closed_cavity_roof(runner, model, surfaces, "#{roof.id} construction",
1029
669
  cavity_r, install_grade,
@@ -1039,7 +679,7 @@ class OSModel
1039
679
  GenericConstructionSet.new(0.0, 0.5, 0.0, mat_roofing), # Standard
1040
680
  GenericConstructionSet.new(0.0, 0.0, 0.0, mat_roofing), # Fallback
1041
681
  ]
1042
- match, constr_set, layer_r = pick_generic_construction_set(assembly_r, constr_sets, inside_film, outside_film, roof.id)
682
+ match, constr_set, layer_r = Constructions.pick_generic_construction_set(assembly_r, constr_sets, inside_film, outside_film, roof.id)
1043
683
 
1044
684
  cavity_r = 0
1045
685
  cavity_ins_thick_in = 0
@@ -1053,13 +693,13 @@ class OSModel
1053
693
  mat_roofing, has_radiant_barrier,
1054
694
  inside_film, outside_film, radiant_barrier_grade)
1055
695
  end
1056
- check_surface_assembly_rvalue(runner, surfaces, inside_film, outside_film, assembly_r, match)
696
+ Constructions.check_surface_assembly_rvalue(runner, surfaces, inside_film, outside_film, assembly_r, match)
1057
697
  end
1058
698
  end
1059
699
 
1060
700
  def self.add_walls(runner, model, spaces)
1061
701
  @hpxml.walls.each do |wall|
1062
- next if wall.net_area < 0.1 # skip modeling net surface area for surfaces comprised entirely of subsurface area
702
+ next if wall.net_area < 1.0 # skip modeling net surface area for surfaces comprised entirely of subsurface area
1063
703
 
1064
704
  if wall.azimuth.nil?
1065
705
  if wall.is_exterior
@@ -1078,7 +718,8 @@ class OSModel
1078
718
  length = (wall.net_area / height) / azimuths.size
1079
719
  z_origin = @foundation_top
1080
720
 
1081
- surface = OpenStudio::Model::Surface.new(add_wall_polygon(length, height, z_origin, azimuth), model)
721
+ vertices = Geometry.create_wall_vertices(length, height, z_origin, azimuth)
722
+ surface = OpenStudio::Model::Surface.new(vertices, model)
1082
723
  surfaces << surface
1083
724
  surface.additionalProperties.setFeature('Length', length)
1084
725
  surface.additionalProperties.setFeature('Azimuth', azimuth)
@@ -1122,8 +763,8 @@ class OSModel
1122
763
  outside_film = Material.AirFilmOutsideASHRAE140
1123
764
  end
1124
765
 
1125
- apply_wall_construction(runner, model, surfaces, wall, wall.id, wall.wall_type, wall.insulation_assembly_r_value,
1126
- drywall_thick_in, inside_film, outside_film, mat_ext_finish)
766
+ Constructions.apply_wall_construction(runner, model, surfaces, wall, wall.id, wall.wall_type, wall.insulation_assembly_r_value,
767
+ drywall_thick_in, inside_film, outside_film, mat_ext_finish)
1127
768
  end
1128
769
  end
1129
770
 
@@ -1146,7 +787,8 @@ class OSModel
1146
787
  length = (rim_joist.area / height) / azimuths.size
1147
788
  z_origin = @foundation_top
1148
789
 
1149
- surface = OpenStudio::Model::Surface.new(add_wall_polygon(length, height, z_origin, azimuth), model)
790
+ vertices = Geometry.create_wall_vertices(length, height, z_origin, azimuth)
791
+ surface = OpenStudio::Model::Surface.new(vertices, model)
1150
792
  surfaces << surface
1151
793
  surface.additionalProperties.setFeature('Length', length)
1152
794
  surface.additionalProperties.setFeature('Azimuth', azimuth)
@@ -1185,12 +827,12 @@ class OSModel
1185
827
  assembly_r = rim_joist.insulation_assembly_r_value
1186
828
 
1187
829
  constr_sets = [
830
+ WoodStudConstructionSet.new(Material.Stud2x(2.0), 0.17, 20.0, 2.0, drywall_thick_in, mat_ext_finish), # 2x4 + R20
1188
831
  WoodStudConstructionSet.new(Material.Stud2x(2.0), 0.17, 10.0, 2.0, drywall_thick_in, mat_ext_finish), # 2x4 + R10
1189
- WoodStudConstructionSet.new(Material.Stud2x(2.0), 0.17, 5.0, 2.0, drywall_thick_in, mat_ext_finish), # 2x4 + R5
1190
832
  WoodStudConstructionSet.new(Material.Stud2x(2.0), 0.17, 0.0, 2.0, drywall_thick_in, mat_ext_finish), # 2x4
1191
833
  WoodStudConstructionSet.new(Material.Stud2x(2.0), 0.01, 0.0, 0.0, 0.0, mat_ext_finish), # Fallback
1192
834
  ]
1193
- match, constr_set, cavity_r = pick_wood_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, rim_joist.id)
835
+ match, constr_set, cavity_r = Constructions.pick_wood_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, rim_joist.id)
1194
836
  install_grade = 1
1195
837
 
1196
838
  Constructions.apply_rim_joist(runner, model, surfaces, rim_joist, "#{rim_joist.id} construction",
@@ -1198,7 +840,7 @@ class OSModel
1198
840
  constr_set.drywall_thick_in, constr_set.osb_thick_in,
1199
841
  constr_set.rigid_r, constr_set.exterior_material,
1200
842
  inside_film, outside_film)
1201
- check_surface_assembly_rvalue(runner, surfaces, inside_film, outside_film, assembly_r, match)
843
+ Constructions.check_surface_assembly_rvalue(runner, surfaces, inside_film, outside_film, assembly_r, match)
1202
844
  end
1203
845
  end
1204
846
 
@@ -1214,12 +856,15 @@ class OSModel
1214
856
  end
1215
857
 
1216
858
  if frame_floor.is_ceiling
1217
- surface = OpenStudio::Model::Surface.new(add_ceiling_polygon(length, width, z_origin), model)
859
+ vertices = Geometry.create_ceiling_vertices(length, width, z_origin, @default_azimuths)
860
+ surface = OpenStudio::Model::Surface.new(vertices, model)
1218
861
  surface.additionalProperties.setFeature('SurfaceType', 'Ceiling')
1219
862
  else
1220
- surface = OpenStudio::Model::Surface.new(add_floor_polygon(length, width, z_origin), model)
863
+ vertices = Geometry.create_floor_vertices(length, width, z_origin, @default_azimuths)
864
+ surface = OpenStudio::Model::Surface.new(vertices, model)
1221
865
  surface.additionalProperties.setFeature('SurfaceType', 'Floor')
1222
866
  end
867
+ surface.additionalProperties.setFeature('Tilt', 0.0)
1223
868
  set_surface_interior(model, spaces, surface, frame_floor)
1224
869
  set_surface_exterior(model, spaces, surface, frame_floor)
1225
870
  surface.setName(frame_floor.id)
@@ -1265,6 +910,7 @@ class OSModel
1265
910
  end
1266
911
  end
1267
912
  constr_sets = [
913
+ WoodStudConstructionSet.new(Material.Stud2x6, 0.10, 20.0, 0.75, 0.0, covering), # 2x6, 24" o.c. + R20
1268
914
  WoodStudConstructionSet.new(Material.Stud2x6, 0.10, 10.0, 0.75, 0.0, covering), # 2x6, 24" o.c. + R10
1269
915
  WoodStudConstructionSet.new(Material.Stud2x6, 0.10, 0.0, 0.75, 0.0, covering), # 2x6, 24" o.c.
1270
916
  WoodStudConstructionSet.new(Material.Stud2x4, 0.13, 0.0, 0.5, 0.0, covering), # 2x4, 16" o.c.
@@ -1273,7 +919,7 @@ class OSModel
1273
919
  end
1274
920
  assembly_r = frame_floor.insulation_assembly_r_value
1275
921
 
1276
- match, constr_set, cavity_r = pick_wood_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, frame_floor.id)
922
+ match, constr_set, cavity_r = Constructions.pick_wood_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, frame_floor.id)
1277
923
 
1278
924
  install_grade = 1
1279
925
  if frame_floor.is_ceiling
@@ -1291,7 +937,7 @@ class OSModel
1291
937
  constr_set.exterior_material, inside_film, outside_film)
1292
938
  end
1293
939
 
1294
- check_surface_assembly_rvalue(runner, [surface], inside_film, outside_film, assembly_r, match)
940
+ Constructions.check_surface_assembly_rvalue(runner, [surface], inside_film, outside_film, assembly_r, match)
1295
941
  end
1296
942
  end
1297
943
 
@@ -1304,7 +950,7 @@ class OSModel
1304
950
  slabs = []
1305
951
  @hpxml.foundation_walls.each do |foundation_wall|
1306
952
  next unless foundation_wall.interior_adjacent_to == foundation_type
1307
- next if foundation_wall.net_area < 0.1 # skip modeling net surface area for surfaces comprised entirely of subsurface area
953
+ next if foundation_wall.net_area < 1.0 # skip modeling net surface area for surfaces comprised entirely of subsurface area
1308
954
 
1309
955
  fnd_walls << foundation_wall
1310
956
  end
@@ -1312,6 +958,7 @@ class OSModel
1312
958
  next unless slab.interior_adjacent_to == foundation_type
1313
959
 
1314
960
  slabs << slab
961
+ slab.exposed_perimeter = [slab.exposed_perimeter, 1.0].max # minimum value to prevent error if no exposed slab
1315
962
  end
1316
963
 
1317
964
  # Calculate combinations of slabs/walls for each Kiva instance
@@ -1379,7 +1026,7 @@ class OSModel
1379
1026
 
1380
1027
  # For each slab, create a no-wall Kiva slab instance if needed.
1381
1028
  slabs.each do |slab|
1382
- next unless no_wall_slab_exp_perim[slab] > 0.1
1029
+ next unless no_wall_slab_exp_perim[slab] > 1.0
1383
1030
 
1384
1031
  z_origin = 0
1385
1032
  slab_area = total_slab_area * no_wall_slab_exp_perim[slab] / total_slab_exp_perim
@@ -1396,7 +1043,7 @@ class OSModel
1396
1043
 
1397
1044
  ag_height = foundation_wall.height - foundation_wall.depth_below_grade
1398
1045
  ag_net_area = foundation_wall.net_area * ag_height / foundation_wall.height
1399
- next if ag_net_area < 0.1
1046
+ next if ag_net_area < 1.0
1400
1047
 
1401
1048
  length = ag_net_area / ag_height
1402
1049
  z_origin = -1 * ag_height
@@ -1406,7 +1053,8 @@ class OSModel
1406
1053
  azimuth = foundation_wall.azimuth
1407
1054
  end
1408
1055
 
1409
- surface = OpenStudio::Model::Surface.new(add_wall_polygon(length, ag_height, z_origin, azimuth), model)
1056
+ vertices = Geometry.create_wall_vertices(length, ag_height, z_origin, azimuth)
1057
+ surface = OpenStudio::Model::Surface.new(vertices, model)
1410
1058
  surface.additionalProperties.setFeature('Length', length)
1411
1059
  surface.additionalProperties.setFeature('Azimuth', azimuth)
1412
1060
  surface.additionalProperties.setFeature('Tilt', 90.0)
@@ -1437,8 +1085,8 @@ class OSModel
1437
1085
  end
1438
1086
  mat_ext_finish = nil
1439
1087
 
1440
- apply_wall_construction(runner, model, [surface], foundation_wall, foundation_wall.id, wall_type, assembly_r,
1441
- drywall_thick_in, inside_film, outside_film, mat_ext_finish)
1088
+ Constructions.apply_wall_construction(runner, model, [surface], foundation_wall, foundation_wall.id, wall_type, assembly_r,
1089
+ drywall_thick_in, inside_film, outside_film, mat_ext_finish)
1442
1090
  end
1443
1091
  end
1444
1092
  end
@@ -1471,7 +1119,8 @@ class OSModel
1471
1119
  subsurface_area = 0
1472
1120
  end
1473
1121
 
1474
- surface = OpenStudio::Model::Surface.new(add_wall_polygon(length, height, z_origin, azimuth, [0] * 4, subsurface_area), model)
1122
+ vertices = Geometry.create_wall_vertices(length, height, z_origin, azimuth, subsurface_area: subsurface_area)
1123
+ surface = OpenStudio::Model::Surface.new(vertices, model)
1475
1124
  surface.additionalProperties.setFeature('Length', length)
1476
1125
  surface.additionalProperties.setFeature('Azimuth', azimuth)
1477
1126
  surface.additionalProperties.setFeature('Tilt', 90.0)
@@ -1521,7 +1170,7 @@ class OSModel
1521
1170
  ext_rigid_r, int_rigid_r, drywall_thick_in, concrete_thick_in, height_ag)
1522
1171
 
1523
1172
  if not assembly_r.nil?
1524
- check_surface_assembly_rvalue(runner, [surface], inside_film, nil, assembly_r, match)
1173
+ Constructions.check_surface_assembly_rvalue(runner, [surface], inside_film, nil, assembly_r, match)
1525
1174
  end
1526
1175
 
1527
1176
  return surface.adjacentFoundation.get
@@ -1540,7 +1189,8 @@ class OSModel
1540
1189
  slab_length = slab_tot_perim / 4.0 + Math.sqrt(sqrt_term) / 4.0
1541
1190
  slab_width = slab_tot_perim / 4.0 - Math.sqrt(sqrt_term) / 4.0
1542
1191
 
1543
- surface = OpenStudio::Model::Surface.new(add_floor_polygon(slab_length, slab_width, z_origin), model)
1192
+ vertices = Geometry.create_floor_vertices(slab_length, slab_width, z_origin, @default_azimuths)
1193
+ surface = OpenStudio::Model::Surface.new(vertices, model)
1544
1194
  surface.setName(slab.id)
1545
1195
  surface.setSurfaceType('Floor')
1546
1196
  surface.setOutsideBoundaryCondition('Foundation')
@@ -1593,7 +1243,8 @@ class OSModel
1593
1243
  sum_cfa = 0.0
1594
1244
  @hpxml.frame_floors.each do |frame_floor|
1595
1245
  next unless frame_floor.is_floor
1596
- next unless frame_floor.interior_adjacent_to == HPXML::LocationLivingSpace
1246
+ next unless [HPXML::LocationLivingSpace, HPXML::LocationBasementConditioned].include?(frame_floor.interior_adjacent_to) ||
1247
+ [HPXML::LocationLivingSpace, HPXML::LocationBasementConditioned].include?(frame_floor.exterior_adjacent_to)
1597
1248
 
1598
1249
  sum_cfa += frame_floor.area
1599
1250
  end
@@ -1604,14 +1255,18 @@ class OSModel
1604
1255
  end
1605
1256
 
1606
1257
  addtl_cfa = @cfa - sum_cfa
1607
- return unless addtl_cfa > 0.1
1258
+
1259
+ fail if addtl_cfa < -1.0 # Allow some rounding; EPvalidator.xml should prevent this
1260
+
1261
+ return unless addtl_cfa > 1.0 # Allow some rounding
1608
1262
 
1609
1263
  floor_width = Math::sqrt(addtl_cfa)
1610
1264
  floor_length = addtl_cfa / floor_width
1611
1265
  z_origin = @foundation_top + 8.0 * (@ncfl_ag - 1)
1612
1266
 
1613
1267
  # Add floor surface
1614
- floor_surface = OpenStudio::Model::Surface.new(add_floor_polygon(-floor_width, -floor_length, z_origin), model)
1268
+ vertices = Geometry.create_floor_vertices(floor_length, floor_width, z_origin, @default_azimuths)
1269
+ floor_surface = OpenStudio::Model::Surface.new(vertices, model)
1615
1270
 
1616
1271
  floor_surface.setSunExposure('NoSun')
1617
1272
  floor_surface.setWindExposure('NoWind')
@@ -1620,9 +1275,11 @@ class OSModel
1620
1275
  floor_surface.setSpace(create_or_get_space(model, spaces, HPXML::LocationLivingSpace))
1621
1276
  floor_surface.setOutsideBoundaryCondition('Adiabatic')
1622
1277
  floor_surface.additionalProperties.setFeature('SurfaceType', 'InferredFloor')
1278
+ floor_surface.additionalProperties.setFeature('Tilt', 0.0)
1623
1279
 
1624
1280
  # Add ceiling surface
1625
- ceiling_surface = OpenStudio::Model::Surface.new(add_ceiling_polygon(-floor_width, -floor_length, z_origin), model)
1281
+ vertices = Geometry.create_ceiling_vertices(floor_length, floor_width, z_origin, @default_azimuths)
1282
+ ceiling_surface = OpenStudio::Model::Surface.new(vertices, model)
1626
1283
 
1627
1284
  ceiling_surface.setSunExposure('NoSun')
1628
1285
  ceiling_surface.setWindExposure('NoWind')
@@ -1631,6 +1288,7 @@ class OSModel
1631
1288
  ceiling_surface.setSpace(create_or_get_space(model, spaces, HPXML::LocationLivingSpace))
1632
1289
  ceiling_surface.setOutsideBoundaryCondition('Adiabatic')
1633
1290
  ceiling_surface.additionalProperties.setFeature('SurfaceType', 'InferredCeiling')
1291
+ ceiling_surface.additionalProperties.setFeature('Tilt', 0.0)
1634
1292
 
1635
1293
  if not @cond_bsmnt_surfaces.empty?
1636
1294
  # assuming added ceiling is in conditioned basement
@@ -1646,13 +1304,13 @@ class OSModel
1646
1304
  if @apply_ashrae140_assumptions
1647
1305
  # 1024 ft2 of interior partition wall mass, no furniture mass
1648
1306
  drywall_thick_in = 0.5
1649
- partition_frac_of_cfa = 1024.0 / @cfa # Ratio of partition wall area to conditioned floor area
1307
+ partition_frac_of_cfa = (1024.0 * 2) / @cfa # Ratio of exposed partition wall area (both sides) to conditioned floor area
1650
1308
  basement_frac_of_cfa = cfa_basement / @cfa
1651
1309
  Constructions.apply_partition_walls(runner, model, 'PartitionWallConstruction', drywall_thick_in, partition_frac_of_cfa,
1652
1310
  basement_frac_of_cfa, @cond_bsmnt_surfaces, spaces[HPXML::LocationLivingSpace])
1653
1311
  else
1654
1312
  drywall_thick_in = 0.5
1655
- partition_frac_of_cfa = 1.0 # Ratio of partition wall area to conditioned floor area
1313
+ partition_frac_of_cfa = 1.0 # Ratio of exposed partition wall area (both sides) to conditioned floor area
1656
1314
  basement_frac_of_cfa = cfa_basement / @cfa
1657
1315
  Constructions.apply_partition_walls(runner, model, 'PartitionWallConstruction', drywall_thick_in, partition_frac_of_cfa,
1658
1316
  basement_frac_of_cfa, @cond_bsmnt_surfaces, spaces[HPXML::LocationLivingSpace])
@@ -1666,36 +1324,16 @@ class OSModel
1666
1324
  end
1667
1325
 
1668
1326
  def self.add_neighbors(runner, model, length)
1669
- z_origin = 0 # shading surface always starts at grade
1670
-
1671
- shading_surfaces = []
1672
- @hpxml.neighbor_buildings.each do |neighbor_building|
1673
- height = neighbor_building.height.nil? ? @walls_top : neighbor_building.height
1674
-
1675
- shading_surface = OpenStudio::Model::ShadingSurface.new(add_wall_polygon(length, height, z_origin, neighbor_building.azimuth), model)
1676
- shading_surface.additionalProperties.setFeature('Azimuth', neighbor_building.azimuth)
1677
- shading_surface.additionalProperties.setFeature('Distance', neighbor_building.distance)
1678
- shading_surface.setName("Neighbor azimuth #{neighbor_building.azimuth} distance #{neighbor_building.distance}")
1679
-
1680
- shading_surfaces << shading_surface
1681
- end
1682
-
1683
- unless shading_surfaces.empty?
1684
- shading_surface_group = OpenStudio::Model::ShadingSurfaceGroup.new(model)
1685
- shading_surface_group.setName(Constants.ObjectNameNeighbors)
1686
- shading_surfaces.each do |shading_surface|
1687
- shading_surface.setShadingSurfaceGroup(shading_surface_group)
1688
- end
1689
- end
1690
1327
  end
1691
1328
 
1692
- def self.add_interior_shading_schedule(runner, model, weather)
1693
- heating_season, cooling_season = HVAC.get_default_heating_and_cooling_seasons(weather)
1694
- @clg_season_sch = MonthWeekdayWeekendSchedule.new(model, 'cooling season schedule', Array.new(24, 1), Array.new(24, 1), cooling_season, Constants.ScheduleTypeLimitsFraction)
1329
+ def self.add_shading_schedule(runner, model, weather)
1330
+ heating_season, @cooling_season = HVAC.get_default_heating_and_cooling_seasons(weather)
1695
1331
 
1332
+ # Create cooling season schedule
1333
+ clg_season_sch = MonthWeekdayWeekendSchedule.new(model, 'cooling season schedule', Array.new(24, 1), Array.new(24, 1), @cooling_season, Constants.ScheduleTypeLimitsFraction)
1696
1334
  @clg_ssn_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Schedule Value')
1697
1335
  @clg_ssn_sensor.setName('cool_season')
1698
- @clg_ssn_sensor.setKeyName(@clg_season_sch.schedule.name.to_s)
1336
+ @clg_ssn_sensor.setKeyName(clg_season_sch.schedule.name.to_s)
1699
1337
  end
1700
1338
 
1701
1339
  def self.add_windows(runner, model, spaces, weather)
@@ -1708,28 +1346,32 @@ class OSModel
1708
1346
  end
1709
1347
  @hpxml.collapse_enclosure_surfaces()
1710
1348
 
1349
+ shading_group = nil
1350
+ shading_schedules = {}
1351
+ shading_ems = { sensors: {}, program: nil }
1352
+
1711
1353
  surfaces = []
1712
- @hpxml.windows.each do |window|
1354
+ @hpxml.windows.each_with_index do |window, i|
1713
1355
  window_height = 4.0 # ft, default
1714
1356
 
1715
1357
  overhang_depth = nil
1716
- if not window.overhangs_depth.nil?
1358
+ if (not window.overhangs_depth.nil?) && (window.overhangs_depth > 0)
1717
1359
  overhang_depth = window.overhangs_depth
1718
1360
  overhang_distance_to_top = window.overhangs_distance_to_top_of_window
1719
1361
  overhang_distance_to_bottom = window.overhangs_distance_to_bottom_of_window
1720
1362
  window_height = overhang_distance_to_bottom - overhang_distance_to_top
1721
1363
  end
1722
1364
 
1723
- window_width = window.area / window_height
1365
+ window_length = window.area / window_height
1724
1366
  z_origin = @foundation_top
1725
1367
 
1726
1368
  if window.is_exterior
1727
1369
 
1728
1370
  # Create parent surface slightly bigger than window
1729
- surface = OpenStudio::Model::Surface.new(add_wall_polygon(window_width, window_height, z_origin,
1730
- window.azimuth, [0, 0.001, 0.001, 0.001]), model)
1371
+ vertices = Geometry.create_wall_vertices(window_length, window_height, z_origin, window.azimuth, add_buffer: true)
1372
+ surface = OpenStudio::Model::Surface.new(vertices, model)
1731
1373
 
1732
- surface.additionalProperties.setFeature('Length', window_width)
1374
+ surface.additionalProperties.setFeature('Length', window_length)
1733
1375
  surface.additionalProperties.setFeature('Azimuth', window.azimuth)
1734
1376
  surface.additionalProperties.setFeature('Tilt', 90.0)
1735
1377
  surface.additionalProperties.setFeature('SurfaceType', 'Window')
@@ -1737,8 +1379,8 @@ class OSModel
1737
1379
  surface.setSurfaceType('Wall')
1738
1380
  set_surface_interior(model, spaces, surface, window.wall)
1739
1381
 
1740
- sub_surface = OpenStudio::Model::SubSurface.new(add_wall_polygon(window_width, window_height, z_origin,
1741
- window.azimuth, [-0.001, 0, 0.001, 0]), model)
1382
+ vertices = Geometry.create_wall_vertices(window_length, window_height, z_origin, window.azimuth)
1383
+ sub_surface = OpenStudio::Model::SubSurface.new(vertices, model)
1742
1384
  sub_surface.setName(window.id)
1743
1385
  sub_surface.setSurface(surface)
1744
1386
  sub_surface.setSubSurfaceType('FixedWindow')
@@ -1752,22 +1394,22 @@ class OSModel
1752
1394
  end
1753
1395
 
1754
1396
  # Apply construction
1755
- cool_shade_mult = window.interior_shading_factor_summer
1756
- heat_shade_mult = window.interior_shading_factor_winter
1757
- Constructions.apply_window(runner, model, [sub_surface],
1758
- 'WindowConstruction',
1759
- weather, @clg_season_sch, window.ufactor, window.shgc,
1760
- heat_shade_mult, cool_shade_mult)
1397
+ Constructions.apply_window(runner, model, sub_surface, 'WindowConstruction', window.ufactor, window.shgc)
1398
+
1399
+ # Apply interior/exterior shading (as needed)
1400
+ shading_vertices = Geometry.create_wall_vertices(window_length, window_height, z_origin, window.azimuth)
1401
+ shading_group = Constructions.apply_window_skylight_shading(model, window, i, shading_vertices, surface, sub_surface, shading_group,
1402
+ shading_schedules, shading_ems, Constants.ObjectNameWindowShade, @cooling_season)
1761
1403
  else
1762
1404
  # Window is on an interior surface, which E+ does not allow. Model
1763
1405
  # as a door instead so that we can get the appropriate conduction
1764
1406
  # heat transfer; there is no solar gains anyway.
1765
1407
 
1766
1408
  # Create parent surface slightly bigger than window
1767
- surface = OpenStudio::Model::Surface.new(add_wall_polygon(window_width, window_height, z_origin,
1768
- window.azimuth, [0, 0.001, 0.001, 0.001]), model)
1409
+ vertices = Geometry.create_wall_vertices(window_length, window_height, z_origin, window.azimuth, add_buffer: true)
1410
+ surface = OpenStudio::Model::Surface.new(vertices, model)
1769
1411
 
1770
- surface.additionalProperties.setFeature('Length', window_width)
1412
+ surface.additionalProperties.setFeature('Length', window_length)
1771
1413
  surface.additionalProperties.setFeature('Azimuth', window.azimuth)
1772
1414
  surface.additionalProperties.setFeature('Tilt', 90.0)
1773
1415
  surface.additionalProperties.setFeature('SurfaceType', 'Door')
@@ -1775,8 +1417,8 @@ class OSModel
1775
1417
  surface.setSurfaceType('Wall')
1776
1418
  set_surface_interior(model, spaces, surface, window.wall)
1777
1419
 
1778
- sub_surface = OpenStudio::Model::SubSurface.new(add_wall_polygon(window_width, window_height, z_origin,
1779
- window.azimuth, [0, 0, 0, 0]), model)
1420
+ vertices = Geometry.create_wall_vertices(window_length, window_height, z_origin, window.azimuth)
1421
+ sub_surface = OpenStudio::Model::SubSurface.new(vertices, model)
1780
1422
  sub_surface.setName(window.id)
1781
1423
  sub_surface.setSurface(surface)
1782
1424
  sub_surface.setSubSurfaceType('Door')
@@ -1785,7 +1427,9 @@ class OSModel
1785
1427
  surfaces << surface
1786
1428
 
1787
1429
  # Apply construction
1788
- Constructions.apply_door(runner, model, [sub_surface], 'Window', window.ufactor)
1430
+ inside_film = Material.AirFilmVertical
1431
+ outside_film = Material.AirFilmVertical
1432
+ Constructions.apply_door(runner, model, [sub_surface], 'Window', window.ufactor, inside_film, outside_film)
1789
1433
  end
1790
1434
  end
1791
1435
 
@@ -1794,16 +1438,20 @@ class OSModel
1794
1438
 
1795
1439
  def self.add_skylights(runner, model, spaces, weather)
1796
1440
  surfaces = []
1797
- @hpxml.skylights.each do |skylight|
1441
+
1442
+ shading_group = nil
1443
+ shading_schedules = {}
1444
+ shading_ems = { sensors: {}, program: nil }
1445
+
1446
+ @hpxml.skylights.each_with_index do |skylight, i|
1798
1447
  tilt = skylight.roof.pitch / 12.0
1799
1448
  width = Math::sqrt(skylight.area)
1800
1449
  length = skylight.area / width
1801
1450
  z_origin = @walls_top + 0.5 * Math.sin(Math.atan(tilt)) * width
1802
1451
 
1803
1452
  # Create parent surface slightly bigger than skylight
1804
- surface = OpenStudio::Model::Surface.new(add_roof_polygon(length + 0.001, width + 0.001, z_origin,
1805
- skylight.azimuth, tilt), model)
1806
-
1453
+ vertices = Geometry.create_roof_vertices(length, width, z_origin, skylight.azimuth, tilt, add_buffer: true)
1454
+ surface = OpenStudio::Model::Surface.new(vertices, model)
1807
1455
  surface.additionalProperties.setFeature('Length', length)
1808
1456
  surface.additionalProperties.setFeature('Width', width)
1809
1457
  surface.additionalProperties.setFeature('Azimuth', skylight.azimuth)
@@ -1815,21 +1463,19 @@ class OSModel
1815
1463
  surface.setOutsideBoundaryCondition('Outdoors') # cannot be adiabatic because subsurfaces won't be created
1816
1464
  surfaces << surface
1817
1465
 
1818
- sub_surface = OpenStudio::Model::SubSurface.new(add_roof_polygon(length, width, z_origin,
1819
- skylight.azimuth, tilt), model)
1466
+ vertices = Geometry.create_roof_vertices(length, width, z_origin, skylight.azimuth, tilt)
1467
+ sub_surface = OpenStudio::Model::SubSurface.new(vertices, model)
1820
1468
  sub_surface.setName(skylight.id)
1821
1469
  sub_surface.setSurface(surface)
1822
1470
  sub_surface.setSubSurfaceType('Skylight')
1823
1471
 
1824
1472
  # Apply construction
1825
- ufactor = skylight.ufactor
1826
- shgc = skylight.shgc
1827
- cool_shade_mult = skylight.interior_shading_factor_summer
1828
- heat_shade_mult = skylight.interior_shading_factor_winter
1829
- Constructions.apply_skylight(runner, model, [sub_surface],
1830
- 'SkylightConstruction',
1831
- weather, @clg_season_sch, ufactor, shgc,
1832
- heat_shade_mult, cool_shade_mult)
1473
+ Constructions.apply_skylight(runner, model, sub_surface, 'SkylightConstruction', skylight.ufactor, skylight.shgc)
1474
+
1475
+ # Apply interior/exterior shading (as needed)
1476
+ shading_vertices = Geometry.create_roof_vertices(length, width, z_origin, skylight.azimuth, tilt)
1477
+ shading_group = Constructions.apply_window_skylight_shading(model, skylight, i, shading_vertices, surface, sub_surface, shading_group,
1478
+ shading_schedules, shading_ems, Constants.ObjectNameSkylightShade, @cooling_season)
1833
1479
  end
1834
1480
 
1835
1481
  apply_adiabatic_construction(runner, model, surfaces, 'roof')
@@ -1839,14 +1485,14 @@ class OSModel
1839
1485
  surfaces = []
1840
1486
  @hpxml.doors.each do |door|
1841
1487
  door_height = 6.67 # ft
1842
- door_width = door.area / door_height
1488
+ door_length = door.area / door_height
1843
1489
  z_origin = @foundation_top
1844
1490
 
1845
1491
  # Create parent surface slightly bigger than door
1846
- surface = OpenStudio::Model::Surface.new(add_wall_polygon(door_width, door_height, z_origin,
1847
- door.azimuth, [0, 0.001, 0.001, 0.001]), model)
1492
+ vertices = Geometry.create_wall_vertices(door_length, door_height, z_origin, door.azimuth, add_buffer: true)
1493
+ surface = OpenStudio::Model::Surface.new(vertices, model)
1848
1494
 
1849
- surface.additionalProperties.setFeature('Length', door_width)
1495
+ surface.additionalProperties.setFeature('Length', door_length)
1850
1496
  surface.additionalProperties.setFeature('Azimuth', door.azimuth)
1851
1497
  surface.additionalProperties.setFeature('Tilt', 90.0)
1852
1498
  surface.additionalProperties.setFeature('SurfaceType', 'Door')
@@ -1854,8 +1500,8 @@ class OSModel
1854
1500
  surface.setSurfaceType('Wall')
1855
1501
  set_surface_interior(model, spaces, surface, door.wall)
1856
1502
 
1857
- sub_surface = OpenStudio::Model::SubSurface.new(add_wall_polygon(door_width, door_height, z_origin,
1858
- door.azimuth, [0, 0, 0, 0]), model)
1503
+ vertices = Geometry.create_wall_vertices(door_length, door_height, z_origin, door.azimuth)
1504
+ sub_surface = OpenStudio::Model::SubSurface.new(vertices, model)
1859
1505
  sub_surface.setName(door.id)
1860
1506
  sub_surface.setSurface(surface)
1861
1507
  sub_surface.setSubSurfaceType('Door')
@@ -1865,7 +1511,13 @@ class OSModel
1865
1511
 
1866
1512
  # Apply construction
1867
1513
  ufactor = 1.0 / door.r_value
1868
- Constructions.apply_door(runner, model, [sub_surface], 'Door', ufactor)
1514
+ inside_film = Material.AirFilmVertical
1515
+ if door.wall.is_exterior
1516
+ outside_film = Material.AirFilmOutside
1517
+ else
1518
+ outside_film = Material.AirFilmVertical
1519
+ end
1520
+ Constructions.apply_door(runner, model, [sub_surface], 'Door', ufactor, inside_film, outside_film)
1869
1521
  end
1870
1522
 
1871
1523
  apply_adiabatic_construction(runner, model, surfaces, 'wall')
@@ -1901,25 +1553,6 @@ class OSModel
1901
1553
  end
1902
1554
 
1903
1555
  def self.add_hot_water_and_appliances(runner, model, weather, spaces)
1904
- if @hpxml.clothes_washers.empty?
1905
- runner.registerWarning('No clothes washer specified, the model will not include clothes washer energy use.')
1906
- end
1907
- if @hpxml.clothes_dryers.empty?
1908
- runner.registerWarning('No clothes dryer specified, the model will not include clothes dryer energy use.')
1909
- end
1910
- if @hpxml.dishwashers.empty?
1911
- runner.registerWarning('No dishwasher specified, the model will not include dishwasher energy use.')
1912
- end
1913
- if @hpxml.refrigerators.empty?
1914
- runner.registerWarning('No refrigerator specified, the model will not include refrigerator energy use.')
1915
- end
1916
- if @hpxml.cooking_ranges.empty?
1917
- runner.registerWarning('No cooking range specified, the model will not include cooking range/oven energy use.')
1918
- end
1919
- if @hpxml.water_heating_systems.empty?
1920
- runner.registerWarning('No water heater specified, the model will not include water heating energy use.')
1921
- end
1922
-
1923
1556
  # Assign spaces
1924
1557
  @hpxml.clothes_washers.each do |clothes_washer|
1925
1558
  clothes_washer.additional_properties.space = get_space_from_location(clothes_washer.location, 'ClothesWasher', model, spaces)
@@ -1952,10 +1585,11 @@ class OSModel
1952
1585
  end
1953
1586
 
1954
1587
  # Water Heater
1588
+ has_uncond_bsmnt = @hpxml.has_space_type(HPXML::LocationBasementUnconditioned)
1955
1589
  @hpxml.water_heating_systems.each do |water_heating_system|
1956
1590
  loc_space, loc_schedule = get_space_or_schedule_from_location(water_heating_system.location, 'WaterHeatingSystem', model, spaces)
1957
1591
 
1958
- ec_adj = HotWaterAndAppliances.get_dist_energy_consumption_adjustment(@has_uncond_bsmnt, @cfa, @ncfl, water_heating_system, hot_water_distribution)
1592
+ ec_adj = HotWaterAndAppliances.get_dist_energy_consumption_adjustment(has_uncond_bsmnt, @cfa, @ncfl, water_heating_system, hot_water_distribution)
1959
1593
 
1960
1594
  if water_heating_system.water_heater_type == HPXML::WaterHeaterTypeStorage
1961
1595
 
@@ -1987,11 +1621,7 @@ class OSModel
1987
1621
  end
1988
1622
 
1989
1623
  # Hot water fixtures and appliances
1990
- HotWaterAndAppliances.apply(model, runner, weather, spaces[HPXML::LocationLivingSpace],
1991
- @cfa, @nbeds, @ncfl, @has_uncond_bsmnt, @hpxml.clothes_washers,
1992
- @hpxml.clothes_dryers, @hpxml.dishwashers, @hpxml.refrigerators,
1993
- @hpxml.freezers, @hpxml.cooking_ranges, @hpxml.ovens, @hpxml.water_heating,
1994
- @hpxml.water_heating_systems, hot_water_distribution, @hpxml.water_fixtures,
1624
+ HotWaterAndAppliances.apply(model, runner, @hpxml, weather, spaces, hot_water_distribution,
1995
1625
  solar_thermal_system, @eri_version, @dhw_map, @schedules_file)
1996
1626
 
1997
1627
  if (not solar_thermal_system.nil?) && (not solar_thermal_system.collector_area.nil?) # Detailed solar water heater
@@ -2003,33 +1633,19 @@ class OSModel
2003
1633
  Waterheater.apply_combi_system_EMS(model, @dhw_map, @hpxml.water_heating_systems)
2004
1634
  end
2005
1635
 
2006
- def self.is_central_air_conditioner_and_furnace(heating_system, cooling_system)
2007
- if not (@hpxml.heating_systems.include?(heating_system) && (heating_system.heating_system_type == HPXML::HVACTypeFurnace))
2008
- return false
2009
- end
2010
- if not (@hpxml.cooling_systems.include?(cooling_system) && (cooling_system.cooling_system_type == HPXML::HVACTypeCentralAirConditioner))
2011
- return false
2012
- end
2013
-
2014
- return true
2015
- end
2016
-
2017
- def self.update_shared_hvac_systems()
2018
- HVAC.apply_shared_systems(@hpxml)
2019
- end
2020
-
2021
1636
  def self.add_cooling_system(runner, model, spaces)
2022
1637
  living_zone = spaces[HPXML::LocationLivingSpace].thermalZone.get
2023
1638
 
2024
- @hpxml.cooling_systems.each do |cooling_system|
2025
- check_distribution_system(cooling_system.distribution_system, cooling_system.cooling_system_type)
1639
+ HVAC.get_hpxml_hvac_systems(@hpxml).each do |hvac_system|
1640
+ next if hvac_system[:cooling].nil?
1641
+ next unless hvac_system[:cooling].is_a? HPXML::CoolingSystem
2026
1642
 
2027
- if cooling_system.cooling_system_type == HPXML::HVACTypeCentralAirConditioner
1643
+ cooling_system = hvac_system[:cooling]
1644
+ heating_system = hvac_system[:heating]
2028
1645
 
2029
- heating_system = cooling_system.attached_heating_system
2030
- if not is_central_air_conditioner_and_furnace(heating_system, cooling_system)
2031
- heating_system = nil
2032
- end
1646
+ check_distribution_system(cooling_system.distribution_system, cooling_system.cooling_system_type)
1647
+
1648
+ if [HPXML::HVACTypeCentralAirConditioner].include? cooling_system.cooling_system_type
2033
1649
 
2034
1650
  HVAC.apply_central_air_conditioner_furnace(model, runner, cooling_system, heating_system,
2035
1651
  @remaining_cool_load_frac, @remaining_heat_load_frac,
@@ -2039,19 +1655,19 @@ class OSModel
2039
1655
  @remaining_heat_load_frac -= heating_system.fraction_heat_load_served
2040
1656
  end
2041
1657
 
2042
- elsif cooling_system.cooling_system_type == HPXML::HVACTypeRoomAirConditioner
1658
+ elsif [HPXML::HVACTypeRoomAirConditioner].include? cooling_system.cooling_system_type
2043
1659
 
2044
1660
  HVAC.apply_room_air_conditioner(model, runner, cooling_system,
2045
1661
  @remaining_cool_load_frac, living_zone,
2046
1662
  @hvac_map)
2047
1663
 
2048
- elsif cooling_system.cooling_system_type == HPXML::HVACTypeEvaporativeCooler
1664
+ elsif [HPXML::HVACTypeEvaporativeCooler].include? cooling_system.cooling_system_type
2049
1665
 
2050
1666
  HVAC.apply_evaporative_cooler(model, runner, cooling_system,
2051
1667
  @remaining_cool_load_frac, living_zone,
2052
1668
  @hvac_map)
2053
1669
 
2054
- elsif cooling_system.cooling_system_type == HPXML::HVACTypeMiniSplitAirConditioner
1670
+ elsif [HPXML::HVACTypeMiniSplitAirConditioner].include? cooling_system.cooling_system_type
2055
1671
 
2056
1672
  HVAC.apply_mini_split_air_conditioner(model, runner, cooling_system,
2057
1673
  @remaining_cool_load_frac,
@@ -2065,13 +1681,18 @@ class OSModel
2065
1681
  def self.add_heating_system(runner, model, spaces)
2066
1682
  living_zone = spaces[HPXML::LocationLivingSpace].thermalZone.get
2067
1683
 
2068
- @hpxml.heating_systems.each do |heating_system|
1684
+ HVAC.get_hpxml_hvac_systems(@hpxml).each do |hvac_system|
1685
+ next if hvac_system[:heating].nil?
1686
+ next unless hvac_system[:heating].is_a? HPXML::HeatingSystem
1687
+
1688
+ cooling_system = hvac_system[:cooling]
1689
+ heating_system = hvac_system[:heating]
1690
+
2069
1691
  check_distribution_system(heating_system.distribution_system, heating_system.heating_system_type)
2070
1692
 
2071
- if heating_system.heating_system_type == HPXML::HVACTypeFurnace
1693
+ if [HPXML::HVACTypeFurnace].include? heating_system.heating_system_type
2072
1694
 
2073
- cooling_system = heating_system.attached_cooling_system
2074
- if is_central_air_conditioner_and_furnace(heating_system, cooling_system)
1695
+ if not cooling_system.nil?
2075
1696
  next # Already processed combined AC+furnace
2076
1697
  end
2077
1698
 
@@ -2079,22 +1700,22 @@ class OSModel
2079
1700
  nil, @remaining_heat_load_frac,
2080
1701
  living_zone, @hvac_map)
2081
1702
 
2082
- elsif heating_system.heating_system_type == HPXML::HVACTypeBoiler
1703
+ elsif [HPXML::HVACTypeBoiler].include? heating_system.heating_system_type
2083
1704
 
2084
1705
  HVAC.apply_boiler(model, runner, heating_system,
2085
1706
  @remaining_heat_load_frac, living_zone, @hvac_map)
2086
1707
 
2087
- elsif heating_system.heating_system_type == HPXML::HVACTypeElectricResistance
1708
+ elsif [HPXML::HVACTypeElectricResistance].include? heating_system.heating_system_type
2088
1709
 
2089
1710
  HVAC.apply_electric_baseboard(model, runner, heating_system,
2090
1711
  @remaining_heat_load_frac, living_zone, @hvac_map)
2091
1712
 
2092
- elsif (heating_system.heating_system_type == HPXML::HVACTypeStove ||
2093
- heating_system.heating_system_type == HPXML::HVACTypePortableHeater ||
2094
- heating_system.heating_system_type == HPXML::HVACTypeFixedHeater ||
2095
- heating_system.heating_system_type == HPXML::HVACTypeWallFurnace ||
2096
- heating_system.heating_system_type == HPXML::HVACTypeFloorFurnace ||
2097
- heating_system.heating_system_type == HPXML::HVACTypeFireplace)
1713
+ elsif [HPXML::HVACTypeStove,
1714
+ HPXML::HVACTypePortableHeater,
1715
+ HPXML::HVACTypeFixedHeater,
1716
+ HPXML::HVACTypeWallFurnace,
1717
+ HPXML::HVACTypeFloorFurnace,
1718
+ HPXML::HVACTypeFireplace].include? heating_system.heating_system_type
2098
1719
 
2099
1720
  HVAC.apply_unit_heater(model, runner, heating_system,
2100
1721
  @remaining_heat_load_frac, living_zone, @hvac_map)
@@ -2107,45 +1728,36 @@ class OSModel
2107
1728
  def self.add_heat_pump(runner, model, weather, spaces)
2108
1729
  living_zone = spaces[HPXML::LocationLivingSpace].thermalZone.get
2109
1730
 
2110
- @hpxml.heat_pumps.each do |heat_pump|
2111
- # FUTURE: Move these checks into hvac.rb
2112
- if not heat_pump.heating_capacity_17F.nil?
2113
- if heat_pump.heating_capacity.nil?
2114
- fail "HeatPump '#{heat_pump.id}' must have both HeatingCapacity and HeatingCapacity17F provided or not provided."
2115
- elsif heat_pump.heating_capacity == 0.0
2116
- heat_pump.heating_capacity_17F = nil
2117
- end
2118
- end
2119
- if not heat_pump.backup_heating_fuel.nil?
2120
- if heat_pump.backup_heating_capacity.nil? ^ heat_pump.heating_capacity.nil?
2121
- fail "HeatPump '#{heat_pump.id}' must have both HeatingCapacity and BackupHeatingCapacity provided or not provided."
2122
- end
2123
- end
1731
+ HVAC.get_hpxml_hvac_systems(@hpxml).each do |hvac_system|
1732
+ next if hvac_system[:cooling].nil?
1733
+ next unless hvac_system[:cooling].is_a? HPXML::HeatPump
1734
+
1735
+ heat_pump = hvac_system[:cooling]
2124
1736
 
2125
1737
  check_distribution_system(heat_pump.distribution_system, heat_pump.heat_pump_type)
2126
1738
 
2127
- if heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpWaterLoopToAir
1739
+ if [HPXML::HVACTypeHeatPumpWaterLoopToAir].include? heat_pump.heat_pump_type
2128
1740
 
2129
1741
  HVAC.apply_water_loop_to_air_heat_pump(model, runner, heat_pump,
2130
1742
  @remaining_heat_load_frac,
2131
1743
  @remaining_cool_load_frac,
2132
1744
  living_zone, @hvac_map)
2133
1745
 
2134
- elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpAirToAir
1746
+ elsif [HPXML::HVACTypeHeatPumpAirToAir].include? heat_pump.heat_pump_type
2135
1747
 
2136
1748
  HVAC.apply_central_air_to_air_heat_pump(model, runner, heat_pump,
2137
1749
  @remaining_heat_load_frac,
2138
1750
  @remaining_cool_load_frac,
2139
1751
  living_zone, @hvac_map)
2140
1752
 
2141
- elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpMiniSplit
1753
+ elsif [HPXML::HVACTypeHeatPumpMiniSplit].include? heat_pump.heat_pump_type
2142
1754
 
2143
1755
  HVAC.apply_mini_split_heat_pump(model, runner, heat_pump,
2144
1756
  @remaining_heat_load_frac,
2145
1757
  @remaining_cool_load_frac,
2146
1758
  living_zone, @hvac_map)
2147
1759
 
2148
- elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir
1760
+ elsif [HPXML::HVACTypeHeatPumpGroundToAir].include? heat_pump.heat_pump_type
2149
1761
 
2150
1762
  HVAC.apply_ground_to_air_heat_pump(model, runner, weather, heat_pump,
2151
1763
  @remaining_heat_load_frac,
@@ -2165,7 +1777,7 @@ class OSModel
2165
1777
  living_zone = spaces[HPXML::LocationLivingSpace].thermalZone.get
2166
1778
  obj_name = Constants.ObjectNameIdealAirSystem
2167
1779
 
2168
- if @hpxml.building_construction.use_only_ideal_air_system
1780
+ if @apply_ashrae140_assumptions && (@hpxml.total_fraction_heat_load_served + @hpxml.total_fraction_heat_load_served == 0.0)
2169
1781
  cooling_load_frac = 1.0
2170
1782
  heating_load_frac = 1.0
2171
1783
  if @apply_ashrae140_assumptions
@@ -2212,19 +1824,17 @@ class OSModel
2212
1824
  obj_name = Constants.ObjectNameIdealAirSystemResidual
2213
1825
 
2214
1826
  if @remaining_cool_load_frac < 1.0
2215
- sequential_cool_load_frac = 1
1827
+ sequential_cool_load_frac = 1.0
2216
1828
  else
2217
- sequential_cool_load_frac = 0 # no cooling system, don't add ideal air for cooling either
2218
- runner.registerWarning('No cooling system specified, the model will not include space cooling energy use.')
1829
+ sequential_cool_load_frac = 0.0 # no cooling system, don't add ideal air for cooling either
2219
1830
  end
2220
1831
 
2221
1832
  if @remaining_heat_load_frac < 1.0
2222
- sequential_heat_load_frac = 1
1833
+ sequential_heat_load_frac = 1.0
2223
1834
  else
2224
- sequential_heat_load_frac = 0 # no heating system, don't add ideal air for heating either
2225
- runner.registerWarning('No heating system specified, the model will not include space heating energy use.')
1835
+ sequential_heat_load_frac = 0.0 # no heating system, don't add ideal air for heating either
2226
1836
  end
2227
- if (sequential_heat_load_frac > 0) || (sequential_cool_load_frac > 0)
1837
+ if (sequential_heat_load_frac > 0.0) || (sequential_cool_load_frac > 0.0)
2228
1838
  HVAC.apply_ideal_air_loads(model, runner, obj_name, sequential_cool_load_frac, sequential_heat_load_frac,
2229
1839
  living_zone)
2230
1840
  end
@@ -2235,8 +1845,9 @@ class OSModel
2235
1845
 
2236
1846
  hvac_control = @hpxml.hvac_controls[0]
2237
1847
  living_zone = spaces[HPXML::LocationLivingSpace].thermalZone.get
1848
+ has_ceiling_fan = (@hpxml.ceiling_fans.size > 0)
2238
1849
 
2239
- HVAC.apply_setpoints(model, runner, weather, hvac_control, living_zone)
1850
+ HVAC.apply_setpoints(model, runner, weather, hvac_control, living_zone, has_ceiling_fan)
2240
1851
  end
2241
1852
 
2242
1853
  def self.add_ceiling_fans(runner, model, weather, spaces)
@@ -2246,25 +1857,24 @@ class OSModel
2246
1857
  HVAC.apply_ceiling_fans(model, runner, weather, ceiling_fan, spaces[HPXML::LocationLivingSpace], @schedules_file)
2247
1858
  end
2248
1859
 
2249
- def self.add_dehumidifier(runner, model, spaces)
1860
+ def self.add_dehumidifiers(runner, model, spaces)
2250
1861
  return if @hpxml.dehumidifiers.size == 0
2251
1862
 
2252
- dehumidifier = @hpxml.dehumidifiers[0]
2253
- HVAC.apply_dehumidifier(model, runner, dehumidifier, spaces[HPXML::LocationLivingSpace], @hvac_map)
1863
+ HVAC.apply_dehumidifiers(model, runner, @hpxml.dehumidifiers, spaces[HPXML::LocationLivingSpace], @hvac_map)
2254
1864
  end
2255
1865
 
2256
1866
  def self.check_distribution_system(hvac_distribution, system_type)
2257
1867
  return if hvac_distribution.nil?
2258
1868
 
2259
1869
  hvac_distribution_type_map = { HPXML::HVACTypeFurnace => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2260
- HPXML::HVACTypeBoiler => [HPXML::HVACDistributionTypeHydronic, HPXML::HVACDistributionTypeHydronicAndAir, HPXML::HVACDistributionTypeDSE],
1870
+ HPXML::HVACTypeBoiler => [HPXML::HVACDistributionTypeHydronic, HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2261
1871
  HPXML::HVACTypeCentralAirConditioner => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2262
1872
  HPXML::HVACTypeEvaporativeCooler => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2263
1873
  HPXML::HVACTypeMiniSplitAirConditioner => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2264
1874
  HPXML::HVACTypeHeatPumpAirToAir => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2265
1875
  HPXML::HVACTypeHeatPumpMiniSplit => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2266
1876
  HPXML::HVACTypeHeatPumpGroundToAir => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2267
- HPXML::HVACTypeHeatPumpWaterLoopToAir => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeHydronicAndAir, HPXML::HVACDistributionTypeDSE] }
1877
+ HPXML::HVACTypeHeatPumpWaterLoopToAir => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE] }
2268
1878
 
2269
1879
  if not hvac_distribution_type_map[system_type].include? hvac_distribution.distribution_system_type
2270
1880
  # validator.rb only checks that a HVAC distribution system of the correct type (for the given HVAC system) exists
@@ -2275,7 +1885,6 @@ class OSModel
2275
1885
 
2276
1886
  def self.add_mels(runner, model, spaces)
2277
1887
  # Misc
2278
- modeled_mels = []
2279
1888
  @hpxml.plug_loads.each do |plug_load|
2280
1889
  if plug_load.plug_load_type == HPXML::PlugLoadTypeOther
2281
1890
  obj_name = Constants.ObjectNameMiscPlugLoads
@@ -2290,15 +1899,8 @@ class OSModel
2290
1899
  runner.registerWarning("Unexpected plug load type '#{plug_load.plug_load_type}'. The plug load will not be modeled.")
2291
1900
  next
2292
1901
  end
2293
- modeled_mels << plug_load.plug_load_type
2294
1902
 
2295
- MiscLoads.apply_plug(model, plug_load, obj_name, spaces[HPXML::LocationLivingSpace], @schedules_file)
2296
- end
2297
- if not modeled_mels.include? HPXML::PlugLoadTypeOther
2298
- runner.registerWarning("No '#{HPXML::PlugLoadTypeOther}' plug loads specified, the model will not include misc plug load energy use.")
2299
- end
2300
- if not modeled_mels.include? HPXML::PlugLoadTypeTelevision
2301
- runner.registerWarning("No '#{HPXML::PlugLoadTypeTelevision}' plug loads specified, the model will not include television plug load energy use.")
1903
+ MiscLoads.apply_plug(model, plug_load, obj_name, spaces[HPXML::LocationLivingSpace], @apply_ashrae140_assumptions, @schedules_file)
2302
1904
  end
2303
1905
  end
2304
1906
 
@@ -2328,37 +1930,25 @@ class OSModel
2328
1930
 
2329
1931
  def self.add_pools_and_hot_tubs(runner, model, spaces)
2330
1932
  @hpxml.pools.each do |pool|
1933
+ next if pool.type == HPXML::TypeNone
1934
+
2331
1935
  MiscLoads.apply_pool_or_hot_tub_heater(model, pool, Constants.ObjectNameMiscPoolHeater, spaces[HPXML::LocationLivingSpace], @schedules_file)
2332
1936
  MiscLoads.apply_pool_or_hot_tub_pump(model, pool, Constants.ObjectNameMiscPoolPump, spaces[HPXML::LocationLivingSpace], @schedules_file)
2333
1937
  end
2334
1938
 
2335
1939
  @hpxml.hot_tubs.each do |hot_tub|
1940
+ next if hot_tub.type == HPXML::TypeNone
1941
+
2336
1942
  MiscLoads.apply_pool_or_hot_tub_heater(model, hot_tub, Constants.ObjectNameMiscHotTubHeater, spaces[HPXML::LocationLivingSpace], @schedules_file)
2337
1943
  MiscLoads.apply_pool_or_hot_tub_pump(model, hot_tub, Constants.ObjectNameMiscHotTubPump, spaces[HPXML::LocationLivingSpace], @schedules_file)
2338
1944
  end
2339
1945
  end
2340
1946
 
2341
1947
  def self.add_airflow(runner, model, weather, spaces)
2342
- # Vented Attic
2343
- vented_attic = nil
2344
- @hpxml.attics.each do |attic|
2345
- next unless attic.attic_type == HPXML::AtticTypeVented
2346
-
2347
- vented_attic = attic
2348
- end
2349
-
2350
- # Vented Crawlspace
2351
- vented_crawl = nil
2352
- @hpxml.foundations.each do |foundation|
2353
- next unless foundation.foundation_type == HPXML::FoundationTypeCrawlspaceVented
2354
-
2355
- vented_crawl = foundation
2356
- end
2357
-
2358
1948
  # Ducts
2359
1949
  duct_systems = {}
2360
1950
  @hpxml.hvac_distributions.each do |hvac_distribution|
2361
- next unless [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeHydronicAndAir].include? hvac_distribution.distribution_system_type
1951
+ next unless hvac_distribution.distribution_system_type == HPXML::HVACDistributionTypeAir
2362
1952
 
2363
1953
  air_ducts = create_ducts(runner, model, hvac_distribution, spaces)
2364
1954
  next if air_ducts.empty?
@@ -2367,7 +1957,7 @@ class OSModel
2367
1957
  added_ducts = false
2368
1958
  hvac_distribution.hvac_systems.each do |hvac_system|
2369
1959
  @hvac_map[hvac_system.id].each do |object|
2370
- next unless object.is_a? OpenStudio::Model::AirLoopHVAC
1960
+ next unless object.is_a?(OpenStudio::Model::AirLoopHVAC) || object.is_a?(OpenStudio::Model::ZoneHVACFourPipeFanCoil)
2371
1961
 
2372
1962
  if duct_systems[air_ducts].nil?
2373
1963
  duct_systems[air_ducts] = object
@@ -2381,37 +1971,14 @@ class OSModel
2381
1971
  end
2382
1972
  end
2383
1973
  end
2384
- if not added_ducts
2385
- # Check if ducted fan coil, which doesn't have an AirLoopHVAC;
2386
- # assign to FanCoil instead.
2387
- if hvac_distribution.distribution_system_type && hvac_distribution.hydronic_and_air_type == HPXML::HydronicAndAirTypeFanCoil
2388
- hvac_distribution.hvac_systems.each do |hvac_system|
2389
- @hvac_map[hvac_system.id].each do |object|
2390
- next unless object.is_a? OpenStudio::Model::ZoneHVACFourPipeFanCoil
2391
-
2392
- duct_systems[air_ducts] = object
2393
- added_ducts = true
2394
- end
2395
- end
2396
- end
2397
- end
2398
1974
  if not added_ducts
2399
1975
  fail 'Unexpected error adding ducts to model.'
2400
1976
  end
2401
1977
  end
2402
1978
 
2403
- air_infils = @hpxml.air_infiltration_measurements
2404
- window_area = @hpxml.windows.map { |w| w.area }.sum(0.0)
2405
- open_window_area = window_area * @frac_windows_operable * 0.5 * 0.2 # Assume A) 50% of the area of an operable window can be open, and B) 20% of openable window area is actually open
2406
- site_type = @hpxml.site.site_type
2407
- shelter_coef = @hpxml.site.shelter_coefficient
2408
- @infil_volume = air_infils.select { |i| !i.infiltration_volume.nil? }[0].infiltration_volume
2409
- infil_height = @hpxml.inferred_infiltration_height(@infil_volume)
2410
- Airflow.apply(model, runner, weather, spaces, air_infils, @hpxml.ventilation_fans, @hpxml.clothes_dryers, @nbeds,
2411
- duct_systems, @infil_volume, infil_height, open_window_area,
2412
- @clg_ssn_sensor, @min_neighbor_distance, vented_attic, vented_crawl,
2413
- site_type, shelter_coef, @hpxml.building_construction.has_flue_or_chimney, @hvac_map, @eri_version,
2414
- @apply_ashrae140_assumptions, @schedules_file)
1979
+ Airflow.apply(model, runner, weather, spaces, @hpxml, @cfa, @nbeds,
1980
+ @ncfl_ag, duct_systems, @clg_ssn_sensor, @hvac_map, @eri_version,
1981
+ @frac_windows_operable, @apply_ashrae140_assumptions, @schedules_file)
2415
1982
  end
2416
1983
 
2417
1984
  def self.create_ducts(runner, model, hvac_distribution, spaces)
@@ -2464,14 +2031,9 @@ class OSModel
2464
2031
  end
2465
2032
 
2466
2033
  # If all ducts are in conditioned space, model leakage as going to outside
2467
- registered_warning = false
2468
2034
  [HPXML::DuctTypeSupply, HPXML::DuctTypeReturn].each do |duct_side|
2469
2035
  next unless (leakage_to_outside[duct_side][0] > 0) && (total_unconditioned_duct_area[duct_side] == 0)
2470
2036
 
2471
- if not registered_warning
2472
- runner.registerWarning("HVACDistribution '#{hvac_distribution.id}' has ducts entirely within conditioned space but there is non-zero leakage to the outside. Leakage to the outside is typically zero in these situations; consider revising leakage values. Leakage will be modeled as heat lost to the ambient environment.")
2473
- registered_warning = true
2474
- end
2475
2037
  duct_area = 0.0
2476
2038
  duct_rvalue = 0.0
2477
2039
  duct_loc_space = nil # outside
@@ -2495,33 +2057,23 @@ class OSModel
2495
2057
  return air_ducts
2496
2058
  end
2497
2059
 
2498
- def self.add_hvac_sizing(runner, model, weather, spaces)
2499
- HVACSizing.apply(model, runner, weather, spaces, @hpxml, @infil_volume, @nbeds, @min_neighbor_distance, @debug)
2500
- end
2501
-
2502
- def self.add_furnace_eae(runner, model)
2503
- # Needs to come after HVAC sizing (needs heating capacity and airflow rate)
2504
- # FUTURE: Could remove this method and simplify everything if we could autosize via the HPXML file
2505
-
2506
- @hpxml.heating_systems.each do |heating_system|
2507
- next unless heating_system.fraction_heat_load_served > 0
2508
- next unless [HPXML::HVACTypeFurnace, HPXML::HVACTypeWallFurnace, HPXML::HVACTypeFloorFurnace, HPXML::HVACTypeStove].include? heating_system.heating_system_type
2509
- next unless heating_system.heating_system_fuel != HPXML::FuelTypeElectricity
2510
-
2511
- HVAC.apply_eae_to_heating_fan(runner, @hvac_map[heating_system.id], heating_system)
2512
- end
2513
- end
2514
-
2515
2060
  def self.add_photovoltaics(runner, model)
2516
2061
  @hpxml.pv_systems.each do |pv_system|
2517
2062
  PV.apply(model, @nbeds, pv_system)
2518
2063
  end
2519
2064
  end
2520
2065
 
2521
- def self.add_additional_properties(runner, model, hpxml_path)
2066
+ def self.add_generators(runner, model)
2067
+ @hpxml.generators.each do |generator|
2068
+ Generator.apply(model, @nbeds, generator)
2069
+ end
2070
+ end
2071
+
2072
+ def self.add_additional_properties(runner, model, hpxml_path, building_id)
2522
2073
  # Store some data for use in reporting measure
2523
2074
  additionalProperties = model.getBuilding.additionalProperties
2524
2075
  additionalProperties.setFeature('hpxml_path', hpxml_path)
2076
+ additionalProperties.setFeature('building_id', building_id.to_s)
2525
2077
  additionalProperties.setFeature('hvac_map', map_to_string(@hvac_map))
2526
2078
  additionalProperties.setFeature('dhw_map', map_to_string(@dhw_map))
2527
2079
  end
@@ -2538,31 +2090,71 @@ class OSModel
2538
2090
  return map_str.to_s
2539
2091
  end
2540
2092
 
2541
- def self.add_component_loads_output(runner, model, spaces)
2093
+ def self.add_loads_output(runner, model, spaces, add_component_loads)
2542
2094
  living_zone = spaces[HPXML::LocationLivingSpace].thermalZone.get
2543
2095
 
2544
- # Prevent certain objects (e.g., OtherEquipment) from being counted towards both, e.g., ducts and internal gains
2545
- objects_already_processed = []
2096
+ liv_load_sensors, intgain_dehumidifier = add_total_loads_output(runner, model, living_zone)
2097
+ return unless add_component_loads
2546
2098
 
2547
- # EMS Sensors: Global
2099
+ add_component_loads_output(runner, model, living_zone, liv_load_sensors, intgain_dehumidifier)
2100
+ end
2548
2101
 
2102
+ def self.add_total_loads_output(runner, model, living_zone)
2549
2103
  liv_load_sensors = {}
2550
-
2551
2104
  liv_load_sensors[:htg] = OpenStudio::Model::EnergyManagementSystemSensor.new(model, "Heating:EnergyTransfer:Zone:#{living_zone.name.to_s.upcase}")
2552
2105
  liv_load_sensors[:htg].setName('htg_load_liv')
2553
-
2554
2106
  liv_load_sensors[:clg] = OpenStudio::Model::EnergyManagementSystemSensor.new(model, "Cooling:EnergyTransfer:Zone:#{living_zone.name.to_s.upcase}")
2555
2107
  liv_load_sensors[:clg].setName('clg_load_liv')
2556
2108
 
2557
2109
  tot_load_sensors = {}
2558
-
2559
2110
  tot_load_sensors[:htg] = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Heating:EnergyTransfer')
2560
2111
  tot_load_sensors[:htg].setName('htg_load_tot')
2561
-
2562
2112
  tot_load_sensors[:clg] = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Cooling:EnergyTransfer')
2563
2113
  tot_load_sensors[:clg].setName('clg_load_tot')
2564
2114
 
2565
- load_adj_sensors = {} # Sensors used to adjust E+ EnergyTransfer meter, eg. dehumidifier as load in our program, but included in Heating:EnergyTransfer as HVAC equipment
2115
+ # Need to adjusted E+ EnergyTransfer meters for dehumidifiers
2116
+ intgain_dehumidifier = nil
2117
+ model.getZoneHVACDehumidifierDXs.each do |e|
2118
+ next unless e.thermalZone.get.name.to_s == living_zone.name.to_s
2119
+
2120
+ { 'Zone Dehumidifier Sensible Heating Energy' => 'ig_dehumidifier' }.each do |var, name|
2121
+ intgain_dehumidifier = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
2122
+ intgain_dehumidifier.setName(name)
2123
+ intgain_dehumidifier.setKeyName(e.name.to_s)
2124
+ end
2125
+ end
2126
+
2127
+ # EMS program
2128
+ program = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
2129
+ program.setName(Constants.ObjectNameTotalLoadsProgram)
2130
+ program.addLine('Set loads_htg_tot = 0')
2131
+ program.addLine('Set loads_clg_tot = 0')
2132
+ program.addLine("If #{liv_load_sensors[:htg].name} > 0")
2133
+ s = " Set loads_htg_tot = #{tot_load_sensors[:htg].name} - #{tot_load_sensors[:clg].name}"
2134
+ if not intgain_dehumidifier.nil?
2135
+ s += " - #{intgain_dehumidifier.name}"
2136
+ end
2137
+ program.addLine(s)
2138
+ program.addLine("ElseIf #{liv_load_sensors[:clg].name} > 0")
2139
+ s = " Set loads_clg_tot = #{tot_load_sensors[:clg].name} - #{tot_load_sensors[:htg].name}"
2140
+ if not intgain_dehumidifier.nil?
2141
+ s += " + #{intgain_dehumidifier.name}"
2142
+ end
2143
+ program.addLine(s)
2144
+ program.addLine('EndIf')
2145
+
2146
+ # EMS calling manager
2147
+ program_calling_manager = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
2148
+ program_calling_manager.setName("#{program.name} calling manager")
2149
+ program_calling_manager.setCallingPoint('EndOfZoneTimestepAfterZoneReporting')
2150
+ program_calling_manager.addProgram(program)
2151
+
2152
+ return liv_load_sensors, intgain_dehumidifier
2153
+ end
2154
+
2155
+ def self.add_component_loads_output(runner, model, living_zone, liv_load_sensors, intgain_dehumidifier)
2156
+ # Prevent certain objects (e.g., OtherEquipment) from being counted towards both, e.g., ducts and internal gains
2157
+ objects_already_processed = []
2566
2158
 
2567
2159
  # EMS Sensors: Surfaces, SubSurfaces, InternalMass
2568
2160
 
@@ -2582,6 +2174,8 @@ class OSModel
2582
2174
  output_diagnostics = model.getOutputDiagnostics
2583
2175
  output_diagnostics.addKey('DisplayAdvancedReportVariables')
2584
2176
 
2177
+ area_tolerance = UnitConversions.convert(1.0, 'ft^2', 'm^2')
2178
+
2585
2179
  model.getSurfaces.sort.each_with_index do |s, idx|
2586
2180
  next unless s.space.get.thermalZone.get.name.to_s == living_zone.name.to_s
2587
2181
 
@@ -2624,7 +2218,7 @@ class OSModel
2624
2218
  end
2625
2219
  end
2626
2220
 
2627
- next if s.netArea < 0.1 # Skip parent surfaces (of subsurfaces) that have near zero net area
2221
+ next if s.netArea < area_tolerance # Skip parent surfaces (of subsurfaces) that have near zero net area
2628
2222
 
2629
2223
  key = { 'FoundationWall' => :foundation_walls,
2630
2224
  'RimJoist' => :rim_joists,
@@ -2704,9 +2298,7 @@ class OSModel
2704
2298
 
2705
2299
  infil_flow_actuators = []
2706
2300
  natvent_flow_actuators = []
2707
- mechvent_flow_actuators = []
2708
2301
  whf_flow_actuators = []
2709
- cd_flow_actuators = []
2710
2302
 
2711
2303
  model.getEnergyManagementSystemActuators.each do |actuator|
2712
2304
  next unless (actuator.actuatedComponentType == 'Zone Infiltration') && (actuator.actuatedComponentControlType == 'Air Exchange Flow Rate')
@@ -2717,18 +2309,15 @@ class OSModel
2717
2309
  natvent_flow_actuators << actuator
2718
2310
  elsif actuator.name.to_s.start_with? Constants.ObjectNameWholeHouseFan.gsub(' ', '_')
2719
2311
  whf_flow_actuators << actuator
2720
- elsif actuator.name.to_s.start_with? Constants.ObjectNameClothesDryerExhaust.gsub(' ', '_')
2721
- cd_flow_actuators << actuator
2722
2312
  end
2723
2313
  end
2724
- if (infil_flow_actuators.size != 1) || (natvent_flow_actuators.size != 1) || (whf_flow_actuators.size != 1) || (cd_flow_actuators.size != 1)
2314
+ if (infil_flow_actuators.size != 1) || (natvent_flow_actuators.size != 1) || (whf_flow_actuators.size != 1)
2725
2315
  fail 'Could not find actuator for component loads.'
2726
2316
  end
2727
2317
 
2728
2318
  infil_flow_actuator = infil_flow_actuators[0]
2729
2319
  natvent_flow_actuator = natvent_flow_actuators[0]
2730
2320
  whf_flow_actuator = whf_flow_actuators[0]
2731
- cd_flow_actuator = cd_flow_actuators[0]
2732
2321
 
2733
2322
  # EMS Sensors: Ducts
2734
2323
 
@@ -2755,27 +2344,7 @@ class OSModel
2755
2344
  ducts_mix_loss_sensor.setKeyName(living_zone.name.to_s)
2756
2345
  end
2757
2346
 
2758
- # Return duct losses
2759
- model.getOtherEquipments.sort.each do |o|
2760
- next if objects_already_processed.include? o
2761
-
2762
- is_duct_load = o.additionalProperties.getFeatureAsBoolean(Constants.IsDuctLoadForReport)
2763
- next unless is_duct_load.is_initialized
2764
-
2765
- objects_already_processed << o
2766
- next unless is_duct_load.get
2767
-
2768
- ducts_sensors << []
2769
- { 'Other Equipment Convective Heating Energy' => 'ducts_conv',
2770
- 'Other Equipment Radiant Heating Energy' => 'ducts_rad' }.each do |var, name|
2771
- ducts_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
2772
- ducts_sensor.setName(name)
2773
- ducts_sensor.setKeyName(o.name.to_s)
2774
- ducts_sensors[-1] << ducts_sensor
2775
- end
2776
- end
2777
-
2778
- # Supply duct losses
2347
+ # Duct losses
2779
2348
  model.getOtherEquipments.sort.each do |o|
2780
2349
  next if objects_already_processed.include? o
2781
2350
 
@@ -2813,20 +2382,6 @@ class OSModel
2813
2382
  end
2814
2383
  end
2815
2384
 
2816
- model.getGasEquipments.sort.each do |o|
2817
- next unless o.space.get.thermalZone.get.name.to_s == living_zone.name.to_s
2818
- next if objects_already_processed.include? o
2819
-
2820
- intgains_sensors << []
2821
- { 'Gas Equipment Convective Heating Energy' => 'ig_ge_conv',
2822
- 'Gas Equipment Radiant Heating Energy' => 'ig_ge_rad' }.each do |var, name|
2823
- intgains_gas_equip_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
2824
- intgains_gas_equip_sensor.setName(name)
2825
- intgains_gas_equip_sensor.setKeyName(o.name.to_s)
2826
- intgains_sensors[-1] << intgains_gas_equip_sensor
2827
- end
2828
- end
2829
-
2830
2385
  model.getOtherEquipments.sort.each do |o|
2831
2386
  next unless o.space.get.thermalZone.get.name.to_s == living_zone.name.to_s
2832
2387
  next if objects_already_processed.include? o
@@ -2868,17 +2423,8 @@ class OSModel
2868
2423
  end
2869
2424
  end
2870
2425
 
2871
- model.getZoneHVACDehumidifierDXs.each do |e|
2872
- next unless e.thermalZone.get.name.to_s == living_zone.name.to_s
2873
-
2874
- intgains_sensors << []
2875
- { 'Zone Dehumidifier Sensible Heating Energy' => 'ig_dehumidifier' }.each do |var, name|
2876
- intgain_dehumidifier = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
2877
- intgain_dehumidifier.setName(name)
2878
- intgain_dehumidifier.setKeyName(e.name.to_s)
2879
- load_adj_sensors[:dehumidifier] = intgain_dehumidifier
2880
- intgains_sensors[-1] << intgain_dehumidifier
2881
- end
2426
+ if not intgain_dehumidifier.nil?
2427
+ intgains_sensors[-1] << intgain_dehumidifier
2882
2428
  end
2883
2429
 
2884
2430
  intgains_dhw_sensors = {}
@@ -2906,7 +2452,7 @@ class OSModel
2906
2452
  intgains_dhw_sensors[dhw_sensor] = [offcycle_loss, oncycle_loss, dhw_rtf_sensor]
2907
2453
  end
2908
2454
 
2909
- nonsurf_names = ['intgains', 'infil', 'mechvent', 'natvent', 'whf', 'ducts', 'cd']
2455
+ nonsurf_names = ['intgains', 'infil', 'mechvent', 'natvent', 'whf', 'ducts']
2910
2456
 
2911
2457
  # EMS program
2912
2458
  program = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
@@ -2946,18 +2492,16 @@ class OSModel
2946
2492
  end
2947
2493
 
2948
2494
  # EMS program: Infiltration, Natural Ventilation, Mechanical Ventilation, Ducts
2949
- program.addLine("Set hr_airflow_rate = #{infil_flow_actuator.name} + #{natvent_flow_actuator.name} + #{whf_flow_actuator.name} + #{cd_flow_actuator.name}")
2495
+ program.addLine("Set hr_airflow_rate = #{infil_flow_actuator.name} + #{natvent_flow_actuator.name} + #{whf_flow_actuator.name}")
2950
2496
  program.addLine('If hr_airflow_rate > 0')
2951
2497
  program.addLine(" Set hr_infil = (#{air_loss_sensor.name} - #{air_gain_sensor.name}) * #{infil_flow_actuator.name} / hr_airflow_rate") # Airflow heat attributed to infiltration
2952
2498
  program.addLine(" Set hr_natvent = (#{air_loss_sensor.name} - #{air_gain_sensor.name}) * #{natvent_flow_actuator.name} / hr_airflow_rate") # Airflow heat attributed to natural ventilation
2953
2499
  program.addLine(" Set hr_whf = (#{air_loss_sensor.name} - #{air_gain_sensor.name}) * #{whf_flow_actuator.name} / hr_airflow_rate") # Airflow heat attributed to whole house fan
2954
- program.addLine(" Set hr_cd = ((#{air_loss_sensor.name} - #{air_gain_sensor.name}) * #{cd_flow_actuator.name} / hr_airflow_rate)") # Airflow heat attributed to clothes dryer exhaust
2955
2500
  program.addLine('Else')
2956
2501
  program.addLine(' Set hr_infil = 0')
2957
2502
  program.addLine(' Set hr_natvent = 0')
2958
2503
  program.addLine(' Set hr_whf = 0')
2959
2504
  program.addLine(' Set hr_mechvent = 0')
2960
- program.addLine(' Set hr_cd = 0')
2961
2505
  program.addLine('EndIf')
2962
2506
  program.addLine('Set hr_mechvent = 0')
2963
2507
  mechvent_sensors.each do |sensor|
@@ -3002,27 +2546,6 @@ class OSModel
3002
2546
  end
3003
2547
  end
3004
2548
 
3005
- # EMS program: Total loads
3006
- program.addLine('Set loads_htg_tot = 0')
3007
- program.addLine('Set loads_clg_tot = 0')
3008
- program.addLine("If #{liv_load_sensors[:htg].name} > 0")
3009
- s = " Set loads_htg_tot = #{tot_load_sensors[:htg].name} - #{tot_load_sensors[:clg].name}"
3010
- load_adj_sensors.each do |key, adj_sensor|
3011
- if ['dehumidifier'].include? key.to_s
3012
- s += " - #{adj_sensor.name}"
3013
- end
3014
- end
3015
- program.addLine(s)
3016
- program.addLine("ElseIf #{liv_load_sensors[:clg].name} > 0")
3017
- s = " Set loads_clg_tot = #{tot_load_sensors[:clg].name} - #{tot_load_sensors[:htg].name}"
3018
- load_adj_sensors.each do |key, adj_sensor|
3019
- if ['dehumidifier'].include? key.to_s
3020
- s += " + #{adj_sensor.name}"
3021
- end
3022
- end
3023
- program.addLine(s)
3024
- program.addLine('EndIf')
3025
-
3026
2549
  # EMS calling manager
3027
2550
  program_calling_manager = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
3028
2551
  program_calling_manager.setName("#{program.name} calling manager")
@@ -3030,400 +2553,28 @@ class OSModel
3030
2553
  program_calling_manager.addProgram(program)
3031
2554
  end
3032
2555
 
3033
- def self.set_vacancy(runner, model)
3034
- return if @schedules_file.nil?
3035
-
3036
- @schedules_file.set_vacancy(col_names: ScheduleGenerator.col_names)
3037
- end
3038
-
3039
- # FUTURE: Move all of these construction methods to constructions.rb
3040
- def self.calc_non_cavity_r(film_r, constr_set)
3041
- # Calculate R-value for all non-cavity layers
3042
- non_cavity_r = film_r
3043
- if not constr_set.exterior_material.nil?
3044
- non_cavity_r += constr_set.exterior_material.rvalue
3045
- end
3046
- if not constr_set.rigid_r.nil?
3047
- non_cavity_r += constr_set.rigid_r
3048
- end
3049
- if not constr_set.osb_thick_in.nil?
3050
- non_cavity_r += Material.Plywood(constr_set.osb_thick_in).rvalue
3051
- end
3052
- if not constr_set.drywall_thick_in.nil?
3053
- non_cavity_r += Material.GypsumWall(constr_set.drywall_thick_in).rvalue
3054
- end
3055
- return non_cavity_r
3056
- end
3057
-
3058
- def self.apply_wall_construction(runner, model, surfaces, wall, wall_id, wall_type, assembly_r,
3059
- drywall_thick_in, inside_film, outside_film, mat_ext_finish)
3060
-
3061
- film_r = inside_film.rvalue + outside_film.rvalue
3062
- if mat_ext_finish.nil?
3063
- fallback_mat_ext_finish = nil
3064
- else
3065
- fallback_mat_ext_finish = Material.ExteriorFinishMaterial(mat_ext_finish.name, mat_ext_finish.tAbs, mat_ext_finish.sAbs, 0.1)
3066
- end
3067
-
3068
- if wall_type == HPXML::WallTypeWoodStud
3069
- install_grade = 1
3070
- cavity_filled = true
3071
-
3072
- constr_sets = [
3073
- WoodStudConstructionSet.new(Material.Stud2x6, 0.20, 10.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x6, 24" o.c. + R10
3074
- WoodStudConstructionSet.new(Material.Stud2x6, 0.20, 5.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x6, 24" o.c. + R5
3075
- WoodStudConstructionSet.new(Material.Stud2x6, 0.20, 0.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x6, 24" o.c.
3076
- WoodStudConstructionSet.new(Material.Stud2x4, 0.23, 0.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x4, 16" o.c.
3077
- WoodStudConstructionSet.new(Material.Stud2x4, 0.01, 0.0, 0.0, 0.0, fallback_mat_ext_finish), # Fallback
3078
- ]
3079
- match, constr_set, cavity_r = pick_wood_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, wall_id)
3080
-
3081
- Constructions.apply_wood_stud_wall(runner, model, surfaces, wall, "#{wall_id} construction",
3082
- cavity_r, install_grade, constr_set.stud.thick_in,
3083
- cavity_filled, constr_set.framing_factor,
3084
- constr_set.drywall_thick_in, constr_set.osb_thick_in,
3085
- constr_set.rigid_r, constr_set.exterior_material,
3086
- 0, inside_film, outside_film)
3087
- elsif wall_type == HPXML::WallTypeSteelStud
3088
- install_grade = 1
3089
- cavity_filled = true
3090
- corr_factor = 0.45
3091
-
3092
- constr_sets = [
3093
- SteelStudConstructionSet.new(5.5, corr_factor, 0.20, 10.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x6, 24" o.c. + R10
3094
- SteelStudConstructionSet.new(5.5, corr_factor, 0.20, 5.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x6, 24" o.c. + R5
3095
- SteelStudConstructionSet.new(5.5, corr_factor, 0.20, 0.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x6, 24" o.c.
3096
- SteelStudConstructionSet.new(3.5, corr_factor, 0.23, 0.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x4, 16" o.c.
3097
- SteelStudConstructionSet.new(3.5, 1.0, 0.01, 0.0, 0.0, 0.0, fallback_mat_ext_finish), # Fallback
3098
- ]
3099
- match, constr_set, cavity_r = pick_steel_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, wall_id)
3100
-
3101
- Constructions.apply_steel_stud_wall(runner, model, surfaces, wall, "#{wall_id} construction",
3102
- cavity_r, install_grade, constr_set.cavity_thick_in,
3103
- cavity_filled, constr_set.framing_factor,
3104
- constr_set.corr_factor, constr_set.drywall_thick_in,
3105
- constr_set.osb_thick_in, constr_set.rigid_r,
3106
- constr_set.exterior_material, inside_film, outside_film)
3107
- elsif wall_type == HPXML::WallTypeDoubleWoodStud
3108
- install_grade = 1
3109
- is_staggered = false
3110
-
3111
- constr_sets = [
3112
- DoubleStudConstructionSet.new(Material.Stud2x4, 0.23, 24.0, 0.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x4, 24" o.c.
3113
- DoubleStudConstructionSet.new(Material.Stud2x4, 0.01, 16.0, 0.0, 0.0, 0.0, fallback_mat_ext_finish), # Fallback
3114
- ]
3115
- match, constr_set, cavity_r = pick_double_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, wall_id)
3116
-
3117
- Constructions.apply_double_stud_wall(runner, model, surfaces, wall, "#{wall_id} construction",
3118
- cavity_r, install_grade, constr_set.stud.thick_in,
3119
- constr_set.stud.thick_in, constr_set.framing_factor,
3120
- constr_set.framing_spacing, is_staggered,
3121
- constr_set.drywall_thick_in, constr_set.osb_thick_in,
3122
- constr_set.rigid_r, constr_set.exterior_material,
3123
- inside_film, outside_film)
3124
- elsif wall_type == HPXML::WallTypeCMU
3125
- density = 119.0 # lb/ft^3
3126
- furring_r = 0
3127
- furring_cavity_depth_in = 0 # in
3128
- furring_spacing = 0
3129
-
3130
- constr_sets = [
3131
- CMUConstructionSet.new(8.0, 1.4, 0.08, 0.5, drywall_thick_in, mat_ext_finish), # 8" perlite-filled CMU
3132
- CMUConstructionSet.new(6.0, 5.29, 0.01, 0.0, 0.0, fallback_mat_ext_finish), # Fallback (6" hollow CMU)
3133
- ]
3134
- match, constr_set, rigid_r = pick_cmu_construction_set(assembly_r, constr_sets, inside_film, outside_film, wall_id)
3135
-
3136
- Constructions.apply_cmu_wall(runner, model, surfaces, wall, "#{wall_id} construction",
3137
- constr_set.thick_in, constr_set.cond_in, density,
3138
- constr_set.framing_factor, furring_r,
3139
- furring_cavity_depth_in, furring_spacing,
3140
- constr_set.drywall_thick_in, constr_set.osb_thick_in,
3141
- rigid_r, constr_set.exterior_material, inside_film,
3142
- outside_film)
3143
- elsif wall_type == HPXML::WallTypeSIP
3144
- sheathing_thick_in = 0.44
3145
-
3146
- constr_sets = [
3147
- SIPConstructionSet.new(10.0, 0.16, 0.0, sheathing_thick_in, 0.5, drywall_thick_in, mat_ext_finish), # 10" SIP core
3148
- SIPConstructionSet.new(5.0, 0.16, 0.0, sheathing_thick_in, 0.5, drywall_thick_in, mat_ext_finish), # 5" SIP core
3149
- SIPConstructionSet.new(1.0, 0.01, 0.0, sheathing_thick_in, 0.0, 0.0, fallback_mat_ext_finish), # Fallback
3150
- ]
3151
- match, constr_set, cavity_r = pick_sip_construction_set(assembly_r, constr_sets, inside_film, outside_film, wall_id)
3152
-
3153
- Constructions.apply_sip_wall(runner, model, surfaces, wall, "#{wall_id} construction",
3154
- cavity_r, constr_set.thick_in, constr_set.framing_factor,
3155
- constr_set.sheath_thick_in, constr_set.drywall_thick_in,
3156
- constr_set.osb_thick_in, constr_set.rigid_r,
3157
- constr_set.exterior_material, inside_film, outside_film)
3158
- elsif wall_type == HPXML::WallTypeICF
3159
- constr_sets = [
3160
- ICFConstructionSet.new(2.0, 4.0, 0.08, 0.0, 0.5, drywall_thick_in, mat_ext_finish), # ICF w/4" concrete and 2" rigid ins layers
3161
- ICFConstructionSet.new(1.0, 1.0, 0.01, 0.0, 0.0, 0.0, fallback_mat_ext_finish), # Fallback
3162
- ]
3163
- match, constr_set, icf_r = pick_icf_construction_set(assembly_r, constr_sets, inside_film, outside_film, wall_id)
3164
-
3165
- Constructions.apply_icf_wall(runner, model, surfaces, wall, "#{wall_id} construction",
3166
- icf_r, constr_set.ins_thick_in,
3167
- constr_set.concrete_thick_in, constr_set.framing_factor,
3168
- constr_set.drywall_thick_in, constr_set.osb_thick_in,
3169
- constr_set.rigid_r, constr_set.exterior_material,
3170
- inside_film, outside_film)
3171
- elsif [HPXML::WallTypeConcrete, HPXML::WallTypeBrick, HPXML::WallTypeAdobe, HPXML::WallTypeStrawBale, HPXML::WallTypeStone, HPXML::WallTypeLog].include? wall_type
3172
- constr_sets = [
3173
- GenericConstructionSet.new(10.0, 0.5, drywall_thick_in, mat_ext_finish), # w/R-10 rigid
3174
- GenericConstructionSet.new(0.0, 0.5, drywall_thick_in, mat_ext_finish), # Standard
3175
- GenericConstructionSet.new(0.0, 0.0, 0.0, fallback_mat_ext_finish), # Fallback
3176
- ]
3177
- match, constr_set, layer_r = pick_generic_construction_set(assembly_r, constr_sets, inside_film, outside_film, wall_id)
3178
-
3179
- if wall_type == HPXML::WallTypeConcrete
3180
- thick_in = 6.0
3181
- base_mat = BaseMaterial.Concrete
3182
- elsif wall_type == HPXML::WallTypeBrick
3183
- thick_in = 8.0
3184
- base_mat = BaseMaterial.Brick
3185
- elsif wall_type == HPXML::WallTypeAdobe
3186
- thick_in = 10.0
3187
- base_mat = BaseMaterial.Soil
3188
- elsif wall_type == HPXML::WallTypeStrawBale
3189
- thick_in = 23.0
3190
- base_mat = BaseMaterial.StrawBale
3191
- elsif wall_type == HPXML::WallTypeStone
3192
- thick_in = 6.0
3193
- base_mat = BaseMaterial.Stone
3194
- elsif wall_type == HPXML::WallTypeLog
3195
- thick_in = 6.0
3196
- base_mat = BaseMaterial.Wood
3197
- end
3198
- thick_ins = [thick_in]
3199
- if layer_r == 0
3200
- conds = [99]
3201
- else
3202
- conds = [thick_in / layer_r]
3203
- end
3204
- denss = [base_mat.rho]
3205
- specheats = [base_mat.cp]
3206
-
3207
- Constructions.apply_generic_layered_wall(runner, model, surfaces, wall, "#{wall_id} construction",
3208
- thick_ins, conds, denss, specheats,
3209
- constr_set.drywall_thick_in, constr_set.osb_thick_in,
3210
- constr_set.rigid_r, constr_set.exterior_material,
3211
- inside_film, outside_film)
3212
- else
3213
- fail "Unexpected wall type '#{wall_type}'."
3214
- end
3215
-
3216
- check_surface_assembly_rvalue(runner, surfaces, inside_film, outside_film, assembly_r, match)
3217
- end
3218
-
3219
- def self.pick_wood_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, surface_name)
3220
- # Picks a construction set from supplied constr_sets for which a positive R-value
3221
- # can be calculated for the unknown insulation to achieve the assembly R-value.
3222
-
3223
- constr_sets.each do |constr_set|
3224
- fail 'Unexpected object.' unless constr_set.is_a? WoodStudConstructionSet
3225
-
3226
- film_r = inside_film.rvalue + outside_film.rvalue
3227
- non_cavity_r = calc_non_cavity_r(film_r, constr_set)
3228
-
3229
- # Calculate effective cavity R-value
3230
- # Assumes installation quality 1
3231
- cavity_frac = 1.0 - constr_set.framing_factor
3232
- cavity_r = cavity_frac / (1.0 / assembly_r - constr_set.framing_factor / (constr_set.stud.rvalue + non_cavity_r)) - non_cavity_r
3233
- if cavity_r > 0 # Choose this construction set
3234
- return true, constr_set, cavity_r
3235
- end
3236
- end
2556
+ def self.add_output_control_files(runner, model)
2557
+ return if @debug
3237
2558
 
3238
- return false, constr_sets[-1], 0.0 # Pick fallback construction with minimum R-value
2559
+ # Disable various output files
2560
+ ocf = model.getOutputControlFiles
2561
+ ocf.setOutputAUDIT(false)
2562
+ ocf.setOutputBND(false)
2563
+ ocf.setOutputEIO(false)
2564
+ ocf.setOutputESO(false)
2565
+ ocf.setOutputMDD(false)
2566
+ ocf.setOutputMTD(false)
2567
+ ocf.setOutputMTR(false)
2568
+ ocf.setOutputRDD(false)
2569
+ ocf.setOutputSHD(false)
2570
+ ocf.setOutputTabular(false)
3239
2571
  end
3240
2572
 
3241
- def self.pick_steel_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, surface_name)
3242
- # Picks a construction set from supplied constr_sets for which a positive R-value
3243
- # can be calculated for the unknown insulation to achieve the assembly R-value.
3244
-
3245
- constr_sets.each do |constr_set|
3246
- fail 'Unexpected object.' unless constr_set.is_a? SteelStudConstructionSet
3247
-
3248
- film_r = inside_film.rvalue + outside_film.rvalue
3249
- non_cavity_r = calc_non_cavity_r(film_r, constr_set)
3250
-
3251
- # Calculate effective cavity R-value
3252
- # Assumes installation quality 1
3253
- cavity_r = (assembly_r - non_cavity_r) / constr_set.corr_factor
3254
- if cavity_r > 0 # Choose this construction set
3255
- return true, constr_set, cavity_r
3256
- end
3257
- end
3258
-
3259
- return false, constr_sets[-1], 0.0 # Pick fallback construction with minimum R-value
3260
- end
3261
-
3262
- def self.pick_double_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, surface_name)
3263
- # Picks a construction set from supplied constr_sets for which a positive R-value
3264
- # can be calculated for the unknown insulation to achieve the assembly R-value.
3265
-
3266
- constr_sets.each do |constr_set|
3267
- fail 'Unexpected object.' unless constr_set.is_a? DoubleStudConstructionSet
3268
-
3269
- film_r = inside_film.rvalue + outside_film.rvalue
3270
- non_cavity_r = calc_non_cavity_r(film_r, constr_set)
3271
-
3272
- # Calculate effective cavity R-value
3273
- # Assumes installation quality 1, not staggered, gap depth == stud depth
3274
- # Solved in Wolfram Alpha: https://www.wolframalpha.com/input/?i=1%2FA+%3D+B%2F(2*C%2Bx%2BD)+%2B+E%2F(3*C%2BD)+%2B+(1-B-E)%2F(3*x%2BD)
3275
- stud_frac = 1.5 / constr_set.framing_spacing
3276
- misc_framing_factor = constr_set.framing_factor - stud_frac
3277
- cavity_frac = 1.0 - (2 * stud_frac + misc_framing_factor)
3278
- a = assembly_r
3279
- b = stud_frac
3280
- c = constr_set.stud.rvalue
3281
- d = non_cavity_r
3282
- e = misc_framing_factor
3283
- cavity_r = ((3 * c + d) * Math.sqrt(4 * a**2 * b**2 + 12 * a**2 * b * e + 4 * a**2 * b + 9 * a**2 * e**2 - 6 * a**2 * e + a**2 - 48 * a * b * c - 16 * a * b * d - 36 * a * c * e + 12 * a * c - 12 * a * d * e + 4 * a * d + 36 * c**2 + 24 * c * d + 4 * d**2) + 6 * a * b * c + 2 * a * b * d + 3 * a * c * e + 3 * a * c + 3 * a * d * e + a * d - 18 * c**2 - 18 * c * d - 4 * d**2) / (2 * (-3 * a * e + 9 * c + 3 * d))
3284
- cavity_r = 3 * cavity_r
3285
- if cavity_r > 0 # Choose this construction set
3286
- return true, constr_set, cavity_r
3287
- end
3288
- end
3289
-
3290
- return false, constr_sets[-1], 0.0 # Pick fallback construction with minimum R-value
3291
- end
3292
-
3293
- def self.pick_sip_construction_set(assembly_r, constr_sets, inside_film, outside_film, surface_name)
3294
- # Picks a construction set from supplied constr_sets for which a positive R-value
3295
- # can be calculated for the unknown insulation to achieve the assembly R-value.
3296
-
3297
- constr_sets.each do |constr_set|
3298
- fail 'Unexpected object.' unless constr_set.is_a? SIPConstructionSet
3299
-
3300
- film_r = inside_film.rvalue + outside_film.rvalue
3301
- non_cavity_r = calc_non_cavity_r(film_r, constr_set)
3302
- non_cavity_r += Material.new(nil, constr_set.sheath_thick_in, BaseMaterial.Wood).rvalue
3303
-
3304
- # Calculate effective SIP core R-value
3305
- # Solved in Wolfram Alpha: https://www.wolframalpha.com/input/?i=1%2FA+%3D+B%2F(C%2BD)+%2B+E%2F(2*F%2BG%2FH*x%2BD)+%2B+(1-B-E)%2F(x%2BD)
3306
- spline_thick_in = 0.5 # in
3307
- ins_thick_in = constr_set.thick_in - (2.0 * spline_thick_in) # in
3308
- framing_r = Material.new(nil, constr_set.thick_in, BaseMaterial.Wood).rvalue
3309
- spline_r = Material.new(nil, spline_thick_in, BaseMaterial.Wood).rvalue
3310
- spline_frac = 4.0 / 48.0 # One 4" spline for every 48" wide panel
3311
- cavity_frac = 1.0 - (spline_frac + constr_set.framing_factor)
3312
- a = assembly_r
3313
- b = constr_set.framing_factor
3314
- c = framing_r
3315
- d = non_cavity_r
3316
- e = spline_frac
3317
- f = spline_r
3318
- g = ins_thick_in
3319
- h = constr_set.thick_in
3320
- cavity_r = (Math.sqrt((a * b * c * g - a * b * d * h - 2 * a * b * f * h + a * c * e * g - a * c * e * h - a * c * g + a * d * e * g - a * d * e * h - a * d * g + c * d * g + c * d * h + 2 * c * f * h + d**2 * g + d**2 * h + 2 * d * f * h)**2 - 4 * (-a * b * g + c * g + d * g) * (a * b * c * d * h + 2 * a * b * c * f * h - a * c * d * h + 2 * a * c * e * f * h - 2 * a * c * f * h - a * d**2 * h + 2 * a * d * e * f * h - 2 * a * d * f * h + c * d**2 * h + 2 * c * d * f * h + d**3 * h + 2 * d**2 * f * h)) - a * b * c * g + a * b * d * h + 2 * a * b * f * h - a * c * e * g + a * c * e * h + a * c * g - a * d * e * g + a * d * e * h + a * d * g - c * d * g - c * d * h - 2 * c * f * h - g * d**2 - d**2 * h - 2 * d * f * h) / (2 * (-a * b * g + c * g + d * g))
3321
- if cavity_r > 0 # Choose this construction set
3322
- return true, constr_set, cavity_r
3323
- end
3324
- end
3325
-
3326
- return false, constr_sets[-1], 0.0 # Pick fallback construction with minimum R-value
3327
- end
3328
-
3329
- def self.pick_cmu_construction_set(assembly_r, constr_sets, inside_film, outside_film, surface_name)
3330
- # Picks a construction set from supplied constr_sets for which a positive R-value
3331
- # can be calculated for the unknown insulation to achieve the assembly R-value.
3332
-
3333
- constr_sets.each do |constr_set|
3334
- fail 'Unexpected object.' unless constr_set.is_a? CMUConstructionSet
3335
-
3336
- film_r = inside_film.rvalue + outside_film.rvalue
3337
- non_cavity_r = calc_non_cavity_r(film_r, constr_set)
3338
-
3339
- # Calculate effective other CMU R-value
3340
- # Assumes no furring strips
3341
- # Solved in Wolfram Alpha: https://www.wolframalpha.com/input/?i=1%2FA+%3D+B%2F(C%2BE%2Bx)+%2B+(1-B)%2F(D%2BE%2Bx)
3342
- a = assembly_r
3343
- b = constr_set.framing_factor
3344
- c = Material.new(nil, constr_set.thick_in, BaseMaterial.Wood).rvalue # Framing
3345
- d = Material.new(nil, constr_set.thick_in, BaseMaterial.Concrete, constr_set.cond_in).rvalue # Concrete
3346
- e = non_cavity_r
3347
- rigid_r = 0.5 * (Math.sqrt(a**2 - 4 * a * b * c + 4 * a * b * d + 2 * a * c - 2 * a * d + c**2 - 2 * c * d + d**2) + a - c - d - 2 * e)
3348
- if rigid_r > 0 # Choose this construction set
3349
- return true, constr_set, rigid_r
3350
- end
3351
- end
3352
-
3353
- return false, constr_sets[-1], 0.0 # Pick fallback construction with minimum R-value
3354
- end
3355
-
3356
- def self.pick_icf_construction_set(assembly_r, constr_sets, inside_film, outside_film, surface_name)
3357
- # Picks a construction set from supplied constr_sets for which a positive R-value
3358
- # can be calculated for the unknown insulation to achieve the assembly R-value.
3359
-
3360
- constr_sets.each do |constr_set|
3361
- fail 'Unexpected object.' unless constr_set.is_a? ICFConstructionSet
3362
-
3363
- film_r = inside_film.rvalue + outside_film.rvalue
3364
- non_cavity_r = calc_non_cavity_r(film_r, constr_set)
3365
-
3366
- # Calculate effective ICF rigid ins R-value
3367
- # Solved in Wolfram Alpha: https://www.wolframalpha.com/input/?i=1%2FA+%3D+B%2F(C%2BE)+%2B+(1-B)%2F(D%2BE%2B2*x)
3368
- a = assembly_r
3369
- b = constr_set.framing_factor
3370
- c = Material.new(nil, 2 * constr_set.ins_thick_in + constr_set.concrete_thick_in, BaseMaterial.Wood).rvalue # Framing
3371
- d = Material.new(nil, constr_set.concrete_thick_in, BaseMaterial.Concrete).rvalue # Concrete
3372
- e = non_cavity_r
3373
- icf_r = (a * b * c - a * b * d - a * c - a * e + c * d + c * e + d * e + e**2) / (2 * (a * b - c - e))
3374
- if icf_r > 0 # Choose this construction set
3375
- return true, constr_set, icf_r
3376
- end
3377
- end
3378
-
3379
- return false, constr_sets[-1], 0.0 # Pick fallback construction with minimum R-value
3380
- end
3381
-
3382
- def self.pick_generic_construction_set(assembly_r, constr_sets, inside_film, outside_film, surface_name)
3383
- # Picks a construction set from supplied constr_sets for which a positive R-value
3384
- # can be calculated for the unknown insulation to achieve the assembly R-value.
3385
-
3386
- constr_sets.each do |constr_set|
3387
- fail 'Unexpected object.' unless constr_set.is_a? GenericConstructionSet
3388
-
3389
- film_r = inside_film.rvalue + outside_film.rvalue
3390
- non_cavity_r = calc_non_cavity_r(film_r, constr_set)
3391
-
3392
- # Calculate effective ins layer R-value
3393
- layer_r = assembly_r - non_cavity_r
3394
- if layer_r > 0 # Choose this construction set
3395
- return true, constr_set, layer_r
3396
- end
3397
- end
3398
-
3399
- return false, constr_sets[-1], 0.0 # Pick fallback construction with minimum R-value
3400
- end
3401
-
3402
- def self.check_surface_assembly_rvalue(runner, surfaces, inside_film, outside_film, assembly_r, match)
3403
- # Verify that the actual OpenStudio construction R-value matches our target assembly R-value
3404
-
3405
- film_r = 0.0
3406
- film_r += inside_film.rvalue unless inside_film.nil?
3407
- film_r += outside_film.rvalue unless outside_film.nil?
3408
- surfaces.each do |surface|
3409
- constr_r = UnitConversions.convert(1.0 / surface.construction.get.uFactor(0.0).get, 'm^2*k/w', 'hr*ft^2*f/btu') + film_r
3410
-
3411
- if surface.adjacentFoundation.is_initialized
3412
- foundation = surface.adjacentFoundation.get
3413
- foundation.customBlocks.each do |custom_block|
3414
- ins_mat = custom_block.material.to_StandardOpaqueMaterial.get
3415
- constr_r += UnitConversions.convert(ins_mat.thickness, 'm', 'ft') / UnitConversions.convert(ins_mat.thermalConductivity, 'W/(m*K)', 'Btu/(hr*ft*R)')
3416
- end
3417
- end
3418
-
3419
- if (assembly_r - constr_r).abs > 0.1
3420
- if match
3421
- fail "Construction R-value (#{constr_r}) does not match Assembly R-value (#{assembly_r}) for '#{surface.name}'."
3422
- else
3423
- runner.registerWarning("Assembly R-value (#{assembly_r}) for '#{surface.name}' below minimum expected value. Construction R-value increased to #{constr_r.round(2)}.")
3424
- end
3425
- end
3426
- end
2573
+ def self.add_ems_debug_output(runner, model)
2574
+ oems = model.getOutputEnergyManagementSystem
2575
+ oems.setActuatorAvailabilityDictionaryReporting('Verbose')
2576
+ oems.setInternalVariableAvailabilityDictionaryReporting('Verbose')
2577
+ oems.setEMSRuntimeLanguageDebugOutputLevel('Verbose')
3427
2578
  end
3428
2579
 
3429
2580
  def self.set_surface_interior(model, spaces, surface, hpxml_surface)
@@ -3451,7 +2602,7 @@ class OSModel
3451
2602
  set_surface_otherside_coefficients(surface, exterior_adjacent_to, model, spaces)
3452
2603
  elsif exterior_adjacent_to == HPXML::LocationBasementConditioned
3453
2604
  surface.createAdjacentSurface(create_or_get_space(model, spaces, HPXML::LocationLivingSpace))
3454
- @cond_bsmnt_surfaces << surface
2605
+ @cond_bsmnt_surfaces << surface.adjacentSurface.get
3455
2606
  else
3456
2607
  surface.createAdjacentSurface(create_or_get_space(model, spaces, exterior_adjacent_to))
3457
2608
  end
@@ -3462,8 +2613,7 @@ class OSModel
3462
2613
  # Create E+ other side coefficient object
3463
2614
  otherside_object = OpenStudio::Model::SurfacePropertyOtherSideCoefficients.new(model)
3464
2615
  otherside_object.setName(exterior_adjacent_to)
3465
- # Refer to: https://www.sciencedirect.com/science/article/pii/B9780123972705000066 6.1.2 Part: Wall and roof transfer functions
3466
- otherside_object.setCombinedConvectiveRadiativeFilmCoefficient(8.3)
2616
+ otherside_object.setCombinedConvectiveRadiativeFilmCoefficient(UnitConversions.convert(1.0 / Material.AirFilmVertical.rvalue, 'Btu/(hr*ft^2*F)', 'W/(m^2*K)'))
3467
2617
  # Schedule of space temperature, can be shared with water heater/ducts
3468
2618
  sch = get_space_temperature_schedule(model, exterior_adjacent_to, spaces)
3469
2619
  otherside_object.setConstantTemperatureSchedule(sch)
@@ -3523,7 +2673,7 @@ class OSModel
3523
2673
  sensor_gnd.setName('ground_temp')
3524
2674
  end
3525
2675
 
3526
- actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(sch, 'Schedule:Constant', 'Schedule Value')
2676
+ actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(sch, *EPlus::EMSActuatorScheduleConstantValue)
3527
2677
  actuator.setName("#{location.gsub(' ', '_').gsub('-', '_')}_temp_sch")
3528
2678
 
3529
2679
  # EMS to actuate schedule
@@ -3594,9 +2744,7 @@ class OSModel
3594
2744
  space = create_or_get_space(model, spaces, location)
3595
2745
  end
3596
2746
 
3597
- if spaces.size != num_orig_spaces
3598
- fail "#{object_name} location is '#{location}' but building does not have this location specified."
3599
- end
2747
+ fail if spaces.size != num_orig_spaces # EPvalidator.xml should prevent this
3600
2748
 
3601
2749
  return space
3602
2750
  end
@@ -3613,19 +2761,6 @@ class OSModel
3613
2761
  end
3614
2762
  end
3615
2763
 
3616
- def self.get_min_neighbor_distance()
3617
- min_neighbor_distance = nil
3618
- @hpxml.neighbor_buildings.each do |neighbor_building|
3619
- if min_neighbor_distance.nil?
3620
- min_neighbor_distance = 9e99
3621
- end
3622
- if neighbor_building.distance < min_neighbor_distance
3623
- min_neighbor_distance = neighbor_building.distance
3624
- end
3625
- end
3626
- return min_neighbor_distance
3627
- end
3628
-
3629
2764
  def self.get_kiva_instances(fnd_walls, slabs)
3630
2765
  # Identify unique Kiva foundations that are required.
3631
2766
  kiva_fnd_walls = []
@@ -3653,93 +2788,5 @@ class OSModel
3653
2788
  end
3654
2789
  end
3655
2790
 
3656
- # FUTURE: Move all of these construction classes to constructions.rb
3657
- class WoodStudConstructionSet
3658
- def initialize(stud, framing_factor, rigid_r, osb_thick_in, drywall_thick_in, exterior_material)
3659
- @stud = stud
3660
- @framing_factor = framing_factor
3661
- @rigid_r = rigid_r
3662
- @osb_thick_in = osb_thick_in
3663
- @drywall_thick_in = drywall_thick_in
3664
- @exterior_material = exterior_material
3665
- end
3666
- attr_accessor(:stud, :framing_factor, :rigid_r, :osb_thick_in, :drywall_thick_in, :exterior_material)
3667
- end
3668
-
3669
- class SteelStudConstructionSet
3670
- def initialize(cavity_thick_in, corr_factor, framing_factor, rigid_r, osb_thick_in, drywall_thick_in, exterior_material)
3671
- @cavity_thick_in = cavity_thick_in
3672
- @corr_factor = corr_factor
3673
- @framing_factor = framing_factor
3674
- @rigid_r = rigid_r
3675
- @osb_thick_in = osb_thick_in
3676
- @drywall_thick_in = drywall_thick_in
3677
- @exterior_material = exterior_material
3678
- end
3679
- attr_accessor(:cavity_thick_in, :corr_factor, :framing_factor, :rigid_r, :osb_thick_in, :drywall_thick_in, :exterior_material)
3680
- end
3681
-
3682
- class DoubleStudConstructionSet
3683
- def initialize(stud, framing_factor, framing_spacing, rigid_r, osb_thick_in, drywall_thick_in, exterior_material)
3684
- @stud = stud
3685
- @framing_factor = framing_factor
3686
- @framing_spacing = framing_spacing
3687
- @rigid_r = rigid_r
3688
- @osb_thick_in = osb_thick_in
3689
- @drywall_thick_in = drywall_thick_in
3690
- @exterior_material = exterior_material
3691
- end
3692
- attr_accessor(:stud, :framing_factor, :framing_spacing, :rigid_r, :osb_thick_in, :drywall_thick_in, :exterior_material)
3693
- end
3694
-
3695
- class SIPConstructionSet
3696
- def initialize(thick_in, framing_factor, rigid_r, sheath_thick_in, osb_thick_in, drywall_thick_in, exterior_material)
3697
- @thick_in = thick_in
3698
- @framing_factor = framing_factor
3699
- @rigid_r = rigid_r
3700
- @sheath_thick_in = sheath_thick_in
3701
- @osb_thick_in = osb_thick_in
3702
- @drywall_thick_in = drywall_thick_in
3703
- @exterior_material = exterior_material
3704
- end
3705
- attr_accessor(:thick_in, :framing_factor, :rigid_r, :sheath_thick_in, :osb_thick_in, :drywall_thick_in, :exterior_material)
3706
- end
3707
-
3708
- class CMUConstructionSet
3709
- def initialize(thick_in, cond_in, framing_factor, osb_thick_in, drywall_thick_in, exterior_material)
3710
- @thick_in = thick_in
3711
- @cond_in = cond_in
3712
- @framing_factor = framing_factor
3713
- @osb_thick_in = osb_thick_in
3714
- @drywall_thick_in = drywall_thick_in
3715
- @exterior_material = exterior_material
3716
- @rigid_r = nil # solved for
3717
- end
3718
- attr_accessor(:thick_in, :cond_in, :framing_factor, :rigid_r, :osb_thick_in, :drywall_thick_in, :exterior_material)
3719
- end
3720
-
3721
- class ICFConstructionSet
3722
- def initialize(ins_thick_in, concrete_thick_in, framing_factor, rigid_r, osb_thick_in, drywall_thick_in, exterior_material)
3723
- @ins_thick_in = ins_thick_in
3724
- @concrete_thick_in = concrete_thick_in
3725
- @framing_factor = framing_factor
3726
- @rigid_r = rigid_r
3727
- @osb_thick_in = osb_thick_in
3728
- @drywall_thick_in = drywall_thick_in
3729
- @exterior_material = exterior_material
3730
- end
3731
- attr_accessor(:ins_thick_in, :concrete_thick_in, :framing_factor, :rigid_r, :osb_thick_in, :drywall_thick_in, :exterior_material)
3732
- end
3733
-
3734
- class GenericConstructionSet
3735
- def initialize(rigid_r, osb_thick_in, drywall_thick_in, exterior_material)
3736
- @rigid_r = rigid_r
3737
- @osb_thick_in = osb_thick_in
3738
- @drywall_thick_in = drywall_thick_in
3739
- @exterior_material = exterior_material
3740
- end
3741
- attr_accessor(:rigid_r, :osb_thick_in, :drywall_thick_in, :exterior_material)
3742
- end
3743
-
3744
2791
  # register the measure to be used by the application
3745
2792
  HPXMLtoOpenStudio.new.registerWithApplication