urbanopt-cli 0.4.1 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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)