urbanopt-cli 0.4.1 → 0.6.1

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