urbanopt-cli 0.5.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (907) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +2 -2
  3. data/CHANGELOG.md +43 -1
  4. data/CMakeLists.txt +14 -14
  5. data/FindOpenStudioSDK.cmake +11 -6
  6. data/Gemfile +11 -5
  7. data/LICENSE.md +11 -1
  8. data/Rakefile +16 -6
  9. data/example_files/Gemfile +8 -8
  10. data/example_files/example_project_combined.json +100 -5
  11. data/example_files/example_project_with_streets.json +826 -0
  12. data/example_files/mappers/Baseline.rb +107 -59
  13. data/example_files/mappers/CreateBar.rb +17 -7
  14. data/example_files/mappers/EvCharging.rb +20 -10
  15. data/example_files/mappers/Floorspace.rb +17 -7
  16. data/example_files/mappers/HighEfficiency.rb +20 -8
  17. data/example_files/mappers/HighEfficiencyCreateBar.rb +19 -8
  18. data/example_files/mappers/HighEfficiencyFloorspace.rb +19 -8
  19. data/example_files/mappers/ThermalStorage.rb +16 -6
  20. data/example_files/measures/BuildResidentialModel/measure.rb +249 -134
  21. data/example_files/reopt/base_assumptions.json +2 -2
  22. data/example_files/reopt/multiPV_assumptions.json +4 -3
  23. data/example_files/residential/clothes_dryer.tsv +7 -7
  24. data/example_files/residential/clothes_washer.tsv +1 -1
  25. data/example_files/residential/cooling_system.tsv +42 -22
  26. data/example_files/residential/dishwasher.tsv +1 -1
  27. data/example_files/residential/exhaust.tsv +3 -0
  28. data/example_files/residential/heat_pump.tsv +62 -40
  29. data/example_files/resources/hpxml-measures/.github/pull_request_template.md +2 -1
  30. data/example_files/resources/hpxml-measures/.github/workflows/config.yml +116 -0
  31. data/example_files/resources/hpxml-measures/.gitignore +1 -8
  32. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.rb +746 -1236
  33. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.xml +1550 -1215
  34. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/constants.rb +0 -8
  35. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb +432 -343
  36. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules.rb +134 -91
  37. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_config.json +388 -0
  38. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_config.md +43 -0
  39. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_weekday_state_and_monthly_schedule_shift.csv +613 -0
  40. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_weekend_state_and_monthly_schedule_shift.csv +613 -0
  41. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-coal.osw +36 -60
  42. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-dehumidifier-ief-portable.osw +35 -59
  43. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-dehumidifier-ief-whole-home.osw +35 -59
  44. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-dehumidifier.osw +35 -59
  45. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-gas.osw +36 -60
  46. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-modified.osw +36 -60
  47. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-none.osw +41 -65
  48. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-oil.osw +36 -60
  49. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-propane.osw +36 -60
  50. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-wood.osw +36 -60
  51. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-flat.osw +36 -60
  52. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-radiant-barrier.osw +36 -60
  53. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-unvented-insulated-roof.osw +36 -60
  54. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-vented.osw +36 -60
  55. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-boiler-only-baseboard.osw +341 -0
  56. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-boiler-only-fan-coil.osw +341 -0
  57. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-mechvent-preconditioning.osw +39 -63
  58. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-mechvent.osw +39 -63
  59. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-pv.osw +39 -63
  60. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-water-heater.osw +39 -63
  61. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily.osw +39 -63
  62. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-single-family-attached.osw +36 -60
  63. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-combi-tankless-outside.osw +36 -61
  64. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-combi-tankless.osw +36 -61
  65. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-dwhr.osw +36 -60
  66. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect-outside.osw +36 -61
  67. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect-standbyloss.osw +36 -61
  68. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect-with-solar-fraction.osw +36 -61
  69. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect.osw +36 -61
  70. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-electric.osw +36 -60
  71. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-gas.osw +36 -60
  72. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-hpwh.osw +36 -60
  73. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-indirect.osw +36 -61
  74. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-low-flow-fixtures.osw +36 -60
  75. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-none.osw +37 -61
  76. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-demand.osw +36 -60
  77. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-manual.osw +36 -60
  78. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-nocontrol.osw +36 -60
  79. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-temperature.osw +36 -60
  80. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-timer.osw +36 -60
  81. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-direct-evacuated-tube.osw +36 -60
  82. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-direct-flat-plate.osw +36 -60
  83. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-direct-ics.osw +36 -60
  84. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-fraction.osw +36 -60
  85. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-indirect-flat-plate.osw +36 -60
  86. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-thermosyphon-flat-plate.osw +36 -60
  87. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-coal.osw +36 -60
  88. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-elec-uef.osw +36 -60
  89. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-gas-outside.osw +36 -60
  90. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-gas-uef.osw +36 -60
  91. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-gas.osw +36 -60
  92. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-outside.osw +36 -60
  93. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-uef.osw +36 -60
  94. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-with-solar-fraction.osw +36 -60
  95. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-with-solar.osw +36 -60
  96. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump.osw +36 -60
  97. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-oil.osw +36 -60
  98. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-wood.osw +36 -60
  99. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-electric-outside.osw +36 -60
  100. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-electric-uef.osw +36 -60
  101. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-electric.osw +36 -60
  102. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas-uef.osw +36 -60
  103. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas-with-solar-fraction.osw +36 -60
  104. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas-with-solar.osw +36 -60
  105. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas.osw +36 -60
  106. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-propane.osw +36 -60
  107. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-2stories-garage.osw +36 -60
  108. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-2stories.osw +36 -60
  109. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-1.osw +36 -60
  110. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-2.osw +36 -60
  111. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-4.osw +36 -60
  112. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-5.osw +36 -60
  113. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-garage.osw +36 -60
  114. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-ach-house-pressure.osw +36 -60
  115. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-cfm-house-pressure.osw +36 -60
  116. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-cfm50.osw +36 -60
  117. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-flue.osw +36 -60
  118. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-natural-ach.osw +37 -61
  119. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-overhangs.osw +37 -61
  120. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-windows-none.osw +36 -60
  121. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-ambient.osw +36 -60
  122. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-conditioned-basement-slab-insulation.osw +36 -60
  123. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-slab.osw +36 -60
  124. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unconditioned-basement-assembly-r.osw +35 -59
  125. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unconditioned-basement-wall-insulation.osw +35 -59
  126. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unconditioned-basement.osw +35 -59
  127. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unvented-crawlspace.osw +35 -59
  128. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-vented-crawlspace.osw +35 -59
  129. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-1-speed-cooling-only.osw +337 -0
  130. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-1-speed-heating-only.osw +337 -0
  131. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-1-speed.osw +36 -61
  132. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-2-speed.osw +36 -60
  133. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-var-speed.osw +36 -60
  134. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-coal-only.osw +36 -60
  135. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-elec-only.osw +36 -60
  136. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-gas-central-ac-1-speed.osw +36 -61
  137. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-gas-only.osw +36 -61
  138. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-oil-only.osw +36 -60
  139. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-propane-only.osw +36 -60
  140. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-wood-only.osw +36 -60
  141. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-only-1-speed.osw +36 -61
  142. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-only-2-speed.osw +36 -60
  143. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-only-var-speed.osw +36 -60
  144. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.osw +36 -62
  145. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-electric.osw +35 -60
  146. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.osw +35 -60
  147. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.osw +35 -59
  148. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.osw +35 -59
  149. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-mini-split-heat-pump-ducted.osw +36 -61
  150. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ducts-leakage-percent.osw +36 -60
  151. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-elec-resistance-only.osw +36 -60
  152. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-evap-cooler-furnace-gas.osw +36 -60
  153. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-evap-cooler-only-ducted.osw +37 -61
  154. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-evap-cooler-only.osw +36 -61
  155. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-fireplace-wood-only.osw +36 -61
  156. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-fixed-heater-gas-only.osw +37 -62
  157. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-floor-furnace-propane-only.osw +36 -61
  158. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-coal-only.osw +337 -0
  159. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-elec-central-ac-1-speed.osw +36 -60
  160. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-elec-only.osw +36 -60
  161. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-central-ac-2-speed.osw +36 -60
  162. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-central-ac-var-speed.osw +36 -60
  163. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-only.osw +36 -61
  164. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-room-ac.osw +36 -60
  165. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-oil-only.osw +36 -60
  166. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-propane-only.osw +36 -60
  167. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-wood-only.osw +36 -60
  168. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ground-to-air-heat-pump-cooling-only.osw +336 -0
  169. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ground-to-air-heat-pump-heating-only.osw +336 -0
  170. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ground-to-air-heat-pump.osw +36 -62
  171. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-plug-loads-additional-multipliers.osw → base-hvac-install-quality-airflow-defect-furnace-gas-central-ac-1-speed.osw} +41 -63
  172. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-air-to-air-heat-pump-1-speed.osw +339 -0
  173. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-air-to-air-heat-pump-2-speed.osw +339 -0
  174. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-air-to-air-heat-pump-var-speed.osw +339 -0
  175. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-central-ac-1-speed.osw +340 -0
  176. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-central-ac-2-speed.osw +340 -0
  177. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-central-ac-var-speed.osw +340 -0
  178. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-only.osw +338 -0
  179. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-ground-to-air-heat-pump.osw +338 -0
  180. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-mini-split-air-conditioner-only-ducted.osw +338 -0
  181. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-mini-split-heat-pump-ducted.osw +339 -0
  182. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-charge-defect-furnace-gas-central-ac-1-speed.osw +338 -0
  183. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-none-furnace-gas-central-ac-1-speed.osw +340 -0
  184. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-air-conditioner-only-ducted.osw +36 -61
  185. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-air-conditioner-only-ductless.osw +36 -61
  186. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ducted-cooling-only.osw +36 -61
  187. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ducted-heating-only.osw +36 -61
  188. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ducted.osw +37 -62
  189. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ductless.osw +37 -62
  190. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-none.osw +36 -60
  191. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-portable-heater-gas-only.osw +37 -62
  192. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-programmable-thermostat-detailed.osw +337 -0
  193. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-room-ac-only-33percent.osw +36 -60
  194. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-room-ac-only.osw +36 -60
  195. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-setpoints.osw +36 -60
  196. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-stove-oil-only.osw +36 -61
  197. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-stove-wood-pellets-only.osw +36 -61
  198. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-undersized.osw +36 -60
  199. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-wall-furnace-elec-only.osw +36 -61
  200. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-lighting-ceiling-fans.osw +36 -60
  201. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-lighting-detailed.osw +36 -60
  202. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-AMY-2012.osw +36 -60
  203. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-baltimore-md.osw +45 -69
  204. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-dallas-tx.osw +36 -60
  205. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-duluth-mn.osw +49 -73
  206. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-helena-mt.osw +337 -0
  207. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{base-appliances-dehumidifier-50percent.osw → base-location-honolulu-hi.osw} +39 -63
  208. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-miami-fl.osw +36 -60
  209. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-phoenix-az.osw +337 -0
  210. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-portland-or.osw +337 -0
  211. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-balanced.osw +36 -60
  212. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-bath-kitchen-fans.osw +44 -70
  213. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-cfis-evap-cooler-only-ducted.osw +37 -61
  214. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-cfis.osw +36 -60
  215. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-erv-atre-asre.osw +36 -60
  216. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-erv.osw +36 -60
  217. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-exhaust-rated-flow-rate.osw +337 -0
  218. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-exhaust.osw +36 -60
  219. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-hrv-asre.osw +36 -60
  220. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-hrv.osw +36 -60
  221. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-supply.osw +36 -60
  222. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-whole-house-fan.osw +36 -60
  223. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-defaults.osw +34 -58
  224. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-loads-large-uncommon.osw +34 -58
  225. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-loads-large-uncommon2.osw +34 -58
  226. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-neighbor-shading.osw +36 -60
  227. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-shielding-of-home.osw +337 -0
  228. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-usage-multiplier.osw +35 -59
  229. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-pv.osw +36 -60
  230. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-vacancy-6-months.osw → base-schedules-stochastic-vacant.osw} +39 -63
  231. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-schedules-stochastic.osw +36 -60
  232. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-schedules-user-specified.osw +36 -60
  233. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-calendar-year-custom.osw +36 -60
  234. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-daylight-saving-custom.osw +36 -60
  235. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-daylight-saving-disabled.osw +36 -60
  236. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-runperiod-1-month.osw +36 -60
  237. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-timestep-10-mins.osw +36 -60
  238. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base.osw +36 -60
  239. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/build_residential_hpxml_test.rb +60 -57
  240. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-auto.osw +36 -60
  241. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-double-exterior.osw +341 -0
  242. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-double-loaded-interior.osw +341 -0
  243. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-eaves.osw +341 -0
  244. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-single-exterior-front.osw +341 -0
  245. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-double-loaded-interior.osw +341 -0
  246. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-bottom-double-loaded-interior.osw +341 -0
  247. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-bottom.osw +341 -0
  248. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-middle-double-loaded-interior.osw +341 -0
  249. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-middle.osw +341 -0
  250. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-top-double-loaded-interior.osw +341 -0
  251. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-top.osw +341 -0
  252. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-bottom-double-loaded-interior.osw +341 -0
  253. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-bottom.osw +341 -0
  254. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-middle-double-loaded-interior.osw +341 -0
  255. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-middle.osw +341 -0
  256. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-top-double-loaded-interior.osw +341 -0
  257. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-top.osw +341 -0
  258. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-bottom-double-loaded-interior.osw +341 -0
  259. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-bottom.osw +341 -0
  260. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-middle-double-loaded-interior.osw +341 -0
  261. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-middle.osw +341 -0
  262. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-top-double-loaded-interior.osw +341 -0
  263. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-top.osw +341 -0
  264. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab.osw +341 -0
  265. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-double-loaded-interior.osw +341 -0
  266. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-bottom-double-loaded-interior.osw +341 -0
  267. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-bottom.osw +341 -0
  268. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-middle-double-loaded-interior.osw +341 -0
  269. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-middle.osw +341 -0
  270. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-top-double-loaded-interior.osw +341 -0
  271. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-top.osw +341 -0
  272. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-bottom-double-loaded-interior.osw +341 -0
  273. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-bottom.osw +341 -0
  274. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-middle-double-loaded-interior.osw +341 -0
  275. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-middle.osw +341 -0
  276. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-top-double-loaded-interior.osw +341 -0
  277. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-top.osw +341 -0
  278. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-bottom-double-loaded-interior.osw +341 -0
  279. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-bottom.osw +341 -0
  280. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-middle-double-loaded-interior.osw +341 -0
  281. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-middle.osw +341 -0
  282. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-top-double-loaded-interior.osw +341 -0
  283. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-top.osw +341 -0
  284. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace.osw +341 -0
  285. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-double-loaded-interior.osw +341 -0
  286. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-bottom-double-loaded-interior.osw +341 -0
  287. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-bottom.osw +341 -0
  288. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-middle-double-loaded-interior.osw +341 -0
  289. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-middle.osw +341 -0
  290. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-top-double-loaded-interior.osw +341 -0
  291. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-top.osw +341 -0
  292. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-bottom-double-loaded-interior.osw +341 -0
  293. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-bottom.osw +341 -0
  294. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-middle-double-loaded-interior.osw +341 -0
  295. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-middle.osw +341 -0
  296. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-top-double-loaded-interior.osw +341 -0
  297. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-top.osw +341 -0
  298. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-bottom-double-loaded-interior.osw +341 -0
  299. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-bottom.osw +341 -0
  300. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-middle-double-loaded-interior.osw +341 -0
  301. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-middle.osw +341 -0
  302. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-top-double-loaded-interior.osw +341 -0
  303. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-top.osw +341 -0
  304. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace.osw +341 -0
  305. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-atticroof-conditioned-eaves-gable.osw +339 -0
  306. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-atticroof-conditioned-eaves-hip.osw +339 -0
  307. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-atticroof-flat.osw +339 -0
  308. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-double-exterior.osw +339 -0
  309. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-double-loaded-interior.osw +339 -0
  310. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-single-exterior-front.osw +339 -0
  311. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-slab-middle.osw +339 -0
  312. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-slab-right.osw +339 -0
  313. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-slab.osw +339 -0
  314. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unconditioned-basement-middle.osw +339 -0
  315. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unconditioned-basement-right.osw +339 -0
  316. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unconditioned-basement.osw +339 -0
  317. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unvented-crawlspace-middle.osw +339 -0
  318. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unvented-crawlspace-right.osw +339 -0
  319. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unvented-crawlspace.osw +339 -0
  320. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-vented-crawlspace-middle.osw +339 -0
  321. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-vented-crawlspace-right.osw +339 -0
  322. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-vented-crawlspace.osw +339 -0
  323. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-dhw-solar-latitude.osw +36 -60
  324. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-atticroof-conditioned-eaves-gable.osw +337 -0
  325. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-atticroof-conditioned-eaves-hip.osw +337 -0
  326. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-garage-atticroof-conditioned.osw +337 -0
  327. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-garage-partially-protruded.osw +36 -60
  328. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-windows-shading.osw +339 -0
  329. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-gas-hot-tub-heater-with-zero-kwh.osw +337 -0
  330. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-gas-pool-heater-with-zero-kwh.osw +337 -0
  331. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-pv-roofpitch.osw +36 -60
  332. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-schedules-random-seed.osw +36 -60
  333. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-boiler-to-heat-pump.osw +336 -0
  334. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-boiler-to-heating-system.osw +337 -0
  335. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-fireplace-to-heat-pump.osw +337 -0
  336. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-second-heating-system-fireplace.osw → extra-second-heating-system-fireplace-to-heating-system.osw} +38 -62
  337. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-portable-heater-to-heat-pump.osw +337 -0
  338. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-second-heating-system-portable-heater.osw → extra-second-heating-system-portable-heater-to-heating-system.osw} +36 -60
  339. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-refrigerator.osw +36 -60
  340. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-clothes-washer-kwh.osw +337 -0
  341. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-dishwasher-kwh.osw +337 -0
  342. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-extra-refrigerator-kwh.osw +337 -0
  343. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-freezer-kwh.osw +337 -0
  344. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-refrigerator-kwh.osw +337 -0
  345. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/conditioned-attic-with-floor-insulation.osw +39 -63
  346. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/conditioned-attic-with-one-floor-above-grade.osw +337 -0
  347. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/conditioned-basement-with-ceiling-insulation.osw +36 -60
  348. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/cooling-system-and-heat-pump.osw +36 -60
  349. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/dhw-indirect-without-boiler.osw +36 -60
  350. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/ducts-location-and-areas-not-same-type.osw +36 -60
  351. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/foundation-wall-insulation-greater-than-height.osw +337 -0
  352. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/heating-system-and-heat-pump.osw +36 -60
  353. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multifamily-bottom-crawlspace-zero-foundation-height.osw +39 -63
  354. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multifamily-bottom-slab-non-zero-foundation-height.osw +39 -63
  355. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multifamily-no-building-orientation.osw +38 -62
  356. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-fuel-loads.osw +36 -60
  357. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-other-plug-loads.osw +337 -0
  358. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/{multipliers-without-plug-loads.osw → multipliers-without-tv-plug-loads.osw} +40 -64
  359. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-vehicle-plug-loads.osw +337 -0
  360. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-well-pump-plug-loads.osw +337 -0
  361. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/non-electric-heat-pump-water-heater.osw +36 -60
  362. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/non-integer-ceiling-fan-quantity.osw +36 -60
  363. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/non-integer-geometry-num-bathrooms.osw +36 -60
  364. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/second-heating-system-but-no-primary-heating.osw +337 -0
  365. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/second-heating-system-serves-majority-heat.osw +36 -60
  366. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/second-heating-system-serves-total-heat-load.osw +337 -0
  367. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-attached-ambient.osw +36 -60
  368. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-attached-no-building-orientation.osw +36 -60
  369. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-detached-finished-basement-zero-foundation-height.osw +36 -60
  370. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-detached-slab-non-zero-foundation-height.osw +36 -60
  371. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-detached-with-shared-system.osw +337 -0
  372. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/slab-non-zero-foundation-height-above-grade.osw +36 -60
  373. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/unconditioned-basement-with-wall-and-ceiling-insulation.osw +36 -60
  374. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/unvented-attic-with-floor-and-roof-insulation.osw +36 -60
  375. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/unvented-crawlspace-with-wall-and-ceiling-insulation.osw +36 -60
  376. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/vented-attic-with-floor-and-roof-insulation.osw +38 -62
  377. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/vented-crawlspace-with-wall-and-ceiling-insulation.osw +36 -60
  378. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/zero-number-of-bedrooms.osw +337 -0
  379. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/schedules/vacant.csv +8761 -0
  380. data/example_files/resources/hpxml-measures/Changelog.md +249 -0
  381. data/example_files/resources/hpxml-measures/Gemfile +3 -4
  382. data/example_files/resources/hpxml-measures/Gemfile.lock +27 -32
  383. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb +318 -1283
  384. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml +167 -121
  385. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/BaseElements.xsd +7 -97
  386. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/EPvalidator.xml +600 -203
  387. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/HPXMLDataTypes.xsd +21 -28
  388. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/HPXMLvalidator.xml +114 -22
  389. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb +112 -177
  390. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constants.rb +16 -180
  391. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb +543 -94
  392. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/energyplus.rb +1 -0
  393. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/generator.rb +4 -7
  394. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb +410 -14
  395. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb +27 -25
  396. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb +782 -460
  397. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_defaults.rb +455 -107
  398. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb +1466 -1403
  399. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb +1391 -1467
  400. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb +2 -1
  401. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/location.rb +20 -7
  402. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/meta_measure.rb +85 -13
  403. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/minitest_helper.rb +4 -26
  404. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb +14 -33
  405. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/pv.rb +3 -4
  406. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb +43 -7
  407. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/simcontrols.rb +24 -7
  408. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/unit_conversions.rb +2 -0
  409. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb +2 -2
  410. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb +4 -4
  411. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb +32 -30
  412. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb +6 -29
  413. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_defaults.rb +523 -635
  414. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_enclosure.rb +151 -0
  415. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_generator.rb +3 -1
  416. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb +4 -2
  417. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac.rb +297 -7
  418. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb +0 -1
  419. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb +3 -1
  420. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_location.rb +3 -1
  421. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb +3 -1
  422. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_pv.rb +3 -1
  423. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_simcontrols.rb +3 -1
  424. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb +26 -3
  425. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_water_heater.rb +3 -1
  426. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/util.rb +26 -0
  427. data/example_files/resources/hpxml-measures/README.md +4 -5
  428. data/example_files/resources/hpxml-measures/Rakefile +1 -2
  429. data/example_files/resources/hpxml-measures/SimulationOutputReport/measure.rb +140 -47
  430. data/example_files/resources/hpxml-measures/SimulationOutputReport/measure.xml +351 -495
  431. data/example_files/resources/hpxml-measures/SimulationOutputReport/tests/output_report_test.rb +260 -189
  432. data/example_files/resources/hpxml-measures/docs/source/conf.py +4 -1
  433. data/example_files/resources/hpxml-measures/docs/source/getting_started.rst +3 -3
  434. data/example_files/resources/hpxml-measures/docs/source/intro.rst +4 -105
  435. data/example_files/resources/hpxml-measures/docs/source/workflow_inputs.rst +538 -396
  436. data/example_files/resources/hpxml-measures/docs/source/workflow_outputs.rst +158 -130
  437. data/example_files/resources/hpxml-measures/tasks.rb +1497 -736
  438. data/example_files/resources/hpxml-measures/weather/USA_AZ_Phoenix-Sky.Harbor.Intl.AP.722780_TMY3-cache.csv +35 -0
  439. data/example_files/resources/hpxml-measures/weather/USA_AZ_Phoenix-Sky.Harbor.Intl.AP.722780_TMY3.epw +8768 -0
  440. data/example_files/resources/hpxml-measures/weather/USA_CO_Denver.Intl.AP.725650_TMY3-cache.csv +10 -10
  441. data/example_files/resources/hpxml-measures/weather/USA_HI_Honolulu.Intl.AP.911820_TMY3-cache.csv +35 -0
  442. data/example_files/resources/hpxml-measures/weather/USA_HI_Honolulu.Intl.AP.911820_TMY3.epw +8768 -0
  443. data/example_files/resources/hpxml-measures/weather/USA_MT_Helena.Rgnl.AP.727720_TMY3-cache.csv +35 -0
  444. data/example_files/resources/hpxml-measures/weather/USA_MT_Helena.Rgnl.AP.727720_TMY3.epw +8768 -0
  445. data/example_files/resources/hpxml-measures/weather/USA_OR_Portland.Intl.AP.726980_TMY3-cache.csv +35 -0
  446. data/example_files/resources/hpxml-measures/weather/USA_OR_Portland.Intl.AP.726980_TMY3.epw +8768 -0
  447. data/example_files/resources/hpxml-measures/workflow/run_simulation.rb +36 -5
  448. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-coal.xml +4 -3
  449. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-portable.xml +5 -3
  450. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-whole-home.xml +5 -3
  451. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-multiple.xml +535 -0
  452. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier.xml +5 -3
  453. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-gas.xml +4 -3
  454. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-modified.xml +4 -3
  455. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-none.xml +4 -2
  456. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil.xml +4 -3
  457. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane.xml +4 -3
  458. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-wood.xml +4 -3
  459. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-cathedral.xml +4 -3
  460. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-conditioned.xml +6 -5
  461. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-flat.xml +4 -3
  462. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-radiant-barrier.xml +4 -3
  463. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-unvented-insulated-roof.xml +4 -3
  464. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-vented.xml +4 -3
  465. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multifamily-buffer-space.xml +4 -3
  466. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multiple.xml +4 -3
  467. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-non-freezing-space.xml +4 -3
  468. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-other-heated-space.xml +4 -3
  469. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-other-housing-unit.xml +4 -3
  470. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-baseboard.xml +0 -1
  471. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil-ducted.xml +4 -4
  472. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil.xml +3 -5
  473. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-water-loop-heat-pump.xml +28 -18
  474. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-cooling-tower-water-loop-heat-pump.xml +28 -18
  475. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-baseboard.xml +0 -1
  476. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-ducted.xml +4 -4
  477. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-eae.xml +3 -5
  478. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil.xml +3 -5
  479. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-water-loop-heat-pump.xml +23 -11
  480. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-baseboard.xml +0 -1
  481. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil-ducted.xml +4 -4
  482. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil.xml +3 -5
  483. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-water-loop-heat-pump.xml +23 -12
  484. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-cooling-tower-only-water-loop-heat-pump.xml +23 -12
  485. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-generator.xml +4 -3
  486. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-ground-loop-ground-to-air-heat-pump.xml +6 -6
  487. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-laundry-room.xml +4 -3
  488. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-multiple.xml +8 -5
  489. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-preconditioning.xml +4 -3
  490. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent.xml +4 -3
  491. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-pv.xml +4 -3
  492. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater-recirc.xml +4 -3
  493. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater.xml +4 -3
  494. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily.xml +4 -3
  495. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-single-family-attached.xml +17 -4
  496. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless-outside.xml +1 -2
  497. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless.xml +1 -2
  498. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-2-speed.xml +3 -2
  499. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-gshp.xml +564 -564
  500. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-hpwh.xml +4 -3
  501. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-tankless.xml +3 -5
  502. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-var-speed.xml +3 -2
  503. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater.xml +3 -5
  504. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-dwhr.xml +4 -3
  505. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-dse.xml +1 -2
  506. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-outside.xml +1 -2
  507. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-standbyloss.xml +1 -2
  508. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-with-solar-fraction.xml +1 -2
  509. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect.xml +1 -2
  510. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-electric.xml +4 -3
  511. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-gas.xml +4 -3
  512. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-hpwh.xml +4 -3
  513. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-indirect.xml +1 -2
  514. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-low-flow-fixtures.xml +4 -3
  515. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-multiple.xml +1 -2
  516. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-none.xml +4 -2
  517. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-demand.xml +4 -3
  518. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-manual.xml +4 -3
  519. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-nocontrol.xml +4 -3
  520. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-temperature.xml +4 -3
  521. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-timer.xml +4 -3
  522. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-evacuated-tube.xml +4 -3
  523. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-flat-plate.xml +4 -3
  524. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-ics.xml +4 -3
  525. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-fraction.xml +4 -3
  526. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-indirect-flat-plate.xml +4 -3
  527. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-thermosyphon-flat-plate.xml +4 -3
  528. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-coal.xml +4 -3
  529. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-elec-uef.xml +4 -3
  530. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-outside.xml +4 -3
  531. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef.xml +4 -3
  532. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas.xml +4 -3
  533. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-outside.xml +4 -3
  534. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-uef.xml +4 -3
  535. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar-fraction.xml +4 -3
  536. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar.xml +4 -3
  537. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump.xml +4 -3
  538. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-oil.xml +4 -3
  539. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-wood.xml +4 -3
  540. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-outside.xml +4 -3
  541. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-uef.xml +4 -3
  542. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric.xml +4 -3
  543. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-uef.xml +4 -3
  544. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar-fraction.xml +4 -3
  545. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar.xml +4 -3
  546. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas.xml +4 -3
  547. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-propane.xml +4 -3
  548. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories-garage.xml +5 -4
  549. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories.xml +4 -3
  550. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-1.xml +4 -3
  551. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-2.xml +4 -3
  552. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-4.xml +4 -3
  553. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-5.xml +4 -3
  554. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-garage.xml +4 -3
  555. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-ach-house-pressure.xml +4 -3
  556. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm-house-pressure.xml +4 -3
  557. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm50.xml +4 -3
  558. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-flue.xml +4 -3
  559. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-natural-ach.xml +5 -4
  560. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-overhangs.xml +9 -3
  561. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-rooftypes.xml +4 -3
  562. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-shading.xml +601 -0
  563. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights.xml +6 -5
  564. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-level.xml +4 -3
  565. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces.xml +22 -21
  566. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces2.xml +2475 -0
  567. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-walltypes.xml +4 -3
  568. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-none.xml +4 -3
  569. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-enclosure-windows-interior-shading.xml → base-enclosure-windows-shading.xml} +577 -561
  570. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-ambient.xml +4 -3
  571. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-basement-garage.xml +644 -0
  572. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-complex.xml +4 -3
  573. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-slab-insulation.xml +4 -3
  574. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-wall-interior-insulation.xml +4 -3
  575. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-multiple.xml +6 -5
  576. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-slab.xml +4 -3
  577. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-above-grade.xml +5 -4
  578. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-assembly-r.xml +5 -4
  579. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-wall-insulation.xml +4 -3
  580. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement.xml +5 -4
  581. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unvented-crawlspace.xml +4 -3
  582. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-vented-crawlspace.xml +4 -3
  583. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-walkout-basement.xml +4 -3
  584. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-cooling-only.xml +556 -0
  585. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-heating-only.xml +562 -0
  586. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed.xml +6 -8
  587. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-2-speed.xml +6 -5
  588. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed.xml +6 -5
  589. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-cooling-only.xml +553 -0
  590. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-heating-only.xml +558 -0
  591. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-air-to-air-heat-pump-1-speed-autosize-manual-s-oversize-allowances.xml → base-hvac-autosize-air-to-air-heat-pump-1-speed-manual-s-oversize-allowances.xml} +2 -4
  592. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed.xml +558 -0
  593. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-air-to-air-heat-pump-2-speed-autosize-manual-s-oversize-allowances.xml → base-hvac-autosize-air-to-air-heat-pump-2-speed-manual-s-oversize-allowances.xml} +560 -559
  594. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-air-to-air-heat-pump-2-speed-autosize.xml → base-hvac-autosize-air-to-air-heat-pump-2-speed.xml} +557 -556
  595. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-air-to-air-heat-pump-var-speed-autosize-manual-s-oversize-allowances.xml → base-hvac-autosize-air-to-air-heat-pump-var-speed-manual-s-oversize-allowances.xml} +560 -559
  596. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-air-to-air-heat-pump-var-speed-autosize.xml → base-hvac-autosize-air-to-air-heat-pump-var-speed.xml} +557 -556
  597. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-boiler-elec-only-autosize.xml → base-hvac-autosize-boiler-elec-only.xml} +517 -518
  598. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-boiler-gas-central-ac-1-speed-autosize.xml → base-hvac-autosize-boiler-gas-central-ac-1-speed.xml} +569 -569
  599. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-boiler-gas-only-autosize.xml → base-hvac-autosize-boiler-gas-only.xml} +518 -519
  600. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-central-ac-only-1-speed-autosize.xml → base-hvac-autosize-central-ac-only-1-speed.xml} +2 -4
  601. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-central-ac-only-2-speed-autosize.xml → base-hvac-autosize-central-ac-only-2-speed.xml} +547 -546
  602. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-central-ac-only-var-speed-autosize.xml → base-hvac-autosize-central-ac-only-var-speed.xml} +547 -546
  603. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-central-ac-plus-air-to-air-heat-pump-heating-autosize.xml → base-hvac-autosize-central-ac-plus-air-to-air-heat-pump-heating.xml} +2 -7
  604. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-autosize.xml → base-hvac-autosize-dual-fuel-air-to-air-heat-pump-1-speed.xml} +2 -4
  605. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-dual-fuel-mini-split-heat-pump-ducted-autosize.xml → base-hvac-autosize-dual-fuel-mini-split-heat-pump-ducted.xml} +2 -4
  606. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-elec-resistance-only-autosize.xml → base-hvac-autosize-elec-resistance-only.xml} +508 -509
  607. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-evap-cooler-furnace-gas-autosize.xml → base-hvac-autosize-evap-cooler-furnace-gas.xml} +553 -552
  608. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-floor-furnace-propane-only-autosize.xml → base-hvac-autosize-floor-furnace-propane-only.xml} +511 -512
  609. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-furnace-elec-only-autosize.xml → base-hvac-autosize-furnace-elec-only.xml} +547 -546
  610. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-furnace-gas-central-ac-2-speed-autosize.xml → base-hvac-autosize-furnace-gas-central-ac-2-speed.xml} +560 -559
  611. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-furnace-gas-central-ac-var-speed-autosize.xml → base-hvac-autosize-furnace-gas-central-ac-var-speed.xml} +560 -559
  612. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-only.xml +548 -0
  613. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-furnace-gas-room-ac-autosize.xml → base-hvac-autosize-furnace-gas-room-ac.xml} +558 -557
  614. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-cooling-only.xml +555 -0
  615. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-heating-only.xml +560 -0
  616. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-ground-to-air-heat-pump-autosize-manual-s-oversize-allowances.xml → base-hvac-autosize-ground-to-air-heat-pump-manual-s-oversize-allowances.xml} +562 -562
  617. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-ground-to-air-heat-pump-autosize.xml → base-hvac-autosize-ground-to-air-heat-pump.xml} +559 -559
  618. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-air-conditioner-only-ducted.xml +547 -0
  619. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-mini-split-heat-pump-ducted-cooling-only-autosize.xml → base-hvac-autosize-mini-split-heat-pump-ducted-cooling-only.xml} +2 -4
  620. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-mini-split-heat-pump-ducted-heating-only-autosize.xml → base-hvac-autosize-mini-split-heat-pump-ducted-heating-only.xml} +2 -4
  621. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-mini-split-heat-pump-ducted-autosize-manual-s-oversize-allowances.xml → base-hvac-autosize-mini-split-heat-pump-ducted-manual-s-oversize-allowances.xml} +2 -4
  622. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted.xml +557 -0
  623. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-room-ac-only-autosize.xml → base-hvac-autosize-room-ac-only.xml} +507 -508
  624. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-stove-oil-only-autosize.xml → base-hvac-autosize-stove-oil-only.xml} +511 -512
  625. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-wall-furnace-elec-only-autosize.xml → base-hvac-autosize-wall-furnace-elec-only.xml} +511 -512
  626. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-autosize.xml → base-hvac-autosize.xml} +560 -559
  627. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-coal-only.xml +1 -2
  628. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-elec-only.xml +1 -2
  629. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-central-ac-1-speed.xml +4 -4
  630. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-only.xml +1 -2
  631. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-oil-only.xml +1 -2
  632. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-propane-only.xml +1 -2
  633. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-wood-only.xml +1 -2
  634. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed.xml +3 -5
  635. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-2-speed.xml +3 -2
  636. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-var-speed.xml +3 -2
  637. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.xml +7 -12
  638. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dse.xml +2 -3
  639. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-electric.xml +5 -7
  640. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.xml +5 -7
  641. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.xml +5 -4
  642. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.xml +5 -4
  643. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-mini-split-heat-pump-ducted.xml +5 -7
  644. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-percent.xml +4 -3
  645. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-elec-resistance-only.xml +1 -2
  646. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-furnace-gas.xml +4 -2
  647. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only-ducted.xml +11 -1
  648. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only.xml +1 -4
  649. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fireplace-wood-only.xml +512 -513
  650. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fixed-heater-gas-only.xml +512 -563
  651. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-floor-furnace-propane-only.xml +512 -513
  652. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-coal-only.xml +548 -547
  653. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-central-ac-1-speed.xml +4 -3
  654. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-only.xml +3 -2
  655. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-2-speed.xml +4 -3
  656. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-var-speed.xml +4 -3
  657. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only.xml +548 -550
  658. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-room-ac.xml +4 -3
  659. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-oil-only.xml +3 -2
  660. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-propane-only.xml +3 -2
  661. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-wood-only.xml +3 -2
  662. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-x3-dse.xml +4 -5
  663. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-cooling-only.xml +557 -0
  664. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-heating-only.xml +563 -0
  665. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump.xml +562 -562
  666. data/example_files/resources/hpxml-measures/workflow/sample_files/{invalid_files/slab-zero-exposed-perimeter.xml → base-hvac-install-quality-airflow-defect-furnace-gas-central-ac-1-speed.xml} +568 -561
  667. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-air-to-air-heat-pump-1-speed-autosize.xml → base-hvac-install-quality-all-air-to-air-heat-pump-1-speed.xml} +566 -559
  668. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-air-to-air-heat-pump-2-speed.xml +567 -0
  669. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-air-to-air-heat-pump-var-speed.xml +567 -0
  670. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-misc-shelter-coefficient.xml → base-hvac-install-quality-all-furnace-gas-central-ac-1-speed.xml} +571 -564
  671. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-furnace-gas-central-ac-2-speed.xml +572 -0
  672. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-furnace-gas-central-ac-var-speed.xml +572 -0
  673. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-furnace-gas-only-autosize.xml → base-hvac-install-quality-all-furnace-gas-only.xml} +552 -549
  674. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-ground-to-air-heat-pump.xml +566 -0
  675. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-mini-split-air-conditioner-only-ducted-autosize.xml → base-hvac-install-quality-all-mini-split-air-conditioner-only-ducted.xml} +552 -548
  676. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-mini-split-heat-pump-ducted-autosize.xml → base-hvac-install-quality-all-mini-split-heat-pump-ducted.xml} +565 -558
  677. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-blower-efficiency-furnace-gas-central-ac-1-speed.xml +569 -0
  678. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-charge-defect-furnace-gas-central-ac-1-speed.xml +566 -0
  679. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-none-furnace-gas-central-ac-1-speed.xml +570 -0
  680. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ducted.xml +3 -5
  681. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ductless.xml +1 -5
  682. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-cooling-only.xml +3 -5
  683. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-heating-only.xml +5 -7
  684. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted.xml +6 -8
  685. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless.xml +3 -7
  686. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple.xml +920 -913
  687. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-none.xml +0 -1
  688. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-portable-heater-gas-only.xml +512 -563
  689. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-programmable-thermostat-detailed.xml +7 -6
  690. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-programmable-thermostat.xml +4 -3
  691. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-33percent.xml +1 -2
  692. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only.xml +1 -2
  693. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints.xml +4 -3
  694. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-oil-only.xml +512 -513
  695. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-wood-pellets-only.xml +512 -513
  696. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized-allow-increased-fixed-capacities.xml +4 -3
  697. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized.xml +4 -3
  698. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-wall-furnace-elec-only.xml +512 -513
  699. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-ceiling-fans.xml +4 -3
  700. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-detailed.xml +4 -3
  701. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-none.xml +4 -3
  702. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-AMY-2012.xml +4 -3
  703. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-baltimore-md.xml +37 -25
  704. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-dallas-tx.xml +4 -3
  705. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-duluth-mn.xml +37 -25
  706. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-helena-mt.xml +563 -0
  707. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-honolulu-hi.xml +517 -0
  708. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-miami-fl.xml +4 -3
  709. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-phoenix-az.xml +517 -0
  710. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-portland-or.xml +577 -0
  711. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-balanced.xml +4 -3
  712. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-bath-kitchen-fans.xml +4 -3
  713. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-dse.xml +2 -3
  714. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-evap-cooler-only-ducted.xml +11 -1
  715. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis.xml +4 -3
  716. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv-atre-asre.xml +4 -3
  717. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv.xml +4 -3
  718. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust-rated-flow-rate.xml +4 -3
  719. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust.xml +4 -3
  720. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv-asre.xml +4 -3
  721. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv.xml +4 -3
  722. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-multiple.xml +32 -29
  723. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-supply.xml +4 -3
  724. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-whole-house-fan.xml +4 -3
  725. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-defaults.xml +4 -2
  726. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators.xml +5 -4
  727. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon.xml +8 -3
  728. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon2.xml +12 -3
  729. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-none.xml +4 -3
  730. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-neighbor-shading.xml +4 -3
  731. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-shielding-of-home.xml +564 -0
  732. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-usage-multiplier.xml +8 -3
  733. data/example_files/resources/hpxml-measures/workflow/sample_files/base-multiple-buildings.xml +1657 -0
  734. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv.xml +4 -3
  735. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-stochastic-vacant.xml +564 -0
  736. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-stochastic.xml +4 -3
  737. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-user-specified.xml +4 -3
  738. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-calendar-year-custom.xml +4 -3
  739. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-custom.xml +4 -3
  740. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-disabled.xml +4 -3
  741. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-runperiod-1-month.xml +4 -3
  742. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins.xml +4 -3
  743. data/example_files/resources/hpxml-measures/workflow/sample_files/base.xml +4 -3
  744. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/boiler-invalid-afue.xml +519 -0
  745. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/cfis-with-hydronic-distribution.xml +1 -2
  746. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/clothes-dryer-location.xml +4 -3
  747. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/clothes-washer-location.xml +4 -3
  748. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/cooking-range-location.xml +4 -3
  749. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-appliances-dehumidifier-50percent.xml → invalid_files/dehumidifier-fraction-served.xml} +534 -523
  750. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dehumidifier-setpoints.xml +535 -0
  751. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dhw-frac-load-served.xml +1 -2
  752. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dhw-invalid-ef-tank.xml +4 -3
  753. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dhw-invalid-uef-tank-heat-pump.xml +4 -3
  754. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dishwasher-location.xml +4 -3
  755. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-leakage-cfm25.xml +563 -0
  756. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-leakage-percent.xml +563 -0
  757. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-location-unconditioned-space.xml +4 -3
  758. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-location.xml +4 -3
  759. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duplicate-id.xml +4 -3
  760. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-attic-missing-roof.xml +4 -3
  761. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-basement-missing-exterior-foundation-wall.xml +5 -4
  762. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-basement-missing-slab.xml +5 -4
  763. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-floor-area-exceeds-cfa.xml +7 -6
  764. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-floor-area-exceeds-cfa2.xml +448 -0
  765. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-garage-missing-exterior-wall.xml +4 -3
  766. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-garage-missing-roof-ceiling.xml +4 -3
  767. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-garage-missing-slab.xml +4 -3
  768. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-living-missing-ceiling-roof.xml +4 -3
  769. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-living-missing-exterior-wall.xml +4 -3
  770. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-living-missing-floor-slab.xml +14 -60
  771. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-sensible-fuel-load.xml +760 -0
  772. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-sensible-plug-load.xml +759 -0
  773. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-total-fuel-load.xml +761 -0
  774. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-total-plug-load.xml +759 -0
  775. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/furnace-invalid-afue.xml +563 -0
  776. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/generator-number-of-bedrooms-served.xml +460 -0
  777. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/generator-output-greater-than-consumption.xml +579 -0
  778. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/heat-pump-mixed-fixed-and-autosize-capacities.xml +3 -5
  779. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-distribution-multiple-attached-cooling.xml +920 -913
  780. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-distribution-multiple-attached-heating.xml +920 -913
  781. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-distribution-return-duct-leakage-missing.xml +3 -7
  782. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-dse-multiple-attached-cooling.xml +3 -4
  783. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-dse-multiple-attached-heating.xml +3 -4
  784. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-frac-load-served.xml +920 -913
  785. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-inconsistent-fan-powers.xml +4 -3
  786. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-invalid-distribution-system-type.xml +4 -3
  787. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-shared-negative-seer-eq.xml +407 -0
  788. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-assembly-effective-rvalue.xml +563 -0
  789. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-datatype-boolean.xml +4 -3
  790. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-datatype-float.xml +4 -3
  791. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-datatype-integer.xml +4 -3
  792. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-daylight-saving.xml +4 -3
  793. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-distribution-cfa-served.xml +5 -4
  794. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-epw-filepath.xml +4 -3
  795. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-facility-type-equipment.xml +4 -3
  796. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-facility-type-surfaces.xml +4 -3
  797. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-foundation-wall-properties.xml +574 -0
  798. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-id.xml +591 -0
  799. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-id2.xml +591 -0
  800. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-infiltration-volume.xml +563 -0
  801. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-input-parameters.xml +4 -3
  802. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-neighbor-shading-azimuth.xml +4 -3
  803. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-number-of-bedrooms-served.xml +465 -0
  804. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-number-of-conditioned-floors.xml +563 -0
  805. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-number-of-units-served.xml +451 -0
  806. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-relatedhvac-desuperheater.xml +3 -5
  807. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-relatedhvac-dhw-indirect.xml +1 -2
  808. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-runperiod.xml +4 -3
  809. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-schema-version.xml +4 -3
  810. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-shared-vent-in-unit-flowrate.xml +473 -0
  811. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-timestep.xml +4 -3
  812. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-window-height.xml +9 -3
  813. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/lighting-fractions.xml +4 -3
  814. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/missing-duct-location.xml +916 -909
  815. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/missing-elements.xml +4 -3
  816. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-appliance.xml +4 -3
  817. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-duct.xml +4 -3
  818. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-surface.xml +15 -4
  819. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-water-heater.xml +4 -3
  820. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-buildings-without-building-id.xml +1657 -0
  821. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-buildings-wrong-building-id.xml +1657 -0
  822. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-ideal-air.xml → invalid_files/multiple-shared-cooling-systems.xml} +431 -498
  823. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-shared-heating-systems.xml +434 -0
  824. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/net-area-negative-roof.xml +5 -4
  825. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/net-area-negative-wall.xml +4 -3
  826. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/num-bedrooms-exceeds-limit.xml +4 -3
  827. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/orphaned-hvac-distribution.xml +3 -2
  828. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/refrigerator-location.xml +4 -3
  829. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/refrigerators-multiple-primary.xml +4 -3
  830. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/refrigerators-no-primary.xml +4 -3
  831. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/repeated-relatedhvac-desuperheater.xml +3 -5
  832. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/repeated-relatedhvac-dhw-indirect.xml +1 -2
  833. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-fraction-one.xml +571 -0
  834. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-thermal-system-with-combi-tankless.xml +1 -2
  835. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-thermal-system-with-desuperheater.xml +3 -5
  836. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-thermal-system-with-dhw-indirect.xml +1 -2
  837. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-cfis.xml +4 -3
  838. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-door.xml +4 -3
  839. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-hvac-distribution.xml +4 -3
  840. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-shared-clothes-washer-water-heater.xml +4 -3
  841. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-shared-dishwasher-water-heater.xml +4 -3
  842. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-skylight.xml +6 -5
  843. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-solar-thermal-system.xml +4 -3
  844. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-window.xml +4 -3
  845. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/water-heater-location-other.xml +4 -3
  846. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/water-heater-location.xml +4 -3
  847. data/example_files/resources/hpxml-measures/workflow/template.osw +5 -1
  848. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AC.xml +0 -3
  849. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AL.xml +0 -3
  850. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AC.xml +0 -3
  851. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AL.xml +0 -3
  852. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AC.xml +0 -3
  853. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AL.xml +0 -3
  854. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AC.xml +0 -3
  855. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AL.xml +0 -3
  856. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AC.xml +0 -3
  857. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AL.xml +0 -3
  858. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AC.xml +0 -3
  859. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AL.xml +0 -3
  860. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AC.xml +0 -3
  861. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AL.xml +0 -3
  862. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AC.xml +0 -3
  863. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AL.xml +0 -3
  864. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AC.xml +0 -3
  865. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AL.xml +0 -3
  866. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AC.xml +0 -3
  867. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AL.xml +0 -3
  868. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AC.xml +0 -3
  869. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AL.xml +0 -3
  870. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L302XC.xml +0 -3
  871. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L304XC.xml +0 -3
  872. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L322XC.xml +0 -3
  873. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L324XC.xml +0 -3
  874. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results.csv +294 -0
  875. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_ashrae_140.csv +27 -0
  876. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_hvac_sizing.csv +294 -0
  877. data/example_files/resources/hpxml-measures/workflow/tests/compare.rb +130 -0
  878. data/example_files/resources/hpxml-measures/workflow/tests/hpxml_translator_test.rb +324 -382
  879. data/example_files/{measures/BuildResidentialModel/resources → resources}/measure-info.json +0 -0
  880. data/example_files/{measures/BuildResidentialModel/resources → resources}/meta_measure.rb +53 -44
  881. data/example_files/visualization/input_visualization_feature.html +13 -14
  882. data/example_files/visualization/input_visualization_scenario.html +14 -9
  883. data/lib/uo_cli.rb +293 -60
  884. data/lib/uo_cli/version.rb +17 -7
  885. data/requirements.txt +2 -0
  886. data/scripts/setup-env-gitbash.sh +4 -4
  887. data/scripts/setup-env-unix.sh +4 -4
  888. data/scripts/setup-env.bat +3 -3
  889. data/scripts/setup-env.ps1 +3 -3
  890. data/uo_cli.gemspec +10 -7
  891. metadata +320 -82
  892. data/example_files/measures/ResidentialGeometryCreateMultifamily/measure.rb +0 -1005
  893. data/example_files/measures/ResidentialGeometryCreateMultifamily/measure.xml +0 -326
  894. data/example_files/measures/ResidentialGeometryCreateMultifamily/tests/create_residential_multifamily_geometry_test.rb +0 -477
  895. data/example_files/measures/ResidentialGeometryCreateSingleFamilyAttached/measure.rb +0 -1039
  896. data/example_files/measures/ResidentialGeometryCreateSingleFamilyAttached/measure.xml +0 -393
  897. data/example_files/measures/ResidentialGeometryCreateSingleFamilyAttached/tests/create_residential_single_family_attached_geometry_test.rb +0 -456
  898. data/example_files/measures/ResidentialGeometryCreateSingleFamilyDetached/measure.rb +0 -979
  899. data/example_files/measures/ResidentialGeometryCreateSingleFamilyDetached/measure.xml +0 -388
  900. data/example_files/measures/ResidentialGeometryCreateSingleFamilyDetached/tests/create_residential_single_family_detached_geometry_test.rb +0 -704
  901. data/example_files/resources/hpxml-measures/.circleci/config.yml +0 -20
  902. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/location.rb +0 -24
  903. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_config.yml +0 -74
  904. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-hvac-programmable-thermostat.osw +0 -369
  905. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_constructions.rb +0 -109
  906. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple2.xml +0 -835
  907. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/heat-pump-mixed-fixed-and-autosize-capacities2.xml +0 -563
@@ -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)