urbanopt-cli 0.5.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (907) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -2
  3. data/CHANGELOG.md +43 -1
  4. data/CMakeLists.txt +14 -14
  5. data/FindOpenStudioSDK.cmake +11 -6
  6. data/Gemfile +11 -5
  7. data/LICENSE.md +11 -1
  8. data/Rakefile +16 -6
  9. data/example_files/Gemfile +8 -8
  10. data/example_files/example_project_combined.json +100 -5
  11. data/example_files/example_project_with_streets.json +826 -0
  12. data/example_files/mappers/Baseline.rb +107 -59
  13. data/example_files/mappers/CreateBar.rb +17 -7
  14. data/example_files/mappers/EvCharging.rb +20 -10
  15. data/example_files/mappers/Floorspace.rb +17 -7
  16. data/example_files/mappers/HighEfficiency.rb +20 -8
  17. data/example_files/mappers/HighEfficiencyCreateBar.rb +19 -8
  18. data/example_files/mappers/HighEfficiencyFloorspace.rb +19 -8
  19. data/example_files/mappers/ThermalStorage.rb +16 -6
  20. data/example_files/measures/BuildResidentialModel/measure.rb +249 -134
  21. data/example_files/reopt/base_assumptions.json +2 -2
  22. data/example_files/reopt/multiPV_assumptions.json +4 -3
  23. data/example_files/residential/clothes_dryer.tsv +7 -7
  24. data/example_files/residential/clothes_washer.tsv +1 -1
  25. data/example_files/residential/cooling_system.tsv +42 -22
  26. data/example_files/residential/dishwasher.tsv +1 -1
  27. data/example_files/residential/exhaust.tsv +3 -0
  28. data/example_files/residential/heat_pump.tsv +62 -40
  29. data/example_files/resources/hpxml-measures/.github/pull_request_template.md +2 -1
  30. data/example_files/resources/hpxml-measures/.github/workflows/config.yml +116 -0
  31. data/example_files/resources/hpxml-measures/.gitignore +1 -8
  32. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.rb +746 -1236
  33. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.xml +1550 -1215
  34. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/constants.rb +0 -8
  35. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb +432 -343
  36. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules.rb +134 -91
  37. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_config.json +388 -0
  38. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_config.md +43 -0
  39. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_weekday_state_and_monthly_schedule_shift.csv +613 -0
  40. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_weekend_state_and_monthly_schedule_shift.csv +613 -0
  41. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-coal.osw +36 -60
  42. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-dehumidifier-ief-portable.osw +35 -59
  43. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-dehumidifier-ief-whole-home.osw +35 -59
  44. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-dehumidifier.osw +35 -59
  45. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-gas.osw +36 -60
  46. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-modified.osw +36 -60
  47. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-none.osw +41 -65
  48. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-oil.osw +36 -60
  49. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-propane.osw +36 -60
  50. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-wood.osw +36 -60
  51. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-flat.osw +36 -60
  52. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-radiant-barrier.osw +36 -60
  53. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-unvented-insulated-roof.osw +36 -60
  54. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-vented.osw +36 -60
  55. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-boiler-only-baseboard.osw +341 -0
  56. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-boiler-only-fan-coil.osw +341 -0
  57. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-mechvent-preconditioning.osw +39 -63
  58. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-mechvent.osw +39 -63
  59. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-pv.osw +39 -63
  60. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-water-heater.osw +39 -63
  61. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily.osw +39 -63
  62. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-single-family-attached.osw +36 -60
  63. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-combi-tankless-outside.osw +36 -61
  64. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-combi-tankless.osw +36 -61
  65. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-dwhr.osw +36 -60
  66. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect-outside.osw +36 -61
  67. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect-standbyloss.osw +36 -61
  68. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect-with-solar-fraction.osw +36 -61
  69. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect.osw +36 -61
  70. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-electric.osw +36 -60
  71. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-gas.osw +36 -60
  72. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-hpwh.osw +36 -60
  73. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-indirect.osw +36 -61
  74. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-low-flow-fixtures.osw +36 -60
  75. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-none.osw +37 -61
  76. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-demand.osw +36 -60
  77. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-manual.osw +36 -60
  78. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-nocontrol.osw +36 -60
  79. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-temperature.osw +36 -60
  80. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-timer.osw +36 -60
  81. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-direct-evacuated-tube.osw +36 -60
  82. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-direct-flat-plate.osw +36 -60
  83. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-direct-ics.osw +36 -60
  84. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-fraction.osw +36 -60
  85. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-indirect-flat-plate.osw +36 -60
  86. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-thermosyphon-flat-plate.osw +36 -60
  87. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-coal.osw +36 -60
  88. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-elec-uef.osw +36 -60
  89. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-gas-outside.osw +36 -60
  90. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-gas-uef.osw +36 -60
  91. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-gas.osw +36 -60
  92. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-outside.osw +36 -60
  93. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-uef.osw +36 -60
  94. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-with-solar-fraction.osw +36 -60
  95. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-with-solar.osw +36 -60
  96. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump.osw +36 -60
  97. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-oil.osw +36 -60
  98. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-wood.osw +36 -60
  99. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-electric-outside.osw +36 -60
  100. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-electric-uef.osw +36 -60
  101. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-electric.osw +36 -60
  102. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas-uef.osw +36 -60
  103. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas-with-solar-fraction.osw +36 -60
  104. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas-with-solar.osw +36 -60
  105. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas.osw +36 -60
  106. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-propane.osw +36 -60
  107. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-2stories-garage.osw +36 -60
  108. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-2stories.osw +36 -60
  109. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-1.osw +36 -60
  110. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-2.osw +36 -60
  111. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-4.osw +36 -60
  112. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-5.osw +36 -60
  113. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-garage.osw +36 -60
  114. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-ach-house-pressure.osw +36 -60
  115. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-cfm-house-pressure.osw +36 -60
  116. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-cfm50.osw +36 -60
  117. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-flue.osw +36 -60
  118. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-natural-ach.osw +37 -61
  119. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-overhangs.osw +37 -61
  120. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-windows-none.osw +36 -60
  121. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-ambient.osw +36 -60
  122. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-conditioned-basement-slab-insulation.osw +36 -60
  123. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-slab.osw +36 -60
  124. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unconditioned-basement-assembly-r.osw +35 -59
  125. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unconditioned-basement-wall-insulation.osw +35 -59
  126. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unconditioned-basement.osw +35 -59
  127. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unvented-crawlspace.osw +35 -59
  128. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-vented-crawlspace.osw +35 -59
  129. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-1-speed-cooling-only.osw +337 -0
  130. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-1-speed-heating-only.osw +337 -0
  131. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-1-speed.osw +36 -61
  132. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-2-speed.osw +36 -60
  133. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-var-speed.osw +36 -60
  134. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-coal-only.osw +36 -60
  135. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-elec-only.osw +36 -60
  136. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-gas-central-ac-1-speed.osw +36 -61
  137. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-gas-only.osw +36 -61
  138. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-oil-only.osw +36 -60
  139. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-propane-only.osw +36 -60
  140. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-wood-only.osw +36 -60
  141. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-only-1-speed.osw +36 -61
  142. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-only-2-speed.osw +36 -60
  143. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-only-var-speed.osw +36 -60
  144. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.osw +36 -62
  145. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-electric.osw +35 -60
  146. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.osw +35 -60
  147. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.osw +35 -59
  148. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.osw +35 -59
  149. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-mini-split-heat-pump-ducted.osw +36 -61
  150. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ducts-leakage-percent.osw +36 -60
  151. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-elec-resistance-only.osw +36 -60
  152. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-evap-cooler-furnace-gas.osw +36 -60
  153. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-evap-cooler-only-ducted.osw +37 -61
  154. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-evap-cooler-only.osw +36 -61
  155. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-fireplace-wood-only.osw +36 -61
  156. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-fixed-heater-gas-only.osw +37 -62
  157. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-floor-furnace-propane-only.osw +36 -61
  158. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-coal-only.osw +337 -0
  159. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-elec-central-ac-1-speed.osw +36 -60
  160. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-elec-only.osw +36 -60
  161. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-central-ac-2-speed.osw +36 -60
  162. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-central-ac-var-speed.osw +36 -60
  163. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-only.osw +36 -61
  164. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-room-ac.osw +36 -60
  165. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-oil-only.osw +36 -60
  166. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-propane-only.osw +36 -60
  167. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-wood-only.osw +36 -60
  168. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ground-to-air-heat-pump-cooling-only.osw +336 -0
  169. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ground-to-air-heat-pump-heating-only.osw +336 -0
  170. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ground-to-air-heat-pump.osw +36 -62
  171. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-plug-loads-additional-multipliers.osw → base-hvac-install-quality-airflow-defect-furnace-gas-central-ac-1-speed.osw} +41 -63
  172. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-air-to-air-heat-pump-1-speed.osw +339 -0
  173. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-air-to-air-heat-pump-2-speed.osw +339 -0
  174. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-air-to-air-heat-pump-var-speed.osw +339 -0
  175. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-central-ac-1-speed.osw +340 -0
  176. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-central-ac-2-speed.osw +340 -0
  177. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-central-ac-var-speed.osw +340 -0
  178. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-only.osw +338 -0
  179. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-ground-to-air-heat-pump.osw +338 -0
  180. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-mini-split-air-conditioner-only-ducted.osw +338 -0
  181. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-mini-split-heat-pump-ducted.osw +339 -0
  182. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-charge-defect-furnace-gas-central-ac-1-speed.osw +338 -0
  183. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-none-furnace-gas-central-ac-1-speed.osw +340 -0
  184. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-air-conditioner-only-ducted.osw +36 -61
  185. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-air-conditioner-only-ductless.osw +36 -61
  186. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ducted-cooling-only.osw +36 -61
  187. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ducted-heating-only.osw +36 -61
  188. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ducted.osw +37 -62
  189. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ductless.osw +37 -62
  190. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-none.osw +36 -60
  191. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-portable-heater-gas-only.osw +37 -62
  192. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-programmable-thermostat-detailed.osw +337 -0
  193. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-room-ac-only-33percent.osw +36 -60
  194. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-room-ac-only.osw +36 -60
  195. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-setpoints.osw +36 -60
  196. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-stove-oil-only.osw +36 -61
  197. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-stove-wood-pellets-only.osw +36 -61
  198. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-undersized.osw +36 -60
  199. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-wall-furnace-elec-only.osw +36 -61
  200. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-lighting-ceiling-fans.osw +36 -60
  201. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-lighting-detailed.osw +36 -60
  202. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-AMY-2012.osw +36 -60
  203. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-baltimore-md.osw +45 -69
  204. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-dallas-tx.osw +36 -60
  205. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-duluth-mn.osw +49 -73
  206. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-helena-mt.osw +337 -0
  207. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{base-appliances-dehumidifier-50percent.osw → base-location-honolulu-hi.osw} +39 -63
  208. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-miami-fl.osw +36 -60
  209. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-phoenix-az.osw +337 -0
  210. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-portland-or.osw +337 -0
  211. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-balanced.osw +36 -60
  212. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-bath-kitchen-fans.osw +44 -70
  213. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-cfis-evap-cooler-only-ducted.osw +37 -61
  214. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-cfis.osw +36 -60
  215. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-erv-atre-asre.osw +36 -60
  216. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-erv.osw +36 -60
  217. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-exhaust-rated-flow-rate.osw +337 -0
  218. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-exhaust.osw +36 -60
  219. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-hrv-asre.osw +36 -60
  220. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-hrv.osw +36 -60
  221. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-supply.osw +36 -60
  222. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-whole-house-fan.osw +36 -60
  223. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-defaults.osw +34 -58
  224. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-loads-large-uncommon.osw +34 -58
  225. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-loads-large-uncommon2.osw +34 -58
  226. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-neighbor-shading.osw +36 -60
  227. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-shielding-of-home.osw +337 -0
  228. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-usage-multiplier.osw +35 -59
  229. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-pv.osw +36 -60
  230. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-vacancy-6-months.osw → base-schedules-stochastic-vacant.osw} +39 -63
  231. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-schedules-stochastic.osw +36 -60
  232. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-schedules-user-specified.osw +36 -60
  233. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-calendar-year-custom.osw +36 -60
  234. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-daylight-saving-custom.osw +36 -60
  235. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-daylight-saving-disabled.osw +36 -60
  236. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-runperiod-1-month.osw +36 -60
  237. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-timestep-10-mins.osw +36 -60
  238. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base.osw +36 -60
  239. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/build_residential_hpxml_test.rb +60 -57
  240. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-auto.osw +36 -60
  241. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-double-exterior.osw +341 -0
  242. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-double-loaded-interior.osw +341 -0
  243. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-eaves.osw +341 -0
  244. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-single-exterior-front.osw +341 -0
  245. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-double-loaded-interior.osw +341 -0
  246. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-bottom-double-loaded-interior.osw +341 -0
  247. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-bottom.osw +341 -0
  248. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-middle-double-loaded-interior.osw +341 -0
  249. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-middle.osw +341 -0
  250. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-top-double-loaded-interior.osw +341 -0
  251. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-top.osw +341 -0
  252. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-bottom-double-loaded-interior.osw +341 -0
  253. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-bottom.osw +341 -0
  254. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-middle-double-loaded-interior.osw +341 -0
  255. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-middle.osw +341 -0
  256. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-top-double-loaded-interior.osw +341 -0
  257. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-top.osw +341 -0
  258. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-bottom-double-loaded-interior.osw +341 -0
  259. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-bottom.osw +341 -0
  260. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-middle-double-loaded-interior.osw +341 -0
  261. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-middle.osw +341 -0
  262. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-top-double-loaded-interior.osw +341 -0
  263. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-top.osw +341 -0
  264. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab.osw +341 -0
  265. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-double-loaded-interior.osw +341 -0
  266. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-bottom-double-loaded-interior.osw +341 -0
  267. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-bottom.osw +341 -0
  268. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-middle-double-loaded-interior.osw +341 -0
  269. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-middle.osw +341 -0
  270. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-top-double-loaded-interior.osw +341 -0
  271. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-top.osw +341 -0
  272. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-bottom-double-loaded-interior.osw +341 -0
  273. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-bottom.osw +341 -0
  274. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-middle-double-loaded-interior.osw +341 -0
  275. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-middle.osw +341 -0
  276. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-top-double-loaded-interior.osw +341 -0
  277. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-top.osw +341 -0
  278. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-bottom-double-loaded-interior.osw +341 -0
  279. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-bottom.osw +341 -0
  280. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-middle-double-loaded-interior.osw +341 -0
  281. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-middle.osw +341 -0
  282. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-top-double-loaded-interior.osw +341 -0
  283. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-top.osw +341 -0
  284. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace.osw +341 -0
  285. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-double-loaded-interior.osw +341 -0
  286. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-bottom-double-loaded-interior.osw +341 -0
  287. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-bottom.osw +341 -0
  288. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-middle-double-loaded-interior.osw +341 -0
  289. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-middle.osw +341 -0
  290. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-top-double-loaded-interior.osw +341 -0
  291. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-top.osw +341 -0
  292. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-bottom-double-loaded-interior.osw +341 -0
  293. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-bottom.osw +341 -0
  294. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-middle-double-loaded-interior.osw +341 -0
  295. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-middle.osw +341 -0
  296. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-top-double-loaded-interior.osw +341 -0
  297. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-top.osw +341 -0
  298. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-bottom-double-loaded-interior.osw +341 -0
  299. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-bottom.osw +341 -0
  300. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-middle-double-loaded-interior.osw +341 -0
  301. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-middle.osw +341 -0
  302. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-top-double-loaded-interior.osw +341 -0
  303. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-top.osw +341 -0
  304. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace.osw +341 -0
  305. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-atticroof-conditioned-eaves-gable.osw +339 -0
  306. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-atticroof-conditioned-eaves-hip.osw +339 -0
  307. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-atticroof-flat.osw +339 -0
  308. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-double-exterior.osw +339 -0
  309. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-double-loaded-interior.osw +339 -0
  310. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-single-exterior-front.osw +339 -0
  311. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-slab-middle.osw +339 -0
  312. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-slab-right.osw +339 -0
  313. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-slab.osw +339 -0
  314. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unconditioned-basement-middle.osw +339 -0
  315. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unconditioned-basement-right.osw +339 -0
  316. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unconditioned-basement.osw +339 -0
  317. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unvented-crawlspace-middle.osw +339 -0
  318. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unvented-crawlspace-right.osw +339 -0
  319. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unvented-crawlspace.osw +339 -0
  320. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-vented-crawlspace-middle.osw +339 -0
  321. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-vented-crawlspace-right.osw +339 -0
  322. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-vented-crawlspace.osw +339 -0
  323. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-dhw-solar-latitude.osw +36 -60
  324. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-atticroof-conditioned-eaves-gable.osw +337 -0
  325. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-atticroof-conditioned-eaves-hip.osw +337 -0
  326. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-garage-atticroof-conditioned.osw +337 -0
  327. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-garage-partially-protruded.osw +36 -60
  328. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-windows-shading.osw +339 -0
  329. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-gas-hot-tub-heater-with-zero-kwh.osw +337 -0
  330. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-gas-pool-heater-with-zero-kwh.osw +337 -0
  331. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-pv-roofpitch.osw +36 -60
  332. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-schedules-random-seed.osw +36 -60
  333. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-boiler-to-heat-pump.osw +336 -0
  334. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-boiler-to-heating-system.osw +337 -0
  335. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-fireplace-to-heat-pump.osw +337 -0
  336. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-second-heating-system-fireplace.osw → extra-second-heating-system-fireplace-to-heating-system.osw} +38 -62
  337. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-portable-heater-to-heat-pump.osw +337 -0
  338. 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} +36 -60
  339. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-refrigerator.osw +36 -60
  340. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-clothes-washer-kwh.osw +337 -0
  341. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-dishwasher-kwh.osw +337 -0
  342. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-extra-refrigerator-kwh.osw +337 -0
  343. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-freezer-kwh.osw +337 -0
  344. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-refrigerator-kwh.osw +337 -0
  345. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/conditioned-attic-with-floor-insulation.osw +39 -63
  346. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/conditioned-attic-with-one-floor-above-grade.osw +337 -0
  347. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/conditioned-basement-with-ceiling-insulation.osw +36 -60
  348. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/cooling-system-and-heat-pump.osw +36 -60
  349. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/dhw-indirect-without-boiler.osw +36 -60
  350. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/ducts-location-and-areas-not-same-type.osw +36 -60
  351. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/foundation-wall-insulation-greater-than-height.osw +337 -0
  352. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/heating-system-and-heat-pump.osw +36 -60
  353. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multifamily-bottom-crawlspace-zero-foundation-height.osw +39 -63
  354. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multifamily-bottom-slab-non-zero-foundation-height.osw +39 -63
  355. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multifamily-no-building-orientation.osw +38 -62
  356. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-fuel-loads.osw +36 -60
  357. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-other-plug-loads.osw +337 -0
  358. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/{multipliers-without-plug-loads.osw → multipliers-without-tv-plug-loads.osw} +40 -64
  359. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-vehicle-plug-loads.osw +337 -0
  360. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-well-pump-plug-loads.osw +337 -0
  361. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/non-electric-heat-pump-water-heater.osw +36 -60
  362. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/non-integer-ceiling-fan-quantity.osw +36 -60
  363. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/non-integer-geometry-num-bathrooms.osw +36 -60
  364. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/second-heating-system-but-no-primary-heating.osw +337 -0
  365. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/second-heating-system-serves-majority-heat.osw +36 -60
  366. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/second-heating-system-serves-total-heat-load.osw +337 -0
  367. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-attached-ambient.osw +36 -60
  368. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-attached-no-building-orientation.osw +36 -60
  369. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-detached-finished-basement-zero-foundation-height.osw +36 -60
  370. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-detached-slab-non-zero-foundation-height.osw +36 -60
  371. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-detached-with-shared-system.osw +337 -0
  372. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/slab-non-zero-foundation-height-above-grade.osw +36 -60
  373. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/unconditioned-basement-with-wall-and-ceiling-insulation.osw +36 -60
  374. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/unvented-attic-with-floor-and-roof-insulation.osw +36 -60
  375. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/unvented-crawlspace-with-wall-and-ceiling-insulation.osw +36 -60
  376. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/vented-attic-with-floor-and-roof-insulation.osw +38 -62
  377. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/vented-crawlspace-with-wall-and-ceiling-insulation.osw +36 -60
  378. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/zero-number-of-bedrooms.osw +337 -0
  379. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/schedules/vacant.csv +8761 -0
  380. data/example_files/resources/hpxml-measures/Changelog.md +249 -0
  381. data/example_files/resources/hpxml-measures/Gemfile +3 -4
  382. data/example_files/resources/hpxml-measures/Gemfile.lock +27 -32
  383. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb +318 -1283
  384. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml +167 -121
  385. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/BaseElements.xsd +7 -97
  386. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/EPvalidator.xml +600 -203
  387. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/HPXMLDataTypes.xsd +21 -28
  388. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/HPXMLvalidator.xml +114 -22
  389. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb +112 -177
  390. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constants.rb +16 -180
  391. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb +543 -94
  392. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/energyplus.rb +1 -0
  393. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/generator.rb +4 -7
  394. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb +410 -14
  395. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb +27 -25
  396. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb +782 -460
  397. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_defaults.rb +455 -107
  398. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb +1466 -1403
  399. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb +1391 -1467
  400. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb +2 -1
  401. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/location.rb +20 -7
  402. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/meta_measure.rb +85 -13
  403. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/minitest_helper.rb +4 -26
  404. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb +14 -33
  405. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/pv.rb +3 -4
  406. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb +43 -7
  407. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/simcontrols.rb +24 -7
  408. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/unit_conversions.rb +2 -0
  409. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb +2 -2
  410. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb +4 -4
  411. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb +32 -30
  412. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb +6 -29
  413. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_defaults.rb +523 -635
  414. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_enclosure.rb +151 -0
  415. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_generator.rb +3 -1
  416. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb +4 -2
  417. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac.rb +297 -7
  418. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb +0 -1
  419. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb +3 -1
  420. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_location.rb +3 -1
  421. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb +3 -1
  422. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_pv.rb +3 -1
  423. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_simcontrols.rb +3 -1
  424. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb +26 -3
  425. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_water_heater.rb +3 -1
  426. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/util.rb +26 -0
  427. data/example_files/resources/hpxml-measures/README.md +4 -5
  428. data/example_files/resources/hpxml-measures/Rakefile +1 -2
  429. data/example_files/resources/hpxml-measures/SimulationOutputReport/measure.rb +140 -47
  430. data/example_files/resources/hpxml-measures/SimulationOutputReport/measure.xml +351 -495
  431. data/example_files/resources/hpxml-measures/SimulationOutputReport/tests/output_report_test.rb +260 -189
  432. data/example_files/resources/hpxml-measures/docs/source/conf.py +4 -1
  433. data/example_files/resources/hpxml-measures/docs/source/getting_started.rst +3 -3
  434. data/example_files/resources/hpxml-measures/docs/source/intro.rst +4 -105
  435. data/example_files/resources/hpxml-measures/docs/source/workflow_inputs.rst +538 -396
  436. data/example_files/resources/hpxml-measures/docs/source/workflow_outputs.rst +158 -130
  437. data/example_files/resources/hpxml-measures/tasks.rb +1497 -736
  438. data/example_files/resources/hpxml-measures/weather/USA_AZ_Phoenix-Sky.Harbor.Intl.AP.722780_TMY3-cache.csv +35 -0
  439. data/example_files/resources/hpxml-measures/weather/USA_AZ_Phoenix-Sky.Harbor.Intl.AP.722780_TMY3.epw +8768 -0
  440. data/example_files/resources/hpxml-measures/weather/USA_CO_Denver.Intl.AP.725650_TMY3-cache.csv +10 -10
  441. data/example_files/resources/hpxml-measures/weather/USA_HI_Honolulu.Intl.AP.911820_TMY3-cache.csv +35 -0
  442. data/example_files/resources/hpxml-measures/weather/USA_HI_Honolulu.Intl.AP.911820_TMY3.epw +8768 -0
  443. data/example_files/resources/hpxml-measures/weather/USA_MT_Helena.Rgnl.AP.727720_TMY3-cache.csv +35 -0
  444. data/example_files/resources/hpxml-measures/weather/USA_MT_Helena.Rgnl.AP.727720_TMY3.epw +8768 -0
  445. data/example_files/resources/hpxml-measures/weather/USA_OR_Portland.Intl.AP.726980_TMY3-cache.csv +35 -0
  446. data/example_files/resources/hpxml-measures/weather/USA_OR_Portland.Intl.AP.726980_TMY3.epw +8768 -0
  447. data/example_files/resources/hpxml-measures/workflow/run_simulation.rb +36 -5
  448. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-coal.xml +4 -3
  449. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-portable.xml +5 -3
  450. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-whole-home.xml +5 -3
  451. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-multiple.xml +535 -0
  452. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier.xml +5 -3
  453. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-gas.xml +4 -3
  454. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-modified.xml +4 -3
  455. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-none.xml +4 -2
  456. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil.xml +4 -3
  457. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane.xml +4 -3
  458. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-wood.xml +4 -3
  459. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-cathedral.xml +4 -3
  460. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-conditioned.xml +6 -5
  461. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-flat.xml +4 -3
  462. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-radiant-barrier.xml +4 -3
  463. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-unvented-insulated-roof.xml +4 -3
  464. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-vented.xml +4 -3
  465. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multifamily-buffer-space.xml +4 -3
  466. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multiple.xml +4 -3
  467. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-non-freezing-space.xml +4 -3
  468. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-other-heated-space.xml +4 -3
  469. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-other-housing-unit.xml +4 -3
  470. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-baseboard.xml +0 -1
  471. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil-ducted.xml +4 -4
  472. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil.xml +3 -5
  473. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-water-loop-heat-pump.xml +28 -18
  474. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-cooling-tower-water-loop-heat-pump.xml +28 -18
  475. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-baseboard.xml +0 -1
  476. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-ducted.xml +4 -4
  477. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-eae.xml +3 -5
  478. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil.xml +3 -5
  479. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-water-loop-heat-pump.xml +23 -11
  480. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-baseboard.xml +0 -1
  481. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil-ducted.xml +4 -4
  482. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil.xml +3 -5
  483. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-water-loop-heat-pump.xml +23 -12
  484. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-cooling-tower-only-water-loop-heat-pump.xml +23 -12
  485. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-generator.xml +4 -3
  486. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-ground-loop-ground-to-air-heat-pump.xml +6 -6
  487. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-laundry-room.xml +4 -3
  488. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-multiple.xml +8 -5
  489. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-preconditioning.xml +4 -3
  490. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent.xml +4 -3
  491. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-pv.xml +4 -3
  492. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater-recirc.xml +4 -3
  493. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater.xml +4 -3
  494. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily.xml +4 -3
  495. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-single-family-attached.xml +17 -4
  496. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless-outside.xml +1 -2
  497. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless.xml +1 -2
  498. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-2-speed.xml +3 -2
  499. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-gshp.xml +564 -564
  500. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-hpwh.xml +4 -3
  501. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-tankless.xml +3 -5
  502. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-var-speed.xml +3 -2
  503. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater.xml +3 -5
  504. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-dwhr.xml +4 -3
  505. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-dse.xml +1 -2
  506. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-outside.xml +1 -2
  507. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-standbyloss.xml +1 -2
  508. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-with-solar-fraction.xml +1 -2
  509. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect.xml +1 -2
  510. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-electric.xml +4 -3
  511. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-gas.xml +4 -3
  512. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-hpwh.xml +4 -3
  513. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-indirect.xml +1 -2
  514. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-low-flow-fixtures.xml +4 -3
  515. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-multiple.xml +1 -2
  516. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-none.xml +4 -2
  517. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-demand.xml +4 -3
  518. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-manual.xml +4 -3
  519. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-nocontrol.xml +4 -3
  520. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-temperature.xml +4 -3
  521. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-timer.xml +4 -3
  522. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-evacuated-tube.xml +4 -3
  523. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-flat-plate.xml +4 -3
  524. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-ics.xml +4 -3
  525. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-fraction.xml +4 -3
  526. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-indirect-flat-plate.xml +4 -3
  527. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-thermosyphon-flat-plate.xml +4 -3
  528. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-coal.xml +4 -3
  529. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-elec-uef.xml +4 -3
  530. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-outside.xml +4 -3
  531. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef.xml +4 -3
  532. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas.xml +4 -3
  533. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-outside.xml +4 -3
  534. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-uef.xml +4 -3
  535. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar-fraction.xml +4 -3
  536. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar.xml +4 -3
  537. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump.xml +4 -3
  538. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-oil.xml +4 -3
  539. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-wood.xml +4 -3
  540. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-outside.xml +4 -3
  541. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-uef.xml +4 -3
  542. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric.xml +4 -3
  543. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-uef.xml +4 -3
  544. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar-fraction.xml +4 -3
  545. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar.xml +4 -3
  546. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas.xml +4 -3
  547. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-propane.xml +4 -3
  548. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories-garage.xml +5 -4
  549. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories.xml +4 -3
  550. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-1.xml +4 -3
  551. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-2.xml +4 -3
  552. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-4.xml +4 -3
  553. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-5.xml +4 -3
  554. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-garage.xml +4 -3
  555. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-ach-house-pressure.xml +4 -3
  556. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm-house-pressure.xml +4 -3
  557. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm50.xml +4 -3
  558. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-flue.xml +4 -3
  559. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-natural-ach.xml +5 -4
  560. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-overhangs.xml +9 -3
  561. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-rooftypes.xml +4 -3
  562. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-shading.xml +601 -0
  563. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights.xml +6 -5
  564. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-level.xml +4 -3
  565. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces.xml +22 -21
  566. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces2.xml +2475 -0
  567. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-walltypes.xml +4 -3
  568. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-none.xml +4 -3
  569. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-enclosure-windows-interior-shading.xml → base-enclosure-windows-shading.xml} +577 -561
  570. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-ambient.xml +4 -3
  571. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-basement-garage.xml +644 -0
  572. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-complex.xml +4 -3
  573. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-slab-insulation.xml +4 -3
  574. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-wall-interior-insulation.xml +4 -3
  575. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-multiple.xml +6 -5
  576. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-slab.xml +4 -3
  577. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-above-grade.xml +5 -4
  578. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-assembly-r.xml +5 -4
  579. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-wall-insulation.xml +4 -3
  580. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement.xml +5 -4
  581. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unvented-crawlspace.xml +4 -3
  582. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-vented-crawlspace.xml +4 -3
  583. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-walkout-basement.xml +4 -3
  584. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-cooling-only.xml +556 -0
  585. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-heating-only.xml +562 -0
  586. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed.xml +6 -8
  587. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-2-speed.xml +6 -5
  588. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed.xml +6 -5
  589. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-cooling-only.xml +553 -0
  590. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-heating-only.xml +558 -0
  591. 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-autosize-air-to-air-heat-pump-1-speed-manual-s-oversize-allowances.xml} +2 -4
  592. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed.xml +558 -0
  593. 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} +560 -559
  594. 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} +557 -556
  595. 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} +560 -559
  596. 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} +557 -556
  597. 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} +517 -518
  598. 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} +569 -569
  599. 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} +518 -519
  600. 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} +2 -4
  601. 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} +547 -546
  602. 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} +547 -546
  603. 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} +2 -7
  604. 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-autosize-dual-fuel-air-to-air-heat-pump-1-speed.xml} +2 -4
  605. 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} +2 -4
  606. 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} +508 -509
  607. 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} +553 -552
  608. 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} +511 -512
  609. 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} +547 -546
  610. 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} +560 -559
  611. 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} +560 -559
  612. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-only.xml +548 -0
  613. 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} +558 -557
  614. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-cooling-only.xml +555 -0
  615. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-heating-only.xml +560 -0
  616. 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} +562 -562
  617. 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} +559 -559
  618. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-air-conditioner-only-ducted.xml +547 -0
  619. 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} +2 -4
  620. 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} +2 -4
  621. 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-autosize-mini-split-heat-pump-ducted-manual-s-oversize-allowances.xml} +2 -4
  622. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted.xml +557 -0
  623. 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} +507 -508
  624. 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} +511 -512
  625. 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} +511 -512
  626. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-autosize.xml → base-hvac-autosize.xml} +560 -559
  627. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-coal-only.xml +1 -2
  628. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-elec-only.xml +1 -2
  629. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-central-ac-1-speed.xml +4 -4
  630. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-only.xml +1 -2
  631. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-oil-only.xml +1 -2
  632. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-propane-only.xml +1 -2
  633. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-wood-only.xml +1 -2
  634. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed.xml +3 -5
  635. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-2-speed.xml +3 -2
  636. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-var-speed.xml +3 -2
  637. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.xml +7 -12
  638. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dse.xml +2 -3
  639. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-electric.xml +5 -7
  640. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.xml +5 -7
  641. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.xml +5 -4
  642. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.xml +5 -4
  643. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-mini-split-heat-pump-ducted.xml +5 -7
  644. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-percent.xml +4 -3
  645. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-elec-resistance-only.xml +1 -2
  646. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-furnace-gas.xml +4 -2
  647. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only-ducted.xml +11 -1
  648. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only.xml +1 -4
  649. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fireplace-wood-only.xml +512 -513
  650. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fixed-heater-gas-only.xml +512 -563
  651. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-floor-furnace-propane-only.xml +512 -513
  652. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-coal-only.xml +548 -547
  653. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-central-ac-1-speed.xml +4 -3
  654. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-only.xml +3 -2
  655. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-2-speed.xml +4 -3
  656. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-var-speed.xml +4 -3
  657. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only.xml +548 -550
  658. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-room-ac.xml +4 -3
  659. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-oil-only.xml +3 -2
  660. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-propane-only.xml +3 -2
  661. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-wood-only.xml +3 -2
  662. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-x3-dse.xml +4 -5
  663. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-cooling-only.xml +557 -0
  664. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-heating-only.xml +563 -0
  665. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump.xml +562 -562
  666. data/example_files/resources/hpxml-measures/workflow/sample_files/{invalid_files/slab-zero-exposed-perimeter.xml → base-hvac-install-quality-airflow-defect-furnace-gas-central-ac-1-speed.xml} +568 -561
  667. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-air-to-air-heat-pump-1-speed-autosize.xml → base-hvac-install-quality-all-air-to-air-heat-pump-1-speed.xml} +566 -559
  668. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-air-to-air-heat-pump-2-speed.xml +567 -0
  669. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-air-to-air-heat-pump-var-speed.xml +567 -0
  670. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-misc-shelter-coefficient.xml → base-hvac-install-quality-all-furnace-gas-central-ac-1-speed.xml} +571 -564
  671. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-furnace-gas-central-ac-2-speed.xml +572 -0
  672. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-furnace-gas-central-ac-var-speed.xml +572 -0
  673. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-furnace-gas-only-autosize.xml → base-hvac-install-quality-all-furnace-gas-only.xml} +552 -549
  674. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-ground-to-air-heat-pump.xml +566 -0
  675. 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} +552 -548
  676. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-mini-split-heat-pump-ducted-autosize.xml → base-hvac-install-quality-all-mini-split-heat-pump-ducted.xml} +565 -558
  677. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-blower-efficiency-furnace-gas-central-ac-1-speed.xml +569 -0
  678. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-charge-defect-furnace-gas-central-ac-1-speed.xml +566 -0
  679. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-none-furnace-gas-central-ac-1-speed.xml +570 -0
  680. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ducted.xml +3 -5
  681. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ductless.xml +1 -5
  682. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-cooling-only.xml +3 -5
  683. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-heating-only.xml +5 -7
  684. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted.xml +6 -8
  685. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless.xml +3 -7
  686. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple.xml +920 -913
  687. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-none.xml +0 -1
  688. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-portable-heater-gas-only.xml +512 -563
  689. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-programmable-thermostat-detailed.xml +7 -6
  690. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-programmable-thermostat.xml +4 -3
  691. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-33percent.xml +1 -2
  692. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only.xml +1 -2
  693. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints.xml +4 -3
  694. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-oil-only.xml +512 -513
  695. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-wood-pellets-only.xml +512 -513
  696. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized-allow-increased-fixed-capacities.xml +4 -3
  697. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized.xml +4 -3
  698. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-wall-furnace-elec-only.xml +512 -513
  699. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-ceiling-fans.xml +4 -3
  700. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-detailed.xml +4 -3
  701. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-none.xml +4 -3
  702. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-AMY-2012.xml +4 -3
  703. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-baltimore-md.xml +37 -25
  704. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-dallas-tx.xml +4 -3
  705. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-duluth-mn.xml +37 -25
  706. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-helena-mt.xml +563 -0
  707. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-honolulu-hi.xml +517 -0
  708. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-miami-fl.xml +4 -3
  709. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-phoenix-az.xml +517 -0
  710. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-portland-or.xml +577 -0
  711. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-balanced.xml +4 -3
  712. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-bath-kitchen-fans.xml +4 -3
  713. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-dse.xml +2 -3
  714. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-evap-cooler-only-ducted.xml +11 -1
  715. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis.xml +4 -3
  716. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv-atre-asre.xml +4 -3
  717. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv.xml +4 -3
  718. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust-rated-flow-rate.xml +4 -3
  719. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust.xml +4 -3
  720. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv-asre.xml +4 -3
  721. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv.xml +4 -3
  722. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-multiple.xml +32 -29
  723. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-supply.xml +4 -3
  724. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-whole-house-fan.xml +4 -3
  725. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-defaults.xml +4 -2
  726. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators.xml +5 -4
  727. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon.xml +8 -3
  728. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon2.xml +12 -3
  729. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-none.xml +4 -3
  730. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-neighbor-shading.xml +4 -3
  731. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-shielding-of-home.xml +564 -0
  732. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-usage-multiplier.xml +8 -3
  733. data/example_files/resources/hpxml-measures/workflow/sample_files/base-multiple-buildings.xml +1657 -0
  734. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv.xml +4 -3
  735. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-stochastic-vacant.xml +564 -0
  736. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-stochastic.xml +4 -3
  737. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-user-specified.xml +4 -3
  738. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-calendar-year-custom.xml +4 -3
  739. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-custom.xml +4 -3
  740. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-disabled.xml +4 -3
  741. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-runperiod-1-month.xml +4 -3
  742. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins.xml +4 -3
  743. data/example_files/resources/hpxml-measures/workflow/sample_files/base.xml +4 -3
  744. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/boiler-invalid-afue.xml +519 -0
  745. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/cfis-with-hydronic-distribution.xml +1 -2
  746. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/clothes-dryer-location.xml +4 -3
  747. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/clothes-washer-location.xml +4 -3
  748. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/cooking-range-location.xml +4 -3
  749. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-appliances-dehumidifier-50percent.xml → invalid_files/dehumidifier-fraction-served.xml} +534 -523
  750. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dehumidifier-setpoints.xml +535 -0
  751. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dhw-frac-load-served.xml +1 -2
  752. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dhw-invalid-ef-tank.xml +4 -3
  753. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dhw-invalid-uef-tank-heat-pump.xml +4 -3
  754. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dishwasher-location.xml +4 -3
  755. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-leakage-cfm25.xml +563 -0
  756. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-leakage-percent.xml +563 -0
  757. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-location-unconditioned-space.xml +4 -3
  758. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-location.xml +4 -3
  759. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duplicate-id.xml +4 -3
  760. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-attic-missing-roof.xml +4 -3
  761. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-basement-missing-exterior-foundation-wall.xml +5 -4
  762. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-basement-missing-slab.xml +5 -4
  763. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-floor-area-exceeds-cfa.xml +7 -6
  764. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-floor-area-exceeds-cfa2.xml +448 -0
  765. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-garage-missing-exterior-wall.xml +4 -3
  766. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-garage-missing-roof-ceiling.xml +4 -3
  767. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-garage-missing-slab.xml +4 -3
  768. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-living-missing-ceiling-roof.xml +4 -3
  769. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-living-missing-exterior-wall.xml +4 -3
  770. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-living-missing-floor-slab.xml +14 -60
  771. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-sensible-fuel-load.xml +760 -0
  772. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-sensible-plug-load.xml +759 -0
  773. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-total-fuel-load.xml +761 -0
  774. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-total-plug-load.xml +759 -0
  775. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/furnace-invalid-afue.xml +563 -0
  776. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/generator-number-of-bedrooms-served.xml +460 -0
  777. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/generator-output-greater-than-consumption.xml +579 -0
  778. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/heat-pump-mixed-fixed-and-autosize-capacities.xml +3 -5
  779. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-distribution-multiple-attached-cooling.xml +920 -913
  780. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-distribution-multiple-attached-heating.xml +920 -913
  781. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-distribution-return-duct-leakage-missing.xml +3 -7
  782. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-dse-multiple-attached-cooling.xml +3 -4
  783. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-dse-multiple-attached-heating.xml +3 -4
  784. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-frac-load-served.xml +920 -913
  785. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-inconsistent-fan-powers.xml +4 -3
  786. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-invalid-distribution-system-type.xml +4 -3
  787. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-shared-negative-seer-eq.xml +407 -0
  788. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-assembly-effective-rvalue.xml +563 -0
  789. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-datatype-boolean.xml +4 -3
  790. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-datatype-float.xml +4 -3
  791. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-datatype-integer.xml +4 -3
  792. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-daylight-saving.xml +4 -3
  793. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-distribution-cfa-served.xml +5 -4
  794. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-epw-filepath.xml +4 -3
  795. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-facility-type-equipment.xml +4 -3
  796. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-facility-type-surfaces.xml +4 -3
  797. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-foundation-wall-properties.xml +574 -0
  798. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-id.xml +591 -0
  799. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-id2.xml +591 -0
  800. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-infiltration-volume.xml +563 -0
  801. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-input-parameters.xml +4 -3
  802. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-neighbor-shading-azimuth.xml +4 -3
  803. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-number-of-bedrooms-served.xml +465 -0
  804. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-number-of-conditioned-floors.xml +563 -0
  805. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-number-of-units-served.xml +451 -0
  806. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-relatedhvac-desuperheater.xml +3 -5
  807. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-relatedhvac-dhw-indirect.xml +1 -2
  808. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-runperiod.xml +4 -3
  809. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-schema-version.xml +4 -3
  810. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-shared-vent-in-unit-flowrate.xml +473 -0
  811. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-timestep.xml +4 -3
  812. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-window-height.xml +9 -3
  813. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/lighting-fractions.xml +4 -3
  814. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/missing-duct-location.xml +916 -909
  815. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/missing-elements.xml +4 -3
  816. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-appliance.xml +4 -3
  817. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-duct.xml +4 -3
  818. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-surface.xml +15 -4
  819. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-water-heater.xml +4 -3
  820. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-buildings-without-building-id.xml +1657 -0
  821. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-buildings-wrong-building-id.xml +1657 -0
  822. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-ideal-air.xml → invalid_files/multiple-shared-cooling-systems.xml} +431 -498
  823. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-shared-heating-systems.xml +434 -0
  824. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/net-area-negative-roof.xml +5 -4
  825. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/net-area-negative-wall.xml +4 -3
  826. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/num-bedrooms-exceeds-limit.xml +4 -3
  827. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/orphaned-hvac-distribution.xml +3 -2
  828. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/refrigerator-location.xml +4 -3
  829. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/refrigerators-multiple-primary.xml +4 -3
  830. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/refrigerators-no-primary.xml +4 -3
  831. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/repeated-relatedhvac-desuperheater.xml +3 -5
  832. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/repeated-relatedhvac-dhw-indirect.xml +1 -2
  833. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-fraction-one.xml +571 -0
  834. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-thermal-system-with-combi-tankless.xml +1 -2
  835. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-thermal-system-with-desuperheater.xml +3 -5
  836. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-thermal-system-with-dhw-indirect.xml +1 -2
  837. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-cfis.xml +4 -3
  838. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-door.xml +4 -3
  839. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-hvac-distribution.xml +4 -3
  840. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-shared-clothes-washer-water-heater.xml +4 -3
  841. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-shared-dishwasher-water-heater.xml +4 -3
  842. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-skylight.xml +6 -5
  843. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-solar-thermal-system.xml +4 -3
  844. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-window.xml +4 -3
  845. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/water-heater-location-other.xml +4 -3
  846. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/water-heater-location.xml +4 -3
  847. data/example_files/resources/hpxml-measures/workflow/template.osw +5 -1
  848. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AC.xml +0 -3
  849. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AL.xml +0 -3
  850. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AC.xml +0 -3
  851. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AL.xml +0 -3
  852. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AC.xml +0 -3
  853. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AL.xml +0 -3
  854. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AC.xml +0 -3
  855. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AL.xml +0 -3
  856. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AC.xml +0 -3
  857. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AL.xml +0 -3
  858. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AC.xml +0 -3
  859. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AL.xml +0 -3
  860. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AC.xml +0 -3
  861. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AL.xml +0 -3
  862. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AC.xml +0 -3
  863. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AL.xml +0 -3
  864. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AC.xml +0 -3
  865. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AL.xml +0 -3
  866. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AC.xml +0 -3
  867. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AL.xml +0 -3
  868. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AC.xml +0 -3
  869. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AL.xml +0 -3
  870. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L302XC.xml +0 -3
  871. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L304XC.xml +0 -3
  872. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L322XC.xml +0 -3
  873. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L324XC.xml +0 -3
  874. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results.csv +294 -0
  875. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_ashrae_140.csv +27 -0
  876. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_hvac_sizing.csv +294 -0
  877. data/example_files/resources/hpxml-measures/workflow/tests/compare.rb +130 -0
  878. data/example_files/resources/hpxml-measures/workflow/tests/hpxml_translator_test.rb +324 -382
  879. data/example_files/{measures/BuildResidentialModel/resources → resources}/measure-info.json +0 -0
  880. data/example_files/{measures/BuildResidentialModel/resources → resources}/meta_measure.rb +53 -44
  881. data/example_files/visualization/input_visualization_feature.html +13 -14
  882. data/example_files/visualization/input_visualization_scenario.html +14 -9
  883. data/lib/uo_cli.rb +293 -60
  884. data/lib/uo_cli/version.rb +17 -7
  885. data/requirements.txt +2 -0
  886. data/scripts/setup-env-gitbash.sh +4 -4
  887. data/scripts/setup-env-unix.sh +4 -4
  888. data/scripts/setup-env.bat +3 -3
  889. data/scripts/setup-env.ps1 +3 -3
  890. data/uo_cli.gemspec +10 -7
  891. metadata +320 -82
  892. data/example_files/measures/ResidentialGeometryCreateMultifamily/measure.rb +0 -1005
  893. data/example_files/measures/ResidentialGeometryCreateMultifamily/measure.xml +0 -326
  894. data/example_files/measures/ResidentialGeometryCreateMultifamily/tests/create_residential_multifamily_geometry_test.rb +0 -477
  895. data/example_files/measures/ResidentialGeometryCreateSingleFamilyAttached/measure.rb +0 -1039
  896. data/example_files/measures/ResidentialGeometryCreateSingleFamilyAttached/measure.xml +0 -393
  897. data/example_files/measures/ResidentialGeometryCreateSingleFamilyAttached/tests/create_residential_single_family_attached_geometry_test.rb +0 -456
  898. data/example_files/measures/ResidentialGeometryCreateSingleFamilyDetached/measure.rb +0 -979
  899. data/example_files/measures/ResidentialGeometryCreateSingleFamilyDetached/measure.xml +0 -388
  900. data/example_files/measures/ResidentialGeometryCreateSingleFamilyDetached/tests/create_residential_single_family_detached_geometry_test.rb +0 -704
  901. data/example_files/resources/hpxml-measures/.circleci/config.yml +0 -20
  902. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/location.rb +0 -24
  903. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_config.yml +0 -74
  904. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-hvac-programmable-thermostat.osw +0 -369
  905. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_constructions.rb +0 -109
  906. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple2.xml +0 -835
  907. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/heat-pump-mixed-fixed-and-autosize-capacities2.xml +0 -563
@@ -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
@@ -2,11 +2,10 @@
2
2
 
3
3
  source 'http://rubygems.org'
4
4
 
5
+ gem 'nokogiri', '~> 1.10'
5
6
  gem 'oga'
7
+ gem 'schematron-nokogiri'
6
8
  gem 'rake'
7
9
  gem 'minitest', '~> 5.9'
8
- gem 'ci_reporter_minitest', '~> 1.0.0'
9
- gem 'simplecov'
10
- gem 'codecov'
11
10
  gem 'minitest-reporters'
12
- gem 'minitest-ci' # For CircleCI Automatic test metadata collection
11
+ gem 'parallel'
@@ -1,54 +1,49 @@
1
- GIT
2
- remote: http://github.com/shorowit/schematron.git
3
- revision: 2e26890fa1fc918198270f94abc7caf659d18bb2
4
- branch: return_context_path
5
- specs:
6
- schematron-nokogiri (0.0.2)
7
- nokogiri (~> 1.6)
8
-
9
1
  GEM
10
2
  remote: http://rubygems.org/
11
3
  specs:
12
4
  ansi (1.5.0)
13
- ast (2.4.1)
5
+ ast (2.4.2)
14
6
  builder (3.2.4)
15
7
  ci_reporter (2.0.0)
16
8
  builder (>= 2.1.2)
17
9
  ci_reporter_minitest (1.0.0)
18
10
  ci_reporter (~> 2.0)
19
11
  minitest (~> 5.0)
20
- codecov (0.2.0)
21
- colorize
12
+ codecov (0.2.12)
22
13
  json
23
14
  simplecov
24
- colorize (0.8.1)
25
- docile (1.3.2)
26
- json (2.3.1)
27
- mini_portile2 (2.4.0)
28
- minitest (5.14.1)
29
- minitest-ci (3.4.0)
30
- minitest (>= 5.0.6)
31
- minitest-reporters (1.4.2)
15
+ docile (1.3.5)
16
+ json (2.5.1)
17
+ mini_portile2 (2.5.0)
18
+ minitest (5.14.4)
19
+ minitest-reporters (1.4.3)
32
20
  ansi
33
21
  builder
34
22
  minitest (>= 5.0)
35
23
  ruby-progressbar
36
- nokogiri (1.10.10)
37
- mini_portile2 (~> 2.4.0)
38
- nokogiri (1.10.10-x64-mingw32)
39
- mini_portile2 (~> 2.4.0)
40
- oga (3.2)
24
+ nokogiri (1.11.2)
25
+ mini_portile2 (~> 2.5.0)
26
+ racc (~> 1.4)
27
+ nokogiri (1.11.2-x64-mingw32)
28
+ racc (~> 1.4)
29
+ oga (3.3)
41
30
  ast
42
31
  ruby-ll (~> 2.1)
43
- rake (13.0.1)
32
+ parallel (1.20.1)
33
+ racc (1.5.2)
34
+ rake (13.0.3)
44
35
  ruby-ll (2.1.2)
45
36
  ansi
46
37
  ast
47
- ruby-progressbar (1.10.1)
48
- simplecov (0.18.5)
38
+ ruby-progressbar (1.11.0)
39
+ schematron-nokogiri (0.0.3)
40
+ nokogiri (~> 1.6)
41
+ simplecov (0.21.2)
49
42
  docile (~> 1.1)
50
43
  simplecov-html (~> 0.11)
51
- simplecov-html (0.12.2)
44
+ simplecov_json_formatter (~> 0.1)
45
+ simplecov-html (0.12.3)
46
+ simplecov_json_formatter (0.1.2)
52
47
 
53
48
  PLATFORMS
54
49
  ruby
@@ -56,15 +51,15 @@ PLATFORMS
56
51
 
57
52
  DEPENDENCIES
58
53
  ci_reporter_minitest (~> 1.0.0)
59
- codecov
54
+ codecov (= 0.2.12)
60
55
  minitest (~> 5.9)
61
- minitest-ci
62
56
  minitest-reporters
63
57
  nokogiri (~> 1.10)
64
58
  oga
59
+ parallel
65
60
  rake
66
- schematron-nokogiri!
61
+ schematron-nokogiri
67
62
  simplecov
68
63
 
69
64
  BUNDLED WITH
70
- 2.1.4
65
+ 2.2.11
@@ -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, 3) Generates additional log output, and 4) Creates all EnergyPlus output files. 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,19 +120,24 @@ 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
- stron_paths = [File.join(File.dirname(__FILE__), 'resources', 'HPXMLvalidator.xml'),
114
- File.join(File.dirname(__FILE__), 'resources', 'EPvalidator.xml')]
115
- hpxml = HPXML.new(hpxml_path: hpxml_path, schematron_validators: stron_paths)
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)
116
141
  hpxml.errors.each do |error|
117
142
  runner.registerError(error)
118
143
  end
@@ -121,9 +146,15 @@ class HPXMLtoOpenStudio < OpenStudio::Measure::ModelMeasure
121
146
  end
122
147
  return false unless hpxml.errors.empty?
123
148
 
124
- 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)
125
150
 
126
- 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)
127
158
  rescue Exception => e
128
159
  runner.registerError("#{e.message}\n#{e.backtrace.join("\n")}")
129
160
  return false
@@ -132,20 +163,7 @@ class HPXMLtoOpenStudio < OpenStudio::Measure::ModelMeasure
132
163
  return true
133
164
  end
134
165
 
135
- def tear_down_model(model, runner)
136
- # Tear down the existing model if it exists
137
- has_existing_objects = (model.getThermalZones.size > 0)
138
- handles = OpenStudio::UUIDVector.new
139
- model.objects.each do |obj|
140
- handles << obj.handle
141
- end
142
- model.removeObjects(handles)
143
- if has_existing_objects
144
- runner.registerWarning('The model contains existing objects and is being reset.')
145
- end
146
- end
147
-
148
- def process_weather(hpxml, runner, model, output_dir, hpxml_path)
166
+ def process_weather(hpxml, runner, model, hpxml_path)
149
167
  epw_path = hpxml.climate_and_risk_zones.weather_station_epw_filepath
150
168
 
151
169
  if not File.exist? epw_path
@@ -185,7 +203,8 @@ class HPXMLtoOpenStudio < OpenStudio::Measure::ModelMeasure
185
203
  end
186
204
 
187
205
  class OSModel
188
- 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)
189
208
  @hpxml = hpxml
190
209
  @debug = debug
191
210
 
@@ -199,14 +218,13 @@ class OSModel
199
218
  # Init
200
219
 
201
220
  weather, epw_file = Location.apply_weather_file(model, runner, epw_path, cache_path)
202
- check_for_errors()
203
- set_defaults_and_globals(runner, output_dir, epw_file)
221
+ set_defaults_and_globals(runner, output_dir, epw_file, weather)
204
222
  Location.apply(model, runner, weather, epw_file, @hpxml)
205
223
  add_simulation_params(model)
206
224
 
207
225
  @schedules_file = nil
208
- if not @hpxml.header.schedules_path.nil?
209
- @schedules_file = SchedulesFile.new(runner: runner, model: model, schedules_path: @hpxml.header.schedules_path, col_names: ScheduleGenerator.col_names)
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)
210
228
  end
211
229
 
212
230
  # Conditioned space/zone
@@ -222,25 +240,24 @@ class OSModel
222
240
  add_rim_joists(runner, model, spaces)
223
241
  add_frame_floors(runner, model, spaces)
224
242
  add_foundation_walls_slabs(runner, model, spaces)
225
- add_interior_shading_schedule(runner, model, weather)
243
+ add_shading_schedule(runner, model, weather)
226
244
  add_windows(runner, model, spaces, weather)
227
245
  add_doors(runner, model, spaces)
228
246
  add_skylights(runner, model, spaces, weather)
229
247
  add_conditioned_floor_area(runner, model, spaces)
230
248
  add_thermal_mass(runner, model, spaces)
231
249
  update_conditioned_basement(runner, model, spaces)
232
- set_zone_volumes(runner, model, spaces)
233
- 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)
234
252
  add_num_occupants(model, runner, spaces)
235
253
 
236
254
  # HVAC
237
255
 
238
- update_shared_hvac_systems()
239
256
  add_ideal_system(runner, model, spaces, epw_path)
240
257
  add_cooling_system(runner, model, spaces)
241
258
  add_heating_system(runner, model, spaces)
242
259
  add_heat_pump(runner, model, weather, spaces)
243
- add_dehumidifier(runner, model, spaces)
260
+ add_dehumidifiers(runner, model, spaces)
244
261
  add_residual_ideal_system(runner, model, spaces)
245
262
  add_ceiling_fans(runner, model, weather, spaces)
246
263
 
@@ -260,22 +277,23 @@ class OSModel
260
277
  # Other
261
278
 
262
279
  add_airflow(runner, model, weather, spaces)
263
- add_hvac_sizing(runner, model, weather, spaces)
264
280
  add_photovoltaics(runner, model)
265
281
  add_generators(runner, model)
266
- add_additional_properties(runner, model, hpxml_path)
282
+ add_additional_properties(runner, model, hpxml_path, building_id)
267
283
 
268
284
  # Output
269
285
 
270
- add_component_loads_output(runner, model, spaces)
286
+ add_loads_output(runner, model, spaces, add_component_loads)
271
287
  add_output_control_files(runner, model)
272
288
  # Uncomment to debug EMS
273
289
  # add_ems_debug_output(runner, model)
274
290
 
275
291
  # Vacancy
276
- set_vacancy(runner, model)
292
+ unless @schedules_file.nil?
293
+ @schedules_file.set_vacancy
294
+ end
277
295
 
278
- if debug && (not output_dir.nil?)
296
+ if debug
279
297
  osm_output_path = File.join(output_dir, 'in.osm')
280
298
  File.write(osm_output_path, model.to_s)
281
299
  runner.registerInfo("Wrote file: #{osm_output_path}")
@@ -284,80 +302,7 @@ class OSModel
284
302
 
285
303
  private
286
304
 
287
- def self.check_for_errors()
288
- # Conditioned space
289
- location = HPXML::LocationLivingSpace
290
- if (@hpxml.roofs.select { |s| s.interior_adjacent_to == location }.size +
291
- @hpxml.frame_floors.select { |s| s.is_ceiling && (s.interior_adjacent_to == location) }.size) == 0
292
- fail 'There must be at least one ceiling/roof adjacent to conditioned space.'
293
- end
294
- if @hpxml.walls.select { |s| (s.interior_adjacent_to == location) && s.is_exterior }.size == 0
295
- fail 'There must be at least one exterior wall adjacent to conditioned space.'
296
- end
297
- if (@hpxml.slabs.select { |s| [location, HPXML::LocationBasementConditioned].include? s.interior_adjacent_to }.size +
298
- @hpxml.frame_floors.select { |s| s.is_floor && (s.interior_adjacent_to == location) }.size) == 0
299
- fail 'There must be at least one floor/slab adjacent to conditioned space.'
300
- end
301
-
302
- # Basement/Crawlspace
303
- [HPXML::LocationBasementConditioned,
304
- HPXML::LocationBasementUnconditioned,
305
- HPXML::LocationCrawlspaceVented,
306
- HPXML::LocationCrawlspaceUnvented].each do |location|
307
- next unless @hpxml.has_space_type(location)
308
-
309
- if location != HPXML::LocationBasementConditioned # HPXML file doesn't need to have FrameFloor between living and conditioned basement
310
- if @hpxml.frame_floors.select { |s| s.is_floor && (s.interior_adjacent_to == HPXML::LocationLivingSpace) && (s.exterior_adjacent_to == location) }.size == 0
311
- fail "There must be at least one ceiling adjacent to #{location}."
312
- end
313
- end
314
- if @hpxml.foundation_walls.select { |s| (s.interior_adjacent_to == location) && s.is_exterior }.size == 0
315
- fail "There must be at least one exterior foundation wall adjacent to #{location}."
316
- end
317
- if @hpxml.slabs.select { |s| s.interior_adjacent_to == location }.size == 0
318
- fail "There must be at least one slab adjacent to #{location}."
319
- end
320
- end
321
-
322
- # Garage
323
- location = HPXML::LocationGarage
324
- if @hpxml.has_space_type(location)
325
- if (@hpxml.roofs.select { |s| s.interior_adjacent_to == location }.size +
326
- @hpxml.frame_floors.select { |s| [s.interior_adjacent_to, s.exterior_adjacent_to].include? location }.size) == 0
327
- fail "There must be at least one roof/ceiling adjacent to #{location}."
328
- end
329
- if (@hpxml.walls.select { |s| (s.interior_adjacent_to == location) && s.is_exterior }.size +
330
- @hpxml.foundation_walls.select { |s| [s.interior_adjacent_to, s.exterior_adjacent_to].include?(location) && s.is_exterior }.size) == 0
331
- fail "There must be at least one exterior wall/foundation wall adjacent to #{location}."
332
- end
333
- if @hpxml.slabs.select { |s| s.interior_adjacent_to == location }.size == 0
334
- fail "There must be at least one slab adjacent to #{location}."
335
- end
336
- end
337
-
338
- # Attic
339
- [HPXML::LocationAtticVented,
340
- HPXML::LocationAtticUnvented].each do |location|
341
- next unless @hpxml.has_space_type(location)
342
-
343
- if @hpxml.roofs.select { |s| s.interior_adjacent_to == location }.size == 0
344
- fail "There must be at least one roof adjacent to #{location}."
345
- end
346
-
347
- if @hpxml.frame_floors.select { |s| s.is_ceiling && [s.interior_adjacent_to, s.exterior_adjacent_to].include?(location) }.size == 0
348
- fail "There must be at least one floor adjacent to #{location}."
349
- end
350
- end
351
-
352
- # Error-checking from RESNET Pub 002: Number of bedrooms
353
- nbeds = @hpxml.building_construction.number_of_bedrooms
354
- nbeds_limit = (@hpxml.building_construction.conditioned_floor_area - 120.0) / 70.0
355
- if nbeds > nbeds_limit
356
- fail "Number of bedrooms (#{nbeds}) exceeds limit of (CFA-120)/70=#{nbeds_limit.round(1)}."
357
- end
358
- end
359
-
360
- def self.set_defaults_and_globals(runner, output_dir, epw_file)
305
+ def self.set_defaults_and_globals(runner, output_dir, epw_file, weather)
361
306
  # Initialize
362
307
  @remaining_heat_load_frac = 1.0
363
308
  @remaining_cool_load_frac = 1.0
@@ -370,212 +315,40 @@ class OSModel
370
315
  @ncfl = @hpxml.building_construction.number_of_conditioned_floors
371
316
  @ncfl_ag = @hpxml.building_construction.number_of_conditioned_floors_above_grade
372
317
  @nbeds = @hpxml.building_construction.number_of_bedrooms
373
- @min_neighbor_distance = get_min_neighbor_distance()
374
318
  @default_azimuths = get_default_azimuths()
375
- @has_uncond_bsmnt = @hpxml.has_space_type(HPXML::LocationBasementUnconditioned)
376
-
377
- if @hpxml.building_construction.use_only_ideal_air_system.nil?
378
- @hpxml.building_construction.use_only_ideal_air_system = false
379
- end
380
319
 
381
320
  # Apply defaults to HPXML object
382
- 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)
383
322
 
384
323
  @frac_windows_operable = @hpxml.fraction_of_windows_operable()
385
324
 
386
- if @debug && (not output_dir.nil?)
387
- # Write updated HPXML object to file
388
- hpxml_defaults_path = File.join(output_dir, 'in.xml')
389
- XMLHelper.write_file(@hpxml.to_oga, hpxml_defaults_path)
390
- runner.registerInfo("Wrote file: #{hpxml_defaults_path}")
391
- end
392
- 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)
393
328
 
394
- def self.add_simulation_params(model)
395
- 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)
396
332
  end
397
333
 
398
- def self.set_zone_volumes(runner, model, spaces)
399
- # Living space
400
- spaces[HPXML::LocationLivingSpace].thermalZone.get.setVolume(UnitConversions.convert(@hpxml.building_construction.conditioned_building_volume, 'ft^3', 'm^3'))
401
-
402
- # Basement, crawlspace, garage
403
- spaces.keys.each do |space_type|
404
- next unless [HPXML::LocationBasementUnconditioned, HPXML::LocationCrawlspaceUnvented, HPXML::LocationCrawlspaceVented, HPXML::LocationGarage].include? space_type
405
-
406
- floor_area = @hpxml.slabs.select { |s| s.interior_adjacent_to == space_type }.map { |s| s.area }.sum(0.0)
407
- if space_type == HPXML::LocationGarage
408
- height = 8.0
409
- else
410
- height = @hpxml.foundation_walls.select { |w| w.interior_adjacent_to == space_type }.map { |w| w.height }.max
411
- end
412
-
413
- spaces[space_type].thermalZone.get.setVolume(UnitConversions.convert(floor_area * height, 'ft^3', 'm^3'))
414
- end
415
-
416
- # Attic
417
- spaces.keys.each do |space_type|
418
- next unless [HPXML::LocationAtticUnvented, HPXML::LocationAtticVented].include? space_type
419
-
420
- 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)
421
- roofs = @hpxml.roofs.select { |r| r.interior_adjacent_to == space_type }
422
- avg_pitch = roofs.map { |r| r.pitch }.sum(0.0) / roofs.size
423
-
424
- if @apply_ashrae140_assumptions
425
- # Hardcode the attic volume to match ASHRAE 140 Table 7-2 specification
426
- volume = 3463
427
- else
428
- # Assume square hip roof for volume calculations; energy results are very insensitive to actual volume
429
- length = floor_area**0.5
430
- height = 0.5 * Math.sin(Math.atan(avg_pitch / 12.0)) * length
431
- volume = [floor_area * height / 3.0, 0.01].max
432
- end
433
-
434
- spaces[space_type].thermalZone.get.setVolume(UnitConversions.convert(volume, 'ft^3', 'm^3'))
435
- end
334
+ def self.add_simulation_params(model)
335
+ SimControls.apply(model, @hpxml)
436
336
  end
437
337
 
438
- def self.explode_surfaces(runner, model)
439
- # Re-position surfaces so as to not shade each other and to make it easier to visualize the building.
440
- # FUTURE: Might be able to use the new self-shading options in E+ 8.9 ShadowCalculation object instead?
441
-
442
- gap_distance = UnitConversions.convert(10.0, 'ft', 'm') # distance between surfaces of the same azimuth
443
- rad90 = UnitConversions.convert(90, 'deg', 'rad')
444
-
445
- # Determine surfaces to shift and distance with which to explode surfaces horizontally outward
446
- surfaces = []
447
- azimuth_lengths = {}
448
- model.getSurfaces.sort.each do |surface|
449
- next unless ['wall', 'roofceiling'].include? surface.surfaceType.downcase
450
- next unless ['outdoors', 'foundation', 'adiabatic'].include? surface.outsideBoundaryCondition.downcase
451
- next if surface.additionalProperties.getFeatureAsDouble('Tilt').get <= 0 # skip flat roofs
452
-
453
- surfaces << surface
454
- azimuth = surface.additionalProperties.getFeatureAsInteger('Azimuth').get
455
- if azimuth_lengths[azimuth].nil?
456
- azimuth_lengths[azimuth] = 0.0
457
- end
458
- azimuth_lengths[azimuth] += surface.additionalProperties.getFeatureAsDouble('Length').get + gap_distance
459
- end
460
- max_azimuth_length = azimuth_lengths.values.max
461
-
462
- # Using the max length for a given azimuth, calculate the apothem (radius of the incircle) of a regular
463
- # n-sided polygon to create the smallest polygon possible without self-shading. The number of polygon
464
- # sides is defined by the minimum difference between two azimuths.
465
- min_azimuth_diff = 360
466
- azimuths_sorted = azimuth_lengths.keys.sort
467
- azimuths_sorted.each_with_index do |az, idx|
468
- diff1 = (az - azimuths_sorted[(idx + 1) % azimuths_sorted.size]).abs
469
- diff2 = 360.0 - diff1 # opposite direction
470
- if diff1 < min_azimuth_diff
471
- min_azimuth_diff = diff1
472
- end
473
- if diff2 < min_azimuth_diff
474
- min_azimuth_diff = diff2
475
- end
476
- end
477
- if min_azimuth_diff > 0
478
- nsides = [(360.0 / min_azimuth_diff).ceil, 4].max # assume rectangle at the minimum
479
- else
480
- nsides = 4
481
- end
482
- explode_distance = max_azimuth_length / (2.0 * Math.tan(UnitConversions.convert(180.0 / nsides, 'deg', 'rad')))
483
-
484
- add_neighbors(runner, model, max_azimuth_length)
485
-
486
- # Initial distance of shifts at 90-degrees to horizontal outward
487
- azimuth_side_shifts = {}
488
- azimuth_lengths.keys.each do |azimuth|
489
- azimuth_side_shifts[azimuth] = max_azimuth_length / 2.0
490
- end
491
-
492
- # Explode neighbors
493
- model.getShadingSurfaceGroups.each do |shading_surface_group|
494
- next if shading_surface_group.name.to_s != Constants.ObjectNameNeighbors
495
-
496
- shading_surface_group.shadingSurfaces.each do |shading_surface|
497
- azimuth = shading_surface.additionalProperties.getFeatureAsInteger('Azimuth').get
498
- azimuth_rad = UnitConversions.convert(azimuth, 'deg', 'rad')
499
- distance = shading_surface.additionalProperties.getFeatureAsDouble('Distance').get
500
-
501
- unless azimuth_lengths.keys.include? azimuth
502
- fail "A neighbor building has an azimuth (#{azimuth}) not equal to the azimuth of any wall."
503
- end
504
-
505
- # Push out horizontally
506
- distance += explode_distance
507
- transformation = get_surface_transformation(distance, Math::sin(azimuth_rad), Math::cos(azimuth_rad), 0)
508
-
509
- shading_surface.setVertices(transformation * shading_surface.vertices)
510
- end
511
- end
512
-
513
- # Explode walls, windows, doors, roofs, and skylights
514
- surfaces_moved = []
515
-
516
- surfaces.sort.each do |surface|
517
- next if surface.additionalProperties.getFeatureAsDouble('Tilt').get <= 0 # skip flat roofs
518
-
519
- if surface.adjacentSurface.is_initialized
520
- next if surfaces_moved.include? surface.adjacentSurface.get
521
- end
522
-
523
- azimuth = surface.additionalProperties.getFeatureAsInteger('Azimuth').get
524
- azimuth_rad = UnitConversions.convert(azimuth, 'deg', 'rad')
525
-
526
- # Push out horizontally
527
- distance = explode_distance
528
-
529
- if surface.surfaceType.downcase == 'roofceiling'
530
- # Ensure pitched surfaces are positioned outward justified with walls, etc.
531
- tilt = surface.additionalProperties.getFeatureAsDouble('Tilt').get
532
- width = surface.additionalProperties.getFeatureAsDouble('Width').get
533
- distance -= 0.5 * Math.cos(Math.atan(tilt)) * width
534
- end
535
- transformation = get_surface_transformation(distance, Math::sin(azimuth_rad), Math::cos(azimuth_rad), 0)
536
-
537
- surface.setVertices(transformation * surface.vertices)
538
- if surface.adjacentSurface.is_initialized
539
- surface.adjacentSurface.get.setVertices(transformation * surface.adjacentSurface.get.vertices)
540
- end
541
- surface.subSurfaces.each do |subsurface|
542
- subsurface.setVertices(transformation * subsurface.vertices)
543
- next unless subsurface.subSurfaceType.downcase == 'fixedwindow'
544
-
545
- subsurface.shadingSurfaceGroups.each do |overhang_group|
546
- overhang_group.shadingSurfaces.each do |overhang|
547
- overhang.setVertices(transformation * overhang.vertices)
548
- end
549
- end
550
- end
551
-
552
- # Shift at 90-degrees to previous transformation
553
- azimuth_side_shifts[azimuth] -= surface.additionalProperties.getFeatureAsDouble('Length').get / 2.0
554
- 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?
555
340
 
556
- surface.setVertices(transformation_shift * surface.vertices)
557
- if surface.adjacentSurface.is_initialized
558
- surface.adjacentSurface.get.setVertices(transformation_shift * surface.adjacentSurface.get.vertices)
559
- end
560
- surface.subSurfaces.each do |subsurface|
561
- subsurface.setVertices(transformation_shift * subsurface.vertices)
562
- 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?
563
346
 
564
- subsurface.shadingSurfaceGroups.each do |overhang_group|
565
- overhang_group.shadingSurfaces.each do |overhang|
566
- overhang.setVertices(transformation_shift * overhang.vertices)
567
- end
568
- end
347
+ cond_bsmnt_surface.subSurfaces.each do |ss|
348
+ new_cond_bsmnt_surfaces << ss
569
349
  end
570
-
571
- azimuth_side_shifts[azimuth] -= (surface.additionalProperties.getFeatureAsDouble('Length').get / 2.0 + gap_distance)
572
-
573
- surfaces_moved << surface
574
350
  end
575
- end
576
-
577
- def self.update_conditioned_basement(runner, model, spaces)
578
- return if @cond_bsmnt_surfaces.empty?
351
+ @cond_bsmnt_surfaces = new_cond_bsmnt_surfaces.dup
579
352
 
580
353
  update_solar_absorptances(runner, model)
581
354
  assign_view_factors(runner, model, spaces)
@@ -584,7 +357,19 @@ class OSModel
584
357
  def self.update_solar_absorptances(runner, model)
585
358
  # modify conditioned basement surface properties
586
359
  # zero out interior solar absorptance in conditioned basement
360
+
587
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
588
373
  const = cond_bsmnt_surface.construction.get
589
374
  layered_const = const.to_LayeredConstruction.get
590
375
  innermost_material = layered_const.layers[layered_const.numLayers() - 1].to_StandardOpaqueMaterial.get
@@ -614,6 +399,13 @@ class OSModel
614
399
  innermost_material = layered_const.layers[layered_const.numLayers() - 1].to_StandardOpaqueMaterial.get
615
400
  innermost_material.setSolarAbsorptance(0.0)
616
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())
617
409
  end
618
410
  end
619
411
 
@@ -635,8 +427,7 @@ class OSModel
635
427
 
636
428
  all_surfaces.each do |surface|
637
429
  if @cond_bsmnt_surfaces.include?(surface) ||
638
- ((@cond_bsmnt_surfaces.include? surface.internalMassDefinition) if surface.is_a? OpenStudio::Model::InternalMass) ||
639
- ((@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)
640
431
  cond_base_surfaces << surface
641
432
  else
642
433
  lv_surfaces << surface
@@ -751,173 +542,26 @@ class OSModel
751
542
  return vf_map
752
543
  end
753
544
 
754
- # FUTURE: Move this method and many below to geometry.rb
755
- def self.create_space_and_zone(model, spaces, space_type)
756
- if not spaces.keys.include? space_type
757
- thermal_zone = OpenStudio::Model::ThermalZone.new(model)
758
- thermal_zone.setName(space_type)
759
-
760
- space = OpenStudio::Model::Space.new(model)
761
- space.setName(space_type)
762
-
763
- st = OpenStudio::Model::SpaceType.new(model)
764
- st.setStandardsSpaceType(space_type)
765
- space.setSpaceType(st)
766
-
767
- space.setThermalZone(thermal_zone)
768
- spaces[space_type] = space
769
- end
770
- end
771
-
772
- def self.get_surface_transformation(offset, x, y, z)
773
- x = UnitConversions.convert(x, 'ft', 'm')
774
- y = UnitConversions.convert(y, 'ft', 'm')
775
- z = UnitConversions.convert(z, 'ft', 'm')
776
-
777
- m = OpenStudio::Matrix.new(4, 4, 0)
778
- m[0, 0] = 1
779
- m[1, 1] = 1
780
- m[2, 2] = 1
781
- m[3, 3] = 1
782
- m[0, 3] = x * offset
783
- m[1, 3] = y * offset
784
- m[2, 3] = z.abs * offset
785
-
786
- return OpenStudio::Transformation.new(m)
787
- end
788
-
789
- def self.add_floor_polygon(x, y, z)
790
- x = UnitConversions.convert(x, 'ft', 'm')
791
- y = UnitConversions.convert(y, 'ft', 'm')
792
- z = UnitConversions.convert(z, 'ft', 'm')
793
-
794
- vertices = OpenStudio::Point3dVector.new
795
- vertices << OpenStudio::Point3d.new(0 - x / 2, 0 - y / 2, z)
796
- vertices << OpenStudio::Point3d.new(0 - x / 2, y / 2, z)
797
- vertices << OpenStudio::Point3d.new(x / 2, y / 2, z)
798
- vertices << OpenStudio::Point3d.new(x / 2, 0 - y / 2, z)
799
-
800
- # Rotate about the z axis
801
- # This is not strictly needed, but will make the floor edges
802
- # parallel to the walls for a better geometry rendering.
803
- azimuth_rad = UnitConversions.convert(@default_azimuths[0], 'deg', 'rad')
804
- m = OpenStudio::Matrix.new(4, 4, 0)
805
- m[0, 0] = Math::cos(-azimuth_rad)
806
- m[1, 1] = Math::cos(-azimuth_rad)
807
- m[0, 1] = -Math::sin(-azimuth_rad)
808
- m[1, 0] = Math::sin(-azimuth_rad)
809
- m[2, 2] = 1
810
- m[3, 3] = 1
811
- transformation = OpenStudio::Transformation.new(m)
812
-
813
- return transformation * vertices
814
- end
815
-
816
- def self.add_wall_polygon(x, y, z, azimuth, offsets = [0] * 4, subsurface_area = 0)
817
- x = UnitConversions.convert(x, 'ft', 'm')
818
- y = UnitConversions.convert(y, 'ft', 'm')
819
- z = UnitConversions.convert(z, 'ft', 'm')
820
-
821
- vertices = OpenStudio::Point3dVector.new
822
- vertices << OpenStudio::Point3d.new(0 - (x / 2) - offsets[1], 0, z - offsets[0])
823
- vertices << OpenStudio::Point3d.new(0 - (x / 2) - offsets[1], 0, z + y + offsets[2])
824
- if subsurface_area > 0
825
- subsurface_area = UnitConversions.convert(subsurface_area, 'ft^2', 'm^2')
826
- sub_length = x / 10.0
827
- sub_height = subsurface_area / sub_length
828
- if sub_height >= y
829
- sub_height = y - 0.1
830
- sub_length = subsurface_area / sub_height
831
- end
832
- vertices << OpenStudio::Point3d.new(x - (x / 2) + offsets[3] - sub_length, 0, z + y + offsets[2])
833
- vertices << OpenStudio::Point3d.new(x - (x / 2) + offsets[3] - sub_length, 0, z + y + offsets[2] - sub_height)
834
- vertices << OpenStudio::Point3d.new(x - (x / 2) + offsets[3], 0, z + y + offsets[2] - sub_height)
835
- else
836
- vertices << OpenStudio::Point3d.new(x - (x / 2) + offsets[3], 0, z + y + offsets[2])
837
- end
838
- vertices << OpenStudio::Point3d.new(x - (x / 2) + offsets[3], 0, z - offsets[0])
839
-
840
- # Rotate about the z axis
841
- azimuth_rad = UnitConversions.convert(azimuth, 'deg', 'rad')
842
- m = OpenStudio::Matrix.new(4, 4, 0)
843
- m[0, 0] = Math::cos(-azimuth_rad)
844
- m[1, 1] = Math::cos(-azimuth_rad)
845
- m[0, 1] = -Math::sin(-azimuth_rad)
846
- m[1, 0] = Math::sin(-azimuth_rad)
847
- m[2, 2] = 1
848
- m[3, 3] = 1
849
- transformation = OpenStudio::Transformation.new(m)
850
-
851
- return transformation * vertices
852
- end
853
-
854
- def self.add_roof_polygon(x, y, z, azimuth, tilt)
855
- x = UnitConversions.convert(x, 'ft', 'm')
856
- y = UnitConversions.convert(y, 'ft', 'm')
857
- z = UnitConversions.convert(z, 'ft', 'm')
858
-
859
- vertices = OpenStudio::Point3dVector.new
860
- vertices << OpenStudio::Point3d.new(x / 2, -y / 2, 0)
861
- vertices << OpenStudio::Point3d.new(x / 2, y / 2, 0)
862
- vertices << OpenStudio::Point3d.new(-x / 2, y / 2, 0)
863
- vertices << OpenStudio::Point3d.new(-x / 2, -y / 2, 0)
864
-
865
- # Rotate about the x axis
866
- m = OpenStudio::Matrix.new(4, 4, 0)
867
- m[0, 0] = 1
868
- m[1, 1] = Math::cos(Math::atan(tilt))
869
- m[1, 2] = -Math::sin(Math::atan(tilt))
870
- m[2, 1] = Math::sin(Math::atan(tilt))
871
- m[2, 2] = Math::cos(Math::atan(tilt))
872
- m[3, 3] = 1
873
- transformation = OpenStudio::Transformation.new(m)
874
- vertices = transformation * vertices
875
-
876
- # Rotate about the z axis
877
- azimuth_rad = UnitConversions.convert(azimuth, 'deg', 'rad')
878
- rad180 = UnitConversions.convert(180, 'deg', 'rad')
879
- m = OpenStudio::Matrix.new(4, 4, 0)
880
- m[0, 0] = Math::cos(rad180 - azimuth_rad)
881
- m[1, 1] = Math::cos(rad180 - azimuth_rad)
882
- m[0, 1] = -Math::sin(rad180 - azimuth_rad)
883
- m[1, 0] = Math::sin(rad180 - azimuth_rad)
884
- m[2, 2] = 1
885
- m[3, 3] = 1
886
- transformation = OpenStudio::Transformation.new(m)
887
- vertices = transformation * vertices
888
-
889
- # Shift up by z
890
- new_vertices = OpenStudio::Point3dVector.new
891
- vertices.each do |vertex|
892
- new_vertices << OpenStudio::Point3d.new(vertex.x, vertex.y, vertex.z + z)
893
- end
894
-
895
- return new_vertices
896
- end
897
-
898
- def self.add_ceiling_polygon(x, y, z)
899
- return OpenStudio::reverse(add_floor_polygon(x, y, z))
900
- end
901
-
902
545
  def self.add_num_occupants(model, runner, spaces)
903
546
  # Occupants
904
547
  num_occ = @hpxml.building_occupancy.number_of_residents
905
- if num_occ > 0
906
- occ_gain, hrs_per_day, sens_frac, lat_frac = Geometry.get_occupancy_default_values()
907
- weekday_sch = Schedule.OccupantsWeekdayFractions
908
- weekday_sch_sum = weekday_sch.split(',').map(&:to_f).sum(0.0)
909
- if (weekday_sch_sum - hrs_per_day).abs > 0.1
910
- fail 'Occupancy schedule inconsistent with hrs_per_day.'
911
- end
548
+ return if num_occ <= 0
912
549
 
913
- weekend_sch = Schedule.OccupantsWeekendFractions
914
- monthly_sch = Schedule.OccupantsMonthlyMultipliers
915
-
916
- 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)
917
- end
550
+ Geometry.apply_occupants(model, num_occ, @cfa, spaces[HPXML::LocationLivingSpace], @schedules_file)
918
551
  end
919
552
 
920
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
+
921
565
  # Returns a list of four azimuths (facing each direction). Determined based
922
566
  # on the primary azimuth, as defined by the azimuth with the largest surface
923
567
  # area, plus azimuths that are offset by 90/180/270 degrees. Used for
@@ -942,20 +586,9 @@ class OSModel
942
586
  sanitize_azimuth(primary_azimuth + 270)].sort
943
587
  end
944
588
 
945
- def self.sanitize_azimuth(azimuth)
946
- # Ensure 0 <= orientation < 360
947
- while azimuth < 0
948
- azimuth += 360
949
- end
950
- while azimuth >= 360
951
- azimuth -= 360
952
- end
953
- return azimuth
954
- end
955
-
956
589
  def self.create_or_get_space(model, spaces, spacetype)
957
590
  if spaces[spacetype].nil?
958
- create_space_and_zone(model, spaces, spacetype)
591
+ Geometry.create_space_and_zone(model, spaces, spacetype)
959
592
  end
960
593
  return spaces[spacetype]
961
594
  end
@@ -982,7 +615,8 @@ class OSModel
982
615
  tilt = roof.pitch / 12.0
983
616
  z_origin = @walls_top + 0.5 * Math.sin(Math.atan(tilt)) * width
984
617
 
985
- 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)
986
620
  surfaces << surface
987
621
  surface.additionalProperties.setFeature('Length', length)
988
622
  surface.additionalProperties.setFeature('Width', width)
@@ -1022,14 +656,14 @@ class OSModel
1022
656
 
1023
657
  if roof.is_thermal_boundary
1024
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
1025
660
  WoodStudConstructionSet.new(Material.Stud2x(8.0), 0.07, 10.0, 0.75, 0.5, mat_roofing), # 2x8, 24" o.c. + R10
1026
- WoodStudConstructionSet.new(Material.Stud2x(8.0), 0.07, 5.0, 0.75, 0.5, mat_roofing), # 2x8, 24" o.c. + R5
1027
661
  WoodStudConstructionSet.new(Material.Stud2x(8.0), 0.07, 0.0, 0.75, 0.5, mat_roofing), # 2x8, 24" o.c.
1028
662
  WoodStudConstructionSet.new(Material.Stud2x6, 0.07, 0.0, 0.75, 0.5, mat_roofing), # 2x6, 24" o.c.
1029
663
  WoodStudConstructionSet.new(Material.Stud2x4, 0.07, 0.0, 0.5, 0.5, mat_roofing), # 2x4, 16" o.c.
1030
664
  WoodStudConstructionSet.new(Material.Stud2x4, 0.01, 0.0, 0.0, 0.0, mat_roofing), # Fallback
1031
665
  ]
1032
- 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)
1033
667
 
1034
668
  Constructions.apply_closed_cavity_roof(runner, model, surfaces, "#{roof.id} construction",
1035
669
  cavity_r, install_grade,
@@ -1045,7 +679,7 @@ class OSModel
1045
679
  GenericConstructionSet.new(0.0, 0.5, 0.0, mat_roofing), # Standard
1046
680
  GenericConstructionSet.new(0.0, 0.0, 0.0, mat_roofing), # Fallback
1047
681
  ]
1048
- 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)
1049
683
 
1050
684
  cavity_r = 0
1051
685
  cavity_ins_thick_in = 0
@@ -1059,7 +693,7 @@ class OSModel
1059
693
  mat_roofing, has_radiant_barrier,
1060
694
  inside_film, outside_film, radiant_barrier_grade)
1061
695
  end
1062
- 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)
1063
697
  end
1064
698
  end
1065
699
 
@@ -1084,7 +718,8 @@ class OSModel
1084
718
  length = (wall.net_area / height) / azimuths.size
1085
719
  z_origin = @foundation_top
1086
720
 
1087
- 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)
1088
723
  surfaces << surface
1089
724
  surface.additionalProperties.setFeature('Length', length)
1090
725
  surface.additionalProperties.setFeature('Azimuth', azimuth)
@@ -1128,8 +763,8 @@ class OSModel
1128
763
  outside_film = Material.AirFilmOutsideASHRAE140
1129
764
  end
1130
765
 
1131
- apply_wall_construction(runner, model, surfaces, wall, wall.id, wall.wall_type, wall.insulation_assembly_r_value,
1132
- 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)
1133
768
  end
1134
769
  end
1135
770
 
@@ -1152,7 +787,8 @@ class OSModel
1152
787
  length = (rim_joist.area / height) / azimuths.size
1153
788
  z_origin = @foundation_top
1154
789
 
1155
- 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)
1156
792
  surfaces << surface
1157
793
  surface.additionalProperties.setFeature('Length', length)
1158
794
  surface.additionalProperties.setFeature('Azimuth', azimuth)
@@ -1191,12 +827,12 @@ class OSModel
1191
827
  assembly_r = rim_joist.insulation_assembly_r_value
1192
828
 
1193
829
  constr_sets = [
830
+ WoodStudConstructionSet.new(Material.Stud2x(2.0), 0.17, 20.0, 2.0, drywall_thick_in, mat_ext_finish), # 2x4 + R20
1194
831
  WoodStudConstructionSet.new(Material.Stud2x(2.0), 0.17, 10.0, 2.0, drywall_thick_in, mat_ext_finish), # 2x4 + R10
1195
- WoodStudConstructionSet.new(Material.Stud2x(2.0), 0.17, 5.0, 2.0, drywall_thick_in, mat_ext_finish), # 2x4 + R5
1196
832
  WoodStudConstructionSet.new(Material.Stud2x(2.0), 0.17, 0.0, 2.0, drywall_thick_in, mat_ext_finish), # 2x4
1197
833
  WoodStudConstructionSet.new(Material.Stud2x(2.0), 0.01, 0.0, 0.0, 0.0, mat_ext_finish), # Fallback
1198
834
  ]
1199
- 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)
1200
836
  install_grade = 1
1201
837
 
1202
838
  Constructions.apply_rim_joist(runner, model, surfaces, rim_joist, "#{rim_joist.id} construction",
@@ -1204,7 +840,7 @@ class OSModel
1204
840
  constr_set.drywall_thick_in, constr_set.osb_thick_in,
1205
841
  constr_set.rigid_r, constr_set.exterior_material,
1206
842
  inside_film, outside_film)
1207
- 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)
1208
844
  end
1209
845
  end
1210
846
 
@@ -1220,10 +856,12 @@ class OSModel
1220
856
  end
1221
857
 
1222
858
  if frame_floor.is_ceiling
1223
- 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)
1224
861
  surface.additionalProperties.setFeature('SurfaceType', 'Ceiling')
1225
862
  else
1226
- 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)
1227
865
  surface.additionalProperties.setFeature('SurfaceType', 'Floor')
1228
866
  end
1229
867
  surface.additionalProperties.setFeature('Tilt', 0.0)
@@ -1272,6 +910,7 @@ class OSModel
1272
910
  end
1273
911
  end
1274
912
  constr_sets = [
913
+ WoodStudConstructionSet.new(Material.Stud2x6, 0.10, 20.0, 0.75, 0.0, covering), # 2x6, 24" o.c. + R20
1275
914
  WoodStudConstructionSet.new(Material.Stud2x6, 0.10, 10.0, 0.75, 0.0, covering), # 2x6, 24" o.c. + R10
1276
915
  WoodStudConstructionSet.new(Material.Stud2x6, 0.10, 0.0, 0.75, 0.0, covering), # 2x6, 24" o.c.
1277
916
  WoodStudConstructionSet.new(Material.Stud2x4, 0.13, 0.0, 0.5, 0.0, covering), # 2x4, 16" o.c.
@@ -1280,7 +919,7 @@ class OSModel
1280
919
  end
1281
920
  assembly_r = frame_floor.insulation_assembly_r_value
1282
921
 
1283
- 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)
1284
923
 
1285
924
  install_grade = 1
1286
925
  if frame_floor.is_ceiling
@@ -1298,7 +937,7 @@ class OSModel
1298
937
  constr_set.exterior_material, inside_film, outside_film)
1299
938
  end
1300
939
 
1301
- 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)
1302
941
  end
1303
942
  end
1304
943
 
@@ -1319,6 +958,7 @@ class OSModel
1319
958
  next unless slab.interior_adjacent_to == foundation_type
1320
959
 
1321
960
  slabs << slab
961
+ slab.exposed_perimeter = [slab.exposed_perimeter, 1.0].max # minimum value to prevent error if no exposed slab
1322
962
  end
1323
963
 
1324
964
  # Calculate combinations of slabs/walls for each Kiva instance
@@ -1413,7 +1053,8 @@ class OSModel
1413
1053
  azimuth = foundation_wall.azimuth
1414
1054
  end
1415
1055
 
1416
- 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)
1417
1058
  surface.additionalProperties.setFeature('Length', length)
1418
1059
  surface.additionalProperties.setFeature('Azimuth', azimuth)
1419
1060
  surface.additionalProperties.setFeature('Tilt', 90.0)
@@ -1444,8 +1085,8 @@ class OSModel
1444
1085
  end
1445
1086
  mat_ext_finish = nil
1446
1087
 
1447
- apply_wall_construction(runner, model, [surface], foundation_wall, foundation_wall.id, wall_type, assembly_r,
1448
- 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)
1449
1090
  end
1450
1091
  end
1451
1092
  end
@@ -1478,7 +1119,8 @@ class OSModel
1478
1119
  subsurface_area = 0
1479
1120
  end
1480
1121
 
1481
- 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)
1482
1124
  surface.additionalProperties.setFeature('Length', length)
1483
1125
  surface.additionalProperties.setFeature('Azimuth', azimuth)
1484
1126
  surface.additionalProperties.setFeature('Tilt', 90.0)
@@ -1528,7 +1170,7 @@ class OSModel
1528
1170
  ext_rigid_r, int_rigid_r, drywall_thick_in, concrete_thick_in, height_ag)
1529
1171
 
1530
1172
  if not assembly_r.nil?
1531
- 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)
1532
1174
  end
1533
1175
 
1534
1176
  return surface.adjacentFoundation.get
@@ -1547,7 +1189,8 @@ class OSModel
1547
1189
  slab_length = slab_tot_perim / 4.0 + Math.sqrt(sqrt_term) / 4.0
1548
1190
  slab_width = slab_tot_perim / 4.0 - Math.sqrt(sqrt_term) / 4.0
1549
1191
 
1550
- 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)
1551
1194
  surface.setName(slab.id)
1552
1195
  surface.setSurfaceType('Floor')
1553
1196
  surface.setOutsideBoundaryCondition('Foundation')
@@ -1613,9 +1256,7 @@ class OSModel
1613
1256
 
1614
1257
  addtl_cfa = @cfa - sum_cfa
1615
1258
 
1616
- if addtl_cfa < -1.0 # Allow some rounding
1617
- fail "Sum of floor/slab area adjacent to conditioned space (#{sum_cfa.round(1)}) is greater than conditioned floor area (#{@cfa.round(1)})."
1618
- end
1259
+ fail if addtl_cfa < -1.0 # Allow some rounding; EPvalidator.xml should prevent this
1619
1260
 
1620
1261
  return unless addtl_cfa > 1.0 # Allow some rounding
1621
1262
 
@@ -1624,7 +1265,8 @@ class OSModel
1624
1265
  z_origin = @foundation_top + 8.0 * (@ncfl_ag - 1)
1625
1266
 
1626
1267
  # Add floor surface
1627
- 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)
1628
1270
 
1629
1271
  floor_surface.setSunExposure('NoSun')
1630
1272
  floor_surface.setWindExposure('NoWind')
@@ -1636,7 +1278,8 @@ class OSModel
1636
1278
  floor_surface.additionalProperties.setFeature('Tilt', 0.0)
1637
1279
 
1638
1280
  # Add ceiling surface
1639
- 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)
1640
1283
 
1641
1284
  ceiling_surface.setSunExposure('NoSun')
1642
1285
  ceiling_surface.setWindExposure('NoWind')
@@ -1681,40 +1324,16 @@ class OSModel
1681
1324
  end
1682
1325
 
1683
1326
  def self.add_neighbors(runner, model, length)
1684
- z_origin = 0 # shading surface always starts at grade
1685
-
1686
- shading_surfaces = []
1687
- @hpxml.neighbor_buildings.each do |neighbor_building|
1688
- height = neighbor_building.height.nil? ? @walls_top : neighbor_building.height
1689
-
1690
- shading_surface = OpenStudio::Model::ShadingSurface.new(add_wall_polygon(length, height, z_origin, neighbor_building.azimuth), model)
1691
- shading_surface.additionalProperties.setFeature('Azimuth', neighbor_building.azimuth)
1692
- shading_surface.additionalProperties.setFeature('Distance', neighbor_building.distance)
1693
- shading_surface.setName("Neighbor azimuth #{neighbor_building.azimuth} distance #{neighbor_building.distance}")
1694
-
1695
- shading_surfaces << shading_surface
1696
- end
1697
-
1698
- unless shading_surfaces.empty?
1699
- shading_surface_group = OpenStudio::Model::ShadingSurfaceGroup.new(model)
1700
- shading_surface_group.setName(Constants.ObjectNameNeighbors)
1701
- shading_surfaces.each do |shading_surface|
1702
- shading_surface.setShadingSurfaceGroup(shading_surface_group)
1703
- end
1704
- end
1705
1327
  end
1706
1328
 
1707
- def self.add_interior_shading_schedule(runner, model, weather)
1708
- heating_season, cooling_season = HVAC.get_default_heating_and_cooling_seasons(weather)
1709
- @clg_season_sch = MonthWeekdayWeekendSchedule.new(model, 'cooling season schedule', Array.new(24, 1), Array.new(24, 1), cooling_season, Constants.ScheduleTypeLimitsFraction)
1710
-
1711
- # Create heating season as opposite of cooling season (i.e., with overlap months)
1712
- non_cooling_season = cooling_season.map { |m| (m - 1).abs }
1713
- @htg_season_sch = MonthWeekdayWeekendSchedule.new(model, 'heating season schedule', Array.new(24, 1), Array.new(24, 1), non_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)
1714
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)
1715
1334
  @clg_ssn_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Schedule Value')
1716
1335
  @clg_ssn_sensor.setName('cool_season')
1717
- @clg_ssn_sensor.setKeyName(@clg_season_sch.schedule.name.to_s)
1336
+ @clg_ssn_sensor.setKeyName(clg_season_sch.schedule.name.to_s)
1718
1337
  end
1719
1338
 
1720
1339
  def self.add_windows(runner, model, spaces, weather)
@@ -1727,28 +1346,32 @@ class OSModel
1727
1346
  end
1728
1347
  @hpxml.collapse_enclosure_surfaces()
1729
1348
 
1349
+ shading_group = nil
1350
+ shading_schedules = {}
1351
+ shading_ems = { sensors: {}, program: nil }
1352
+
1730
1353
  surfaces = []
1731
- @hpxml.windows.each do |window|
1354
+ @hpxml.windows.each_with_index do |window, i|
1732
1355
  window_height = 4.0 # ft, default
1733
1356
 
1734
1357
  overhang_depth = nil
1735
- if not window.overhangs_depth.nil?
1358
+ if (not window.overhangs_depth.nil?) && (window.overhangs_depth > 0)
1736
1359
  overhang_depth = window.overhangs_depth
1737
1360
  overhang_distance_to_top = window.overhangs_distance_to_top_of_window
1738
1361
  overhang_distance_to_bottom = window.overhangs_distance_to_bottom_of_window
1739
1362
  window_height = overhang_distance_to_bottom - overhang_distance_to_top
1740
1363
  end
1741
1364
 
1742
- window_width = window.area / window_height
1365
+ window_length = window.area / window_height
1743
1366
  z_origin = @foundation_top
1744
1367
 
1745
1368
  if window.is_exterior
1746
1369
 
1747
1370
  # Create parent surface slightly bigger than window
1748
- surface = OpenStudio::Model::Surface.new(add_wall_polygon(window_width, window_height, z_origin,
1749
- 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)
1750
1373
 
1751
- surface.additionalProperties.setFeature('Length', window_width)
1374
+ surface.additionalProperties.setFeature('Length', window_length)
1752
1375
  surface.additionalProperties.setFeature('Azimuth', window.azimuth)
1753
1376
  surface.additionalProperties.setFeature('Tilt', 90.0)
1754
1377
  surface.additionalProperties.setFeature('SurfaceType', 'Window')
@@ -1756,8 +1379,8 @@ class OSModel
1756
1379
  surface.setSurfaceType('Wall')
1757
1380
  set_surface_interior(model, spaces, surface, window.wall)
1758
1381
 
1759
- sub_surface = OpenStudio::Model::SubSurface.new(add_wall_polygon(window_width, window_height, z_origin,
1760
- 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)
1761
1384
  sub_surface.setName(window.id)
1762
1385
  sub_surface.setSurface(surface)
1763
1386
  sub_surface.setSubSurfaceType('FixedWindow')
@@ -1771,21 +1394,22 @@ class OSModel
1771
1394
  end
1772
1395
 
1773
1396
  # Apply construction
1774
- cool_shade_mult = window.interior_shading_factor_summer
1775
- heat_shade_mult = window.interior_shading_factor_winter
1776
- Constructions.apply_window(runner, model, sub_surface, 'WindowConstruction',
1777
- weather, @htg_season_sch, @clg_season_sch, window.ufactor, window.shgc,
1778
- 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)
1779
1403
  else
1780
1404
  # Window is on an interior surface, which E+ does not allow. Model
1781
1405
  # as a door instead so that we can get the appropriate conduction
1782
1406
  # heat transfer; there is no solar gains anyway.
1783
1407
 
1784
1408
  # Create parent surface slightly bigger than window
1785
- surface = OpenStudio::Model::Surface.new(add_wall_polygon(window_width, window_height, z_origin,
1786
- 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)
1787
1411
 
1788
- surface.additionalProperties.setFeature('Length', window_width)
1412
+ surface.additionalProperties.setFeature('Length', window_length)
1789
1413
  surface.additionalProperties.setFeature('Azimuth', window.azimuth)
1790
1414
  surface.additionalProperties.setFeature('Tilt', 90.0)
1791
1415
  surface.additionalProperties.setFeature('SurfaceType', 'Door')
@@ -1793,8 +1417,8 @@ class OSModel
1793
1417
  surface.setSurfaceType('Wall')
1794
1418
  set_surface_interior(model, spaces, surface, window.wall)
1795
1419
 
1796
- sub_surface = OpenStudio::Model::SubSurface.new(add_wall_polygon(window_width, window_height, z_origin,
1797
- 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)
1798
1422
  sub_surface.setName(window.id)
1799
1423
  sub_surface.setSurface(surface)
1800
1424
  sub_surface.setSubSurfaceType('Door')
@@ -1814,16 +1438,20 @@ class OSModel
1814
1438
 
1815
1439
  def self.add_skylights(runner, model, spaces, weather)
1816
1440
  surfaces = []
1817
- @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|
1818
1447
  tilt = skylight.roof.pitch / 12.0
1819
1448
  width = Math::sqrt(skylight.area)
1820
1449
  length = skylight.area / width
1821
1450
  z_origin = @walls_top + 0.5 * Math.sin(Math.atan(tilt)) * width
1822
1451
 
1823
1452
  # Create parent surface slightly bigger than skylight
1824
- surface = OpenStudio::Model::Surface.new(add_roof_polygon(length + 0.001, width + 0.001, z_origin,
1825
- skylight.azimuth, tilt), model)
1826
-
1453
+ vertices = Geometry.create_roof_vertices(length, width, z_origin, skylight.azimuth, tilt, add_buffer: true)
1454
+ surface = OpenStudio::Model::Surface.new(vertices, model)
1827
1455
  surface.additionalProperties.setFeature('Length', length)
1828
1456
  surface.additionalProperties.setFeature('Width', width)
1829
1457
  surface.additionalProperties.setFeature('Azimuth', skylight.azimuth)
@@ -1835,20 +1463,19 @@ class OSModel
1835
1463
  surface.setOutsideBoundaryCondition('Outdoors') # cannot be adiabatic because subsurfaces won't be created
1836
1464
  surfaces << surface
1837
1465
 
1838
- sub_surface = OpenStudio::Model::SubSurface.new(add_roof_polygon(length, width, z_origin,
1839
- 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)
1840
1468
  sub_surface.setName(skylight.id)
1841
1469
  sub_surface.setSurface(surface)
1842
1470
  sub_surface.setSubSurfaceType('Skylight')
1843
1471
 
1844
1472
  # Apply construction
1845
- ufactor = skylight.ufactor
1846
- shgc = skylight.shgc
1847
- cool_shade_mult = skylight.interior_shading_factor_summer
1848
- heat_shade_mult = skylight.interior_shading_factor_winter
1849
- Constructions.apply_skylight(runner, model, sub_surface, 'SkylightConstruction',
1850
- weather, @htg_season_sch, @clg_season_sch, ufactor, shgc,
1851
- 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)
1852
1479
  end
1853
1480
 
1854
1481
  apply_adiabatic_construction(runner, model, surfaces, 'roof')
@@ -1858,14 +1485,14 @@ class OSModel
1858
1485
  surfaces = []
1859
1486
  @hpxml.doors.each do |door|
1860
1487
  door_height = 6.67 # ft
1861
- door_width = door.area / door_height
1488
+ door_length = door.area / door_height
1862
1489
  z_origin = @foundation_top
1863
1490
 
1864
1491
  # Create parent surface slightly bigger than door
1865
- surface = OpenStudio::Model::Surface.new(add_wall_polygon(door_width, door_height, z_origin,
1866
- 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)
1867
1494
 
1868
- surface.additionalProperties.setFeature('Length', door_width)
1495
+ surface.additionalProperties.setFeature('Length', door_length)
1869
1496
  surface.additionalProperties.setFeature('Azimuth', door.azimuth)
1870
1497
  surface.additionalProperties.setFeature('Tilt', 90.0)
1871
1498
  surface.additionalProperties.setFeature('SurfaceType', 'Door')
@@ -1873,8 +1500,8 @@ class OSModel
1873
1500
  surface.setSurfaceType('Wall')
1874
1501
  set_surface_interior(model, spaces, surface, door.wall)
1875
1502
 
1876
- sub_surface = OpenStudio::Model::SubSurface.new(add_wall_polygon(door_width, door_height, z_origin,
1877
- 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)
1878
1505
  sub_surface.setName(door.id)
1879
1506
  sub_surface.setSurface(surface)
1880
1507
  sub_surface.setSubSurfaceType('Door')
@@ -1958,10 +1585,11 @@ class OSModel
1958
1585
  end
1959
1586
 
1960
1587
  # Water Heater
1588
+ has_uncond_bsmnt = @hpxml.has_space_type(HPXML::LocationBasementUnconditioned)
1961
1589
  @hpxml.water_heating_systems.each do |water_heating_system|
1962
1590
  loc_space, loc_schedule = get_space_or_schedule_from_location(water_heating_system.location, 'WaterHeatingSystem', model, spaces)
1963
1591
 
1964
- 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)
1965
1593
 
1966
1594
  if water_heating_system.water_heater_type == HPXML::WaterHeaterTypeStorage
1967
1595
 
@@ -1993,11 +1621,7 @@ class OSModel
1993
1621
  end
1994
1622
 
1995
1623
  # Hot water fixtures and appliances
1996
- HotWaterAndAppliances.apply(model, runner, weather, spaces[HPXML::LocationLivingSpace],
1997
- @cfa, @nbeds, @ncfl, @has_uncond_bsmnt, @hpxml.clothes_washers,
1998
- @hpxml.clothes_dryers, @hpxml.dishwashers, @hpxml.refrigerators,
1999
- @hpxml.freezers, @hpxml.cooking_ranges, @hpxml.ovens, @hpxml.water_heating,
2000
- @hpxml.water_heating_systems, hot_water_distribution, @hpxml.water_fixtures,
1624
+ HotWaterAndAppliances.apply(model, runner, @hpxml, weather, spaces, hot_water_distribution,
2001
1625
  solar_thermal_system, @eri_version, @dhw_map, @schedules_file)
2002
1626
 
2003
1627
  if (not solar_thermal_system.nil?) && (not solar_thermal_system.collector_area.nil?) # Detailed solar water heater
@@ -2009,33 +1633,19 @@ class OSModel
2009
1633
  Waterheater.apply_combi_system_EMS(model, @dhw_map, @hpxml.water_heating_systems)
2010
1634
  end
2011
1635
 
2012
- def self.is_central_air_conditioner_and_furnace(heating_system, cooling_system)
2013
- if not (@hpxml.heating_systems.include?(heating_system) && (heating_system.heating_system_type == HPXML::HVACTypeFurnace))
2014
- return false
2015
- end
2016
- if not (@hpxml.cooling_systems.include?(cooling_system) && (cooling_system.cooling_system_type == HPXML::HVACTypeCentralAirConditioner))
2017
- return false
2018
- end
2019
-
2020
- return true
2021
- end
2022
-
2023
- def self.update_shared_hvac_systems()
2024
- HVAC.apply_shared_systems(@hpxml)
2025
- end
2026
-
2027
1636
  def self.add_cooling_system(runner, model, spaces)
2028
1637
  living_zone = spaces[HPXML::LocationLivingSpace].thermalZone.get
2029
1638
 
2030
- @hpxml.cooling_systems.each do |cooling_system|
2031
- 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
2032
1642
 
2033
- if cooling_system.cooling_system_type == HPXML::HVACTypeCentralAirConditioner
1643
+ cooling_system = hvac_system[:cooling]
1644
+ heating_system = hvac_system[:heating]
2034
1645
 
2035
- heating_system = cooling_system.attached_heating_system
2036
- if not is_central_air_conditioner_and_furnace(heating_system, cooling_system)
2037
- heating_system = nil
2038
- 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
2039
1649
 
2040
1650
  HVAC.apply_central_air_conditioner_furnace(model, runner, cooling_system, heating_system,
2041
1651
  @remaining_cool_load_frac, @remaining_heat_load_frac,
@@ -2045,19 +1655,19 @@ class OSModel
2045
1655
  @remaining_heat_load_frac -= heating_system.fraction_heat_load_served
2046
1656
  end
2047
1657
 
2048
- elsif cooling_system.cooling_system_type == HPXML::HVACTypeRoomAirConditioner
1658
+ elsif [HPXML::HVACTypeRoomAirConditioner].include? cooling_system.cooling_system_type
2049
1659
 
2050
1660
  HVAC.apply_room_air_conditioner(model, runner, cooling_system,
2051
1661
  @remaining_cool_load_frac, living_zone,
2052
1662
  @hvac_map)
2053
1663
 
2054
- elsif cooling_system.cooling_system_type == HPXML::HVACTypeEvaporativeCooler
1664
+ elsif [HPXML::HVACTypeEvaporativeCooler].include? cooling_system.cooling_system_type
2055
1665
 
2056
1666
  HVAC.apply_evaporative_cooler(model, runner, cooling_system,
2057
1667
  @remaining_cool_load_frac, living_zone,
2058
1668
  @hvac_map)
2059
1669
 
2060
- elsif cooling_system.cooling_system_type == HPXML::HVACTypeMiniSplitAirConditioner
1670
+ elsif [HPXML::HVACTypeMiniSplitAirConditioner].include? cooling_system.cooling_system_type
2061
1671
 
2062
1672
  HVAC.apply_mini_split_air_conditioner(model, runner, cooling_system,
2063
1673
  @remaining_cool_load_frac,
@@ -2071,13 +1681,18 @@ class OSModel
2071
1681
  def self.add_heating_system(runner, model, spaces)
2072
1682
  living_zone = spaces[HPXML::LocationLivingSpace].thermalZone.get
2073
1683
 
2074
- @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
+
2075
1691
  check_distribution_system(heating_system.distribution_system, heating_system.heating_system_type)
2076
1692
 
2077
- if heating_system.heating_system_type == HPXML::HVACTypeFurnace
1693
+ if [HPXML::HVACTypeFurnace].include? heating_system.heating_system_type
2078
1694
 
2079
- cooling_system = heating_system.attached_cooling_system
2080
- if is_central_air_conditioner_and_furnace(heating_system, cooling_system)
1695
+ if not cooling_system.nil?
2081
1696
  next # Already processed combined AC+furnace
2082
1697
  end
2083
1698
 
@@ -2085,22 +1700,22 @@ class OSModel
2085
1700
  nil, @remaining_heat_load_frac,
2086
1701
  living_zone, @hvac_map)
2087
1702
 
2088
- elsif heating_system.heating_system_type == HPXML::HVACTypeBoiler
1703
+ elsif [HPXML::HVACTypeBoiler].include? heating_system.heating_system_type
2089
1704
 
2090
1705
  HVAC.apply_boiler(model, runner, heating_system,
2091
1706
  @remaining_heat_load_frac, living_zone, @hvac_map)
2092
1707
 
2093
- elsif heating_system.heating_system_type == HPXML::HVACTypeElectricResistance
1708
+ elsif [HPXML::HVACTypeElectricResistance].include? heating_system.heating_system_type
2094
1709
 
2095
1710
  HVAC.apply_electric_baseboard(model, runner, heating_system,
2096
1711
  @remaining_heat_load_frac, living_zone, @hvac_map)
2097
1712
 
2098
- elsif (heating_system.heating_system_type == HPXML::HVACTypeStove ||
2099
- heating_system.heating_system_type == HPXML::HVACTypePortableHeater ||
2100
- heating_system.heating_system_type == HPXML::HVACTypeFixedHeater ||
2101
- heating_system.heating_system_type == HPXML::HVACTypeWallFurnace ||
2102
- heating_system.heating_system_type == HPXML::HVACTypeFloorFurnace ||
2103
- 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
2104
1719
 
2105
1720
  HVAC.apply_unit_heater(model, runner, heating_system,
2106
1721
  @remaining_heat_load_frac, living_zone, @hvac_map)
@@ -2113,45 +1728,36 @@ class OSModel
2113
1728
  def self.add_heat_pump(runner, model, weather, spaces)
2114
1729
  living_zone = spaces[HPXML::LocationLivingSpace].thermalZone.get
2115
1730
 
2116
- @hpxml.heat_pumps.each do |heat_pump|
2117
- # FUTURE: Move these checks into hvac.rb
2118
- if not heat_pump.heating_capacity_17F.nil?
2119
- if heat_pump.heating_capacity.nil?
2120
- fail "HeatPump '#{heat_pump.id}' must have both HeatingCapacity and HeatingCapacity17F provided or not provided."
2121
- elsif heat_pump.heating_capacity == 0.0
2122
- heat_pump.heating_capacity_17F = nil
2123
- end
2124
- end
2125
- if not heat_pump.backup_heating_fuel.nil?
2126
- if heat_pump.backup_heating_capacity.nil? ^ heat_pump.heating_capacity.nil?
2127
- fail "HeatPump '#{heat_pump.id}' must have both HeatingCapacity and BackupHeatingCapacity provided or not provided."
2128
- end
2129
- 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]
2130
1736
 
2131
1737
  check_distribution_system(heat_pump.distribution_system, heat_pump.heat_pump_type)
2132
1738
 
2133
- if heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpWaterLoopToAir
1739
+ if [HPXML::HVACTypeHeatPumpWaterLoopToAir].include? heat_pump.heat_pump_type
2134
1740
 
2135
1741
  HVAC.apply_water_loop_to_air_heat_pump(model, runner, heat_pump,
2136
1742
  @remaining_heat_load_frac,
2137
1743
  @remaining_cool_load_frac,
2138
1744
  living_zone, @hvac_map)
2139
1745
 
2140
- elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpAirToAir
1746
+ elsif [HPXML::HVACTypeHeatPumpAirToAir].include? heat_pump.heat_pump_type
2141
1747
 
2142
1748
  HVAC.apply_central_air_to_air_heat_pump(model, runner, heat_pump,
2143
1749
  @remaining_heat_load_frac,
2144
1750
  @remaining_cool_load_frac,
2145
1751
  living_zone, @hvac_map)
2146
1752
 
2147
- elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpMiniSplit
1753
+ elsif [HPXML::HVACTypeHeatPumpMiniSplit].include? heat_pump.heat_pump_type
2148
1754
 
2149
1755
  HVAC.apply_mini_split_heat_pump(model, runner, heat_pump,
2150
1756
  @remaining_heat_load_frac,
2151
1757
  @remaining_cool_load_frac,
2152
1758
  living_zone, @hvac_map)
2153
1759
 
2154
- elsif heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir
1760
+ elsif [HPXML::HVACTypeHeatPumpGroundToAir].include? heat_pump.heat_pump_type
2155
1761
 
2156
1762
  HVAC.apply_ground_to_air_heat_pump(model, runner, weather, heat_pump,
2157
1763
  @remaining_heat_load_frac,
@@ -2171,7 +1777,7 @@ class OSModel
2171
1777
  living_zone = spaces[HPXML::LocationLivingSpace].thermalZone.get
2172
1778
  obj_name = Constants.ObjectNameIdealAirSystem
2173
1779
 
2174
- 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)
2175
1781
  cooling_load_frac = 1.0
2176
1782
  heating_load_frac = 1.0
2177
1783
  if @apply_ashrae140_assumptions
@@ -2218,19 +1824,17 @@ class OSModel
2218
1824
  obj_name = Constants.ObjectNameIdealAirSystemResidual
2219
1825
 
2220
1826
  if @remaining_cool_load_frac < 1.0
2221
- sequential_cool_load_frac = 1
1827
+ sequential_cool_load_frac = 1.0
2222
1828
  else
2223
- sequential_cool_load_frac = 0 # no cooling system, don't add ideal air for cooling either
2224
- 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
2225
1830
  end
2226
1831
 
2227
1832
  if @remaining_heat_load_frac < 1.0
2228
- sequential_heat_load_frac = 1
1833
+ sequential_heat_load_frac = 1.0
2229
1834
  else
2230
- sequential_heat_load_frac = 0 # no heating system, don't add ideal air for heating either
2231
- 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
2232
1836
  end
2233
- 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)
2234
1838
  HVAC.apply_ideal_air_loads(model, runner, obj_name, sequential_cool_load_frac, sequential_heat_load_frac,
2235
1839
  living_zone)
2236
1840
  end
@@ -2253,25 +1857,24 @@ class OSModel
2253
1857
  HVAC.apply_ceiling_fans(model, runner, weather, ceiling_fan, spaces[HPXML::LocationLivingSpace], @schedules_file)
2254
1858
  end
2255
1859
 
2256
- def self.add_dehumidifier(runner, model, spaces)
1860
+ def self.add_dehumidifiers(runner, model, spaces)
2257
1861
  return if @hpxml.dehumidifiers.size == 0
2258
1862
 
2259
- dehumidifier = @hpxml.dehumidifiers[0]
2260
- HVAC.apply_dehumidifier(model, runner, dehumidifier, spaces[HPXML::LocationLivingSpace], @hvac_map)
1863
+ HVAC.apply_dehumidifiers(model, runner, @hpxml.dehumidifiers, spaces[HPXML::LocationLivingSpace], @hvac_map)
2261
1864
  end
2262
1865
 
2263
1866
  def self.check_distribution_system(hvac_distribution, system_type)
2264
1867
  return if hvac_distribution.nil?
2265
1868
 
2266
1869
  hvac_distribution_type_map = { HPXML::HVACTypeFurnace => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2267
- HPXML::HVACTypeBoiler => [HPXML::HVACDistributionTypeHydronic, HPXML::HVACDistributionTypeHydronicAndAir, HPXML::HVACDistributionTypeDSE],
1870
+ HPXML::HVACTypeBoiler => [HPXML::HVACDistributionTypeHydronic, HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2268
1871
  HPXML::HVACTypeCentralAirConditioner => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2269
1872
  HPXML::HVACTypeEvaporativeCooler => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2270
1873
  HPXML::HVACTypeMiniSplitAirConditioner => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2271
1874
  HPXML::HVACTypeHeatPumpAirToAir => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2272
1875
  HPXML::HVACTypeHeatPumpMiniSplit => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2273
1876
  HPXML::HVACTypeHeatPumpGroundToAir => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE],
2274
- HPXML::HVACTypeHeatPumpWaterLoopToAir => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeHydronicAndAir, HPXML::HVACDistributionTypeDSE] }
1877
+ HPXML::HVACTypeHeatPumpWaterLoopToAir => [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeDSE] }
2275
1878
 
2276
1879
  if not hvac_distribution_type_map[system_type].include? hvac_distribution.distribution_system_type
2277
1880
  # validator.rb only checks that a HVAC distribution system of the correct type (for the given HVAC system) exists
@@ -2282,7 +1885,6 @@ class OSModel
2282
1885
 
2283
1886
  def self.add_mels(runner, model, spaces)
2284
1887
  # Misc
2285
- modeled_mels = []
2286
1888
  @hpxml.plug_loads.each do |plug_load|
2287
1889
  if plug_load.plug_load_type == HPXML::PlugLoadTypeOther
2288
1890
  obj_name = Constants.ObjectNameMiscPlugLoads
@@ -2297,7 +1899,6 @@ class OSModel
2297
1899
  runner.registerWarning("Unexpected plug load type '#{plug_load.plug_load_type}'. The plug load will not be modeled.")
2298
1900
  next
2299
1901
  end
2300
- modeled_mels << plug_load.plug_load_type
2301
1902
 
2302
1903
  MiscLoads.apply_plug(model, plug_load, obj_name, spaces[HPXML::LocationLivingSpace], @apply_ashrae140_assumptions, @schedules_file)
2303
1904
  end
@@ -2329,37 +1930,25 @@ class OSModel
2329
1930
 
2330
1931
  def self.add_pools_and_hot_tubs(runner, model, spaces)
2331
1932
  @hpxml.pools.each do |pool|
1933
+ next if pool.type == HPXML::TypeNone
1934
+
2332
1935
  MiscLoads.apply_pool_or_hot_tub_heater(model, pool, Constants.ObjectNameMiscPoolHeater, spaces[HPXML::LocationLivingSpace], @schedules_file)
2333
1936
  MiscLoads.apply_pool_or_hot_tub_pump(model, pool, Constants.ObjectNameMiscPoolPump, spaces[HPXML::LocationLivingSpace], @schedules_file)
2334
1937
  end
2335
1938
 
2336
1939
  @hpxml.hot_tubs.each do |hot_tub|
1940
+ next if hot_tub.type == HPXML::TypeNone
1941
+
2337
1942
  MiscLoads.apply_pool_or_hot_tub_heater(model, hot_tub, Constants.ObjectNameMiscHotTubHeater, spaces[HPXML::LocationLivingSpace], @schedules_file)
2338
1943
  MiscLoads.apply_pool_or_hot_tub_pump(model, hot_tub, Constants.ObjectNameMiscHotTubPump, spaces[HPXML::LocationLivingSpace], @schedules_file)
2339
1944
  end
2340
1945
  end
2341
1946
 
2342
1947
  def self.add_airflow(runner, model, weather, spaces)
2343
- # Vented Attic
2344
- vented_attic = nil
2345
- @hpxml.attics.each do |attic|
2346
- next unless attic.attic_type == HPXML::AtticTypeVented
2347
-
2348
- vented_attic = attic
2349
- end
2350
-
2351
- # Vented Crawlspace
2352
- vented_crawl = nil
2353
- @hpxml.foundations.each do |foundation|
2354
- next unless foundation.foundation_type == HPXML::FoundationTypeCrawlspaceVented
2355
-
2356
- vented_crawl = foundation
2357
- end
2358
-
2359
1948
  # Ducts
2360
1949
  duct_systems = {}
2361
1950
  @hpxml.hvac_distributions.each do |hvac_distribution|
2362
- next unless [HPXML::HVACDistributionTypeAir, HPXML::HVACDistributionTypeHydronicAndAir].include? hvac_distribution.distribution_system_type
1951
+ next unless hvac_distribution.distribution_system_type == HPXML::HVACDistributionTypeAir
2363
1952
 
2364
1953
  air_ducts = create_ducts(runner, model, hvac_distribution, spaces)
2365
1954
  next if air_ducts.empty?
@@ -2368,7 +1957,7 @@ class OSModel
2368
1957
  added_ducts = false
2369
1958
  hvac_distribution.hvac_systems.each do |hvac_system|
2370
1959
  @hvac_map[hvac_system.id].each do |object|
2371
- next unless object.is_a? OpenStudio::Model::AirLoopHVAC
1960
+ next unless object.is_a?(OpenStudio::Model::AirLoopHVAC) || object.is_a?(OpenStudio::Model::ZoneHVACFourPipeFanCoil)
2372
1961
 
2373
1962
  if duct_systems[air_ducts].nil?
2374
1963
  duct_systems[air_ducts] = object
@@ -2382,37 +1971,14 @@ class OSModel
2382
1971
  end
2383
1972
  end
2384
1973
  end
2385
- if not added_ducts
2386
- # Check if ducted fan coil, which doesn't have an AirLoopHVAC;
2387
- # assign to FanCoil instead.
2388
- if hvac_distribution.distribution_system_type && hvac_distribution.hydronic_and_air_type == HPXML::HydronicAndAirTypeFanCoil
2389
- hvac_distribution.hvac_systems.each do |hvac_system|
2390
- @hvac_map[hvac_system.id].each do |object|
2391
- next unless object.is_a? OpenStudio::Model::ZoneHVACFourPipeFanCoil
2392
-
2393
- duct_systems[air_ducts] = object
2394
- added_ducts = true
2395
- end
2396
- end
2397
- end
2398
- end
2399
1974
  if not added_ducts
2400
1975
  fail 'Unexpected error adding ducts to model.'
2401
1976
  end
2402
1977
  end
2403
1978
 
2404
- air_infils = @hpxml.air_infiltration_measurements
2405
- window_area = @hpxml.windows.map { |w| w.area }.sum(0.0)
2406
- 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
2407
- site_type = @hpxml.site.site_type
2408
- shelter_coef = @hpxml.site.shelter_coefficient
2409
- @infil_volume = air_infils.select { |i| !i.infiltration_volume.nil? }[0].infiltration_volume
2410
- infil_height = @hpxml.inferred_infiltration_height(@infil_volume)
2411
- Airflow.apply(model, runner, weather, spaces, air_infils, @hpxml.ventilation_fans, @hpxml.clothes_dryers, @nbeds,
2412
- duct_systems, @infil_volume, infil_height, open_window_area,
2413
- @clg_ssn_sensor, @min_neighbor_distance, vented_attic, vented_crawl,
2414
- site_type, shelter_coef, @hpxml.building_construction.has_flue_or_chimney, @hvac_map, @eri_version,
2415
- @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)
2416
1982
  end
2417
1983
 
2418
1984
  def self.create_ducts(runner, model, hvac_distribution, spaces)
@@ -2465,14 +2031,9 @@ class OSModel
2465
2031
  end
2466
2032
 
2467
2033
  # If all ducts are in conditioned space, model leakage as going to outside
2468
- registered_warning = false
2469
2034
  [HPXML::DuctTypeSupply, HPXML::DuctTypeReturn].each do |duct_side|
2470
2035
  next unless (leakage_to_outside[duct_side][0] > 0) && (total_unconditioned_duct_area[duct_side] == 0)
2471
2036
 
2472
- if not registered_warning
2473
- 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.")
2474
- registered_warning = true
2475
- end
2476
2037
  duct_area = 0.0
2477
2038
  duct_rvalue = 0.0
2478
2039
  duct_loc_space = nil # outside
@@ -2496,10 +2057,6 @@ class OSModel
2496
2057
  return air_ducts
2497
2058
  end
2498
2059
 
2499
- def self.add_hvac_sizing(runner, model, weather, spaces)
2500
- HVACSizing.apply(model, runner, weather, spaces, @hpxml, @infil_volume, @nbeds, @min_neighbor_distance, @debug)
2501
- end
2502
-
2503
2060
  def self.add_photovoltaics(runner, model)
2504
2061
  @hpxml.pv_systems.each do |pv_system|
2505
2062
  PV.apply(model, @nbeds, pv_system)
@@ -2512,10 +2069,11 @@ class OSModel
2512
2069
  end
2513
2070
  end
2514
2071
 
2515
- def self.add_additional_properties(runner, model, hpxml_path)
2072
+ def self.add_additional_properties(runner, model, hpxml_path, building_id)
2516
2073
  # Store some data for use in reporting measure
2517
2074
  additionalProperties = model.getBuilding.additionalProperties
2518
2075
  additionalProperties.setFeature('hpxml_path', hpxml_path)
2076
+ additionalProperties.setFeature('building_id', building_id.to_s)
2519
2077
  additionalProperties.setFeature('hvac_map', map_to_string(@hvac_map))
2520
2078
  additionalProperties.setFeature('dhw_map', map_to_string(@dhw_map))
2521
2079
  end
@@ -2532,31 +2090,71 @@ class OSModel
2532
2090
  return map_str.to_s
2533
2091
  end
2534
2092
 
2535
- def self.add_component_loads_output(runner, model, spaces)
2093
+ def self.add_loads_output(runner, model, spaces, add_component_loads)
2536
2094
  living_zone = spaces[HPXML::LocationLivingSpace].thermalZone.get
2537
2095
 
2538
- # Prevent certain objects (e.g., OtherEquipment) from being counted towards both, e.g., ducts and internal gains
2539
- objects_already_processed = []
2096
+ liv_load_sensors, intgain_dehumidifier = add_total_loads_output(runner, model, living_zone)
2097
+ return unless add_component_loads
2540
2098
 
2541
- # EMS Sensors: Global
2099
+ add_component_loads_output(runner, model, living_zone, liv_load_sensors, intgain_dehumidifier)
2100
+ end
2542
2101
 
2102
+ def self.add_total_loads_output(runner, model, living_zone)
2543
2103
  liv_load_sensors = {}
2544
-
2545
2104
  liv_load_sensors[:htg] = OpenStudio::Model::EnergyManagementSystemSensor.new(model, "Heating:EnergyTransfer:Zone:#{living_zone.name.to_s.upcase}")
2546
2105
  liv_load_sensors[:htg].setName('htg_load_liv')
2547
-
2548
2106
  liv_load_sensors[:clg] = OpenStudio::Model::EnergyManagementSystemSensor.new(model, "Cooling:EnergyTransfer:Zone:#{living_zone.name.to_s.upcase}")
2549
2107
  liv_load_sensors[:clg].setName('clg_load_liv')
2550
2108
 
2551
2109
  tot_load_sensors = {}
2552
-
2553
2110
  tot_load_sensors[:htg] = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Heating:EnergyTransfer')
2554
2111
  tot_load_sensors[:htg].setName('htg_load_tot')
2555
-
2556
2112
  tot_load_sensors[:clg] = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Cooling:EnergyTransfer')
2557
2113
  tot_load_sensors[:clg].setName('clg_load_tot')
2558
2114
 
2559
- 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 = []
2560
2158
 
2561
2159
  # EMS Sensors: Surfaces, SubSurfaces, InternalMass
2562
2160
 
@@ -2746,27 +2344,7 @@ class OSModel
2746
2344
  ducts_mix_loss_sensor.setKeyName(living_zone.name.to_s)
2747
2345
  end
2748
2346
 
2749
- # Return duct losses
2750
- model.getOtherEquipments.sort.each do |o|
2751
- next if objects_already_processed.include? o
2752
-
2753
- is_duct_load = o.additionalProperties.getFeatureAsBoolean(Constants.IsDuctLoadForReport)
2754
- next unless is_duct_load.is_initialized
2755
-
2756
- objects_already_processed << o
2757
- next unless is_duct_load.get
2758
-
2759
- ducts_sensors << []
2760
- { 'Other Equipment Convective Heating Energy' => 'ducts_conv',
2761
- 'Other Equipment Radiant Heating Energy' => 'ducts_rad' }.each do |var, name|
2762
- ducts_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
2763
- ducts_sensor.setName(name)
2764
- ducts_sensor.setKeyName(o.name.to_s)
2765
- ducts_sensors[-1] << ducts_sensor
2766
- end
2767
- end
2768
-
2769
- # Supply duct losses
2347
+ # Duct losses
2770
2348
  model.getOtherEquipments.sort.each do |o|
2771
2349
  next if objects_already_processed.include? o
2772
2350
 
@@ -2804,20 +2382,6 @@ class OSModel
2804
2382
  end
2805
2383
  end
2806
2384
 
2807
- model.getGasEquipments.sort.each do |o|
2808
- next unless o.space.get.thermalZone.get.name.to_s == living_zone.name.to_s
2809
- next if objects_already_processed.include? o
2810
-
2811
- intgains_sensors << []
2812
- { 'Gas Equipment Convective Heating Energy' => 'ig_ge_conv',
2813
- 'Gas Equipment Radiant Heating Energy' => 'ig_ge_rad' }.each do |var, name|
2814
- intgains_gas_equip_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
2815
- intgains_gas_equip_sensor.setName(name)
2816
- intgains_gas_equip_sensor.setKeyName(o.name.to_s)
2817
- intgains_sensors[-1] << intgains_gas_equip_sensor
2818
- end
2819
- end
2820
-
2821
2385
  model.getOtherEquipments.sort.each do |o|
2822
2386
  next unless o.space.get.thermalZone.get.name.to_s == living_zone.name.to_s
2823
2387
  next if objects_already_processed.include? o
@@ -2859,17 +2423,8 @@ class OSModel
2859
2423
  end
2860
2424
  end
2861
2425
 
2862
- model.getZoneHVACDehumidifierDXs.each do |e|
2863
- next unless e.thermalZone.get.name.to_s == living_zone.name.to_s
2864
-
2865
- intgains_sensors << []
2866
- { 'Zone Dehumidifier Sensible Heating Energy' => 'ig_dehumidifier' }.each do |var, name|
2867
- intgain_dehumidifier = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
2868
- intgain_dehumidifier.setName(name)
2869
- intgain_dehumidifier.setKeyName(e.name.to_s)
2870
- load_adj_sensors[:dehumidifier] = intgain_dehumidifier
2871
- intgains_sensors[-1] << intgain_dehumidifier
2872
- end
2426
+ if not intgain_dehumidifier.nil?
2427
+ intgains_sensors[-1] << intgain_dehumidifier
2873
2428
  end
2874
2429
 
2875
2430
  intgains_dhw_sensors = {}
@@ -2991,27 +2546,6 @@ class OSModel
2991
2546
  end
2992
2547
  end
2993
2548
 
2994
- # EMS program: Total loads
2995
- program.addLine('Set loads_htg_tot = 0')
2996
- program.addLine('Set loads_clg_tot = 0')
2997
- program.addLine("If #{liv_load_sensors[:htg].name} > 0")
2998
- s = " Set loads_htg_tot = #{tot_load_sensors[:htg].name} - #{tot_load_sensors[:clg].name}"
2999
- load_adj_sensors.each do |key, adj_sensor|
3000
- if ['dehumidifier'].include? key.to_s
3001
- s += " - #{adj_sensor.name}"
3002
- end
3003
- end
3004
- program.addLine(s)
3005
- program.addLine("ElseIf #{liv_load_sensors[:clg].name} > 0")
3006
- s = " Set loads_clg_tot = #{tot_load_sensors[:clg].name} - #{tot_load_sensors[:htg].name}"
3007
- load_adj_sensors.each do |key, adj_sensor|
3008
- if ['dehumidifier'].include? key.to_s
3009
- s += " + #{adj_sensor.name}"
3010
- end
3011
- end
3012
- program.addLine(s)
3013
- program.addLine('EndIf')
3014
-
3015
2549
  # EMS calling manager
3016
2550
  program_calling_manager = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
3017
2551
  program_calling_manager.setName("#{program.name} calling manager")
@@ -3019,12 +2553,6 @@ class OSModel
3019
2553
  program_calling_manager.addProgram(program)
3020
2554
  end
3021
2555
 
3022
- def self.set_vacancy(runner, model)
3023
- return if @schedules_file.nil?
3024
-
3025
- @schedules_file.set_vacancy(col_names: ScheduleGenerator.col_names)
3026
- end
3027
-
3028
2556
  def self.add_output_control_files(runner, model)
3029
2557
  return if @debug
3030
2558
 
@@ -3049,396 +2577,6 @@ class OSModel
3049
2577
  oems.setEMSRuntimeLanguageDebugOutputLevel('Verbose')
3050
2578
  end
3051
2579
 
3052
- # FUTURE: Move all of these construction methods to constructions.rb
3053
- def self.calc_non_cavity_r(film_r, constr_set)
3054
- # Calculate R-value for all non-cavity layers
3055
- non_cavity_r = film_r
3056
- if not constr_set.exterior_material.nil?
3057
- non_cavity_r += constr_set.exterior_material.rvalue
3058
- end
3059
- if not constr_set.rigid_r.nil?
3060
- non_cavity_r += constr_set.rigid_r
3061
- end
3062
- if not constr_set.osb_thick_in.nil?
3063
- non_cavity_r += Material.Plywood(constr_set.osb_thick_in).rvalue
3064
- end
3065
- if not constr_set.drywall_thick_in.nil?
3066
- non_cavity_r += Material.GypsumWall(constr_set.drywall_thick_in).rvalue
3067
- end
3068
- return non_cavity_r
3069
- end
3070
-
3071
- def self.apply_wall_construction(runner, model, surfaces, wall, wall_id, wall_type, assembly_r,
3072
- drywall_thick_in, inside_film, outside_film, mat_ext_finish)
3073
-
3074
- film_r = inside_film.rvalue + outside_film.rvalue
3075
- if mat_ext_finish.nil?
3076
- fallback_mat_ext_finish = nil
3077
- else
3078
- fallback_mat_ext_finish = Material.ExteriorFinishMaterial(mat_ext_finish.name, mat_ext_finish.tAbs, mat_ext_finish.sAbs, 0.1)
3079
- end
3080
-
3081
- if wall_type == HPXML::WallTypeWoodStud
3082
- install_grade = 1
3083
- cavity_filled = true
3084
-
3085
- constr_sets = [
3086
- WoodStudConstructionSet.new(Material.Stud2x6, 0.20, 10.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x6, 24" o.c. + R10
3087
- WoodStudConstructionSet.new(Material.Stud2x6, 0.20, 5.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x6, 24" o.c. + R5
3088
- WoodStudConstructionSet.new(Material.Stud2x6, 0.20, 0.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x6, 24" o.c.
3089
- WoodStudConstructionSet.new(Material.Stud2x4, 0.23, 0.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x4, 16" o.c.
3090
- WoodStudConstructionSet.new(Material.Stud2x4, 0.01, 0.0, 0.0, 0.0, fallback_mat_ext_finish), # Fallback
3091
- ]
3092
- match, constr_set, cavity_r = pick_wood_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, wall_id)
3093
-
3094
- Constructions.apply_wood_stud_wall(runner, model, surfaces, wall, "#{wall_id} construction",
3095
- cavity_r, install_grade, constr_set.stud.thick_in,
3096
- cavity_filled, constr_set.framing_factor,
3097
- constr_set.drywall_thick_in, constr_set.osb_thick_in,
3098
- constr_set.rigid_r, constr_set.exterior_material,
3099
- 0, inside_film, outside_film)
3100
- elsif wall_type == HPXML::WallTypeSteelStud
3101
- install_grade = 1
3102
- cavity_filled = true
3103
- corr_factor = 0.45
3104
-
3105
- constr_sets = [
3106
- SteelStudConstructionSet.new(5.5, corr_factor, 0.20, 10.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x6, 24" o.c. + R10
3107
- SteelStudConstructionSet.new(5.5, corr_factor, 0.20, 5.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x6, 24" o.c. + R5
3108
- SteelStudConstructionSet.new(5.5, corr_factor, 0.20, 0.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x6, 24" o.c.
3109
- SteelStudConstructionSet.new(3.5, corr_factor, 0.23, 0.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x4, 16" o.c.
3110
- SteelStudConstructionSet.new(3.5, 1.0, 0.01, 0.0, 0.0, 0.0, fallback_mat_ext_finish), # Fallback
3111
- ]
3112
- match, constr_set, cavity_r = pick_steel_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, wall_id)
3113
-
3114
- Constructions.apply_steel_stud_wall(runner, model, surfaces, wall, "#{wall_id} construction",
3115
- cavity_r, install_grade, constr_set.cavity_thick_in,
3116
- cavity_filled, constr_set.framing_factor,
3117
- constr_set.corr_factor, constr_set.drywall_thick_in,
3118
- constr_set.osb_thick_in, constr_set.rigid_r,
3119
- constr_set.exterior_material, inside_film, outside_film)
3120
- elsif wall_type == HPXML::WallTypeDoubleWoodStud
3121
- install_grade = 1
3122
- is_staggered = false
3123
-
3124
- constr_sets = [
3125
- DoubleStudConstructionSet.new(Material.Stud2x4, 0.23, 24.0, 0.0, 0.5, drywall_thick_in, mat_ext_finish), # 2x4, 24" o.c.
3126
- DoubleStudConstructionSet.new(Material.Stud2x4, 0.01, 16.0, 0.0, 0.0, 0.0, fallback_mat_ext_finish), # Fallback
3127
- ]
3128
- match, constr_set, cavity_r = pick_double_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, wall_id)
3129
-
3130
- Constructions.apply_double_stud_wall(runner, model, surfaces, wall, "#{wall_id} construction",
3131
- cavity_r, install_grade, constr_set.stud.thick_in,
3132
- constr_set.stud.thick_in, constr_set.framing_factor,
3133
- constr_set.framing_spacing, is_staggered,
3134
- constr_set.drywall_thick_in, constr_set.osb_thick_in,
3135
- constr_set.rigid_r, constr_set.exterior_material,
3136
- inside_film, outside_film)
3137
- elsif wall_type == HPXML::WallTypeCMU
3138
- density = 119.0 # lb/ft^3
3139
- furring_r = 0
3140
- furring_cavity_depth_in = 0 # in
3141
- furring_spacing = 0
3142
-
3143
- constr_sets = [
3144
- CMUConstructionSet.new(8.0, 1.4, 0.08, 0.5, drywall_thick_in, mat_ext_finish), # 8" perlite-filled CMU
3145
- CMUConstructionSet.new(6.0, 5.29, 0.01, 0.0, 0.0, fallback_mat_ext_finish), # Fallback (6" hollow CMU)
3146
- ]
3147
- match, constr_set, rigid_r = pick_cmu_construction_set(assembly_r, constr_sets, inside_film, outside_film, wall_id)
3148
-
3149
- Constructions.apply_cmu_wall(runner, model, surfaces, wall, "#{wall_id} construction",
3150
- constr_set.thick_in, constr_set.cond_in, density,
3151
- constr_set.framing_factor, furring_r,
3152
- furring_cavity_depth_in, furring_spacing,
3153
- constr_set.drywall_thick_in, constr_set.osb_thick_in,
3154
- rigid_r, constr_set.exterior_material, inside_film,
3155
- outside_film)
3156
- elsif wall_type == HPXML::WallTypeSIP
3157
- sheathing_thick_in = 0.44
3158
-
3159
- constr_sets = [
3160
- SIPConstructionSet.new(10.0, 0.16, 0.0, sheathing_thick_in, 0.5, drywall_thick_in, mat_ext_finish), # 10" SIP core
3161
- SIPConstructionSet.new(5.0, 0.16, 0.0, sheathing_thick_in, 0.5, drywall_thick_in, mat_ext_finish), # 5" SIP core
3162
- SIPConstructionSet.new(1.0, 0.01, 0.0, sheathing_thick_in, 0.0, 0.0, fallback_mat_ext_finish), # Fallback
3163
- ]
3164
- match, constr_set, cavity_r = pick_sip_construction_set(assembly_r, constr_sets, inside_film, outside_film, wall_id)
3165
-
3166
- Constructions.apply_sip_wall(runner, model, surfaces, wall, "#{wall_id} construction",
3167
- cavity_r, constr_set.thick_in, constr_set.framing_factor,
3168
- constr_set.sheath_thick_in, constr_set.drywall_thick_in,
3169
- constr_set.osb_thick_in, constr_set.rigid_r,
3170
- constr_set.exterior_material, inside_film, outside_film)
3171
- elsif wall_type == HPXML::WallTypeICF
3172
- constr_sets = [
3173
- 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
3174
- ICFConstructionSet.new(1.0, 1.0, 0.01, 0.0, 0.0, 0.0, fallback_mat_ext_finish), # Fallback
3175
- ]
3176
- match, constr_set, icf_r = pick_icf_construction_set(assembly_r, constr_sets, inside_film, outside_film, wall_id)
3177
-
3178
- Constructions.apply_icf_wall(runner, model, surfaces, wall, "#{wall_id} construction",
3179
- icf_r, constr_set.ins_thick_in,
3180
- constr_set.concrete_thick_in, constr_set.framing_factor,
3181
- constr_set.drywall_thick_in, constr_set.osb_thick_in,
3182
- constr_set.rigid_r, constr_set.exterior_material,
3183
- inside_film, outside_film)
3184
- elsif [HPXML::WallTypeConcrete, HPXML::WallTypeBrick, HPXML::WallTypeAdobe, HPXML::WallTypeStrawBale, HPXML::WallTypeStone, HPXML::WallTypeLog].include? wall_type
3185
- constr_sets = [
3186
- GenericConstructionSet.new(10.0, 0.5, drywall_thick_in, mat_ext_finish), # w/R-10 rigid
3187
- GenericConstructionSet.new(0.0, 0.5, drywall_thick_in, mat_ext_finish), # Standard
3188
- GenericConstructionSet.new(0.0, 0.0, 0.0, fallback_mat_ext_finish), # Fallback
3189
- ]
3190
- match, constr_set, layer_r = pick_generic_construction_set(assembly_r, constr_sets, inside_film, outside_film, wall_id)
3191
-
3192
- if wall_type == HPXML::WallTypeConcrete
3193
- thick_in = 6.0
3194
- base_mat = BaseMaterial.Concrete
3195
- elsif wall_type == HPXML::WallTypeBrick
3196
- thick_in = 8.0
3197
- base_mat = BaseMaterial.Brick
3198
- elsif wall_type == HPXML::WallTypeAdobe
3199
- thick_in = 10.0
3200
- base_mat = BaseMaterial.Soil
3201
- elsif wall_type == HPXML::WallTypeStrawBale
3202
- thick_in = 23.0
3203
- base_mat = BaseMaterial.StrawBale
3204
- elsif wall_type == HPXML::WallTypeStone
3205
- thick_in = 6.0
3206
- base_mat = BaseMaterial.Stone
3207
- elsif wall_type == HPXML::WallTypeLog
3208
- thick_in = 6.0
3209
- base_mat = BaseMaterial.Wood
3210
- end
3211
- thick_ins = [thick_in]
3212
- if layer_r == 0
3213
- conds = [99]
3214
- else
3215
- conds = [thick_in / layer_r]
3216
- end
3217
- denss = [base_mat.rho]
3218
- specheats = [base_mat.cp]
3219
-
3220
- Constructions.apply_generic_layered_wall(runner, model, surfaces, wall, "#{wall_id} construction",
3221
- thick_ins, conds, denss, specheats,
3222
- constr_set.drywall_thick_in, constr_set.osb_thick_in,
3223
- constr_set.rigid_r, constr_set.exterior_material,
3224
- inside_film, outside_film)
3225
- else
3226
- fail "Unexpected wall type '#{wall_type}'."
3227
- end
3228
-
3229
- check_surface_assembly_rvalue(runner, surfaces, inside_film, outside_film, assembly_r, match)
3230
- end
3231
-
3232
- def self.pick_wood_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, surface_name)
3233
- # Picks a construction set from supplied constr_sets for which a positive R-value
3234
- # can be calculated for the unknown insulation to achieve the assembly R-value.
3235
-
3236
- constr_sets.each do |constr_set|
3237
- fail 'Unexpected object.' unless constr_set.is_a? WoodStudConstructionSet
3238
-
3239
- film_r = inside_film.rvalue + outside_film.rvalue
3240
- non_cavity_r = calc_non_cavity_r(film_r, constr_set)
3241
-
3242
- # Calculate effective cavity R-value
3243
- # Assumes installation quality 1
3244
- cavity_frac = 1.0 - constr_set.framing_factor
3245
- cavity_r = cavity_frac / (1.0 / assembly_r - constr_set.framing_factor / (constr_set.stud.rvalue + non_cavity_r)) - non_cavity_r
3246
- if cavity_r > 0 # Choose this construction set
3247
- return true, constr_set, cavity_r
3248
- end
3249
- end
3250
-
3251
- return false, constr_sets[-1], 0.0 # Pick fallback construction with minimum R-value
3252
- end
3253
-
3254
- def self.pick_steel_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, surface_name)
3255
- # Picks a construction set from supplied constr_sets for which a positive R-value
3256
- # can be calculated for the unknown insulation to achieve the assembly R-value.
3257
-
3258
- constr_sets.each do |constr_set|
3259
- fail 'Unexpected object.' unless constr_set.is_a? SteelStudConstructionSet
3260
-
3261
- film_r = inside_film.rvalue + outside_film.rvalue
3262
- non_cavity_r = calc_non_cavity_r(film_r, constr_set)
3263
-
3264
- # Calculate effective cavity R-value
3265
- # Assumes installation quality 1
3266
- cavity_r = (assembly_r - non_cavity_r) / constr_set.corr_factor
3267
- if cavity_r > 0 # Choose this construction set
3268
- return true, constr_set, cavity_r
3269
- end
3270
- end
3271
-
3272
- return false, constr_sets[-1], 0.0 # Pick fallback construction with minimum R-value
3273
- end
3274
-
3275
- def self.pick_double_stud_construction_set(assembly_r, constr_sets, inside_film, outside_film, surface_name)
3276
- # Picks a construction set from supplied constr_sets for which a positive R-value
3277
- # can be calculated for the unknown insulation to achieve the assembly R-value.
3278
-
3279
- constr_sets.each do |constr_set|
3280
- fail 'Unexpected object.' unless constr_set.is_a? DoubleStudConstructionSet
3281
-
3282
- film_r = inside_film.rvalue + outside_film.rvalue
3283
- non_cavity_r = calc_non_cavity_r(film_r, constr_set)
3284
-
3285
- # Calculate effective cavity R-value
3286
- # Assumes installation quality 1, not staggered, gap depth == stud depth
3287
- # 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)
3288
- stud_frac = 1.5 / constr_set.framing_spacing
3289
- misc_framing_factor = constr_set.framing_factor - stud_frac
3290
- cavity_frac = 1.0 - (2 * stud_frac + misc_framing_factor)
3291
- a = assembly_r
3292
- b = stud_frac
3293
- c = constr_set.stud.rvalue
3294
- d = non_cavity_r
3295
- e = misc_framing_factor
3296
- 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))
3297
- cavity_r = 3 * cavity_r
3298
- if cavity_r > 0 # Choose this construction set
3299
- return true, constr_set, cavity_r
3300
- end
3301
- end
3302
-
3303
- return false, constr_sets[-1], 0.0 # Pick fallback construction with minimum R-value
3304
- end
3305
-
3306
- def self.pick_sip_construction_set(assembly_r, constr_sets, inside_film, outside_film, surface_name)
3307
- # Picks a construction set from supplied constr_sets for which a positive R-value
3308
- # can be calculated for the unknown insulation to achieve the assembly R-value.
3309
-
3310
- constr_sets.each do |constr_set|
3311
- fail 'Unexpected object.' unless constr_set.is_a? SIPConstructionSet
3312
-
3313
- film_r = inside_film.rvalue + outside_film.rvalue
3314
- non_cavity_r = calc_non_cavity_r(film_r, constr_set)
3315
- non_cavity_r += Material.new(nil, constr_set.sheath_thick_in, BaseMaterial.Wood).rvalue
3316
-
3317
- # Calculate effective SIP core R-value
3318
- # 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)
3319
- spline_thick_in = 0.5 # in
3320
- ins_thick_in = constr_set.thick_in - (2.0 * spline_thick_in) # in
3321
- framing_r = Material.new(nil, constr_set.thick_in, BaseMaterial.Wood).rvalue
3322
- spline_r = Material.new(nil, spline_thick_in, BaseMaterial.Wood).rvalue
3323
- spline_frac = 4.0 / 48.0 # One 4" spline for every 48" wide panel
3324
- cavity_frac = 1.0 - (spline_frac + constr_set.framing_factor)
3325
- a = assembly_r
3326
- b = constr_set.framing_factor
3327
- c = framing_r
3328
- d = non_cavity_r
3329
- e = spline_frac
3330
- f = spline_r
3331
- g = ins_thick_in
3332
- h = constr_set.thick_in
3333
- 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))
3334
- if cavity_r > 0 # Choose this construction set
3335
- return true, constr_set, cavity_r
3336
- end
3337
- end
3338
-
3339
- return false, constr_sets[-1], 0.0 # Pick fallback construction with minimum R-value
3340
- end
3341
-
3342
- def self.pick_cmu_construction_set(assembly_r, constr_sets, inside_film, outside_film, surface_name)
3343
- # Picks a construction set from supplied constr_sets for which a positive R-value
3344
- # can be calculated for the unknown insulation to achieve the assembly R-value.
3345
-
3346
- constr_sets.each do |constr_set|
3347
- fail 'Unexpected object.' unless constr_set.is_a? CMUConstructionSet
3348
-
3349
- film_r = inside_film.rvalue + outside_film.rvalue
3350
- non_cavity_r = calc_non_cavity_r(film_r, constr_set)
3351
-
3352
- # Calculate effective other CMU R-value
3353
- # Assumes no furring strips
3354
- # 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)
3355
- a = assembly_r
3356
- b = constr_set.framing_factor
3357
- c = Material.new(nil, constr_set.thick_in, BaseMaterial.Wood).rvalue # Framing
3358
- d = Material.new(nil, constr_set.thick_in, BaseMaterial.Concrete, constr_set.cond_in).rvalue # Concrete
3359
- e = non_cavity_r
3360
- 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)
3361
- if rigid_r > 0 # Choose this construction set
3362
- return true, constr_set, rigid_r
3363
- end
3364
- end
3365
-
3366
- return false, constr_sets[-1], 0.0 # Pick fallback construction with minimum R-value
3367
- end
3368
-
3369
- def self.pick_icf_construction_set(assembly_r, constr_sets, inside_film, outside_film, surface_name)
3370
- # Picks a construction set from supplied constr_sets for which a positive R-value
3371
- # can be calculated for the unknown insulation to achieve the assembly R-value.
3372
-
3373
- constr_sets.each do |constr_set|
3374
- fail 'Unexpected object.' unless constr_set.is_a? ICFConstructionSet
3375
-
3376
- film_r = inside_film.rvalue + outside_film.rvalue
3377
- non_cavity_r = calc_non_cavity_r(film_r, constr_set)
3378
-
3379
- # Calculate effective ICF rigid ins R-value
3380
- # 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)
3381
- a = assembly_r
3382
- b = constr_set.framing_factor
3383
- c = Material.new(nil, 2 * constr_set.ins_thick_in + constr_set.concrete_thick_in, BaseMaterial.Wood).rvalue # Framing
3384
- d = Material.new(nil, constr_set.concrete_thick_in, BaseMaterial.Concrete).rvalue # Concrete
3385
- e = non_cavity_r
3386
- 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))
3387
- if icf_r > 0 # Choose this construction set
3388
- return true, constr_set, icf_r
3389
- end
3390
- end
3391
-
3392
- return false, constr_sets[-1], 0.0 # Pick fallback construction with minimum R-value
3393
- end
3394
-
3395
- def self.pick_generic_construction_set(assembly_r, constr_sets, inside_film, outside_film, surface_name)
3396
- # Picks a construction set from supplied constr_sets for which a positive R-value
3397
- # can be calculated for the unknown insulation to achieve the assembly R-value.
3398
-
3399
- constr_sets.each do |constr_set|
3400
- fail 'Unexpected object.' unless constr_set.is_a? GenericConstructionSet
3401
-
3402
- film_r = inside_film.rvalue + outside_film.rvalue
3403
- non_cavity_r = calc_non_cavity_r(film_r, constr_set)
3404
-
3405
- # Calculate effective ins layer R-value
3406
- layer_r = assembly_r - non_cavity_r
3407
- if layer_r > 0 # Choose this construction set
3408
- return true, constr_set, layer_r
3409
- end
3410
- end
3411
-
3412
- return false, constr_sets[-1], 0.0 # Pick fallback construction with minimum R-value
3413
- end
3414
-
3415
- def self.check_surface_assembly_rvalue(runner, surfaces, inside_film, outside_film, assembly_r, match)
3416
- # Verify that the actual OpenStudio construction R-value matches our target assembly R-value
3417
-
3418
- film_r = 0.0
3419
- film_r += inside_film.rvalue unless inside_film.nil?
3420
- film_r += outside_film.rvalue unless outside_film.nil?
3421
- surfaces.each do |surface|
3422
- constr_r = UnitConversions.convert(1.0 / surface.construction.get.uFactor(0.0).get, 'm^2*k/w', 'hr*ft^2*f/btu') + film_r
3423
-
3424
- if surface.adjacentFoundation.is_initialized
3425
- foundation = surface.adjacentFoundation.get
3426
- foundation.customBlocks.each do |custom_block|
3427
- ins_mat = custom_block.material.to_StandardOpaqueMaterial.get
3428
- constr_r += UnitConversions.convert(ins_mat.thickness, 'm', 'ft') / UnitConversions.convert(ins_mat.thermalConductivity, 'W/(m*K)', 'Btu/(hr*ft*R)')
3429
- end
3430
- end
3431
-
3432
- if (assembly_r - constr_r).abs > 0.1
3433
- if match
3434
- fail "Construction R-value (#{constr_r}) does not match Assembly R-value (#{assembly_r}) for '#{surface.name}'."
3435
- else
3436
- runner.registerWarning("Assembly R-value (#{assembly_r}) for '#{surface.name}' below minimum expected value. Construction R-value increased to #{constr_r.round(2)}.")
3437
- end
3438
- end
3439
- end
3440
- end
3441
-
3442
2580
  def self.set_surface_interior(model, spaces, surface, hpxml_surface)
3443
2581
  interior_adjacent_to = hpxml_surface.interior_adjacent_to
3444
2582
  if [HPXML::LocationBasementConditioned].include? interior_adjacent_to
@@ -3464,7 +2602,7 @@ class OSModel
3464
2602
  set_surface_otherside_coefficients(surface, exterior_adjacent_to, model, spaces)
3465
2603
  elsif exterior_adjacent_to == HPXML::LocationBasementConditioned
3466
2604
  surface.createAdjacentSurface(create_or_get_space(model, spaces, HPXML::LocationLivingSpace))
3467
- @cond_bsmnt_surfaces << surface
2605
+ @cond_bsmnt_surfaces << surface.adjacentSurface.get
3468
2606
  else
3469
2607
  surface.createAdjacentSurface(create_or_get_space(model, spaces, exterior_adjacent_to))
3470
2608
  end
@@ -3606,9 +2744,7 @@ class OSModel
3606
2744
  space = create_or_get_space(model, spaces, location)
3607
2745
  end
3608
2746
 
3609
- if spaces.size != num_orig_spaces
3610
- fail "#{object_name} location is '#{location}' but building does not have this location specified."
3611
- end
2747
+ fail if spaces.size != num_orig_spaces # EPvalidator.xml should prevent this
3612
2748
 
3613
2749
  return space
3614
2750
  end
@@ -3625,19 +2761,6 @@ class OSModel
3625
2761
  end
3626
2762
  end
3627
2763
 
3628
- def self.get_min_neighbor_distance()
3629
- min_neighbor_distance = nil
3630
- @hpxml.neighbor_buildings.each do |neighbor_building|
3631
- if min_neighbor_distance.nil?
3632
- min_neighbor_distance = 9e99
3633
- end
3634
- if neighbor_building.distance < min_neighbor_distance
3635
- min_neighbor_distance = neighbor_building.distance
3636
- end
3637
- end
3638
- return min_neighbor_distance
3639
- end
3640
-
3641
2764
  def self.get_kiva_instances(fnd_walls, slabs)
3642
2765
  # Identify unique Kiva foundations that are required.
3643
2766
  kiva_fnd_walls = []
@@ -3665,93 +2788,5 @@ class OSModel
3665
2788
  end
3666
2789
  end
3667
2790
 
3668
- # FUTURE: Move all of these construction classes to constructions.rb
3669
- class WoodStudConstructionSet
3670
- def initialize(stud, framing_factor, rigid_r, osb_thick_in, drywall_thick_in, exterior_material)
3671
- @stud = stud
3672
- @framing_factor = framing_factor
3673
- @rigid_r = rigid_r
3674
- @osb_thick_in = osb_thick_in
3675
- @drywall_thick_in = drywall_thick_in
3676
- @exterior_material = exterior_material
3677
- end
3678
- attr_accessor(:stud, :framing_factor, :rigid_r, :osb_thick_in, :drywall_thick_in, :exterior_material)
3679
- end
3680
-
3681
- class SteelStudConstructionSet
3682
- def initialize(cavity_thick_in, corr_factor, framing_factor, rigid_r, osb_thick_in, drywall_thick_in, exterior_material)
3683
- @cavity_thick_in = cavity_thick_in
3684
- @corr_factor = corr_factor
3685
- @framing_factor = framing_factor
3686
- @rigid_r = rigid_r
3687
- @osb_thick_in = osb_thick_in
3688
- @drywall_thick_in = drywall_thick_in
3689
- @exterior_material = exterior_material
3690
- end
3691
- attr_accessor(:cavity_thick_in, :corr_factor, :framing_factor, :rigid_r, :osb_thick_in, :drywall_thick_in, :exterior_material)
3692
- end
3693
-
3694
- class DoubleStudConstructionSet
3695
- def initialize(stud, framing_factor, framing_spacing, rigid_r, osb_thick_in, drywall_thick_in, exterior_material)
3696
- @stud = stud
3697
- @framing_factor = framing_factor
3698
- @framing_spacing = framing_spacing
3699
- @rigid_r = rigid_r
3700
- @osb_thick_in = osb_thick_in
3701
- @drywall_thick_in = drywall_thick_in
3702
- @exterior_material = exterior_material
3703
- end
3704
- attr_accessor(:stud, :framing_factor, :framing_spacing, :rigid_r, :osb_thick_in, :drywall_thick_in, :exterior_material)
3705
- end
3706
-
3707
- class SIPConstructionSet
3708
- def initialize(thick_in, framing_factor, rigid_r, sheath_thick_in, osb_thick_in, drywall_thick_in, exterior_material)
3709
- @thick_in = thick_in
3710
- @framing_factor = framing_factor
3711
- @rigid_r = rigid_r
3712
- @sheath_thick_in = sheath_thick_in
3713
- @osb_thick_in = osb_thick_in
3714
- @drywall_thick_in = drywall_thick_in
3715
- @exterior_material = exterior_material
3716
- end
3717
- attr_accessor(:thick_in, :framing_factor, :rigid_r, :sheath_thick_in, :osb_thick_in, :drywall_thick_in, :exterior_material)
3718
- end
3719
-
3720
- class CMUConstructionSet
3721
- def initialize(thick_in, cond_in, framing_factor, osb_thick_in, drywall_thick_in, exterior_material)
3722
- @thick_in = thick_in
3723
- @cond_in = cond_in
3724
- @framing_factor = framing_factor
3725
- @osb_thick_in = osb_thick_in
3726
- @drywall_thick_in = drywall_thick_in
3727
- @exterior_material = exterior_material
3728
- @rigid_r = nil # solved for
3729
- end
3730
- attr_accessor(:thick_in, :cond_in, :framing_factor, :rigid_r, :osb_thick_in, :drywall_thick_in, :exterior_material)
3731
- end
3732
-
3733
- class ICFConstructionSet
3734
- def initialize(ins_thick_in, concrete_thick_in, framing_factor, rigid_r, osb_thick_in, drywall_thick_in, exterior_material)
3735
- @ins_thick_in = ins_thick_in
3736
- @concrete_thick_in = concrete_thick_in
3737
- @framing_factor = framing_factor
3738
- @rigid_r = rigid_r
3739
- @osb_thick_in = osb_thick_in
3740
- @drywall_thick_in = drywall_thick_in
3741
- @exterior_material = exterior_material
3742
- end
3743
- attr_accessor(:ins_thick_in, :concrete_thick_in, :framing_factor, :rigid_r, :osb_thick_in, :drywall_thick_in, :exterior_material)
3744
- end
3745
-
3746
- class GenericConstructionSet
3747
- def initialize(rigid_r, osb_thick_in, drywall_thick_in, exterior_material)
3748
- @rigid_r = rigid_r
3749
- @osb_thick_in = osb_thick_in
3750
- @drywall_thick_in = drywall_thick_in
3751
- @exterior_material = exterior_material
3752
- end
3753
- attr_accessor(:rigid_r, :osb_thick_in, :drywall_thick_in, :exterior_material)
3754
- end
3755
-
3756
2791
  # register the measure to be used by the application
3757
2792
  HPXMLtoOpenStudio.new.registerWithApplication