urbanopt-cli 0.5.1 → 0.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (871) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +14 -1
  3. data/CMakeLists.txt +8 -8
  4. data/LICENSE.md +11 -1
  5. data/Rakefile +16 -6
  6. data/example_files/example_project_combined.json +100 -5
  7. data/example_files/mappers/Baseline.rb +31 -18
  8. data/example_files/mappers/CreateBar.rb +16 -6
  9. data/example_files/mappers/EvCharging.rb +20 -10
  10. data/example_files/mappers/Floorspace.rb +16 -6
  11. data/example_files/mappers/HighEfficiencyCreateBar.rb +16 -6
  12. data/example_files/mappers/HighEfficiencyFloorspace.rb +16 -6
  13. data/example_files/mappers/ThermalStorage.rb +16 -6
  14. data/example_files/measures/BuildResidentialModel/measure.rb +211 -129
  15. data/example_files/residential/clothes_dryer.tsv +7 -7
  16. data/example_files/residential/clothes_washer.tsv +1 -1
  17. data/example_files/residential/cooling_system.tsv +42 -22
  18. data/example_files/residential/dishwasher.tsv +1 -1
  19. data/example_files/residential/exhaust.tsv +3 -0
  20. data/example_files/residential/heat_pump.tsv +62 -40
  21. data/example_files/resources/hpxml-measures/.github/pull_request_template.md +1 -0
  22. data/example_files/resources/hpxml-measures/.github/workflows/config.yml +23 -0
  23. data/example_files/resources/hpxml-measures/.gitignore +1 -8
  24. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.rb +633 -1188
  25. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.xml +1524 -1211
  26. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/constants.rb +0 -8
  27. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb +424 -335
  28. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules.rb +104 -62
  29. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_weekday_state_and_monthly_schedule_shift.csv +613 -0
  30. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_weekend_state_and_monthly_schedule_shift.csv +613 -0
  31. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-coal.osw +31 -55
  32. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-dehumidifier-50percent.osw +30 -54
  33. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-dehumidifier-ief-portable.osw +30 -54
  34. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-dehumidifier-ief-whole-home.osw +30 -54
  35. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-dehumidifier.osw +30 -54
  36. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-gas.osw +31 -55
  37. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-modified.osw +31 -55
  38. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-none.osw +36 -60
  39. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-oil.osw +31 -55
  40. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-propane.osw +31 -55
  41. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-wood.osw +31 -55
  42. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-flat.osw +31 -55
  43. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-radiant-barrier.osw +31 -55
  44. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-unvented-insulated-roof.osw +31 -55
  45. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-vented.osw +31 -55
  46. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-mechvent-preconditioning.osw +31 -55
  47. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-mechvent.osw +31 -55
  48. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-pv.osw +31 -55
  49. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-water-heater.osw +31 -55
  50. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily.osw +31 -55
  51. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-single-family-attached.osw +31 -55
  52. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-combi-tankless-outside.osw +31 -56
  53. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-combi-tankless.osw +31 -56
  54. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-dwhr.osw +31 -55
  55. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect-outside.osw +31 -56
  56. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect-standbyloss.osw +31 -56
  57. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect-with-solar-fraction.osw +31 -56
  58. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect.osw +31 -56
  59. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-electric.osw +31 -55
  60. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-gas.osw +31 -55
  61. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-hpwh.osw +31 -55
  62. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-indirect.osw +31 -56
  63. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-low-flow-fixtures.osw +31 -55
  64. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-none.osw +32 -56
  65. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-demand.osw +31 -55
  66. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-manual.osw +31 -55
  67. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-nocontrol.osw +31 -55
  68. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-temperature.osw +31 -55
  69. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-timer.osw +31 -55
  70. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-direct-evacuated-tube.osw +31 -55
  71. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-direct-flat-plate.osw +31 -55
  72. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-direct-ics.osw +31 -55
  73. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-fraction.osw +31 -55
  74. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-indirect-flat-plate.osw +31 -55
  75. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-thermosyphon-flat-plate.osw +31 -55
  76. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-coal.osw +31 -55
  77. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-elec-uef.osw +31 -55
  78. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-gas-outside.osw +31 -55
  79. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-gas-uef.osw +31 -55
  80. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-gas.osw +31 -55
  81. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-outside.osw +31 -55
  82. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-uef.osw +31 -55
  83. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-with-solar-fraction.osw +31 -55
  84. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-with-solar.osw +31 -55
  85. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump.osw +31 -55
  86. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-oil.osw +31 -55
  87. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-wood.osw +31 -55
  88. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-electric-outside.osw +31 -55
  89. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-electric-uef.osw +31 -55
  90. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-electric.osw +31 -55
  91. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas-uef.osw +31 -55
  92. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas-with-solar-fraction.osw +31 -55
  93. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas-with-solar.osw +31 -55
  94. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas.osw +31 -55
  95. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-propane.osw +31 -55
  96. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-2stories-garage.osw +31 -55
  97. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-2stories.osw +31 -55
  98. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-1.osw +31 -55
  99. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-2.osw +31 -55
  100. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-4.osw +31 -55
  101. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-5.osw +31 -55
  102. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-garage.osw +31 -55
  103. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-ach-house-pressure.osw +31 -55
  104. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-cfm-house-pressure.osw +31 -55
  105. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-cfm50.osw +31 -55
  106. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-flue.osw +31 -55
  107. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-natural-ach.osw +31 -55
  108. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-overhangs.osw +32 -56
  109. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-windows-none.osw +31 -55
  110. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-ambient.osw +31 -55
  111. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-conditioned-basement-slab-insulation.osw +31 -55
  112. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-slab.osw +31 -55
  113. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unconditioned-basement-assembly-r.osw +30 -54
  114. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unconditioned-basement-wall-insulation.osw +30 -54
  115. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unconditioned-basement.osw +30 -54
  116. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unvented-crawlspace.osw +30 -54
  117. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-vented-crawlspace.osw +30 -54
  118. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-1-speed-cooling-only.osw +337 -0
  119. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-1-speed-heating-only.osw +337 -0
  120. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-1-speed.osw +31 -56
  121. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-2-speed.osw +31 -55
  122. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-var-speed.osw +31 -55
  123. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-coal-only.osw +31 -55
  124. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-elec-only.osw +31 -55
  125. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-gas-central-ac-1-speed.osw +31 -56
  126. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-gas-only.osw +31 -56
  127. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-oil-only.osw +31 -55
  128. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-propane-only.osw +31 -55
  129. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-wood-only.osw +31 -55
  130. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-only-1-speed.osw +31 -56
  131. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-only-2-speed.osw +31 -55
  132. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-only-var-speed.osw +31 -55
  133. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.osw +31 -57
  134. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-electric.osw +31 -56
  135. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.osw +31 -56
  136. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.osw +31 -55
  137. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.osw +31 -55
  138. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-mini-split-heat-pump-ducted.osw +32 -57
  139. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ducts-leakage-percent.osw +31 -55
  140. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-elec-resistance-only.osw +31 -55
  141. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-evap-cooler-furnace-gas.osw +31 -55
  142. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-evap-cooler-only-ducted.osw +32 -56
  143. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-evap-cooler-only.osw +31 -56
  144. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-fireplace-wood-only.osw +31 -56
  145. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-fixed-heater-gas-only.osw +31 -56
  146. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-floor-furnace-propane-only.osw +31 -56
  147. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-coal-only.osw +337 -0
  148. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-elec-central-ac-1-speed.osw +31 -55
  149. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-elec-only.osw +31 -55
  150. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-central-ac-2-speed.osw +31 -55
  151. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-central-ac-var-speed.osw +31 -55
  152. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-only.osw +31 -56
  153. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-room-ac.osw +31 -55
  154. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-oil-only.osw +31 -55
  155. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-propane-only.osw +31 -55
  156. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-wood-only.osw +31 -55
  157. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ground-to-air-heat-pump-cooling-only.osw +336 -0
  158. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ground-to-air-heat-pump-heating-only.osw +336 -0
  159. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ground-to-air-heat-pump.osw +31 -57
  160. 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} +36 -58
  161. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-air-to-air-heat-pump-1-speed.osw +339 -0
  162. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-air-to-air-heat-pump-2-speed.osw +339 -0
  163. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-air-to-air-heat-pump-var-speed.osw +339 -0
  164. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-central-ac-1-speed.osw +340 -0
  165. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-central-ac-2-speed.osw +340 -0
  166. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-central-ac-var-speed.osw +340 -0
  167. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-only.osw +338 -0
  168. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-ground-to-air-heat-pump.osw +338 -0
  169. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-mini-split-air-conditioner-only-ducted.osw +338 -0
  170. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-mini-split-heat-pump-ducted.osw +339 -0
  171. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-charge-defect-furnace-gas-central-ac-1-speed.osw +338 -0
  172. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-none-furnace-gas-central-ac-1-speed.osw +340 -0
  173. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-air-conditioner-only-ducted.osw +31 -56
  174. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-air-conditioner-only-ductless.osw +31 -56
  175. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ducted-cooling-only.osw +32 -57
  176. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ducted-heating-only.osw +32 -57
  177. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ducted.osw +32 -57
  178. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ductless.osw +32 -57
  179. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-none.osw +31 -55
  180. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-portable-heater-gas-only.osw +31 -56
  181. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-programmable-thermostat-detailed.osw +337 -0
  182. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-room-ac-only-33percent.osw +31 -55
  183. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-room-ac-only.osw +31 -55
  184. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-setpoints.osw +31 -55
  185. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-stove-oil-only.osw +31 -56
  186. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-stove-wood-pellets-only.osw +31 -56
  187. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-undersized.osw +31 -55
  188. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-wall-furnace-elec-only.osw +31 -56
  189. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-lighting-ceiling-fans.osw +31 -55
  190. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-lighting-detailed.osw +31 -55
  191. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-AMY-2012.osw +31 -55
  192. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-baltimore-md.osw +40 -64
  193. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-dallas-tx.osw +31 -55
  194. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-duluth-mn.osw +44 -68
  195. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-helena-mt.osw +337 -0
  196. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-honolulu-hi.osw +337 -0
  197. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-miami-fl.osw +31 -55
  198. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-phoenix-az.osw +337 -0
  199. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-portland-or.osw +337 -0
  200. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-balanced.osw +31 -55
  201. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-bath-kitchen-fans.osw +39 -65
  202. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-cfis-evap-cooler-only-ducted.osw +32 -56
  203. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-cfis.osw +31 -55
  204. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-erv-atre-asre.osw +31 -55
  205. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-erv.osw +31 -55
  206. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-exhaust-rated-flow-rate.osw +337 -0
  207. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-exhaust.osw +31 -55
  208. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-hrv-asre.osw +31 -55
  209. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-hrv.osw +31 -55
  210. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-supply.osw +31 -55
  211. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-whole-house-fan.osw +31 -55
  212. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-defaults.osw +29 -53
  213. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-loads-large-uncommon.osw +29 -53
  214. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-loads-large-uncommon2.osw +29 -53
  215. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-neighbor-shading.osw +31 -55
  216. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-shielding-of-home.osw +337 -0
  217. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-usage-multiplier.osw +30 -54
  218. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-pv.osw +31 -55
  219. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-vacancy-6-months.osw → base-schedules-stochastic-vacant.osw} +34 -58
  220. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-schedules-stochastic.osw +31 -55
  221. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-schedules-user-specified.osw +31 -55
  222. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-calendar-year-custom.osw +31 -55
  223. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-daylight-saving-custom.osw +31 -55
  224. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-daylight-saving-disabled.osw +31 -55
  225. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-runperiod-1-month.osw +31 -55
  226. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-timestep-10-mins.osw +31 -55
  227. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base.osw +31 -55
  228. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/build_residential_hpxml_test.rb +57 -56
  229. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-auto.osw +31 -55
  230. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-double-exterior.osw +341 -0
  231. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-double-loaded-interior.osw +341 -0
  232. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-eaves.osw +341 -0
  233. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-single-exterior-front.osw +341 -0
  234. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-double-loaded-interior.osw +341 -0
  235. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-bottom-double-loaded-interior.osw +341 -0
  236. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-bottom.osw +341 -0
  237. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-middle-double-loaded-interior.osw +341 -0
  238. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-middle.osw +341 -0
  239. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-top-double-loaded-interior.osw +341 -0
  240. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-top.osw +341 -0
  241. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-bottom-double-loaded-interior.osw +341 -0
  242. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-bottom.osw +341 -0
  243. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-middle-double-loaded-interior.osw +341 -0
  244. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-middle.osw +341 -0
  245. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-top-double-loaded-interior.osw +341 -0
  246. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-top.osw +341 -0
  247. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-bottom-double-loaded-interior.osw +341 -0
  248. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-bottom.osw +341 -0
  249. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-middle-double-loaded-interior.osw +341 -0
  250. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-middle.osw +341 -0
  251. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-top-double-loaded-interior.osw +341 -0
  252. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-top.osw +341 -0
  253. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab.osw +341 -0
  254. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-double-loaded-interior.osw +341 -0
  255. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-bottom-double-loaded-interior.osw +341 -0
  256. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-bottom.osw +341 -0
  257. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-middle-double-loaded-interior.osw +341 -0
  258. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-middle.osw +341 -0
  259. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-top-double-loaded-interior.osw +341 -0
  260. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-top.osw +341 -0
  261. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-bottom-double-loaded-interior.osw +341 -0
  262. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-bottom.osw +341 -0
  263. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-middle-double-loaded-interior.osw +341 -0
  264. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-middle.osw +341 -0
  265. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-top-double-loaded-interior.osw +341 -0
  266. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-top.osw +341 -0
  267. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-bottom-double-loaded-interior.osw +341 -0
  268. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-bottom.osw +341 -0
  269. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-middle-double-loaded-interior.osw +341 -0
  270. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-middle.osw +341 -0
  271. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-top-double-loaded-interior.osw +341 -0
  272. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-top.osw +341 -0
  273. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace.osw +341 -0
  274. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-double-loaded-interior.osw +341 -0
  275. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-bottom-double-loaded-interior.osw +341 -0
  276. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-bottom.osw +341 -0
  277. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-middle-double-loaded-interior.osw +341 -0
  278. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-middle.osw +341 -0
  279. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-top-double-loaded-interior.osw +341 -0
  280. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-top.osw +341 -0
  281. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-bottom-double-loaded-interior.osw +341 -0
  282. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-bottom.osw +341 -0
  283. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-middle-double-loaded-interior.osw +341 -0
  284. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-middle.osw +341 -0
  285. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-top-double-loaded-interior.osw +341 -0
  286. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-top.osw +341 -0
  287. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-bottom-double-loaded-interior.osw +341 -0
  288. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-bottom.osw +341 -0
  289. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-middle-double-loaded-interior.osw +341 -0
  290. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-middle.osw +341 -0
  291. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-top-double-loaded-interior.osw +341 -0
  292. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-top.osw +341 -0
  293. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace.osw +341 -0
  294. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-atticroof-conditioned-eaves-gable.osw +339 -0
  295. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-atticroof-conditioned-eaves-hip.osw +339 -0
  296. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-double-exterior.osw +339 -0
  297. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-double-loaded-interior.osw +339 -0
  298. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-single-exterior-front.osw +339 -0
  299. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-slab-middle.osw +339 -0
  300. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-slab-right.osw +339 -0
  301. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-slab.osw +339 -0
  302. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unconditioned-basement-middle.osw +339 -0
  303. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unconditioned-basement-right.osw +339 -0
  304. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unconditioned-basement.osw +339 -0
  305. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unvented-crawlspace-middle.osw +339 -0
  306. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unvented-crawlspace-right.osw +339 -0
  307. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unvented-crawlspace.osw +339 -0
  308. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-vented-crawlspace-middle.osw +339 -0
  309. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-vented-crawlspace-right.osw +339 -0
  310. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-vented-crawlspace.osw +339 -0
  311. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-dhw-solar-latitude.osw +31 -55
  312. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-atticroof-conditioned-eaves-gable.osw +337 -0
  313. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-atticroof-conditioned-eaves-hip.osw +337 -0
  314. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-garage-atticroof-conditioned.osw +337 -0
  315. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-garage-partially-protruded.osw +31 -55
  316. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-windows-shading.osw +339 -0
  317. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-pv-roofpitch.osw +31 -55
  318. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-schedules-random-seed.osw +31 -55
  319. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-boiler-to-heat-pump.osw +336 -0
  320. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-boiler-to-heating-system.osw +337 -0
  321. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-fireplace-to-heat-pump.osw +337 -0
  322. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-second-heating-system-fireplace.osw → extra-second-heating-system-fireplace-to-heating-system.osw} +34 -58
  323. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-portable-heater-to-heat-pump.osw +337 -0
  324. 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} +32 -56
  325. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-refrigerator.osw +31 -55
  326. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-clothes-washer-kwh.osw +337 -0
  327. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-dishwasher-kwh.osw +337 -0
  328. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-extra-refrigerator-kwh.osw +337 -0
  329. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-freezer-kwh.osw +337 -0
  330. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-refrigerator-kwh.osw +337 -0
  331. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/conditioned-attic-with-floor-insulation.osw +34 -58
  332. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/conditioned-attic-with-one-floor-above-grade.osw +337 -0
  333. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/conditioned-basement-with-ceiling-insulation.osw +31 -55
  334. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/cooling-system-and-heat-pump.osw +31 -55
  335. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/dhw-indirect-without-boiler.osw +31 -55
  336. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/ducts-location-and-areas-not-same-type.osw +31 -55
  337. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/foundation-wall-insulation-greater-than-height.osw +337 -0
  338. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/heating-system-and-heat-pump.osw +31 -55
  339. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multifamily-bottom-crawlspace-zero-foundation-height.osw +31 -55
  340. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multifamily-bottom-slab-non-zero-foundation-height.osw +31 -55
  341. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multifamily-no-building-orientation.osw +31 -55
  342. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-fuel-loads.osw +31 -55
  343. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-other-plug-loads.osw +337 -0
  344. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/{multipliers-without-plug-loads.osw → multipliers-without-tv-plug-loads.osw} +35 -59
  345. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-vehicle-plug-loads.osw +337 -0
  346. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-well-pump-plug-loads.osw +337 -0
  347. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/non-electric-heat-pump-water-heater.osw +31 -55
  348. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/non-integer-ceiling-fan-quantity.osw +31 -55
  349. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/non-integer-geometry-num-bathrooms.osw +31 -55
  350. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/second-heating-system-but-no-primary-heating.osw +337 -0
  351. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/second-heating-system-serves-majority-heat.osw +31 -55
  352. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/second-heating-system-serves-total-heat-load.osw +337 -0
  353. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-attached-ambient.osw +31 -55
  354. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-attached-no-building-orientation.osw +31 -55
  355. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-detached-finished-basement-zero-foundation-height.osw +31 -55
  356. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-detached-slab-non-zero-foundation-height.osw +31 -55
  357. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/slab-non-zero-foundation-height-above-grade.osw +31 -55
  358. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/unconditioned-basement-with-wall-and-ceiling-insulation.osw +31 -55
  359. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/unvented-attic-with-floor-and-roof-insulation.osw +31 -55
  360. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/unvented-crawlspace-with-wall-and-ceiling-insulation.osw +31 -55
  361. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/vented-attic-with-floor-and-roof-insulation.osw +33 -57
  362. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/vented-crawlspace-with-wall-and-ceiling-insulation.osw +31 -55
  363. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/zero-number-of-bedrooms.osw +337 -0
  364. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/schedules/vacant.csv +8761 -0
  365. data/example_files/resources/hpxml-measures/Changelog.md +238 -0
  366. data/example_files/resources/hpxml-measures/Gemfile +4 -2
  367. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb +265 -838
  368. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml +135 -114
  369. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/BaseElements.xsd +5 -97
  370. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/EPvalidator.xml +573 -193
  371. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/HPXMLDataTypes.xsd +2 -28
  372. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/HPXMLvalidator.xml +114 -22
  373. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb +107 -176
  374. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constants.rb +12 -180
  375. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb +481 -94
  376. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/generator.rb +2 -6
  377. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb +23 -11
  378. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb +27 -25
  379. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb +735 -453
  380. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_defaults.rb +417 -105
  381. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb +1377 -1335
  382. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb +1393 -1467
  383. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb +2 -1
  384. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/location.rb +20 -7
  385. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/meta_measure.rb +64 -3
  386. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb +2 -22
  387. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/pv.rb +1 -3
  388. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb +15 -6
  389. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/simcontrols.rb +7 -1
  390. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/unit_conversions.rb +2 -0
  391. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb +1 -1
  392. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb +3 -4
  393. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb +31 -30
  394. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb +4 -1
  395. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_constructions.rb +62 -16
  396. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_defaults.rb +507 -628
  397. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_generator.rb +3 -0
  398. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb +4 -1
  399. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac.rb +321 -6
  400. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb +3 -0
  401. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_location.rb +3 -0
  402. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb +3 -0
  403. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_pv.rb +3 -0
  404. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_simcontrols.rb +3 -0
  405. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb +25 -1
  406. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_water_heater.rb +3 -0
  407. data/example_files/resources/hpxml-measures/README.md +4 -4
  408. data/example_files/resources/hpxml-measures/SimulationOutputReport/measure.rb +111 -37
  409. data/example_files/resources/hpxml-measures/SimulationOutputReport/measure.xml +318 -490
  410. data/example_files/resources/hpxml-measures/SimulationOutputReport/tests/output_report_test.rb +237 -183
  411. data/example_files/resources/hpxml-measures/docs/source/conf.py +4 -1
  412. data/example_files/resources/hpxml-measures/docs/source/getting_started.rst +2 -2
  413. data/example_files/resources/hpxml-measures/docs/source/intro.rst +3 -105
  414. data/example_files/resources/hpxml-measures/docs/source/workflow_inputs.rst +476 -351
  415. data/example_files/resources/hpxml-measures/docs/source/workflow_outputs.rst +154 -130
  416. data/example_files/resources/hpxml-measures/tasks.rb +1287 -511
  417. data/example_files/resources/hpxml-measures/weather/USA_AZ_Phoenix-Sky.Harbor.Intl.AP.722780_TMY3-cache.csv +35 -0
  418. data/example_files/resources/hpxml-measures/weather/USA_AZ_Phoenix-Sky.Harbor.Intl.AP.722780_TMY3.epw +8768 -0
  419. data/example_files/resources/hpxml-measures/weather/USA_HI_Honolulu.Intl.AP.911820_TMY3-cache.csv +35 -0
  420. data/example_files/resources/hpxml-measures/weather/USA_HI_Honolulu.Intl.AP.911820_TMY3.epw +8768 -0
  421. data/example_files/resources/hpxml-measures/weather/USA_MT_Helena.Rgnl.AP.727720_TMY3-cache.csv +35 -0
  422. data/example_files/resources/hpxml-measures/weather/USA_MT_Helena.Rgnl.AP.727720_TMY3.epw +8768 -0
  423. data/example_files/resources/hpxml-measures/weather/USA_OR_Portland.Intl.AP.726980_TMY3-cache.csv +35 -0
  424. data/example_files/resources/hpxml-measures/weather/USA_OR_Portland.Intl.AP.726980_TMY3.epw +8768 -0
  425. data/example_files/resources/hpxml-measures/workflow/run_simulation.rb +23 -5
  426. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-coal.xml +1 -1
  427. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-50percent.xml +2 -1
  428. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-portable.xml +2 -1
  429. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-whole-home.xml +2 -1
  430. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-multiple.xml +534 -0
  431. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier.xml +2 -1
  432. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-gas.xml +1 -1
  433. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-modified.xml +1 -1
  434. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-none.xml +1 -0
  435. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil.xml +1 -1
  436. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane.xml +1 -1
  437. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-wood.xml +1 -1
  438. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-cathedral.xml +1 -1
  439. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-conditioned.xml +3 -3
  440. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-flat.xml +1 -1
  441. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-radiant-barrier.xml +1 -1
  442. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-unvented-insulated-roof.xml +1 -1
  443. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-vented.xml +1 -1
  444. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multifamily-buffer-space.xml +1 -1
  445. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multiple.xml +1 -1
  446. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-non-freezing-space.xml +1 -1
  447. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-other-heated-space.xml +1 -1
  448. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-other-housing-unit.xml +1 -1
  449. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-baseboard.xml +0 -1
  450. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil-ducted.xml +4 -4
  451. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil.xml +20 -4
  452. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-water-loop-heat-pump.xml +27 -18
  453. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-cooling-tower-water-loop-heat-pump.xml +27 -18
  454. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-baseboard.xml +0 -1
  455. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-ducted.xml +4 -4
  456. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-eae.xml +20 -4
  457. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil.xml +20 -4
  458. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-water-loop-heat-pump.xml +22 -11
  459. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-baseboard.xml +0 -1
  460. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil-ducted.xml +4 -4
  461. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil.xml +20 -4
  462. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-water-loop-heat-pump.xml +22 -12
  463. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-cooling-tower-only-water-loop-heat-pump.xml +22 -12
  464. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-generator.xml +1 -1
  465. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-ground-loop-ground-to-air-heat-pump.xml +2 -3
  466. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-laundry-room.xml +1 -1
  467. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-multiple.xml +2 -1
  468. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-preconditioning.xml +1 -1
  469. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent.xml +1 -1
  470. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-pv.xml +1 -1
  471. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater-recirc.xml +1 -1
  472. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater.xml +1 -1
  473. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily.xml +1 -1
  474. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-single-family-attached.xml +14 -2
  475. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless-outside.xml +0 -1
  476. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless.xml +0 -1
  477. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-2-speed.xml +1 -1
  478. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-gshp.xml +563 -564
  479. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-hpwh.xml +1 -1
  480. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-tankless.xml +1 -4
  481. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-var-speed.xml +1 -1
  482. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater.xml +1 -4
  483. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-dwhr.xml +1 -1
  484. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-dse.xml +0 -1
  485. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-outside.xml +0 -1
  486. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-standbyloss.xml +0 -1
  487. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-with-solar-fraction.xml +0 -1
  488. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect.xml +0 -1
  489. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-electric.xml +1 -1
  490. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-gas.xml +1 -1
  491. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-hpwh.xml +1 -1
  492. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-indirect.xml +0 -1
  493. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-low-flow-fixtures.xml +1 -1
  494. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-multiple.xml +0 -1
  495. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-none.xml +1 -0
  496. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-demand.xml +1 -1
  497. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-manual.xml +1 -1
  498. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-nocontrol.xml +1 -1
  499. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-temperature.xml +1 -1
  500. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-timer.xml +1 -1
  501. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-evacuated-tube.xml +1 -1
  502. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-flat-plate.xml +1 -1
  503. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-ics.xml +1 -1
  504. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-fraction.xml +1 -1
  505. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-indirect-flat-plate.xml +1 -1
  506. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-thermosyphon-flat-plate.xml +1 -1
  507. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-coal.xml +1 -1
  508. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-elec-uef.xml +1 -1
  509. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-outside.xml +1 -1
  510. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef.xml +1 -1
  511. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas.xml +1 -1
  512. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-outside.xml +1 -1
  513. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-uef.xml +1 -1
  514. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar-fraction.xml +1 -1
  515. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar.xml +1 -1
  516. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump.xml +1 -1
  517. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-oil.xml +1 -1
  518. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-wood.xml +1 -1
  519. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-outside.xml +1 -1
  520. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-uef.xml +1 -1
  521. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric.xml +1 -1
  522. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-uef.xml +1 -1
  523. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar-fraction.xml +1 -1
  524. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar.xml +1 -1
  525. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas.xml +1 -1
  526. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-propane.xml +1 -1
  527. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories-garage.xml +2 -2
  528. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories.xml +1 -1
  529. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-1.xml +1 -1
  530. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-2.xml +1 -1
  531. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-4.xml +1 -1
  532. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-5.xml +1 -1
  533. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-garage.xml +1 -1
  534. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-ach-house-pressure.xml +1 -1
  535. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm-house-pressure.xml +1 -1
  536. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm50.xml +1 -1
  537. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-flue.xml +1 -1
  538. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-natural-ach.xml +1 -1
  539. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-overhangs.xml +6 -1
  540. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-rooftypes.xml +1 -1
  541. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-shading.xml +600 -0
  542. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights.xml +1 -1
  543. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-level.xml +1 -1
  544. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces.xml +1 -1
  545. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces2.xml +2474 -0
  546. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-walltypes.xml +1 -1
  547. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-none.xml +1 -1
  548. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-enclosure-windows-interior-shading.xml → base-enclosure-windows-shading.xml} +576 -561
  549. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-ambient.xml +1 -1
  550. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-basement-garage.xml +643 -0
  551. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-complex.xml +1 -1
  552. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-slab-insulation.xml +1 -1
  553. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-wall-interior-insulation.xml +1 -1
  554. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-multiple.xml +3 -3
  555. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-slab.xml +1 -1
  556. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-above-grade.xml +2 -2
  557. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-assembly-r.xml +2 -2
  558. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-wall-insulation.xml +1 -1
  559. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement.xml +2 -2
  560. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unvented-crawlspace.xml +1 -1
  561. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-vented-crawlspace.xml +1 -1
  562. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-walkout-basement.xml +1 -1
  563. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-cooling-only.xml +555 -0
  564. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-heating-only.xml +561 -0
  565. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed.xml +1 -4
  566. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-2-speed.xml +1 -1
  567. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed.xml +1 -1
  568. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-cooling-only.xml +552 -0
  569. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-heating-only.xml +557 -0
  570. 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} +1 -4
  571. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-hvac-air-to-air-heat-pump-1-speed-autosize.xml → base-hvac-autosize-air-to-air-heat-pump-1-speed.xml} +1 -4
  572. 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} +559 -559
  573. 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} +556 -556
  574. 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-manual-s-oversize-allowances.xml} +559 -556
  575. 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.xml} +556 -559
  576. 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
  577. 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} +568 -569
  578. 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
  579. 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} +1 -4
  580. 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} +546 -546
  581. 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} +546 -546
  582. 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} +1 -7
  583. 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} +1 -4
  584. 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} +1 -4
  585. 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
  586. 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} +552 -552
  587. 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
  588. 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} +546 -546
  589. 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} +559 -559
  590. 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} +559 -559
  591. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-only.xml +547 -0
  592. 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} +557 -557
  593. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-cooling-only.xml +554 -0
  594. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-heating-only.xml +559 -0
  595. 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} +561 -562
  596. 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} +558 -559
  597. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-air-conditioner-only-ducted.xml +546 -0
  598. 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} +1 -4
  599. 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} +1 -4
  600. 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} +1 -4
  601. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted.xml +556 -0
  602. 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
  603. 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
  604. 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
  605. data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-autosize.xml → base-hvac-autosize.xml} +559 -559
  606. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-coal-only.xml +0 -1
  607. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-elec-only.xml +0 -1
  608. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-central-ac-1-speed.xml +1 -2
  609. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-only.xml +0 -1
  610. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-oil-only.xml +0 -1
  611. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-propane-only.xml +0 -1
  612. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-wood-only.xml +0 -1
  613. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed.xml +1 -4
  614. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-2-speed.xml +1 -1
  615. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-var-speed.xml +1 -1
  616. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.xml +1 -7
  617. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dse.xml +0 -1
  618. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-electric.xml +1 -4
  619. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.xml +1 -4
  620. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.xml +1 -1
  621. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.xml +1 -1
  622. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-mini-split-heat-pump-ducted.xml +1 -4
  623. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-percent.xml +1 -1
  624. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-elec-resistance-only.xml +0 -1
  625. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-furnace-gas.xml +2 -1
  626. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only-ducted.xml +10 -1
  627. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only.xml +1 -4
  628. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fireplace-wood-only.xml +512 -513
  629. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fixed-heater-gas-only.xml +563 -563
  630. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-floor-furnace-propane-only.xml +512 -513
  631. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-coal-only.xml +547 -547
  632. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-central-ac-1-speed.xml +1 -1
  633. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-only.xml +1 -1
  634. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-2-speed.xml +1 -1
  635. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-var-speed.xml +1 -1
  636. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only.xml +547 -550
  637. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-room-ac.xml +1 -1
  638. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-oil-only.xml +1 -1
  639. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-propane-only.xml +1 -1
  640. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-wood-only.xml +1 -1
  641. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-x3-dse.xml +0 -1
  642. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-cooling-only.xml +556 -0
  643. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-heating-only.xml +562 -0
  644. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump.xml +561 -562
  645. 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} +567 -561
  646. data/example_files/resources/hpxml-measures/workflow/sample_files/{invalid_files/heat-pump-mixed-fixed-and-autosize-capacities2.xml → base-hvac-install-quality-all-air-to-air-heat-pump-1-speed.xml} +565 -562
  647. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-air-to-air-heat-pump-2-speed.xml +566 -0
  648. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-air-to-air-heat-pump-var-speed.xml +566 -0
  649. 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} +570 -564
  650. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-furnace-gas-central-ac-2-speed.xml +571 -0
  651. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-furnace-gas-central-ac-var-speed.xml +571 -0
  652. 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} +551 -549
  653. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-ground-to-air-heat-pump.xml +565 -0
  654. 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} +551 -548
  655. 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} +564 -558
  656. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-blower-efficiency-furnace-gas-central-ac-1-speed.xml +568 -0
  657. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-charge-defect-furnace-gas-central-ac-1-speed.xml +565 -0
  658. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-none-furnace-gas-central-ac-1-speed.xml +569 -0
  659. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ducted.xml +1 -4
  660. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ductless.xml +0 -4
  661. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-cooling-only.xml +1 -4
  662. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-heating-only.xml +1 -4
  663. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted.xml +1 -4
  664. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless.xml +0 -4
  665. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple.xml +916 -913
  666. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple2.xml +837 -834
  667. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-none.xml +0 -1
  668. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-portable-heater-gas-only.xml +563 -563
  669. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-programmable-thermostat-detailed.xml +1 -1
  670. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-programmable-thermostat.xml +1 -1
  671. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-33percent.xml +0 -1
  672. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only.xml +0 -1
  673. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints.xml +1 -1
  674. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-oil-only.xml +512 -513
  675. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-wood-pellets-only.xml +512 -513
  676. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized-allow-increased-fixed-capacities.xml +1 -1
  677. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized.xml +1 -1
  678. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-wall-furnace-elec-only.xml +512 -513
  679. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-ceiling-fans.xml +1 -1
  680. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-detailed.xml +1 -1
  681. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-none.xml +1 -1
  682. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-AMY-2012.xml +1 -1
  683. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-baltimore-md.xml +34 -23
  684. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-dallas-tx.xml +1 -1
  685. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-duluth-mn.xml +34 -23
  686. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-helena-mt.xml +562 -0
  687. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-honolulu-hi.xml +516 -0
  688. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-miami-fl.xml +1 -1
  689. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-phoenix-az.xml +516 -0
  690. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-portland-or.xml +576 -0
  691. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-balanced.xml +1 -1
  692. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-bath-kitchen-fans.xml +1 -1
  693. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-dse.xml +0 -1
  694. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-evap-cooler-only-ducted.xml +10 -1
  695. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis.xml +1 -1
  696. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv-atre-asre.xml +1 -1
  697. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv.xml +1 -1
  698. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust-rated-flow-rate.xml +1 -1
  699. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust.xml +1 -1
  700. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv-asre.xml +1 -1
  701. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv.xml +1 -1
  702. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-multiple.xml +2 -1
  703. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-supply.xml +1 -1
  704. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-whole-house-fan.xml +1 -1
  705. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-defaults.xml +1 -0
  706. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators.xml +1 -1
  707. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon.xml +5 -1
  708. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon2.xml +9 -1
  709. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-none.xml +1 -1
  710. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-neighbor-shading.xml +1 -1
  711. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-shielding-of-home.xml +563 -0
  712. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-usage-multiplier.xml +5 -1
  713. data/example_files/resources/hpxml-measures/workflow/sample_files/base-multiple-buildings.xml +1654 -0
  714. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv.xml +1 -1
  715. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-stochastic-vacant.xml +563 -0
  716. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-stochastic.xml +1 -1
  717. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-user-specified.xml +1 -1
  718. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-calendar-year-custom.xml +1 -1
  719. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-custom.xml +1 -1
  720. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-disabled.xml +1 -1
  721. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-runperiod-1-month.xml +1 -1
  722. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins.xml +1 -1
  723. data/example_files/resources/hpxml-measures/workflow/sample_files/base.xml +1 -1
  724. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/boiler-invalid-afue.xml +519 -0
  725. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/cfis-with-hydronic-distribution.xml +0 -1
  726. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/clothes-dryer-location.xml +1 -1
  727. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/clothes-washer-location.xml +1 -1
  728. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/cooking-range-location.xml +1 -1
  729. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dehumidifier-fraction-served.xml +534 -0
  730. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dehumidifier-setpoints.xml +534 -0
  731. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dhw-frac-load-served.xml +0 -1
  732. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dhw-invalid-ef-tank.xml +1 -1
  733. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dhw-invalid-uef-tank-heat-pump.xml +1 -1
  734. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dishwasher-location.xml +1 -1
  735. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-leakage-cfm25.xml +562 -0
  736. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-leakage-percent.xml +562 -0
  737. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-location-unconditioned-space.xml +1 -1
  738. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-location.xml +1 -1
  739. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duplicate-id.xml +1 -1
  740. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-attic-missing-roof.xml +1 -1
  741. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-basement-missing-exterior-foundation-wall.xml +2 -2
  742. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-basement-missing-slab.xml +2 -2
  743. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-floor-area-exceeds-cfa.xml +4 -4
  744. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-floor-area-exceeds-cfa2.xml +447 -0
  745. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-garage-missing-exterior-wall.xml +1 -1
  746. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-garage-missing-roof-ceiling.xml +1 -1
  747. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-garage-missing-slab.xml +1 -1
  748. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-living-missing-ceiling-roof.xml +1 -1
  749. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-living-missing-exterior-wall.xml +1 -1
  750. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-living-missing-floor-slab.xml +11 -58
  751. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-sensible-fuel-load.xml +759 -0
  752. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-sensible-plug-load.xml +758 -0
  753. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-total-fuel-load.xml +760 -0
  754. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-total-plug-load.xml +758 -0
  755. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/furnace-invalid-afue.xml +562 -0
  756. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/generator-number-of-bedrooms-served.xml +459 -0
  757. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/generator-output-greater-than-consumption.xml +578 -0
  758. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/heat-pump-mixed-fixed-and-autosize-capacities.xml +1 -4
  759. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-distribution-multiple-attached-cooling.xml +916 -913
  760. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-distribution-multiple-attached-heating.xml +916 -913
  761. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-distribution-return-duct-leakage-missing.xml +2 -7
  762. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-dse-multiple-attached-cooling.xml +0 -1
  763. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-dse-multiple-attached-heating.xml +0 -1
  764. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-frac-load-served.xml +916 -913
  765. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-inconsistent-fan-powers.xml +1 -1
  766. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-invalid-distribution-system-type.xml +1 -1
  767. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-assembly-effective-rvalue.xml +562 -0
  768. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-datatype-boolean.xml +1 -1
  769. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-datatype-float.xml +1 -1
  770. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-datatype-integer.xml +1 -1
  771. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-daylight-saving.xml +1 -1
  772. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-distribution-cfa-served.xml +2 -2
  773. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-epw-filepath.xml +1 -1
  774. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-facility-type-equipment.xml +1 -1
  775. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-facility-type-surfaces.xml +1 -1
  776. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-foundation-wall-properties.xml +573 -0
  777. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-id.xml +590 -0
  778. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-id2.xml +590 -0
  779. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-infiltration-volume.xml +562 -0
  780. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-input-parameters.xml +1 -1
  781. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-neighbor-shading-azimuth.xml +1 -1
  782. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-number-of-bedrooms-served.xml +464 -0
  783. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-number-of-conditioned-floors.xml +562 -0
  784. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-number-of-units-served.xml +450 -0
  785. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-relatedhvac-desuperheater.xml +1 -4
  786. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-relatedhvac-dhw-indirect.xml +0 -1
  787. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-runperiod.xml +1 -1
  788. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-schema-version.xml +1 -1
  789. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-shared-vent-in-unit-flowrate.xml +472 -0
  790. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-timestep.xml +1 -1
  791. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-window-height.xml +6 -1
  792. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/lighting-fractions.xml +1 -1
  793. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/missing-duct-location.xml +912 -909
  794. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/missing-elements.xml +1 -1
  795. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-appliance.xml +1 -1
  796. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-duct.xml +1 -1
  797. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-surface.xml +12 -2
  798. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-water-heater.xml +1 -1
  799. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-buildings-without-building-id.xml +1654 -0
  800. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-buildings-wrong-building-id.xml +1654 -0
  801. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-ideal-air.xml → invalid_files/multiple-shared-cooling-systems.xml} +431 -498
  802. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-shared-heating-systems.xml +434 -0
  803. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/net-area-negative-roof.xml +1 -1
  804. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/net-area-negative-wall.xml +1 -1
  805. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/num-bedrooms-exceeds-limit.xml +1 -1
  806. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/orphaned-hvac-distribution.xml +1 -1
  807. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/refrigerator-location.xml +1 -1
  808. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/refrigerators-multiple-primary.xml +1 -1
  809. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/refrigerators-no-primary.xml +1 -1
  810. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/repeated-relatedhvac-desuperheater.xml +1 -4
  811. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/repeated-relatedhvac-dhw-indirect.xml +0 -1
  812. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-thermal-system-with-combi-tankless.xml +0 -1
  813. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-thermal-system-with-desuperheater.xml +1 -4
  814. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-thermal-system-with-dhw-indirect.xml +0 -1
  815. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-cfis.xml +1 -1
  816. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-door.xml +1 -1
  817. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-hvac-distribution.xml +1 -1
  818. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-shared-clothes-washer-water-heater.xml +1 -1
  819. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-shared-dishwasher-water-heater.xml +1 -1
  820. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-skylight.xml +1 -1
  821. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-solar-thermal-system.xml +1 -1
  822. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-window.xml +1 -1
  823. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/water-heater-location-other.xml +1 -1
  824. data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/water-heater-location.xml +1 -1
  825. data/example_files/resources/hpxml-measures/workflow/template.osw +4 -1
  826. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AC.xml +0 -3
  827. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AL.xml +0 -3
  828. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AC.xml +0 -3
  829. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AL.xml +0 -3
  830. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AC.xml +0 -3
  831. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AL.xml +0 -3
  832. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AC.xml +0 -3
  833. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AL.xml +0 -3
  834. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AC.xml +0 -3
  835. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AL.xml +0 -3
  836. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AC.xml +0 -3
  837. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AL.xml +0 -3
  838. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AC.xml +0 -3
  839. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AL.xml +0 -3
  840. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AC.xml +0 -3
  841. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AL.xml +0 -3
  842. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AC.xml +0 -3
  843. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AL.xml +0 -3
  844. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AC.xml +0 -3
  845. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AL.xml +0 -3
  846. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AC.xml +0 -3
  847. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AL.xml +0 -3
  848. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L302XC.xml +0 -3
  849. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L304XC.xml +0 -3
  850. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L322XC.xml +0 -3
  851. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L324XC.xml +0 -3
  852. data/example_files/resources/hpxml-measures/workflow/tests/hpxml_translator_test.rb +232 -360
  853. data/example_files/{measures/BuildResidentialModel/resources → resources}/measure-info.json +0 -0
  854. data/example_files/{measures/BuildResidentialModel/resources → resources}/meta_measure.rb +53 -44
  855. data/lib/uo_cli.rb +187 -44
  856. data/lib/uo_cli/version.rb +17 -7
  857. data/requirements.txt +2 -0
  858. data/uo_cli.gemspec +2 -2
  859. metadata +248 -64
  860. data/example_files/measures/ResidentialGeometryCreateMultifamily/measure.rb +0 -1005
  861. data/example_files/measures/ResidentialGeometryCreateMultifamily/measure.xml +0 -326
  862. data/example_files/measures/ResidentialGeometryCreateMultifamily/tests/create_residential_multifamily_geometry_test.rb +0 -477
  863. data/example_files/measures/ResidentialGeometryCreateSingleFamilyAttached/measure.rb +0 -1039
  864. data/example_files/measures/ResidentialGeometryCreateSingleFamilyAttached/measure.xml +0 -393
  865. data/example_files/measures/ResidentialGeometryCreateSingleFamilyAttached/tests/create_residential_single_family_attached_geometry_test.rb +0 -456
  866. data/example_files/measures/ResidentialGeometryCreateSingleFamilyDetached/measure.rb +0 -979
  867. data/example_files/measures/ResidentialGeometryCreateSingleFamilyDetached/measure.xml +0 -388
  868. data/example_files/measures/ResidentialGeometryCreateSingleFamilyDetached/tests/create_residential_single_family_detached_geometry_test.rb +0 -704
  869. data/example_files/resources/hpxml-measures/.circleci/config.yml +0 -20
  870. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/location.rb +0 -24
  871. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-hvac-programmable-thermostat.osw +0 -369
@@ -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,108 @@ 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
+ u_wall = sum_ua_wall / sum_a_wall
894
+
895
+ # Calculate partition temperature different cooling (PTDC) per Manual J Figure A12-17
896
+ # Calculate partition temperature different heating (PTDH) per Manual J Figure A12-6
897
+ if [HPXML::LocationCrawlspaceVented].include? adjacent_space
898
+ # Vented or Leaky
899
+ ptdc_floor = @ctd / (1.0 + (4.0 * u_floor) / (u_wall + 0.11))
900
+ ptdh_floor = @htd / (1.0 + (4.0 * u_floor) / (u_wall + 0.11))
901
+ elsif [HPXML::LocationCrawlspaceUnvented, HPXML::LocationBasementUnconditioned].include? adjacent_space
902
+ # Sealed Tight
903
+ ptdc_floor = u_wall * @ctd / (4.0 * u_floor + u_wall)
904
+ ptdh_floor = u_wall * @htd / (4.0 * u_floor + u_wall)
905
+ end
906
+
907
+ bldg_design_loads.Cool_Floors += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * ptdc_floor
908
+ bldg_design_loads.Heat_Floors += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * ptdh_floor
909
+ else # E.g., floor over garage
910
+ bldg_design_loads.Cool_Floors += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * (@cool_design_temps[adjacent_space] - @cool_setpoint)
911
+ bldg_design_loads.Heat_Floors += (1.0 / frame_floor.insulation_assembly_r_value) * frame_floor.area * (@heat_setpoint - @heat_design_temps[adjacent_space])
912
+ end
862
913
  end
863
914
  end
915
+ end
916
+
917
+ def self.process_load_slabs(bldg_design_loads, weather)
918
+ '''
919
+ Heating and Cooling Loads: Floors
920
+ '''
921
+
922
+ bldg_design_loads.Heat_Slabs = 0.0
864
923
 
865
924
  @hpxml.slabs.each do |slab|
866
925
  next unless slab.is_thermal_boundary
867
926
 
868
927
  if slab.interior_adjacent_to == HPXML::LocationLivingSpace # Slab-on-grade
869
928
  f_value = calc_slab_f_value(slab)
870
- zone_loads.Heat_Floors += f_value * slab.exposed_perimeter * @htd
929
+ bldg_design_loads.Heat_Slabs += f_value * slab.exposed_perimeter * @htd
871
930
  elsif slab.interior_adjacent_to == HPXML::LocationBasementConditioned
872
931
  # Based on MJ 8th Ed. A12-7 and ASHRAE HoF 2013 pg 18.31 Eq 40
873
932
  # FIXME: Assumes slab is uninsulated?
@@ -879,95 +938,120 @@ class HVACSizing
879
938
  length = slab.exposed_perimeter / 4.0 + Math.sqrt(sqrt_term) / 4.0
880
939
  width = slab.exposed_perimeter / 4.0 - Math.sqrt(sqrt_term) / 4.0
881
940
  w_b = [length, width].min
941
+ w_b = [w_b, 1.0].max # handle zero exposed perimeter
882
942
  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
943
  u_value_mj8 = 0.85 * u_avg_bf
884
- zone_loads.Heat_Floors += u_value_mj8 * slab.area * @htd
944
+ bldg_design_loads.Heat_Slabs += u_value_mj8 * slab.area * @htd
885
945
  end
886
946
  end
887
-
888
- return zone_loads
889
947
  end
890
948
 
891
- def self.process_infiltration_ventilation(model, zone_loads, weather, infilvolume)
949
+ def self.process_load_infiltration_ventilation(bldg_design_loads, weather, cfa)
892
950
  '''
893
951
  Heating and Cooling Loads: Infiltration & Ventilation
894
952
  '''
895
953
 
896
- # Per ANSI/RESNET/ICC 301
897
- ach_nat = get_feature(@cond_zone, Constants.SizingInfoZoneInfiltrationACH, 'double')
954
+ # FUTURE: Consolidate code w/ airflow.rb
955
+ infil_volume = @hpxml.air_infiltration_measurements.select { |i| !i.infiltration_volume.nil? }[0].infiltration_volume
956
+ infil_height = @hpxml.inferred_infiltration_height(infil_volume)
957
+ sla = nil
958
+ @hpxml.air_infiltration_measurements.each do |measurement|
959
+ if [HPXML::UnitsACH, HPXML::UnitsCFM].include?(measurement.unit_of_measure) && !measurement.house_pressure.nil?
960
+ if measurement.unit_of_measure == HPXML::UnitsACH
961
+ ach50 = Airflow.calc_air_leakage_at_diff_pressure(0.65, measurement.air_leakage, measurement.house_pressure, 50.0)
962
+ elsif measurement.unit_of_measure == HPXML::UnitsCFM
963
+ achXX = measurement.air_leakage * 60.0 / infil_volume # Convert CFM to ACH
964
+ ach50 = Airflow.calc_air_leakage_at_diff_pressure(0.65, achXX, measurement.house_pressure, 50.0)
965
+ end
966
+ sla = Airflow.get_infiltration_SLA_from_ACH50(ach50, 0.65, cfa, infil_volume)
967
+ elsif measurement.unit_of_measure == HPXML::UnitsACHNatural
968
+ sla = Airflow.get_infiltration_SLA_from_ACH(measurement.air_leakage, infil_height, weather)
969
+ end
970
+ end
971
+ ela = sla * cfa
972
+
973
+ ncfl_ag = @hpxml.building_construction.number_of_conditioned_floors_above_grade
898
974
 
899
- ach_Cooling = 1.2 * ach_nat
900
- ach_Heating = 1.6 * ach_nat
975
+ # Set stack/wind coefficients from Tables 5D/5E
976
+ c_s = 0.015 * ncfl_ag
977
+ 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
978
+ c_w = c_w_base * ncfl_ag**0.4
901
979
 
902
- icfm_Cooling = ach_Cooling / UnitConversions.convert(1.0, 'hr', 'min') * infilvolume
903
- icfm_Heating = ach_Heating / UnitConversions.convert(1.0, 'hr', 'min') * infilvolume
980
+ ela_in2 = UnitConversions.convert(ela, 'ft^2', 'in^2')
981
+ windspeed_cooling_mph = 7.5 # Table 5D/5E Wind Velocity Value footnote
982
+ windspeed_heating_mph = 15.0 # Table 5D/5E Wind Velocity Value footnote
904
983
 
905
- q_unb_cfm, q_preheat, q_precool, q_recirc, q_bal_Sens, q_bal_Lat = get_ventilation_rates(model)
984
+ icfm_Cooling = ela_in2 * (c_s * @ctd + c_w * windspeed_cooling_mph**2)**0.5
985
+ icfm_Heating = ela_in2 * (c_s * @htd + c_w * windspeed_heating_mph**2)**0.5
986
+
987
+ q_unb_cfm, q_preheat, q_precool, q_recirc, q_bal_Sens, q_bal_Lat = get_ventilation_rates()
906
988
 
907
989
  cfm_Heating = q_bal_Sens + (icfm_Heating**2.0 + q_unb_cfm**2.0)**0.5 - q_preheat - q_recirc
908
990
 
909
991
  cfm_Cool_Load_Sens = q_bal_Sens + (icfm_Cooling**2.0 + q_unb_cfm**2.0)**0.5 - q_precool - q_recirc
910
992
  cfm_Cool_Load_Lat = q_bal_Lat + (icfm_Cooling**2.0 + q_unb_cfm**2.0)**0.5 - q_recirc
911
993
 
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)
994
+ bldg_design_loads.Heat_InfilVent = 1.1 * @acf * cfm_Heating * @htd
916
995
 
917
- return zone_loads
996
+ bldg_design_loads.Cool_Infil_Sens = 1.1 * @acf * cfm_Cool_Load_Sens * @ctd
997
+ bldg_design_loads.Cool_Infil_Lat = 0.68 * @acf * cfm_Cool_Load_Lat * (@cool_design_grains - @cool_indoor_grains)
918
998
  end
919
999
 
920
- def self.process_internal_gains(zone_loads, nbeds)
1000
+ def self.process_load_internal_gains(bldg_design_loads, nbeds)
921
1001
  '''
922
1002
  Cooling Load: Internal Gains
923
1003
  '''
924
1004
 
925
1005
  # Per ANSI/RESNET/ICC 301
926
1006
  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
1007
+ bldg_design_loads.Cool_IntGains_Sens = 1600.0 + 230.0 * n_occupants
1008
+ bldg_design_loads.Cool_IntGains_Lat = 200.0 * n_occupants
931
1009
  end
932
1010
 
933
- def self.aggregate_zone_loads(zone_loads)
1011
+ def self.aggregate_loads(bldg_design_loads)
934
1012
  '''
935
- Intermediate Loads
936
- (total loads excluding ducts)
1013
+ Building Loads (excluding ducts)
937
1014
  '''
938
1015
 
939
- init_loads = InitialLoads.new
940
1016
  # 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
1017
+ bldg_design_loads.Heat_Tot = [bldg_design_loads.Heat_Windows + bldg_design_loads.Heat_Skylights +
1018
+ bldg_design_loads.Heat_Doors + bldg_design_loads.Heat_Walls +
1019
+ bldg_design_loads.Heat_Floors + bldg_design_loads.Heat_Slabs +
1020
+ bldg_design_loads.Heat_Ceilings + bldg_design_loads.Heat_Roofs, 0.0].max +
1021
+ bldg_design_loads.Heat_InfilVent
945
1022
 
946
1023
  # 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)
1024
+ bldg_design_loads.Cool_Sens = bldg_design_loads.Cool_Windows + bldg_design_loads.Cool_Skylights +
1025
+ bldg_design_loads.Cool_Doors + bldg_design_loads.Cool_Walls +
1026
+ bldg_design_loads.Cool_Floors + bldg_design_loads.Cool_Ceilings +
1027
+ bldg_design_loads.Cool_Roofs + bldg_design_loads.Cool_Infil_Sens +
1028
+ bldg_design_loads.Cool_IntGains_Sens
1029
+ bldg_design_loads.Cool_Lat = bldg_design_loads.Cool_Infil_Lat + bldg_design_loads.Cool_IntGains_Lat
1030
+ if bldg_design_loads.Cool_Lat < 0 # No latent loads; also zero out individual components
1031
+ bldg_design_loads.Cool_Lat = 0.0
1032
+ bldg_design_loads.Cool_Infil_Lat = 0.0
1033
+ bldg_design_loads.Cool_IntGains_Lat = 0.0
1034
+ end
1035
+ bldg_design_loads.Cool_Tot = bldg_design_loads.Cool_Sens + bldg_design_loads.Cool_Lat
1036
+
1037
+ # Initialize ducts
1038
+ bldg_design_loads.Heat_Ducts = 0.0
1039
+ bldg_design_loads.Cool_Ducts_Sens = 0.0
1040
+ bldg_design_loads.Cool_Ducts_Lat = 0.0
1041
+ end
1042
+
1043
+ def self.apply_hvac_temperatures(hvac, bldg_design_loads)
960
1044
  '''
961
1045
  HVAC Temperatures
962
1046
  '''
963
- # evap cooler temperature calculation based on Mannual S Figure 4-7
964
- if hvac.has_type(Constants.ObjectNameEvaporativeCooler)
1047
+ # Evaporative cooler temperature calculation based on Manual S Figure 4-7
1048
+ if hvac.CoolType == HPXML::HVACTypeEvaporativeCooler
965
1049
  td_potential = @cool_design_temps[HPXML::LocationOutside] - @wetbulb_outdoor_cooling
966
1050
  td = td_potential * hvac.EvapCoolerEffectiveness
967
1051
  hvac.LeavingAirTemp = @cool_design_temps[HPXML::LocationOutside] - td
968
1052
  else
969
1053
  # Calculate Leaving Air Temperature
970
- shr = [hvac_init_loads.Cool_Sens / hvac_init_loads.Cool_Tot, 1.0].min
1054
+ shr = [bldg_design_loads.Cool_Sens / bldg_design_loads.Cool_Tot, 1.0].min
971
1055
  # Determine the Leaving Air Temperature (LAT) based on Manual S Table 1-4
972
1056
  if shr < 0.80
973
1057
  hvac.LeavingAirTemp = 54.0 # F
@@ -981,42 +1065,46 @@ class HVACSizing
981
1065
  end
982
1066
 
983
1067
  # Calculate Supply Air Temperature
984
- if hvac.has_type(Constants.ObjectNameFurnace)
985
- hvac.SupplyAirTemp = 120.0 # F
986
- else
1068
+ if [HPXML::HVACTypeHeatPumpAirToAir,
1069
+ HPXML::HVACTypeHeatPumpMiniSplit,
1070
+ HPXML::HVACTypeHeatPumpGroundToAir,
1071
+ HPXML::HVACTypeHeatPumpWaterLoopToAir].include? hvac.HeatType
987
1072
  hvac.SupplyAirTemp = 105.0 # F
1073
+ else
1074
+ hvac.SupplyAirTemp = 120.0 # F
988
1075
  end
989
1076
  end
990
1077
 
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
1078
+ def self.apply_hvac_loads(hvac, hvac_sizing_values, bldg_design_loads)
1079
+ # Calculate design loads that this HVAC system serves
999
1080
 
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
1081
+ # Heating
1082
+ hvac_sizing_values.Heat_Load = bldg_design_loads.Heat_Tot * hvac.HeatingLoadFraction
1083
+ if hvac.HeatType == HPXML::HVACTypeHeatPumpWaterLoopToAir
1084
+ # Size to meet original fraction load served (not adjusted value from HVAC.apply_shared_heating_systems()
1085
+ # This ensures, e.g., that an appropriate heating airflow is used for duct losses.
1086
+ hvac_sizing_values.Heat_Load = hvac_sizing_values.Heat_Load / (1.0 / hvac.HeatingCOP)
1087
+ end
1088
+
1089
+ # Cooling
1090
+ hvac_sizing_values.Cool_Load_Tot = bldg_design_loads.Cool_Tot * hvac.CoolingLoadFraction
1091
+ hvac_sizing_values.Cool_Load_Sens = bldg_design_loads.Cool_Sens * hvac.CoolingLoadFraction
1092
+ hvac_sizing_values.Cool_Load_Lat = bldg_design_loads.Cool_Lat * hvac.CoolingLoadFraction
1005
1093
  end
1006
1094
 
1007
- def self.apply_hp_sizing_logic(hvac_init_loads, hvac)
1095
+ def self.apply_hvac_heat_pump_logic(hvac_sizing_values, hvac)
1008
1096
  # If true, uses the larger of heating and cooling loads for heat pump capacity sizing (required for ERI).
1009
1097
  # 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
1098
+ if [HPXML::HVACTypeHeatPumpAirToAir,
1099
+ HPXML::HVACTypeHeatPumpMiniSplit,
1100
+ HPXML::HVACTypeHeatPumpGroundToAir,
1101
+ HPXML::HVACTypeHeatPumpWaterLoopToAir].include? hvac.CoolType
1102
+ if @hpxml.header.use_max_load_for_heat_pumps && (hvac.CoolingLoadFraction > 0) && (hvac.HeatingLoadFraction > 0)
1103
+ max_load = [hvac_sizing_values.Heat_Load, hvac_sizing_values.Cool_Load_Tot].max
1104
+ hvac_sizing_values.Heat_Load = max_load
1105
+ hvac_sizing_values.Cool_Load_Sens *= max_load / hvac_sizing_values.Cool_Load_Tot
1106
+ hvac_sizing_values.Cool_Load_Lat *= max_load / hvac_sizing_values.Cool_Load_Tot
1107
+ hvac_sizing_values.Cool_Load_Tot = max_load
1020
1108
 
1021
1109
  # Override Manual S oversize allowances:
1022
1110
  hvac.OverSizeLimit = 1.0
@@ -1095,137 +1183,129 @@ class HVACSizing
1095
1183
  return dse_Fregain
1096
1184
  end
1097
1185
 
1098
- def self.process_duct_loads_heating(hvac_final_values, weather, hvac, init_heat_load)
1186
+ def self.apply_load_ducts_heating(bldg_design_loads, weather, hvac)
1099
1187
  '''
1100
1188
  Heating Duct Loads
1101
1189
  '''
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
1190
 
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)
1191
+ return if (bldg_design_loads.Heat_Tot == 0) || (hvac.HeatingLoadFraction == 0) || hvac.Ducts.empty?
1112
1192
 
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)
1193
+ init_heat_load = bldg_design_loads.Heat_Tot * hvac.HeatingLoadFraction
1122
1194
 
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))
1195
+ # Distribution system efficiency (DSE) calculations based on ASHRAE Standard 152
1196
+ dse_As, dse_Ar = calc_ducts_areas(hvac.Ducts)
1197
+ supply_r, return_r = calc_ducts_rvalues(hvac.Ducts)
1127
1198
 
1128
- for _iter in 0..19
1129
- break if delta.abs <= 0.001
1199
+ design_temp_values = { HPXML::DuctTypeSupply => @heat_design_temps, HPXML::DuctTypeReturn => @heat_design_temps }
1200
+ dse_Tamb_heating_s, dse_Tamb_heating_r = calc_ducts_area_weighted_average(hvac.Ducts, design_temp_values)
1130
1201
 
1131
- dse_Qs, dse_Qr = calc_ducts_leakages(hvac.Ducts, heat_cfm)
1202
+ # ASHRAE 152 6.5.2
1203
+ # For systems with ducts in several locations, F_regain shall be weighted by the fraction of exposed duct area
1204
+ # in each space. F_regain shall be calculated separately for supply and return locations.
1205
+ dse_Fregains = {}
1206
+ hvac.Ducts.each do |duct|
1207
+ dse_Fregains[duct.Location] = get_duct_regain_factor(duct)
1208
+ end
1209
+ fregain_values = { HPXML::DuctTypeSupply => dse_Fregains, HPXML::DuctTypeReturn => dse_Fregains }
1210
+ dse_Fregain_s, dse_Fregain_r = calc_ducts_area_weighted_average(hvac.Ducts, fregain_values)
1132
1211
 
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)
1212
+ # Initialize for the iteration
1213
+ delta = 1
1214
+ heat_load_next = init_heat_load
1134
1215
 
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
1216
+ for _iter in 0..19
1217
+ break if delta.abs <= 0.001
1137
1218
 
1138
- # Calculate the change since the last iteration
1139
- delta = (heatingLoad_Next - heatingLoad_Prev) / heatingLoad_Prev
1219
+ heat_load_prev = heat_load_next
1140
1220
 
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))
1221
+ # Calculate the new heating air flow rate
1222
+ heat_cfm = calc_airflow_rate(heat_load_next, (hvac.SupplyAirTemp - @heat_setpoint))
1144
1223
 
1145
- end
1224
+ dse_Qs, dse_Qr = calc_ducts_leakages(hvac.Ducts, heat_cfm)
1225
+
1226
+ 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
1227
 
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
1228
+ # Calculate the increase in heating load due to ducts (Approach: DE = Qload/Qequip -> Qducts = Qequip-Qload)
1229
+ heat_load_next = init_heat_load / dse_DE
1230
+
1231
+ # Calculate the change since the last iteration
1232
+ delta = (heat_load_next - heat_load_prev) / heat_load_prev
1149
1233
  end
1234
+
1235
+ ducts_heat_load = heat_load_next - init_heat_load
1236
+
1237
+ bldg_design_loads.Heat_Ducts += ducts_heat_load
1238
+ bldg_design_loads.Heat_Tot += ducts_heat_load
1150
1239
  end
1151
1240
 
1152
- def self.process_duct_loads_cooling(hvac_final_values, weather, hvac, init_cool_load_sens, init_cool_load_lat)
1241
+ def self.apply_load_ducts_cooling(bldg_design_loads, weather, hvac)
1153
1242
  '''
1154
1243
  Cooling Duct Loads
1155
1244
  '''
1245
+ return if (bldg_design_loads.Cool_Sens == 0) || (hvac.CoolingLoadFraction == 0) || hvac.Ducts.empty?
1156
1246
 
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)
1247
+ init_cool_load_sens = bldg_design_loads.Cool_Sens * hvac.CoolingLoadFraction
1248
+ init_cool_load_lat = bldg_design_loads.Cool_Lat * hvac.CoolingLoadFraction
1180
1249
 
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')
1250
+ # Distribution system efficiency (DSE) calculations based on ASHRAE Standard 152
1251
+ dse_As, dse_Ar = calc_ducts_areas(hvac.Ducts)
1252
+ supply_r, return_r = calc_ducts_rvalues(hvac.Ducts)
1183
1253
 
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
1254
+ design_temp_values = { HPXML::DuctTypeSupply => @cool_design_temps, HPXML::DuctTypeReturn => @cool_design_temps }
1255
+ dse_Tamb_cooling_s, dse_Tamb_cooling_r = calc_ducts_area_weighted_average(hvac.Ducts, design_temp_values)
1190
1256
 
1191
- initial_Cool_Airflow = calc_airflow_rate(init_cool_load_sens, (@cool_setpoint - hvac.LeavingAirTemp))
1257
+ # ASHRAE 152 6.5.2
1258
+ # For systems with ducts in several locations, F_regain shall be weighted by the fraction of exposed duct area
1259
+ # in each space. F_regain shall be calculated separately for supply and return locations.
1260
+ dse_Fregains = {}
1261
+ hvac.Ducts.each do |duct|
1262
+ dse_Fregains[duct.Location] = get_duct_regain_factor(duct)
1263
+ end
1264
+ fregain_values = { HPXML::DuctTypeSupply => dse_Fregains, HPXML::DuctTypeReturn => dse_Fregains }
1265
+ dse_Fregain_s, dse_Fregain_r = calc_ducts_area_weighted_average(hvac.Ducts, fregain_values)
1192
1266
 
1193
- supply_leakage_cfm, return_leakage_cfm = calc_ducts_leakages(hvac.Ducts, initial_Cool_Airflow)
1267
+ # Calculate the air enthalpy in the return duct location for DSE calculations
1268
+ 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
1269
 
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)
1270
+ # Initialize for the iteration
1271
+ delta = 1
1272
+ cool_load_tot_next = init_cool_load_sens + init_cool_load_lat
1196
1273
 
1197
- for _iter in 1..50
1198
- break if delta.abs <= 0.001
1274
+ cool_cfm = calc_airflow_rate(init_cool_load_sens, (@cool_setpoint - hvac.LeavingAirTemp))
1275
+ dse_Qs, dse_Qr = calc_ducts_leakages(hvac.Ducts, cool_cfm)
1199
1276
 
1200
- coolingLoad_Tot_Prev = coolingLoad_Tot_Next
1277
+ for _iter in 1..50
1278
+ break if delta.abs <= 0.001
1201
1279
 
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
1280
+ cool_load_tot_prev = cool_load_tot_next
1204
1281
 
1205
- # Calculate the new cooling air flow rate
1206
- cool_Airflow = calc_airflow_rate(hvac_final_values.Cool_Load_Sens, (@cool_setpoint - hvac.LeavingAirTemp))
1282
+ cool_load_lat, cool_load_sens = calculate_sensible_latent_split(dse_Qr, cool_load_tot_next, init_cool_load_lat)
1283
+ cool_load_tot = cool_load_lat + cool_load_sens
1207
1284
 
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)
1285
+ # Calculate the new cooling air flow rate
1286
+ cool_cfm = calc_airflow_rate(cool_load_sens, (@cool_setpoint - hvac.LeavingAirTemp))
1210
1287
 
1211
- dse_Qs, dse_Qr = calc_ducts_leakages(hvac.Ducts, cool_Airflow)
1288
+ dse_Qs, dse_Qr = calc_ducts_leakages(hvac.Ducts, cool_cfm)
1212
1289
 
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)
1290
+ 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
1291
 
1215
- coolingLoad_Tot_Next = (init_cool_load_sens + init_cool_load_lat) / dse_DE
1292
+ cool_load_tot_next = (init_cool_load_sens + init_cool_load_lat) / dse_DE
1216
1293
 
1217
- # Calculate the change since the last iteration
1218
- delta = (coolingLoad_Tot_Next - coolingLoad_Tot_Prev) / coolingLoad_Tot_Prev
1219
- end
1294
+ # Calculate the change since the last iteration
1295
+ delta = (cool_load_tot_next - cool_load_tot_prev) / cool_load_tot_prev
1220
1296
  end
1221
1297
 
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))
1298
+ ducts_cool_load_sens = cool_load_sens - init_cool_load_sens
1299
+ ducts_cool_load_lat = cool_load_lat - init_cool_load_lat
1224
1300
 
1225
- hvac_final_values.Cool_Load_Ducts_Lat = hvac_final_values.Cool_Load_Ducts_Tot - hvac_final_values.Cool_Load_Ducts_Sens
1301
+ bldg_design_loads.Cool_Ducts_Sens += ducts_cool_load_sens
1302
+ bldg_design_loads.Cool_Sens += ducts_cool_load_sens
1303
+ bldg_design_loads.Cool_Ducts_Lat += ducts_cool_load_lat
1304
+ bldg_design_loads.Cool_Lat += ducts_cool_load_lat
1305
+ bldg_design_loads.Cool_Tot += ducts_cool_load_sens + ducts_cool_load_lat
1226
1306
  end
1227
1307
 
1228
- def self.process_equipment_adjustments(hvac_final_values, weather, hvac)
1308
+ def self.apply_hvac_equipment_adjustments(hvac_sizing_values, weather, hvac, cfa)
1229
1309
  '''
1230
1310
  Equipment Adjustments
1231
1311
  '''
@@ -1233,458 +1313,659 @@ class HVACSizing
1233
1313
  underSizeLimit = 0.9
1234
1314
 
1235
1315
  # Cooling
1236
- if hvac.has_type([Constants.ObjectNameCentralAirConditioner,
1237
- Constants.ObjectNameAirSourceHeatPump,
1238
- Constants.ObjectNameMiniSplitHeatPump,
1239
- Constants.ObjectNameRoomAirConditioner,
1240
- Constants.ObjectNameGroundSourceHeatPump])
1241
1316
 
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
1317
+ # Calculate the air flow rate required for design conditions
1318
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(hvac_sizing_values.Cool_Load_Sens, (@cool_setpoint - hvac.LeavingAirTemp))
1247
1319
 
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
1320
+ if hvac_sizing_values.Cool_Load_Tot <= 0
1254
1321
 
1255
- if hvac.has_type([Constants.ObjectNameCentralAirConditioner,
1256
- Constants.ObjectNameAirSourceHeatPump])
1322
+ hvac_sizing_values.Cool_Capacity = 0.0
1323
+ hvac_sizing_values.Cool_Capacity_Sens = 0.0
1324
+ hvac_sizing_values.Cool_Airflow = 0.0
1257
1325
 
1258
- hvac.SizingSpeed = get_sizing_speed(hvac)
1259
- coefficients = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed]
1326
+ elsif [HPXML::HVACTypeCentralAirConditioner,
1327
+ HPXML::HVACTypeHeatPumpAirToAir].include? hvac.CoolType
1260
1328
 
1261
- totalCap_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, enteringTemp, coefficients)
1262
- coolCap_Rated = hvac_final_values.Cool_Load_Tot / totalCap_CurveValue
1329
+ enteringTemp = weather.design.CoolingDrybulb
1330
+ coefficients = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed]
1263
1331
 
1264
- sensCap_Rated = coolCap_Rated * hvac.SHRRated[hvac.SizingSpeed]
1332
+ totalCap_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, enteringTemp, coefficients)
1333
+ coolCap_Rated = hvac_sizing_values.Cool_Load_Tot / totalCap_CurveValue
1265
1334
 
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
1335
+ sensCap_Rated = coolCap_Rated * hvac.SHRRated[hvac.SizingSpeed]
1269
1336
 
1270
- a_sens = @shr_biquadratic[0]
1271
- b_sens = @shr_biquadratic[1]
1272
- c_sens = @shr_biquadratic[3]
1273
- d_sens = @shr_biquadratic[5]
1337
+ sensibleCap_CurveValue = process_curve_fit(hvac_sizing_values.Cool_Airflow, hvac_sizing_values.Cool_Load_Tot, enteringTemp)
1338
+ sensCap_Design = sensCap_Rated * sensibleCap_CurveValue
1339
+ latCap_Design = [hvac_sizing_values.Cool_Load_Tot - sensCap_Design, 1.0].max
1274
1340
 
1275
- # Adjust Sizing
1276
- if latCap_Design < hvac_final_values.Cool_Load_Lat
1277
- # Size by MJ8 Latent load, return to rated conditions
1341
+ shr_biquadratic = get_shr_biquadratic
1342
+ a_sens = shr_biquadratic[0]
1343
+ b_sens = shr_biquadratic[1]
1344
+ c_sens = shr_biquadratic[3]
1345
+ d_sens = shr_biquadratic[5]
1278
1346
 
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))
1347
+ # Adjust Sizing
1348
+ if latCap_Design < hvac_sizing_values.Cool_Load_Lat
1349
+ # Size by MJ8 Latent load, return to rated conditions
1283
1350
 
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)
1351
+ # Solve for the new sensible and total capacity at design conditions:
1352
+ # CoolingLoad_Lat = cool_Capacity_Design - cool_Load_SensCap_Design
1353
+ # solve the following for cool_Capacity_Design: SensCap_Design = SHRRated * cool_Capacity_Design / TotalCap_CurveValue * function(CFM/cool_Capacity_Design, ODB)
1354
+ # substituting in CFM = cool_Load_SensCap_Design / (1.1 * ACF * (cool_setpoint - LAT))
1288
1355
 
1289
- cool_Capacity_Design = cool_Load_SensCap_Design + hvac_final_values.Cool_Load_Lat
1356
+ cool_Load_SensCap_Design = hvac_sizing_values.Cool_Load_Lat / ((totalCap_CurveValue / hvac.SHRRated[hvac.SizingSpeed] - \
1357
+ (UnitConversions.convert(b_sens, 'ton', 'Btu/hr') + UnitConversions.convert(d_sens, 'ton', 'Btu/hr') * enteringTemp) / \
1358
+ (1.1 * @acf * (@cool_setpoint - hvac.LeavingAirTemp))) / \
1359
+ (a_sens + c_sens * enteringTemp) - 1.0)
1290
1360
 
1291
- # The SHR of the equipment at the design condition
1292
- sHR_design = cool_Load_SensCap_Design / cool_Capacity_Design
1361
+ cool_Capacity_Design = cool_Load_SensCap_Design + hvac_sizing_values.Cool_Load_Lat
1293
1362
 
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
1363
+ # The SHR of the equipment at the design condition
1364
+ sHR_design = cool_Load_SensCap_Design / cool_Capacity_Design
1299
1365
 
1300
- # Limit total capacity to oversize limit
1301
- cool_Capacity_Design = [cool_Capacity_Design, hvac.OverSizeLimit * hvac_final_values.Cool_Load_Tot].min
1366
+ # If the adjusted equipment size is negative (occurs at altitude), use oversize limit (the adjustment
1367
+ # almost always hits the oversize limit in this case, making this a safe assumption)
1368
+ if (cool_Capacity_Design < 0) || (cool_Load_SensCap_Design < 0)
1369
+ cool_Capacity_Design = hvac.OverSizeLimit * hvac_sizing_values.Cool_Load_Tot
1370
+ end
1302
1371
 
1303
- # Determine the final sensible capacity at design using the SHR
1304
- cool_Load_SensCap_Design = sHR_design * cool_Capacity_Design
1372
+ # Limit total capacity to oversize limit
1373
+ cool_Capacity_Design = [cool_Capacity_Design, hvac.OverSizeLimit * hvac_sizing_values.Cool_Load_Tot].min
1305
1374
 
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))
1375
+ # Determine the final sensible capacity at design using the SHR
1376
+ cool_Load_SensCap_Design = sHR_design * cool_Capacity_Design
1308
1377
 
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]
1378
+ # Calculate the final air flow rate using final sensible capacity at design
1379
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1312
1380
 
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
1381
+ # Determine rated capacities
1382
+ hvac_sizing_values.Cool_Capacity = cool_Capacity_Design / totalCap_CurveValue
1383
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1316
1384
 
1317
- sensCap_Design = underSizeLimit * hvac_final_values.Cool_Load_Sens
1385
+ elsif sensCap_Design < underSizeLimit * hvac_sizing_values.Cool_Load_Sens
1386
+ # Size by MJ8 Sensible load, return to rated conditions, find Sens with SHRRated. Limit total
1387
+ # capacity to oversizing limit
1318
1388
 
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)
1389
+ sensCap_Design = underSizeLimit * hvac_sizing_values.Cool_Load_Sens
1323
1390
 
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)
1391
+ # Solve for the new total system capacity at design conditions:
1392
+ # SensCap_Design = SensCap_Rated * SensibleCap_CurveValue
1393
+ # = SHRRated * cool_Capacity_Design / TotalCap_CurveValue * SensibleCap_CurveValue
1394
+ # = SHRRated * cool_Capacity_Design / TotalCap_CurveValue * function(CFM/cool_Capacity_Design, ODB)
1328
1395
 
1329
- # Limit total capacity to oversize limit
1330
- cool_Capacity_Design = [cool_Capacity_Design, hvac.OverSizeLimit * hvac_final_values.Cool_Load_Tot].min
1396
+ cool_Capacity_Design = (sensCap_Design / (hvac.SHRRated[hvac.SizingSpeed] / totalCap_CurveValue) - \
1397
+ (b_sens * UnitConversions.convert(hvac_sizing_values.Cool_Airflow, 'ton', 'Btu/hr') + \
1398
+ d_sens * UnitConversions.convert(hvac_sizing_values.Cool_Airflow, 'ton', 'Btu/hr') * enteringTemp)) / \
1399
+ (a_sens + c_sens * enteringTemp)
1331
1400
 
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]
1401
+ # Limit total capacity to oversize limit
1402
+ cool_Capacity_Design = [cool_Capacity_Design, hvac.OverSizeLimit * hvac_sizing_values.Cool_Load_Tot].min
1334
1403
 
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))
1404
+ hvac_sizing_values.Cool_Capacity = cool_Capacity_Design / totalCap_CurveValue
1405
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1338
1406
 
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]
1407
+ # Recalculate the air flow rate in case the oversizing limit has been used
1408
+ cool_Load_SensCap_Design = hvac_sizing_values.Cool_Capacity_Sens * sensibleCap_CurveValue
1409
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1342
1410
 
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
1411
+ else
1412
+ hvac_sizing_values.Cool_Capacity = hvac_sizing_values.Cool_Load_Tot / totalCap_CurveValue
1413
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1346
1414
 
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
1415
+ cool_Load_SensCap_Design = hvac_sizing_values.Cool_Capacity_Sens * sensibleCap_CurveValue
1416
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1417
+ end
1354
1418
 
1355
- elsif hvac.has_type(Constants.ObjectNameMiniSplitHeatPump)
1419
+ # Ensure the air flow rate is in between 200 and 500 cfm/ton.
1420
+ # Reset the air flow rate (with a safety margin), if required.
1421
+ if hvac_sizing_values.Cool_Airflow / UnitConversions.convert(hvac_sizing_values.Cool_Capacity, 'Btu/hr', 'ton') > 500
1422
+ hvac_sizing_values.Cool_Airflow = 499.0 * UnitConversions.convert(hvac_sizing_values.Cool_Capacity, 'Btu/hr', 'ton') # CFM
1423
+ elsif hvac_sizing_values.Cool_Airflow / UnitConversions.convert(hvac_sizing_values.Cool_Capacity, 'Btu/hr', 'ton') < 200
1424
+ hvac_sizing_values.Cool_Airflow = 201.0 * UnitConversions.convert(hvac_sizing_values.Cool_Capacity, 'Btu/hr', 'ton') # CFM
1425
+ end
1356
1426
 
1357
- hvac.SizingSpeed = get_sizing_speed(hvac)
1358
- coefficients = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed]
1427
+ elsif [HPXML::HVACTypeHeatPumpMiniSplit,
1428
+ HPXML::HVACTypeMiniSplitAirConditioner].include? hvac.CoolType
1359
1429
 
1360
- totalCap_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, enteringTemp, coefficients)
1430
+ enteringTemp = weather.design.CoolingDrybulb
1431
+ coefficients = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed]
1361
1432
 
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')
1433
+ totalCap_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, enteringTemp, coefficients)
1365
1434
 
1366
- elsif hvac.has_type(Constants.ObjectNameRoomAirConditioner)
1435
+ hvac_sizing_values.Cool_Capacity = (hvac_sizing_values.Cool_Load_Tot / totalCap_CurveValue)
1436
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1437
+ # FIXME: Why not use calc_airflow_rate?
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
+ # FIXME: Why not use calc_airflow_rate?
1448
+ hvac_sizing_values.Cool_Airflow = hvac.RatedCFMperTonCooling[hvac.SizingSpeed] * UnitConversions.convert(hvac_sizing_values.Cool_Capacity, 'Btu/hr', 'ton')
1376
1449
 
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])
1450
+ elsif hvac.CoolType == HPXML::HVACTypeHeatPumpGroundToAir
1451
+ coil_bf = gshp_coil_bf
1452
+ enteringTemp = hvac.GSHP_design_chw
1382
1453
 
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]
1454
+ # Neglecting the water flow rate for now because it's not available yet. Air flow rate is pre-adjusted values.
1455
+ design_wb_temp = UnitConversions.convert(@wetbulb_indoor_cooling, 'f', 'k')
1456
+ design_db_temp = UnitConversions.convert(@cool_setpoint, 'f', 'k')
1457
+ design_w_temp = UnitConversions.convert(enteringTemp, 'f', 'k')
1458
+ design_vfr_air = UnitConversions.convert(hvac_sizing_values.Cool_Airflow, 'cfm', 'm^3/s')
1385
1459
 
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
1460
+ totalCap_CurveValue, sensibleCap_CurveValue = calc_gshp_clg_curve_value(hvac, design_wb_temp, design_db_temp, design_w_temp, design_vfr_air, nil)
1390
1461
 
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
1462
+ bypassFactor_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, @cool_setpoint, gshp_coil_bf_ft_spec)
1395
1463
 
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]
1464
+ hvac_sizing_values.Cool_Capacity = hvac_sizing_values.Cool_Load_Tot / totalCap_CurveValue # Note: cool_Capacity_Design = hvac_sizing_values.Cool_Load_Tot
1465
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1400
1466
 
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
1467
+ cool_Load_SensCap_Design = (hvac_sizing_values.Cool_Capacity_Sens * sensibleCap_CurveValue /
1468
+ (1.0 + (1.0 - coil_bf * bypassFactor_CurveValue) *
1469
+ (80.0 - @cool_setpoint) / (@cool_setpoint - hvac.LeavingAirTemp)))
1470
+ cool_Load_LatCap_Design = hvac_sizing_values.Cool_Load_Tot - cool_Load_SensCap_Design
1407
1471
 
1408
- fail 'Unexpected cooling system.'
1409
- end
1472
+ # Adjust Sizing so that coil sensible at design >= CoolingLoad_MJ8_Sens, and coil latent at design >= CoolingLoad_MJ8_Lat, and equipment SHRRated is maintained.
1473
+ cool_Load_SensCap_Design = [cool_Load_SensCap_Design, hvac_sizing_values.Cool_Load_Sens].max
1474
+ cool_Load_LatCap_Design = [cool_Load_LatCap_Design, hvac_sizing_values.Cool_Load_Lat].max
1475
+ cool_Capacity_Design = cool_Load_SensCap_Design + cool_Load_LatCap_Design
1410
1476
 
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
1477
+ # Limit total capacity via oversizing limit
1478
+ cool_Capacity_Design = [cool_Capacity_Design, hvac.OverSizeLimit * hvac_sizing_values.Cool_Load_Tot].min
1479
+ hvac_sizing_values.Cool_Capacity = cool_Capacity_Design / totalCap_CurveValue
1480
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1481
+
1482
+ # Recalculate the air flow rate in case the oversizing limit has been used
1483
+ cool_Load_SensCap_Design = (hvac_sizing_values.Cool_Capacity_Sens * sensibleCap_CurveValue /
1484
+ (1.0 + (1.0 - coil_bf * bypassFactor_CurveValue) *
1485
+ (80.0 - @cool_setpoint) / (@cool_setpoint - hvac.LeavingAirTemp)))
1486
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1487
+
1488
+ elsif hvac.CoolType == HPXML::HVACTypeEvaporativeCooler
1489
+
1490
+ hvac_sizing_values.Cool_Capacity = hvac_sizing_values.Cool_Load_Tot
1491
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Load_Sens
1414
1492
  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))
1493
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(hvac_sizing_values.Cool_Load_Sens, (@cool_setpoint - hvac.LeavingAirTemp))
1416
1494
  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
1495
+ hvac_sizing_values.Cool_Airflow = cfa * 2.0 # Use industry rule of thumb sizing method adopted by HEScore
1419
1496
  end
1420
1497
 
1421
- elsif hvac.has_type(Constants.ObjectNameWaterLoopHeatPump)
1498
+ elsif hvac.CoolType == HPXML::HVACTypeHeatPumpWaterLoopToAir
1499
+
1422
1500
  # 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
1501
+ hvac_sizing_values.Cool_Capacity = 0.0
1502
+ hvac_sizing_values.Cool_Capacity_Sens = 0.0
1503
+ hvac_sizing_values.Cool_Airflow = 0.0
1504
+
1505
+ elsif hvac.CoolType.nil?
1506
+
1507
+ hvac_sizing_values.Cool_Capacity = 0.0
1508
+ hvac_sizing_values.Cool_Capacity_Sens = 0.0
1509
+ hvac_sizing_values.Cool_Airflow = 0.0
1426
1510
 
1427
1511
  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
1512
+
1513
+ fail "Unexpected cooling type: #{hvac.CoolType}."
1431
1514
 
1432
1515
  end
1433
1516
 
1434
1517
  # Heating
1435
- if hvac.has_type(Constants.ObjectNameAirSourceHeatPump)
1436
- hvac_final_values = process_heat_pump_adjustment(hvac_final_values, weather, hvac, totalCap_CurveValue)
1518
+ if hvac_sizing_values.Heat_Load <= 0
1437
1519
 
1438
- hvac_final_values.Heat_Capacity = hvac_final_values.Cool_Capacity
1439
- hvac_final_values.Heat_Capacity_Supp = hvac_final_values.Heat_Load
1520
+ hvac_sizing_values.Heat_Capacity = 0.0
1521
+ hvac_sizing_values.Heat_Capacity_Supp = 0.0
1522
+ hvac_sizing_values.Heat_Airflow = 0.0
1440
1523
 
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))
1524
+ elsif hvac.HeatType == HPXML::HVACTypeHeatPumpAirToAir
1525
+
1526
+ if hvac_sizing_values.Cool_Capacity > 0
1527
+ process_heat_pump_adjustment(hvac_sizing_values, weather, hvac, totalCap_CurveValue)
1528
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Cool_Capacity
1529
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Load
1443
1530
  else
1444
- hvac_final_values.Heat_Airflow = calc_airflow_rate(hvac_final_values.Heat_Capacity_Supp, (hvac.SupplyAirTemp - @heat_setpoint))
1531
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1532
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Load
1445
1533
  end
1534
+ hvac_sizing_values.Heat_Airflow = calc_airflow_rate(hvac_sizing_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1446
1535
 
1447
- elsif hvac.has_type(Constants.ObjectNameMiniSplitHeatPump)
1448
- hvac_final_values = process_heat_pump_adjustment(hvac_final_values, weather, hvac, totalCap_CurveValue)
1536
+ elsif hvac.HeatType == HPXML::HVACTypeHeatPumpMiniSplit
1449
1537
 
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
1538
+ if hvac_sizing_values.Cool_Capacity > 0
1539
+ process_heat_pump_adjustment(hvac_sizing_values, weather, hvac, totalCap_CurveValue)
1540
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Cool_Capacity
1541
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Load
1542
+ else
1543
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1544
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Load
1545
+ end
1546
+ # FIXME: Why not use calc_airflow_rate?
1547
+ 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
1548
 
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
1549
+ elsif hvac.HeatType == HPXML::HVACTypeHeatPumpGroundToAir
1454
1550
 
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
1551
+ if hvac_sizing_values.Cool_Capacity > 0
1552
+ coil_bf = gshp_coil_bf
1553
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1554
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Load
1458
1555
 
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
1556
+ # For single stage compressor, when heating capacity is much larger than cooling capacity,
1557
+ # in order to avoid frequent cycling in cooling mode, heating capacity is derated to 75%.
1558
+ if hvac_sizing_values.Heat_Capacity >= 1.5 * hvac_sizing_values.Cool_Capacity
1559
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load * 0.75
1560
+ elsif hvac_sizing_values.Heat_Capacity < hvac_sizing_values.Cool_Capacity
1561
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Capacity
1562
+ end
1563
+
1564
+ hvac_sizing_values.Cool_Capacity = [hvac_sizing_values.Cool_Capacity, hvac_sizing_values.Heat_Capacity].max
1565
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Cool_Capacity
1566
+
1567
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1568
+ cool_Load_SensCap_Design = (hvac_sizing_values.Cool_Capacity_Sens * sensibleCap_CurveValue /
1569
+ (1.0 + (1.0 - coil_bf * bypassFactor_CurveValue) *
1570
+ (80.0 - @cool_setpoint) / (@cool_setpoint - hvac.LeavingAirTemp)))
1571
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1572
+ else
1573
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1574
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Load
1465
1575
  end
1576
+ hvac_sizing_values.Heat_Airflow = calc_airflow_rate(hvac_sizing_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1466
1577
 
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
1578
+ elsif hvac.HeatType == HPXML::HVACTypeHeatPumpWaterLoopToAir
1469
1579
 
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))
1580
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1581
+ hvac_sizing_values.Heat_Capacity_Supp = hvac_sizing_values.Heat_Load
1476
1582
 
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
1583
+ hvac_sizing_values.Heat_Airflow = calc_airflow_rate(hvac_sizing_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1480
1584
 
1481
- hvac_final_values.Heat_Airflow = calc_airflow_rate(hvac_final_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1585
+ elsif hvac.HeatType == HPXML::HVACTypeFurnace
1482
1586
 
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
1587
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1588
+ hvac_sizing_values.Heat_Capacity_Supp = 0.0
1486
1589
 
1487
- hvac_final_values.Heat_Airflow = calc_airflow_rate(hvac_final_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1590
+ hvac_sizing_values.Heat_Airflow = calc_airflow_rate(hvac_sizing_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1488
1591
 
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
1592
+ elsif [HPXML::HVACTypeStove,
1593
+ HPXML::HVACTypePortableHeater,
1594
+ HPXML::HVACTypeFixedHeater,
1595
+ HPXML::HVACTypeWallFurnace,
1596
+ HPXML::HVACTypeFloorFurnace,
1597
+ HPXML::HVACTypeFireplace].include? hvac.HeatType
1598
+
1599
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1600
+ hvac_sizing_values.Heat_Capacity_Supp = 0.0
1492
1601
 
1493
1602
  if hvac.RatedCFMperTonHeating[0] > 0
1494
1603
  # Fixed airflow rate
1495
- hvac_final_values.Heat_Airflow = UnitConversions.convert(hvac_final_values.Heat_Capacity, 'Btu/hr', 'ton') * hvac.RatedCFMperTonHeating[0]
1604
+ # FIXME: Is this still needed?
1605
+ hvac_sizing_values.Heat_Airflow = UnitConversions.convert(hvac_sizing_values.Heat_Capacity, 'Btu/hr', 'ton') * hvac.RatedCFMperTonHeating[0]
1496
1606
  else
1497
1607
  # Autosized airflow rate
1498
- hvac_final_values.Heat_Airflow = calc_airflow_rate(hvac_final_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1608
+ hvac_sizing_values.Heat_Airflow = calc_airflow_rate(hvac_sizing_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1499
1609
  end
1500
1610
 
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
1611
+ elsif [HPXML::HVACTypeBoiler,
1612
+ HPXML::HVACTypeElectricResistance].include? hvac.HeatType
1613
+
1614
+ hvac_sizing_values.Heat_Capacity = hvac_sizing_values.Heat_Load
1615
+ hvac_sizing_values.Heat_Capacity_Supp = 0.0
1616
+ hvac_sizing_values.Heat_Airflow = 0.0
1617
+
1618
+ elsif hvac.HeatType.nil?
1619
+
1620
+ hvac_sizing_values.Heat_Capacity = 0.0
1621
+ hvac_sizing_values.Heat_Capacity_Supp = 0.0
1622
+ hvac_sizing_values.Heat_Airflow = 0.0
1506
1623
 
1507
1624
  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
1625
+
1626
+ fail "Unexpected heating type: #{hvac.HeatType}."
1511
1627
 
1512
1628
  end
1513
1629
  end
1514
1630
 
1515
- def self.process_fixed_equipment(hvac_final_values, hvac)
1631
+ def self.apply_hvac_installation_quality(hvac_sizing_values, weather, hvac)
1632
+ # Increases the autosized heating/cooling capacities to account for any reduction
1633
+ # in capacity due to HVAC installation quality. This is done to prevent causing
1634
+ # unmet loads.
1635
+
1636
+ return unless [HPXML::HVACTypeCentralAirConditioner,
1637
+ HPXML::HVACTypeHeatPumpAirToAir,
1638
+ HPXML::HVACTypeHeatPumpMiniSplit,
1639
+ HPXML::HVACTypeMiniSplitAirConditioner,
1640
+ HPXML::HVACTypeHeatPumpGroundToAir].include? hvac.CoolType
1641
+ return if (hvac.ChargeDefectRatio.to_f.abs < 0.001) && (hvac.AirflowDefectRatioCooling.to_f.abs < 0.001) && (hvac.AirflowDefectRatioHeating.to_f.abs < 0.001)
1642
+
1643
+ tin_cool = UnitConversions.convert(@cool_setpoint, 'F', 'C')
1644
+ tin_heat = UnitConversions.convert(@heat_setpoint, 'F', 'C')
1645
+
1646
+ tout_cool = UnitConversions.convert(weather.design.CoolingDrybulb, 'F', 'C')
1647
+ tout_heat = UnitConversions.convert(weather.design.HeatingDrybulb, 'F', 'C')
1648
+
1649
+ if hvac.CoolType == HPXML::HVACTypeHeatPumpGroundToAir
1650
+ if hvac.CoolingLoadFraction > 0
1651
+ # Cooling
1652
+ coil_bf = gshp_coil_bf
1653
+ # Calculate curve point w/ and w/o defect ratios
1654
+ design_wb_temp = UnitConversions.convert(@wetbulb_indoor_cooling, 'f', 'k')
1655
+ design_db_temp = UnitConversions.convert(@cool_setpoint, 'f', 'k')
1656
+ design_w_temp = UnitConversions.convert(hvac.GSHP_design_chw, 'f', 'k')
1657
+ design_vfr_air = UnitConversions.convert(hvac_sizing_values.Cool_Airflow, 'cfm', 'm^3/s')
1658
+ design_vfr_air_defect = UnitConversions.convert(hvac_sizing_values.Cool_Airflow, 'cfm', 'm^3/s') * (1 + hvac.AirflowDefectRatioCooling)
1659
+ # calculate water flow based on current capacity.
1660
+ loop_flow = [1.0, UnitConversions.convert([hvac_sizing_values.Heat_Capacity, hvac_sizing_values.Cool_Capacity].max, 'Btu/hr', 'ton')].max.floor * 3.0
1661
+ loop_flow_m3s = UnitConversions.convert(loop_flow, 'gal/min', 'm^3/s')
1662
+
1663
+ 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)
1664
+ 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)
1665
+
1666
+ cap_clg_ratio = 1 / (totalCap_CurveValue_d / totalCap_CurveValue)
1667
+ if cap_clg_ratio > 1
1668
+ hvac_sizing_values.Cool_Capacity *= cap_clg_ratio
1669
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1670
+ bypassFactor_CurveValue = MathTools.biquadratic(@wetbulb_indoor_cooling, @cool_setpoint, gshp_coil_bf_ft_spec)
1671
+
1672
+ cool_Load_SensCap_Design = (hvac_sizing_values.Cool_Capacity_Sens * sensibleCap_CurveValue /
1673
+ (1.0 + (1.0 - coil_bf * bypassFactor_CurveValue) *
1674
+ (80.0 - @cool_setpoint) / (@cool_setpoint - hvac.LeavingAirTemp)))
1675
+ hvac_sizing_values.Cool_Airflow = calc_airflow_rate(cool_Load_SensCap_Design, (@cool_setpoint - hvac.LeavingAirTemp))
1676
+ end
1677
+ end
1678
+
1679
+ # Heating
1680
+ if hvac.HeatingLoadFraction > 0
1681
+ # Calculate curve point w/ and w/o defect ratios
1682
+ design_db_temp = UnitConversions.convert(@heat_setpoint, 'f', 'k')
1683
+ design_w_temp = UnitConversions.convert(hvac.GSHP_design_chw, 'f', 'k')
1684
+ design_vfr_air = UnitConversions.convert(hvac_sizing_values.Heat_Airflow, 'cfm', 'm^3/s')
1685
+ design_vfr_air_defect = UnitConversions.convert(hvac_sizing_values.Heat_Airflow, 'cfm', 'm^3/s') * (1 + hvac.AirflowDefectRatioHeating)
1686
+ # calculate water flow based on current capacity.
1687
+ loop_flow = [1.0, UnitConversions.convert([hvac_sizing_values.Heat_Capacity, hvac_sizing_values.Cool_Capacity].max, 'Btu/hr', 'ton')].max.floor * 3.0
1688
+ loop_flow_m3s = UnitConversions.convert(loop_flow, 'gal/min', 'm^3/s')
1689
+
1690
+ totalCap_CurveValue = calc_gshp_htg_curve_value(hvac, design_db_temp, design_w_temp, design_vfr_air, loop_flow_m3s)
1691
+ totalCap_CurveValue_d = calc_gshp_htg_curve_value(hvac, design_db_temp, design_w_temp, design_vfr_air_defect, loop_flow_m3s)
1692
+
1693
+ cap_htg_ratio = 1 / (totalCap_CurveValue_d / totalCap_CurveValue)
1694
+ if cap_htg_ratio > 1
1695
+ hvac_sizing_values.Heat_Capacity *= cap_htg_ratio
1696
+ hvac_sizing_values.Heat_Airflow = calc_airflow_rate(hvac_sizing_values.Heat_Capacity, (hvac.SupplyAirTemp - @heat_setpoint))
1697
+ end
1698
+ end
1699
+ else
1700
+ f_ch = hvac.ChargeDefectRatio.round(3)
1701
+
1702
+ # Cooling
1703
+ if [HPXML::HVACTypeHeatPumpAirToAir,
1704
+ HPXML::HVACTypeCentralAirConditioner,
1705
+ HPXML::HVACTypeHeatPumpMiniSplit,
1706
+ HPXML::HVACTypeMiniSplitAirConditioner].include?(hvac.CoolType) && hvac.CoolingLoadFraction > 0
1707
+ cool_airflow_rated_defect_ratio = []
1708
+ cool_airflow_rated_ratio = []
1709
+ cool_cfm_m3s = UnitConversions.convert(hvac_sizing_values.Cool_Airflow, 'cfm', 'm^3/s')
1710
+ for speed in 0..(hvac.NumSpeedsCooling - 1)
1711
+ cool_airflow_rated_ratio << cool_cfm_m3s / HVAC.calc_rated_airflow(hvac_sizing_values.Cool_Capacity, hvac.RatedCFMperTonCooling[speed], hvac.CapacityRatioCooling[speed])
1712
+ 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])
1713
+ end
1714
+ if not cool_airflow_rated_defect_ratio.empty?
1715
+ cap_clg_ratios = []
1716
+ for speed in 0..(hvac.NumSpeedsCooling - 1)
1717
+ # NOTE: heat pump (cooling) curves don't exhibit expected trends at extreme faults;
1718
+ a1_AF_Qgr_c = hvac.COOL_CAP_FFLOW_SPEC[speed][0]
1719
+ a2_AF_Qgr_c = hvac.COOL_CAP_FFLOW_SPEC[speed][1]
1720
+ a3_AF_Qgr_c = hvac.COOL_CAP_FFLOW_SPEC[speed][2]
1721
+
1722
+ p_values, qgr_values, ff_chg_values = HVAC.get_installation_quality_cooling_coeff(f_ch)
1723
+
1724
+ a1_CH_Qgr_c = qgr_values[0]
1725
+ a2_CH_Qgr_c = qgr_values[1]
1726
+ a3_CH_Qgr_c = qgr_values[2]
1727
+ a4_CH_Qgr_c = qgr_values[3]
1728
+
1729
+ 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)
1730
+
1731
+ q0_CH = a1_CH_Qgr_c
1732
+ q1_CH = a2_CH_Qgr_c * tin_cool
1733
+ q2_CH = a3_CH_Qgr_c * tout_cool
1734
+ q3_CH = a4_CH_Qgr_c * f_ch
1735
+ y_CH_Q_c = 1 + ((q0_CH + q1_CH + q2_CH + q3_CH) * f_ch)
1736
+
1737
+ q0_AF_CH = a1_AF_Qgr_c
1738
+ q1_AF_CH = a2_AF_Qgr_c * ff_ch_c
1739
+ q2_AF_CH = a3_AF_Qgr_c * ff_ch_c * ff_ch_c
1740
+ p_CH_Q_c = y_CH_Q_c / (q0_AF_CH + q1_AF_CH + q2_AF_CH)
1741
+
1742
+ ff_AF_c = cool_airflow_rated_defect_ratio[speed].round(3)
1743
+ ff_AF_c_nodefect = cool_airflow_rated_ratio[speed].round(3)
1744
+ ff_AF_comb_c = ff_ch_c * ff_AF_c
1745
+
1746
+ q0_AF_comb = a1_AF_Qgr_c
1747
+ q1_AF_comb = a2_AF_Qgr_c * ff_AF_comb_c
1748
+ q2_AF_comb = a3_AF_Qgr_c * ff_AF_comb_c * ff_AF_comb_c
1749
+ p_AF_Q_c = q0_AF_comb + q1_AF_comb + q2_AF_comb
1750
+
1751
+ cool_cap_fff = (p_CH_Q_c * p_AF_Q_c)
1752
+ 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
1753
+ cap_clg_ratio = 1 / (cool_cap_fff / cool_cap_fff_nodefect)
1754
+ cap_clg_ratios << cap_clg_ratio
1755
+ end
1756
+ prev_capacity = hvac_sizing_values.Cool_Capacity
1757
+ hvac_sizing_values.Cool_Capacity *= cap_clg_ratios.max
1758
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity * hvac.SHRRated[hvac.SizingSpeed]
1759
+ if prev_capacity > 0 # Preserve cfm/ton
1760
+ hvac_sizing_values.Cool_Airflow = hvac_sizing_values.Cool_Airflow * hvac_sizing_values.Cool_Capacity / prev_capacity
1761
+ else
1762
+ hvac_sizing_values.Cool_Airflow = 0.0
1763
+ end
1764
+ end
1765
+ end
1766
+
1767
+ # Heating
1768
+ if [HPXML::HVACTypeHeatPumpAirToAir,
1769
+ HPXML::HVACTypeHeatPumpMiniSplit].include?(hvac.HeatType) && hvac.HeatingLoadFraction > 0
1770
+ heat_airflow_rated_defect_ratio = []
1771
+ heat_airflow_rated_ratio = []
1772
+ heat_cfm_m3s = UnitConversions.convert(hvac_sizing_values.Heat_Airflow, 'cfm', 'm^3/s')
1773
+ for speed in 0..(hvac.NumSpeedsHeating - 1)
1774
+ heat_airflow_rated_ratio << heat_cfm_m3s / HVAC.calc_rated_airflow(hvac_sizing_values.Heat_Capacity, hvac.RatedCFMperTonHeating[speed], hvac.CapacityRatioHeating[speed])
1775
+ 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])
1776
+ end
1777
+ if not heat_airflow_rated_defect_ratio.empty?
1778
+ cap_htg_ratios = []
1779
+ for speed in 0..(hvac.NumSpeedsHeating - 1)
1780
+ a1_AF_Qgr_h = hvac.HEAT_CAP_FFLOW_SPEC[speed][0]
1781
+ a2_AF_Qgr_h = hvac.HEAT_CAP_FFLOW_SPEC[speed][1]
1782
+ a3_AF_Qgr_h = hvac.HEAT_CAP_FFLOW_SPEC[speed][2]
1783
+
1784
+ p_values, qgr_values, ff_chg_values = HVAC.get_installation_quality_heating_coeff(f_ch)
1785
+
1786
+ a1_CH_Qgr_h = qgr_values[0]
1787
+ a2_CH_Qgr_h = qgr_values[1]
1788
+ a3_CH_Qgr_h = qgr_values[2]
1789
+
1790
+ ff_ch_h = (1 / (1 + (qgr_values[0] + qgr_values[1] * ff_chg_values[0] + qgr_values[2] * f_ch) * f_ch)).round(3)
1791
+
1792
+ qh1_CH = a1_CH_Qgr_h
1793
+ qh2_CH = a2_CH_Qgr_h * tout_heat
1794
+ qh3_CH = a3_CH_Qgr_h * f_ch
1795
+ y_CH_Q_h = 1 + ((qh1_CH + qh2_CH + qh3_CH) * f_ch)
1796
+
1797
+ qh0_AF_CH = a1_AF_Qgr_h
1798
+ qh1_AF_CH = a2_AF_Qgr_h * ff_ch_h
1799
+ qh2_AF_CH = a3_AF_Qgr_h * ff_ch_h * ff_ch_h
1800
+ p_CH_Q_h = y_CH_Q_h / (qh0_AF_CH + qh1_AF_CH + qh2_AF_CH)
1801
+
1802
+ ff_AF_h = heat_airflow_rated_defect_ratio[speed].round(3)
1803
+ ff_AF_h_nodefect = heat_airflow_rated_ratio[speed].round(3)
1804
+ ff_AF_comb_h = ff_ch_h * ff_AF_h
1805
+
1806
+ qh0_AF_comb = a1_AF_Qgr_h
1807
+ qh1_AF_comb = a2_AF_Qgr_h * ff_AF_comb_h
1808
+ qh2_AF_comb = a3_AF_Qgr_h * ff_AF_comb_h * ff_AF_comb_h
1809
+ p_AF_Q_h = qh0_AF_comb + qh1_AF_comb + qh2_AF_comb
1810
+
1811
+ heat_cap_fff = (p_CH_Q_h * p_AF_Q_h)
1812
+ 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
1813
+ cap_htg_ratio = 1 / (heat_cap_fff / heat_cap_fff_nodefect)
1814
+ cap_htg_ratios << cap_htg_ratio
1815
+ end
1816
+ prev_capacity = hvac_sizing_values.Heat_Capacity
1817
+ hvac_sizing_values.Heat_Capacity *= cap_htg_ratios.max
1818
+ if prev_capacity > 0 # Preserve cfm/ton
1819
+ hvac_sizing_values.Heat_Airflow = hvac_sizing_values.Heat_Airflow * hvac_sizing_values.Heat_Capacity / prev_capacity
1820
+ else
1821
+ hvac_sizing_values.Heat_Airflow = 0.0
1822
+ end
1823
+ end
1824
+ end
1825
+ end
1826
+ end
1827
+
1828
+ def self.apply_hvac_fixed_capacities(hvac_sizing_values, hvac)
1516
1829
  '''
1517
1830
  Fixed Sizing Equipment
1518
1831
  '''
1519
1832
 
1520
1833
  # 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
1834
+ if (not hvac.FixedCoolingCapacity.nil?) && (hvac_sizing_values.Cool_Capacity > 0)
1835
+ prev_capacity = hvac_sizing_values.Cool_Capacity
1836
+ hvac_sizing_values.Cool_Capacity = hvac.FixedCoolingCapacity
1524
1837
  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
1838
+ hvac_sizing_values.Cool_Capacity = [hvac_sizing_values.Cool_Capacity, prev_capacity].max
1532
1839
  end
1840
+ hvac_sizing_values.Cool_Capacity_Sens = hvac_sizing_values.Cool_Capacity_Sens * hvac_sizing_values.Cool_Capacity / prev_capacity
1841
+ hvac_sizing_values.Cool_Airflow = hvac_sizing_values.Cool_Airflow * hvac_sizing_values.Cool_Capacity / prev_capacity
1533
1842
  end
1534
- if not hvac.FixedHeatingCapacity.nil?
1535
- prev_capacity = hvac_final_values.Heat_Capacity
1536
- hvac_final_values.Heat_Capacity = hvac.FixedHeatingCapacity
1843
+ if (not hvac.FixedHeatingCapacity.nil?) && (hvac_sizing_values.Heat_Capacity > 0)
1844
+ prev_capacity = hvac_sizing_values.Heat_Capacity
1845
+ hvac_sizing_values.Heat_Capacity = hvac.FixedHeatingCapacity
1537
1846
  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
1847
+ hvac_sizing_values.Heat_Capacity = [hvac_sizing_values.Heat_Capacity, prev_capacity].max
1544
1848
  end
1849
+ hvac_sizing_values.Heat_Airflow = hvac_sizing_values.Heat_Airflow * hvac_sizing_values.Heat_Capacity / prev_capacity
1545
1850
  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
1851
+ if (not hvac.FixedSuppHeatingCapacity.nil?) && (hvac_sizing_values.Heat_Capacity_Supp > 0)
1852
+ prev_capacity = hvac_sizing_values.Heat_Capacity_Supp
1853
+ hvac_sizing_values.Heat_Capacity_Supp = hvac.FixedSuppHeatingCapacity
1549
1854
  if @hpxml.header.allow_increased_fixed_capacities
1550
- hvac_final_values.Heat_Capacity_Supp = [hvac_final_values.Heat_Capacity_Supp, prev_capacity].max
1855
+ hvac_sizing_values.Heat_Capacity_Supp = [hvac_sizing_values.Heat_Capacity_Supp, prev_capacity].max
1551
1856
  end
1552
1857
  end
1553
1858
  end
1554
1859
 
1555
- def self.process_ground_loop(hvac_final_values, weather, hvac)
1860
+ def self.apply_hvac_ground_loop(hvac_sizing_values, weather, hvac)
1556
1861
  '''
1557
1862
  GSHP Ground Loop Sizing Calculations
1558
1863
  '''
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
1864
+ return unless hvac.CoolType == HPXML::HVACTypeHeatPumpGroundToAir
1865
+
1866
+ # Autosize ground loop heat exchanger length
1867
+ bore_spacing = 20.0 # ft, distance between bores
1868
+ pipe_r_value = gshp_hx_pipe_rvalue(hvac)
1869
+ nom_length_heat, nom_length_cool = gshp_hxbore_ft_per_ton(weather, hvac, bore_spacing, pipe_r_value)
1870
+
1871
+ bore_length_heat = nom_length_heat * hvac_sizing_values.Heat_Capacity / UnitConversions.convert(1.0, 'ton', 'Btu/hr')
1872
+ bore_length_cool = nom_length_cool * hvac_sizing_values.Cool_Capacity / UnitConversions.convert(1.0, 'ton', 'Btu/hr')
1873
+ bore_length = [bore_length_heat, bore_length_cool].max
1874
+
1875
+ loop_flow = [1.0, UnitConversions.convert([hvac_sizing_values.Heat_Capacity, hvac_sizing_values.Cool_Capacity].max, 'Btu/hr', 'ton')].max.floor * 3.0
1876
+
1877
+ num_bore_holes = [1, (UnitConversions.convert(hvac_sizing_values.Cool_Capacity, 'Btu/hr', 'ton') + 0.5).floor].max
1878
+ bore_depth = (bore_length / num_bore_holes).floor # ft
1879
+ min_bore_depth = 0.15 * bore_spacing # 0.15 is the maximum Spacing2DepthRatio defined for the G-function
1880
+
1881
+ (0..4).to_a.each do |tmp|
1882
+ if (bore_depth < min_bore_depth) && (num_bore_holes > 1)
1883
+ num_bore_holes -= 1
1884
+ bore_depth = (bore_length / num_bore_holes).floor
1885
+ elsif bore_depth > 345
1886
+ num_bore_holes += 1
1887
+ bore_depth = (bore_length / num_bore_holes).floor
1888
+ end
1889
+ end
1890
+
1891
+ bore_depth = (bore_length / num_bore_holes).floor + 5
1892
+
1893
+ bore_length = bore_depth * num_bore_holes
1894
+
1895
+ if num_bore_holes == 1
1896
+ bore_config = 'single'
1897
+ elsif num_bore_holes == 2
1898
+ bore_config = 'line'
1899
+ elsif num_bore_holes == 3
1900
+ bore_config = 'line'
1901
+ elsif num_bore_holes == 4
1902
+ bore_config = 'rectangle'
1903
+ elsif num_bore_holes == 5
1904
+ bore_config = 'u-config'
1905
+ elsif num_bore_holes > 5
1906
+ bore_config = 'line'
1907
+ end
1908
+
1909
+ # Test for valid GSHP bore field configurations
1910
+ valid_configs = { 'single' => [1],
1911
+ 'line' => [2, 3, 4, 5, 6, 7, 8, 9, 10],
1912
+ 'l-config' => [3, 4, 5, 6],
1913
+ 'rectangle' => [2, 4, 6, 8],
1914
+ 'u-config' => [5, 7, 9],
1915
+ 'l2-config' => [8],
1916
+ 'open-rectangle' => [8] }
1917
+ valid_num_bores = valid_configs[bore_config]
1918
+ max_valid_configs = { 'line' => 10, 'l-config' => 6 }
1919
+ unless valid_num_bores.include? num_bore_holes
1920
+ # Any configuration with a max_valid_configs value can accept any number of bores up to the maximum
1921
+ if max_valid_configs.keys.include? bore_config
1922
+ max_num_bore_holes = max_valid_configs[bore_config]
1923
+ num_bore_holes = max_num_bore_holes
1600
1924
  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
1925
+ # Search for first valid bore field
1926
+ new_bore_config = nil
1927
+ valid_field_found = false
1928
+ valid_configs.keys.each do |bore_config|
1929
+ next unless valid_configs[bore_config].include? num_bore_holes
1930
+
1931
+ valid_field_found = true
1932
+ new_bore_config = bore_config
1933
+ break
1934
+ end
1935
+ if valid_field_found
1936
+ bore_config = new_bore_config
1640
1937
  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
1938
+ fail 'Could not construct a valid GSHP bore field configuration.'
1657
1939
  end
1658
1940
  end
1941
+ end
1659
1942
 
1660
- spacing_to_depth_ratio = hvac.GSHP_BoreSpacing / hvac.GSHP_BoreDepth
1943
+ spacing_to_depth_ratio = bore_spacing / bore_depth
1661
1944
 
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)
1945
+ 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]
1946
+ gfnc_coeff = gshp_gfnc_coeff(bore_config, num_bore_holes, spacing_to_depth_ratio)
1664
1947
 
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
1948
+ hvac_sizing_values.GSHP_Loop_flow = loop_flow
1949
+ hvac_sizing_values.GSHP_Bore_Depth = bore_depth
1950
+ hvac_sizing_values.GSHP_Bore_Holes = num_bore_holes
1951
+ hvac_sizing_values.GSHP_G_Functions = [lntts, gfnc_coeff]
1670
1952
  end
1671
1953
 
1672
- def self.process_finalize(hvac_final_values, zone_loads, weather, hvac)
1954
+ def self.apply_hvac_finalize_airflows(hvac_sizing_values, weather, hvac)
1673
1955
  '''
1674
1956
  Finalize Sizing Calculations
1675
1957
  '''
1676
1958
 
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
1959
+ if hvac_sizing_values.Heat_Airflow > 0
1960
+ hvac_sizing_values.Heat_Airflow *= (1.0 + hvac.AirflowDefectRatioHeating)
1681
1961
  end
1682
- if hvac_final_values.Cool_Airflow > 0
1683
- hvac_final_values.Cool_Airflow = [hvac_final_values.Cool_Airflow, min_air_flow].max
1962
+
1963
+ if hvac_sizing_values.Cool_Airflow > 0
1964
+ hvac_sizing_values.Cool_Airflow *= (1.0 + hvac.AirflowDefectRatioCooling)
1684
1965
  end
1685
1966
  end
1686
1967
 
1687
- def self.process_heat_pump_adjustment(hvac_final_values, weather, hvac, totalCap_CurveValue)
1968
+ def self.process_heat_pump_adjustment(hvac_sizing_values, weather, hvac, totalCap_CurveValue)
1688
1969
  '''
1689
1970
  Adjust heat pump sizing
1690
1971
  '''
@@ -1696,88 +1977,129 @@ class HVACSizing
1696
1977
  capacity_ratio = 1.0
1697
1978
  end
1698
1979
 
1699
- heatCap_Rated = (hvac_final_values.Heat_Load / MathTools.biquadratic(@heat_setpoint, weather.design.HeatingDrybulb, coefficients)) / capacity_ratio
1980
+ heatCap_Rated = (hvac_sizing_values.Heat_Load / MathTools.biquadratic(@heat_setpoint, weather.design.HeatingDrybulb, coefficients)) / capacity_ratio
1700
1981
 
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
1982
+ if heatCap_Rated >= hvac_sizing_values.Cool_Capacity
1983
+ cfm_per_btuh = hvac_sizing_values.Cool_Airflow / hvac_sizing_values.Cool_Capacity
1984
+ load_shr = hvac_sizing_values.Cool_Load_Sens / hvac_sizing_values.Cool_Load_Tot
1710
1985
  if ((weather.data.HDD65F / weather.data.CDD50F) < 2.0) || (load_shr < 0.95)
1711
1986
  # 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
1987
+ hvac_sizing_values.Cool_Capacity = [(hvac.OverSizeLimit * hvac_sizing_values.Cool_Load_Tot) / totalCap_CurveValue, heatCap_Rated].min
1713
1988
  else
1714
1989
  # 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
1990
+ hvac_sizing_values.Cool_Capacity = [(hvac_sizing_values.Cool_Load_Tot + hvac.OverSizeDelta) / totalCap_CurveValue, heatCap_Rated].min
1716
1991
  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
1992
+ if hvac.HeatType == HPXML::HVACTypeHeatPumpAirToAir
1993
+ hvac_sizing_values.Cool_Airflow = cfm_per_btuh * hvac_sizing_values.Cool_Capacity
1994
+ elsif hvac.HeatType == HPXML::HVACTypeHeatPumpMiniSplit
1995
+ hvac_sizing_values.Cool_Airflow = hvac.RatedCFMperTonCooling[-1] * hvac.CapacityRatioCooling[-1] * UnitConversions.convert(hvac_sizing_values.Cool_Capacity, 'Btu/hr', 'ton')
1723
1996
  end
1724
1997
  end
1725
-
1726
- return hvac_final_values
1727
1998
  end
1728
1999
 
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
2000
+ def self.get_ventilation_rates()
2001
+ vent_fans_mech = @hpxml.ventilation_fans.select { |f| f.used_for_whole_building_ventilation }
2002
+ if vent_fans_mech.empty?
2003
+ return [0.0, 0.0, 0.0, 0.0, 0.0, 0.0]
1754
2004
  end
1755
2005
 
1756
- return shelter_class
1757
- end
2006
+ # Categorize fans into different types
2007
+ vent_mech_preheat = vent_fans_mech.select { |vent_mech| (not vent_mech.preheating_efficiency_cop.nil?) }
2008
+ vent_mech_precool = vent_fans_mech.select { |vent_mech| (not vent_mech.precooling_efficiency_cop.nil?) }
2009
+ vent_mech_shared = vent_fans_mech.select { |vent_mech| vent_mech.is_shared_system }
2010
+
2011
+ vent_mech_sup_tot = vent_fans_mech.select { |vent_mech| vent_mech.fan_type == HPXML::MechVentTypeSupply }
2012
+ vent_mech_exh_tot = vent_fans_mech.select { |vent_mech| vent_mech.fan_type == HPXML::MechVentTypeExhaust }
2013
+ vent_mech_cfis_tot = vent_fans_mech.select { |vent_mech| vent_mech.fan_type == HPXML::MechVentTypeCFIS }
2014
+ vent_mech_bal_tot = vent_fans_mech.select { |vent_mech| vent_mech.fan_type == HPXML::MechVentTypeBalanced }
2015
+ vent_mech_erv_hrv_tot = vent_fans_mech.select { |vent_mech| [HPXML::MechVentTypeERV, HPXML::MechVentTypeHRV].include? vent_mech.fan_type }
2016
+
2017
+ # Average in-unit CFMs (include recirculation from in unit CFMs for shared systems)
2018
+ sup_cfm_tot = vent_mech_sup_tot.map { |vent_mech| vent_mech.average_total_unit_flow_rate }.sum(0.0)
2019
+ exh_cfm_tot = vent_mech_exh_tot.map { |vent_mech| vent_mech.average_total_unit_flow_rate }.sum(0.0)
2020
+ bal_cfm_tot = vent_mech_bal_tot.map { |vent_mech| vent_mech.average_total_unit_flow_rate }.sum(0.0)
2021
+ erv_hrv_cfm_tot = vent_mech_erv_hrv_tot.map { |vent_mech| vent_mech.average_total_unit_flow_rate }.sum(0.0)
2022
+ cfis_cfm_tot = vent_mech_cfis_tot.map { |vent_mech| vent_mech.average_total_unit_flow_rate }.sum(0.0)
2023
+
2024
+ # Average preconditioned OA air CFMs (only OA, recirculation will be addressed below for all shared systems)
2025
+ 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)
2026
+ 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)
2027
+ 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)
2028
+
2029
+ # Total CFMS
2030
+ tot_sup_cfm = sup_cfm_tot + bal_cfm_tot + erv_hrv_cfm_tot + cfis_cfm_tot
2031
+ tot_exh_cfm = exh_cfm_tot + bal_cfm_tot + erv_hrv_cfm_tot
2032
+ tot_unbal_cfm = (tot_sup_cfm - tot_exh_cfm).abs
2033
+ tot_bal_cfm = [tot_exh_cfm, tot_sup_cfm].min
1758
2034
 
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
2035
+ # Calculate effectivenesses for all ERV/HRV and store results in a hash
2036
+ hrv_erv_effectiveness_map = Airflow.calc_hrv_erv_effectiveness(vent_mech_erv_hrv_tot)
1762
2037
 
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')
2038
+ # Calculate cfm weighted average effectivenesses for the combined balanced airflow
2039
+ weighted_vent_mech_lat_eff = 0.0
2040
+ weighted_vent_mech_apparent_sens_eff = 0.0
2041
+ 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? }
2042
+ vent_mech_erv_hrv_unprecond.each do |vent_mech|
2043
+ 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]
2044
+ 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]
2045
+ end
1770
2046
 
1771
- q_bal_sens = q_b * (1.0 - apparentSensibleEffectiveness)
1772
- q_bal_lat = q_b * (1.0 - latentEffectiveness)
2047
+ tot_bal_cfm_sens = tot_bal_cfm * (1.0 - weighted_vent_mech_apparent_sens_eff)
2048
+ tot_bal_cfm_lat = tot_bal_cfm * (1.0 - weighted_vent_mech_lat_eff)
1773
2049
 
1774
- return [q_unb_cfm, q_preheat, q_precool, q_recirc, q_bal_sens, q_bal_lat]
2050
+ return [tot_unbal_cfm, oa_cfm_preheat, oa_cfm_precool, recirc_cfm_shared, tot_bal_cfm_sens, tot_bal_cfm_lat]
1775
2051
  end
1776
2052
 
1777
2053
  def self.calc_airflow_rate(load_or_capacity, deltaT)
1778
2054
  return load_or_capacity / (1.1 * @acf * deltaT)
1779
2055
  end
1780
2056
 
2057
+ def self.calc_gshp_clg_curve_value(hvac, wb_temp, db_temp, w_temp, vfr_air, loop_flow)
2058
+ # Reference conditions in thesis with largest capacity:
2059
+ # See Appendix B Figure B.3 of https://hvac.okstate.edu/sites/default/files/pubs/theses/MS/27-Tang_Thesis_05.pdf
2060
+ ref_temp = 283 # K
2061
+ ref_vfr_air = UnitConversions.convert(1200, 'cfm', 'm^3/s')
2062
+ ref_vfr_water = 0.000284
2063
+
2064
+ a_1 = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed][0]
2065
+ a_2 = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed][1]
2066
+ a_3 = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed][2]
2067
+ a_4 = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed][3]
2068
+ a_5 = hvac.COOL_CAP_FT_SPEC[hvac.SizingSpeed][4]
2069
+ b_1 = hvac.COOL_SH_FT_SPEC[hvac.SizingSpeed][0]
2070
+ b_2 = hvac.COOL_SH_FT_SPEC[hvac.SizingSpeed][1]
2071
+ b_3 = hvac.COOL_SH_FT_SPEC[hvac.SizingSpeed][2]
2072
+ b_4 = hvac.COOL_SH_FT_SPEC[hvac.SizingSpeed][3]
2073
+ b_5 = hvac.COOL_SH_FT_SPEC[hvac.SizingSpeed][4]
2074
+ b_6 = hvac.COOL_SH_FT_SPEC[hvac.SizingSpeed][5]
2075
+
2076
+ if not loop_flow.nil?
2077
+ 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
2078
+ 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
2079
+ else
2080
+ totalCap_CurveValue = a_1 + wb_temp / ref_temp * a_2 + w_temp / ref_temp * a_3 + vfr_air / ref_vfr_air * a_4
2081
+ 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
2082
+ end
2083
+ return totalCap_CurveValue, sensibleCap_CurveValue
2084
+ end
2085
+
2086
+ def self.calc_gshp_htg_curve_value(hvac, db_temp, w_temp, vfr_air, loop_flow)
2087
+ # Reference conditions in thesis with largest capacity:
2088
+ # See Appendix B Figure B.3 of https://hvac.okstate.edu/sites/default/files/pubs/theses/MS/27-Tang_Thesis_05.pdf
2089
+ ref_temp = 283 # K
2090
+ ref_vfr_air = UnitConversions.convert(1200, 'cfm', 'm^3/s')
2091
+ ref_vfr_water = 0.000284
2092
+
2093
+ a_1 = hvac.HEAT_CAP_FT_SPEC[hvac.SizingSpeed][0]
2094
+ a_2 = hvac.HEAT_CAP_FT_SPEC[hvac.SizingSpeed][1]
2095
+ a_3 = hvac.HEAT_CAP_FT_SPEC[hvac.SizingSpeed][2]
2096
+ a_4 = hvac.HEAT_CAP_FT_SPEC[hvac.SizingSpeed][3]
2097
+ a_5 = hvac.HEAT_CAP_FT_SPEC[hvac.SizingSpeed][4]
2098
+
2099
+ 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
2100
+ return cap_CurveValue
2101
+ end
2102
+
1781
2103
  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
2104
  '''
1783
2105
  Calculate the Delivery Effectiveness for heating (using the method of ASHRAE Standard 152).
@@ -1862,61 +2184,6 @@ class HVACSizing
1862
2184
  return cool_Load_Lat, cool_Load_Sens
1863
2185
  end
1864
2186
 
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
2187
  def self.calc_ducts_area_weighted_average(ducts, values)
1921
2188
  '''
1922
2189
  Calculate area-weighted average values for unconditioned duct(s)
@@ -1966,9 +2233,9 @@ class HVACSizing
1966
2233
  ducts.each do |duct|
1967
2234
  next if [HPXML::LocationLivingSpace, HPXML::LocationBasementConditioned].include? duct.Location
1968
2235
 
1969
- if not duct.LeakageFrac.nil?
2236
+ if duct.LeakageFrac.to_f > 0
1970
2237
  cfms[duct.Side] += duct.LeakageFrac * system_cfm
1971
- elsif not duct.LeakageCFM25.nil?
2238
+ elsif duct.LeakageCFM25.to_f > 0
1972
2239
  cfms[duct.Side] += duct.LeakageCFM25
1973
2240
  end
1974
2241
  end
@@ -1993,302 +2260,243 @@ class HVACSizing
1993
2260
  return 1.0 / supply_u, 1.0 / return_u
1994
2261
  end
1995
2262
 
1996
- def self.get_hvacs(model)
1997
- hvacs = []
1998
-
1999
- # Get unique set of HVAC equipment
2000
- equips = []
2263
+ def self.get_hvac_information(hvac_system)
2264
+ # FUTURE: Remove this method and use hvac_system objects directly.
2265
+ hvac = HVACInfo.new
2001
2266
 
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
2267
+ hpxml_hvacs = []
2268
+ if not hvac_system[:heating].nil?
2269
+ hpxml_hvacs << hvac_system[:heating]
2270
+ end
2271
+ if not hvac_system[:cooling].nil?
2272
+ hpxml_hvacs << hvac_system[:cooling]
2007
2273
  end
2008
2274
 
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)
2275
+ # Get heating/cooling system info from HPXML objects
2276
+ hpxml_hvacs.uniq.each do |hpxml_hvac|
2277
+ hpxml_hvac_ap = hpxml_hvac.additional_properties
2031
2278
 
2032
- hvac.CoolingLoadFraction = get_feature(equip, Constants.SizingInfoHVACFracCoolLoadServed, 'double')
2033
- hvac.EvapCoolerEffectiveness = equip.coolerEffectiveness
2279
+ # System type
2280
+ if hpxml_hvac.respond_to? :heating_system_type
2281
+ hvac.HeatType = hpxml_hvac.heating_system_type
2282
+ elsif hpxml_hvac.respond_to? :cooling_system_type
2283
+ hvac.CoolType = hpxml_hvac.cooling_system_type
2284
+ elsif hpxml_hvac.respond_to? :heat_pump_type
2285
+ hvac.HeatType = hpxml_hvac.heat_pump_type
2286
+ hvac.CoolType = hpxml_hvac.heat_pump_type
2034
2287
  end
2035
2288
 
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')
2289
+ # Load fractions
2290
+ if hpxml_hvac.respond_to? :fraction_heat_load_served
2291
+ hvac.HeatingLoadFraction = hpxml_hvac.fraction_heat_load_served
2292
+ end
2293
+ if hpxml_hvac.respond_to? :fraction_cool_load_served
2294
+ hvac.CoolingLoadFraction = hpxml_hvac.fraction_cool_load_served
2044
2295
  end
2045
2296
 
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
2297
+ # Capacities
2298
+ if hpxml_hvac.respond_to? :heating_capacity
2299
+ hvac.FixedHeatingCapacity = hpxml_hvac.heating_capacity
2300
+ end
2301
+ if hpxml_hvac.respond_to? :cooling_capacity
2302
+ hvac.FixedCoolingCapacity = hpxml_hvac.cooling_capacity
2303
+ end
2304
+ if hpxml_hvac.respond_to? :backup_heating_capacity
2305
+ hvac.FixedSuppHeatingCapacity = hpxml_hvac.backup_heating_capacity
2306
+ end
2060
2307
 
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')
2308
+ # Number of speeds
2309
+ if hpxml_hvac.is_a?(HPXML::CoolingSystem) || hpxml_hvac.is_a?(HPXML::HeatPump)
2310
+ # Cooling
2311
+ if hpxml_hvac_ap.respond_to? :num_speeds
2312
+ num_speeds = hpxml_hvac_ap.num_speeds
2064
2313
  end
2065
-
2066
- elsif clg_coil.is_a? OpenStudio::Model::CoilCoolingDXMultiSpeed
2067
- hvac.NumSpeedsCooling = clg_coil.stages.size
2314
+ num_speeds = 1 if num_speeds.nil?
2315
+ hvac.NumSpeedsCooling = num_speeds
2068
2316
  if hvac.NumSpeedsCooling == 2
2069
2317
  hvac.OverSizeLimit = 1.2
2070
- else
2318
+ elsif hvac.NumSpeedsCooling > 2
2071
2319
  hvac.OverSizeLimit = 1.3
2072
2320
  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}."
2321
+ end
2322
+ if hpxml_hvac.is_a?(HPXML::HeatingSystem) || hpxml_hvac.is_a?(HPXML::HeatPump)
2323
+ # Heating
2324
+ if hpxml_hvac_ap.respond_to? :num_speeds
2325
+ num_speeds = hpxml_hvac_ap.num_speeds
2080
2326
  end
2327
+ num_speeds = 1 if num_speeds.nil?
2328
+ hvac.NumSpeedsHeating = num_speeds
2329
+ end
2081
2330
 
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
2331
+ # HVAC installation quality
2332
+ if hpxml_hvac.respond_to? :charge_defect_ratio
2333
+ if [HPXML::HVACTypeCentralAirConditioner,
2334
+ HPXML::HVACTypeMiniSplitAirConditioner,
2335
+ HPXML::HVACTypeHeatPumpAirToAir,
2336
+ HPXML::HVACTypeHeatPumpMiniSplit,
2337
+ HPXML::HVACTypeHeatPumpGroundToAir].include? hvac.CoolType
2338
+ hvac.ChargeDefectRatio = hpxml_hvac.charge_defect_ratio
2090
2339
  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}."
2340
+ end
2341
+ if hpxml_hvac.respond_to? :airflow_defect_ratio
2342
+ # Cooling
2343
+ if [HPXML::HVACTypeCentralAirConditioner,
2344
+ HPXML::HVACTypeMiniSplitAirConditioner,
2345
+ HPXML::HVACTypeHeatPumpAirToAir,
2346
+ HPXML::HVACTypeHeatPumpMiniSplit,
2347
+ HPXML::HVACTypeHeatPumpGroundToAir].include? hvac.CoolType
2348
+ if not hpxml_hvac.distribution_system.nil? # Exclude ductless
2349
+ hvac.AirflowDefectRatioCooling = hpxml_hvac.airflow_defect_ratio
2098
2350
  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
2351
  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')
2352
+ # Heating
2353
+ if [HPXML::HVACTypeFurnace,
2354
+ HPXML::HVACTypeHeatPumpAirToAir,
2355
+ HPXML::HVACTypeHeatPumpMiniSplit,
2356
+ HPXML::HVACTypeHeatPumpGroundToAir].include? hvac.HeatType
2357
+ if not hpxml_hvac.distribution_system.nil? # Exclude ductless
2358
+ hvac.AirflowDefectRatioHeating = hpxml_hvac.airflow_defect_ratio
2359
+ end
2139
2360
  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
2361
  end
2154
2362
 
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
2363
+ # Rated airflow rates
2364
+ if hpxml_hvac_ap.respond_to? :cool_rated_cfm_per_ton
2365
+ hvac.RatedCFMperTonCooling = hpxml_hvac_ap.cool_rated_cfm_per_ton
2160
2366
  end
2161
-
2162
- heatingLoadFraction = get_feature(equip, Constants.SizingInfoHVACFracHeatLoadServed, 'double', false)
2163
- if not heatingLoadFraction.nil?
2164
- hvac.HeatingLoadFraction = heatingLoadFraction
2367
+ if hpxml_hvac_ap.respond_to? :heat_rated_cfm_per_ton
2368
+ hvac.RatedCFMperTonHeating = hpxml_hvac_ap.heat_rated_cfm_per_ton
2165
2369
  end
2166
2370
 
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)
2371
+ # Capacity ratios
2372
+ if hpxml_hvac_ap.respond_to? :cool_capacity_ratios
2373
+ hvac.CapacityRatioCooling = hpxml_hvac_ap.cool_capacity_ratios
2374
+ end
2375
+ if hpxml_hvac_ap.respond_to? :heat_capacity_ratios
2376
+ hvac.CapacityRatioHeating = hpxml_hvac_ap.heat_capacity_ratios
2377
+ end
2224
2378
 
2225
- if hvac.HeatType == Constants.ObjectNameMiniSplitHeatPump
2226
- ratedCFMperTonHeating = get_feature(equip, Constants.SizingInfoHVACRatedCFMperTonHeating, 'string')
2227
- hvac.RatedCFMperTonHeating = ratedCFMperTonHeating.split(',').map(&:to_f)
2379
+ # Sizing speed
2380
+ hvac.SizingSpeed = get_sizing_speed(hvac.NumSpeedsCooling, hvac.CapacityRatioCooling)
2228
2381
 
2229
- hvac.HeatingCapacityOffset = get_feature(equip, Constants.SizingInfoHVACHeatingCapacityOffset, 'double')
2230
- end
2382
+ # Rated SHRs
2383
+ if hpxml_hvac_ap.respond_to? :cool_rated_shrs_gross
2384
+ hvac.SHRRated = hpxml_hvac_ap.cool_rated_shrs_gross
2385
+ end
2231
2386
 
2232
- elsif htg_coil.is_a? OpenStudio::Model::CoilHeatingWaterToAirHeatPumpEquationFit
2233
- hvac.NumSpeedsHeating = 1
2387
+ # Performance curves
2388
+ if hpxml_hvac_ap.respond_to? :cool_cap_ft_spec
2389
+ hvac.COOL_CAP_FT_SPEC = hpxml_hvac_ap.cool_cap_ft_spec
2390
+ end
2391
+ if hpxml_hvac_ap.respond_to? :cool_sh_ft_spec
2392
+ hvac.COOL_SH_FT_SPEC = hpxml_hvac_ap.cool_sh_ft_spec
2393
+ end
2394
+ if hpxml_hvac_ap.respond_to? :heat_cap_ft_spec
2395
+ hvac.HEAT_CAP_FT_SPEC = hpxml_hvac_ap.heat_cap_ft_spec
2396
+ end
2397
+ if hpxml_hvac_ap.respond_to? :cool_cap_fflow_spec
2398
+ hvac.COOL_CAP_FFLOW_SPEC = hpxml_hvac_ap.cool_cap_fflow_spec
2399
+ end
2400
+ if hpxml_hvac_ap.respond_to? :heat_cap_fflow_spec
2401
+ hvac.HEAT_CAP_FFLOW_SPEC = hpxml_hvac_ap.heat_cap_fflow_spec
2402
+ end
2234
2403
 
2235
- if htg_coil.ratedHeatingCapacity.is_initialized
2236
- hvac.FixedHeatingCapacity = UnitConversions.convert(htg_coil.ratedHeatingCapacity.get, 'W', 'Btu/hr')
2237
- end
2404
+ # WLHP
2405
+ if hpxml_hvac.respond_to? :heating_efficiency_cop
2406
+ hvac.HeatingCOP = hpxml_hvac.heating_efficiency_cop
2407
+ end
2238
2408
 
2239
- hvac.HeatingEIR = 1.0 / htg_coil.ratedHeatingCoefficientofPerformance
2409
+ # GSHP
2410
+ if hpxml_hvac_ap.respond_to? :u_tube_spacing_type
2411
+ hvac.GSHP_SpacingType = hpxml_hvac_ap.u_tube_spacing_type
2412
+ end
2413
+ if hpxml_hvac_ap.respond_to? :cool_rated_eirs
2414
+ hvac.CoolingEIR = hpxml_hvac_ap.cool_rated_eirs[0]
2415
+ end
2416
+ if hpxml_hvac_ap.respond_to? :heat_rated_eirs
2417
+ hvac.HeatingEIR = hpxml_hvac_ap.heat_rated_eirs[0]
2418
+ end
2419
+ if hvac.HeatType == HPXML::HVACTypeHeatPumpGroundToAir
2420
+ hvac.GSHP_design_chw = hpxml_hvac_ap.design_chw
2421
+ hvac.GSHP_design_delta_t = hpxml_hvac_ap.design_delta_t
2422
+ hvac.GSHP_design_hw = hpxml_hvac_ap.design_hw
2423
+ hvac.GSHP_bore_d = hpxml_hvac_ap.bore_diameter
2424
+ hvac.GSHP_pipe_od = hpxml_hvac_ap.pipe_od
2425
+ hvac.GSHP_pipe_id = hpxml_hvac_ap.pipe_id
2426
+ hvac.GSHP_pipe_cond = hpxml_hvac_ap.pipe_cond
2427
+ hvac.GSHP_ground_k = hpxml_hvac_ap.ground_conductivity
2428
+ hvac.GSHP_grout_k = hpxml_hvac_ap.grout_conductivity
2429
+ end
2240
2430
 
2241
- plant_loop = htg_coil.plantLoop.get
2242
- plant_loop.supplyComponents.each do |plc|
2243
- next if !plc.to_GroundHeatExchangerVertical.is_initialized
2431
+ # Evaporative cooler
2432
+ if hpxml_hvac_ap.respond_to? :effectiveness
2433
+ hvac.EvapCoolerEffectiveness = hpxml_hvac_ap.effectiveness
2434
+ end
2244
2435
 
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
2436
+ # Ducts
2437
+ # FUTURE: Consolidate w/ ducts code in measure.rb
2438
+ hvac.Ducts = []
2439
+ next unless not hpxml_hvac.distribution_system.nil?
2440
+ lto = { supply_percent: nil, supply_cfm25: nil, return_percent: nil, return_cfm25: nil }
2441
+ hpxml_hvac.distribution_system.duct_leakage_measurements.each do |m|
2442
+ next unless m.duct_leakage_total_or_to_outside == 'to outside'
2250
2443
 
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.'
2444
+ if m.duct_leakage_units == HPXML::UnitsPercent && m.duct_type == HPXML::DuctTypeSupply
2445
+ lto[:supply_percent] = m.duct_leakage_value
2446
+ elsif m.duct_leakage_units == HPXML::UnitsCFM25 && m.duct_type == HPXML::DuctTypeSupply
2447
+ lto[:supply_cfm25] = m.duct_leakage_value
2448
+ elsif m.duct_leakage_units == HPXML::UnitsPercent && m.duct_type == HPXML::DuctTypeReturn
2449
+ lto[:return_percent] = m.duct_leakage_value
2450
+ elsif m.duct_leakage_units == HPXML::UnitsCFM25 && m.duct_type == HPXML::DuctTypeReturn
2451
+ lto[:return_cfm25] = m.duct_leakage_value
2256
2452
  end
2453
+ end
2454
+ total_uncond_supply_area = hpxml_hvac.distribution_system.total_unconditioned_duct_areas[HPXML::DuctTypeSupply]
2455
+ total_uncond_return_area = hpxml_hvac.distribution_system.total_unconditioned_duct_areas[HPXML::DuctTypeReturn]
2456
+ hpxml_hvac.distribution_system.ducts.each do |duct|
2457
+ next if [HPXML::LocationLivingSpace, HPXML::LocationBasementConditioned].include? duct.duct_location
2257
2458
 
2258
- hvac.GSHP_PumpWattsPerTon = get_feature(equip, Constants.SizingInfoHVACPumpPower, 'double')
2459
+ d = DuctInfo.new
2460
+ d.Side = duct.duct_type
2461
+ d.Location = duct.duct_location
2462
+ d.Area = duct.duct_surface_area
2259
2463
 
2260
- elsif not htg_coil.nil?
2261
- fail "Unexpected heating coil: #{htg_coil.name}."
2262
- end
2464
+ # Calculate R-value w/ air film
2465
+ d.Rvalue = Airflow.get_duct_insulation_rvalue(duct.duct_insulation_r_value, d.Side)
2263
2466
 
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')
2467
+ # Leakage to Outside apportioned to this duct
2468
+ if d.Side == HPXML::DuctTypeSupply
2469
+ d.LeakageFrac = lto[:supply_percent].to_f * d.Area / total_uncond_supply_area
2470
+ d.LeakageCFM25 = lto[:supply_cfm25].to_f * d.Area / total_uncond_supply_area
2471
+ elsif d.Side == HPXML::DuctTypeReturn
2472
+ d.LeakageFrac = lto[:return_percent].to_f * d.Area / total_uncond_return_area
2473
+ d.LeakageCFM25 = lto[:return_cfm25].to_f * d.Area / total_uncond_return_area
2268
2474
  end
2269
-
2270
- elsif not supp_htg_coil.nil?
2271
- fail "Unexpected supplemental heating coil: #{supp_htg_coil.name}."
2475
+ hvac.Ducts << d
2272
2476
  end
2477
+ # If all ducts are in conditioned space, treat leakage as going to outside
2478
+ if (lto[:supply_percent].to_f + lto[:supply_cfm25].to_f) > 0 && total_uncond_supply_area == 0
2479
+ d = DuctInfo.new
2480
+ d.Side = HPXML::DuctTypeSupply
2481
+ d.Location = HPXML::LocationOutside
2482
+ d.Area = 0.0
2483
+ d.Rvalue = Airflow.get_duct_insulation_rvalue(0.0, d.Side)
2484
+ d.LeakageFrac = lto[:supply_percent]
2485
+ d.LeakageCFM25 = lto[:supply_cfm25]
2486
+ hvac.Ducts << d
2487
+ end
2488
+ next unless (lto[:return_percent].to_f + lto[:return_cfm25].to_f) > 0 && total_uncond_return_area == 0
2489
+ d = DuctInfo.new
2490
+ d.Side = HPXML::DuctTypeReturn
2491
+ d.Location = HPXML::LocationOutside
2492
+ d.Area = 0.0
2493
+ d.Rvalue = Airflow.get_duct_insulation_rvalue(0.0, d.Side)
2494
+ d.LeakageFrac = lto[:return_percent]
2495
+ d.LeakageCFM25 = lto[:return_cfm25]
2496
+ hvac.Ducts << d
2273
2497
  end
2274
2498
 
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
2499
+ return hvac
2292
2500
  end
2293
2501
 
2294
2502
  def self.process_curve_fit(airFlowRate, capacity, temp)
@@ -2296,16 +2504,23 @@ class HVACSizing
2296
2504
  return 0 if capacity == 0
2297
2505
 
2298
2506
  capacity_tons = UnitConversions.convert(capacity, 'Btu/hr', 'ton')
2299
- return MathTools.biquadratic(airFlowRate / capacity_tons, temp, @shr_biquadratic)
2507
+ return MathTools.biquadratic(airFlowRate / capacity_tons, temp, get_shr_biquadratic)
2508
+ end
2509
+
2510
+ def self.get_shr_biquadratic
2511
+ # Based on EnergyPlus's model for calculating SHR at off-rated conditions. This curve fit
2512
+ # avoids the iterations in the actual model. It does not account for altitude or variations
2513
+ # in the SHRRated. It is a function of ODB (MJ design temp) and CFM/Ton (from MJ)
2514
+ return [1.08464364, 0.002096954, 0, -0.005766327, 0, -0.000011147]
2300
2515
  end
2301
2516
 
2302
- def self.get_sizing_speed(hvac)
2303
- if hvac.NumSpeedsCooling > 1
2304
- sizingSpeed = hvac.NumSpeedsCooling # Default
2517
+ def self.get_sizing_speed(num_speeds_cooling, capacity_ratios_cooling)
2518
+ if num_speeds_cooling > 1
2519
+ sizingSpeed = num_speeds_cooling # Default
2305
2520
  sizingSpeed_Test = 10 # Initialize
2306
- for speed in 0..(hvac.NumSpeedsCooling - 1)
2521
+ for speed in 0..(num_speeds_cooling - 1)
2307
2522
  # Select curves for sizing using the speed with the capacity ratio closest to 1
2308
- temp = (hvac.CapacityRatioCooling[speed] - 1).abs
2523
+ temp = (capacity_ratios_cooling[speed] - 1).abs
2309
2524
  if temp <= sizingSpeed_Test
2310
2525
  sizingSpeed = speed
2311
2526
  sizingSpeed_Test = temp
@@ -2353,8 +2568,44 @@ class HVACSizing
2353
2568
  end
2354
2569
 
2355
2570
  # 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?
2571
+ infiltration_cfm = nil
2572
+ ach = nil
2573
+ if [HPXML::LocationCrawlspaceVented, HPXML::LocationAtticVented].include? space_type
2574
+ # Vented space
2575
+ if space_type == HPXML::LocationCrawlspaceVented
2576
+ vented_crawl = @hpxml.foundations.select { |f| f.foundation_type == HPXML::FoundationTypeCrawlspaceVented }[0]
2577
+ sla = vented_crawl.vented_crawlspace_sla
2578
+ else
2579
+ vented_attic = @hpxml.attics.select { |f| f.attic_type == HPXML::AtticTypeVented }[0]
2580
+ if not vented_attic.vented_attic_sla.nil?
2581
+ sla = vented_attic.vented_attic_sla
2582
+ else
2583
+ ach = vented_attic.vented_attic_ach
2584
+ end
2585
+ end
2586
+ ach = Airflow.get_infiltration_ACH_from_SLA(sla, 8.202, weather) if ach.nil?
2587
+ else # Unvented space
2588
+ ach = 0.1 # Assumption
2589
+ end
2590
+ # FUTURE: Reuse code from measure.rb set_zone_volumes()
2591
+ if [HPXML::LocationAtticVented, HPXML::LocationAtticUnvented].include? space_type
2592
+ 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)
2593
+ roofs = @hpxml.roofs.select { |r| r.interior_adjacent_to == space_type }
2594
+ avg_pitch = roofs.map { |r| r.pitch }.sum(0.0) / roofs.size
2595
+ # Assume square hip roof for volume calculations; energy results are very insensitive to actual volume
2596
+ length = floor_area**0.5
2597
+ height = 0.5 * Math.sin(Math.atan(avg_pitch / 12.0)) * length
2598
+ volume = [floor_area * height / 3.0, 0.01].max
2599
+ else # foundation/garage space
2600
+ floor_area = @hpxml.slabs.select { |s| s.interior_adjacent_to == space_type }.map { |s| s.area }.sum(0.0)
2601
+ if space_type == HPXML::LocationGarage
2602
+ height = 8.0
2603
+ else
2604
+ height = @hpxml.foundation_walls.select { |w| w.interior_adjacent_to == space_type }.map { |w| w.height }.max
2605
+ end
2606
+ volume = floor_area * height
2607
+ end
2608
+ infiltration_cfm = ach / UnitConversions.convert(1.0, 'hr', 'min') * volume
2358
2609
  outside_air_density = UnitConversions.convert(weather.header.LocalPressure, 'atm', 'Btu/ft^3') / (Gas.Air.r * (weather.data.AnnualAvgDrybulb + 460.0))
2359
2610
  space_UAs['infil'] = infiltration_cfm * outside_air_density * Gas.Air.cp * UnitConversions.convert(1.0, 'hr', 'min')
2360
2611
 
@@ -2404,8 +2655,8 @@ class HVACSizing
2404
2655
  # when the roof is insulated
2405
2656
  min_temp_rise = 5.0
2406
2657
 
2407
- max_cooling_temp = @conditioned_cool_design_temp + max_temp_rise
2408
- min_cooling_temp = @conditioned_cool_design_temp + min_temp_rise
2658
+ max_cooling_temp = @cool_setpoint + max_temp_rise
2659
+ min_cooling_temp = @cool_setpoint + min_temp_rise
2409
2660
 
2410
2661
  ua_conditioned = 0.0
2411
2662
  ua_outside = 0.0
@@ -2447,42 +2698,85 @@ class HVACSizing
2447
2698
  wall_ufactor = 1.0 / wall.insulation_assembly_r_value
2448
2699
 
2449
2700
  # 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
2701
+ if wall_type == HPXML::WallTypeWoodStud
2702
+ if wall.siding == HPXML::SidingTypeBrick
2703
+ if wall_ufactor <= 0.070
2704
+ wall_group = 11 # K
2705
+ elsif wall_ufactor <= 0.083
2706
+ wall_group = 10 # J
2707
+ elsif wall_ufactor <= 0.095
2708
+ wall_group = 9 # I
2709
+ elsif wall_ufactor <= 0.100
2710
+ wall_group = 8 # H
2711
+ elsif wall_ufactor <= 0.130
2712
+ wall_group = 7 # G
2713
+ elsif wall_ufactor <= 0.175
2714
+ wall_group = 6 # F
2470
2715
  else
2471
- wall_group += 4
2716
+ wall_group = 5 # E
2472
2717
  end
2473
- elsif wall.insulation_continuous_r_value > 7
2474
- if wall.insulation_cavity_r_value < 2
2475
- wall_group += 4
2718
+ else
2719
+ if wall_ufactor <= 0.048
2720
+ wall_group = 10 # J
2721
+ elsif wall_ufactor <= 0.051
2722
+ wall_group = 9 # I
2723
+ elsif wall_ufactor <= 0.059
2724
+ wall_group = 8 # H
2725
+ elsif wall_ufactor <= 0.063
2726
+ wall_group = 7 # G
2727
+ elsif wall_ufactor <= 0.067
2728
+ wall_group = 6 # F
2729
+ elsif wall_ufactor <= 0.075
2730
+ wall_group = 5 # E
2731
+ elsif wall_ufactor <= 0.086
2732
+ wall_group = 4 # D
2733
+ elsif wall_ufactor <= 0.110
2734
+ wall_group = 3 # C
2735
+ elsif wall_ufactor <= 0.170
2736
+ wall_group = 2 # B
2476
2737
  else
2477
- wall_group += 6
2738
+ wall_group = 1 # A
2478
2739
  end
2479
2740
  end
2480
- # Adjust the wall group for brick siding
2741
+
2742
+ elsif wall_type == HPXML::WallTypeSteelStud
2481
2743
  if wall.siding == HPXML::SidingTypeBrick
2482
- if wall.insulation_cavity_r_value < 2
2483
- wall_group += 4
2744
+ if wall_ufactor <= 0.090
2745
+ wall_group = 11 # K
2746
+ elsif wall_ufactor <= 0.105
2747
+ wall_group = 10 # J
2748
+ elsif wall_ufactor <= 0.118
2749
+ wall_group = 9 # I
2750
+ elsif wall_ufactor <= 0.125
2751
+ wall_group = 8 # H
2752
+ elsif wall_ufactor <= 0.145
2753
+ wall_group = 7 # G
2754
+ elsif wall_ufactor <= 0.200
2755
+ wall_group = 6 # F
2756
+ else
2757
+ wall_group = 5 # E
2758
+ end
2759
+ else
2760
+ if wall_ufactor <= 0.066
2761
+ wall_group = 10 # J
2762
+ elsif wall_ufactor <= 0.070
2763
+ wall_group = 9 # I
2764
+ elsif wall_ufactor <= 0.075
2765
+ wall_group = 8 # H
2766
+ elsif wall_ufactor <= 0.081
2767
+ wall_group = 7 # G
2768
+ elsif wall_ufactor <= 0.088
2769
+ wall_group = 6 # F
2770
+ elsif wall_ufactor <= 0.100
2771
+ wall_group = 5 # E
2772
+ elsif wall_ufactor <= 0.105
2773
+ wall_group = 4 # D
2774
+ elsif wall_ufactor <= 0.120
2775
+ wall_group = 3 # C
2776
+ elsif wall_ufactor <= 0.200
2777
+ wall_group = 2 # B
2484
2778
  else
2485
- wall_group += 6
2779
+ wall_group = 1 # A
2486
2780
  end
2487
2781
  end
2488
2782
 
@@ -2511,24 +2805,20 @@ class HVACSizing
2511
2805
  end
2512
2806
 
2513
2807
  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
2808
+ # Table 4A - Construction Number 13
2809
+ if wall_ufactor <= 0.0575
2524
2810
  wall_group = 10 # J
2525
- elsif wall.insulation_cavity_r_value <= 21
2526
- wall_group = 11 # K
2811
+ elsif wall_ufactor <= 0.067
2812
+ wall_group = 9 # I
2813
+ elsif wall_ufactor <= 0.080
2814
+ wall_group = 8 # H
2815
+ elsif wall_ufactor <= 0.108
2816
+ wall_group = 7 # G
2817
+ elsif wall_ufactor <= 0.148
2818
+ wall_group = 6 # F
2527
2819
  else
2528
- wall_group = 11 # K
2820
+ wall_group = 5 # E
2529
2821
  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
2822
 
2533
2823
  elsif [HPXML::WallTypeBrick, HPXML::WallTypeAdobe].include? wall_type
2534
2824
  # Two Courses Brick
@@ -2569,32 +2859,40 @@ class HVACSizing
2569
2859
  return wall_group
2570
2860
  end
2571
2861
 
2572
- def self.gshp_hx_pipe_rvalue(pipe_od, pipe_id, pipe_cond)
2862
+ def self.gshp_coil_bf
2863
+ return 0.0806
2864
+ end
2865
+
2866
+ def self.gshp_coil_bf_ft_spec
2867
+ return [1.21005458, -0.00664200, 0.00000000, 0.00348246, 0.00000000, 0.00000000]
2868
+ end
2869
+
2870
+ def self.gshp_hx_pipe_rvalue(hvac)
2573
2871
  # Thermal Resistance of Pipe
2574
- return Math.log(pipe_od / pipe_id) / 2.0 / Math::PI / pipe_cond
2872
+ return Math.log(hvac.GSHP_pipe_od / hvac.GSHP_pipe_id) / 2.0 / Math::PI / hvac.GSHP_pipe_cond
2575
2873
  end
2576
2874
 
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'
2875
+ def self.gshp_hxbore_ft_per_ton(weather, hvac, bore_spacing, pipe_r_value)
2876
+ if hvac.GSHP_SpacingType == 'b'
2579
2877
  beta_0 = 17.4427
2580
2878
  beta_1 = -0.6052
2581
- elsif spacing_type == 'c'
2879
+ elsif hvac.GSHP_SpacingType == 'c'
2582
2880
  beta_0 = 21.9059
2583
2881
  beta_1 = -0.3796
2584
- elsif spacing_type == 'as'
2882
+ elsif hvac.GSHP_SpacingType == 'as'
2585
2883
  beta_0 = 20.1004
2586
2884
  beta_1 = -0.94467
2587
2885
  end
2588
2886
 
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)
2887
+ r_value_ground = Math.log(bore_spacing / hvac.GSHP_bore_d * 12.0) / 2.0 / Math::PI / hvac.GSHP_ground_k
2888
+ r_value_grout = 1.0 / hvac.GSHP_grout_k / beta_0 / ((hvac.GSHP_bore_d / hvac.GSHP_pipe_od)**beta_1)
2591
2889
  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
2890
 
2593
2891
  rtf_DesignMon_Heat = [0.25, (71.0 - weather.data.MonthlyAvgDrybulbs[0]) / @htd].max
2594
2892
  rtf_DesignMon_Cool = [0.25, (weather.data.MonthlyAvgDrybulbs[6] - 76.0) / @ctd].max
2595
2893
 
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')
2894
+ 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')
2895
+ 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
2896
 
2599
2897
  return nom_length_heat, nom_length_cool
2600
2898
  end
@@ -2602,9 +2900,9 @@ class HVACSizing
2602
2900
  def self.gshp_gfnc_coeff(bore_config, num_bore_holes, spacing_to_depth_ratio)
2603
2901
  # Set GFNC coefficients
2604
2902
  gfnc_coeff = nil
2605
- if bore_config == Constants.BoreConfigSingle
2903
+ if bore_config == 'single'
2606
2904
  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
2905
+ elsif bore_config == 'line'
2608
2906
  if num_bore_holes == 2
2609
2907
  if spacing_to_depth_ratio <= 0.02
2610
2908
  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 +3012,7 @@ class HVACSizing
2714
3012
  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
3013
  end
2716
3014
  end
2717
- elsif bore_config == Constants.BoreConfigLconfig
3015
+ elsif bore_config == 'l-config'
2718
3016
  if num_bore_holes == 3
2719
3017
  if spacing_to_depth_ratio <= 0.02
2720
3018
  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 +3062,7 @@ class HVACSizing
2764
3062
  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
3063
  end
2766
3064
  end
2767
- elsif bore_config == Constants.BoreConfigL2config
3065
+ elsif bore_config == 'l2-config'
2768
3066
  if num_bore_holes == 8
2769
3067
  if spacing_to_depth_ratio <= 0.02
2770
3068
  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 +3088,7 @@ class HVACSizing
2790
3088
  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
3089
  end
2792
3090
  end
2793
- elsif bore_config == Constants.BoreConfigUconfig
3091
+ elsif bore_config == 'u-config'
2794
3092
  if num_bore_holes == 5
2795
3093
  if spacing_to_depth_ratio <= 0.02
2796
3094
  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 +3126,7 @@ class HVACSizing
2828
3126
  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
3127
  end
2830
3128
  end
2831
- elsif bore_config == Constants.BoreConfigOpenRectangle
3129
+ elsif bore_config == 'open-rectangle'
2832
3130
  if num_bore_holes == 8
2833
3131
  if spacing_to_depth_ratio <= 0.02
2834
3132
  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 +3152,7 @@ class HVACSizing
2854
3152
  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
3153
  end
2856
3154
  end
2857
- elsif bore_config == Constants.BoreConfigRectangle
3155
+ elsif bore_config == 'rectangle'
2858
3156
  if num_bore_holes == 4
2859
3157
  if spacing_to_depth_ratio <= 0.02
2860
3158
  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 +3341,24 @@ class HVACSizing
3043
3341
 
3044
3342
  return f_values.sum() / f_values.size
3045
3343
  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
3344
  end
3401
3345
 
3402
- class ZoneLoads
3403
- # Thermal zone loads
3346
+ class DesignLoads
3404
3347
  def initialize
3405
3348
  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,
3349
+ attr_accessor(:Cool_Sens, :Cool_Lat, :Cool_Tot, :Heat_Tot, :Heat_Ducts, :Cool_Ducts_Sens, :Cool_Ducts_Lat,
3350
+ :Cool_Windows, :Cool_Skylights, :Cool_Doors, :Cool_Walls, :Cool_Roofs, :Cool_Floors,
3351
+ :Cool_Ceilings, :Cool_Infil_Sens, :Cool_Infil_Lat, :Cool_IntGains_Sens, :Cool_IntGains_Lat,
3408
3352
  :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)
3353
+ :Heat_Slabs, :Heat_Ceilings, :Heat_InfilVent)
3417
3354
  end
3418
3355
 
3419
- class FinalValues
3420
- # Final loads (including ducts), airflow rates, equipment capacities, etc.
3356
+ class HVACSizingValues
3421
3357
  def initialize
3422
3358
  end
3423
3359
  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
3360
  :Cool_Capacity, :Cool_Capacity_Sens, :Cool_Airflow,
3426
- :Heat_Load, :Heat_Load_Ducts,
3427
- :Heat_Capacity, :Heat_Capacity_Supp, :Heat_Airflow,
3361
+ :Heat_Load, :Heat_Capacity, :Heat_Capacity_Supp, :Heat_Airflow,
3428
3362
  :GSHP_Loop_flow, :GSHP_Bore_Holes, :GSHP_Bore_Depth, :GSHP_G_Functions)
3429
3363
  end
3430
3364
 
@@ -3439,37 +3373,29 @@ class HVACInfo
3439
3373
  self.CapacityRatioHeating = [1.0]
3440
3374
  self.OverSizeLimit = 1.15
3441
3375
  self.OverSizeDelta = 15000.0
3442
- self.FanspeedRatioCooling = [1.0]
3443
3376
  self.Ducts = []
3377
+ self.AirflowDefectRatioCooling = 0.0
3378
+ self.AirflowDefectRatioHeating = 0.0
3444
3379
  end
3445
3380
 
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,
3381
+ attr_accessor(:HeatType, :CoolType, :Ducts, :NumSpeedsCooling, :NumSpeedsHeating,
3459
3382
  :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,
3383
+ :AirflowDefectRatioCooling, :AirflowDefectRatioHeating,
3384
+ :RatedCFMperTonCooling, :RatedCFMperTonHeating, :ChargeDefectRatio,
3385
+ :COOL_CAP_FT_SPEC, :HEAT_CAP_FT_SPEC, :COOL_SH_FT_SPEC,
3386
+ :COOL_CAP_FFLOW_SPEC, :HEAT_CAP_FFLOW_SPEC,
3387
+ :SHRRated, :CapacityRatioCooling, :CapacityRatioHeating,
3388
+ :OverSizeLimit, :OverSizeDelta,
3389
+ :HeatingEIR, :CoolingEIR, :SizingSpeed, :HeatingCOP,
3390
+ :GSHP_SpacingType, :EvapCoolerEffectiveness,
3467
3391
  :HeatingLoadFraction, :CoolingLoadFraction, :SupplyAirTemp, :LeavingAirTemp,
3468
- :EvapCoolerEffectiveness)
3392
+ :GSHP_design_chw, :GSHP_design_delta_t, :GSHP_design_hw, :GSHP_bore_d,
3393
+ :GSHP_pipe_od, :GSHP_pipe_id, :GSHP_pipe_cond, :GSHP_ground_k, :GSHP_grout_k)
3469
3394
  end
3470
3395
 
3471
3396
  class DuctInfo
3472
3397
  # Model info for a duct
3398
+ # FUTURE: Remove class; use either airflow.rb Duct class or HPXML Ducts class directly
3473
3399
  def initial
3474
3400
  end
3475
3401
  attr_accessor(:LeakageFrac, :LeakageCFM25, :Area, :Rvalue, :Location, :Side)