urbanopt-cli 0.5.1 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
@@ -1,64 +1,54 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  class HVACSizing
4
- def self.apply(model, runner, weather, spaces, hpxml, infilvolume, nbeds, min_neighbor_distance, debug)
5
- @runner = runner
6
- @hpxml = hpxml
7
- @spaces = spaces
8
- @cond_zone = spaces[HPXML::LocationLivingSpace].thermalZone.get
9
-
10
- @conditioned_heat_design_temp = 70.0 # Indoor heating design temperature according to ACCA MANUAL J
11
- @conditioned_cool_design_temp = 75.0 # Indoor cooling design temperature according to ACCA MANUAL J
12
-
13
- @min_cooling_capacity = 1.0 # Btu/hr
14
-
15
- # Based on EnergyPlus's model for calculating SHR at off-rated conditions. This curve fit
16
- # avoids the iterations in the actual model. It does not account for altitude or variations
17
- # in the SHRRated. It is a function of ODB (MJ design temp) and CFM/Ton (from MJ)
18
- @shr_biquadratic = [1.08464364, 0.002096954, 0, -0.005766327, 0, -0.000011147]
4
+ def self.calculate(weather, hpxml, cfa, nbeds, hvac_systems)
5
+ # Calculates heating/cooling design loads, and selects equipment
6
+ # values (e.g., capacities, airflows) specific to each HVAC system.
7
+ # Calculations generally follow ACCA Manual J/S.
19
8
 
20
- # Inside air density
21
- @inside_air_dens = UnitConversions.convert(weather.header.LocalPressure, 'atm', 'Btu/ft^3') / (Gas.Air.r * (Constants.AssumedInsideTemp + 460.0))
9
+ @hpxml = hpxml
22
10
 
23
11
  process_site_calcs_and_design_temps(weather)
24
12
 
25
- # Get shelter class
26
- @shelter_class = get_shelter_class(model, min_neighbor_distance)
27
-
28
13
  # Calculate loads for the conditioned thermal zone
29
- zone_loads = process_zone_loads(model, weather, nbeds, infilvolume)
30
-
31
- # Display debug info
32
- display_zone_loads(zone_loads) if debug
14
+ bldg_design_loads = DesignLoads.new
15
+ process_load_windows_skylights(bldg_design_loads, weather)
16
+ process_load_doors(bldg_design_loads, weather)
17
+ process_load_walls(bldg_design_loads, weather)
18
+ process_load_roofs(bldg_design_loads, weather)
19
+ process_load_ceilings(bldg_design_loads, weather)
20
+ process_load_floors(bldg_design_loads, weather)
21
+ process_load_slabs(bldg_design_loads, weather)
22
+ process_load_infiltration_ventilation(bldg_design_loads, weather, cfa)
23
+ process_load_internal_gains(bldg_design_loads, nbeds)
33
24
 
34
25
  # Aggregate zone loads into initial loads
35
- init_loads = aggregate_zone_loads(zone_loads)
36
-
37
- # Get HVAC system info
38
- hvacs = get_hvacs(model)
26
+ aggregate_loads(bldg_design_loads)
39
27
 
40
- hvacs.each do |hvac|
41
- # Init
42
- hvac_init_loads = init_loads.dup
43
- calculate_hvac_temperatures(hvac_init_loads, hvac)
44
- apply_hvac_load_fractions(hvac_init_loads, hvac)
45
- apply_hp_sizing_logic(hvac_init_loads, hvac)
28
+ # Loop through each HVAC system
29
+ all_hvac_sizing_values = {}
30
+ hvac_systems.each do |hvac_system|
31
+ hvac = get_hvac_information(hvac_system)
46
32
 
47
- # Calculate final HVAC capacity/airflow
48
- hvac_final_values = FinalValues.new
49
- process_duct_loads_heating(hvac_final_values, weather, hvac, hvac_init_loads.Heat)
50
- process_duct_loads_cooling(hvac_final_values, weather, hvac, hvac_init_loads.Cool_Sens, hvac_init_loads.Cool_Lat)
51
- process_equipment_adjustments(hvac_final_values, weather, hvac)
52
- process_fixed_equipment(hvac_final_values, hvac)
53
- process_ground_loop(hvac_final_values, weather, hvac)
54
- process_finalize(hvac_final_values, zone_loads, weather, hvac)
33
+ # Add duct losses
34
+ apply_hvac_temperatures(hvac, bldg_design_loads)
35
+ apply_load_ducts_heating(bldg_design_loads, weather, hvac)
36
+ apply_load_ducts_cooling(bldg_design_loads, weather, hvac)
55
37
 
56
- # Set OpenStudio object values
57
- set_object_values(model, hvac, hvac_final_values)
38
+ # Calculate equipment values
39
+ hvac_sizing_values = HVACSizingValues.new
40
+ apply_hvac_loads(hvac, hvac_sizing_values, bldg_design_loads)
41
+ apply_hvac_heat_pump_logic(hvac_sizing_values, hvac)
42
+ apply_hvac_equipment_adjustments(hvac_sizing_values, weather, hvac, cfa)
43
+ apply_hvac_installation_quality(hvac_sizing_values, weather, hvac)
44
+ apply_hvac_fixed_capacities(hvac_sizing_values, hvac)
45
+ apply_hvac_ground_loop(hvac_sizing_values, weather, hvac)
46
+ apply_hvac_finalize_airflows(hvac_sizing_values, weather, hvac)
58
47
 
59
- # Display debug info
60
- display_hvac_final_values_results(hvac_final_values, hvac) if debug
48
+ all_hvac_sizing_values[hvac_system] = hvac_sizing_values
61
49
  end
50
+
51
+ return bldg_design_loads, all_hvac_sizing_values
62
52
  end
63
53
 
64
54
  private
@@ -72,8 +62,8 @@ class HVACSizing
72
62
  @daily_range_temp_adjust = [4, 0, -5]
73
63
 
74
64
  # Manual J inside conditions
75
- @cool_setpoint = 75
76
- @heat_setpoint = 70
65
+ @cool_setpoint = 75.0
66
+ @heat_setpoint = 70.0
77
67
 
78
68
  @cool_design_grains = UnitConversions.convert(weather.design.CoolingHumidityRatio, 'lbm/lbm', 'grains')
79
69
 
@@ -110,31 +100,49 @@ class HVACSizing
110
100
  @enthalpy_indoor_cooling = (1.006 * db_indoor_degC + hr_indoor_cooling * (2501.0 + 1.86 * db_indoor_degC)) * UnitConversions.convert(1.0, 'kJ', 'Btu') * UnitConversions.convert(1.0, 'lbm', 'kg')
111
101
  @wetbulb_outdoor_cooling = weather.design.CoolingWetbulb
112
102
 
103
+ # Inside air density
104
+ avg_setpoint = (@cool_setpoint + @heat_setpoint) / 2.0
105
+ @inside_air_dens = UnitConversions.convert(weather.header.LocalPressure, 'atm', 'Btu/ft^3') / (Gas.Air.r * (avg_setpoint + 460.0))
106
+
113
107
  # Design Temperatures
114
108
 
115
109
  @cool_design_temps = {}
116
110
  @heat_design_temps = {}
117
111
 
118
- @cool_design_temps[HPXML::LocationOutside] = weather.design.CoolingDrybulb
119
- @heat_design_temps[HPXML::LocationOutside] = weather.design.HeatingDrybulb
120
-
121
- [HPXML::LocationOtherHousingUnit, HPXML::LocationOtherHeatedSpace, HPXML::LocationOtherMultifamilyBufferSpace,
122
- HPXML::LocationOtherNonFreezingSpace, HPXML::LocationExteriorWall, HPXML::LocationUnderSlab].each do |space_type|
123
- @heat_design_temps[space_type] = calculate_scheduled_space_design_temps(space_type, @heat_setpoint, weather.design.HeatingDrybulb, weather.data.GroundMonthlyTemps.min)
124
- @cool_design_temps[space_type] = calculate_scheduled_space_design_temps(space_type, @cool_setpoint, weather.design.CoolingDrybulb, weather.data.GroundMonthlyTemps.max)
112
+ space_types = []
113
+ (@hpxml.roofs + @hpxml.rim_joists + @hpxml.walls + @hpxml.foundation_walls + @hpxml.frame_floors + @hpxml.slabs).each do |surface|
114
+ space_types << surface.interior_adjacent_to
115
+ space_types << surface.exterior_adjacent_to
116
+ end
117
+ @hpxml.hvac_distributions.each do |hvac_dist|
118
+ hvac_dist.ducts.each do |duct|
119
+ space_types << duct.duct_location
120
+ end
125
121
  end
126
122
 
127
- @spaces.each do |space_type, space|
128
- next unless space.is_a? OpenStudio::Model::Space
123
+ space_types.uniq.each do |space_type|
124
+ next if [HPXML::LocationGround].include? space_type
129
125
 
130
- @cool_design_temps[space_type] = process_design_temp_cooling(weather, space_type)
131
- @heat_design_temps[space_type] = process_design_temp_heating(weather, space_type)
126
+ if [HPXML::LocationOtherHousingUnit, HPXML::LocationOtherHeatedSpace, HPXML::LocationOtherMultifamilyBufferSpace,
127
+ HPXML::LocationOtherNonFreezingSpace, HPXML::LocationExteriorWall, HPXML::LocationUnderSlab].include? space_type
128
+ @cool_design_temps[space_type] = calculate_scheduled_space_design_temps(space_type, @cool_setpoint, weather.design.CoolingDrybulb, weather.data.GroundMonthlyTemps.max)
129
+ @heat_design_temps[space_type] = calculate_scheduled_space_design_temps(space_type, @heat_setpoint, weather.design.HeatingDrybulb, weather.data.GroundMonthlyTemps.min)
130
+ elsif [HPXML::LocationOutside, HPXML::LocationRoofDeck].include? space_type
131
+ @cool_design_temps[space_type] = weather.design.CoolingDrybulb
132
+ @heat_design_temps[space_type] = weather.design.HeatingDrybulb
133
+ elsif space_type == HPXML::LocationBasementConditioned
134
+ @cool_design_temps[space_type] = process_design_temp_cooling(weather, HPXML::LocationLivingSpace)
135
+ @heat_design_temps[space_type] = process_design_temp_heating(weather, HPXML::LocationLivingSpace)
136
+ else
137
+ @cool_design_temps[space_type] = process_design_temp_cooling(weather, space_type)
138
+ @heat_design_temps[space_type] = process_design_temp_heating(weather, space_type)
139
+ end
132
140
  end
133
141
  end
134
142
 
135
143
  def self.process_design_temp_heating(weather, space_type)
136
144
  if space_type == HPXML::LocationLivingSpace
137
- heat_temp = @conditioned_heat_design_temp
145
+ heat_temp = @heat_setpoint
138
146
 
139
147
  elsif space_type == HPXML::LocationGarage
140
148
  heat_temp = weather.design.HeatingDrybulb + 13.0
@@ -153,14 +161,14 @@ class HVACSizing
153
161
  if space_type == HPXML::LocationAtticVented
154
162
  heat_temp = weather.design.HeatingDrybulb
155
163
  else
156
- heat_temp = calculate_space_design_temps(space_type, weather, @conditioned_heat_design_temp, weather.design.HeatingDrybulb, weather.data.GroundMonthlyTemps.min)
164
+ heat_temp = calculate_space_design_temps(space_type, weather, @heat_setpoint, weather.design.HeatingDrybulb, weather.data.GroundMonthlyTemps.min)
157
165
  end
158
166
  else
159
167
  heat_temp = weather.design.HeatingDrybulb
160
168
  end
161
169
 
162
170
  elsif [HPXML::LocationBasementUnconditioned, HPXML::LocationCrawlspaceUnvented, HPXML::LocationCrawlspaceVented].include? space_type
163
- heat_temp = calculate_space_design_temps(space_type, weather, @conditioned_heat_design_temp, weather.design.HeatingDrybulb, weather.data.GroundMonthlyTemps.min)
171
+ heat_temp = calculate_space_design_temps(space_type, weather, @heat_setpoint, weather.design.HeatingDrybulb, weather.data.GroundMonthlyTemps.min)
164
172
 
165
173
  end
166
174
 
@@ -171,7 +179,7 @@ class HVACSizing
171
179
 
172
180
  def self.process_design_temp_cooling(weather, space_type)
173
181
  if space_type == HPXML::LocationLivingSpace
174
- cool_temp = @conditioned_cool_design_temp
182
+ cool_temp = @cool_setpoint
175
183
 
176
184
  elsif space_type == HPXML::LocationGarage
177
185
  # Calculate fraction of garage under conditioned space
@@ -188,7 +196,11 @@ class HVACSizing
188
196
  area_total += frame_floor.area
189
197
  area_conditioned += frame_floor.area if frame_floor.is_thermal_boundary
190
198
  end
191
- garage_frac_under_conditioned = area_conditioned / area_total
199
+ if area_total == 0
200
+ garage_frac_under_conditioned = 0.5
201
+ else
202
+ garage_frac_under_conditioned = area_conditioned / area_total
203
+ end
192
204
 
193
205
  # Calculate the garage cooling design temperature based on Table 4C
194
206
  # Linearly interpolate between having living space over the garage and not having living space above the garage
@@ -220,7 +232,7 @@ class HVACSizing
220
232
  if space_type == HPXML::LocationAtticVented
221
233
  cool_temp = weather.design.CoolingDrybulb + 40.0 # This is the number from a California study with dark shingle roof and similar ventilation.
222
234
  else
223
- cool_temp = calculate_space_design_temps(space_type, weather, @conditioned_cool_design_temp, weather.design.CoolingDrybulb, weather.data.GroundMonthlyTemps.max, true)
235
+ cool_temp = calculate_space_design_temps(space_type, weather, @cool_setpoint, weather.design.CoolingDrybulb, weather.data.GroundMonthlyTemps.max, true)
224
236
  end
225
237
 
226
238
  else
@@ -304,7 +316,7 @@ class HVACSizing
304
316
  end
305
317
 
306
318
  elsif [HPXML::LocationBasementUnconditioned, HPXML::LocationCrawlspaceUnvented, HPXML::LocationCrawlspaceVented].include? space_type
307
- cool_temp = calculate_space_design_temps(space_type, weather, @conditioned_cool_design_temp, weather.design.CoolingDrybulb, weather.data.GroundMonthlyTemps.max)
319
+ cool_temp = calculate_space_design_temps(space_type, weather, @cool_setpoint, weather.design.CoolingDrybulb, weather.data.GroundMonthlyTemps.max)
308
320
 
309
321
  end
310
322
 
@@ -313,20 +325,7 @@ class HVACSizing
313
325
  return cool_temp
314
326
  end
315
327
 
316
- def self.process_zone_loads(model, weather, nbeds, infilvolume)
317
- # Constant loads (no variation throughout day)
318
- zone_loads = ZoneLoads.new
319
- zone_loads = process_load_windows_skylights(zone_loads, weather)
320
- zone_loads = process_load_doors(zone_loads, weather)
321
- zone_loads = process_load_walls(zone_loads, weather)
322
- zone_loads = process_load_roofs(zone_loads, weather)
323
- zone_loads = process_load_floors(zone_loads, weather)
324
- zone_loads = process_infiltration_ventilation(model, zone_loads, weather, infilvolume)
325
- zone_loads = process_internal_gains(zone_loads, nbeds)
326
- return zone_loads
327
- end
328
-
329
- def self.process_load_windows_skylights(zone_loads, weather)
328
+ def self.process_load_windows_skylights(bldg_design_loads, weather)
330
329
  '''
331
330
  Heating and Cooling Loads: Windows & Skylights
332
331
  '''
@@ -436,13 +435,11 @@ class HVACSizing
436
435
  if latitude < 20.0
437
436
  psf_lat << psf[cnt][0]
438
437
  if cnt == 0
439
- @runner.registerWarning('Latitude of 20 was assumed for Manual J solar load calculations.')
440
438
  psf_lat_horiz = psf_horiz[0]
441
439
  end
442
440
  elsif latitude >= 64.0
443
441
  psf_lat << psf[cnt][11]
444
442
  if cnt == 0
445
- @runner.registerWarning('Latitude of 64 was assumed for Manual J solar load calculations.') if latitude > 64.0
446
443
  psf_lat_horiz = psf_horiz[11]
447
444
  end
448
445
  else
@@ -458,17 +455,18 @@ class HVACSizing
458
455
  end
459
456
 
460
457
  # Windows
461
- zone_loads.Heat_Windows = 0.0
458
+ bldg_design_loads.Heat_Windows = 0.0
462
459
  alp_load = 0.0 # Average Load Procedure (ALP) Load
463
460
  afl_hr = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] # Initialize Hourly Aggregate Fenestration Load (AFL)
464
461
 
465
462
  @hpxml.windows.each do |window|
466
463
  next unless window.wall.is_exterior_thermal_boundary
467
464
 
465
+ window_summer_sf = window.interior_shading_factor_summer * window.exterior_shading_factor_summer
468
466
  window_true_azimuth = get_true_azimuth(window.azimuth)
469
467
  cnt225 = (window_true_azimuth / 22.5).round.to_i
470
468
 
471
- zone_loads.Heat_Windows += window.ufactor * window.area * @htd
469
+ bldg_design_loads.Heat_Windows += window.ufactor * window.area * @htd
472
470
 
473
471
  for hr in -1..12
474
472
 
@@ -478,7 +476,7 @@ class HVACSizing
478
476
  # clf_d: Average Cooling Load Factor for the given window direction
479
477
  # clf_n: Average Cooling Load Factor for a window facing North (fully shaded)
480
478
  if hr == -1
481
- if window.interior_shading_factor_summer < 1
479
+ if window_summer_sf < 1
482
480
  clf_d = clf_avg_is[cnt225]
483
481
  clf_n = clf_avg_is[8]
484
482
  else
@@ -486,7 +484,7 @@ class HVACSizing
486
484
  clf_n = clf_avg_nois[8]
487
485
  end
488
486
  else
489
- if window.interior_shading_factor_summer < 1
487
+ if window_summer_sf < 1
490
488
  clf_d = clf_hr_is[cnt225][hr]
491
489
  clf_n = clf_hr_is[8][hr]
492
490
  else
@@ -502,10 +500,10 @@ class HVACSizing
502
500
  end
503
501
 
504
502
  # Hourly Heat Transfer Multiplier for the given window Direction
505
- htm_d = psf_lat[cnt225] * clf_d * window.shgc * window.interior_shading_factor_summer / 0.87 + window.ufactor * ctd_adj
503
+ htm_d = psf_lat[cnt225] * clf_d * window.shgc * window_summer_sf / 0.87 + window.ufactor * ctd_adj
506
504
 
507
505
  # Hourly Heat Transfer Multiplier for a window facing North (fully shaded)
508
- htm_n = psf_lat[8] * clf_n * window.shgc * window.interior_shading_factor_summer / 0.87 + window.ufactor * ctd_adj
506
+ htm_n = psf_lat[8] * clf_n * window.shgc * window_summer_sf / 0.87 + window.ufactor * ctd_adj
509
507
 
510
508
  if window_true_azimuth < 180
511
509
  surf_azimuth = window_true_azimuth
@@ -513,7 +511,7 @@ class HVACSizing
513
511
  surf_azimuth = window_true_azimuth - 360.0
514
512
  end
515
513
 
516
- if not window.overhangs_depth.nil?
514
+ if (not window.overhangs_depth.nil?) && (window.overhangs_depth > 0)
517
515
  if ((hr == -1) && (surf_azimuth.abs < 90.1)) || (hr > -1)
518
516
  if hr == -1
519
517
  actual_hr = slm_alp_hr[cnt225]
@@ -586,19 +584,20 @@ class HVACSizing
586
584
  eal = [0.0, pfl - ell].max
587
585
 
588
586
  # Window Cooling Load
589
- zone_loads.Cool_Windows = alp_load + eal
587
+ bldg_design_loads.Cool_Windows = alp_load + eal
590
588
 
591
589
  # Skylights
592
- zone_loads.Heat_Skylights = 0.0
590
+ bldg_design_loads.Heat_Skylights = 0.0
593
591
  alp_load = 0.0 # Average Load Procedure (ALP) Load
594
592
  afl_hr = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] # Initialize Hourly Aggregate Fenestration Load (AFL)
595
593
 
596
594
  @hpxml.skylights.each do |skylight|
595
+ skylight_summer_sf = skylight.interior_shading_factor_summer * skylight.exterior_shading_factor_summer
597
596
  skylight_true_azimuth = get_true_azimuth(skylight.azimuth)
598
597
  cnt225 = (skylight_true_azimuth / 22.5).round.to_i
599
598
  inclination_angle = UnitConversions.convert(Math.atan(skylight.roof.pitch / 12.0), 'rad', 'deg')
600
599
 
601
- zone_loads.Heat_Skylights += skylight.ufactor * skylight.area * @htd
600
+ bldg_design_loads.Heat_Skylights += skylight.ufactor * skylight.area * @htd
602
601
 
603
602
  for hr in -1..12
604
603
 
@@ -608,7 +607,7 @@ class HVACSizing
608
607
  # clf_d: Average Cooling Load Factor for the given skylight direction
609
608
  # clf_d: Average Cooling Load Factor for horizontal
610
609
  if hr == -1
611
- if skylight.interior_shading_factor_summer < 1
610
+ if skylight_summer_sf < 1
612
611
  clf_d = clf_avg_is[cnt225]
613
612
  clf_horiz = clf_avg_is_horiz
614
613
  else
@@ -616,7 +615,7 @@ class HVACSizing
616
615
  clf_horiz = clf_avg_nois_horiz
617
616
  end
618
617
  else
619
- if skylight.interior_shading_factor_summer < 1
618
+ if skylight_summer_sf < 1
620
619
  clf_d = clf_hr_is[cnt225][hr]
621
620
  clf_horiz = clf_hr_is_horiz[hr]
622
621
  else
@@ -638,7 +637,7 @@ class HVACSizing
638
637
  u_curb = 0.51 # default to wood (Table 2B-3)
639
638
  ar_curb = 0.35 # default to small (Table 2B-3)
640
639
  u_eff_skylight = skylight.ufactor + u_curb * ar_curb
641
- htm = (sol_h + sol_v) * (skylight.shgc * skylight.interior_shading_factor_summer / 0.87) + u_eff_skylight * (ctd_adj + 15.0)
640
+ htm = (sol_h + sol_v) * (skylight.shgc * skylight_summer_sf / 0.87) + u_eff_skylight * (ctd_adj + 15.0)
642
641
 
643
642
  if hr == -1
644
643
  alp_load += htm * skylight.area
@@ -661,12 +660,10 @@ class HVACSizing
661
660
  eal = [0.0, pfl - ell].max
662
661
 
663
662
  # Skylight Cooling Load
664
- zone_loads.Cool_Skylights = alp_load + eal
665
-
666
- return zone_loads
663
+ bldg_design_loads.Cool_Skylights = alp_load + eal
667
664
  end
668
665
 
669
- def self.process_load_doors(zone_loads, weather)
666
+ def self.process_load_doors(bldg_design_loads, weather)
670
667
  '''
671
668
  Heating and Cooling Loads: Doors
672
669
  '''
@@ -679,32 +676,30 @@ class HVACSizing
679
676
  cltd = @ctd + 6.0
680
677
  end
681
678
 
682
- zone_loads.Heat_Doors = 0.0
683
- zone_loads.Cool_Doors = 0.0
679
+ bldg_design_loads.Heat_Doors = 0.0
680
+ bldg_design_loads.Cool_Doors = 0.0
684
681
 
685
682
  @hpxml.doors.each do |door|
686
683
  next unless door.is_thermal_boundary
687
684
 
688
685
  if door.wall.is_exterior
689
- zone_loads.Heat_Doors += (1.0 / door.r_value) * door.area * @htd
690
- zone_loads.Cool_Doors += (1.0 / door.r_value) * door.area * cltd
691
- else
686
+ bldg_design_loads.Heat_Doors += (1.0 / door.r_value) * door.area * @htd
687
+ bldg_design_loads.Cool_Doors += (1.0 / door.r_value) * door.area * cltd
688
+ else # Partition door
692
689
  adjacent_space = door.wall.exterior_adjacent_to
693
- zone_loads.Cool_Doors += (1.0 / door.r_value) * door.area * (@cool_design_temps[adjacent_space] - @cool_setpoint)
694
- zone_loads.Heat_Doors += (1.0 / door.r_value) * door.area * (@heat_setpoint - @heat_design_temps[adjacent_space])
690
+ bldg_design_loads.Cool_Doors += (1.0 / door.r_value) * door.area * (@cool_design_temps[adjacent_space] - @cool_setpoint)
691
+ bldg_design_loads.Heat_Doors += (1.0 / door.r_value) * door.area * (@heat_setpoint - @heat_design_temps[adjacent_space])
695
692
  end
696
693
  end
697
-
698
- return zone_loads
699
694
  end
700
695
 
701
- def self.process_load_walls(zone_loads, weather)
696
+ def self.process_load_walls(bldg_design_loads, weather)
702
697
  '''
703
698
  Heating and Cooling Loads: Walls
704
699
  '''
705
700
 
706
- zone_loads.Heat_Walls = 0.0
707
- zone_loads.Cool_Walls = 0.0
701
+ bldg_design_loads.Heat_Walls = 0.0
702
+ bldg_design_loads.Cool_Walls = 0.0
708
703
 
709
704
  # Above-Grade Walls
710
705
  (@hpxml.walls + @hpxml.rim_joists).each do |wall|
@@ -762,12 +757,12 @@ class HVACSizing
762
757
  cltd = [cltd + cltd_corr, 0.0].max # Assume zero cooling load for negative CLTD's
763
758
  end
764
759
 
765
- zone_loads.Cool_Walls += (1.0 / wall.insulation_assembly_r_value) * wall_area / azimuths.size * cltd
766
- zone_loads.Heat_Walls += (1.0 / wall.insulation_assembly_r_value) * wall_area / azimuths.size * @htd
767
- else
760
+ bldg_design_loads.Cool_Walls += (1.0 / wall.insulation_assembly_r_value) * wall_area / azimuths.size * cltd
761
+ bldg_design_loads.Heat_Walls += (1.0 / wall.insulation_assembly_r_value) * wall_area / azimuths.size * @htd
762
+ else # Partition wall
768
763
  adjacent_space = wall.exterior_adjacent_to
769
- zone_loads.Cool_Walls += (1.0 / wall.insulation_assembly_r_value) * wall_area / azimuths.size * (@cool_design_temps[adjacent_space] - @cool_setpoint)
770
- zone_loads.Heat_Walls += (1.0 / wall.insulation_assembly_r_value) * wall_area / azimuths.size * (@heat_setpoint - @heat_design_temps[adjacent_space])
764
+ bldg_design_loads.Cool_Walls += (1.0 / wall.insulation_assembly_r_value) * wall_area / azimuths.size * (@cool_design_temps[adjacent_space] - @cool_setpoint)
765
+ bldg_design_loads.Heat_Walls += (1.0 / wall.insulation_assembly_r_value) * wall_area / azimuths.size * (@heat_setpoint - @heat_design_temps[adjacent_space])
771
766
  end
772
767
  end
773
768
  end
@@ -777,21 +772,17 @@ class HVACSizing
777
772
  next unless foundation_wall.is_exterior_thermal_boundary
778
773
 
779
774
  u_wall_with_soil, u_wall_without_soil = get_foundation_wall_properties(foundation_wall)
780
- zone_loads.Heat_Walls += u_wall_with_soil * foundation_wall.net_area * @htd
775
+ bldg_design_loads.Heat_Walls += u_wall_with_soil * foundation_wall.net_area * @htd
781
776
  end
782
-
783
- return zone_loads
784
777
  end
785
778
 
786
- def self.process_load_roofs(zone_loads, weather)
779
+ def self.process_load_roofs(bldg_design_loads, weather)
787
780
  '''
788
- Heating and Cooling Loads: Ceilings
781
+ Heating and Cooling Loads: Roofs
789
782
  '''
790
783
 
791
- cltd = 0.0
792
-
793
- zone_loads.Heat_Roofs = 0.0
794
- zone_loads.Cool_Roofs = 0.0
784
+ bldg_design_loads.Heat_Roofs = 0.0
785
+ bldg_design_loads.Cool_Roofs = 0.0
795
786
 
796
787
  # Roofs
797
788
  @hpxml.roofs.each do |roof|
@@ -834,40 +825,109 @@ class HVACSizing
834
825
  # Adjust base CLTD for different CTD or DR
835
826
  cltd += (weather.design.CoolingDrybulb - 95.0) + @daily_range_temp_adjust[@daily_range_num]
836
827
 
837
- zone_loads.Cool_Roofs += (1.0 / roof.insulation_assembly_r_value) * roof.net_area * cltd
838
- zone_loads.Heat_Roofs += (1.0 / roof.insulation_assembly_r_value) * roof.net_area * @htd
828
+ bldg_design_loads.Cool_Roofs += (1.0 / roof.insulation_assembly_r_value) * roof.net_area * cltd
829
+ bldg_design_loads.Heat_Roofs += (1.0 / roof.insulation_assembly_r_value) * roof.net_area * @htd
839
830
  end
831
+ end
832
+
833
+ def self.process_load_ceilings(bldg_design_loads, weather)
834
+ '''
835
+ Heating and Cooling Loads: Ceilings
836
+ '''
840
837
 
841
- return zone_loads
838
+ bldg_design_loads.Heat_Ceilings = 0.0
839
+ bldg_design_loads.Cool_Ceilings = 0.0
840
+
841
+ @hpxml.frame_floors.each do |frame_floor|
842
+ next unless frame_floor.is_ceiling
843
+ next unless frame_floor.is_thermal_boundary
844
+
845
+ if frame_floor.is_exterior
846
+ bldg_design_loads.Cool_Ceilings += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * (@ctd - 5.0 + @daily_range_temp_adjust[@daily_range_num])
847
+ bldg_design_loads.Heat_Ceilings += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * @htd
848
+ else
849
+ adjacent_space = frame_floor.exterior_adjacent_to
850
+ bldg_design_loads.Cool_Ceilings += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * (@cool_design_temps[adjacent_space] - @cool_setpoint)
851
+ bldg_design_loads.Heat_Ceilings += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * (@heat_setpoint - @heat_design_temps[adjacent_space])
852
+ end
853
+ end
842
854
  end
843
855
 
844
- def self.process_load_floors(zone_loads, weather)
856
+ def self.process_load_floors(bldg_design_loads, weather)
845
857
  '''
846
858
  Heating and Cooling Loads: Floors
847
859
  '''
848
860
 
849
- zone_loads.Heat_Floors = 0.0
850
- zone_loads.Cool_Floors = 0.0
861
+ bldg_design_loads.Heat_Floors = 0.0
862
+ bldg_design_loads.Cool_Floors = 0.0
851
863
 
852
864
  @hpxml.frame_floors.each do |frame_floor|
865
+ next unless frame_floor.is_floor
853
866
  next unless frame_floor.is_thermal_boundary
854
867
 
855
868
  if frame_floor.is_exterior
856
- zone_loads.Cool_Floors += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * (@ctd - 5.0 + @daily_range_temp_adjust[@daily_range_num])
857
- zone_loads.Heat_Floors += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * @htd
858
- else
869
+ bldg_design_loads.Cool_Floors += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * (@ctd - 5.0 + @daily_range_temp_adjust[@daily_range_num])
870
+ bldg_design_loads.Heat_Floors += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * @htd
871
+ else # Partition floor
859
872
  adjacent_space = frame_floor.exterior_adjacent_to
860
- zone_loads.Cool_Floors += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * (@cool_design_temps[adjacent_space] - @cool_setpoint)
861
- zone_loads.Heat_Floors += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * (@heat_setpoint - @heat_design_temps[adjacent_space])
873
+ if frame_floor.is_floor && [HPXML::LocationCrawlspaceVented, HPXML::LocationCrawlspaceUnvented, HPXML::LocationBasementUnconditioned].include?(adjacent_space)
874
+ u_floor = 1.0 / frame_floor.insulation_assembly_r_value
875
+
876
+ sum_ua_wall = 0.0
877
+ sum_a_wall = 0.0
878
+ @hpxml.foundation_walls.each do |foundation_wall|
879
+ next unless foundation_wall.is_exterior && foundation_wall.interior_adjacent_to == adjacent_space
880
+
881
+ u_wall_with_soil, u_wall_without_soil = get_foundation_wall_properties(foundation_wall)
882
+
883
+ sum_a_wall += foundation_wall.net_area
884
+ sum_ua_wall += (u_wall_without_soil * foundation_wall.net_area)
885
+ end
886
+ @hpxml.walls.each do |wall|
887
+ next unless wall.is_exterior && wall.interior_adjacent_to == adjacent_space
888
+
889
+ sum_a_wall += wall.net_area
890
+ sum_ua_wall += (1.0 / wall.insulation_assembly_r_value * wall.net_area)
891
+ end
892
+ fail 'Could not find connected walls.' if sum_a_wall <= 0
893
+
894
+ u_wall = sum_ua_wall / sum_a_wall
895
+
896
+ # Calculate partition temperature different cooling (PTDC) per Manual J Figure A12-17
897
+ # Calculate partition temperature different heating (PTDH) per Manual J Figure A12-6
898
+ if [HPXML::LocationCrawlspaceVented].include? adjacent_space
899
+ # Vented or Leaky
900
+ ptdc_floor = @ctd / (1.0 + (4.0 * u_floor) / (u_wall + 0.11))
901
+ ptdh_floor = @htd / (1.0 + (4.0 * u_floor) / (u_wall + 0.11))
902
+ elsif [HPXML::LocationCrawlspaceUnvented, HPXML::LocationBasementUnconditioned].include? adjacent_space
903
+ # Sealed Tight
904
+ ptdc_floor = u_wall * @ctd / (4.0 * u_floor + u_wall)
905
+ ptdh_floor = u_wall * @htd / (4.0 * u_floor + u_wall)
906
+ end
907
+
908
+ bldg_design_loads.Cool_Floors += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * ptdc_floor
909
+ bldg_design_loads.Heat_Floors += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * ptdh_floor
910
+ else # E.g., floor over garage
911
+ bldg_design_loads.Cool_Floors += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * (@cool_design_temps[adjacent_space] - @cool_setpoint)
912
+ bldg_design_loads.Heat_Floors += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * (@heat_setpoint - @heat_design_temps[adjacent_space])
913
+ end
862
914
  end
863
915
  end
916
+ end
917
+
918
+ def self.process_load_slabs(bldg_design_loads, weather)
919
+ '''
920
+ Heating and Cooling Loads: Floors
921
+ '''
922
+
923
+ bldg_design_loads.Heat_Slabs = 0.0
864
924
 
865
925
  @hpxml.slabs.each do |slab|
866
926
  next unless slab.is_thermal_boundary
867
927
 
868
928
  if slab.interior_adjacent_to == HPXML::LocationLivingSpace # Slab-on-grade
869
929
  f_value = calc_slab_f_value(slab)
870
- zone_loads.Heat_Floors += f_value * slab.exposed_perimeter * @htd
930
+ bldg_design_loads.Heat_Slabs += f_value * slab.exposed_perimeter * @htd
871
931
  elsif slab.interior_adjacent_to == HPXML::LocationBasementConditioned
872
932
  # Based on MJ 8th Ed. A12-7 and ASHRAE HoF 2013 pg 18.31 Eq 40
873
933
  # FIXME: Assumes slab is uninsulated?
@@ -879,95 +939,120 @@ class HVACSizing
879
939
  length = slab.exposed_perimeter / 4.0 + Math.sqrt(sqrt_term) / 4.0
880
940
  width = slab.exposed_perimeter / 4.0 - Math.sqrt(sqrt_term) / 4.0
881
941
  w_b = [length, width].min
942
+ w_b = [w_b, 1.0].max # handle zero exposed perimeter
882
943
  u_avg_bf = (2.0 * k_soil / (Math::PI * w_b)) * (Math::log(w_b / 2.0 + z_f / 2.0 + (k_soil * r_other) / Math::PI) - Math::log(z_f / 2.0 + (k_soil * r_other) / Math::PI))
883
944
  u_value_mj8 = 0.85 * u_avg_bf
884
- zone_loads.Heat_Floors += u_value_mj8 * slab.area * @htd
945
+ bldg_design_loads.Heat_Slabs += u_value_mj8 * slab.area * @htd
885
946
  end
886
947
  end
887
-
888
- return zone_loads
889
948
  end
890
949
 
891
- def self.process_infiltration_ventilation(model, zone_loads, weather, infilvolume)
950
+ def self.process_load_infiltration_ventilation(bldg_design_loads, weather, cfa)
892
951
  '''
893
952
  Heating and Cooling Loads: Infiltration & Ventilation
894
953
  '''
895
954
 
896
- # Per ANSI/RESNET/ICC 301
897
- ach_nat = get_feature(@cond_zone, Constants.SizingInfoZoneInfiltrationACH, 'double')
955
+ # FUTURE: Consolidate code w/ airflow.rb
956
+ infil_volume = @hpxml.air_infiltration_measurements.select { |i| !i.infiltration_volume.nil? }[0].infiltration_volume
957
+ infil_height = @hpxml.inferred_infiltration_height(infil_volume)
958
+ sla = nil
959
+ @hpxml.air_infiltration_measurements.each do |measurement|
960
+ if [HPXML::UnitsACH, HPXML::UnitsCFM].include?(measurement.unit_of_measure) && !measurement.house_pressure.nil?
961
+ if measurement.unit_of_measure == HPXML::UnitsACH
962
+ ach50 = Airflow.calc_air_leakage_at_diff_pressure(0.65, measurement.air_leakage, measurement.house_pressure, 50.0)
963
+ elsif measurement.unit_of_measure == HPXML::UnitsCFM
964
+ achXX = measurement.air_leakage * 60.0 / infil_volume # Convert CFM to ACH
965
+ ach50 = Airflow.calc_air_leakage_at_diff_pressure(0.65, achXX, measurement.house_pressure, 50.0)
966
+ end
967
+ sla = Airflow.get_infiltration_SLA_from_ACH50(ach50, 0.65, cfa, infil_volume)
968
+ elsif measurement.unit_of_measure == HPXML::UnitsACHNatural
969
+ sla = Airflow.get_infiltration_SLA_from_ACH(measurement.air_leakage, infil_height, weather)
970
+ end
971
+ end
972
+ ela = sla * cfa
973
+
974
+ ncfl_ag = @hpxml.building_construction.number_of_conditioned_floors_above_grade
898
975
 
899
- ach_Cooling = 1.2 * ach_nat
900
- ach_Heating = 1.6 * ach_nat
976
+ # Set stack/wind coefficients from Tables 5D/5E
977
+ c_s = 0.015 * ncfl_ag
978
+ c_w_base = [0.0133 * @hpxml.site.additional_properties.aim2_shelter_coeff - 0.0027, 0.0].max # Linear relationship between shelter coefficient and c_w coefficients by shielding class
979
+ c_w = c_w_base * ncfl_ag**0.4
901
980
 
902
- icfm_Cooling = ach_Cooling / UnitConversions.convert(1.0, 'hr', 'min') * infilvolume
903
- icfm_Heating = ach_Heating / UnitConversions.convert(1.0, 'hr', 'min') * infilvolume
981
+ ela_in2 = UnitConversions.convert(ela, 'ft^2', 'in^2')
982
+ windspeed_cooling_mph = 7.5 # Table 5D/5E Wind Velocity Value footnote
983
+ windspeed_heating_mph = 15.0 # Table 5D/5E Wind Velocity Value footnote
904
984
 
905
- q_unb_cfm, q_preheat, q_precool, q_recirc, q_bal_Sens, q_bal_Lat = get_ventilation_rates(model)
985
+ icfm_Cooling = ela_in2 * (c_s * @ctd + c_w * windspeed_cooling_mph**2)**0.5
986
+ icfm_Heating = ela_in2 * (c_s * @htd + c_w * windspeed_heating_mph**2)**0.5
987
+
988
+ q_unb_cfm, q_preheat, q_precool, q_recirc, q_bal_Sens, q_bal_Lat = get_ventilation_rates()
906
989
 
907
990
  cfm_Heating = q_bal_Sens + (icfm_Heating**2.0 + q_unb_cfm**2.0)**0.5 - q_preheat - q_recirc
908
991
 
909
992
  cfm_Cool_Load_Sens = q_bal_Sens + (icfm_Cooling**2.0 + q_unb_cfm**2.0)**0.5 - q_precool - q_recirc
910
993
  cfm_Cool_Load_Lat = q_bal_Lat + (icfm_Cooling**2.0 + q_unb_cfm**2.0)**0.5 - q_recirc
911
994
 
912
- zone_loads.Heat_Infil = 1.1 * @acf * cfm_Heating * @htd
913
-
914
- zone_loads.Cool_Infil_Sens = 1.1 * @acf * cfm_Cool_Load_Sens * @ctd
915
- zone_loads.Cool_Infil_Lat = 0.68 * @acf * cfm_Cool_Load_Lat * (@cool_design_grains - @cool_indoor_grains)
995
+ bldg_design_loads.Heat_InfilVent = 1.1 * @acf * cfm_Heating * @htd
916
996
 
917
- return zone_loads
997
+ bldg_design_loads.Cool_Infil_Sens = 1.1 * @acf * cfm_Cool_Load_Sens * @ctd
998
+ bldg_design_loads.Cool_Infil_Lat = 0.68 * @acf * cfm_Cool_Load_Lat * (@cool_design_grains - @cool_indoor_grains)
918
999
  end
919
1000
 
920
- def self.process_internal_gains(zone_loads, nbeds)
1001
+ def self.process_load_internal_gains(bldg_design_loads, nbeds)
921
1002
  '''
922
1003
  Cooling Load: Internal Gains
923
1004
  '''
924
1005
 
925
1006
  # Per ANSI/RESNET/ICC 301
926
1007
  n_occupants = nbeds + 1
927
- zone_loads.Cool_IntGains_Sens = 1600.0 + 230.0 * n_occupants
928
- zone_loads.Cool_IntGains_Lat = 200.0 * n_occupants
929
-
930
- return zone_loads
1008
+ bldg_design_loads.Cool_IntGains_Sens = 1600.0 + 230.0 * n_occupants
1009
+ bldg_design_loads.Cool_IntGains_Lat = 200.0 * n_occupants
931
1010
  end
932
1011
 
933
- def self.aggregate_zone_loads(zone_loads)
1012
+ def self.aggregate_loads(bldg_design_loads)
934
1013
  '''
935
- Intermediate Loads
936
- (total loads excluding ducts)
1014
+ Building Loads (excluding ducts)
937
1015
  '''
938
1016
 
939
- init_loads = InitialLoads.new
940
1017
  # Heating
941
- init_loads.Heat = [zone_loads.Heat_Windows + zone_loads.Heat_Skylights +
942
- zone_loads.Heat_Doors + zone_loads.Heat_Walls +
943
- zone_loads.Heat_Floors + zone_loads.Heat_Roofs, 0.0].max +
944
- zone_loads.Heat_Infil
1018
+ bldg_design_loads.Heat_Tot = [bldg_design_loads.Heat_Windows + bldg_design_loads.Heat_Skylights +
1019
+ bldg_design_loads.Heat_Doors + bldg_design_loads.Heat_Walls +
1020
+ bldg_design_loads.Heat_Floors + bldg_design_loads.Heat_Slabs +
1021
+ bldg_design_loads.Heat_Ceilings + bldg_design_loads.Heat_Roofs, 0.0].max +
1022
+ bldg_design_loads.Heat_InfilVent
945
1023
 
946
1024
  # Cooling
947
- init_loads.Cool_Sens = zone_loads.Cool_Windows + zone_loads.Cool_Skylights +
948
- zone_loads.Cool_Doors + zone_loads.Cool_Walls +
949
- zone_loads.Cool_Floors + zone_loads.Cool_Roofs +
950
- zone_loads.Cool_Infil_Sens + zone_loads.Cool_IntGains_Sens
951
- init_loads.Cool_Lat = zone_loads.Cool_Infil_Lat + zone_loads.Cool_IntGains_Lat
952
-
953
- init_loads.Cool_Lat = [init_loads.Cool_Lat, 0.0].max
954
- init_loads.Cool_Tot = init_loads.Cool_Sens + init_loads.Cool_Lat
955
-
956
- return init_loads
957
- end
958
-
959
- def self.calculate_hvac_temperatures(hvac_init_loads, hvac)
1025
+ bldg_design_loads.Cool_Sens = bldg_design_loads.Cool_Windows + bldg_design_loads.Cool_Skylights +
1026
+ bldg_design_loads.Cool_Doors + bldg_design_loads.Cool_Walls +
1027
+ bldg_design_loads.Cool_Floors + bldg_design_loads.Cool_Ceilings +
1028
+ bldg_design_loads.Cool_Roofs + bldg_design_loads.Cool_Infil_Sens +
1029
+ bldg_design_loads.Cool_IntGains_Sens
1030
+ bldg_design_loads.Cool_Lat = bldg_design_loads.Cool_Infil_Lat + bldg_design_loads.Cool_IntGains_Lat
1031
+ if bldg_design_loads.Cool_Lat < 0 # No latent loads; also zero out individual components
1032
+ bldg_design_loads.Cool_Lat = 0.0
1033
+ bldg_design_loads.Cool_Infil_Lat = 0.0
1034
+ bldg_design_loads.Cool_IntGains_Lat = 0.0
1035
+ end
1036
+ bldg_design_loads.Cool_Tot = bldg_design_loads.Cool_Sens + bldg_design_loads.Cool_Lat
1037
+
1038
+ # Initialize ducts
1039
+ bldg_design_loads.Heat_Ducts = 0.0
1040
+ bldg_design_loads.Cool_Ducts_Sens = 0.0
1041
+ bldg_design_loads.Cool_Ducts_Lat = 0.0
1042
+ end
1043
+
1044
+ def self.apply_hvac_temperatures(hvac, bldg_design_loads)
960
1045
  '''
961
1046
  HVAC Temperatures
962
1047
  '''
963
- # evap cooler temperature calculation based on Mannual S Figure 4-7
964
- if hvac.has_type(Constants.ObjectNameEvaporativeCooler)
1048
+ # Evaporative cooler temperature calculation based on Manual S Figure 4-7
1049
+ if hvac.CoolType == HPXML::HVACTypeEvaporativeCooler
965
1050
  td_potential = @cool_design_temps[HPXML::LocationOutside] - @wetbulb_outdoor_cooling
966
1051
  td = td_potential * hvac.EvapCoolerEffectiveness
967
1052
  hvac.LeavingAirTemp = @cool_design_temps[HPXML::LocationOutside] - td
968
1053
  else
969
1054
  # Calculate Leaving Air Temperature
970
- shr = [hvac_init_loads.Cool_Sens / hvac_init_loads.Cool_Tot, 1.0].min
1055
+ shr = [bldg_design_loads.Cool_Sens / bldg_design_loads.Cool_Tot, 1.0].min
971
1056
  # Determine the Leaving Air Temperature (LAT) based on Manual S Table 1-4
972
1057
  if shr < 0.80
973
1058
  hvac.LeavingAirTemp = 54.0 # F
@@ -981,42 +1066,46 @@ class HVACSizing
981
1066
  end
982
1067
 
983
1068
  # Calculate Supply Air Temperature
984
- if hvac.has_type(Constants.ObjectNameFurnace)
985
- hvac.SupplyAirTemp = 120.0 # F
986
- else
1069
+ if [HPXML::HVACTypeHeatPumpAirToAir,
1070
+ HPXML::HVACTypeHeatPumpMiniSplit,
1071
+ HPXML::HVACTypeHeatPumpGroundToAir,
1072
+ HPXML::HVACTypeHeatPumpWaterLoopToAir].include? hvac.HeatType
987
1073
  hvac.SupplyAirTemp = 105.0 # F
1074
+ else
1075
+ hvac.SupplyAirTemp = 120.0 # F
988
1076
  end
989
1077
  end
990
1078
 
991
- def self.apply_hvac_load_fractions(hvac_init_loads, hvac)
992
- '''
993
- Intermediate Loads (HVAC-specific)
994
- '''
995
- hvac_init_loads.Heat *= hvac.HeatingLoadFraction
996
- hvac_init_loads.Cool_Sens *= hvac.CoolingLoadFraction
997
- hvac_init_loads.Cool_Lat *= hvac.CoolingLoadFraction
998
- hvac_init_loads.Cool_Tot *= hvac.CoolingLoadFraction
1079
+ def self.apply_hvac_loads(hvac, hvac_sizing_values, bldg_design_loads)
1080
+ # Calculate design loads that this HVAC system serves
999
1081
 
1000
- # Prevent error for, e.g., an ASHP with CoolingLoadFraction == 0.
1001
- hvac_init_loads.Heat = [hvac_init_loads.Heat, 0.001].max
1002
- hvac_init_loads.Cool_Sens = [hvac_init_loads.Cool_Sens, 0.001].max
1003
- hvac_init_loads.Cool_Lat = [hvac_init_loads.Cool_Lat, 0.001].max
1004
- hvac_init_loads.Cool_Tot = [hvac_init_loads.Cool_Tot, 0.001].max
1082
+ # Heating
1083
+ hvac_sizing_values.Heat_Load = bldg_design_loads.Heat_Tot * hvac.HeatingLoadFraction
1084
+ if hvac.HeatType == HPXML::HVACTypeHeatPumpWaterLoopToAir
1085
+ # Size to meet original fraction load served (not adjusted value from HVAC.apply_shared_heating_systems()
1086
+ # This ensures, e.g., that an appropriate heating airflow is used for duct losses.
1087
+ hvac_sizing_values.Heat_Load = hvac_sizing_values.Heat_Load / (1.0 / hvac.HeatingCOP)
1088
+ end
1089
+
1090
+ # Cooling
1091
+ hvac_sizing_values.Cool_Load_Tot = bldg_design_loads.Cool_Tot * hvac.CoolingLoadFraction
1092
+ hvac_sizing_values.Cool_Load_Sens = bldg_design_loads.Cool_Sens * hvac.CoolingLoadFraction
1093
+ hvac_sizing_values.Cool_Load_Lat = bldg_design_loads.Cool_Lat * hvac.CoolingLoadFraction
1005
1094
  end
1006
1095
 
1007
- def self.apply_hp_sizing_logic(hvac_init_loads, hvac)
1096
+ def self.apply_hvac_heat_pump_logic(hvac_sizing_values, hvac)
1008
1097
  # If true, uses the larger of heating and cooling loads for heat pump capacity sizing (required for ERI).
1009
1098
  # Otherwise, uses standard Manual S oversize allowances.
1010
- if hvac.has_type([Constants.ObjectNameAirSourceHeatPump,
1011
- Constants.ObjectNameMiniSplitHeatPump,
1012
- Constants.ObjectNameGroundSourceHeatPump,
1013
- Constants.ObjectNameWaterLoopHeatPump])
1014
- if @hpxml.header.use_max_load_for_heat_pumps
1015
- max_load = [hvac_init_loads.Heat, hvac_init_loads.Cool_Tot].max
1016
- hvac_init_loads.Heat = max_load
1017
- hvac_init_loads.Cool_Sens *= max_load / hvac_init_loads.Cool_Tot
1018
- hvac_init_loads.Cool_Lat *= max_load / hvac_init_loads.Cool_Tot
1019
- hvac_init_loads.Cool_Tot = max_load
1099
+ if [HPXML::HVACTypeHeatPumpAirToAir,
1100
+ HPXML::HVACTypeHeatPumpMiniSplit,
1101
+ HPXML::HVACTypeHeatPumpGroundToAir,
1102
+ HPXML::HVACTypeHeatPumpWaterLoopToAir].include? hvac.CoolType
1103
+ if @hpxml.header.use_max_load_for_heat_pumps && (hvac.CoolingLoadFraction > 0) && (hvac.HeatingLoadFraction > 0)
1104
+ max_load = [hvac_sizing_values.Heat_Load, hvac_sizing_values.Cool_Load_Tot].max
1105
+ hvac_sizing_values.Heat_Load = max_load
1106
+ hvac_sizing_values.Cool_Load_Sens *= max_load / hvac_sizing_values.Cool_Load_Tot
1107
+ hvac_sizing_values.Cool_Load_Lat *= max_load / hvac_sizing_values.Cool_Load_Tot
1108
+ hvac_sizing_values.Cool_Load_Tot = max_load
1020
1109
 
1021
1110
  # Override Manual S oversize allowances:
1022
1111
  hvac.OverSizeLimit = 1.0
@@ -1095,137 +1184,129 @@ class HVACSizing
1095
1184
  return dse_Fregain
1096
1185
  end
1097
1186
 
1098
- def self.process_duct_loads_heating(hvac_final_values, weather, hvac, init_heat_load)
1187
+ def self.apply_load_ducts_heating(bldg_design_loads, weather, hvac)
1099
1188
  '''
1100
1189
  Heating Duct Loads
1101
1190
  '''
1102
- if (init_heat_load == 0) || (hvac.Ducts.size == 0)
1103
- hvac_final_values.Heat_Load_Ducts = 0.0
1104
- hvac_final_values.Heat_Load = init_heat_load
1105
- else
1106
- # Distribution system efficiency (DSE) calculations based on ASHRAE Standard 152
1107
- dse_As, dse_Ar = calc_ducts_areas(hvac.Ducts)
1108
- supply_r, return_r = calc_ducts_rvalues(hvac.Ducts)
1109
1191
 
1110
- design_temp_values = { HPXML::DuctTypeSupply => @heat_design_temps, HPXML::DuctTypeReturn => @heat_design_temps }
1111
- dse_Tamb_heating_s, dse_Tamb_heating_r = calc_ducts_area_weighted_average(hvac.Ducts, design_temp_values)
1192
+ return if (bldg_design_loads.Heat_Tot == 0) || (hvac.HeatingLoadFraction == 0) || hvac.Ducts.empty?
1112
1193
 
1113
- # ASHRAE 152 6.5.2
1114
- # For systems with ducts in several locations, Fregain shall be weighted by the fraction of exposed duct area
1115
- # in each space. Fregain shall be calculated separately for supply and return locations.
1116
- dse_Fregains = {}
1117
- hvac.Ducts.each do |duct|
1118
- dse_Fregains[duct.Location] = get_duct_regain_factor(duct)
1119
- end
1120
- fregain_values = { HPXML::DuctTypeSupply => dse_Fregains, HPXML::DuctTypeReturn => dse_Fregains }
1121
- dse_Fregain_s, dse_Fregain_r = calc_ducts_area_weighted_average(hvac.Ducts, fregain_values)
1194
+ init_heat_load = bldg_design_loads.Heat_Tot * hvac.HeatingLoadFraction
1122
1195
 
1123
- # Initialize for the iteration
1124
- delta = 1
1125
- heatingLoad_Prev = init_heat_load
1126
- heat_cfm = calc_airflow_rate(init_heat_load, (hvac.SupplyAirTemp - @heat_setpoint))
1196
+ # Distribution system efficiency (DSE) calculations based on ASHRAE Standard 152
1197
+ dse_As, dse_Ar = calc_ducts_areas(hvac.Ducts)
1198
+ supply_r, return_r = calc_ducts_rvalues(hvac.Ducts)
1127
1199
 
1128
- for _iter in 0..19
1129
- break if delta.abs <= 0.001
1200
+ design_temp_values = { HPXML::DuctTypeSupply => @heat_design_temps, HPXML::DuctTypeReturn => @heat_design_temps }
1201
+ dse_Tamb_heating_s, dse_Tamb_heating_r = calc_ducts_area_weighted_average(hvac.Ducts, design_temp_values)
1130
1202
 
1131
- dse_Qs, dse_Qr = calc_ducts_leakages(hvac.Ducts, heat_cfm)
1203
+ # ASHRAE 152 6.5.2
1204
+ # For systems with ducts in several locations, F_regain shall be weighted by the fraction of exposed duct area
1205
+ # in each space. F_regain shall be calculated separately for supply and return locations.
1206
+ dse_Fregains = {}
1207
+ hvac.Ducts.each do |duct|
1208
+ dse_Fregains[duct.Location] = get_duct_regain_factor(duct)
1209
+ end
1210
+ fregain_values = { HPXML::DuctTypeSupply => dse_Fregains, HPXML::DuctTypeReturn => dse_Fregains }
1211
+ dse_Fregain_s, dse_Fregain_r = calc_ducts_area_weighted_average(hvac.Ducts, fregain_values)
1132
1212
 
1133
- dse_DE = calc_delivery_effectiveness_heating(dse_Qs, dse_Qr, heat_cfm, heatingLoad_Prev, dse_Tamb_heating_s, dse_Tamb_heating_r, dse_As, dse_Ar, @heat_setpoint, dse_Fregain_s, dse_Fregain_r, supply_r, return_r)
1213
+ # Initialize for the iteration
1214
+ delta = 1
1215
+ heat_load_next = init_heat_load
1134
1216
 
1135
- # Calculate the increase in heating load due to ducts (Approach: DE = Qload/Qequip -> Qducts = Qequip-Qload)
1136
- heatingLoad_Next = init_heat_load / dse_DE
1217
+ for _iter in 0..19
1218
+ break if delta.abs <= 0.001
1137
1219
 
1138
- # Calculate the change since the last iteration
1139
- delta = (heatingLoad_Next - heatingLoad_Prev) / heatingLoad_Prev
1220
+ heat_load_prev = heat_load_next
1140
1221
 
1141
- # Update the flow rate for the next iteration
1142
- heatingLoad_Prev = heatingLoad_Next
1143
- heat_cfm = calc_airflow_rate(heatingLoad_Next, (hvac.SupplyAirTemp - @heat_setpoint))
1222
+ # Calculate the new heating air flow rate
1223
+ heat_cfm = calc_airflow_rate(heat_load_next, (hvac.SupplyAirTemp - @heat_setpoint))
1144
1224
 
1145
- end
1225
+ dse_Qs, dse_Qr = calc_ducts_leakages(hvac.Ducts, heat_cfm)
1226
+
1227
+ dse_DE = calc_delivery_effectiveness_heating(dse_Qs, dse_Qr, heat_cfm, heat_load_next, dse_Tamb_heating_s, dse_Tamb_heating_r, dse_As, dse_Ar, @heat_setpoint, dse_Fregain_s, dse_Fregain_r, supply_r, return_r)
1146
1228
 
1147
- hvac_final_values.Heat_Load_Ducts = heatingLoad_Next - init_heat_load
1148
- hvac_final_values.Heat_Load = init_heat_load + hvac_final_values.Heat_Load_Ducts
1229
+ # Calculate the increase in heating load due to ducts (Approach: DE = Qload/Qequip -> Qducts = Qequip-Qload)
1230
+ heat_load_next = init_heat_load / dse_DE
1231
+
1232
+ # Calculate the change since the last iteration
1233
+ delta = (heat_load_next - heat_load_prev) / heat_load_prev
1149
1234
  end
1235
+
1236
+ ducts_heat_load = heat_load_next - init_heat_load
1237
+
1238
+ bldg_design_loads.Heat_Ducts += ducts_heat_load
1239
+ bldg_design_loads.Heat_Tot += ducts_heat_load
1150
1240
  end
1151
1241
 
1152
- def self.process_duct_loads_cooling(hvac_final_values, weather, hvac, init_cool_load_sens, init_cool_load_lat)
1242
+ def self.apply_load_ducts_cooling(bldg_design_loads, weather, hvac)
1153
1243
  '''
1154
1244
  Cooling Duct Loads
1155
1245
  '''
1246
+ return if (bldg_design_loads.Cool_Sens == 0) || (hvac.CoolingLoadFraction == 0) || hvac.Ducts.empty?
1156
1247
 
1157
- if (init_cool_load_sens == 0) || (hvac.Ducts.size == 0)
1158
- hvac_final_values.Cool_Load_Ducts_Sens = 0.0
1159
- hvac_final_values.Cool_Load_Ducts_Tot = 0.0
1160
- hvac_final_values.Cool_Load_Sens = init_cool_load_sens
1161
- hvac_final_values.Cool_Load_Lat = init_cool_load_lat
1162
- hvac_final_values.Cool_Load_Tot = hvac_final_values.Cool_Load_Sens + hvac_final_values.Cool_Load_Lat
1163
- else
1164
- # Distribution system efficiency (DSE) calculations based on ASHRAE Standard 152
1165
- dse_As, dse_Ar = calc_ducts_areas(hvac.Ducts)
1166
- supply_r, return_r = calc_ducts_rvalues(hvac.Ducts)
1167
-
1168
- design_temp_values = { HPXML::DuctTypeSupply => @cool_design_temps, HPXML::DuctTypeReturn => @cool_design_temps }
1169
- dse_Tamb_cooling_s, dse_Tamb_cooling_r = calc_ducts_area_weighted_average(hvac.Ducts, design_temp_values)
1170
-
1171
- # ASHRAE 152 6.5.2
1172
- # For systems with ducts in several locations, Fregain shall be weighted by the fraction of exposed duct area
1173
- # in each space. Fregain shall be calculated separately for supply and return locations.
1174
- dse_Fregains = {}
1175
- hvac.Ducts.each do |duct|
1176
- dse_Fregains[duct.Location] = get_duct_regain_factor(duct)
1177
- end
1178
- fregain_values = { HPXML::DuctTypeSupply => dse_Fregains, HPXML::DuctTypeReturn => dse_Fregains }
1179
- dse_Fregain_s, dse_Fregain_r = calc_ducts_area_weighted_average(hvac.Ducts, fregain_values)
1248
+ init_cool_load_sens = bldg_design_loads.Cool_Sens * hvac.CoolingLoadFraction
1249
+ init_cool_load_lat = bldg_design_loads.Cool_Lat * hvac.CoolingLoadFraction
1180
1250
 
1181
- # Calculate the air enthalpy in the return duct location for DSE calculations
1182
- dse_h_r = (1.006 * UnitConversions.convert(dse_Tamb_cooling_r, 'F', 'C') + weather.design.CoolingHumidityRatio * (2501.0 + 1.86 * UnitConversions.convert(dse_Tamb_cooling_r, 'F', 'C'))) * UnitConversions.convert(1.0, 'kJ', 'Btu') * UnitConversions.convert(1.0, 'lbm', 'kg')
1251
+ # Distribution system efficiency (DSE) calculations based on ASHRAE Standard 152
1252
+ dse_As, dse_Ar = calc_ducts_areas(hvac.Ducts)
1253
+ supply_r, return_r = calc_ducts_rvalues(hvac.Ducts)
1183
1254
 
1184
- # Initialize for the iteration
1185
- delta = 1
1186
- coolingLoad_Tot_Prev = init_cool_load_sens + init_cool_load_lat
1187
- coolingLoad_Tot_Next = init_cool_load_sens + init_cool_load_lat
1188
- hvac_final_values.Cool_Load_Tot = init_cool_load_sens + init_cool_load_lat
1189
- hvac_final_values.Cool_Load_Sens = init_cool_load_sens
1255
+ design_temp_values = { HPXML::DuctTypeSupply => @cool_design_temps, HPXML::DuctTypeReturn => @cool_design_temps }
1256
+ dse_Tamb_cooling_s, dse_Tamb_cooling_r = calc_ducts_area_weighted_average(hvac.Ducts, design_temp_values)
1190
1257
 
1191
- initial_Cool_Airflow = calc_airflow_rate(init_cool_load_sens, (@cool_setpoint - hvac.LeavingAirTemp))
1258
+ # ASHRAE 152 6.5.2
1259
+ # For systems with ducts in several locations, F_regain shall be weighted by the fraction of exposed duct area
1260
+ # in each space. F_regain shall be calculated separately for supply and return locations.
1261
+ dse_Fregains = {}
1262
+ hvac.Ducts.each do |duct|
1263
+ dse_Fregains[duct.Location] = get_duct_regain_factor(duct)
1264
+ end
1265
+ fregain_values = { HPXML::DuctTypeSupply => dse_Fregains, HPXML::DuctTypeReturn => dse_Fregains }
1266
+ dse_Fregain_s, dse_Fregain_r = calc_ducts_area_weighted_average(hvac.Ducts, fregain_values)
1192
1267
 
1193
- supply_leakage_cfm, return_leakage_cfm = calc_ducts_leakages(hvac.Ducts, initial_Cool_Airflow)
1268
+ # Calculate the air enthalpy in the return duct location for DSE calculations
1269
+ dse_h_r = (1.006 * UnitConversions.convert(dse_Tamb_cooling_r, 'F', 'C') + weather.design.CoolingHumidityRatio * (2501.0 + 1.86 * UnitConversions.convert(dse_Tamb_cooling_r, 'F', 'C'))) * UnitConversions.convert(1.0, 'kJ', 'Btu') * UnitConversions.convert(1.0, 'lbm', 'kg')
1194
1270
 
1195
- hvac_final_values.Cool_Load_Lat, hvac_final_values.Cool_Load_Sens = calculate_sensible_latent_split(return_leakage_cfm, coolingLoad_Tot_Next, init_cool_load_lat)
1271
+ # Initialize for the iteration
1272
+ delta = 1
1273
+ cool_load_tot_next = init_cool_load_sens + init_cool_load_lat
1196
1274
 
1197
- for _iter in 1..50
1198
- break if delta.abs <= 0.001
1275
+ cool_cfm = calc_airflow_rate(init_cool_load_sens, (@cool_setpoint - hvac.LeavingAirTemp))
1276
+ dse_Qs, dse_Qr = calc_ducts_leakages(hvac.Ducts, cool_cfm)
1199
1277
 
1200
- coolingLoad_Tot_Prev = coolingLoad_Tot_Next
1278
+ for _iter in 1..50
1279
+ break if delta.abs <= 0.001
1201
1280
 
1202
- hvac_final_values.Cool_Load_Lat, hvac_final_values.Cool_Load_Sens = calculate_sensible_latent_split(return_leakage_cfm, coolingLoad_Tot_Next, init_cool_load_lat)
1203
- hvac_final_values.Cool_Load_Tot = hvac_final_values.Cool_Load_Lat + hvac_final_values.Cool_Load_Sens
1281
+ cool_load_tot_prev = cool_load_tot_next
1204
1282
 
1205
- # Calculate the new cooling air flow rate
1206
- cool_Airflow = calc_airflow_rate(hvac_final_values.Cool_Load_Sens, (@cool_setpoint - hvac.LeavingAirTemp))
1283
+ cool_load_lat, cool_load_sens = calculate_sensible_latent_split(dse_Qr, cool_load_tot_next, init_cool_load_lat)
1284
+ cool_load_tot = cool_load_lat + cool_load_sens
1207
1285
 
1208
- hvac_final_values.Cool_Load_Ducts_Sens = hvac_final_values.Cool_Load_Sens - init_cool_load_sens
1209
- hvac_final_values.Cool_Load_Ducts_Tot = coolingLoad_Tot_Next - (init_cool_load_sens + init_cool_load_lat)
1286
+ # Calculate the new cooling air flow rate
1287
+ cool_cfm = calc_airflow_rate(cool_load_sens, (@cool_setpoint - hvac.LeavingAirTemp))
1210
1288
 
1211
- dse_Qs, dse_Qr = calc_ducts_leakages(hvac.Ducts, cool_Airflow)
1289
+ dse_Qs, dse_Qr = calc_ducts_leakages(hvac.Ducts, cool_cfm)
1212
1290
 
1213
- dse_DE, dse_dTe_cooling, hvac_final_values.Cool_Load_Ducts_Sens = calc_delivery_effectiveness_cooling(dse_Qs, dse_Qr, hvac.LeavingAirTemp, cool_Airflow, hvac_final_values.Cool_Load_Sens, dse_Tamb_cooling_s, dse_Tamb_cooling_r, dse_As, dse_Ar, @cool_setpoint, dse_Fregain_s, dse_Fregain_r, hvac_final_values.Cool_Load_Tot, dse_h_r, supply_r, return_r)
1291
+ dse_DE, dse_dTe_cooling, cool_duct_sens = calc_delivery_effectiveness_cooling(dse_Qs, dse_Qr, hvac.LeavingAirTemp, cool_cfm, cool_load_sens, dse_Tamb_cooling_s, dse_Tamb_cooling_r, dse_As, dse_Ar, @cool_setpoint, dse_Fregain_s, dse_Fregain_r, cool_load_tot, dse_h_r, supply_r, return_r)
1214
1292
 
1215
- coolingLoad_Tot_Next = (init_cool_load_sens + init_cool_load_lat) / dse_DE
1293
+ cool_load_tot_next = (init_cool_load_sens + init_cool_load_lat) / dse_DE
1216
1294
 
1217
- # Calculate the change since the last iteration
1218
- delta = (coolingLoad_Tot_Next - coolingLoad_Tot_Prev) / coolingLoad_Tot_Prev
1219
- end
1295
+ # Calculate the change since the last iteration
1296
+ delta = (cool_load_tot_next - cool_load_tot_prev) / cool_load_tot_prev
1220
1297
  end
1221
1298
 
1222
- # Calculate the air flow rate required for design conditions
1223
- hvac_final_values.Cool_Airflow = calc_airflow_rate(hvac_final_values.Cool_Load_Sens, (@cool_setpoint - hvac.LeavingAirTemp))
1299
+ ducts_cool_load_sens = cool_load_sens - init_cool_load_sens
1300
+ ducts_cool_load_lat = cool_load_lat - init_cool_load_lat
1224
1301
 
1225
- hvac_final_values.Cool_Load_Ducts_Lat = hvac_final_values.Cool_Load_Ducts_Tot - hvac_final_values.Cool_Load_Ducts_Sens
1302
+ bldg_design_loads.Cool_Ducts_Sens += ducts_cool_load_sens
1303
+ bldg_design_loads.Cool_Sens += ducts_cool_load_sens
1304
+ bldg_design_loads.Cool_Ducts_Lat += ducts_cool_load_lat
1305
+ bldg_design_loads.Cool_Lat += ducts_cool_load_lat
1306
+ bldg_design_loads.Cool_Tot += ducts_cool_load_sens + ducts_cool_load_lat
1226
1307
  end
1227
1308
 
1228
- def self.process_equipment_adjustments(hvac_final_values, weather, hvac)
1309
+ def self.apply_hvac_equipment_adjustments(hvac_sizing_values, weather, hvac, cfa)
1229
1310
  '''
1230
1311
  Equipment Adjustments
1231
1312
  '''
@@ -1233,458 +1314,656 @@ class HVACSizing
1233
1314
  underSizeLimit = 0.9
1234
1315
 
1235
1316
  # Cooling
1236
- if hvac.has_type([Constants.ObjectNameCentralAirConditioner,
1237
- Constants.ObjectNameAirSourceHeatPump,
1238
- Constants.ObjectNameMiniSplitHeatPump,
1239
- Constants.ObjectNameRoomAirConditioner,
1240
- Constants.ObjectNameGroundSourceHeatPump])
1241
1317
 
1242
- if hvac_final_values.Cool_Load_Tot < 0
1243
- hvac_final_values.Cool_Capacity = @min_cooling_capacity
1244
- hvac_final_values.Cool_Capacity_Sens = 0.78 * @min_cooling_capacity
1245
- hvac_final_values.Cool_Airflow = 400.0 * UnitConversions.convert(@min_cooling_capacity, 'Btu/hr', 'ton')
1246
- end
1318
+ # Calculate the air flow rate required for design conditions
1319
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(hvac_sizing_values.Cool_Load_Sens, (@cool_setpoint - hvac.LeavingAirTemp))
1247
1320
 
1248
- # Adjust the total cooling capacity to the rated conditions using performance curves
1249
- if not hvac.has_type(Constants.ObjectNameGroundSourceHeatPump)
1250
- enteringTemp = weather.design.CoolingDrybulb
1251
- else
1252
- enteringTemp = hvac.GSHP_HXCHWDesign
1253
- end
1321
+ if hvac_sizing_values.Cool_Load_Tot <= 0
1254
1322
 
1255
- if hvac.has_type([Constants.ObjectNameCentralAirConditioner,
1256
- Constants.ObjectNameAirSourceHeatPump])
1323
+ hvac_sizing_values.Cool_Capacity = 0.0
1324
+ hvac_sizing_values.Cool_Capacity_Sens = 0.0
1325
+ hvac_sizing_values.Cool_Airflow = 0.0
1257
1326
 
1258
- hvac.SizingSpeed = get_sizing_speed(hvac)
1259
- coefficients = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed]
1327
+ elsif [HPXML::HVACTypeCentralAirConditioner,
1328
+ HPXML::HVACTypeHeatPumpAirToAir].include? hvac.CoolType
1260
1329
 
1261
- totalCap_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, enteringTemp, coefficients)
1262
- coolCap_Rated = hvac_final_values.Cool_Load_Tot / totalCap_CurveValue
1330
+ enteringTemp = weather.design.CoolingDrybulb
1331
+ coefficients = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed]
1263
1332
 
1264
- sensCap_Rated = coolCap_Rated * hvac.SHRRated[hvac.SizingSpeed]
1333
+ totalCap_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, enteringTemp, coefficients)
1334
+ coolCap_Rated = hvac_sizing_values.Cool_Load_Tot / totalCap_CurveValue
1265
1335
 
1266
- sensibleCap_CurveValue = process_curve_fit(hvac_final_values.Cool_Airflow, hvac_final_values.Cool_Load_Tot, enteringTemp)
1267
- sensCap_Design = sensCap_Rated * sensibleCap_CurveValue
1268
- latCap_Design = [hvac_final_values.Cool_Load_Tot - sensCap_Design, 1.0].max
1336
+ sensCap_Rated = coolCap_Rated * hvac.SHRRated[hvac.SizingSpeed]
1269
1337
 
1270
- a_sens = @shr_biquadratic[0]
1271
- b_sens = @shr_biquadratic[1]
1272
- c_sens = @shr_biquadratic[3]
1273
- d_sens = @shr_biquadratic[5]
1338
+ sensibleCap_CurveValue = process_curve_fit(hvac_sizing_values.Cool_Airflow, hvac_sizing_values.Cool_Load_Tot, enteringTemp)
1339
+ sensCap_Design = sensCap_Rated * sensibleCap_CurveValue
1340
+ latCap_Design = [hvac_sizing_values.Cool_Load_Tot - sensCap_Design, 1.0].max
1274
1341
 
1275
- # Adjust Sizing
1276
- if latCap_Design < hvac_final_values.Cool_Load_Lat
1277
- # Size by MJ8 Latent load, return to rated conditions
1342
+ shr_biquadratic = get_shr_biquadratic
1343
+ a_sens = shr_biquadratic[0]
1344
+ b_sens = shr_biquadratic[1]
1345
+ c_sens = shr_biquadratic[3]
1346
+ d_sens = shr_biquadratic[5]
1278
1347
 
1279
- # Solve for the new sensible and total capacity at design conditions:
1280
- # CoolingLoad_Lat = cool_Capacity_Design - cool_Load_SensCap_Design
1281
- # solve the following for cool_Capacity_Design: SensCap_Design = SHRRated * cool_Capacity_Design / TotalCap_CurveValue * function(CFM/cool_Capacity_Design, ODB)
1282
- # substituting in CFM = cool_Load_SensCap_Design / (1.1 * ACF * (cool_setpoint - LAT))
1348
+ # Adjust Sizing
1349
+ if latCap_Design < hvac_sizing_values.Cool_Load_Lat
1350
+ # Size by MJ8 Latent load, return to rated conditions
1283
1351
 
1284
- cool_Load_SensCap_Design = hvac_final_values.Cool_Load_Lat / ((totalCap_CurveValue / hvac.SHRRated[hvac.SizingSpeed] - \
1285
- (UnitConversions.convert(b_sens, 'ton', 'Btu/hr') + UnitConversions.convert(d_sens, 'ton', 'Btu/hr') * enteringTemp) / \
1286
- (1.1 * @acf * (@cool_setpoint - hvac.LeavingAirTemp))) / \
1287
- (a_sens + c_sens * enteringTemp) - 1.0)
1352
+ # Solve for the new sensible and total capacity at design conditions:
1353
+ # CoolingLoad_Lat = cool_Capacity_Design - cool_Load_SensCap_Design
1354
+ # solve the following for cool_Capacity_Design: SensCap_Design = SHRRated * cool_Capacity_Design / TotalCap_CurveValue * function(CFM/cool_Capacity_Design, ODB)
1355
+ # substituting in CFM = cool_Load_SensCap_Design / (1.1 * ACF * (cool_setpoint - LAT))
1288
1356
 
1289
- cool_Capacity_Design = cool_Load_SensCap_Design + hvac_final_values.Cool_Load_Lat
1357
+ cool_Load_SensCap_Design = hvac_sizing_values.Cool_Load_Lat / ((totalCap_CurveValue / hvac.SHRRated[hvac.SizingSpeed] - \
1358
+ (UnitConversions.convert(b_sens, 'ton', 'Btu/hr') + UnitConversions.convert(d_sens, 'ton', 'Btu/hr') * enteringTemp) / \
1359
+ (1.1 * @acf * (@cool_setpoint - hvac.LeavingAirTemp))) / \
1360
+ (a_sens + c_sens * enteringTemp) - 1.0)
1290
1361
 
1291
- # The SHR of the equipment at the design condition
1292
- sHR_design = cool_Load_SensCap_Design / cool_Capacity_Design
1362
+ cool_Capacity_Design = cool_Load_SensCap_Design + hvac_sizing_values.Cool_Load_Lat
1293
1363
 
1294
- # If the adjusted equipment size is negative (occurs at altitude), use oversize limit (the adjustment
1295
- # almost always hits the oversize limit in this case, making this a safe assumption)
1296
- if (cool_Capacity_Design < 0) || (cool_Load_SensCap_Design < 0)
1297
- cool_Capacity_Design = hvac.OverSizeLimit * hvac_final_values.Cool_Load_Tot
1298
- end
1364
+ # The SHR of the equipment at the design condition
1365
+ sHR_design = cool_Load_SensCap_Design / cool_Capacity_Design
1299
1366
 
1300
- # Limit total capacity to oversize limit
1301
- cool_Capacity_Design = [cool_Capacity_Design, hvac.OverSizeLimit * hvac_final_values.Cool_Load_Tot].min
1367
+ # If the adjusted equipment size is negative (occurs at altitude), use oversize limit (the adjustment
1368
+ # almost always hits the oversize limit in this case, making this a safe assumption)
1369
+ if (cool_Capacity_Design < 0) || (cool_Load_SensCap_Design < 0)
1370
+ cool_Capacity_Design = hvac.OverSizeLimit * hvac_sizing_values.Cool_Load_Tot
1371
+ end
1302
1372
 
1303
- # Determine the final sensible capacity at design using the SHR
1304
- cool_Load_SensCap_Design = sHR_design * cool_Capacity_Design
1373
+ # Limit total capacity to oversize limit
1374
+ cool_Capacity_Design = [cool_Capacity_Design, hvac.OverSizeLimit * hvac_sizing_values.Cool_Load_Tot].min
1305
1375
 
1306
- # Calculate the final air flow rate using final sensible capacity at design
1307
- hvac_final_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1376
+ # Determine the final sensible capacity at design using the SHR
1377
+ cool_Load_SensCap_Design = sHR_design * cool_Capacity_Design
1308
1378
 
1309
- # Determine rated capacities
1310
- hvac_final_values.Cool_Capacity = cool_Capacity_Design / totalCap_CurveValue
1311
- hvac_final_values.Cool_Capacity_Sens = hvac_final_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1379
+ # Calculate the final air flow rate using final sensible capacity at design
1380
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1312
1381
 
1313
- elsif sensCap_Design < underSizeLimit * hvac_final_values.Cool_Load_Sens
1314
- # Size by MJ8 Sensible load, return to rated conditions, find Sens with SHRRated. Limit total
1315
- # capacity to oversizing limit
1382
+ # Determine rated capacities
1383
+ hvac_sizing_values.Cool_Capacity = cool_Capacity_Design / totalCap_CurveValue
1384
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1316
1385
 
1317
- sensCap_Design = underSizeLimit * hvac_final_values.Cool_Load_Sens
1386
+ elsif sensCap_Design < underSizeLimit * hvac_sizing_values.Cool_Load_Sens
1387
+ # Size by MJ8 Sensible load, return to rated conditions, find Sens with SHRRated. Limit total
1388
+ # capacity to oversizing limit
1318
1389
 
1319
- # Solve for the new total system capacity at design conditions:
1320
- # SensCap_Design = SensCap_Rated * SensibleCap_CurveValue
1321
- # = SHRRated * cool_Capacity_Design / TotalCap_CurveValue * SensibleCap_CurveValue
1322
- # = SHRRated * cool_Capacity_Design / TotalCap_CurveValue * function(CFM/cool_Capacity_Design, ODB)
1390
+ sensCap_Design = underSizeLimit * hvac_sizing_values.Cool_Load_Sens
1323
1391
 
1324
- cool_Capacity_Design = (sensCap_Design / (hvac.SHRRated[hvac.SizingSpeed] / totalCap_CurveValue) - \
1325
- (b_sens * UnitConversions.convert(hvac_final_values.Cool_Airflow, 'ton', 'Btu/hr') + \
1326
- d_sens * UnitConversions.convert(hvac_final_values.Cool_Airflow, 'ton', 'Btu/hr') * enteringTemp)) / \
1327
- (a_sens + c_sens * enteringTemp)
1392
+ # Solve for the new total system capacity at design conditions:
1393
+ # SensCap_Design = SensCap_Rated * SensibleCap_CurveValue
1394
+ # = SHRRated * cool_Capacity_Design / TotalCap_CurveValue * SensibleCap_CurveValue
1395
+ # = SHRRated * cool_Capacity_Design / TotalCap_CurveValue * function(CFM/cool_Capacity_Design, ODB)
1328
1396
 
1329
- # Limit total capacity to oversize limit
1330
- cool_Capacity_Design = [cool_Capacity_Design, hvac.OverSizeLimit * hvac_final_values.Cool_Load_Tot].min
1397
+ cool_Capacity_Design = (sensCap_Design / (hvac.SHRRated[hvac.SizingSpeed] / totalCap_CurveValue) - \
1398
+ (b_sens * UnitConversions.convert(hvac_sizing_values.Cool_Airflow, 'ton', 'Btu/hr') + \
1399
+ d_sens * UnitConversions.convert(hvac_sizing_values.Cool_Airflow, 'ton', 'Btu/hr') * enteringTemp)) / \
1400
+ (a_sens + c_sens * enteringTemp)
1331
1401
 
1332
- hvac_final_values.Cool_Capacity = cool_Capacity_Design / totalCap_CurveValue
1333
- hvac_final_values.Cool_Capacity_Sens = hvac_final_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1402
+ # Limit total capacity to oversize limit
1403
+ cool_Capacity_Design = [cool_Capacity_Design, hvac.OverSizeLimit * hvac_sizing_values.Cool_Load_Tot].min
1334
1404
 
1335
- # Recalculate the air flow rate in case the oversizing limit has been used
1336
- cool_Load_SensCap_Design = hvac_final_values.Cool_Capacity_Sens * sensibleCap_CurveValue
1337
- hvac_final_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1405
+ hvac_sizing_values.Cool_Capacity = cool_Capacity_Design / totalCap_CurveValue
1406
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1338
1407
 
1339
- else
1340
- hvac_final_values.Cool_Capacity = hvac_final_values.Cool_Load_Tot / totalCap_CurveValue
1341
- hvac_final_values.Cool_Capacity_Sens = hvac_final_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1408
+ # Recalculate the air flow rate in case the oversizing limit has been used
1409
+ cool_Load_SensCap_Design = hvac_sizing_values.Cool_Capacity_Sens * sensibleCap_CurveValue
1410
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1342
1411
 
1343
- cool_Load_SensCap_Design = hvac_final_values.Cool_Capacity_Sens * sensibleCap_CurveValue
1344
- hvac_final_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1345
- end
1412
+ else
1413
+ hvac_sizing_values.Cool_Capacity = hvac_sizing_values.Cool_Load_Tot / totalCap_CurveValue
1414
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1346
1415
 
1347
- # Ensure the air flow rate is in between 200 and 500 cfm/ton.
1348
- # Reset the air flow rate (with a safety margin), if required.
1349
- if hvac_final_values.Cool_Airflow / UnitConversions.convert(hvac_final_values.Cool_Capacity, 'Btu/hr', 'ton') > 500
1350
- hvac_final_values.Cool_Airflow = 499.0 * UnitConversions.convert(hvac_final_values.Cool_Capacity, 'Btu/hr', 'ton') # CFM
1351
- elsif hvac_final_values.Cool_Airflow / UnitConversions.convert(hvac_final_values.Cool_Capacity, 'Btu/hr', 'ton') < 200
1352
- hvac_final_values.Cool_Airflow = 201.0 * UnitConversions.convert(hvac_final_values.Cool_Capacity, 'Btu/hr', 'ton') # CFM
1353
- end
1416
+ cool_Load_SensCap_Design = hvac_sizing_values.Cool_Capacity_Sens * sensibleCap_CurveValue
1417
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1418
+ end
1354
1419
 
1355
- elsif hvac.has_type(Constants.ObjectNameMiniSplitHeatPump)
1420
+ # Ensure the air flow rate is in between 200 and 500 cfm/ton.
1421
+ # Reset the air flow rate (with a safety margin), if required.
1422
+ if hvac_sizing_values.Cool_Airflow / UnitConversions.convert(hvac_sizing_values.Cool_Capacity, 'Btu/hr', 'ton') > 500
1423
+ hvac_sizing_values.Cool_Airflow = 499.0 * UnitConversions.convert(hvac_sizing_values.Cool_Capacity, 'Btu/hr', 'ton') # CFM
1424
+ elsif hvac_sizing_values.Cool_Airflow / UnitConversions.convert(hvac_sizing_values.Cool_Capacity, 'Btu/hr', 'ton') < 200
1425
+ hvac_sizing_values.Cool_Airflow = 201.0 * UnitConversions.convert(hvac_sizing_values.Cool_Capacity, 'Btu/hr', 'ton') # CFM
1426
+ end
1356
1427
 
1357
- hvac.SizingSpeed = get_sizing_speed(hvac)
1358
- coefficients = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed]
1428
+ elsif [HPXML::HVACTypeHeatPumpMiniSplit,
1429
+ HPXML::HVACTypeMiniSplitAirConditioner].include? hvac.CoolType
1359
1430
 
1360
- totalCap_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, enteringTemp, coefficients)
1431
+ enteringTemp = weather.design.CoolingDrybulb
1432
+ coefficients = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed]
1361
1433
 
1362
- hvac_final_values.Cool_Capacity = (hvac_final_values.Cool_Load_Tot / totalCap_CurveValue)
1363
- hvac_final_values.Cool_Capacity_Sens = hvac_final_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1364
- hvac_final_values.Cool_Airflow = hvac.RatedCFMperTonCooling[-1] * UnitConversions.convert(hvac_final_values.Cool_Capacity, 'Btu/hr', 'ton')
1434
+ totalCap_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, enteringTemp, coefficients)
1365
1435
 
1366
- elsif hvac.has_type(Constants.ObjectNameRoomAirConditioner)
1436
+ hvac_sizing_values.Cool_Capacity = (hvac_sizing_values.Cool_Load_Tot / totalCap_CurveValue)
1437
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1438
+ hvac_sizing_values.Cool_Airflow = hvac.RatedCFMperTonCooling[-1] * hvac.CapacityRatioCooling[-1] * UnitConversions.convert(hvac_sizing_values.Cool_Capacity, 'Btu/hr', 'ton')
1367
1439
 
1368
- hvac.SizingSpeed = 0
1369
- totalCap_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, enteringTemp, hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed])
1440
+ elsif hvac.CoolType == HPXML::HVACTypeRoomAirConditioner
1370
1441
 
1371
- hvac_final_values.Cool_Capacity = hvac_final_values.Cool_Load_Tot / totalCap_CurveValue
1372
- hvac_final_values.Cool_Capacity_Sens = hvac_final_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1373
- hvac_final_values.Cool_Airflow = hvac.RatedCFMperTonCooling[hvac.SizingSpeed] * UnitConversions.convert(hvac_final_values.Cool_Capacity, 'Btu/hr', 'ton')
1442
+ enteringTemp = weather.design.CoolingDrybulb
1443
+ totalCap_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, enteringTemp, hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed])
1374
1444
 
1375
- elsif hvac.has_type(Constants.ObjectNameGroundSourceHeatPump)
1445
+ hvac_sizing_values.Cool_Capacity = hvac_sizing_values.Cool_Load_Tot / totalCap_CurveValue
1446
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1447
+ hvac_sizing_values.Cool_Airflow = hvac.RatedCFMperTonCooling[hvac.SizingSpeed] * UnitConversions.convert(hvac_sizing_values.Cool_Capacity, 'Btu/hr', 'ton')
1376
1448
 
1377
- # Single speed as current
1378
- hvac.SizingSpeed = 0
1379
- totalCap_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, enteringTemp, hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed])
1380
- sensibleCap_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, enteringTemp, hvac.COOL_SH_FT_SPEC[hvac.SizingSpeed])
1381
- bypassFactor_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, @cool_setpoint, hvac.COIL_BF_FT_SPEC[hvac.SizingSpeed])
1449
+ elsif hvac.CoolType == HPXML::HVACTypeHeatPumpGroundToAir
1450
+ coil_bf = gshp_coil_bf
1451
+ enteringTemp = hvac.GSHP_design_chw
1382
1452
 
1383
- hvac_final_values.Cool_Capacity = hvac_final_values.Cool_Load_Tot / totalCap_CurveValue # Note: cool_Capacity_Design = hvac_final_values.Cool_Load_Tot
1384
- hvac_final_values.Cool_Capacity_Sens = hvac_final_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1453
+ # Neglecting the water flow rate for now because it's not available yet. Air flow rate is pre-adjusted values.
1454
+ design_wb_temp = UnitConversions.convert(@wetbulb_indoor_cooling, 'f', 'k')
1455
+ design_db_temp = UnitConversions.convert(@cool_setpoint, 'f', 'k')
1456
+ design_w_temp = UnitConversions.convert(enteringTemp, 'f', 'k')
1457
+ design_vfr_air = UnitConversions.convert(hvac_sizing_values.Cool_Airflow, 'cfm', 'm^3/s')
1385
1458
 
1386
- cool_Load_SensCap_Design = (hvac_final_values.Cool_Capacity_Sens * sensibleCap_CurveValue /
1387
- (1.0 + (1.0 - hvac.CoilBF * bypassFactor_CurveValue) *
1388
- (80.0 - @cool_setpoint) / (@cool_setpoint - hvac.LeavingAirTemp)))
1389
- cool_Load_LatCap_Design = hvac_final_values.Cool_Load_Tot - cool_Load_SensCap_Design
1459
+ totalCap_CurveValue, sensibleCap_CurveValue = calc_gshp_clg_curve_value(hvac, design_wb_temp, design_db_temp, design_w_temp, design_vfr_air, nil)
1390
1460
 
1391
- # Adjust Sizing so that coil sensible at design >= CoolingLoad_MJ8_Sens, and coil latent at design >= CoolingLoad_MJ8_Lat, and equipment SHRRated is maintained.
1392
- cool_Load_SensCap_Design = [cool_Load_SensCap_Design, hvac_final_values.Cool_Load_Sens].max
1393
- cool_Load_LatCap_Design = [cool_Load_LatCap_Design, hvac_final_values.Cool_Load_Lat].max
1394
- cool_Capacity_Design = cool_Load_SensCap_Design + cool_Load_LatCap_Design
1461
+ bypassFactor_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, @cool_setpoint, gshp_coil_bf_ft_spec)
1395
1462
 
1396
- # Limit total capacity via oversizing limit
1397
- cool_Capacity_Design = [cool_Capacity_Design, hvac.OverSizeLimit * hvac_final_values.Cool_Load_Tot].min
1398
- hvac_final_values.Cool_Capacity = cool_Capacity_Design / totalCap_CurveValue
1399
- hvac_final_values.Cool_Capacity_Sens = hvac_final_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1463
+ hvac_sizing_values.Cool_Capacity = hvac_sizing_values.Cool_Load_Tot / totalCap_CurveValue # Note: cool_Capacity_Design = hvac_sizing_values.Cool_Load_Tot
1464
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1400
1465
 
1401
- # Recalculate the air flow rate in case the oversizing limit has been used
1402
- cool_Load_SensCap_Design = (hvac_final_values.Cool_Capacity_Sens * sensibleCap_CurveValue /
1403
- (1.0 + (1.0 - hvac.CoilBF * bypassFactor_CurveValue) *
1404
- (80.0 - @cool_setpoint) / (@cool_setpoint - hvac.LeavingAirTemp)))
1405
- hvac_final_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1406
- else
1466
+ cool_Load_SensCap_Design = (hvac_sizing_values.Cool_Capacity_Sens * sensibleCap_CurveValue /
1467
+ (1.0 + (1.0 - coil_bf * bypassFactor_CurveValue) *
1468
+ (80.0 - @cool_setpoint) / (@cool_setpoint - hvac.LeavingAirTemp)))
1469
+ cool_Load_LatCap_Design = hvac_sizing_values.Cool_Load_Tot - cool_Load_SensCap_Design
1407
1470
 
1408
- fail 'Unexpected cooling system.'
1409
- end
1471
+ # Adjust Sizing so that coil sensible at design >= CoolingLoad_MJ8_Sens, and coil latent at design >= CoolingLoad_MJ8_Lat, and equipment SHRRated is maintained.
1472
+ cool_Load_SensCap_Design = [cool_Load_SensCap_Design, hvac_sizing_values.Cool_Load_Sens].max
1473
+ cool_Load_LatCap_Design = [cool_Load_LatCap_Design, hvac_sizing_values.Cool_Load_Lat].max
1474
+ cool_Capacity_Design = cool_Load_SensCap_Design + cool_Load_LatCap_Design
1410
1475
 
1411
- elsif hvac.has_type(Constants.ObjectNameEvaporativeCooler)
1412
- hvac_final_values.Cool_Capacity = hvac_final_values.Cool_Load_Tot
1413
- hvac_final_values.Cool_Capacity_Sens = hvac_final_values.Cool_Load_Sens
1476
+ # Limit total capacity via oversizing limit
1477
+ cool_Capacity_Design = [cool_Capacity_Design, hvac.OverSizeLimit * hvac_sizing_values.Cool_Load_Tot].min
1478
+ hvac_sizing_values.Cool_Capacity = cool_Capacity_Design / totalCap_CurveValue
1479
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1480
+
1481
+ # Recalculate the air flow rate in case the oversizing limit has been used
1482
+ cool_Load_SensCap_Design = (hvac_sizing_values.Cool_Capacity_Sens * sensibleCap_CurveValue /
1483
+ (1.0 + (1.0 - coil_bf * bypassFactor_CurveValue) *
1484
+ (80.0 - @cool_setpoint) / (@cool_setpoint - hvac.LeavingAirTemp)))
1485
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1486
+
1487
+ elsif hvac.CoolType == HPXML::HVACTypeEvaporativeCooler
1488
+
1489
+ hvac_sizing_values.Cool_Capacity = hvac_sizing_values.Cool_Load_Tot
1490
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Load_Sens
1414
1491
  if @cool_setpoint - hvac.LeavingAirTemp > 0
1415
- hvac_final_values.Cool_Airflow = calc_airflow_rate(hvac_final_values.Cool_Load_Sens, (@cool_setpoint - hvac.LeavingAirTemp))
1492
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(hvac_sizing_values.Cool_Load_Sens, (@cool_setpoint - hvac.LeavingAirTemp))
1416
1493
  else
1417
- cfa = UnitConversions.convert(@spaces[HPXML::LocationLivingSpace].floorArea, 'm^2', 'ft^2')
1418
- hvac_final_values.Cool_Airflow = cfa * 2.0 # Use industry rule of thumb sizing method adopted by HEScore
1494
+ hvac_sizing_values.Cool_Airflow = cfa * 2.0 # Use industry rule of thumb sizing method adopted by HEScore
1419
1495
  end
1420
1496
 
1421
- elsif hvac.has_type(Constants.ObjectNameWaterLoopHeatPump)
1497
+ elsif hvac.CoolType == HPXML::HVACTypeHeatPumpWaterLoopToAir
1498
+
1422
1499
  # Model only currently used for heating
1423
- hvac_final_values.Cool_Capacity = 0.0
1424
- hvac_final_values.Cool_Capacity_Sens = 0.0
1425
- hvac_final_values.Cool_Airflow = 0.0
1500
+ hvac_sizing_values.Cool_Capacity = 0.0
1501
+ hvac_sizing_values.Cool_Capacity_Sens = 0.0
1502
+ hvac_sizing_values.Cool_Airflow = 0.0
1503
+
1504
+ elsif hvac.CoolType.nil?
1505
+
1506
+ hvac_sizing_values.Cool_Capacity = 0.0
1507
+ hvac_sizing_values.Cool_Capacity_Sens = 0.0
1508
+ hvac_sizing_values.Cool_Airflow = 0.0
1426
1509
 
1427
1510
  else
1428
- hvac_final_values.Cool_Capacity = 0.0
1429
- hvac_final_values.Cool_Capacity_Sens = 0.0
1430
- hvac_final_values.Cool_Airflow = 0.0
1511
+
1512
+ fail "Unexpected cooling type: #{hvac.CoolType}."
1431
1513
 
1432
1514
  end
1433
1515
 
1434
1516
  # Heating
1435
- if hvac.has_type(Constants.ObjectNameAirSourceHeatPump)
1436
- hvac_final_values = process_heat_pump_adjustment(hvac_final_values, weather, hvac, totalCap_CurveValue)
1517
+ if hvac_sizing_values.Heat_Load <= 0
1437
1518
 
1438
- hvac_final_values.Heat_Capacity = hvac_final_values.Cool_Capacity
1439
- hvac_final_values.Heat_Capacity_Supp = hvac_final_values.Heat_Load
1519
+ hvac_sizing_values.Heat_Capacity = 0.0
1520
+ hvac_sizing_values.Heat_Capacity_Supp = 0.0
1521
+ hvac_sizing_values.Heat_Airflow = 0.0
1440
1522
 
1441
- if hvac_final_values.Cool_Capacity > @min_cooling_capacity
1442
- hvac_final_values.Heat_Airflow = calc_airflow_rate(hvac_final_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1523
+ elsif hvac.HeatType == HPXML::HVACTypeHeatPumpAirToAir
1524
+
1525
+ if hvac_sizing_values.Cool_Capacity > 0
1526
+ process_heat_pump_adjustment(hvac_sizing_values, weather, hvac, totalCap_CurveValue)
1527
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Cool_Capacity
1528
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Load
1443
1529
  else
1444
- hvac_final_values.Heat_Airflow = calc_airflow_rate(hvac_final_values.Heat_Capacity_Supp, (hvac.SupplyAirTemp - @heat_setpoint))
1530
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1531
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Load
1445
1532
  end
1533
+ hvac_sizing_values.Heat_Airflow = calc_airflow_rate(hvac_sizing_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1446
1534
 
1447
- elsif hvac.has_type(Constants.ObjectNameMiniSplitHeatPump)
1448
- hvac_final_values = process_heat_pump_adjustment(hvac_final_values, weather, hvac, totalCap_CurveValue)
1535
+ elsif hvac.HeatType == HPXML::HVACTypeHeatPumpMiniSplit
1449
1536
 
1450
- hvac_final_values.Heat_Capacity = [hvac_final_values.Cool_Capacity + hvac.HeatingCapacityOffset, Constants.small].max
1451
- hvac_final_values.Heat_Capacity_Supp = hvac_final_values.Heat_Load
1537
+ if hvac_sizing_values.Cool_Capacity > 0
1538
+ process_heat_pump_adjustment(hvac_sizing_values, weather, hvac, totalCap_CurveValue)
1539
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Cool_Capacity
1540
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Load
1541
+ else
1542
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1543
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Load
1544
+ end
1545
+ hvac_sizing_values.Heat_Airflow = hvac.RatedCFMperTonHeating[-1] * hvac.CapacityRatioHeating[-1] * UnitConversions.convert(hvac_sizing_values.Heat_Capacity, 'Btu/hr', 'ton') # Maximum air flow under heating operation
1452
1546
 
1453
- hvac_final_values.Heat_Airflow = hvac.RatedCFMperTonHeating[-1] * UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'ton') # Maximum air flow under heating operation
1547
+ elsif hvac.HeatType == HPXML::HVACTypeHeatPumpGroundToAir
1454
1548
 
1455
- elsif hvac.has_type(Constants.ObjectNameGroundSourceHeatPump)
1456
- hvac_final_values.Heat_Capacity = hvac_final_values.Heat_Load
1457
- hvac_final_values.Heat_Capacity_Supp = hvac_final_values.Heat_Load
1549
+ if hvac_sizing_values.Cool_Capacity > 0
1550
+ coil_bf = gshp_coil_bf
1551
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1552
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Load
1458
1553
 
1459
- # For single stage compressor, when heating capacity is much larger than cooling capacity,
1460
- # in order to avoid frequent cycling in cooling mode, heating capacity is derated to 75%.
1461
- if hvac_final_values.Heat_Capacity >= 1.5 * hvac_final_values.Cool_Capacity
1462
- hvac_final_values.Heat_Capacity = hvac_final_values.Heat_Load * 0.75
1463
- elsif hvac_final_values.Heat_Capacity < hvac_final_values.Cool_Capacity
1464
- hvac_final_values.Heat_Capacity_Supp = hvac_final_values.Heat_Capacity
1554
+ # For single stage compressor, when heating capacity is much larger than cooling capacity,
1555
+ # in order to avoid frequent cycling in cooling mode, heating capacity is derated to 75%.
1556
+ if hvac_sizing_values.Heat_Capacity >= 1.5 * hvac_sizing_values.Cool_Capacity
1557
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load * 0.75
1558
+ elsif hvac_sizing_values.Heat_Capacity < hvac_sizing_values.Cool_Capacity
1559
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Capacity
1560
+ end
1561
+
1562
+ hvac_sizing_values.Cool_Capacity = [hvac_sizing_values.Cool_Capacity, hvac_sizing_values.Heat_Capacity].max
1563
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Cool_Capacity
1564
+
1565
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1566
+ cool_Load_SensCap_Design = (hvac_sizing_values.Cool_Capacity_Sens * sensibleCap_CurveValue /
1567
+ (1.0 + (1.0 - coil_bf * bypassFactor_CurveValue) *
1568
+ (80.0 - @cool_setpoint) / (@cool_setpoint - hvac.LeavingAirTemp)))
1569
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1570
+ else
1571
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1572
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Load
1465
1573
  end
1574
+ hvac_sizing_values.Heat_Airflow = calc_airflow_rate(hvac_sizing_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1466
1575
 
1467
- hvac_final_values.Cool_Capacity = [hvac_final_values.Cool_Capacity, hvac_final_values.Heat_Capacity].max
1468
- hvac_final_values.Heat_Capacity = hvac_final_values.Cool_Capacity
1576
+ elsif hvac.HeatType == HPXML::HVACTypeHeatPumpWaterLoopToAir
1469
1577
 
1470
- hvac_final_values.Cool_Capacity_Sens = hvac_final_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1471
- cool_Load_SensCap_Design = (hvac_final_values.Cool_Capacity_Sens * sensibleCap_CurveValue /
1472
- (1.0 + (1.0 - hvac.CoilBF * bypassFactor_CurveValue) *
1473
- (80.0 - @cool_setpoint) / (@cool_setpoint - hvac.LeavingAirTemp)))
1474
- hvac_final_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1475
- hvac_final_values.Heat_Airflow = calc_airflow_rate(hvac_final_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1578
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1579
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Load
1476
1580
 
1477
- elsif hvac.has_type(Constants.ObjectNameWaterLoopHeatPump)
1478
- hvac_final_values.Heat_Capacity = hvac_final_values.Heat_Load
1479
- hvac_final_values.Heat_Capacity_Supp = hvac_final_values.Heat_Load
1581
+ hvac_sizing_values.Heat_Airflow = calc_airflow_rate(hvac_sizing_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1480
1582
 
1481
- hvac_final_values.Heat_Airflow = calc_airflow_rate(hvac_final_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1583
+ elsif hvac.HeatType == HPXML::HVACTypeFurnace
1482
1584
 
1483
- elsif hvac.has_type(Constants.ObjectNameFurnace)
1484
- hvac_final_values.Heat_Capacity = hvac_final_values.Heat_Load
1485
- hvac_final_values.Heat_Capacity_Supp = 0.0
1585
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1586
+ hvac_sizing_values.Heat_Capacity_Supp = 0.0
1486
1587
 
1487
- hvac_final_values.Heat_Airflow = calc_airflow_rate(hvac_final_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1588
+ hvac_sizing_values.Heat_Airflow = calc_airflow_rate(hvac_sizing_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1488
1589
 
1489
- elsif hvac.has_type(Constants.ObjectNameUnitHeater)
1490
- hvac_final_values.Heat_Capacity = hvac_final_values.Heat_Load
1491
- hvac_final_values.Heat_Capacity_Supp = 0.0
1590
+ elsif [HPXML::HVACTypeStove,
1591
+ HPXML::HVACTypePortableHeater,
1592
+ HPXML::HVACTypeFixedHeater,
1593
+ HPXML::HVACTypeWallFurnace,
1594
+ HPXML::HVACTypeFloorFurnace,
1595
+ HPXML::HVACTypeFireplace].include? hvac.HeatType
1596
+
1597
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1598
+ hvac_sizing_values.Heat_Capacity_Supp = 0.0
1492
1599
 
1493
1600
  if hvac.RatedCFMperTonHeating[0] > 0
1494
1601
  # Fixed airflow rate
1495
- hvac_final_values.Heat_Airflow = UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'ton') * hvac.RatedCFMperTonHeating[0]
1602
+ # FIXME: Is this still needed?
1603
+ hvac_sizing_values.Heat_Airflow = UnitConversions.convert(hvac_sizing_values.Heat_Capacity, 'Btu/hr', 'ton') * hvac.RatedCFMperTonHeating[0]
1496
1604
  else
1497
1605
  # Autosized airflow rate
1498
- hvac_final_values.Heat_Airflow = calc_airflow_rate(hvac_final_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1606
+ hvac_sizing_values.Heat_Airflow = calc_airflow_rate(hvac_sizing_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1499
1607
  end
1500
1608
 
1501
- elsif hvac.has_type([Constants.ObjectNameBoiler,
1502
- Constants.ObjectNameElectricBaseboard])
1503
- hvac_final_values.Heat_Capacity = hvac_final_values.Heat_Load
1504
- hvac_final_values.Heat_Capacity_Supp = 0.0
1505
- hvac_final_values.Heat_Airflow = 0.0
1609
+ elsif [HPXML::HVACTypeBoiler,
1610
+ HPXML::HVACTypeElectricResistance].include? hvac.HeatType
1611
+
1612
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1613
+ hvac_sizing_values.Heat_Capacity_Supp = 0.0
1614
+ hvac_sizing_values.Heat_Airflow = 0.0
1615
+
1616
+ elsif hvac.HeatType.nil?
1617
+
1618
+ hvac_sizing_values.Heat_Capacity = 0.0
1619
+ hvac_sizing_values.Heat_Capacity_Supp = 0.0
1620
+ hvac_sizing_values.Heat_Airflow = 0.0
1506
1621
 
1507
1622
  else
1508
- hvac_final_values.Heat_Capacity = 0.0
1509
- hvac_final_values.Heat_Capacity_Supp = 0.0
1510
- hvac_final_values.Heat_Airflow = 0.0
1623
+
1624
+ fail "Unexpected heating type: #{hvac.HeatType}."
1511
1625
 
1512
1626
  end
1513
1627
  end
1514
1628
 
1515
- def self.process_fixed_equipment(hvac_final_values, hvac)
1629
+ def self.apply_hvac_installation_quality(hvac_sizing_values, weather, hvac)
1630
+ # Increases the autosized heating/cooling capacities to account for any reduction
1631
+ # in capacity due to HVAC installation quality. This is done to prevent causing
1632
+ # unmet loads.
1633
+
1634
+ return unless [HPXML::HVACTypeCentralAirConditioner,
1635
+ HPXML::HVACTypeHeatPumpAirToAir,
1636
+ HPXML::HVACTypeHeatPumpMiniSplit,
1637
+ HPXML::HVACTypeMiniSplitAirConditioner,
1638
+ HPXML::HVACTypeHeatPumpGroundToAir].include? hvac.CoolType
1639
+ return if (hvac.ChargeDefectRatio.to_f.abs < 0.001) && (hvac.AirflowDefectRatioCooling.to_f.abs < 0.001) && (hvac.AirflowDefectRatioHeating.to_f.abs < 0.001)
1640
+
1641
+ tin_cool = UnitConversions.convert(@cool_setpoint, 'F', 'C')
1642
+ tin_heat = UnitConversions.convert(@heat_setpoint, 'F', 'C')
1643
+
1644
+ tout_cool = UnitConversions.convert(weather.design.CoolingDrybulb, 'F', 'C')
1645
+ tout_heat = UnitConversions.convert(weather.design.HeatingDrybulb, 'F', 'C')
1646
+
1647
+ if hvac.CoolType == HPXML::HVACTypeHeatPumpGroundToAir
1648
+ if hvac.CoolingLoadFraction > 0
1649
+ # Cooling
1650
+ coil_bf = gshp_coil_bf
1651
+ # Calculate curve point w/ and w/o defect ratios
1652
+ design_wb_temp = UnitConversions.convert(@wetbulb_indoor_cooling, 'f', 'k')
1653
+ design_db_temp = UnitConversions.convert(@cool_setpoint, 'f', 'k')
1654
+ design_w_temp = UnitConversions.convert(hvac.GSHP_design_chw, 'f', 'k')
1655
+ design_vfr_air = UnitConversions.convert(hvac_sizing_values.Cool_Airflow, 'cfm', 'm^3/s')
1656
+ design_vfr_air_defect = UnitConversions.convert(hvac_sizing_values.Cool_Airflow, 'cfm', 'm^3/s') * (1 + hvac.AirflowDefectRatioCooling)
1657
+ # calculate water flow based on current capacity.
1658
+ loop_flow = [1.0, UnitConversions.convert([hvac_sizing_values.Heat_Capacity, hvac_sizing_values.Cool_Capacity].max, 'Btu/hr', 'ton')].max.floor * 3.0
1659
+ loop_flow_m3s = UnitConversions.convert(loop_flow, 'gal/min', 'm^3/s')
1660
+
1661
+ totalCap_CurveValue, sensibleCap_CurveValue = calc_gshp_clg_curve_value(hvac, design_wb_temp, design_db_temp, design_w_temp, design_vfr_air, loop_flow_m3s)
1662
+ totalCap_CurveValue_d, sensibleCap_CurveValue_d = calc_gshp_clg_curve_value(hvac, design_wb_temp, design_db_temp, design_w_temp, design_vfr_air_defect, loop_flow_m3s)
1663
+
1664
+ cap_clg_ratio = 1 / (totalCap_CurveValue_d / totalCap_CurveValue)
1665
+ if cap_clg_ratio > 1
1666
+ hvac_sizing_values.Cool_Capacity *= cap_clg_ratio
1667
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1668
+ bypassFactor_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, @cool_setpoint, gshp_coil_bf_ft_spec)
1669
+
1670
+ cool_Load_SensCap_Design = (hvac_sizing_values.Cool_Capacity_Sens * sensibleCap_CurveValue /
1671
+ (1.0 + (1.0 - coil_bf * bypassFactor_CurveValue) *
1672
+ (80.0 - @cool_setpoint) / (@cool_setpoint - hvac.LeavingAirTemp)))
1673
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1674
+ end
1675
+ end
1676
+
1677
+ # Heating
1678
+ if hvac.HeatingLoadFraction > 0
1679
+ # Calculate curve point w/ and w/o defect ratios
1680
+ design_db_temp = UnitConversions.convert(@heat_setpoint, 'f', 'k')
1681
+ design_w_temp = UnitConversions.convert(hvac.GSHP_design_chw, 'f', 'k')
1682
+ design_vfr_air = UnitConversions.convert(hvac_sizing_values.Heat_Airflow, 'cfm', 'm^3/s')
1683
+ design_vfr_air_defect = UnitConversions.convert(hvac_sizing_values.Heat_Airflow, 'cfm', 'm^3/s') * (1 + hvac.AirflowDefectRatioHeating)
1684
+ # calculate water flow based on current capacity.
1685
+ loop_flow = [1.0, UnitConversions.convert([hvac_sizing_values.Heat_Capacity, hvac_sizing_values.Cool_Capacity].max, 'Btu/hr', 'ton')].max.floor * 3.0
1686
+ loop_flow_m3s = UnitConversions.convert(loop_flow, 'gal/min', 'm^3/s')
1687
+
1688
+ totalCap_CurveValue = calc_gshp_htg_curve_value(hvac, design_db_temp, design_w_temp, design_vfr_air, loop_flow_m3s)
1689
+ totalCap_CurveValue_d = calc_gshp_htg_curve_value(hvac, design_db_temp, design_w_temp, design_vfr_air_defect, loop_flow_m3s)
1690
+
1691
+ cap_htg_ratio = 1 / (totalCap_CurveValue_d / totalCap_CurveValue)
1692
+ if cap_htg_ratio > 1
1693
+ hvac_sizing_values.Heat_Capacity *= cap_htg_ratio
1694
+ hvac_sizing_values.Heat_Airflow = calc_airflow_rate(hvac_sizing_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1695
+ end
1696
+ end
1697
+ else
1698
+ f_ch = hvac.ChargeDefectRatio.round(3)
1699
+
1700
+ # Cooling
1701
+ if [HPXML::HVACTypeHeatPumpAirToAir,
1702
+ HPXML::HVACTypeCentralAirConditioner,
1703
+ HPXML::HVACTypeHeatPumpMiniSplit,
1704
+ HPXML::HVACTypeMiniSplitAirConditioner].include?(hvac.CoolType) && hvac.CoolingLoadFraction > 0
1705
+ cool_airflow_rated_defect_ratio = []
1706
+ cool_airflow_rated_ratio = []
1707
+ cool_cfm_m3s = UnitConversions.convert(hvac_sizing_values.Cool_Airflow, 'cfm', 'm^3/s')
1708
+ for speed in 0..(hvac.NumSpeedsCooling - 1)
1709
+ cool_airflow_rated_ratio << cool_cfm_m3s / HVAC.calc_rated_airflow(hvac_sizing_values.Cool_Capacity, hvac.RatedCFMperTonCooling[speed], hvac.CapacityRatioCooling[speed])
1710
+ cool_airflow_rated_defect_ratio << cool_cfm_m3s * (1 + hvac.AirflowDefectRatioCooling) / HVAC.calc_rated_airflow(hvac_sizing_values.Cool_Capacity, hvac.RatedCFMperTonCooling[speed], hvac.CapacityRatioCooling[speed])
1711
+ end
1712
+ if not cool_airflow_rated_defect_ratio.empty?
1713
+ cap_clg_ratios = []
1714
+ for speed in 0..(hvac.NumSpeedsCooling - 1)
1715
+ # NOTE: heat pump (cooling) curves don't exhibit expected trends at extreme faults;
1716
+ a1_AF_Qgr_c = hvac.COOL_CAP_FFLOW_SPEC[speed][0]
1717
+ a2_AF_Qgr_c = hvac.COOL_CAP_FFLOW_SPEC[speed][1]
1718
+ a3_AF_Qgr_c = hvac.COOL_CAP_FFLOW_SPEC[speed][2]
1719
+
1720
+ p_values, qgr_values, ff_chg_values = HVAC.get_installation_quality_cooling_coeff(f_ch)
1721
+
1722
+ a1_CH_Qgr_c = qgr_values[0]
1723
+ a2_CH_Qgr_c = qgr_values[1]
1724
+ a3_CH_Qgr_c = qgr_values[2]
1725
+ a4_CH_Qgr_c = qgr_values[3]
1726
+
1727
+ ff_ch_c = (1.0 / (1.0 + (qgr_values[0] + (qgr_values[1] * ff_chg_values[0]) + (qgr_values[2] * ff_chg_values[1]) + (qgr_values[3] * f_ch)) * f_ch)).round(3)
1728
+
1729
+ q0_CH = a1_CH_Qgr_c
1730
+ q1_CH = a2_CH_Qgr_c * tin_cool
1731
+ q2_CH = a3_CH_Qgr_c * tout_cool
1732
+ q3_CH = a4_CH_Qgr_c * f_ch
1733
+ y_CH_Q_c = 1 + ((q0_CH + q1_CH + q2_CH + q3_CH) * f_ch)
1734
+
1735
+ q0_AF_CH = a1_AF_Qgr_c
1736
+ q1_AF_CH = a2_AF_Qgr_c * ff_ch_c
1737
+ q2_AF_CH = a3_AF_Qgr_c * ff_ch_c * ff_ch_c
1738
+ p_CH_Q_c = y_CH_Q_c / (q0_AF_CH + q1_AF_CH + q2_AF_CH)
1739
+
1740
+ ff_AF_c = cool_airflow_rated_defect_ratio[speed].round(3)
1741
+ ff_AF_c_nodefect = cool_airflow_rated_ratio[speed].round(3)
1742
+ ff_AF_comb_c = ff_ch_c * ff_AF_c
1743
+
1744
+ q0_AF_comb = a1_AF_Qgr_c
1745
+ q1_AF_comb = a2_AF_Qgr_c * ff_AF_comb_c
1746
+ q2_AF_comb = a3_AF_Qgr_c * ff_AF_comb_c * ff_AF_comb_c
1747
+ p_AF_Q_c = q0_AF_comb + q1_AF_comb + q2_AF_comb
1748
+
1749
+ cool_cap_fff = (p_CH_Q_c * p_AF_Q_c)
1750
+ cool_cap_fff_nodefect = a1_AF_Qgr_c + a2_AF_Qgr_c * ff_AF_c_nodefect + a3_AF_Qgr_c * ff_AF_c_nodefect * ff_AF_c_nodefect
1751
+ cap_clg_ratio = 1 / (cool_cap_fff / cool_cap_fff_nodefect)
1752
+ cap_clg_ratios << cap_clg_ratio
1753
+ end
1754
+ prev_capacity = hvac_sizing_values.Cool_Capacity
1755
+ hvac_sizing_values.Cool_Capacity *= cap_clg_ratios.max
1756
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1757
+ if prev_capacity > 0 # Preserve cfm/ton
1758
+ hvac_sizing_values.Cool_Airflow = hvac_sizing_values.Cool_Airflow * hvac_sizing_values.Cool_Capacity / prev_capacity
1759
+ else
1760
+ hvac_sizing_values.Cool_Airflow = 0.0
1761
+ end
1762
+ end
1763
+ end
1764
+
1765
+ # Heating
1766
+ if [HPXML::HVACTypeHeatPumpAirToAir,
1767
+ HPXML::HVACTypeHeatPumpMiniSplit].include?(hvac.HeatType) && hvac.HeatingLoadFraction > 0
1768
+ heat_airflow_rated_defect_ratio = []
1769
+ heat_airflow_rated_ratio = []
1770
+ heat_cfm_m3s = UnitConversions.convert(hvac_sizing_values.Heat_Airflow, 'cfm', 'm^3/s')
1771
+ for speed in 0..(hvac.NumSpeedsHeating - 1)
1772
+ heat_airflow_rated_ratio << heat_cfm_m3s / HVAC.calc_rated_airflow(hvac_sizing_values.Heat_Capacity, hvac.RatedCFMperTonHeating[speed], hvac.CapacityRatioHeating[speed])
1773
+ heat_airflow_rated_defect_ratio << heat_cfm_m3s * (1 + hvac.AirflowDefectRatioHeating) / HVAC.calc_rated_airflow(hvac_sizing_values.Heat_Capacity, hvac.RatedCFMperTonHeating[speed], hvac.CapacityRatioHeating[speed])
1774
+ end
1775
+ if not heat_airflow_rated_defect_ratio.empty?
1776
+ cap_htg_ratios = []
1777
+ for speed in 0..(hvac.NumSpeedsHeating - 1)
1778
+ a1_AF_Qgr_h = hvac.HEAT_CAP_FFLOW_SPEC[speed][0]
1779
+ a2_AF_Qgr_h = hvac.HEAT_CAP_FFLOW_SPEC[speed][1]
1780
+ a3_AF_Qgr_h = hvac.HEAT_CAP_FFLOW_SPEC[speed][2]
1781
+
1782
+ p_values, qgr_values, ff_chg_values = HVAC.get_installation_quality_heating_coeff(f_ch)
1783
+
1784
+ a1_CH_Qgr_h = qgr_values[0]
1785
+ a2_CH_Qgr_h = qgr_values[1]
1786
+ a3_CH_Qgr_h = qgr_values[2]
1787
+
1788
+ ff_ch_h = (1 / (1 + (qgr_values[0] + qgr_values[1] * ff_chg_values[0] + qgr_values[2] * f_ch) * f_ch)).round(3)
1789
+
1790
+ qh1_CH = a1_CH_Qgr_h
1791
+ qh2_CH = a2_CH_Qgr_h * tout_heat
1792
+ qh3_CH = a3_CH_Qgr_h * f_ch
1793
+ y_CH_Q_h = 1 + ((qh1_CH + qh2_CH + qh3_CH) * f_ch)
1794
+
1795
+ qh0_AF_CH = a1_AF_Qgr_h
1796
+ qh1_AF_CH = a2_AF_Qgr_h * ff_ch_h
1797
+ qh2_AF_CH = a3_AF_Qgr_h * ff_ch_h * ff_ch_h
1798
+ p_CH_Q_h = y_CH_Q_h / (qh0_AF_CH + qh1_AF_CH + qh2_AF_CH)
1799
+
1800
+ ff_AF_h = heat_airflow_rated_defect_ratio[speed].round(3)
1801
+ ff_AF_h_nodefect = heat_airflow_rated_ratio[speed].round(3)
1802
+ ff_AF_comb_h = ff_ch_h * ff_AF_h
1803
+
1804
+ qh0_AF_comb = a1_AF_Qgr_h
1805
+ qh1_AF_comb = a2_AF_Qgr_h * ff_AF_comb_h
1806
+ qh2_AF_comb = a3_AF_Qgr_h * ff_AF_comb_h * ff_AF_comb_h
1807
+ p_AF_Q_h = qh0_AF_comb + qh1_AF_comb + qh2_AF_comb
1808
+
1809
+ heat_cap_fff = (p_CH_Q_h * p_AF_Q_h)
1810
+ heat_cap_fff_nodefect = a1_AF_Qgr_h + a2_AF_Qgr_h * ff_AF_h_nodefect + a3_AF_Qgr_h * ff_AF_h_nodefect * ff_AF_h_nodefect
1811
+ cap_htg_ratio = 1 / (heat_cap_fff / heat_cap_fff_nodefect)
1812
+ cap_htg_ratios << cap_htg_ratio
1813
+ end
1814
+ prev_capacity = hvac_sizing_values.Heat_Capacity
1815
+ hvac_sizing_values.Heat_Capacity *= cap_htg_ratios.max
1816
+ if prev_capacity > 0 # Preserve cfm/ton
1817
+ hvac_sizing_values.Heat_Airflow = hvac_sizing_values.Heat_Airflow * hvac_sizing_values.Heat_Capacity / prev_capacity
1818
+ else
1819
+ hvac_sizing_values.Heat_Airflow = 0.0
1820
+ end
1821
+ end
1822
+ end
1823
+ end
1824
+ end
1825
+
1826
+ def self.apply_hvac_fixed_capacities(hvac_sizing_values, hvac)
1516
1827
  '''
1517
1828
  Fixed Sizing Equipment
1518
1829
  '''
1519
1830
 
1520
1831
  # Override HVAC capacities if values are provided
1521
- if not hvac.FixedCoolingCapacity.nil?
1522
- prev_capacity = hvac_final_values.Cool_Capacity
1523
- hvac_final_values.Cool_Capacity = hvac.FixedCoolingCapacity
1832
+ if (not hvac.FixedCoolingCapacity.nil?) && (hvac_sizing_values.Cool_Capacity > 0)
1833
+ prev_capacity = hvac_sizing_values.Cool_Capacity
1834
+ hvac_sizing_values.Cool_Capacity = hvac.FixedCoolingCapacity
1524
1835
  if @hpxml.header.allow_increased_fixed_capacities
1525
- hvac_final_values.Cool_Capacity = [hvac_final_values.Cool_Capacity, prev_capacity].max
1526
- end
1527
- hvac_final_values.Cool_Capacity_Sens = hvac_final_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1528
- if prev_capacity > 0 # Preserve cfm/ton
1529
- hvac_final_values.Cool_Airflow = hvac_final_values.Cool_Airflow * hvac_final_values.Cool_Capacity / prev_capacity
1530
- else
1531
- hvac_final_values.Cool_Airflow = 0.0
1836
+ hvac_sizing_values.Cool_Capacity = [hvac_sizing_values.Cool_Capacity, prev_capacity].max
1532
1837
  end
1838
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity_Sens * hvac_sizing_values.Cool_Capacity / prev_capacity
1839
+ hvac_sizing_values.Cool_Airflow = hvac_sizing_values.Cool_Airflow * hvac_sizing_values.Cool_Capacity / prev_capacity
1533
1840
  end
1534
- if not hvac.FixedHeatingCapacity.nil?
1535
- prev_capacity = hvac_final_values.Heat_Capacity
1536
- hvac_final_values.Heat_Capacity = hvac.FixedHeatingCapacity
1841
+ if (not hvac.FixedHeatingCapacity.nil?) && (hvac_sizing_values.Heat_Capacity > 0)
1842
+ prev_capacity = hvac_sizing_values.Heat_Capacity
1843
+ hvac_sizing_values.Heat_Capacity = hvac.FixedHeatingCapacity
1537
1844
  if @hpxml.header.allow_increased_fixed_capacities
1538
- hvac_final_values.Heat_Capacity = [hvac_final_values.Heat_Capacity, prev_capacity].max
1539
- end
1540
- if prev_capacity > 0 # Preserve cfm/ton
1541
- hvac_final_values.Heat_Airflow = hvac_final_values.Heat_Airflow * hvac_final_values.Heat_Capacity / prev_capacity
1542
- else
1543
- hvac_final_values.Heat_Airflow = 0.0
1845
+ hvac_sizing_values.Heat_Capacity = [hvac_sizing_values.Heat_Capacity, prev_capacity].max
1544
1846
  end
1847
+ hvac_sizing_values.Heat_Airflow = hvac_sizing_values.Heat_Airflow * hvac_sizing_values.Heat_Capacity / prev_capacity
1545
1848
  end
1546
- if not hvac.FixedSuppHeatingCapacity.nil?
1547
- prev_capacity = hvac_final_values.Heat_Capacity_Supp
1548
- hvac_final_values.Heat_Capacity_Supp = hvac.FixedSuppHeatingCapacity
1849
+ if (not hvac.FixedSuppHeatingCapacity.nil?) && (hvac_sizing_values.Heat_Capacity_Supp > 0)
1850
+ prev_capacity = hvac_sizing_values.Heat_Capacity_Supp
1851
+ hvac_sizing_values.Heat_Capacity_Supp = hvac.FixedSuppHeatingCapacity
1549
1852
  if @hpxml.header.allow_increased_fixed_capacities
1550
- hvac_final_values.Heat_Capacity_Supp = [hvac_final_values.Heat_Capacity_Supp, prev_capacity].max
1853
+ hvac_sizing_values.Heat_Capacity_Supp = [hvac_sizing_values.Heat_Capacity_Supp, prev_capacity].max
1551
1854
  end
1552
1855
  end
1553
1856
  end
1554
1857
 
1555
- def self.process_ground_loop(hvac_final_values, weather, hvac)
1858
+ def self.apply_hvac_ground_loop(hvac_sizing_values, weather, hvac)
1556
1859
  '''
1557
1860
  GSHP Ground Loop Sizing Calculations
1558
1861
  '''
1559
- if hvac.has_type(Constants.ObjectNameGroundSourceHeatPump)
1560
- ground_conductivity = UnitConversions.convert(hvac.GSHP_HXVertical.groundThermalConductivity.get, 'W/(m*K)', 'Btu/(hr*ft*R)')
1561
- grout_conductivity = UnitConversions.convert(hvac.GSHP_HXVertical.groutThermalConductivity.get, 'W/(m*K)', 'Btu/(hr*ft*R)')
1562
- bore_diameter = UnitConversions.convert(hvac.GSHP_HXVertical.boreHoleRadius.get * 2.0, 'm', 'in')
1563
- pipe_od = UnitConversions.convert(hvac.GSHP_HXVertical.pipeOutDiameter.get, 'm', 'in')
1564
- pipe_id = pipe_od - UnitConversions.convert(hvac.GSHP_HXVertical.pipeThickness.get * 2.0, 'm', 'in')
1565
- pipe_cond = UnitConversions.convert(hvac.GSHP_HXVertical.pipeThermalConductivity.get, 'W/(m*K)', 'Btu/(hr*ft*R)')
1566
- pipe_r_value = gshp_hx_pipe_rvalue(pipe_od, pipe_id, pipe_cond)
1567
-
1568
- # Autosize ground loop heat exchanger length
1569
- nom_length_heat, nom_length_cool = gshp_hxbore_ft_per_ton(weather, hvac.GSHP_BoreSpacing, ground_conductivity, hvac.GSHP_SpacingType, grout_conductivity, bore_diameter, pipe_od, pipe_r_value, hvac.HeatingEIR, hvac.CoolingEIR, hvac.GSHP_HXCHWDesign, hvac.GSHP_HXHWDesign, hvac.GSHP_HXDTDesign)
1570
-
1571
- bore_length_heat = nom_length_heat * hvac_final_values.Heat_Capacity / UnitConversions.convert(1.0, 'ton', 'Btu/hr')
1572
- bore_length_cool = nom_length_cool * hvac_final_values.Cool_Capacity / UnitConversions.convert(1.0, 'ton', 'Btu/hr')
1573
- bore_length = [bore_length_heat, bore_length_cool].max
1574
-
1575
- loop_flow = [1.0, UnitConversions.convert([hvac_final_values.Heat_Capacity, hvac_final_values.Cool_Capacity].max, 'Btu/hr', 'ton')].max.floor * 3.0
1576
-
1577
- if hvac.GSHP_BoreHoles.nil? && hvac.GSHP_BoreDepth.nil?
1578
- hvac.GSHP_BoreHoles = [1, (UnitConversions.convert(hvac_final_values.Cool_Capacity, 'Btu/hr', 'ton') + 0.5).floor].max
1579
- hvac.GSHP_BoreDepth = (bore_length / hvac.GSHP_BoreHoles).floor
1580
- min_bore_depth = 0.15 * hvac.GSHP_BoreSpacing # 0.15 is the maximum Spacing2DepthRatio defined for the G-function
1581
-
1582
- (0..4).to_a.each do |tmp|
1583
- if (hvac.GSHP_BoreDepth < min_bore_depth) && (hvac.GSHP_BoreHoles > 1)
1584
- hvac.GSHP_BoreHoles -= 1
1585
- hvac.GSHP_BoreDepth = (bore_length / hvac.GSHP_BoreHoles).floor
1586
- elsif hvac.GSHP_BoreDepth > 345
1587
- hvac.GSHP_BoreHoles += 1
1588
- hvac.GSHP_BoreDepth = (bore_length / hvac.GSHP_BoreHoles).floor
1589
- end
1590
- end
1591
-
1592
- hvac.GSHP_BoreDepth = (bore_length / hvac.GSHP_BoreHoles).floor + 5
1593
-
1594
- elsif hvac.GSHP_BoreHoles.nil? && (not hvac.GSHP_BoreDepth.nil?)
1595
- hvac.GSHP_BoreHoles = (bore_length / hvac.GSHP_BoreDepth.to_f + 0.5).floor
1596
- hvac.GSHP_BoreDepth = hvac.GSHP_BoreDepth.to_f
1597
- elsif (not hvac.GSHP_BoreHoles.nil?) && hvac.GSHP_BoreDepth.nil?
1598
- hvac.GSHP_BoreHoles = hvac.GSHP_BoreHoles.to_f
1599
- hvac.GSHP_BoreDepth = (bore_length / hvac.GSHP_BoreHoles).floor + 5
1862
+ return unless hvac.CoolType == HPXML::HVACTypeHeatPumpGroundToAir
1863
+
1864
+ # Autosize ground loop heat exchanger length
1865
+ bore_spacing = 20.0 # ft, distance between bores
1866
+ pipe_r_value = gshp_hx_pipe_rvalue(hvac)
1867
+ nom_length_heat, nom_length_cool = gshp_hxbore_ft_per_ton(weather, hvac, bore_spacing, pipe_r_value)
1868
+
1869
+ bore_length_heat = nom_length_heat * hvac_sizing_values.Heat_Capacity / UnitConversions.convert(1.0, 'ton', 'Btu/hr')
1870
+ bore_length_cool = nom_length_cool * hvac_sizing_values.Cool_Capacity / UnitConversions.convert(1.0, 'ton', 'Btu/hr')
1871
+ bore_length = [bore_length_heat, bore_length_cool].max
1872
+
1873
+ loop_flow = [1.0, UnitConversions.convert([hvac_sizing_values.Heat_Capacity, hvac_sizing_values.Cool_Capacity].max, 'Btu/hr', 'ton')].max.floor * 3.0
1874
+
1875
+ num_bore_holes = [1, (UnitConversions.convert(hvac_sizing_values.Cool_Capacity, 'Btu/hr', 'ton') + 0.5).floor].max
1876
+ bore_depth = (bore_length / num_bore_holes).floor # ft
1877
+ min_bore_depth = 0.15 * bore_spacing # 0.15 is the maximum Spacing2DepthRatio defined for the G-function
1878
+
1879
+ (0..4).to_a.each do |tmp|
1880
+ if (bore_depth < min_bore_depth) && (num_bore_holes > 1)
1881
+ num_bore_holes -= 1
1882
+ bore_depth = (bore_length / num_bore_holes).floor
1883
+ elsif bore_depth > 345
1884
+ num_bore_holes += 1
1885
+ bore_depth = (bore_length / num_bore_holes).floor
1886
+ end
1887
+ end
1888
+
1889
+ bore_depth = (bore_length / num_bore_holes).floor + 5
1890
+
1891
+ bore_length = bore_depth * num_bore_holes
1892
+
1893
+ if num_bore_holes == 1
1894
+ bore_config = 'single'
1895
+ elsif num_bore_holes == 2
1896
+ bore_config = 'line'
1897
+ elsif num_bore_holes == 3
1898
+ bore_config = 'line'
1899
+ elsif num_bore_holes == 4
1900
+ bore_config = 'rectangle'
1901
+ elsif num_bore_holes == 5
1902
+ bore_config = 'u-config'
1903
+ elsif num_bore_holes > 5
1904
+ bore_config = 'line'
1905
+ end
1906
+
1907
+ # Test for valid GSHP bore field configurations
1908
+ valid_configs = { 'single' => [1],
1909
+ 'line' => [2, 3, 4, 5, 6, 7, 8, 9, 10],
1910
+ 'l-config' => [3, 4, 5, 6],
1911
+ 'rectangle' => [2, 4, 6, 8],
1912
+ 'u-config' => [5, 7, 9],
1913
+ 'l2-config' => [8],
1914
+ 'open-rectangle' => [8] }
1915
+ valid_num_bores = valid_configs[bore_config]
1916
+ max_valid_configs = { 'line' => 10, 'l-config' => 6 }
1917
+ unless valid_num_bores.include? num_bore_holes
1918
+ # Any configuration with a max_valid_configs value can accept any number of bores up to the maximum
1919
+ if max_valid_configs.keys.include? bore_config
1920
+ max_num_bore_holes = max_valid_configs[bore_config]
1921
+ num_bore_holes = max_num_bore_holes
1600
1922
  else
1601
- @runner.registerWarning('User is hard sizing the bore field, improper sizing may lead to unbalanced / unsteady ground loop temperature and erroneous prediction of system energy related cost.')
1602
- hvac.GSHP_BoreHoles = hvac.GSHP_BoreHoles.to_f
1603
- hvac.GSHP_BoreDepth = hvac.GSHP_BoreDepth.to_f
1604
- end
1605
-
1606
- bore_length = hvac.GSHP_BoreDepth * hvac.GSHP_BoreHoles
1607
-
1608
- if hvac.GSHP_BoreConfig.nil?
1609
- if hvac.GSHP_BoreHoles == 1
1610
- hvac.GSHP_BoreConfig = Constants.BoreConfigSingle
1611
- elsif hvac.GSHP_BoreHoles == 2
1612
- hvac.GSHP_BoreConfig = Constants.BoreConfigLine
1613
- elsif hvac.GSHP_BoreHoles == 3
1614
- hvac.GSHP_BoreConfig = Constants.BoreConfigLine
1615
- elsif hvac.GSHP_BoreHoles == 4
1616
- hvac.GSHP_BoreConfig = Constants.BoreConfigRectangle
1617
- elsif hvac.GSHP_BoreHoles == 5
1618
- hvac.GSHP_BoreConfig = Constants.BoreConfigUconfig
1619
- elsif hvac.GSHP_BoreHoles > 5
1620
- hvac.GSHP_BoreConfig = Constants.BoreConfigLine
1621
- end
1622
- end
1623
-
1624
- # Test for valid GSHP bore field configurations
1625
- valid_configs = { Constants.BoreConfigSingle => [1],
1626
- Constants.BoreConfigLine => [2, 3, 4, 5, 6, 7, 8, 9, 10],
1627
- Constants.BoreConfigLconfig => [3, 4, 5, 6],
1628
- Constants.BoreConfigRectangle => [2, 4, 6, 8],
1629
- Constants.BoreConfigUconfig => [5, 7, 9],
1630
- Constants.BoreConfigL2config => [8],
1631
- Constants.BoreConfigOpenRectangle => [8] }
1632
- valid_num_bores = valid_configs[hvac.GSHP_BoreConfig]
1633
- max_valid_configs = { Constants.BoreConfigLine => 10, Constants.BoreConfigLconfig => 6 }
1634
- unless valid_num_bores.include? hvac.GSHP_BoreHoles
1635
- # Any configuration with a max_valid_configs value can accept any number of bores up to the maximum
1636
- if max_valid_configs.keys.include? hvac.GSHP_BoreConfig
1637
- max_bore_holes = max_valid_configs[hvac.GSHP_BoreConfig]
1638
- @runner.registerWarning("Maximum number of bore holes for '#{hvac.GSHP_BoreConfig}' bore configuration is #{max_bore_holes}. Overriding value of #{hvac.GSHP_BoreHoles} bore holes to #{max_bore_holes}.")
1639
- hvac.GSHP_BoreHoles = max_bore_holes
1923
+ # Search for first valid bore field
1924
+ new_bore_config = nil
1925
+ valid_field_found = false
1926
+ valid_configs.keys.each do |bore_config|
1927
+ next unless valid_configs[bore_config].include? num_bore_holes
1928
+
1929
+ valid_field_found = true
1930
+ new_bore_config = bore_config
1931
+ break
1932
+ end
1933
+ if valid_field_found
1934
+ bore_config = new_bore_config
1640
1935
  else
1641
- # Search for first valid bore field
1642
- new_bore_config = nil
1643
- valid_field_found = false
1644
- valid_configs.keys.each do |bore_config|
1645
- next unless valid_configs[bore_config].include? hvac.GSHP_BoreHoles
1646
-
1647
- valid_field_found = true
1648
- new_bore_config = bore_config
1649
- break
1650
- end
1651
- if valid_field_found
1652
- @runner.registerWarning("Bore field '#{hvac.GSHP_BoreConfig}' with #{hvac.GSHP_BoreHoles.to_i} bore holes is an invalid configuration. Changing layout to '#{new_bore_config}' configuration.")
1653
- hvac.GSHP_BoreConfig = new_bore_config
1654
- else
1655
- fail 'Could not construct a valid GSHP bore field configuration.'
1656
- end
1936
+ fail 'Could not construct a valid GSHP bore field configuration.'
1657
1937
  end
1658
1938
  end
1939
+ end
1659
1940
 
1660
- spacing_to_depth_ratio = hvac.GSHP_BoreSpacing / hvac.GSHP_BoreDepth
1941
+ spacing_to_depth_ratio = bore_spacing / bore_depth
1661
1942
 
1662
- lntts = [-8.5, -7.8, -7.2, -6.5, -5.9, -5.2, -4.5, -3.963, -3.27, -2.864, -2.577, -2.171, -1.884, -1.191, -0.497, -0.274, -0.051, 0.196, 0.419, 0.642, 0.873, 1.112, 1.335, 1.679, 2.028, 2.275, 3.003]
1663
- gfnc_coeff = gshp_gfnc_coeff(hvac.GSHP_BoreConfig, hvac.GSHP_BoreHoles, spacing_to_depth_ratio)
1943
+ lntts = [-8.5, -7.8, -7.2, -6.5, -5.9, -5.2, -4.5, -3.963, -3.27, -2.864, -2.577, -2.171, -1.884, -1.191, -0.497, -0.274, -0.051, 0.196, 0.419, 0.642, 0.873, 1.112, 1.335, 1.679, 2.028, 2.275, 3.003]
1944
+ gfnc_coeff = gshp_gfnc_coeff(bore_config, num_bore_holes, spacing_to_depth_ratio)
1664
1945
 
1665
- hvac_final_values.GSHP_Loop_flow = loop_flow
1666
- hvac_final_values.GSHP_Bore_Depth = hvac.GSHP_BoreDepth
1667
- hvac_final_values.GSHP_Bore_Holes = hvac.GSHP_BoreHoles
1668
- hvac_final_values.GSHP_G_Functions = [lntts, gfnc_coeff]
1669
- end
1946
+ hvac_sizing_values.GSHP_Loop_flow = loop_flow
1947
+ hvac_sizing_values.GSHP_Bore_Depth = bore_depth
1948
+ hvac_sizing_values.GSHP_Bore_Holes = num_bore_holes
1949
+ hvac_sizing_values.GSHP_G_Functions = [lntts, gfnc_coeff]
1670
1950
  end
1671
1951
 
1672
- def self.process_finalize(hvac_final_values, zone_loads, weather, hvac)
1952
+ def self.apply_hvac_finalize_airflows(hvac_sizing_values, weather, hvac)
1673
1953
  '''
1674
1954
  Finalize Sizing Calculations
1675
1955
  '''
1676
1956
 
1677
- # Prevent errors of "has no air flow"
1678
- min_air_flow = 3.0 # cfm; E+ minimum is 0.001 m^3/s"
1679
- if hvac_final_values.Heat_Airflow > 0
1680
- hvac_final_values.Heat_Airflow = [hvac_final_values.Heat_Airflow, min_air_flow].max
1957
+ if hvac_sizing_values.Heat_Airflow > 0
1958
+ hvac_sizing_values.Heat_Airflow *= (1.0 + hvac.AirflowDefectRatioHeating)
1681
1959
  end
1682
- if hvac_final_values.Cool_Airflow > 0
1683
- hvac_final_values.Cool_Airflow = [hvac_final_values.Cool_Airflow, min_air_flow].max
1960
+
1961
+ if hvac_sizing_values.Cool_Airflow > 0
1962
+ hvac_sizing_values.Cool_Airflow *= (1.0 + hvac.AirflowDefectRatioCooling)
1684
1963
  end
1685
1964
  end
1686
1965
 
1687
- def self.process_heat_pump_adjustment(hvac_final_values, weather, hvac, totalCap_CurveValue)
1966
+ def self.process_heat_pump_adjustment(hvac_sizing_values, weather, hvac, totalCap_CurveValue)
1688
1967
  '''
1689
1968
  Adjust heat pump sizing
1690
1969
  '''
@@ -1696,88 +1975,129 @@ class HVACSizing
1696
1975
  capacity_ratio = 1.0
1697
1976
  end
1698
1977
 
1699
- heatCap_Rated = (hvac_final_values.Heat_Load / MathTools.biquadratic(@heat_setpoint, weather.design.HeatingDrybulb, coefficients)) / capacity_ratio
1978
+ heatCap_Rated = (hvac_sizing_values.Heat_Load / MathTools.biquadratic(@heat_setpoint, weather.design.HeatingDrybulb, coefficients)) / capacity_ratio
1700
1979
 
1701
- if heatCap_Rated < hvac_final_values.Cool_Capacity
1702
- if hvac.has_type(Constants.ObjectNameAirSourceHeatPump)
1703
- hvac_final_values.Heat_Capacity = hvac_final_values.Cool_Capacity
1704
- elsif hvac.has_type(Constants.ObjectNameMiniSplitHeatPump)
1705
- hvac_final_values.Heat_Capacity = [hvac_final_values.Cool_Capacity + hvac.HeatingCapacityOffset, Constants.small].max
1706
- end
1707
- else
1708
- cfm_Btu = hvac_final_values.Cool_Airflow / hvac_final_values.Cool_Capacity
1709
- load_shr = hvac_final_values.Cool_Load_Sens / hvac_final_values.Cool_Load_Tot
1980
+ if heatCap_Rated >= hvac_sizing_values.Cool_Capacity
1981
+ cfm_per_btuh = hvac_sizing_values.Cool_Airflow / hvac_sizing_values.Cool_Capacity
1982
+ load_shr = hvac_sizing_values.Cool_Load_Sens / hvac_sizing_values.Cool_Load_Tot
1710
1983
  if ((weather.data.HDD65F / weather.data.CDD50F) < 2.0) || (load_shr < 0.95)
1711
1984
  # Mild winter or has a latent cooling load
1712
- hvac_final_values.Cool_Capacity = [(hvac.OverSizeLimit * hvac_final_values.Cool_Load_Tot) / totalCap_CurveValue, heatCap_Rated].min
1985
+ hvac_sizing_values.Cool_Capacity = [(hvac.OverSizeLimit * hvac_sizing_values.Cool_Load_Tot) / totalCap_CurveValue, heatCap_Rated].min
1713
1986
  else
1714
1987
  # Cold winter and no latent cooling load (add a ton rule applies)
1715
- hvac_final_values.Cool_Capacity = [(hvac_final_values.Cool_Load_Tot + hvac.OverSizeDelta) / totalCap_CurveValue, heatCap_Rated].min
1988
+ hvac_sizing_values.Cool_Capacity = [(hvac_sizing_values.Cool_Load_Tot + hvac.OverSizeDelta) / totalCap_CurveValue, heatCap_Rated].min
1716
1989
  end
1717
- if hvac.has_type(Constants.ObjectNameAirSourceHeatPump)
1718
- hvac_final_values.Cool_Airflow = cfm_Btu * hvac_final_values.Cool_Capacity
1719
- hvac_final_values.Heat_Capacity = hvac_final_values.Cool_Capacity
1720
- elsif hvac.has_type(Constants.ObjectNameMiniSplitHeatPump)
1721
- hvac_final_values.Cool_Airflow = hvac.RatedCFMperTonCooling[-1] * UnitConversions.convert(hvac_final_values.Cool_Capacity, 'Btu/hr', 'ton')
1722
- hvac_final_values.Heat_Capacity = [hvac_final_values.Cool_Capacity + hvac.HeatingCapacityOffset, Constants.small].max
1990
+ if hvac.HeatType == HPXML::HVACTypeHeatPumpAirToAir
1991
+ hvac_sizing_values.Cool_Airflow = cfm_per_btuh * hvac_sizing_values.Cool_Capacity
1992
+ elsif hvac.HeatType == HPXML::HVACTypeHeatPumpMiniSplit
1993
+ hvac_sizing_values.Cool_Airflow = hvac.RatedCFMperTonCooling[-1] * hvac.CapacityRatioCooling[-1] * UnitConversions.convert(hvac_sizing_values.Cool_Capacity, 'Btu/hr', 'ton')
1723
1994
  end
1724
1995
  end
1725
-
1726
- return hvac_final_values
1727
1996
  end
1728
1997
 
1729
- def self.get_shelter_class(model, min_neighbor_distance)
1730
- height_ft = Geometry.get_height_of_spaces([@spaces[HPXML::LocationLivingSpace]])
1731
- tot_cb_area, ext_cb_area = @hpxml.compartmentalization_boundary_areas()
1732
- exposed_wall_ratio = ext_cb_area / tot_cb_area
1733
-
1734
- if exposed_wall_ratio > 0.5 # 3 or 4 exposures; Table 5D
1735
- if min_neighbor_distance.nil?
1736
- shelter_class = 2 # Typical shelter for isolated rural house
1737
- elsif min_neighbor_distance > height_ft
1738
- shelter_class = 3 # Typical shelter caused by other buildings across the street
1739
- else
1740
- shelter_class = 4 # Typical shelter for urban buildings where sheltering obstacles are less than one building height away
1741
- end
1742
- else # 0, 1, or 2 exposures; Table 5E
1743
- if min_neighbor_distance.nil?
1744
- if exposed_wall_ratio > 0.25 # 2 exposures; Table 5E
1745
- shelter_class = 2 # Typical shelter for isolated rural house
1746
- else # 1 exposure; Table 5E
1747
- shelter_class = 3 # Typical shelter caused by other buildings across the street
1748
- end
1749
- elsif min_neighbor_distance > height_ft
1750
- shelter_class = 4 # Typical shelter for urban buildings where sheltering obstacles are less than one building height away
1751
- else
1752
- shelter_class = 5 # Typical shelter for urban buildings where sheltering obstacles are less than one building height away
1753
- end
1998
+ def self.get_ventilation_rates()
1999
+ vent_fans_mech = @hpxml.ventilation_fans.select { |f| f.used_for_whole_building_ventilation }
2000
+ if vent_fans_mech.empty?
2001
+ return [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
1754
2002
  end
1755
2003
 
1756
- return shelter_class
1757
- end
2004
+ # Categorize fans into different types
2005
+ vent_mech_preheat = vent_fans_mech.select { |vent_mech| (not vent_mech.preheating_efficiency_cop.nil?) }
2006
+ vent_mech_precool = vent_fans_mech.select { |vent_mech| (not vent_mech.precooling_efficiency_cop.nil?) }
2007
+ vent_mech_shared = vent_fans_mech.select { |vent_mech| vent_mech.is_shared_system }
2008
+
2009
+ vent_mech_sup_tot = vent_fans_mech.select { |vent_mech| vent_mech.fan_type == HPXML::MechVentTypeSupply }
2010
+ vent_mech_exh_tot = vent_fans_mech.select { |vent_mech| vent_mech.fan_type == HPXML::MechVentTypeExhaust }
2011
+ vent_mech_cfis_tot = vent_fans_mech.select { |vent_mech| vent_mech.fan_type == HPXML::MechVentTypeCFIS }
2012
+ vent_mech_bal_tot = vent_fans_mech.select { |vent_mech| vent_mech.fan_type == HPXML::MechVentTypeBalanced }
2013
+ vent_mech_erv_hrv_tot = vent_fans_mech.select { |vent_mech| [HPXML::MechVentTypeERV, HPXML::MechVentTypeHRV].include? vent_mech.fan_type }
2014
+
2015
+ # Average in-unit CFMs (include recirculation from in unit CFMs for shared systems)
2016
+ sup_cfm_tot = vent_mech_sup_tot.map { |vent_mech| vent_mech.average_total_unit_flow_rate }.sum(0.0)
2017
+ exh_cfm_tot = vent_mech_exh_tot.map { |vent_mech| vent_mech.average_total_unit_flow_rate }.sum(0.0)
2018
+ bal_cfm_tot = vent_mech_bal_tot.map { |vent_mech| vent_mech.average_total_unit_flow_rate }.sum(0.0)
2019
+ erv_hrv_cfm_tot = vent_mech_erv_hrv_tot.map { |vent_mech| vent_mech.average_total_unit_flow_rate }.sum(0.0)
2020
+ cfis_cfm_tot = vent_mech_cfis_tot.map { |vent_mech| vent_mech.average_total_unit_flow_rate }.sum(0.0)
2021
+
2022
+ # Average preconditioned OA air CFMs (only OA, recirculation will be addressed below for all shared systems)
2023
+ oa_cfm_preheat = vent_mech_preheat.map { |vent_mech| vent_mech.average_oa_unit_flow_rate * vent_mech.preheating_fraction_load_served }.sum(0.0)
2024
+ oa_cfm_precool = vent_mech_precool.map { |vent_mech| vent_mech.average_oa_unit_flow_rate * vent_mech.precooling_fraction_load_served }.sum(0.0)
2025
+ recirc_cfm_shared = vent_mech_shared.map { |vent_mech| vent_mech.average_total_unit_flow_rate - vent_mech.average_oa_unit_flow_rate }.sum(0.0)
2026
+
2027
+ # Total CFMS
2028
+ tot_sup_cfm = sup_cfm_tot + bal_cfm_tot + erv_hrv_cfm_tot + cfis_cfm_tot
2029
+ tot_exh_cfm = exh_cfm_tot + bal_cfm_tot + erv_hrv_cfm_tot
2030
+ tot_unbal_cfm = (tot_sup_cfm - tot_exh_cfm).abs
2031
+ tot_bal_cfm = [tot_exh_cfm, tot_sup_cfm].min
1758
2032
 
1759
- def self.get_ventilation_rates(model)
1760
- mechVentExist = get_feature(model.getBuilding, Constants.SizingInfoMechVentExist, 'boolean')
1761
- return [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] unless mechVentExist
2033
+ # Calculate effectivenesses for all ERV/HRV and store results in a hash
2034
+ hrv_erv_effectiveness_map = Airflow.calc_hrv_erv_effectiveness(vent_mech_erv_hrv_tot)
1762
2035
 
1763
- q_unb_cfm = get_feature(model.getBuilding, Constants.SizingInfoMechVentWholeHouseRateUnbalanced, 'double')
1764
- q_b = get_feature(model.getBuilding, Constants.SizingInfoMechVentWholeHouseRateBalanced, 'double')
1765
- q_preheat = get_feature(model.getBuilding, Constants.SizingInfoMechVentWholeHouseRatePreHeated, 'double')
1766
- q_precool = get_feature(model.getBuilding, Constants.SizingInfoMechVentWholeHouseRatePreCooled, 'double')
1767
- q_recirc = get_feature(model.getBuilding, Constants.SizingInfoMechVentWholeHouseRateRecirculated, 'double')
1768
- apparentSensibleEffectiveness = get_feature(model.getBuilding, Constants.SizingInfoMechVentApparentSensibleEffectiveness, 'double')
1769
- latentEffectiveness = get_feature(model.getBuilding, Constants.SizingInfoMechVentLatentEffectiveness, 'double')
2036
+ # Calculate cfm weighted average effectivenesses for the combined balanced airflow
2037
+ weighted_vent_mech_lat_eff = 0.0
2038
+ weighted_vent_mech_apparent_sens_eff = 0.0
2039
+ vent_mech_erv_hrv_unprecond = vent_mech_erv_hrv_tot.select { |vent_mech| vent_mech.preheating_efficiency_cop.nil? && vent_mech.precooling_efficiency_cop.nil? }
2040
+ vent_mech_erv_hrv_unprecond.each do |vent_mech|
2041
+ weighted_vent_mech_lat_eff += vent_mech.average_oa_unit_flow_rate / tot_bal_cfm * hrv_erv_effectiveness_map[vent_mech][:vent_mech_lat_eff]
2042
+ weighted_vent_mech_apparent_sens_eff += vent_mech.average_oa_unit_flow_rate / tot_bal_cfm * hrv_erv_effectiveness_map[vent_mech][:vent_mech_apparent_sens_eff]
2043
+ end
1770
2044
 
1771
- q_bal_sens = q_b * (1.0 - apparentSensibleEffectiveness)
1772
- q_bal_lat = q_b * (1.0 - latentEffectiveness)
2045
+ tot_bal_cfm_sens = tot_bal_cfm * (1.0 - weighted_vent_mech_apparent_sens_eff)
2046
+ tot_bal_cfm_lat = tot_bal_cfm * (1.0 - weighted_vent_mech_lat_eff)
1773
2047
 
1774
- return [q_unb_cfm, q_preheat, q_precool, q_recirc, q_bal_sens, q_bal_lat]
2048
+ return [tot_unbal_cfm, oa_cfm_preheat, oa_cfm_precool, recirc_cfm_shared, tot_bal_cfm_sens, tot_bal_cfm_lat]
1775
2049
  end
1776
2050
 
1777
2051
  def self.calc_airflow_rate(load_or_capacity, deltaT)
1778
2052
  return load_or_capacity / (1.1 * @acf * deltaT)
1779
2053
  end
1780
2054
 
2055
+ def self.calc_gshp_clg_curve_value(hvac, wb_temp, db_temp, w_temp, vfr_air, loop_flow)
2056
+ # Reference conditions in thesis with largest capacity:
2057
+ # See Appendix B Figure B.3 of https://hvac.okstate.edu/sites/default/files/pubs/theses/MS/27-Tang_Thesis_05.pdf
2058
+ ref_temp = 283 # K
2059
+ ref_vfr_air = UnitConversions.convert(1200, 'cfm', 'm^3/s')
2060
+ ref_vfr_water = 0.000284
2061
+
2062
+ a_1 = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed][0]
2063
+ a_2 = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed][1]
2064
+ a_3 = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed][2]
2065
+ a_4 = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed][3]
2066
+ a_5 = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed][4]
2067
+ b_1 = hvac.COOL_SH_FT_SPEC[hvac.SizingSpeed][0]
2068
+ b_2 = hvac.COOL_SH_FT_SPEC[hvac.SizingSpeed][1]
2069
+ b_3 = hvac.COOL_SH_FT_SPEC[hvac.SizingSpeed][2]
2070
+ b_4 = hvac.COOL_SH_FT_SPEC[hvac.SizingSpeed][3]
2071
+ b_5 = hvac.COOL_SH_FT_SPEC[hvac.SizingSpeed][4]
2072
+ b_6 = hvac.COOL_SH_FT_SPEC[hvac.SizingSpeed][5]
2073
+
2074
+ if not loop_flow.nil?
2075
+ totalCap_CurveValue = a_1 + wb_temp / ref_temp * a_2 + w_temp / ref_temp * a_3 + vfr_air / ref_vfr_air * a_4 + loop_flow / ref_vfr_water * a_5
2076
+ sensibleCap_CurveValue = b_1 + db_temp / ref_temp * b_2 + wb_temp / ref_temp * b_3 + w_temp / ref_temp * b_4 + vfr_air / ref_vfr_air * b_5 + loop_flow / ref_vfr_water * b_6
2077
+ else
2078
+ totalCap_CurveValue = a_1 + wb_temp / ref_temp * a_2 + w_temp / ref_temp * a_3 + vfr_air / ref_vfr_air * a_4
2079
+ sensibleCap_CurveValue = b_1 + db_temp / ref_temp * b_2 + wb_temp / ref_temp * b_3 + w_temp / ref_temp * b_4 + vfr_air / ref_vfr_air * b_5
2080
+ end
2081
+ return totalCap_CurveValue, sensibleCap_CurveValue
2082
+ end
2083
+
2084
+ def self.calc_gshp_htg_curve_value(hvac, db_temp, w_temp, vfr_air, loop_flow)
2085
+ # Reference conditions in thesis with largest capacity:
2086
+ # See Appendix B Figure B.3 of https://hvac.okstate.edu/sites/default/files/pubs/theses/MS/27-Tang_Thesis_05.pdf
2087
+ ref_temp = 283 # K
2088
+ ref_vfr_air = UnitConversions.convert(1200, 'cfm', 'm^3/s')
2089
+ ref_vfr_water = 0.000284
2090
+
2091
+ a_1 = hvac.HEAT_CAP_FT_SPEC[hvac.SizingSpeed][0]
2092
+ a_2 = hvac.HEAT_CAP_FT_SPEC[hvac.SizingSpeed][1]
2093
+ a_3 = hvac.HEAT_CAP_FT_SPEC[hvac.SizingSpeed][2]
2094
+ a_4 = hvac.HEAT_CAP_FT_SPEC[hvac.SizingSpeed][3]
2095
+ a_5 = hvac.HEAT_CAP_FT_SPEC[hvac.SizingSpeed][4]
2096
+
2097
+ cap_CurveValue = a_1 + db_temp / ref_temp * a_2 + w_temp / ref_temp * a_3 + vfr_air / ref_vfr_air * a_4 + loop_flow / ref_vfr_water * a_5
2098
+ return cap_CurveValue
2099
+ end
2100
+
1781
2101
  def self.calc_delivery_effectiveness_heating(dse_Qs, dse_Qr, system_cfm, load_sens, dse_Tamb_s, dse_Tamb_r, dse_As, dse_Ar, t_setpoint, dse_Fregain_s, dse_Fregain_r, supply_r, return_r, air_dens = @inside_air_dens, air_cp = Gas.Air.cp)
1782
2102
  '''
1783
2103
  Calculate the Delivery Effectiveness for heating (using the method of ASHRAE Standard 152).
@@ -1862,61 +2182,6 @@ class HVACSizing
1862
2182
  return cool_Load_Lat, cool_Load_Sens
1863
2183
  end
1864
2184
 
1865
- def self.get_ducts_for_object(object)
1866
- ducts = []
1867
-
1868
- # Ducted?
1869
- is_ducted = get_feature(object, Constants.SizingInfoHVACSystemIsDucted, 'boolean', false)
1870
- is_ducted = true if is_ducted.nil?
1871
- return ducts if not is_ducted
1872
-
1873
- # Has ducts?
1874
- has_ducts = get_feature(object, Constants.SizingInfoDuctExist, 'boolean', false)
1875
- return ducts if ducts.nil?
1876
-
1877
- # Leakage values
1878
- leakage_fracs = get_feature(object, Constants.SizingInfoDuctLeakageFracs, 'string', false)
1879
- leakage_cfm25s = get_feature(object, Constants.SizingInfoDuctLeakageCFM25s, 'string', false)
1880
- return ducts if leakage_fracs.nil? || leakage_cfm25s.nil?
1881
-
1882
- leakage_fracs = leakage_fracs.split(',').map(&:to_f)
1883
- leakage_cfm25s = leakage_cfm25s.split(',').map(&:to_f)
1884
- if leakage_fracs.sum(0.0) == 0.0
1885
- leakage_fracs = [nil] * leakage_fracs.size
1886
- else
1887
- leakage_cfm25s = [nil] * leakage_cfm25s.size
1888
- end
1889
-
1890
- # Areas
1891
- areas = get_feature(object, Constants.SizingInfoDuctAreas, 'string')
1892
- areas = areas.split(',').map(&:to_f)
1893
-
1894
- # R-values
1895
- rvalues = get_feature(object, Constants.SizingInfoDuctRvalues, 'string')
1896
- rvalues = rvalues.split(',').map(&:to_f)
1897
-
1898
- # Locations
1899
- locations = get_feature(object, Constants.SizingInfoDuctLocations, 'string')
1900
- locations = locations.split(',')
1901
-
1902
- # Sides
1903
- sides = get_feature(object, Constants.SizingInfoDuctSides, 'string')
1904
- sides = sides.split(',')
1905
-
1906
- locations.each_with_index do |location, index|
1907
- d = DuctInfo.new
1908
- d.Location = location
1909
- d.LeakageFrac = leakage_fracs[index]
1910
- d.LeakageCFM25 = leakage_cfm25s[index]
1911
- d.Area = areas[index]
1912
- d.Rvalue = rvalues[index]
1913
- d.Side = sides[index]
1914
- ducts << d
1915
- end
1916
-
1917
- return ducts
1918
- end
1919
-
1920
2185
  def self.calc_ducts_area_weighted_average(ducts, values)
1921
2186
  '''
1922
2187
  Calculate area-weighted average values for unconditioned duct(s)
@@ -1966,9 +2231,9 @@ class HVACSizing
1966
2231
  ducts.each do |duct|
1967
2232
  next if [HPXML::LocationLivingSpace, HPXML::LocationBasementConditioned].include? duct.Location
1968
2233
 
1969
- if not duct.LeakageFrac.nil?
2234
+ if duct.LeakageFrac.to_f > 0
1970
2235
  cfms[duct.Side] += duct.LeakageFrac * system_cfm
1971
- elsif not duct.LeakageCFM25.nil?
2236
+ elsif duct.LeakageCFM25.to_f > 0
1972
2237
  cfms[duct.Side] += duct.LeakageCFM25
1973
2238
  end
1974
2239
  end
@@ -1993,302 +2258,243 @@ class HVACSizing
1993
2258
  return 1.0 / supply_u, 1.0 / return_u
1994
2259
  end
1995
2260
 
1996
- def self.get_hvacs(model)
1997
- hvacs = []
1998
-
1999
- # Get unique set of HVAC equipment
2000
- equips = []
2261
+ def self.get_hvac_information(hvac_system)
2262
+ # FUTURE: Remove this method and use hvac_system objects directly.
2263
+ hvac = HVACInfo.new
2001
2264
 
2002
- HVAC.existing_equipment(model, @cond_zone, @runner).each do |equip|
2003
- next if equips.include? equip
2004
- next if equip.is_a? OpenStudio::Model::ZoneHVACIdealLoadsAirSystem
2005
-
2006
- equips << equip
2265
+ hpxml_hvacs = []
2266
+ if not hvac_system[:heating].nil?
2267
+ hpxml_hvacs << hvac_system[:heating]
2268
+ end
2269
+ if not hvac_system[:cooling].nil?
2270
+ hpxml_hvacs << hvac_system[:cooling]
2007
2271
  end
2008
2272
 
2009
- # Process each equipment
2010
- equips.each do |equip|
2011
- hvac = HVACInfo.new
2012
- hvacs << hvac
2013
-
2014
- hvac.Objects = [equip]
2015
-
2016
- clg_coil, htg_coil, supp_htg_coil = HVAC.get_coils_from_hvac_equip(model, equip)
2017
-
2018
- # Get type of heating/cooling system
2019
- hvac.CoolType = get_feature(equip, Constants.SizingInfoHVACCoolType, 'string', false)
2020
- hvac.HeatType = get_feature(equip, Constants.SizingInfoHVACHeatType, 'string', false)
2021
-
2022
- # Retrieve ducts if they exist
2023
- if equip.is_a? OpenStudio::Model::AirLoopHVACUnitarySystem
2024
- if equip.airLoopHVAC.is_initialized
2025
- hvac.Ducts = get_ducts_for_object(equip.airLoopHVAC.get)
2026
- end
2027
- elsif equip.is_a? OpenStudio::Model::ZoneHVACFourPipeFanCoil
2028
- hvac.Ducts = get_ducts_for_object(equip)
2029
- elsif equip.is_a? OpenStudio::Model::EvaporativeCoolerDirectResearchSpecial
2030
- hvac.Ducts = get_ducts_for_object(equip.airLoopHVAC.get)
2273
+ # Get heating/cooling system info from HPXML objects
2274
+ hpxml_hvacs.uniq.each do |hpxml_hvac|
2275
+ hpxml_hvac_ap = hpxml_hvac.additional_properties
2031
2276
 
2032
- hvac.CoolingLoadFraction = get_feature(equip, Constants.SizingInfoHVACFracCoolLoadServed, 'double')
2033
- hvac.EvapCoolerEffectiveness = equip.coolerEffectiveness
2277
+ # System type
2278
+ if hpxml_hvac.respond_to? :heating_system_type
2279
+ hvac.HeatType = hpxml_hvac.heating_system_type
2280
+ elsif hpxml_hvac.respond_to? :cooling_system_type
2281
+ hvac.CoolType = hpxml_hvac.cooling_system_type
2282
+ elsif hpxml_hvac.respond_to? :heat_pump_type
2283
+ hvac.HeatType = hpxml_hvac.heat_pump_type
2284
+ hvac.CoolType = hpxml_hvac.heat_pump_type
2034
2285
  end
2035
2286
 
2036
- hvac.FanWatts = get_feature(equip, Constants.SizingInfoHVACFanWatts, 'double', false)
2037
- if not clg_coil.nil?
2038
- ratedCFMperTonCooling = get_feature(equip, Constants.SizingInfoHVACRatedCFMperTonCooling, 'string', false)
2039
- if not ratedCFMperTonCooling.nil?
2040
- hvac.RatedCFMperTonCooling = ratedCFMperTonCooling.split(',').map(&:to_f)
2041
- end
2042
-
2043
- hvac.CoolingLoadFraction = get_feature(equip, Constants.SizingInfoHVACFracCoolLoadServed, 'double')
2287
+ # Load fractions
2288
+ if hpxml_hvac.respond_to? :fraction_heat_load_served
2289
+ hvac.HeatingLoadFraction = hpxml_hvac.fraction_heat_load_served
2290
+ end
2291
+ if hpxml_hvac.respond_to? :fraction_cool_load_served
2292
+ hvac.CoolingLoadFraction = hpxml_hvac.fraction_cool_load_served
2044
2293
  end
2045
2294
 
2046
- if clg_coil.is_a? OpenStudio::Model::CoilCoolingDXSingleSpeed
2047
- hvac.NumSpeedsCooling = 1
2048
-
2049
- if hvac.has_type(Constants.ObjectNameRoomAirConditioner)
2050
- ratedCFMperTonCooling = get_feature(equip, Constants.SizingInfoHVACRatedCFMperTonCooling, 'string')
2051
-
2052
- hvac.RatedCFMperTonCooling = ratedCFMperTonCooling.split(',').map(&:to_f)
2053
- end
2054
-
2055
- curves = [clg_coil.totalCoolingCapacityFunctionOfTemperatureCurve]
2056
- hvac.COOL_CAP_FT_SPEC = get_2d_vector_from_CAP_FT_SPEC_curves(curves, hvac.NumSpeedsCooling)
2057
- if not clg_coil.ratedSensibleHeatRatio.is_initialized
2058
- fail "SHR not set for #{clg_coil.name}."
2059
- end
2295
+ # Capacities
2296
+ if hpxml_hvac.respond_to? :heating_capacity
2297
+ hvac.FixedHeatingCapacity = hpxml_hvac.heating_capacity
2298
+ end
2299
+ if hpxml_hvac.respond_to? :cooling_capacity
2300
+ hvac.FixedCoolingCapacity = hpxml_hvac.cooling_capacity
2301
+ end
2302
+ if hpxml_hvac.respond_to? :backup_heating_capacity
2303
+ hvac.FixedSuppHeatingCapacity = hpxml_hvac.backup_heating_capacity
2304
+ end
2060
2305
 
2061
- hvac.SHRRated = [clg_coil.ratedSensibleHeatRatio.get]
2062
- if clg_coil.ratedTotalCoolingCapacity.is_initialized
2063
- hvac.FixedCoolingCapacity = UnitConversions.convert(clg_coil.ratedTotalCoolingCapacity.get, 'W', 'Btu/hr')
2306
+ # Number of speeds
2307
+ if hpxml_hvac.is_a?(HPXML::CoolingSystem) || hpxml_hvac.is_a?(HPXML::HeatPump)
2308
+ # Cooling
2309
+ if hpxml_hvac_ap.respond_to? :num_speeds
2310
+ num_speeds = hpxml_hvac_ap.num_speeds
2064
2311
  end
2065
-
2066
- elsif clg_coil.is_a? OpenStudio::Model::CoilCoolingDXMultiSpeed
2067
- hvac.NumSpeedsCooling = clg_coil.stages.size
2312
+ num_speeds = 1 if num_speeds.nil?
2313
+ hvac.NumSpeedsCooling = num_speeds
2068
2314
  if hvac.NumSpeedsCooling == 2
2069
2315
  hvac.OverSizeLimit = 1.2
2070
- else
2316
+ elsif hvac.NumSpeedsCooling > 2
2071
2317
  hvac.OverSizeLimit = 1.3
2072
2318
  end
2073
-
2074
- capacityRatioCooling = get_feature(equip, Constants.SizingInfoHVACCapacityRatioCooling, 'string')
2075
-
2076
- hvac.CapacityRatioCooling = capacityRatioCooling.split(',').map(&:to_f)
2077
-
2078
- if not equip.designSpecificationMultispeedObject.is_initialized
2079
- fail "DesignSpecificationMultispeedObject not set for #{equip.name}."
2319
+ end
2320
+ if hpxml_hvac.is_a?(HPXML::HeatingSystem) || hpxml_hvac.is_a?(HPXML::HeatPump)
2321
+ # Heating
2322
+ if hpxml_hvac_ap.respond_to? :num_speeds
2323
+ num_speeds = hpxml_hvac_ap.num_speeds
2080
2324
  end
2325
+ num_speeds = 1 if num_speeds.nil?
2326
+ hvac.NumSpeedsHeating = num_speeds
2327
+ end
2081
2328
 
2082
- perf = equip.designSpecificationMultispeedObject.get
2083
- hvac.FanspeedRatioCooling = []
2084
- perf.supplyAirflowRatioFields.each do |airflowRatioField|
2085
- if not airflowRatioField.coolingRatio.is_initialized
2086
- fail "Cooling airflow ratio not set for #{perf.name}"
2087
- end
2088
-
2089
- hvac.FanspeedRatioCooling << airflowRatioField.coolingRatio.get
2329
+ # HVAC installation quality
2330
+ if hpxml_hvac.respond_to? :charge_defect_ratio
2331
+ if [HPXML::HVACTypeCentralAirConditioner,
2332
+ HPXML::HVACTypeMiniSplitAirConditioner,
2333
+ HPXML::HVACTypeHeatPumpAirToAir,
2334
+ HPXML::HVACTypeHeatPumpMiniSplit,
2335
+ HPXML::HVACTypeHeatPumpGroundToAir].include? hvac.CoolType
2336
+ hvac.ChargeDefectRatio = hpxml_hvac.charge_defect_ratio
2090
2337
  end
2091
-
2092
- curves = []
2093
- hvac.SHRRated = []
2094
- clg_coil.stages.each_with_index do |stage, speed|
2095
- curves << stage.totalCoolingCapacityFunctionofTemperatureCurve
2096
- if not stage.grossRatedSensibleHeatRatio.is_initialized
2097
- fail "SHR not set for #{clg_coil.name}."
2338
+ end
2339
+ if hpxml_hvac.respond_to? :airflow_defect_ratio
2340
+ # Cooling
2341
+ if [HPXML::HVACTypeCentralAirConditioner,
2342
+ HPXML::HVACTypeMiniSplitAirConditioner,
2343
+ HPXML::HVACTypeHeatPumpAirToAir,
2344
+ HPXML::HVACTypeHeatPumpMiniSplit,
2345
+ HPXML::HVACTypeHeatPumpGroundToAir].include? hvac.CoolType
2346
+ if not hpxml_hvac.distribution_system.nil? # Exclude ductless
2347
+ hvac.AirflowDefectRatioCooling = hpxml_hvac.airflow_defect_ratio
2098
2348
  end
2099
-
2100
- hvac.SHRRated << stage.grossRatedSensibleHeatRatio.get
2101
- next if !stage.grossRatedTotalCoolingCapacity.is_initialized
2102
-
2103
- hvac.FixedCoolingCapacity = UnitConversions.convert(stage.grossRatedTotalCoolingCapacity.get, 'W', 'Btu/hr')
2104
- end
2105
- hvac.COOL_CAP_FT_SPEC = get_2d_vector_from_CAP_FT_SPEC_curves(curves, hvac.NumSpeedsCooling)
2106
-
2107
- if hvac.CoolType == Constants.ObjectNameMiniSplitHeatPump
2108
- ratedCFMperTonCooling = get_feature(equip, Constants.SizingInfoHVACRatedCFMperTonCooling, 'string')
2109
- hvac.RatedCFMperTonCooling = ratedCFMperTonCooling.split(',').map(&:to_f)
2110
2349
  end
2111
-
2112
- elsif clg_coil.is_a? OpenStudio::Model::CoilCoolingWaterToAirHeatPumpEquationFit
2113
- hvac.NumSpeedsCooling = 1
2114
-
2115
- cOOL_CAP_FT_SPEC = [clg_coil.totalCoolingCapacityCoefficient1,
2116
- clg_coil.totalCoolingCapacityCoefficient2,
2117
- clg_coil.totalCoolingCapacityCoefficient3,
2118
- clg_coil.totalCoolingCapacityCoefficient4,
2119
- clg_coil.totalCoolingCapacityCoefficient5]
2120
- hvac.COOL_CAP_FT_SPEC = [HVAC.convert_curve_gshp(cOOL_CAP_FT_SPEC, true)]
2121
-
2122
- cOOL_SH_FT_SPEC = [clg_coil.sensibleCoolingCapacityCoefficient1,
2123
- clg_coil.sensibleCoolingCapacityCoefficient3,
2124
- clg_coil.sensibleCoolingCapacityCoefficient4,
2125
- clg_coil.sensibleCoolingCapacityCoefficient5,
2126
- clg_coil.sensibleCoolingCapacityCoefficient6]
2127
- hvac.COOL_SH_FT_SPEC = [HVAC.convert_curve_gshp(cOOL_SH_FT_SPEC, true)]
2128
-
2129
- cOIL_BF_FT_SPEC = get_feature(equip, Constants.SizingInfoGSHPCoil_BF_FT_SPEC, 'string')
2130
- hvac.COIL_BF_FT_SPEC = [cOIL_BF_FT_SPEC.split(',').map(&:to_f)]
2131
-
2132
- shr_rated = get_feature(equip, Constants.SizingInfoHVACSHR, 'string')
2133
- hvac.SHRRated = shr_rated.split(',').map(&:to_f)
2134
-
2135
- hvac.CoilBF = get_feature(equip, Constants.SizingInfoGSHPCoilBF, 'double')
2136
-
2137
- if clg_coil.ratedTotalCoolingCapacity.is_initialized
2138
- hvac.FixedCoolingCapacity = UnitConversions.convert(clg_coil.ratedTotalCoolingCapacity.get, 'W', 'Btu/hr')
2350
+ # Heating
2351
+ if [HPXML::HVACTypeFurnace,
2352
+ HPXML::HVACTypeHeatPumpAirToAir,
2353
+ HPXML::HVACTypeHeatPumpMiniSplit,
2354
+ HPXML::HVACTypeHeatPumpGroundToAir].include? hvac.HeatType
2355
+ if not hpxml_hvac.distribution_system.nil? # Exclude ductless
2356
+ hvac.AirflowDefectRatioHeating = hpxml_hvac.airflow_defect_ratio
2357
+ end
2139
2358
  end
2140
-
2141
- hvac.CoolingEIR = 1.0 / clg_coil.ratedCoolingCoefficientofPerformance
2142
-
2143
- hvac.GSHP_BoreSpacing = get_feature(equip, Constants.SizingInfoGSHPBoreSpacing, 'double')
2144
- hvac.GSHP_BoreHoles = get_feature(equip, Constants.SizingInfoGSHPBoreHoles, 'string')
2145
- hvac.GSHP_BoreHoles = nil if hvac.GSHP_BoreHoles.empty?
2146
- hvac.GSHP_BoreDepth = get_feature(equip, Constants.SizingInfoGSHPBoreDepth, 'string')
2147
- hvac.GSHP_BoreDepth = nil if hvac.GSHP_BoreDepth.empty?
2148
- hvac.GSHP_BoreConfig = get_feature(equip, Constants.SizingInfoGSHPBoreConfig, 'string')
2149
- hvac.GSHP_BoreConfig = nil if hvac.GSHP_BoreConfig.empty?
2150
- hvac.GSHP_SpacingType = get_feature(equip, Constants.SizingInfoGSHPUTubeSpacingType, 'string')
2151
- elsif not clg_coil.nil?
2152
- fail "Unexpected cooling coil: #{clg_coil.name}."
2153
2359
  end
2154
2360
 
2155
- if not htg_coil.nil?
2156
- ratedCFMperTonHeating = get_feature(equip, Constants.SizingInfoHVACRatedCFMperTonHeating, 'string', false)
2157
- if not ratedCFMperTonHeating.nil?
2158
- hvac.RatedCFMperTonHeating = ratedCFMperTonHeating.split(',').map(&:to_f)
2159
- end
2361
+ # Rated airflow rates
2362
+ if hpxml_hvac_ap.respond_to? :cool_rated_cfm_per_ton
2363
+ hvac.RatedCFMperTonCooling = hpxml_hvac_ap.cool_rated_cfm_per_ton
2160
2364
  end
2161
-
2162
- heatingLoadFraction = get_feature(equip, Constants.SizingInfoHVACFracHeatLoadServed, 'double', false)
2163
- if not heatingLoadFraction.nil?
2164
- hvac.HeatingLoadFraction = heatingLoadFraction
2365
+ if hpxml_hvac_ap.respond_to? :heat_rated_cfm_per_ton
2366
+ hvac.RatedCFMperTonHeating = hpxml_hvac_ap.heat_rated_cfm_per_ton
2165
2367
  end
2166
2368
 
2167
- if equip.is_a? OpenStudio::Model::ZoneHVACBaseboardConvectiveElectric
2168
- if equip.nominalCapacity.is_initialized
2169
- hvac.FixedHeatingCapacity = UnitConversions.convert(equip.nominalCapacity.get, 'W', 'Btu/hr')
2170
- end
2171
-
2172
- elsif htg_coil.is_a? OpenStudio::Model::CoilHeatingElectric
2173
- hvac.NumSpeedsHeating = 1
2174
- if htg_coil.nominalCapacity.is_initialized
2175
- hvac.FixedHeatingCapacity = UnitConversions.convert(htg_coil.nominalCapacity.get, 'W', 'Btu/hr')
2176
- end
2177
-
2178
- elsif htg_coil.is_a? OpenStudio::Model::CoilHeatingGas
2179
- hvac.NumSpeedsHeating = 1
2180
- if htg_coil.nominalCapacity.is_initialized
2181
- hvac.FixedHeatingCapacity = UnitConversions.convert(htg_coil.nominalCapacity.get, 'W', 'Btu/hr')
2182
- end
2183
-
2184
- elsif htg_coil.is_a? OpenStudio::Model::CoilHeatingWaterBaseboard
2185
- hvac.NumSpeedsHeating = 1
2186
- if htg_coil.heatingDesignCapacity.is_initialized
2187
- hvac.FixedHeatingCapacity = UnitConversions.convert(htg_coil.heatingDesignCapacity.get, 'W', 'Btu/hr')
2188
- end
2189
-
2190
- hvac.BoilerDesignTemp = UnitConversions.convert(htg_coil.plantLoop.get.sizingPlant.designLoopExitTemperature, 'C', 'F')
2191
-
2192
- elsif htg_coil.is_a? OpenStudio::Model::CoilHeatingWater
2193
- hvac.NumSpeedsHeating = 1
2194
- if htg_coil.ratedCapacity.is_initialized
2195
- hvac.FixedHeatingCapacity = UnitConversions.convert(htg_coil.ratedCapacity.get, 'W', 'Btu/hr')
2196
- end
2197
-
2198
- hvac.BoilerDesignTemp = UnitConversions.convert(htg_coil.plantLoop.get.sizingPlant.designLoopExitTemperature, 'C', 'F')
2199
-
2200
- elsif htg_coil.is_a? OpenStudio::Model::CoilHeatingDXSingleSpeed
2201
- hvac.NumSpeedsHeating = 1
2202
-
2203
- curves = [htg_coil.totalHeatingCapacityFunctionofTemperatureCurve]
2204
- hvac.HEAT_CAP_FT_SPEC = get_2d_vector_from_CAP_FT_SPEC_curves(curves, hvac.NumSpeedsHeating)
2205
-
2206
- if htg_coil.ratedTotalHeatingCapacity.is_initialized
2207
- hvac.FixedHeatingCapacity = UnitConversions.convert(htg_coil.ratedTotalHeatingCapacity.get, 'W', 'Btu/hr')
2208
- end
2209
-
2210
- elsif htg_coil.is_a? OpenStudio::Model::CoilHeatingDXMultiSpeed
2211
- hvac.NumSpeedsHeating = htg_coil.stages.size
2212
-
2213
- capacityRatioHeating = get_feature(equip, Constants.SizingInfoHVACCapacityRatioHeating, 'string')
2214
- hvac.CapacityRatioHeating = capacityRatioHeating.split(',').map(&:to_f)
2215
-
2216
- curves = []
2217
- htg_coil.stages.each_with_index do |stage, speed|
2218
- curves << stage.heatingCapacityFunctionofTemperatureCurve
2219
- next if !stage.grossRatedHeatingCapacity.is_initialized
2220
-
2221
- hvac.FixedHeatingCapacity = UnitConversions.convert(stage.grossRatedHeatingCapacity.get, 'W', 'Btu/hr')
2222
- end
2223
- hvac.HEAT_CAP_FT_SPEC = get_2d_vector_from_CAP_FT_SPEC_curves(curves, hvac.NumSpeedsHeating)
2369
+ # Capacity ratios
2370
+ if hpxml_hvac_ap.respond_to? :cool_capacity_ratios
2371
+ hvac.CapacityRatioCooling = hpxml_hvac_ap.cool_capacity_ratios
2372
+ end
2373
+ if hpxml_hvac_ap.respond_to? :heat_capacity_ratios
2374
+ hvac.CapacityRatioHeating = hpxml_hvac_ap.heat_capacity_ratios
2375
+ end
2224
2376
 
2225
- if hvac.HeatType == Constants.ObjectNameMiniSplitHeatPump
2226
- ratedCFMperTonHeating = get_feature(equip, Constants.SizingInfoHVACRatedCFMperTonHeating, 'string')
2227
- hvac.RatedCFMperTonHeating = ratedCFMperTonHeating.split(',').map(&:to_f)
2377
+ # Sizing speed
2378
+ hvac.SizingSpeed = get_sizing_speed(hvac.NumSpeedsCooling, hvac.CapacityRatioCooling)
2228
2379
 
2229
- hvac.HeatingCapacityOffset = get_feature(equip, Constants.SizingInfoHVACHeatingCapacityOffset, 'double')
2230
- end
2380
+ # Rated SHRs
2381
+ if hpxml_hvac_ap.respond_to? :cool_rated_shrs_gross
2382
+ hvac.SHRRated = hpxml_hvac_ap.cool_rated_shrs_gross
2383
+ end
2231
2384
 
2232
- elsif htg_coil.is_a? OpenStudio::Model::CoilHeatingWaterToAirHeatPumpEquationFit
2233
- hvac.NumSpeedsHeating = 1
2385
+ # Performance curves
2386
+ if hpxml_hvac_ap.respond_to? :cool_cap_ft_spec
2387
+ hvac.COOL_CAP_FT_SPEC = hpxml_hvac_ap.cool_cap_ft_spec
2388
+ end
2389
+ if hpxml_hvac_ap.respond_to? :cool_sh_ft_spec
2390
+ hvac.COOL_SH_FT_SPEC = hpxml_hvac_ap.cool_sh_ft_spec
2391
+ end
2392
+ if hpxml_hvac_ap.respond_to? :heat_cap_ft_spec
2393
+ hvac.HEAT_CAP_FT_SPEC = hpxml_hvac_ap.heat_cap_ft_spec
2394
+ end
2395
+ if hpxml_hvac_ap.respond_to? :cool_cap_fflow_spec
2396
+ hvac.COOL_CAP_FFLOW_SPEC = hpxml_hvac_ap.cool_cap_fflow_spec
2397
+ end
2398
+ if hpxml_hvac_ap.respond_to? :heat_cap_fflow_spec
2399
+ hvac.HEAT_CAP_FFLOW_SPEC = hpxml_hvac_ap.heat_cap_fflow_spec
2400
+ end
2234
2401
 
2235
- if htg_coil.ratedHeatingCapacity.is_initialized
2236
- hvac.FixedHeatingCapacity = UnitConversions.convert(htg_coil.ratedHeatingCapacity.get, 'W', 'Btu/hr')
2237
- end
2402
+ # WLHP
2403
+ if hpxml_hvac.respond_to? :heating_efficiency_cop
2404
+ hvac.HeatingCOP = hpxml_hvac.heating_efficiency_cop
2405
+ end
2238
2406
 
2239
- hvac.HeatingEIR = 1.0 / htg_coil.ratedHeatingCoefficientofPerformance
2407
+ # GSHP
2408
+ if hpxml_hvac_ap.respond_to? :u_tube_spacing_type
2409
+ hvac.GSHP_SpacingType = hpxml_hvac_ap.u_tube_spacing_type
2410
+ end
2411
+ if hpxml_hvac_ap.respond_to? :cool_rated_eirs
2412
+ hvac.CoolingEIR = hpxml_hvac_ap.cool_rated_eirs[0]
2413
+ end
2414
+ if hpxml_hvac_ap.respond_to? :heat_rated_eirs
2415
+ hvac.HeatingEIR = hpxml_hvac_ap.heat_rated_eirs[0]
2416
+ end
2417
+ if hvac.HeatType == HPXML::HVACTypeHeatPumpGroundToAir
2418
+ hvac.GSHP_design_chw = hpxml_hvac_ap.design_chw
2419
+ hvac.GSHP_design_delta_t = hpxml_hvac_ap.design_delta_t
2420
+ hvac.GSHP_design_hw = hpxml_hvac_ap.design_hw
2421
+ hvac.GSHP_bore_d = hpxml_hvac_ap.bore_diameter
2422
+ hvac.GSHP_pipe_od = hpxml_hvac_ap.pipe_od
2423
+ hvac.GSHP_pipe_id = hpxml_hvac_ap.pipe_id
2424
+ hvac.GSHP_pipe_cond = hpxml_hvac_ap.pipe_cond
2425
+ hvac.GSHP_ground_k = hpxml_hvac_ap.ground_conductivity
2426
+ hvac.GSHP_grout_k = hpxml_hvac_ap.grout_conductivity
2427
+ end
2240
2428
 
2241
- plant_loop = htg_coil.plantLoop.get
2242
- plant_loop.supplyComponents.each do |plc|
2243
- next if !plc.to_GroundHeatExchangerVertical.is_initialized
2429
+ # Evaporative cooler
2430
+ if hpxml_hvac_ap.respond_to? :effectiveness
2431
+ hvac.EvapCoolerEffectiveness = hpxml_hvac_ap.effectiveness
2432
+ end
2244
2433
 
2245
- hvac.GSHP_HXVertical = plc.to_GroundHeatExchangerVertical.get
2246
- end
2247
- if hvac.GSHP_HXVertical.nil?
2248
- fail 'Could not find GroundHeatExchangerVertical object on GSHP plant loop.'
2249
- end
2434
+ # Ducts
2435
+ # FUTURE: Consolidate w/ ducts code in measure.rb
2436
+ hvac.Ducts = []
2437
+ next unless not hpxml_hvac.distribution_system.nil?
2438
+ lto = { supply_percent: nil, supply_cfm25: nil, return_percent: nil, return_cfm25: nil }
2439
+ hpxml_hvac.distribution_system.duct_leakage_measurements.each do |m|
2440
+ next unless m.duct_leakage_total_or_to_outside == 'to outside'
2250
2441
 
2251
- hvac.GSHP_HXDTDesign = UnitConversions.convert(plant_loop.sizingPlant.loopDesignTemperatureDifference, 'K', 'R')
2252
- hvac.GSHP_HXCHWDesign = UnitConversions.convert(plant_loop.sizingPlant.designLoopExitTemperature, 'C', 'F')
2253
- hvac.GSHP_HXHWDesign = UnitConversions.convert(plant_loop.minimumLoopTemperature, 'C', 'F')
2254
- if hvac.GSHP_HXDTDesign.nil? || hvac.GSHP_HXCHWDesign.nil? || hvac.GSHP_HXHWDesign.nil?
2255
- fail 'Could not find GSHP plant loop.'
2442
+ if m.duct_leakage_units == HPXML::UnitsPercent && m.duct_type == HPXML::DuctTypeSupply
2443
+ lto[:supply_percent] = m.duct_leakage_value
2444
+ elsif m.duct_leakage_units == HPXML::UnitsCFM25 && m.duct_type == HPXML::DuctTypeSupply
2445
+ lto[:supply_cfm25] = m.duct_leakage_value
2446
+ elsif m.duct_leakage_units == HPXML::UnitsPercent && m.duct_type == HPXML::DuctTypeReturn
2447
+ lto[:return_percent] = m.duct_leakage_value
2448
+ elsif m.duct_leakage_units == HPXML::UnitsCFM25 && m.duct_type == HPXML::DuctTypeReturn
2449
+ lto[:return_cfm25] = m.duct_leakage_value
2256
2450
  end
2451
+ end
2452
+ total_uncond_supply_area = hpxml_hvac.distribution_system.total_unconditioned_duct_areas[HPXML::DuctTypeSupply]
2453
+ total_uncond_return_area = hpxml_hvac.distribution_system.total_unconditioned_duct_areas[HPXML::DuctTypeReturn]
2454
+ hpxml_hvac.distribution_system.ducts.each do |duct|
2455
+ next if [HPXML::LocationLivingSpace, HPXML::LocationBasementConditioned].include? duct.duct_location
2257
2456
 
2258
- hvac.GSHP_PumpWattsPerTon = get_feature(equip, Constants.SizingInfoHVACPumpPower, 'double')
2457
+ d = DuctInfo.new
2458
+ d.Side = duct.duct_type
2459
+ d.Location = duct.duct_location
2460
+ d.Area = duct.duct_surface_area
2259
2461
 
2260
- elsif not htg_coil.nil?
2261
- fail "Unexpected heating coil: #{htg_coil.name}."
2262
- end
2462
+ # Calculate R-value w/ air film
2463
+ d.Rvalue = Airflow.get_duct_insulation_rvalue(duct.duct_insulation_r_value, d.Side)
2263
2464
 
2264
- # Supplemental heating
2265
- if supp_htg_coil.is_a?(OpenStudio::Model::CoilHeatingElectric) || supp_htg_coil.is_a?(OpenStudio::Model::CoilHeatingGas)
2266
- if supp_htg_coil.nominalCapacity.is_initialized
2267
- hvac.FixedSuppHeatingCapacity = UnitConversions.convert(supp_htg_coil.nominalCapacity.get, 'W', 'Btu/hr')
2465
+ # Leakage to Outside apportioned to this duct
2466
+ if d.Side == HPXML::DuctTypeSupply
2467
+ d.LeakageFrac = lto[:supply_percent].to_f * d.Area / total_uncond_supply_area
2468
+ d.LeakageCFM25 = lto[:supply_cfm25].to_f * d.Area / total_uncond_supply_area
2469
+ elsif d.Side == HPXML::DuctTypeReturn
2470
+ d.LeakageFrac = lto[:return_percent].to_f * d.Area / total_uncond_return_area
2471
+ d.LeakageCFM25 = lto[:return_cfm25].to_f * d.Area / total_uncond_return_area
2268
2472
  end
2269
-
2270
- elsif not supp_htg_coil.nil?
2271
- fail "Unexpected supplemental heating coil: #{supp_htg_coil.name}."
2473
+ hvac.Ducts << d
2272
2474
  end
2475
+ # If all ducts are in conditioned space, treat leakage as going to outside
2476
+ if (lto[:supply_percent].to_f + lto[:supply_cfm25].to_f) > 0 && total_uncond_supply_area == 0
2477
+ d = DuctInfo.new
2478
+ d.Side = HPXML::DuctTypeSupply
2479
+ d.Location = HPXML::LocationOutside
2480
+ d.Area = 0.0
2481
+ d.Rvalue = Airflow.get_duct_insulation_rvalue(0.0, d.Side)
2482
+ d.LeakageFrac = lto[:supply_percent]
2483
+ d.LeakageCFM25 = lto[:supply_cfm25]
2484
+ hvac.Ducts << d
2485
+ end
2486
+ next unless (lto[:return_percent].to_f + lto[:return_cfm25].to_f) > 0 && total_uncond_return_area == 0
2487
+ d = DuctInfo.new
2488
+ d.Side = HPXML::DuctTypeReturn
2489
+ d.Location = HPXML::LocationOutside
2490
+ d.Area = 0.0
2491
+ d.Rvalue = Airflow.get_duct_insulation_rvalue(0.0, d.Side)
2492
+ d.LeakageFrac = lto[:return_percent]
2493
+ d.LeakageCFM25 = lto[:return_cfm25]
2494
+ hvac.Ducts << d
2273
2495
  end
2274
2496
 
2275
- return hvacs
2276
- end
2277
-
2278
- def self.get_2d_vector_from_CAP_FT_SPEC_curves(curves, num_speeds)
2279
- vector = []
2280
- curves.each do |curve|
2281
- bi = curve.to_CurveBiquadratic.get
2282
- c_si = [bi.coefficient1Constant, bi.coefficient2x, bi.coefficient3xPOW2, bi.coefficient4y, bi.coefficient5yPOW2, bi.coefficient6xTIMESY]
2283
- vector << HVAC.convert_curve_biquadratic(c_si, curves_in_ip = false)
2284
- end
2285
- if (num_speeds > 1) && (vector.size == 1)
2286
- # Repeat coefficients for each speed
2287
- for i in 1..num_speeds
2288
- vector << vector[0]
2289
- end
2290
- end
2291
- return vector
2497
+ return hvac
2292
2498
  end
2293
2499
 
2294
2500
  def self.process_curve_fit(airFlowRate, capacity, temp)
@@ -2296,16 +2502,23 @@ class HVACSizing
2296
2502
  return 0 if capacity == 0
2297
2503
 
2298
2504
  capacity_tons = UnitConversions.convert(capacity, 'Btu/hr', 'ton')
2299
- return MathTools.biquadratic(airFlowRate / capacity_tons, temp, @shr_biquadratic)
2505
+ return MathTools.biquadratic(airFlowRate / capacity_tons, temp, get_shr_biquadratic)
2506
+ end
2507
+
2508
+ def self.get_shr_biquadratic
2509
+ # Based on EnergyPlus's model for calculating SHR at off-rated conditions. This curve fit
2510
+ # avoids the iterations in the actual model. It does not account for altitude or variations
2511
+ # in the SHRRated. It is a function of ODB (MJ design temp) and CFM/Ton (from MJ)
2512
+ return [1.08464364, 0.002096954, 0, -0.005766327, 0, -0.000011147]
2300
2513
  end
2301
2514
 
2302
- def self.get_sizing_speed(hvac)
2303
- if hvac.NumSpeedsCooling > 1
2304
- sizingSpeed = hvac.NumSpeedsCooling # Default
2515
+ def self.get_sizing_speed(num_speeds_cooling, capacity_ratios_cooling)
2516
+ if num_speeds_cooling > 1
2517
+ sizingSpeed = num_speeds_cooling # Default
2305
2518
  sizingSpeed_Test = 10 # Initialize
2306
- for speed in 0..(hvac.NumSpeedsCooling - 1)
2519
+ for speed in 0..(num_speeds_cooling - 1)
2307
2520
  # Select curves for sizing using the speed with the capacity ratio closest to 1
2308
- temp = (hvac.CapacityRatioCooling[speed] - 1).abs
2521
+ temp = (capacity_ratios_cooling[speed] - 1).abs
2309
2522
  if temp <= sizingSpeed_Test
2310
2523
  sizingSpeed = speed
2311
2524
  sizingSpeed_Test = temp
@@ -2353,8 +2566,44 @@ class HVACSizing
2353
2566
  end
2354
2567
 
2355
2568
  # Infiltration UA
2356
- infiltration_cfm = get_feature(@spaces[space_type].thermalZone.get, Constants.SizingInfoZoneInfiltrationCFM, 'double', false)
2357
- infiltration_cfm = 0.0 if infiltration_cfm.nil?
2569
+ infiltration_cfm = nil
2570
+ ach = nil
2571
+ if [HPXML::LocationCrawlspaceVented, HPXML::LocationAtticVented].include? space_type
2572
+ # Vented space
2573
+ if space_type == HPXML::LocationCrawlspaceVented
2574
+ vented_crawl = @hpxml.foundations.select { |f| f.foundation_type == HPXML::FoundationTypeCrawlspaceVented }[0]
2575
+ sla = vented_crawl.vented_crawlspace_sla
2576
+ else
2577
+ vented_attic = @hpxml.attics.select { |f| f.attic_type == HPXML::AtticTypeVented }[0]
2578
+ if not vented_attic.vented_attic_sla.nil?
2579
+ sla = vented_attic.vented_attic_sla
2580
+ else
2581
+ ach = vented_attic.vented_attic_ach
2582
+ end
2583
+ end
2584
+ ach = Airflow.get_infiltration_ACH_from_SLA(sla, 8.202, weather) if ach.nil?
2585
+ else # Unvented space
2586
+ ach = 0.1 # Assumption
2587
+ end
2588
+ # FUTURE: Reuse code from Geometry.set_zone_volumes()
2589
+ if [HPXML::LocationAtticVented, HPXML::LocationAtticUnvented].include? space_type
2590
+ 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)
2591
+ roofs = @hpxml.roofs.select { |r| r.interior_adjacent_to == space_type }
2592
+ avg_pitch = roofs.map { |r| r.pitch }.sum(0.0) / roofs.size
2593
+ # Assume square hip roof for volume calculations; energy results are very insensitive to actual volume
2594
+ length = floor_area**0.5
2595
+ height = 0.5 * Math.sin(Math.atan(avg_pitch / 12.0)) * length
2596
+ volume = [floor_area * height / 3.0, 0.01].max
2597
+ else # foundation/garage space
2598
+ floor_area = @hpxml.slabs.select { |s| s.interior_adjacent_to == space_type }.map { |s| s.area }.sum(0.0)
2599
+ if space_type == HPXML::LocationGarage
2600
+ height = 8.0
2601
+ else
2602
+ height = @hpxml.foundation_walls.select { |w| w.interior_adjacent_to == space_type }.map { |w| w.height }.max
2603
+ end
2604
+ volume = floor_area * height
2605
+ end
2606
+ infiltration_cfm = ach / UnitConversions.convert(1.0, 'hr', 'min') * volume
2358
2607
  outside_air_density = UnitConversions.convert(weather.header.LocalPressure, 'atm', 'Btu/ft^3') / (Gas.Air.r * (weather.data.AnnualAvgDrybulb + 460.0))
2359
2608
  space_UAs['infil'] = infiltration_cfm * outside_air_density * Gas.Air.cp * UnitConversions.convert(1.0, 'hr', 'min')
2360
2609
 
@@ -2404,8 +2653,8 @@ class HVACSizing
2404
2653
  # when the roof is insulated
2405
2654
  min_temp_rise = 5.0
2406
2655
 
2407
- max_cooling_temp = @conditioned_cool_design_temp + max_temp_rise
2408
- min_cooling_temp = @conditioned_cool_design_temp + min_temp_rise
2656
+ max_cooling_temp = @cool_setpoint + max_temp_rise
2657
+ min_cooling_temp = @cool_setpoint + min_temp_rise
2409
2658
 
2410
2659
  ua_conditioned = 0.0
2411
2660
  ua_outside = 0.0
@@ -2447,42 +2696,85 @@ class HVACSizing
2447
2696
  wall_ufactor = 1.0 / wall.insulation_assembly_r_value
2448
2697
 
2449
2698
  # The following correlations were estimated by analyzing MJ8 construction tables.
2450
- if [HPXML::WallTypeWoodStud, HPXML::WallTypeSteelStud].include? wall_type
2451
- if wall.insulation_cavity_r_value < 2
2452
- wall_group = 1 # A
2453
- elsif wall.insulation_cavity_r_value <= 11
2454
- wall_group = 2 # B
2455
- elsif wall.insulation_cavity_r_value <= 13
2456
- wall_group = 3 # C
2457
- elsif wall.insulation_cavity_r_value <= 15
2458
- wall_group = 4 # D
2459
- elsif wall.insulation_cavity_r_value <= 19
2460
- wall_group = 5 # E
2461
- elsif wall.insulation_cavity_r_value <= 21
2462
- wall_group = 6 # F
2463
- else
2464
- wall_group = 7 # G
2465
- end
2466
- # Adjust the wall group for rigid foam insulation
2467
- if (wall.insulation_continuous_r_value > 1) && (wall.insulation_continuous_r_value <= 7)
2468
- if wall.insulation_cavity_r_value < 2
2469
- wall_group += 2
2699
+ if wall_type == HPXML::WallTypeWoodStud
2700
+ if wall.siding == HPXML::SidingTypeBrick
2701
+ if wall_ufactor <= 0.070
2702
+ wall_group = 11 # K
2703
+ elsif wall_ufactor <= 0.083
2704
+ wall_group = 10 # J
2705
+ elsif wall_ufactor <= 0.095
2706
+ wall_group = 9 # I
2707
+ elsif wall_ufactor <= 0.100
2708
+ wall_group = 8 # H
2709
+ elsif wall_ufactor <= 0.130
2710
+ wall_group = 7 # G
2711
+ elsif wall_ufactor <= 0.175
2712
+ wall_group = 6 # F
2470
2713
  else
2471
- wall_group += 4
2714
+ wall_group = 5 # E
2472
2715
  end
2473
- elsif wall.insulation_continuous_r_value > 7
2474
- if wall.insulation_cavity_r_value < 2
2475
- wall_group += 4
2716
+ else
2717
+ if wall_ufactor <= 0.048
2718
+ wall_group = 10 # J
2719
+ elsif wall_ufactor <= 0.051
2720
+ wall_group = 9 # I
2721
+ elsif wall_ufactor <= 0.059
2722
+ wall_group = 8 # H
2723
+ elsif wall_ufactor <= 0.063
2724
+ wall_group = 7 # G
2725
+ elsif wall_ufactor <= 0.067
2726
+ wall_group = 6 # F
2727
+ elsif wall_ufactor <= 0.075
2728
+ wall_group = 5 # E
2729
+ elsif wall_ufactor <= 0.086
2730
+ wall_group = 4 # D
2731
+ elsif wall_ufactor <= 0.110
2732
+ wall_group = 3 # C
2733
+ elsif wall_ufactor <= 0.170
2734
+ wall_group = 2 # B
2476
2735
  else
2477
- wall_group += 6
2736
+ wall_group = 1 # A
2478
2737
  end
2479
2738
  end
2480
- # Adjust the wall group for brick siding
2739
+
2740
+ elsif wall_type == HPXML::WallTypeSteelStud
2481
2741
  if wall.siding == HPXML::SidingTypeBrick
2482
- if wall.insulation_cavity_r_value < 2
2483
- wall_group += 4
2742
+ if wall_ufactor <= 0.090
2743
+ wall_group = 11 # K
2744
+ elsif wall_ufactor <= 0.105
2745
+ wall_group = 10 # J
2746
+ elsif wall_ufactor <= 0.118
2747
+ wall_group = 9 # I
2748
+ elsif wall_ufactor <= 0.125
2749
+ wall_group = 8 # H
2750
+ elsif wall_ufactor <= 0.145
2751
+ wall_group = 7 # G
2752
+ elsif wall_ufactor <= 0.200
2753
+ wall_group = 6 # F
2754
+ else
2755
+ wall_group = 5 # E
2756
+ end
2757
+ else
2758
+ if wall_ufactor <= 0.066
2759
+ wall_group = 10 # J
2760
+ elsif wall_ufactor <= 0.070
2761
+ wall_group = 9 # I
2762
+ elsif wall_ufactor <= 0.075
2763
+ wall_group = 8 # H
2764
+ elsif wall_ufactor <= 0.081
2765
+ wall_group = 7 # G
2766
+ elsif wall_ufactor <= 0.088
2767
+ wall_group = 6 # F
2768
+ elsif wall_ufactor <= 0.100
2769
+ wall_group = 5 # E
2770
+ elsif wall_ufactor <= 0.105
2771
+ wall_group = 4 # D
2772
+ elsif wall_ufactor <= 0.120
2773
+ wall_group = 3 # C
2774
+ elsif wall_ufactor <= 0.200
2775
+ wall_group = 2 # B
2484
2776
  else
2485
- wall_group += 6
2777
+ wall_group = 1 # A
2486
2778
  end
2487
2779
  end
2488
2780
 
@@ -2511,24 +2803,20 @@ class HVACSizing
2511
2803
  end
2512
2804
 
2513
2805
  elsif wall_type == HPXML::WallTypeCMU
2514
- # Manual J uses the same wall group for filled or hollow block
2515
- if wall.insulation_cavity_r_value < 2
2516
- wall_group = 5 # E
2517
- elsif wall.insulation_cavity_r_value <= 11
2518
- wall_group = 8 # H
2519
- elsif wall.insulation_cavity_r_value <= 13
2520
- wall_group = 9 # I
2521
- elsif wall.insulation_cavity_r_value <= 15
2522
- wall_group = 9 # I
2523
- elsif wall.insulation_cavity_r_value <= 19
2806
+ # Table 4A - Construction Number 13
2807
+ if wall_ufactor <= 0.0575
2524
2808
  wall_group = 10 # J
2525
- elsif wall.insulation_cavity_r_value <= 21
2526
- wall_group = 11 # K
2809
+ elsif wall_ufactor <= 0.067
2810
+ wall_group = 9 # I
2811
+ elsif wall_ufactor <= 0.080
2812
+ wall_group = 8 # H
2813
+ elsif wall_ufactor <= 0.108
2814
+ wall_group = 7 # G
2815
+ elsif wall_ufactor <= 0.148
2816
+ wall_group = 6 # F
2527
2817
  else
2528
- wall_group = 11 # K
2818
+ wall_group = 5 # E
2529
2819
  end
2530
- # This is an estimate based on Table 4A - Construction Number 13
2531
- wall_group += (wall.insulation_continuous_r_value / 3.0).floor # Group is increased by approximately 1 letter for each R3
2532
2820
 
2533
2821
  elsif [HPXML::WallTypeBrick, HPXML::WallTypeAdobe].include? wall_type
2534
2822
  # Two Courses Brick
@@ -2569,32 +2857,40 @@ class HVACSizing
2569
2857
  return wall_group
2570
2858
  end
2571
2859
 
2572
- def self.gshp_hx_pipe_rvalue(pipe_od, pipe_id, pipe_cond)
2860
+ def self.gshp_coil_bf
2861
+ return 0.0806
2862
+ end
2863
+
2864
+ def self.gshp_coil_bf_ft_spec
2865
+ return [1.21005458, -0.00664200, 0.00000000, 0.00348246, 0.00000000, 0.00000000]
2866
+ end
2867
+
2868
+ def self.gshp_hx_pipe_rvalue(hvac)
2573
2869
  # Thermal Resistance of Pipe
2574
- return Math.log(pipe_od / pipe_id) / 2.0 / Math::PI / pipe_cond
2870
+ return Math.log(hvac.GSHP_pipe_od / hvac.GSHP_pipe_id) / 2.0 / Math::PI / hvac.GSHP_pipe_cond
2575
2871
  end
2576
2872
 
2577
- def self.gshp_hxbore_ft_per_ton(weather, bore_spacing, ground_conductivity, spacing_type, grout_conductivity, bore_diameter, pipe_od, pipe_r_value, heating_eir, cooling_eir, chw_design, hw_design, design_delta_t)
2578
- if spacing_type == 'b'
2873
+ def self.gshp_hxbore_ft_per_ton(weather, hvac, bore_spacing, pipe_r_value)
2874
+ if hvac.GSHP_SpacingType == 'b'
2579
2875
  beta_0 = 17.4427
2580
2876
  beta_1 = -0.6052
2581
- elsif spacing_type == 'c'
2877
+ elsif hvac.GSHP_SpacingType == 'c'
2582
2878
  beta_0 = 21.9059
2583
2879
  beta_1 = -0.3796
2584
- elsif spacing_type == 'as'
2880
+ elsif hvac.GSHP_SpacingType == 'as'
2585
2881
  beta_0 = 20.1004
2586
2882
  beta_1 = -0.94467
2587
2883
  end
2588
2884
 
2589
- r_value_ground = Math.log(bore_spacing / bore_diameter * 12.0) / 2.0 / Math::PI / ground_conductivity
2590
- r_value_grout = 1.0 / grout_conductivity / beta_0 / ((bore_diameter / pipe_od)**beta_1)
2885
+ r_value_ground = Math.log(bore_spacing / hvac.GSHP_bore_d * 12.0) / 2.0 / Math::PI / hvac.GSHP_ground_k
2886
+ r_value_grout = 1.0 / hvac.GSHP_grout_k / beta_0 / ((hvac.GSHP_bore_d / hvac.GSHP_pipe_od)**beta_1)
2591
2887
  r_value_bore = r_value_grout + pipe_r_value / 2.0 # Note: Convection resistance is negligible when calculated against Glhepro (Jeffrey D. Spitler, 2000)
2592
2888
 
2593
2889
  rtf_DesignMon_Heat = [0.25, (71.0 - weather.data.MonthlyAvgDrybulbs[0]) / @htd].max
2594
2890
  rtf_DesignMon_Cool = [0.25, (weather.data.MonthlyAvgDrybulbs[6] - 76.0) / @ctd].max
2595
2891
 
2596
- nom_length_heat = (1.0 - heating_eir) * (r_value_bore + r_value_ground * rtf_DesignMon_Heat) / (weather.data.AnnualAvgDrybulb - (2.0 * hw_design - design_delta_t) / 2.0) * UnitConversions.convert(1.0, 'ton', 'Btu/hr')
2597
- nom_length_cool = (1.0 + cooling_eir) * (r_value_bore + r_value_ground * rtf_DesignMon_Cool) / ((2.0 * chw_design + design_delta_t) / 2.0 - weather.data.AnnualAvgDrybulb) * UnitConversions.convert(1.0, 'ton', 'Btu/hr')
2892
+ nom_length_heat = (1.0 - hvac.HeatingEIR) * (r_value_bore + r_value_ground * rtf_DesignMon_Heat) / (weather.data.AnnualAvgDrybulb - (2.0 * hvac.GSHP_design_hw - hvac.GSHP_design_delta_t) / 2.0) * UnitConversions.convert(1.0, 'ton', 'Btu/hr')
2893
+ nom_length_cool = (1.0 + hvac.CoolingEIR) * (r_value_bore + r_value_ground * rtf_DesignMon_Cool) / ((2.0 * hvac.GSHP_design_chw + hvac.GSHP_design_delta_t) / 2.0 - weather.data.AnnualAvgDrybulb) * UnitConversions.convert(1.0, 'ton', 'Btu/hr')
2598
2894
 
2599
2895
  return nom_length_heat, nom_length_cool
2600
2896
  end
@@ -2602,9 +2898,9 @@ class HVACSizing
2602
2898
  def self.gshp_gfnc_coeff(bore_config, num_bore_holes, spacing_to_depth_ratio)
2603
2899
  # Set GFNC coefficients
2604
2900
  gfnc_coeff = nil
2605
- if bore_config == Constants.BoreConfigSingle
2901
+ if bore_config == 'single'
2606
2902
  gfnc_coeff = 2.681, 3.024, 3.320, 3.666, 3.963, 4.306, 4.645, 4.899, 5.222, 5.405, 5.531, 5.704, 5.821, 6.082, 6.304, 6.366, 6.422, 6.477, 6.520, 6.558, 6.591, 6.619, 6.640, 6.665, 6.893, 6.694, 6.715
2607
- elsif bore_config == Constants.BoreConfigLine
2903
+ elsif bore_config == 'line'
2608
2904
  if num_bore_holes == 2
2609
2905
  if spacing_to_depth_ratio <= 0.02
2610
2906
  gfnc_coeff = 2.681, 3.043, 3.397, 3.9, 4.387, 5.005, 5.644, 6.137, 6.77, 7.131, 7.381, 7.722, 7.953, 8.462, 8.9, 9.022, 9.13, 9.238, 9.323, 9.396, 9.46, 9.515, 9.556, 9.604, 9.636, 9.652, 9.678
@@ -2714,7 +3010,7 @@ class HVACSizing
2714
3010
  gfnc_coeff = 2.679, 3.023, 3.318, 3.664, 3.961, 4.306, 4.65, 4.838, 5.275, 5.587, 5.837, 6.238, 6.552, 7.399, 8.347, 8.654, 8.956, 9.283, 9.549, 9.79, 10.014, 10.209, 10.36, 10.541, 10.669, 10.732, 10.837
2715
3011
  end
2716
3012
  end
2717
- elsif bore_config == Constants.BoreConfigLconfig
3013
+ elsif bore_config == 'l-config'
2718
3014
  if num_bore_holes == 3
2719
3015
  if spacing_to_depth_ratio <= 0.02
2720
3016
  gfnc_coeff = 2.682, 3.052, 3.435, 4.036, 4.668, 5.519, 6.435, 7.155, 8.091, 8.626, 8.997, 9.504, 9.847, 10.605, 11.256, 11.434, 11.596, 11.755, 11.88, 11.988, 12.083, 12.163, 12.224, 12.294, 12.342, 12.365, 12.405
@@ -2764,7 +3060,7 @@ class HVACSizing
2764
3060
  gfnc_coeff = 2.679, 3.023, 3.318, 3.664, 3.961, 4.306, 4.65, 4.838, 5.27, 5.579, 5.828, 6.225, 6.535, 7.384, 8.244, 8.515, 8.768, 9.026, 9.244, 9.428, 9.595, 9.737, 9.845, 9.97, 10.057, 10.099, 10.168
2765
3061
  end
2766
3062
  end
2767
- elsif bore_config == Constants.BoreConfigL2config
3063
+ elsif bore_config == 'l2-config'
2768
3064
  if num_bore_holes == 8
2769
3065
  if spacing_to_depth_ratio <= 0.02
2770
3066
  gfnc_coeff = 2.685, 3.078, 3.547, 4.438, 5.521, 7.194, 9.237, 10.973, 13.311, 14.677, 15.634, 16.942, 17.831, 19.791, 21.462, 21.917, 22.329, 22.734, 23.052, 23.328, 23.568, 23.772, 23.925, 24.102, 24.224, 24.283, 24.384
@@ -2790,7 +3086,7 @@ class HVACSizing
2790
3086
  gfnc_coeff = 2.679, 3.023, 3.318, 3.664, 3.961, 4.307, 4.653, 4.842, 5.331, 5.731, 6.083, 6.683, 7.178, 8.6, 10.054, 10.508, 10.929, 11.356, 11.711, 12.009, 12.275, 12.5, 12.671, 12.866, 13, 13.064, 13.17
2791
3087
  end
2792
3088
  end
2793
- elsif bore_config == Constants.BoreConfigUconfig
3089
+ elsif bore_config == 'u-config'
2794
3090
  if num_bore_holes == 5
2795
3091
  if spacing_to_depth_ratio <= 0.02
2796
3092
  gfnc_coeff = 2.683, 3.057, 3.46, 4.134, 4.902, 6.038, 7.383, 8.503, 9.995, 10.861, 11.467, 12.294, 12.857, 14.098, 15.16, 15.449, 15.712, 15.97, 16.173, 16.349, 16.503, 16.633, 16.731, 16.844, 16.922, 16.96, 17.024
@@ -2828,7 +3124,7 @@ class HVACSizing
2828
3124
  gfnc_coeff = 2.679, 3.023, 3.318, 3.664, 3.961, 4.306, 4.65, 4.838, 5.277, 5.6, 5.87, 6.322, 6.698, 7.823, 9.044, 9.438, 9.809, 10.188, 10.506, 10.774, 11.015, 11.219, 11.374, 11.552, 11.674, 11.733, 11.83
2829
3125
  end
2830
3126
  end
2831
- elsif bore_config == Constants.BoreConfigOpenRectangle
3127
+ elsif bore_config == 'open-rectangle'
2832
3128
  if num_bore_holes == 8
2833
3129
  if spacing_to_depth_ratio <= 0.02
2834
3130
  gfnc_coeff = 2.684, 3.066, 3.497, 4.275, 5.229, 6.767, 8.724, 10.417, 12.723, 14.079, 15.03, 16.332, 17.217, 19.17, 20.835, 21.288, 21.698, 22.101, 22.417, 22.692, 22.931, 23.133, 23.286, 23.462, 23.583, 23.642, 23.742
@@ -2854,7 +3150,7 @@ class HVACSizing
2854
3150
  gfnc_coeff = 2.679, 3.023, 3.318, 3.664, 3.961, 4.306, 4.651, 4.839, 5.292, 5.636, 5.928, 6.425, 6.841, 8.089, 9.44, 9.875, 10.284, 10.7, 11.05, 11.344, 11.608, 11.831, 12.001, 12.196, 12.329, 12.393, 12.499
2855
3151
  end
2856
3152
  end
2857
- elsif bore_config == Constants.BoreConfigRectangle
3153
+ elsif bore_config == 'rectangle'
2858
3154
  if num_bore_holes == 4
2859
3155
  if spacing_to_depth_ratio <= 0.02
2860
3156
  gfnc_coeff = 2.684, 3.066, 3.493, 4.223, 5.025, 6.131, 7.338, 8.291, 9.533, 10.244, 10.737, 11.409, 11.865, 12.869, 13.73, 13.965, 14.178, 14.388, 14.553, 14.696, 14.821, 14.927, 15.007, 15.099, 15.162, 15.193, 15.245
@@ -3043,388 +3339,24 @@ class HVACSizing
3043
3339
 
3044
3340
  return f_values.sum() / f_values.size
3045
3341
  end
3046
-
3047
- def self.get_feature(obj, feature, datatype, fail_on_error = true)
3048
- val = nil
3049
- if datatype == 'string'
3050
- val = obj.additionalProperties.getFeatureAsString(feature)
3051
- elsif datatype == 'double'
3052
- val = obj.additionalProperties.getFeatureAsDouble(feature)
3053
- elsif datatype == 'boolean'
3054
- val = obj.additionalProperties.getFeatureAsBoolean(feature)
3055
- end
3056
- if not val.is_initialized
3057
- if fail_on_error
3058
- fail "Could not find additionalProperties value for '#{feature}' with datatype #{datatype} on object #{obj.name}."
3059
- end
3060
-
3061
- return
3062
- end
3063
- return val.get
3064
- end
3065
-
3066
- def self.set_object_values(model, hvac, hvac_final_values)
3067
- # Updates object properties in the model
3068
-
3069
- hvac.Objects.each do |object|
3070
- if object.is_a? OpenStudio::Model::AirLoopHVACUnitarySystem
3071
-
3072
- # Fan Airflow
3073
- if object.coolingCoil.is_initialized && object.heatingCoil.is_initialized
3074
- fan_airflow = [hvac_final_values.Heat_Airflow, hvac_final_values.Cool_Airflow].max
3075
- elsif object.coolingCoil.is_initialized
3076
- fan_airflow = hvac_final_values.Cool_Airflow
3077
- elsif object.heatingCoil.is_initialized
3078
- fan_airflow = hvac_final_values.Heat_Airflow
3079
- end
3080
- end
3081
-
3082
- if object.is_a?(OpenStudio::Model::AirLoopHVACUnitarySystem) && object.airLoopHVAC.is_initialized
3083
-
3084
- ## Air Loop HVAC Unitary System ##
3085
-
3086
- # Unitary System
3087
- object.setSupplyAirFlowRateMethodDuringCoolingOperation('SupplyAirFlowRate')
3088
- if object.coolingCoil.is_initialized
3089
- object.setSupplyAirFlowRateDuringCoolingOperation(UnitConversions.convert(hvac_final_values.Cool_Airflow, 'cfm', 'm^3/s'))
3090
- else
3091
- object.setSupplyAirFlowRateDuringCoolingOperation(0.0)
3092
- end
3093
- object.setSupplyAirFlowRateMethodDuringHeatingOperation('SupplyAirFlowRate')
3094
- if object.heatingCoil.is_initialized
3095
- object.setSupplyAirFlowRateDuringHeatingOperation(UnitConversions.convert(hvac_final_values.Heat_Airflow, 'cfm', 'm^3/s'))
3096
- else
3097
- object.setSupplyAirFlowRateDuringHeatingOperation(0.0)
3098
- end
3099
-
3100
- # Fan
3101
- fanonoff = object.supplyFan.get.to_FanOnOff.get
3102
- fanonoff.setMaximumFlowRate(hvac.FanspeedRatioCooling.max * UnitConversions.convert(fan_airflow + 0.01, 'cfm', 'm^3/s'))
3103
-
3104
- # Air Loop
3105
- air_loop = object.airLoopHVAC.get
3106
- air_loop.setDesignSupplyAirFlowRate(hvac.FanspeedRatioCooling.max * UnitConversions.convert(fan_airflow, 'cfm', 'm^3/s'))
3107
-
3108
- @cond_zone.airLoopHVACTerminals.each do |aterm|
3109
- next if air_loop != aterm.airLoopHVAC.get
3110
- next unless aterm.to_AirTerminalSingleDuctUncontrolled.is_initialized
3111
-
3112
- # Air Terminal
3113
- aterm = aterm.to_AirTerminalSingleDuctUncontrolled.get
3114
- aterm.setMaximumAirFlowRate(UnitConversions.convert(fan_airflow, 'cfm', 'm^3/s'))
3115
- end
3116
-
3117
- # Coils
3118
- setCoilsObjectValues(model, hvac, object, hvac_final_values)
3119
-
3120
- if hvac.has_type(Constants.ObjectNameGroundSourceHeatPump)
3121
-
3122
- clg_coil, htg_coil, supp_htg_coil = HVAC.get_coils_from_hvac_equip(model, object)
3123
-
3124
- if not htg_coil.nil?
3125
- plant_loop = htg_coil.plantLoop.get
3126
- elsif not clg_coil.nil?
3127
- plant_loop = clg_coil.plantLoop.get
3128
- end
3129
-
3130
- # Plant Loop
3131
- plant_loop.setMaximumLoopFlowRate(UnitConversions.convert(hvac_final_values.GSHP_Loop_flow, 'gal/min', 'm^3/s'))
3132
-
3133
- # Ground Heat Exchanger Vertical
3134
- hvac.GSHP_HXVertical.setDesignFlowRate(UnitConversions.convert(hvac_final_values.GSHP_Loop_flow, 'gal/min', 'm^3/s'))
3135
- hvac.GSHP_HXVertical.setNumberofBoreHoles(hvac_final_values.GSHP_Bore_Holes.to_i)
3136
- hvac.GSHP_HXVertical.setBoreHoleLength(UnitConversions.convert(hvac_final_values.GSHP_Bore_Depth, 'ft', 'm'))
3137
- hvac.GSHP_HXVertical.removeAllGFunctions
3138
- for i in 0..(hvac_final_values.GSHP_G_Functions[0].size - 1)
3139
- hvac.GSHP_HXVertical.addGFunction(hvac_final_values.GSHP_G_Functions[0][i], hvac_final_values.GSHP_G_Functions[1][i])
3140
- end
3141
-
3142
- plant_loop.supplyComponents.each do |plc|
3143
- next unless plc.to_PumpVariableSpeed.is_initialized
3144
-
3145
- # Pump
3146
- pump_w = hvac.GSHP_PumpWattsPerTon * UnitConversions.convert(clg_coil.ratedTotalCoolingCapacity.get, 'W', 'ton')
3147
- pump = plc.to_PumpVariableSpeed.get
3148
- pump.setRatedPowerConsumption(pump_w)
3149
- pump.setRatedFlowRate(HVAC.calc_pump_rated_flow_rate(0.75, pump_w, pump.ratedPumpHead))
3150
- HVAC.set_pump_power_ems_program(model, pump_w, pump, object)
3151
- end
3152
- end
3153
-
3154
- elsif object.is_a? OpenStudio::Model::AirLoopHVACUnitarySystem
3155
-
3156
- ## Zone HVAC Unitary System ##
3157
-
3158
- thermal_zone = object.thermalZone.get
3159
-
3160
- # Unitary System
3161
- object.setSupplyAirFlowRateMethodDuringCoolingOperation('SupplyAirFlowRate')
3162
- if object.coolingCoil.is_initialized
3163
- object.setSupplyAirFlowRateDuringCoolingOperation(UnitConversions.convert(hvac_final_values.Cool_Airflow, 'cfm', 'm^3/s'))
3164
- else
3165
- object.setSupplyAirFlowRateDuringCoolingOperation(0.0)
3166
- end
3167
- object.setSupplyAirFlowRateMethodDuringHeatingOperation('SupplyAirFlowRate')
3168
- if object.heatingCoil.is_initialized
3169
- object.setSupplyAirFlowRateDuringHeatingOperation(UnitConversions.convert(hvac_final_values.Heat_Airflow, 'cfm', 'm^3/s'))
3170
- else
3171
- object.setSupplyAirFlowRateDuringHeatingOperation(0.0)
3172
- end
3173
-
3174
- # Fan
3175
- fanonoff = object.supplyFan.get.to_FanOnOff.get
3176
- fanonoff.setMaximumFlowRate(UnitConversions.convert(fan_airflow + 0.01, 'cfm', 'm^3/s'))
3177
- fan_watts_per_cfm = hvac.FanWatts / fan_airflow
3178
- HVAC.set_fan_power(fanonoff, fan_watts_per_cfm)
3179
-
3180
- # Coils
3181
- setCoilsObjectValues(model, hvac, object, hvac_final_values)
3182
-
3183
- elsif object.is_a? OpenStudio::Model::EvaporativeCoolerDirectResearchSpecial
3184
-
3185
- ## Evaporative Cooler ##
3186
-
3187
- # Air Loop
3188
- vfr = UnitConversions.convert(hvac_final_values.Cool_Airflow, 'cfm', 'm^3/s')
3189
- # evap cooler design flow rate
3190
- object.setPrimaryAirDesignFlowRate(vfr)
3191
- # air loop object design flow rates
3192
- air_loop = object.airLoopHVAC.get
3193
- air_loop.setDesignSupplyAirFlowRate(vfr)
3194
- fan = air_loop.supplyFan.get.to_FanVariableVolume.get
3195
- fan.setMaximumFlowRate(vfr)
3196
- oa_system = air_loop.components.select { |comp| comp.to_AirLoopHVACOutdoorAirSystem.is_initialized }[0].to_AirLoopHVACOutdoorAirSystem.get
3197
- oa_controller = oa_system.getControllerOutdoorAir
3198
- oa_controller.setMaximumOutdoorAirFlowRate(vfr)
3199
-
3200
- # Fan power
3201
- if fan.fanEfficiency == 1 # Not user specified, so default here
3202
- fan_watts_per_cfm = [2.79 * hvac_final_values.Cool_Airflow**-0.29, 0.6].min # fit of efficacy to air flow from the CEC listed equipment W/cfm
3203
- HVAC.set_fan_power(fan, fan_watts_per_cfm)
3204
- end
3205
-
3206
- @cond_zone.airLoopHVACTerminals.each do |aterm|
3207
- next if air_loop != aterm.airLoopHVAC.get
3208
- next unless aterm.to_AirTerminalSingleDuctVAVNoReheat.is_initialized
3209
-
3210
- # Air Terminal
3211
- aterm = aterm.to_AirTerminalSingleDuctVAVNoReheat.get
3212
- aterm.setMaximumAirFlowRate(vfr)
3213
- end
3214
-
3215
- elsif object.is_a?(OpenStudio::Model::ZoneHVACBaseboardConvectiveWater) || object.is_a?(OpenStudio::Model::ZoneHVACFourPipeFanCoil)
3216
-
3217
- ## Hot Water Boiler ##
3218
-
3219
- plant_loop = object.heatingCoil.plantLoop.get
3220
-
3221
- max_water_flow = UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'W') / UnitConversions.convert(20.0, 'R', 'K') / 4.186 / 998.2 / 1000.0 * 2.0
3222
- bb_UA = UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'W') / UnitConversions.convert(hvac.BoilerDesignTemp - 10.0 - 95.0, 'R', 'K') * 3.0
3223
- if object.is_a? OpenStudio::Model::ZoneHVACBaseboardConvectiveWater
3224
- # Baseboard Coil
3225
- coil = object.heatingCoil.to_CoilHeatingWaterBaseboard.get
3226
- coil.setUFactorTimesAreaValue(bb_UA)
3227
- coil.setMaximumWaterFlowRate(max_water_flow)
3228
- coil.setHeatingDesignCapacityMethod('HeatingDesignCapacity')
3229
- elsif object.is_a? OpenStudio::Model::ZoneHVACFourPipeFanCoil
3230
- coil = object.heatingCoil.to_CoilHeatingWater.get
3231
- coil.setRatedCapacity(UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'W'))
3232
- coil.setUFactorTimesAreaValue(bb_UA)
3233
- coil.setMaximumWaterFlowRate(max_water_flow)
3234
- coil.setPerformanceInputMethod('NominalCapacity')
3235
-
3236
- max_air_flow = UnitConversions.convert(400.0 * UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'ton'), 'cfm', 'm^3/s') # Assumes 400 cfm/ton
3237
- object.setMaximumSupplyAirFlowRate(max_air_flow)
3238
- object.setMaximumHotWaterFlowRate(max_water_flow)
3239
- object.supplyAirFan.to_FanOnOff.get.setMaximumFlowRate(max_air_flow)
3240
- end
3241
-
3242
- plant_loop.components.each do |component|
3243
- # Boiler
3244
- if component.to_BoilerHotWater.is_initialized
3245
- boiler = component.to_BoilerHotWater.get
3246
- boiler.setNominalCapacity(UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'W'))
3247
- end
3248
- end
3249
-
3250
- elsif object.is_a? OpenStudio::Model::ZoneHVACBaseboardConvectiveElectric
3251
-
3252
- ## Electric Baseboard ##
3253
-
3254
- thermal_zone = object.thermalZone.get
3255
-
3256
- # Baseboard
3257
- object.setNominalCapacity(UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'W'))
3258
-
3259
- elsif object.is_a? OpenStudio::Model::ZoneHVACPackagedTerminalAirConditioner
3260
-
3261
- ## Window AC ##
3262
-
3263
- thermal_zone = object.thermalZone.get
3264
-
3265
- # PTAC
3266
- object.setSupplyAirFlowRateDuringCoolingOperation(UnitConversions.convert(hvac_final_values.Cool_Airflow, 'cfm', 'm^3/s'))
3267
- object.setSupplyAirFlowRateDuringHeatingOperation(0.00001)
3268
- object.setSupplyAirFlowRateWhenNoCoolingorHeatingisNeeded(0.0)
3269
- object.setOutdoorAirFlowRateDuringCoolingOperation(0.0)
3270
- object.setOutdoorAirFlowRateDuringHeatingOperation(0.0)
3271
- object.setOutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded(0.0)
3272
-
3273
- # Fan
3274
- fanonoff = object.supplyAirFan.to_FanOnOff.get
3275
- fanonoff.setMaximumFlowRate(UnitConversions.convert(hvac_final_values.Cool_Airflow, 'cfm', 'm^3/s'))
3276
-
3277
- # Coils
3278
- setCoilsObjectValues(model, hvac, object, hvac_final_values)
3279
-
3280
- # Heating Coil override
3281
- ptac_htg_coil = object.heatingCoil.to_CoilHeatingElectric.get
3282
- ptac_htg_coil.setNominalCapacity(0.0)
3283
-
3284
- else
3285
- fail "Unexpected object type: #{object.class}."
3286
-
3287
- end # object type
3288
- end # hvac Object
3289
- end
3290
-
3291
- def self.setCoilsObjectValues(model, hvac, equip, hvac_final_values)
3292
- clg_coil, htg_coil, supp_htg_coil = HVAC.get_coils_from_hvac_equip(model, equip)
3293
-
3294
- # Cooling coil
3295
- if clg_coil.is_a? OpenStudio::Model::CoilCoolingDXSingleSpeed
3296
- clg_coil.setRatedTotalCoolingCapacity(UnitConversions.convert(hvac_final_values.Cool_Capacity, 'Btu/hr', 'W'))
3297
- clg_coil.setRatedAirFlowRate(UnitConversions.convert(hvac_final_values.Cool_Capacity, 'Btu/hr', 'ton') * UnitConversions.convert(hvac.RatedCFMperTonCooling[0], 'cfm', 'm^3/s'))
3298
- elsif clg_coil.is_a? OpenStudio::Model::CoilCoolingDXMultiSpeed
3299
- clg_coil.stages.each_with_index do |stage, speed|
3300
- stage.setGrossRatedTotalCoolingCapacity(UnitConversions.convert(hvac_final_values.Cool_Capacity, 'Btu/hr', 'W') * hvac.CapacityRatioCooling[speed])
3301
- if clg_coil.name.to_s.start_with?(Constants.ObjectNameAirSourceHeatPump) || clg_coil.name.to_s.start_with?(Constants.ObjectNameCentralAirConditioner)
3302
- stage.setRatedAirFlowRate(UnitConversions.convert(hvac_final_values.Cool_Capacity, 'Btu/hr', 'ton') * UnitConversions.convert(hvac.RatedCFMperTonCooling[speed], 'cfm', 'm^3/s') * hvac.CapacityRatioCooling[speed])
3303
- elsif clg_coil.name.to_s.start_with? Constants.ObjectNameMiniSplitHeatPump
3304
- stage.setRatedAirFlowRate(UnitConversions.convert(hvac_final_values.Cool_Capacity, 'Btu/hr', 'ton') * UnitConversions.convert(hvac.RatedCFMperTonCooling[speed], 'cfm', 'm^3/s'))
3305
- end
3306
- end
3307
-
3308
- elsif clg_coil.is_a? OpenStudio::Model::CoilCoolingWaterToAirHeatPumpEquationFit
3309
- clg_coil.setRatedAirFlowRate(UnitConversions.convert(hvac_final_values.Cool_Airflow, 'cfm', 'm^3/s'))
3310
- clg_coil.setRatedWaterFlowRate(UnitConversions.convert(hvac_final_values.GSHP_Loop_flow, 'gal/min', 'm^3/s'))
3311
- clg_coil.setRatedTotalCoolingCapacity(UnitConversions.convert(hvac_final_values.Cool_Capacity, 'Btu/hr', 'W'))
3312
- clg_coil.setRatedSensibleCoolingCapacity(UnitConversions.convert(hvac_final_values.Cool_Capacity_Sens, 'Btu/hr', 'W'))
3313
-
3314
- end
3315
-
3316
- # Heating coil
3317
- if htg_coil.is_a? OpenStudio::Model::CoilHeatingElectric
3318
- if not equip.is_a? OpenStudio::Model::ZoneHVACPackagedTerminalAirConditioner
3319
- htg_coil.setNominalCapacity(UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'W'))
3320
- end
3321
-
3322
- elsif htg_coil.is_a? OpenStudio::Model::CoilHeatingGas
3323
- htg_coil.setNominalCapacity(UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'W'))
3324
-
3325
- elsif htg_coil.is_a? OpenStudio::Model::CoilHeatingDXSingleSpeed
3326
- htg_coil.setRatedTotalHeatingCapacity(UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'W'))
3327
- if htg_coil.name.to_s.start_with? Constants.ObjectNameWaterLoopHeatPump
3328
- htg_coil.setRatedAirFlowRate(UnitConversions.convert(hvac_final_values.Heat_Airflow, 'cfm', 'm^3/s'))
3329
- else
3330
- htg_coil.setRatedAirFlowRate(UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'ton') * UnitConversions.convert(hvac.RatedCFMperTonHeating[0], 'cfm', 'm^3/s'))
3331
- end
3332
-
3333
- elsif htg_coil.is_a? OpenStudio::Model::CoilHeatingDXMultiSpeed
3334
- htg_coil.stages.each_with_index do |stage, speed|
3335
- stage.setGrossRatedHeatingCapacity(UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'W') * hvac.CapacityRatioHeating[speed])
3336
- if htg_coil.name.to_s.start_with? Constants.ObjectNameAirSourceHeatPump
3337
- stage.setRatedAirFlowRate(UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'ton') * UnitConversions.convert(hvac.RatedCFMperTonHeating[speed], 'cfm', 'm^3/s') * hvac.CapacityRatioHeating[speed])
3338
- elsif htg_coil.name.to_s.start_with? Constants.ObjectNameMiniSplitHeatPump
3339
- stage.setRatedAirFlowRate(UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'ton') * UnitConversions.convert(hvac.RatedCFMperTonHeating[speed], 'cfm', 'm^3/s'))
3340
- end
3341
- end
3342
-
3343
- elsif htg_coil.is_a? OpenStudio::Model::CoilHeatingWaterToAirHeatPumpEquationFit
3344
- htg_coil.setRatedAirFlowRate(UnitConversions.convert(hvac_final_values.Heat_Airflow, 'cfm', 'm^3/s'))
3345
- htg_coil.setRatedWaterFlowRate(UnitConversions.convert(hvac_final_values.GSHP_Loop_flow, 'gal/min', 'm^3/s'))
3346
- htg_coil.setRatedHeatingCapacity(UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'W'))
3347
-
3348
- end
3349
-
3350
- # Supplemental heating coil
3351
- if supp_htg_coil.is_a?(OpenStudio::Model::CoilHeatingElectric) || supp_htg_coil.is_a?(OpenStudio::Model::CoilHeatingGas)
3352
- supp_htg_coil.setNominalCapacity(UnitConversions.convert(hvac_final_values.Heat_Capacity_Supp, 'Btu/hr', 'W'))
3353
- end
3354
- end
3355
-
3356
- def self.display_zone_loads(zone_loads)
3357
- s = "Zone Loads for #{@cond_zone.name}:"
3358
- properties = [
3359
- :Heat_Windows, :Heat_Skylights,
3360
- :Heat_Doors, :Heat_Walls,
3361
- :Heat_Roofs, :Heat_Floors,
3362
- :Heat_Infil,
3363
- :Cool_Windows, :Cool_Skylights,
3364
- :Cool_Doors, :Cool_Walls,
3365
- :Cool_Roofs, :Cool_Floors,
3366
- :Cool_Infil_Sens, :Cool_Infil_Lat,
3367
- :Cool_IntGains_Sens, :Cool_IntGains_Lat,
3368
- ]
3369
- properties.each do |property|
3370
- s += "\n#{property.to_s.gsub('_', ' ')} = #{zone_loads.send(property).round(0)} Btu/hr"
3371
- end
3372
- @runner.registerInfo("#{s}\n")
3373
- end
3374
-
3375
- def self.display_hvac_final_values_results(hvac_final_values, hvac)
3376
- s = "Final Results for #{hvac.Objects[0].name}:"
3377
- loads = [
3378
- :Heat_Load, :Heat_Load_Ducts,
3379
- :Cool_Load_Lat, :Cool_Load_Sens,
3380
- :Cool_Load_Ducts_Lat, :Cool_Load_Ducts_Sens,
3381
- ]
3382
- caps = [
3383
- :Cool_Capacity, :Cool_Capacity_Sens,
3384
- :Heat_Capacity, :Heat_Capacity_Supp,
3385
- ]
3386
- airflows = [
3387
- :Cool_Airflow, :Heat_Airflow,
3388
- ]
3389
- loads.each do |load|
3390
- s += "\n#{load.to_s.gsub('_', ' ')} = #{hvac_final_values.send(load).round(0)} Btu/hr"
3391
- end
3392
- caps.each do |cap|
3393
- s += "\n#{cap.to_s.gsub('_', ' ')} = #{hvac_final_values.send(cap).round(0)} Btu/hr"
3394
- end
3395
- airflows.each do |airflow|
3396
- s += "\n#{airflow.to_s.gsub('_', ' ')} = #{hvac_final_values.send(airflow).round(0)} cfm"
3397
- end
3398
- @runner.registerInfo("#{s}\n")
3399
- end
3400
3342
  end
3401
3343
 
3402
- class ZoneLoads
3403
- # Thermal zone loads
3344
+ class DesignLoads
3404
3345
  def initialize
3405
3346
  end
3406
- attr_accessor(:Cool_Windows, :Cool_Skylights, :Cool_Doors, :Cool_Walls, :Cool_Roofs, :Cool_Floors,
3407
- :Cool_Infil_Sens, :Cool_Infil_Lat, :Cool_IntGains_Sens, :Cool_IntGains_Lat,
3347
+ attr_accessor(:Cool_Sens, :Cool_Lat, :Cool_Tot, :Heat_Tot, :Heat_Ducts, :Cool_Ducts_Sens, :Cool_Ducts_Lat,
3348
+ :Cool_Windows, :Cool_Skylights, :Cool_Doors, :Cool_Walls, :Cool_Roofs, :Cool_Floors,
3349
+ :Cool_Ceilings, :Cool_Infil_Sens, :Cool_Infil_Lat, :Cool_IntGains_Sens, :Cool_IntGains_Lat,
3408
3350
  :Heat_Windows, :Heat_Skylights, :Heat_Doors, :Heat_Walls, :Heat_Roofs, :Heat_Floors,
3409
- :Heat_Infil)
3410
- end
3411
-
3412
- class InitialLoads
3413
- # Initial loads (aggregated across thermal zones and excluding ducts)
3414
- def initialize
3415
- end
3416
- attr_accessor(:Cool_Sens, :Cool_Lat, :Cool_Tot, :Heat)
3351
+ :Heat_Slabs, :Heat_Ceilings, :Heat_InfilVent)
3417
3352
  end
3418
3353
 
3419
- class FinalValues
3420
- # Final loads (including ducts), airflow rates, equipment capacities, etc.
3354
+ class HVACSizingValues
3421
3355
  def initialize
3422
3356
  end
3423
3357
  attr_accessor(:Cool_Load_Sens, :Cool_Load_Lat, :Cool_Load_Tot,
3424
- :Cool_Load_Ducts_Sens, :Cool_Load_Ducts_Lat, :Cool_Load_Ducts_Tot,
3425
3358
  :Cool_Capacity, :Cool_Capacity_Sens, :Cool_Airflow,
3426
- :Heat_Load, :Heat_Load_Ducts,
3427
- :Heat_Capacity, :Heat_Capacity_Supp, :Heat_Airflow,
3359
+ :Heat_Load, :Heat_Capacity, :Heat_Capacity_Supp, :Heat_Airflow,
3428
3360
  :GSHP_Loop_flow, :GSHP_Bore_Holes, :GSHP_Bore_Depth, :GSHP_G_Functions)
3429
3361
  end
3430
3362
 
@@ -3439,37 +3371,29 @@ class HVACInfo
3439
3371
  self.CapacityRatioHeating = [1.0]
3440
3372
  self.OverSizeLimit = 1.15
3441
3373
  self.OverSizeDelta = 15000.0
3442
- self.FanspeedRatioCooling = [1.0]
3443
3374
  self.Ducts = []
3375
+ self.AirflowDefectRatioCooling = 0.0
3376
+ self.AirflowDefectRatioHeating = 0.0
3444
3377
  end
3445
3378
 
3446
- def has_type(name_or_names)
3447
- if not name_or_names.is_a? Array
3448
- name_or_names = [name_or_names]
3449
- end
3450
- name_or_names.each do |name|
3451
- next unless (self.HeatType == name) || (self.CoolType == name)
3452
-
3453
- return true
3454
- end
3455
- return false
3456
- end
3457
-
3458
- attr_accessor(:HeatType, :CoolType, :Handle, :Objects, :Ducts, :NumSpeedsCooling, :NumSpeedsHeating,
3379
+ attr_accessor(:HeatType, :CoolType, :Ducts, :NumSpeedsCooling, :NumSpeedsHeating,
3459
3380
  :FixedCoolingCapacity, :FixedHeatingCapacity, :FixedSuppHeatingCapacity,
3460
- :RatedCFMperTonCooling, :RatedCFMperTonHeating,
3461
- :COOL_CAP_FT_SPEC, :HEAT_CAP_FT_SPEC, :COOL_SH_FT_SPEC, :COIL_BF_FT_SPEC,
3462
- :SHRRated, :CapacityRatioCooling, :CapacityRatioHeating, :FanWatts,
3463
- :HeatingCapacityOffset, :OverSizeLimit, :OverSizeDelta, :FanspeedRatioCooling,
3464
- :BoilerDesignTemp, :CoilBF, :HeatingEIR, :CoolingEIR, :SizingSpeed,
3465
- :GSHP_PumpWattsPerTon, :GSHP_HXVertical, :GSHP_HXDTDesign, :GSHP_HXCHWDesign, :GSHP_HXHWDesign,
3466
- :GSHP_BoreSpacing, :GSHP_BoreHoles, :GSHP_BoreDepth, :GSHP_BoreConfig, :GSHP_SpacingType,
3381
+ :AirflowDefectRatioCooling, :AirflowDefectRatioHeating,
3382
+ :RatedCFMperTonCooling, :RatedCFMperTonHeating, :ChargeDefectRatio,
3383
+ :COOL_CAP_FT_SPEC, :HEAT_CAP_FT_SPEC, :COOL_SH_FT_SPEC,
3384
+ :COOL_CAP_FFLOW_SPEC, :HEAT_CAP_FFLOW_SPEC,
3385
+ :SHRRated, :CapacityRatioCooling, :CapacityRatioHeating,
3386
+ :OverSizeLimit, :OverSizeDelta,
3387
+ :HeatingEIR, :CoolingEIR, :SizingSpeed, :HeatingCOP,
3388
+ :GSHP_SpacingType, :EvapCoolerEffectiveness,
3467
3389
  :HeatingLoadFraction, :CoolingLoadFraction, :SupplyAirTemp, :LeavingAirTemp,
3468
- :EvapCoolerEffectiveness)
3390
+ :GSHP_design_chw, :GSHP_design_delta_t, :GSHP_design_hw, :GSHP_bore_d,
3391
+ :GSHP_pipe_od, :GSHP_pipe_id, :GSHP_pipe_cond, :GSHP_ground_k, :GSHP_grout_k)
3469
3392
  end
3470
3393
 
3471
3394
  class DuctInfo
3472
3395
  # Model info for a duct
3396
+ # FUTURE: Remove class; use either airflow.rb Duct class or HPXML Ducts class directly
3473
3397
  def initial
3474
3398
  end
3475
3399
  attr_accessor(:LeakageFrac, :LeakageCFM25, :Area, :Rvalue, :Location, :Side)