urbanopt-cli 0.4.1 → 0.6.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -1
- data/CHANGELOG.md +59 -0
- data/CMakeLists.txt +17 -17
- data/FindOpenStudioSDK.cmake +12 -7
- data/Gemfile +8 -10
- data/LICENSE.md +11 -1
- data/README.md +1 -0
- data/Rakefile +16 -6
- data/example_files/Gemfile +25 -9
- data/example_files/example_project.json +35 -20
- data/example_files/example_project_combined.json +100 -5
- data/example_files/example_project_with_electric_network.json +2116 -0
- data/example_files/mappers/Baseline.rb +111 -51
- data/example_files/mappers/CreateBar.rb +19 -7
- data/example_files/mappers/EvCharging.rb +141 -0
- data/example_files/mappers/Floorspace.rb +29 -17
- data/example_files/mappers/HighEfficiency.rb +20 -8
- data/example_files/mappers/HighEfficiencyCreateBar.rb +19 -8
- data/example_files/mappers/HighEfficiencyFloorspace.rb +19 -8
- data/example_files/mappers/ThermalStorage.rb +16 -6
- data/example_files/mappers/base_workflow.osw +26 -1
- data/example_files/mappers/floorspace_workflow.osw +9 -0
- data/example_files/measures/BuildResidentialModel/measure.rb +249 -134
- data/example_files/reopt/base_assumptions.json +2 -2
- data/example_files/reopt/multiPV_assumptions.json +4 -3
- data/example_files/residential/clothes_dryer.tsv +7 -7
- data/example_files/residential/clothes_washer.tsv +2 -2
- data/example_files/residential/cooling_system.tsv +42 -22
- data/example_files/residential/dishwasher.tsv +1 -1
- data/example_files/residential/exhaust.tsv +3 -0
- data/example_files/residential/heat_pump.tsv +62 -40
- data/example_files/residential/water_heater.tsv +1 -1
- data/example_files/resources/hpxml-measures/.github/pull_request_template.md +14 -0
- data/example_files/resources/hpxml-measures/.github/workflows/config.yml +116 -0
- data/example_files/resources/hpxml-measures/.gitignore +1 -8
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.rb +1088 -1329
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.xml +1819 -1383
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/constants.rb +0 -8
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb +450 -362
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules.rb +165 -112
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_config.json +388 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_config.md +43 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_weekday_state_and_monthly_schedule_shift.csv +613 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_weekend_state_and_monthly_schedule_shift.csv +613 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-coal.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{base-appliances-dehumidifier-ief.osw → base-appliances-dehumidifier-ief-portable.osw} +57 -83
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{base-appliances-dehumidifier-50percent.osw → base-appliances-dehumidifier-ief-whole-home.osw} +59 -85
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-dehumidifier.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-gas.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-modified.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-none.osw +61 -87
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-oil.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-propane.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-appliances-wood.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-flat.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-radiant-barrier.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-unvented-insulated-roof.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-atticroof-vented.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-boiler-only-baseboard.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-boiler-only-fan-coil.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-mechvent-shared-preconditioning.osw → base-bldgtype-multifamily-shared-mechvent-preconditioning.osw} +70 -95
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-mechvent-shared.osw → base-bldgtype-multifamily-shared-mechvent.osw} +70 -95
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-pv.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily-shared-water-heater.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-bldgtype-multifamily.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{base-single-family-attached.osw → base-bldgtype-single-family-attached.osw} +59 -85
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-combi-tankless-outside.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-combi-tankless.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-dwhr.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect-outside.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect-standbyloss.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect-with-solar-fraction.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-indirect.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-electric.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-gas.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-hpwh.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-jacket-indirect.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-low-flow-fixtures.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-none.osw +57 -83
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-demand.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-manual.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-nocontrol.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-temperature.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-recirc-timer.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-direct-evacuated-tube.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-direct-flat-plate.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-direct-ics.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-fraction.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-indirect-flat-plate.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-solar-thermosyphon-flat-plate.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-coal.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-elec-uef.osw +338 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-gas-outside.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-gas-uef.osw +338 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-gas.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-outside.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-uef.osw +338 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-with-solar-fraction.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump-with-solar.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-heat-pump.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-oil.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tank-wood.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-electric-outside.osw +56 -83
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-electric-uef.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-electric.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas-uef.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas-with-solar-fraction.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas-with-solar.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-gas.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-dhw-tankless-propane.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-2stories-garage.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-2stories.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-1.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-2.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-4.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-beds-5.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-garage.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-ach-house-pressure.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-cfm-house-pressure.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-cfm50.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-flue.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-infil-natural-ach.osw +57 -83
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-overhangs.osw +57 -83
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-enclosure-windows-none.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-ambient.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-conditioned-basement-slab-insulation.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-slab.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unconditioned-basement-assembly-r.osw +55 -81
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unconditioned-basement-wall-insulation.osw +55 -81
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unconditioned-basement.osw +55 -81
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-unvented-crawlspace.osw +55 -81
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-foundation-vented-crawlspace.osw +55 -81
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-1-speed-cooling-only.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-1-speed-heating-only.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-1-speed.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-2-speed.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-air-to-air-heat-pump-var-speed.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-coal-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-elec-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-gas-central-ac-1-speed.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-gas-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-oil-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-propane-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-boiler-wood-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-only-1-speed.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-only-2-speed.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-only-var-speed.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-electric.osw +55 -81
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.osw +55 -81
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.osw +55 -81
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.osw +55 -81
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-dual-fuel-mini-split-heat-pump-ducted.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ducts-leakage-percent.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-elec-resistance-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-evap-cooler-furnace-gas.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-evap-cooler-only-ducted.osw +57 -83
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-evap-cooler-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-fireplace-wood-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-fixed-heater-gas-only.osw +57 -83
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-floor-furnace-propane-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-coal-only.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-elec-central-ac-1-speed.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-elec-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-central-ac-2-speed.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-central-ac-var-speed.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-gas-room-ac.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-oil-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-propane-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-furnace-wood-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ground-to-air-heat-pump-cooling-only.osw +336 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ground-to-air-heat-pump-heating-only.osw +336 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-ground-to-air-heat-pump.osw +56 -84
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-airflow-defect-furnace-gas-central-ac-1-speed.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-air-to-air-heat-pump-1-speed.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-air-to-air-heat-pump-2-speed.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-air-to-air-heat-pump-var-speed.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-central-ac-1-speed.osw +340 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-central-ac-2-speed.osw +340 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-central-ac-var-speed.osw +340 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-furnace-gas-only.osw +338 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-ground-to-air-heat-pump.osw +338 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-mini-split-air-conditioner-only-ducted.osw +338 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-all-mini-split-heat-pump-ducted.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-charge-defect-furnace-gas-central-ac-1-speed.osw +338 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-install-quality-none-furnace-gas-central-ac-1-speed.osw +340 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-air-conditioner-only-ducted.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-air-conditioner-only-ductless.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ducted-cooling-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ducted-heating-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ducted.osw +57 -83
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-mini-split-heat-pump-ductless.osw +57 -83
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-none.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-portable-heater-gas-only.osw +57 -83
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-programmable-thermostat-detailed.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-room-ac-only-33percent.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-room-ac-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-setpoints.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-stove-oil-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-stove-wood-pellets-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-undersized.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-hvac-wall-furnace-elec-only.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-lighting-ceiling-fans.osw +57 -83
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-lighting-detailed.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-AMY-2012.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-baltimore-md.osw +64 -90
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-dallas-tx.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-duluth-mn.osw +69 -95
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-helena-mt.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-honolulu-hi.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-miami-fl.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-phoenix-az.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-location-portland-or.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-balanced.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-bath-kitchen-fans.osw +64 -92
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-cfis-evap-cooler-only-ducted.osw +57 -83
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-cfis.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-erv-atre-asre.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-erv.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-exhaust-rated-flow-rate.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-exhaust.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-hrv-asre.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-hrv.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-supply.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-mechvent-whole-house-fan.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-defaults.osw +57 -83
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-loads-large-uncommon.osw +60 -86
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-loads-large-uncommon2.osw +60 -86
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-neighbor-shading.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-shielding-of-home.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-misc-usage-multiplier.osw +52 -78
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-pv.osw +52 -78
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-vacancy-6-months.osw → base-schedules-stochastic-vacant.osw} +59 -85
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-schedules-stochastic.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-schedules-user-specified.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-calendar-year-custom.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-daylight-saving-custom.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-daylight-saving-disabled.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-runperiod-1-month.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base-simcontrol-timestep-10-mins.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/base.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/build_residential_hpxml_test.rb +71 -57
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-auto.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-double-exterior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-eaves.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-single-exterior-front.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-bottom-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-bottom.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-middle-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-middle.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-top-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-left-top.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-bottom-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-bottom.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-middle-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-middle.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-top-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-middle-top.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-bottom-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-bottom.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-middle-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-middle.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-top-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab-right-top.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-slab.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-bottom-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-bottom.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-middle-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-middle.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-top-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-left-top.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-bottom-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-bottom.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-middle-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-middle.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-top-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-middle-top.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-bottom-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-bottom.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-middle-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-middle.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-top-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace-right-top.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-unvented-crawlspace.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-bottom-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-bottom.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-middle-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-middle.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-top-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-left-top.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-bottom-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-bottom.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-middle-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-middle.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-top-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-middle-top.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-bottom-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-bottom.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-middle-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-middle.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-top-double-loaded-interior.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace-right-top.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-multifamily-vented-crawlspace.osw +341 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-atticroof-conditioned-eaves-gable.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-atticroof-conditioned-eaves-hip.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-atticroof-flat.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{extra-pv-shared.osw → extra-bldgtype-single-family-attached-double-exterior.osw} +62 -89
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-double-loaded-interior.osw +339 -0
- 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
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-slab-middle.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-slab-right.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-slab.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unconditioned-basement-middle.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unconditioned-basement-right.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{base-multifamily.osw → extra-bldgtype-single-family-attached-unconditioned-basement.osw} +64 -91
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unvented-crawlspace-middle.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unvented-crawlspace-right.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-unvented-crawlspace.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-vented-crawlspace-middle.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-vented-crawlspace-right.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-bldgtype-single-family-attached-vented-crawlspace.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-dhw-solar-latitude.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-atticroof-conditioned-eaves-gable.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-atticroof-conditioned-eaves-hip.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-garage-atticroof-conditioned.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-garage-partially-protruded.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-enclosure-windows-shading.osw +339 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-gas-hot-tub-heater-with-zero-kwh.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-gas-pool-heater-with-zero-kwh.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-pv-roofpitch.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-schedules-random-seed.osw +338 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-boiler-to-heat-pump.osw +336 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-boiler-to-heating-system.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-fireplace-to-heat-pump.osw +337 -0
- 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
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-heating-system-portable-heater-to-heat-pump.osw +337 -0
- 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
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-second-refrigerator.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-clothes-washer-kwh.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-dishwasher-kwh.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-extra-refrigerator-kwh.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-freezer-kwh.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/extra-zero-refrigerator-kwh.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/conditioned-attic-with-floor-insulation.osw +59 -85
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/conditioned-attic-with-one-floor-above-grade.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/conditioned-basement-with-ceiling-insulation.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/cooling-system-and-heat-pump.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/dhw-indirect-without-boiler.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/ducts-location-and-areas-not-same-type.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/foundation-wall-insulation-greater-than-height.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/heating-system-and-heat-pump.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multifamily-bottom-crawlspace-zero-foundation-height.osw +64 -89
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multifamily-bottom-slab-non-zero-foundation-height.osw +64 -89
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multifamily-no-building-orientation.osw +63 -88
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{base-hvac-programmable-thermostat.osw → invalid_files/multipliers-without-fuel-loads.osw} +54 -80
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-other-plug-loads.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-tv-plug-loads.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{base-dhw-uef.osw → invalid_files/multipliers-without-vehicle-plug-loads.osw} +58 -84
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/multipliers-without-well-pump-plug-loads.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/non-electric-heat-pump-water-heater.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/non-integer-ceiling-fan-quantity.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/non-integer-geometry-num-bathrooms.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/second-heating-system-but-no-primary-heating.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/second-heating-system-serves-majority-heat.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/second-heating-system-serves-total-heat-load.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-attached-ambient.osw +58 -84
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-attached-no-building-orientation.osw +58 -84
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-detached-finished-basement-zero-foundation-height.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-detached-slab-non-zero-foundation-height.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/single-family-detached-with-shared-system.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/slab-non-zero-foundation-height-above-grade.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/unconditioned-basement-with-wall-and-ceiling-insulation.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/unvented-attic-with-floor-and-roof-insulation.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/unvented-crawlspace-with-wall-and-ceiling-insulation.osw +59 -85
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/vented-attic-with-floor-and-roof-insulation.osw +58 -84
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/vented-crawlspace-with-wall-and-ceiling-insulation.osw +56 -82
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/invalid_files/zero-number-of-bedrooms.osw +337 -0
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/schedules/vacant.csv +8761 -0
- data/example_files/resources/hpxml-measures/Changelog.md +249 -0
- data/example_files/resources/hpxml-measures/Gemfile +2 -5
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb +404 -1357
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml +247 -171
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/BaseElements.xsd +11 -101
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/EPvalidator.xml +824 -301
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/HPXMLDataTypes.xsd +18 -35
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/HPXMLvalidator.xml +526 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb +135 -207
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constants.rb +14 -186
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb +549 -93
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/energyplus.rb +12 -15
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/generator.rb +78 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb +413 -15
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb +48 -37
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb +1627 -1227
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_defaults.rb +1192 -434
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb +1555 -1616
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb +1436 -1479
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb +3 -2
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/location.rb +22 -10
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/meta_measure.rb +85 -19
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/minitest_helper.rb +4 -26
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb +22 -46
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/pv.rb +22 -21
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb +51 -14
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/simcontrols.rb +24 -7
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/unit_conversions.rb +2 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/validator.rb +80 -19
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb +9 -2
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb +106 -75
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb +109 -34
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb +22 -36
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_defaults.rb +1565 -768
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_enclosure.rb +151 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_generator.rb +101 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb +9 -18
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac.rb +316 -28
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb +53 -0
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb +4 -2
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_location.rb +13 -11
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb +4 -2
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_pv.rb +5 -3
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_simcontrols.rb +13 -11
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb +102 -62
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_water_heater.rb +189 -35
- data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/util.rb +26 -0
- data/example_files/resources/hpxml-measures/README.md +5 -5
- data/example_files/resources/hpxml-measures/Rakefile +2 -10
- data/example_files/resources/hpxml-measures/SimulationOutputReport/measure.rb +416 -299
- data/example_files/resources/hpxml-measures/SimulationOutputReport/measure.xml +364 -481
- data/example_files/resources/hpxml-measures/SimulationOutputReport/resources/constants.rb +1 -2
- data/example_files/resources/hpxml-measures/SimulationOutputReport/tests/output_report_test.rb +327 -320
- data/example_files/resources/hpxml-measures/docs/source/build_residential_hpxml.rst +3 -3
- data/example_files/resources/hpxml-measures/docs/source/conf.py +11 -5
- data/example_files/resources/hpxml-measures/docs/source/getting_started.rst +6 -6
- data/example_files/resources/hpxml-measures/docs/source/index.rst +2 -2
- data/example_files/resources/hpxml-measures/docs/source/intro.rst +7 -109
- data/example_files/resources/hpxml-measures/docs/source/nstatic/stylesheet.css +13 -1
- data/example_files/resources/hpxml-measures/docs/source/workflow_inputs.rst +2482 -0
- data/example_files/resources/hpxml-measures/docs/source/workflow_outputs.rst +282 -0
- data/example_files/resources/hpxml-measures/tasks.rb +2494 -1248
- data/example_files/resources/hpxml-measures/weather/USA_AZ_Phoenix-Sky.Harbor.Intl.AP.722780_TMY3-cache.csv +35 -0
- data/example_files/resources/hpxml-measures/weather/USA_AZ_Phoenix-Sky.Harbor.Intl.AP.722780_TMY3.epw +8768 -0
- data/example_files/resources/hpxml-measures/weather/USA_CO_Denver.Intl.AP.725650_TMY3-cache.csv +10 -10
- data/example_files/resources/hpxml-measures/weather/USA_HI_Honolulu.Intl.AP.911820_TMY3-cache.csv +35 -0
- data/example_files/resources/hpxml-measures/weather/USA_HI_Honolulu.Intl.AP.911820_TMY3.epw +8768 -0
- data/example_files/resources/hpxml-measures/weather/USA_MT_Helena.Rgnl.AP.727720_TMY3-cache.csv +35 -0
- data/example_files/resources/hpxml-measures/weather/USA_MT_Helena.Rgnl.AP.727720_TMY3.epw +8768 -0
- data/example_files/resources/hpxml-measures/weather/USA_OR_Portland.Intl.AP.726980_TMY3-cache.csv +35 -0
- data/example_files/resources/hpxml-measures/weather/USA_OR_Portland.Intl.AP.726980_TMY3.epw +8768 -0
- data/example_files/resources/hpxml-measures/workflow/run_simulation.rb +96 -21
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-coal.xml +558 -559
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-appliances-dehumidifier-ief.xml → base-appliances-dehumidifier-ief-portable.xml} +8 -7
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-appliances-dehumidifier-50percent.xml → base-appliances-dehumidifier-ief-whole-home.xml} +10 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-multiple.xml +535 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier.xml +525 -524
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-gas.xml +558 -559
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-modified.xml +564 -565
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-none.xml +513 -513
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil.xml +558 -559
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane.xml +558 -559
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-wood.xml +558 -559
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-cathedral.xml +565 -566
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-conditioned.xml +633 -634
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-flat.xml +531 -532
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-radiant-barrier.xml +517 -518
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-unvented-insulated-roof.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-vented.xml +565 -566
- 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
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multiple.xml +554 -0
- 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
- 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
- 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
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-baseboard.xml +425 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil-ducted.xml +457 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil.xml +427 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-water-loop-heat-pump.xml +479 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-cooling-tower-water-loop-heat-pump.xml +474 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-baseboard.xml +408 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-ducted.xml +439 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-eae.xml +406 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil.xml +409 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-water-loop-heat-pump.xml +457 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-baseboard.xml +407 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil-ducted.xml +438 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil.xml +408 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-water-loop-heat-pump.xml +456 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-cooling-tower-only-water-loop-heat-pump.xml +451 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-generator.xml +460 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-ground-loop-ground-to-air-heat-pump.xml +451 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-laundry-room.xml +466 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-mechvent-shared-multiple.xml → base-bldgtype-multifamily-shared-mechvent-multiple.xml} +43 -415
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-preconditioning.xml +489 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent.xml +473 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-pv.xml +465 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater-recirc.xml +458 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater.xml +451 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily.xml +448 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-single-family-attached.xml +619 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless-outside.xml +516 -519
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless.xml +516 -519
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-2-speed.xml +550 -551
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-gshp.xml +7 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-hpwh.xml +563 -564
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-tankless.xml +548 -549
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-var-speed.xml +550 -551
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater.xml +550 -551
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-dwhr.xml +567 -568
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-dse.xml +517 -520
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-outside.xml +517 -520
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-standbyloss.xml +518 -521
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-with-solar-fraction.xml +525 -528
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect.xml +517 -520
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-electric.xml +567 -568
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-gas.xml +568 -569
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-hpwh.xml +566 -567
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-indirect.xml +522 -525
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-low-flow-fixtures.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-multiple.xml +575 -578
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-none.xml +497 -497
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-demand.xml +565 -566
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-manual.xml +565 -566
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-nocontrol.xml +565 -566
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-temperature.xml +565 -566
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-timer.xml +565 -566
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-evacuated-tube.xml +577 -578
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-flat-plate.xml +577 -578
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-ics.xml +577 -578
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-fraction.xml +570 -571
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-indirect-flat-plate.xml +577 -578
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-thermosyphon-flat-plate.xml +577 -578
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-coal.xml +563 -564
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-elec-uef.xml +564 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-outside.xml +563 -564
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef.xml +565 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas.xml +563 -564
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-outside.xml +561 -562
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-uef.xml +564 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar-fraction.xml +569 -570
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar.xml +576 -577
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump.xml +561 -562
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-oil.xml +563 -564
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-wood.xml +563 -564
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-outside.xml +561 -562
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-uef.xml +561 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric.xml +560 -561
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-uef.xml +561 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar-fraction.xml +568 -569
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar.xml +575 -576
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas.xml +560 -561
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-propane.xml +560 -561
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories-garage.xml +661 -664
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories.xml +575 -576
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-1.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-2.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-4.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-5.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-garage.xml +636 -639
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-ach-house-pressure.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm-house-pressure.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm50.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-flue.xml +565 -566
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-natural-ach.xml +561 -562
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-overhangs.xml +582 -578
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-rooftypes.xml +590 -591
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-shading.xml +601 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights.xml +590 -591
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-level.xml +517 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces.xml +2474 -2493
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces2.xml +2475 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-walltypes.xml +754 -755
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-none.xml +504 -505
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-enclosure-windows-interior-shading.xml → base-enclosure-windows-shading.xml} +23 -9
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-ambient.xml +498 -497
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-basement-garage.xml +644 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-complex.xml +724 -729
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-slab-insulation.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-wall-interior-insulation.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-multiple.xml +685 -688
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-slab.xml +516 -517
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-above-grade.xml +609 -610
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-assembly-r.xml +558 -559
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-wall-insulation.xml +573 -574
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement.xml +573 -574
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unvented-crawlspace.xml +573 -574
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-vented-crawlspace.xml +576 -577
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-walkout-basement.xml +627 -628
- 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
- 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
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed.xml +561 -562
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-2-speed.xml +561 -562
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed.xml +561 -562
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-cooling-only.xml +553 -0
- 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
- 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
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed.xml +558 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-air-to-air-heat-pump-1-speed.xml +559 -0
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-cooling-only.xml +555 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-heating-only.xml +560 -0
- 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
- 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
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-air-conditioner-only-ducted.xml +547 -0
- 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
- 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
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-manual-s-oversize-allowances.xml +560 -0
- 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
- 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
- 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
- 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
- data/example_files/resources/hpxml-measures/workflow/sample_files/{hvac_autosizing/base-autosize.xml → base-hvac-autosize.xml} +4 -5
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-coal-only.xml +518 -521
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-elec-only.xml +518 -521
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-central-ac-1-speed.xml +571 -573
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-only.xml +519 -522
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-oil-only.xml +518 -521
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-propane-only.xml +518 -521
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-wood-only.xml +518 -521
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed.xml +548 -549
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-2-speed.xml +548 -549
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-var-speed.xml +548 -549
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.xml +575 -576
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dse.xml +532 -535
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-electric.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-mini-split-heat-pump-ducted.xml +561 -562
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-percent.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-elec-resistance-only.xml +509 -512
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-furnace-gas.xml +555 -555
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only-ducted.xml +536 -528
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only.xml +503 -505
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fireplace-wood-only.xml +6 -7
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fixed-heater-gas-only.xml +6 -57
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-floor-furnace-propane-only.xml +6 -7
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-coal-only.xml +549 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-central-ac-1-speed.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-only.xml +548 -549
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-2-speed.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-var-speed.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only.xml +5 -7
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-room-ac.xml +560 -561
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-oil-only.xml +548 -549
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-propane-only.xml +548 -549
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-wood-only.xml +548 -549
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-x3-dse.xml +576 -579
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-cooling-only.xml +557 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-heating-only.xml +563 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump.xml +7 -9
- 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
- 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
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-air-to-air-heat-pump-2-speed.xml +567 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-air-to-air-heat-pump-var-speed.xml +567 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-furnace-gas-central-ac-1-speed.xml +572 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-furnace-gas-central-ac-2-speed.xml +572 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-furnace-gas-central-ac-var-speed.xml +572 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-furnace-gas-only.xml +553 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-all-ground-to-air-heat-pump.xml +566 -0
- 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
- 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
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-blower-efficiency-furnace-gas-central-ac-1-speed.xml +569 -0
- 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
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-none-furnace-gas-central-ac-1-speed.xml +570 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ducted.xml +547 -548
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ductless.xml +508 -511
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-cooling-only.xml +554 -555
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-heating-only.xml +560 -561
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted.xml +560 -561
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless.xml +515 -518
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple.xml +21 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-none.xml +486 -489
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-portable-heater-gas-only.xml +6 -57
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-programmable-thermostat-detailed.xml +567 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-programmable-thermostat.xml +570 -571
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-33percent.xml +508 -511
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only.xml +508 -511
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-oil-only.xml +6 -7
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-wood-pellets-only.xml +6 -7
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized-allow-increased-fixed-capacities.xml +565 -566
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-wall-furnace-elec-only.xml +6 -7
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-ceiling-fans.xml +573 -574
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-detailed.xml +585 -586
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-none.xml +488 -489
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-AMY-2012.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-baltimore-md.xml +573 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-dallas-tx.xml +516 -517
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-duluth-mn.xml +573 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-helena-mt.xml +563 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-honolulu-hi.xml +517 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-miami-fl.xml +516 -517
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-phoenix-az.xml +517 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-portland-or.xml +577 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-balanced.xml +574 -575
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-bath-kitchen-fans.xml +590 -591
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-dse.xml +545 -548
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-evap-cooler-only-ducted.xml +549 -541
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis.xml +575 -576
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv-atre-asre.xml +576 -577
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv.xml +576 -577
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust-rated-flow-rate.xml +574 -575
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust.xml +574 -575
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv-asre.xml +575 -576
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv.xml +575 -576
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-multiple.xml +796 -795
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-supply.xml +574 -575
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-whole-house-fan.xml +572 -573
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-defaults.xml +478 -495
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators.xml +579 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon.xml +758 -833
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon2.xml +749 -820
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-none.xml +550 -559
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-neighbor-shading.xml +575 -576
- data/example_files/resources/hpxml-measures/workflow/sample_files/{invalid_files/invalid-calendar-year.xml → base-misc-shielding-of-home.xml} +7 -8
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-usage-multiplier.xml +728 -725
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-multiple-buildings.xml +1657 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv.xml +6 -7
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-stochastic-vacant.xml +564 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-stochastic.xml +6 -7
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-user-specified.xml +6 -7
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-calendar-year-custom.xml +563 -564
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-custom.xml +569 -570
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-disabled.xml +565 -566
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-runperiod-1-month.xml +566 -567
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/base.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/boiler-invalid-afue.xml +519 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/cfis-with-hydronic-distribution.xml +532 -535
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/clothes-dryer-location.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/clothes-washer-location.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/cooking-range-location.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dehumidifier-fraction-served.xml +535 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dehumidifier-setpoints.xml +535 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dhw-frac-load-served.xml +575 -578
- data/example_files/resources/hpxml-measures/workflow/sample_files/{base-dhw-uef.xml → invalid_files/dhw-invalid-ef-tank.xml} +7 -8
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dhw-invalid-uef-tank-heat-pump.xml +564 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/dishwasher-location.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-leakage-cfm25.xml +563 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-leakage-percent.xml +563 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-location-unconditioned-space.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duct-location.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/duplicate-id.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-attic-missing-roof.xml +546 -547
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-basement-missing-exterior-foundation-wall.xml +543 -544
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-basement-missing-slab.xml +546 -545
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-floor-area-exceeds-cfa.xml +563 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-floor-area-exceeds-cfa2.xml +448 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-garage-missing-exterior-wall.xml +613 -616
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-garage-missing-roof-ceiling.xml +626 -629
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-garage-missing-slab.xml +610 -611
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-living-missing-ceiling-roof.xml +550 -551
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-living-missing-exterior-wall.xml +472 -473
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/enclosure-living-missing-floor-slab.xml +488 -534
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-sensible-fuel-load.xml +760 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-sensible-plug-load.xml +759 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-total-fuel-load.xml +761 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/frac-total-plug-load.xml +759 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/furnace-invalid-afue.xml +563 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/generator-number-of-bedrooms-served.xml +460 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/generator-output-greater-than-consumption.xml +579 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/heat-pump-mixed-fixed-and-autosize-capacities.xml +559 -560
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-distribution-multiple-attached-cooling.xml +21 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-distribution-multiple-attached-heating.xml +21 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-distribution-return-duct-leakage-missing.xml +528 -534
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-dse-multiple-attached-cooling.xml +546 -549
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-dse-multiple-attached-heating.xml +546 -549
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-frac-load-served.xml +21 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-inconsistent-fan-powers.xml +569 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-invalid-distribution-system-type.xml +570 -571
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/hvac-shared-negative-seer-eq.xml +407 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-assembly-effective-rvalue.xml +563 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-datatype-boolean.xml +563 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-datatype-float.xml +563 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-datatype-integer.xml +563 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-daylight-saving.xml +569 -567
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-distribution-cfa-served.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-epw-filepath.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-facility-type-equipment.xml +466 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-facility-type-surfaces.xml +644 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/{appliances-location-unconditioned-space.xml → invalid-foundation-wall-properties.xml} +39 -29
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-id.xml +591 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-id2.xml +591 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-infiltration-volume.xml +563 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-input-parameters.xml +565 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-neighbor-shading-azimuth.xml +575 -576
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-number-of-bedrooms-served.xml +465 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/{slab-zero-exposed-perimeter.xml → invalid-number-of-conditioned-floors.xml} +7 -8
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-number-of-units-served.xml +451 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-relatedhvac-desuperheater.xml +550 -551
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-relatedhvac-dhw-indirect.xml +517 -520
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-runperiod.xml +564 -565
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-schema-version.xml +563 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-shared-vent-in-unit-flowrate.xml +473 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-timestep.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-window-height.xml +582 -578
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/lighting-fractions.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/missing-duct-location.xml +21 -13
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/missing-elements.xml +560 -561
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-appliance.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-duct.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-surface.xml +575 -566
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multifamily-reference-water-heater.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-buildings-without-building-id.xml +1657 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-buildings-wrong-building-id.xml +1657 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-shared-cooling-systems.xml +432 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/multiple-shared-heating-systems.xml +434 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/net-area-negative-roof.xml +590 -591
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/net-area-negative-wall.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/num-bedrooms-exceeds-limit.xml +563 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/orphaned-hvac-distribution.xml +546 -547
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/refrigerator-location.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/refrigerators-multiple-primary.xml +568 -569
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/refrigerators-no-primary.xml +568 -569
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/repeated-relatedhvac-desuperheater.xml +563 -564
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/repeated-relatedhvac-dhw-indirect.xml +526 -529
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-fraction-one.xml +571 -0
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-thermal-system-with-combi-tankless.xml +531 -534
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-thermal-system-with-desuperheater.xml +565 -566
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/solar-thermal-system-with-dhw-indirect.xml +531 -534
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-cfis.xml +575 -576
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-door.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-hvac-distribution.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-shared-clothes-washer-water-heater.xml +465 -827
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-shared-dishwasher-water-heater.xml +465 -827
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-skylight.xml +590 -591
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-solar-thermal-system.xml +577 -578
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/unattached-window.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/water-heater-location-other.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/water-heater-location.xml +562 -563
- data/example_files/resources/hpxml-measures/workflow/template.osw +5 -1
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AC.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AL.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AC.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AL.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AC.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AL.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AC.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AL.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AC.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AL.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AC.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AL.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AC.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AL.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AC.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AL.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AC.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AL.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AC.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AL.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AC.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AL.xml +6 -17
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L302XC.xml +6 -19
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L304XC.xml +6 -19
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L322XC.xml +6 -19
- data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L324XC.xml +6 -19
- data/example_files/resources/hpxml-measures/workflow/tests/base_results/results.csv +294 -0
- data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_ashrae_140.csv +27 -0
- data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_hvac_sizing.csv +294 -0
- data/example_files/resources/hpxml-measures/workflow/tests/compare.rb +130 -0
- data/example_files/resources/hpxml-measures/workflow/tests/hpxml_translator_test.rb +522 -527
- data/example_files/{measures/BuildResidentialModel/resources → resources}/measure-info.json +0 -0
- data/example_files/{measures/BuildResidentialModel/resources → resources}/meta_measure.rb +53 -44
- data/example_files/validation_schema.yaml +149 -0
- data/example_files/visualization/input_visualization_feature.html +213 -56
- data/example_files/visualization/input_visualization_scenario.html +92 -30
- data/lib/uo_cli.rb +406 -128
- data/lib/uo_cli/version.rb +17 -7
- data/requirements.txt +2 -0
- data/scripts/setup-env-gitbash.sh +5 -5
- data/scripts/setup-env-unix.sh +4 -4
- data/scripts/setup-env.bat +14 -11
- data/scripts/setup-env.ps1 +13 -10
- data/uo_cli.gemspec +10 -8
- metadata +390 -130
- data/developer_nrel_key.rb +0 -31
- data/example_files/measures/ResidentialGeometryCreateMultifamily/measure.rb +0 -1005
- data/example_files/measures/ResidentialGeometryCreateMultifamily/measure.xml +0 -326
- data/example_files/measures/ResidentialGeometryCreateMultifamily/tests/create_residential_multifamily_geometry_test.rb +0 -477
- data/example_files/measures/ResidentialGeometryCreateSingleFamilyAttached/measure.rb +0 -1039
- data/example_files/measures/ResidentialGeometryCreateSingleFamilyAttached/measure.xml +0 -393
- data/example_files/measures/ResidentialGeometryCreateSingleFamilyAttached/tests/create_residential_single_family_attached_geometry_test.rb +0 -456
- data/example_files/measures/ResidentialGeometryCreateSingleFamilyDetached/measure.rb +0 -979
- data/example_files/measures/ResidentialGeometryCreateSingleFamilyDetached/measure.xml +0 -388
- data/example_files/measures/ResidentialGeometryCreateSingleFamilyDetached/tests/create_residential_single_family_detached_geometry_test.rb +0 -704
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/location.rb +0 -24
- data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/schedules_config.yml +0 -61
- data/example_files/resources/hpxml-measures/docs/source/hpxml_to_openstudio.rst +0 -1386
- data/example_files/resources/hpxml-measures/docs/source/simulation_output_report.rst +0 -252
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-shared-laundry-room.xml +0 -828
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-shared-water-heater-recirc.xml +0 -820
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-shared-water-heater.xml +0 -813
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-attached-multifamily.xml +0 -810
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-common-surfaces.xml +0 -928
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ideal-air.xml +0 -501
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple2.xml +0 -838
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-chiller-baseboard.xml +0 -777
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-chiller-fan-coil-ducted.xml +0 -808
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-chiller-fan-coil.xml +0 -780
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-chiller-water-loop-heat-pump.xml +0 -820
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-cooling-tower-water-loop-heat-pump.xml +0 -815
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-only-baseboard.xml +0 -760
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-only-fan-coil-ducted.xml +0 -790
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-only-fan-coil-eae.xml +0 -759
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-only-fan-coil.xml +0 -762
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-boiler-only-water-loop-heat-pump.xml +0 -796
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-chiller-only-baseboard.xml +0 -759
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-chiller-only-fan-coil-ducted.xml +0 -789
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-chiller-only-fan-coil.xml +0 -761
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-chiller-only-water-loop-heat-pump.xml +0 -796
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-cooling-tower-only-water-loop-heat-pump.xml +0 -791
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-shared-ground-loop-ground-to-air-heat-pump.xml +0 -814
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-shared-preconditioning.xml +0 -851
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-shared.xml +0 -835
- data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-shared.xml +0 -827
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/coal-for-non-boiler-heating.xml +0 -514
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-facility-type.xml +0 -828
- data/example_files/resources/hpxml-measures/workflow/sample_files/invalid_files/invalid-window-interior-shading.xml +0 -564
@@ -15,6 +15,13 @@ class HVAC
|
|
15
15
|
obj_name = Constants.ObjectNameCentralAirConditionerAndFurnace
|
16
16
|
end
|
17
17
|
|
18
|
+
if not heating_system.nil?
|
19
|
+
htg_ap = heating_system.additional_properties
|
20
|
+
end
|
21
|
+
if not cooling_system.nil?
|
22
|
+
clg_ap = cooling_system.additional_properties
|
23
|
+
end
|
24
|
+
|
18
25
|
if not heating_system.nil?
|
19
26
|
sequential_heat_load_frac = calc_sequential_load_fraction(heating_system.fraction_heat_load_served, remaining_heat_load_frac)
|
20
27
|
else
|
@@ -26,84 +33,14 @@ class HVAC
|
|
26
33
|
sequential_cool_load_frac = 0.0
|
27
34
|
end
|
28
35
|
|
36
|
+
# Cooling Coil
|
29
37
|
if not cooling_system.nil?
|
30
|
-
|
31
|
-
num_speeds = 1
|
32
|
-
elsif cooling_system.compressor_type == HPXML::HVACCompressorTypeTwoStage
|
33
|
-
num_speeds = 2
|
34
|
-
elsif cooling_system.compressor_type == HPXML::HVACCompressorTypeVariableSpeed
|
35
|
-
num_speeds = 4
|
36
|
-
end
|
37
|
-
fan_power_rated = get_fan_power_rated(cooling_system.cooling_efficiency_seer)
|
38
|
-
crankcase_kw, crankcase_temp = get_crankcase_assumptions(cooling_system.fraction_cool_load_served)
|
39
|
-
|
40
|
-
# Cooling Coil
|
41
|
-
|
42
|
-
cool_c_d = get_cool_c_d(num_speeds, cooling_system.cooling_efficiency_seer)
|
43
|
-
cool_cfm = cooling_system.cooling_cfm
|
44
|
-
if num_speeds == 1
|
45
|
-
cool_rated_airflow_rate = 386.1 # cfm/ton
|
46
|
-
cool_capacity_ratios = [1.0]
|
47
|
-
cool_fan_speed_ratios = [1.0]
|
48
|
-
cool_shrs = [cooling_system.cooling_shr]
|
49
|
-
cool_cap_ft_spec = [[3.670270705, -0.098652414, 0.000955906, 0.006552414, -0.0000156, -0.000131877]]
|
50
|
-
cool_eir_ft_spec = [[-3.302695861, 0.137871531, -0.001056996, -0.012573945, 0.000214638, -0.000145054]]
|
51
|
-
cool_cap_fflow_spec = [[0.718605468, 0.410099989, -0.128705457]]
|
52
|
-
cool_eir_fflow_spec = [[1.32299905, -0.477711207, 0.154712157]]
|
53
|
-
cool_eers = [calc_eer_cooling_1speed(cooling_system.cooling_efficiency_seer, fan_power_rated, cool_eir_ft_spec)]
|
54
|
-
elsif num_speeds == 2
|
55
|
-
cool_rated_airflow_rate = 355.2 # cfm/ton
|
56
|
-
cool_capacity_ratios = [0.72, 1.0]
|
57
|
-
cool_fan_speed_ratios = [0.86, 1.0]
|
58
|
-
cool_shrs = [cooling_system.cooling_shr - 0.02, cooling_system.cooling_shr] # TODO: is the following assumption correct (revisit Dylan's data?)? OR should value from HPXML be used for both stages
|
59
|
-
cool_cap_ft_spec = [[3.940185508, -0.104723455, 0.001019298, 0.006471171, -0.00000953, -0.000161658],
|
60
|
-
[3.109456535, -0.085520461, 0.000863238, 0.00863049, -0.0000210, -0.000140186]]
|
61
|
-
cool_eir_ft_spec = [[-3.877526888, 0.164566276, -0.001272755, -0.019956043, 0.000256512, -0.000133539],
|
62
|
-
[-1.990708931, 0.093969249, -0.00073335, -0.009062553, 0.000165099, -0.0000997]]
|
63
|
-
cool_cap_fflow_spec = [[0.65673024, 0.516470835, -0.172887149],
|
64
|
-
[0.690334551, 0.464383753, -0.154507638]]
|
65
|
-
cool_eir_fflow_spec = [[1.562945114, -0.791859997, 0.230030877],
|
66
|
-
[1.31565404, -0.482467162, 0.166239001]]
|
67
|
-
cool_eers = calc_eers_cooling_2speed(runner, cooling_system.cooling_efficiency_seer, cool_c_d, cool_capacity_ratios, cool_fan_speed_ratios, fan_power_rated, cool_eir_ft_spec, cool_cap_ft_spec)
|
68
|
-
elsif num_speeds == 4
|
69
|
-
cool_rated_airflow_rate = 411.0 # cfm/ton
|
70
|
-
cool_capacity_ratios = [0.36, 0.51, 0.67, 1.0]
|
71
|
-
cool_fan_speed_ratios = [0.42, 0.54, 0.68, 1.0]
|
72
|
-
cool_shrs = [1.115, 1.026, 1.013, 1.0].map { |mult| cooling_system.cooling_shr * mult }
|
73
|
-
# The following coefficients were generated using NREL experimental performance mapping for the Carrier unit
|
74
|
-
cool_cap_coeff_perf_map = [[1.6516044444444447, 0.0698916049382716, -0.0005546296296296296, -0.08870160493827162, 0.0004135802469135802, 0.00029077160493827157],
|
75
|
-
[-6.84948049382716, 0.26946, -0.0019413580246913577, -0.03281469135802469, 0.00015694444444444442, 3.32716049382716e-05],
|
76
|
-
[-4.53543086419753, 0.15358543209876546, -0.0009345679012345678, 0.002666913580246914, -7.993827160493826e-06, -0.00011617283950617283],
|
77
|
-
[-3.500948395061729, 0.11738987654320988, -0.0006580246913580248, 0.007003148148148148, -2.8518518518518517e-05, -0.0001284259259259259],
|
78
|
-
[1.8769221728395058, -0.04768641975308643, 0.0006885802469135801, 0.006643395061728395, 1.4209876543209876e-05, -0.00024043209876543206]]
|
79
|
-
cool_cap_ft_spec = cool_cap_coeff_perf_map.select { |i| [0, 1, 2, 4].include? cool_cap_coeff_perf_map.index(i) }
|
80
|
-
cool_cap_ft_spec_3 = cool_cap_coeff_perf_map.select { |i| [0, 1, 4].include? cool_cap_coeff_perf_map.index(i) }
|
81
|
-
cool_eir_coeff_perf_map = [[2.896298765432099, -0.12487654320987657, 0.0012148148148148148, 0.04492037037037037, 8.734567901234567e-05, -0.0006348765432098764],
|
82
|
-
[6.428076543209876, -0.20913209876543212, 0.0018521604938271604, 0.024392592592592594, 0.00019691358024691356, -0.0006012345679012346],
|
83
|
-
[5.136356049382716, -0.1591530864197531, 0.0014151234567901232, 0.018665555555555557, 0.00020398148148148147, -0.0005407407407407407],
|
84
|
-
[1.3823471604938273, -0.02875123456790123, 0.00038302469135802463, 0.006344814814814816, 0.00024836419753086417, -0.00047469135802469134],
|
85
|
-
[-1.0411735802469133, 0.055261604938271605, -0.0004404320987654321, 0.0002154938271604939, 0.00017484567901234564, -0.0002017901234567901]]
|
86
|
-
cool_eir_ft_spec = cool_eir_coeff_perf_map.select { |i| [0, 1, 2, 4].include? cool_eir_coeff_perf_map.index(i) }
|
87
|
-
cool_eir_ft_spec_3 = cool_eir_coeff_perf_map.select { |i| [0, 1, 4].include? cool_eir_coeff_perf_map.index(i) }
|
88
|
-
cool_cap_fflow_spec = [[1, 0, 0]] * 4
|
89
|
-
cool_eir_fflow_spec = [[1, 0, 0]] * 4
|
90
|
-
cap_ratio_seer_3 = cool_capacity_ratios.select { |i| [0, 1, 3].include? cool_capacity_ratios.index(i) }
|
91
|
-
fan_speed_seer_3 = cool_fan_speed_ratios.select { |i| [0, 1, 3].include? cool_fan_speed_ratios.index(i) }
|
92
|
-
cool_eers = calc_eers_cooling_4speed(runner, cooling_system.cooling_efficiency_seer, cool_c_d, cap_ratio_seer_3, fan_speed_seer_3, fan_power_rated, cool_eir_ft_spec_3, cool_cap_ft_spec_3)
|
93
|
-
end
|
94
|
-
cool_cfms_ton_rated = calc_cfms_ton_rated(cool_rated_airflow_rate, cool_fan_speed_ratios, cool_capacity_ratios)
|
95
|
-
cool_shrs_rated_gross = calc_shrs_rated_gross(num_speeds, cool_shrs, fan_power_rated, cool_cfms_ton_rated)
|
96
|
-
cool_eirs = calc_cool_eirs(num_speeds, cool_eers, fan_power_rated)
|
97
|
-
cool_closs_fplr_spec = [calc_plr_coefficients(cool_c_d)] * num_speeds
|
98
|
-
clg_coil = create_dx_cooling_coil(model, obj_name, (0...num_speeds).to_a, cool_eirs, cool_cap_ft_spec, cool_eir_ft_spec, cool_closs_fplr_spec, cool_cap_fflow_spec, cool_eir_fflow_spec, cool_shrs_rated_gross, cooling_system.cooling_capacity, crankcase_kw, crankcase_temp, fan_power_rated)
|
38
|
+
clg_coil = create_dx_cooling_coil(model, obj_name, cooling_system)
|
99
39
|
hvac_map[cooling_system.id] << clg_coil
|
100
40
|
end
|
101
41
|
|
42
|
+
# Heating Coil
|
102
43
|
if not heating_system.nil?
|
103
|
-
heat_cfm = heating_system.heating_cfm
|
104
|
-
|
105
|
-
# Heating Coil
|
106
|
-
|
107
44
|
if heating_system.heating_system_fuel == HPXML::FuelTypeElectricity
|
108
45
|
htg_coil = OpenStudio::Model::CoilHeatingElectric.new(model)
|
109
46
|
htg_coil.setEfficiency(heating_system.heating_efficiency_afue)
|
@@ -112,23 +49,39 @@ class HVAC
|
|
112
49
|
htg_coil.setGasBurnerEfficiency(heating_system.heating_efficiency_afue)
|
113
50
|
htg_coil.setParasiticElectricLoad(0)
|
114
51
|
htg_coil.setParasiticGasLoad(0)
|
115
|
-
htg_coil.setFuelType(EPlus.
|
52
|
+
htg_coil.setFuelType(EPlus.fuel_type(heating_system.heating_system_fuel))
|
116
53
|
end
|
54
|
+
htg_coil.setNominalCapacity(UnitConversions.convert(heating_system.heating_capacity, 'Btu/hr', 'W'))
|
117
55
|
htg_coil.setName(obj_name + ' htg coil')
|
118
|
-
if not heating_system.heating_capacity.nil?
|
119
|
-
htg_coil.setNominalCapacity(UnitConversions.convert([heating_system.heating_capacity, Constants.small].max, 'Btu/hr', 'W')) # Used by HVACSizing measure
|
120
|
-
end
|
121
56
|
hvac_map[heating_system.id] << htg_coil
|
122
57
|
end
|
123
58
|
|
124
59
|
# Fan
|
60
|
+
if (not cooling_system.nil?) && (not heating_system.nil?) && (cooling_system.fan_watts_per_cfm.to_f != heating_system.fan_watts_per_cfm.to_f)
|
61
|
+
fail "Fan powers for heating system '#{heating_system.id}' and cooling system '#{cooling_system.id}' are attached to a single distribution system and therefore must be the same."
|
62
|
+
end
|
125
63
|
|
64
|
+
if (not cooling_system.nil?) && (not cooling_system.fan_watts_per_cfm.nil?)
|
65
|
+
fan_watts_per_cfm = cooling_system.fan_watts_per_cfm
|
66
|
+
else
|
67
|
+
fan_watts_per_cfm = heating_system.fan_watts_per_cfm
|
68
|
+
end
|
126
69
|
if not cooling_system.nil?
|
127
|
-
|
70
|
+
num_speeds = clg_ap.num_speeds
|
128
71
|
else
|
129
|
-
|
72
|
+
num_speeds = 1
|
73
|
+
end
|
74
|
+
if not heating_system.nil?
|
75
|
+
htg_cfm = heating_system.heating_airflow_cfm
|
76
|
+
end
|
77
|
+
if not cooling_system.nil?
|
78
|
+
clg_cfm = cooling_system.cooling_airflow_cfm
|
79
|
+
end
|
80
|
+
fan_cfm = [htg_cfm.to_f, clg_cfm.to_f].max
|
81
|
+
if not cooling_system.nil?
|
82
|
+
fan_cfm *= clg_ap.cool_fan_speed_ratios.max
|
130
83
|
end
|
131
|
-
fan = create_supply_fan(model, obj_name, num_speeds,
|
84
|
+
fan = create_supply_fan(model, obj_name, num_speeds, fan_watts_per_cfm, fan_cfm)
|
132
85
|
if not cooling_system.nil?
|
133
86
|
hvac_map[cooling_system.id] += disaggregate_fan_or_pump(model, fan, nil, clg_coil, nil)
|
134
87
|
end
|
@@ -137,8 +90,7 @@ class HVAC
|
|
137
90
|
end
|
138
91
|
|
139
92
|
# Unitary System
|
140
|
-
|
141
|
-
air_loop_unitary = create_air_loop_unitary_system(model, obj_name, fan, htg_coil, clg_coil, nil, clg_cfm: cool_cfm, htg_cfm: heat_cfm)
|
93
|
+
air_loop_unitary = create_air_loop_unitary_system(model, obj_name, fan, htg_coil, clg_coil, nil, htg_cfm, clg_cfm)
|
142
94
|
if not cooling_system.nil?
|
143
95
|
hvac_map[cooling_system.id] << air_loop_unitary
|
144
96
|
end
|
@@ -146,20 +98,19 @@ class HVAC
|
|
146
98
|
hvac_map[heating_system.id] << air_loop_unitary
|
147
99
|
end
|
148
100
|
|
101
|
+
# Unitary System Performance
|
149
102
|
if (not cooling_system.nil?) && (num_speeds > 1)
|
150
|
-
# Unitary System Performance
|
151
103
|
perf = OpenStudio::Model::UnitarySystemPerformanceMultispeed.new(model)
|
152
104
|
perf.setSingleModeOperation(false)
|
153
105
|
for speed in 1..num_speeds
|
154
|
-
f = OpenStudio::Model::SupplyAirflowRatioField.fromCoolingRatio(cool_fan_speed_ratios[speed - 1])
|
106
|
+
f = OpenStudio::Model::SupplyAirflowRatioField.fromCoolingRatio(clg_ap.cool_fan_speed_ratios[speed - 1])
|
155
107
|
perf.addSupplyAirflowRatioField(f)
|
156
108
|
end
|
157
109
|
air_loop_unitary.setDesignSpecificationMultispeedObject(perf)
|
158
110
|
end
|
159
111
|
|
160
112
|
# Air Loop
|
161
|
-
|
162
|
-
air_loop = create_air_loop(model, obj_name, air_loop_unitary, control_zone, sequential_heat_load_frac, sequential_cool_load_frac)
|
113
|
+
air_loop = create_air_loop(model, obj_name, air_loop_unitary, control_zone, sequential_heat_load_frac, sequential_cool_load_frac, fan_cfm)
|
163
114
|
if not cooling_system.nil?
|
164
115
|
hvac_map[cooling_system.id] << air_loop
|
165
116
|
end
|
@@ -167,17 +118,8 @@ class HVAC
|
|
167
118
|
hvac_map[heating_system.id] << air_loop
|
168
119
|
end
|
169
120
|
|
170
|
-
#
|
171
|
-
|
172
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACCapacityRatioCooling, cool_capacity_ratios.join(','))
|
173
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACRatedCFMperTonCooling, cool_cfms_ton_rated.join(','))
|
174
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACFracCoolLoadServed, cooling_system.fraction_cool_load_served)
|
175
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACCoolType, Constants.ObjectNameCentralAirConditioner)
|
176
|
-
end
|
177
|
-
if not heating_system.nil?
|
178
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACFracHeatLoadServed, heating_system.fraction_heat_load_served)
|
179
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACHeatType, Constants.ObjectNameFurnace)
|
180
|
-
end
|
121
|
+
# HVAC Installation Quality
|
122
|
+
apply_installation_quality(model, heating_system, cooling_system, air_loop_unitary, htg_coil, clg_coil, control_zone)
|
181
123
|
end
|
182
124
|
|
183
125
|
def self.apply_room_air_conditioner(model, runner, cooling_system,
|
@@ -187,73 +129,57 @@ class HVAC
|
|
187
129
|
hvac_map[cooling_system.id] = []
|
188
130
|
obj_name = Constants.ObjectNameRoomAirConditioner
|
189
131
|
sequential_cool_load_frac = calc_sequential_load_fraction(cooling_system.fraction_cool_load_served, remaining_cool_load_frac)
|
190
|
-
|
132
|
+
|
133
|
+
clg_ap = cooling_system.additional_properties
|
191
134
|
|
192
135
|
# Performance curves
|
193
|
-
|
194
|
-
|
195
|
-
cool_cap_ft_spec = [0.43945980246913574, -0.0008922469135802481, 0.00013984567901234569, 0.0038489259259259253, -5.6327160493827156e-05, 2.041358024691358e-05]
|
196
|
-
cool_cap_ft_spec_si = convert_curve_biquadratic(cool_cap_ft_spec)
|
197
|
-
cool_eir_ft_spec = [6.310506172839506, -0.17705185185185185, 0.0014645061728395061, 0.012571604938271608, 0.0001493827160493827, -0.00040308641975308644]
|
198
|
-
cool_eir_ft_spec_si = convert_curve_biquadratic(cool_eir_ft_spec)
|
199
|
-
cool_cap_fflow_spec = [0.887, 0.1128, 0]
|
200
|
-
cool_eir_fflow_spec = [1.763, -0.6081, 0]
|
201
|
-
cool_plf_fplr = [0.78, 0.22, 0]
|
202
|
-
cfms_ton_rated = [312] # cfm/ton, medium speed
|
203
|
-
|
204
|
-
roomac_cap_ft_curve = create_curve_biquadratic(model, cool_cap_ft_spec_si, 'RoomAC-Cap-fT', 0, 100, 0, 100)
|
205
|
-
roomac_cap_fff_curve = create_curve_quadratic(model, cool_cap_fflow_spec, 'RoomAC-Cap-fFF', 0, 2, 0, 2)
|
206
|
-
roomac_eir_ft_curve = create_curve_biquadratic(model, cool_eir_ft_spec_si, 'RoomAC-eir-fT', 0, 100, 0, 100)
|
207
|
-
roomcac_eir_fff_curve = create_curve_quadratic(model, cool_eir_fflow_spec, 'RoomAC-eir-fFF', 0, 2, 0, 2)
|
208
|
-
roomac_plf_fplr_curve = create_curve_quadratic(model, cool_plf_fplr, 'RoomAC-PLF-fPLR', 0, 1, 0, 1)
|
136
|
+
cool_cap_ft_spec_si = convert_curve_biquadratic(clg_ap.cool_cap_ft_spec[0])
|
137
|
+
cool_eir_ft_spec_si = convert_curve_biquadratic(clg_ap.cool_eir_ft_spec[0])
|
209
138
|
|
210
|
-
|
139
|
+
roomac_cap_ft_curve = create_curve_biquadratic(model, cool_cap_ft_spec_si, 'Cool-CAP-fT', 0, 100, 0, 100)
|
140
|
+
roomac_cap_fff_curve = create_curve_quadratic(model, clg_ap.cool_cap_fflow_spec[0], 'Cool-CAP-fFF', 0, 2, 0, 2)
|
141
|
+
roomac_eir_ft_curve = create_curve_biquadratic(model, cool_eir_ft_spec_si, 'Cool-EIR-fT', 0, 100, 0, 100)
|
142
|
+
roomcac_eir_fff_curve = create_curve_quadratic(model, clg_ap.cool_eir_fflow_spec[0], 'Cool-EIR-fFF', 0, 2, 0, 2)
|
143
|
+
roomac_plf_fplr_curve = create_curve_quadratic(model, clg_ap.cool_plf_fplr_spec[0], 'Cool-PLF-fPLR', 0, 1, 0, 1)
|
211
144
|
|
145
|
+
# Cooling Coil
|
212
146
|
clg_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(model, model.alwaysOnDiscreteSchedule, roomac_cap_ft_curve, roomac_cap_fff_curve, roomac_eir_ft_curve, roomcac_eir_fff_curve, roomac_plf_fplr_curve)
|
213
147
|
clg_coil.setName(obj_name + ' clg coil')
|
214
|
-
if not cooling_system.cooling_capacity.nil?
|
215
|
-
clg_coil.setRatedTotalCoolingCapacity(UnitConversions.convert([cooling_system.cooling_capacity, Constants.small].max, 'Btu/hr', 'W')) # Used by HVACSizing measure
|
216
|
-
end
|
217
148
|
clg_coil.setRatedSensibleHeatRatio(cooling_system.cooling_shr)
|
218
149
|
clg_coil.setRatedCOP(UnitConversions.convert(cooling_system.cooling_efficiency_eer, 'Btu/hr', 'W'))
|
219
150
|
clg_coil.setRatedEvaporatorFanPowerPerVolumeFlowRate(773.3)
|
220
151
|
clg_coil.setEvaporativeCondenserEffectiveness(0.9)
|
221
152
|
clg_coil.setMaximumOutdoorDryBulbTemperatureForCrankcaseHeaterOperation(10)
|
222
153
|
clg_coil.setBasinHeaterSetpointTemperature(2)
|
154
|
+
clg_coil.setRatedTotalCoolingCapacity(UnitConversions.convert(cooling_system.cooling_capacity, 'Btu/hr', 'W'))
|
155
|
+
clg_coil.setRatedAirFlowRate(calc_rated_airflow(cooling_system.cooling_capacity, clg_ap.cool_rated_cfm_per_ton[0], 1.0))
|
223
156
|
hvac_map[cooling_system.id] << clg_coil
|
224
157
|
|
225
158
|
# Fan
|
226
|
-
|
227
|
-
fan =
|
228
|
-
fan.setName(obj_name + ' supply fan')
|
229
|
-
fan.setEndUseSubcategory('supply fan')
|
230
|
-
fan.setFanEfficiency(1)
|
231
|
-
fan.setPressureRise(0)
|
232
|
-
fan.setMotorEfficiency(1)
|
233
|
-
fan.setMotorInAirstreamFraction(0)
|
159
|
+
clg_cfm = cooling_system.cooling_airflow_cfm
|
160
|
+
fan = create_supply_fan(model, obj_name, 1, 0.0, clg_cfm) # Fan power included in EER (net COP) above
|
234
161
|
hvac_map[cooling_system.id] += disaggregate_fan_or_pump(model, fan, nil, clg_coil, nil)
|
235
162
|
|
236
163
|
# Heating Coil (none)
|
237
|
-
|
238
164
|
htg_coil = OpenStudio::Model::CoilHeatingElectric.new(model, model.alwaysOffDiscreteSchedule())
|
165
|
+
htg_coil.setNominalCapacity(0.0)
|
239
166
|
htg_coil.setName(obj_name + ' htg coil')
|
240
167
|
|
241
168
|
# PTAC
|
242
|
-
|
243
169
|
ptac = OpenStudio::Model::ZoneHVACPackagedTerminalAirConditioner.new(model, model.alwaysOnDiscreteSchedule, fan, htg_coil, clg_coil)
|
244
170
|
ptac.setName(obj_name)
|
245
171
|
ptac.setSupplyAirFanOperatingModeSchedule(model.alwaysOffDiscreteSchedule)
|
172
|
+
ptac.setSupplyAirFlowRateDuringCoolingOperation(UnitConversions.convert(clg_cfm, 'cfm', 'm^3/s'))
|
173
|
+
ptac.setSupplyAirFlowRateDuringHeatingOperation(0.00001)
|
174
|
+
ptac.setSupplyAirFlowRateWhenNoCoolingorHeatingisNeeded(0.0)
|
175
|
+
ptac.setOutdoorAirFlowRateDuringCoolingOperation(0.0)
|
176
|
+
ptac.setOutdoorAirFlowRateDuringHeatingOperation(0.0)
|
177
|
+
ptac.setOutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded(0.0)
|
246
178
|
ptac.addToThermalZone(control_zone)
|
247
179
|
hvac_map[cooling_system.id] << ptac
|
248
180
|
|
249
181
|
control_zone.setSequentialCoolingFractionSchedule(ptac, get_sequential_load_schedule(model, sequential_cool_load_frac))
|
250
182
|
control_zone.setSequentialHeatingFractionSchedule(ptac, get_sequential_load_schedule(model, 0))
|
251
|
-
|
252
|
-
# Store info for HVAC Sizing measure
|
253
|
-
ptac.additionalProperties.setFeature(Constants.SizingInfoHVACCoolingCFMs, airflow_rate.to_s)
|
254
|
-
ptac.additionalProperties.setFeature(Constants.SizingInfoHVACRatedCFMperTonCooling, cfms_ton_rated.join(','))
|
255
|
-
ptac.additionalProperties.setFeature(Constants.SizingInfoHVACFracCoolLoadServed, cooling_system.fraction_cool_load_served)
|
256
|
-
ptac.additionalProperties.setFeature(Constants.SizingInfoHVACCoolType, Constants.ObjectNameRoomAirConditioner)
|
257
183
|
end
|
258
184
|
|
259
185
|
def self.apply_evaporative_cooler(model, runner, cooling_system,
|
@@ -264,29 +190,28 @@ class HVAC
|
|
264
190
|
obj_name = Constants.ObjectNameEvaporativeCooler
|
265
191
|
sequential_cool_load_frac = calc_sequential_load_fraction(cooling_system.fraction_cool_load_served, remaining_cool_load_frac)
|
266
192
|
|
267
|
-
|
193
|
+
clg_ap = cooling_system.additional_properties
|
194
|
+
clg_cfm = cooling_system.cooling_airflow_cfm
|
268
195
|
|
196
|
+
# Evap Cooler
|
269
197
|
evap_cooler = OpenStudio::Model::EvaporativeCoolerDirectResearchSpecial.new(model, model.alwaysOnDiscreteSchedule)
|
270
198
|
evap_cooler.setName(obj_name)
|
271
|
-
evap_cooler.setCoolerEffectiveness(
|
199
|
+
evap_cooler.setCoolerEffectiveness(clg_ap.effectiveness)
|
272
200
|
evap_cooler.setEvaporativeOperationMinimumDrybulbTemperature(0) # relax limitation to open evap cooler for any potential cooling
|
273
201
|
evap_cooler.setEvaporativeOperationMaximumLimitWetbulbTemperature(50) # relax limitation to open evap cooler for any potential cooling
|
274
202
|
evap_cooler.setEvaporativeOperationMaximumLimitDrybulbTemperature(50) # relax limitation to open evap cooler for any potential cooling
|
203
|
+
evap_cooler.setPrimaryAirDesignFlowRate(UnitConversions.convert(clg_cfm, 'cfm', 'm^3/s'))
|
275
204
|
hvac_map[cooling_system.id] << evap_cooler
|
276
205
|
|
277
206
|
# Air Loop
|
278
|
-
|
279
|
-
air_loop = create_air_loop(model, obj_name, evap_cooler, control_zone, 0, sequential_cool_load_frac)
|
280
|
-
air_loop.additionalProperties.setFeature(Constants.SizingInfoHVACSystemIsDucted, !cooling_system.distribution_system_idref.nil?)
|
281
|
-
air_loop.additionalProperties.setFeature(Constants.SizingInfoHVACCoolType, Constants.ObjectNameEvaporativeCooler)
|
207
|
+
air_loop = create_air_loop(model, obj_name, evap_cooler, control_zone, 0, sequential_cool_load_frac, clg_cfm)
|
282
208
|
hvac_map[cooling_system.id] << air_loop
|
283
209
|
|
284
210
|
# Fan
|
285
|
-
|
211
|
+
# Use VariableVolume object
|
286
212
|
fan = OpenStudio::Model::FanVariableVolume.new(model, model.alwaysOnDiscreteSchedule)
|
287
213
|
fan.setName(obj_name + ' supply fan')
|
288
214
|
fan.setEndUseSubcategory('supply fan')
|
289
|
-
fan.setFanEfficiency(1)
|
290
215
|
fan.setMotorEfficiency(1)
|
291
216
|
fan.setMotorInAirstreamFraction(0)
|
292
217
|
fan.setFanPowerCoefficient1(0)
|
@@ -294,6 +219,9 @@ class HVAC
|
|
294
219
|
fan.setFanPowerCoefficient3(0)
|
295
220
|
fan.setFanPowerCoefficient4(0)
|
296
221
|
fan.setFanPowerCoefficient5(0)
|
222
|
+
fan.setMaximumFlowRate(UnitConversions.convert(clg_cfm, 'cfm', 'm^3/s'))
|
223
|
+
fan_watts_per_cfm = [2.79 * clg_cfm**-0.29, 0.6].min # W/cfm; fit of efficacy to air flow from the CEC listed equipment
|
224
|
+
set_fan_power(fan, fan_watts_per_cfm)
|
297
225
|
fan.addToNode(air_loop.supplyInletNode)
|
298
226
|
hvac_map[cooling_system.id] += disaggregate_fan_or_pump(model, fan, nil, evap_cooler, nil)
|
299
227
|
|
@@ -303,6 +231,7 @@ class HVAC
|
|
303
231
|
oa_intake_controller.setMinimumLimitType('FixedMinimum')
|
304
232
|
oa_intake_controller.resetEconomizerMinimumLimitDryBulbTemperature
|
305
233
|
oa_intake_controller.setMinimumFractionofOutdoorAirSchedule(model.alwaysOnDiscreteSchedule)
|
234
|
+
oa_intake_controller.setMaximumOutdoorAirFlowRate(UnitConversions.convert(clg_cfm, 'cfm', 'm^3/s'))
|
306
235
|
|
307
236
|
oa_intake = OpenStudio::Model::AirLoopHVACOutdoorAirSystem.new(model, oa_intake_controller)
|
308
237
|
oa_intake.setName("#{air_loop.name} OA System")
|
@@ -315,10 +244,6 @@ class HVAC
|
|
315
244
|
evap_stpt_manager.setReferenceTemperatureType('OutdoorAirWetBulb')
|
316
245
|
evap_stpt_manager.setOffsetTemperatureDifference(0.0)
|
317
246
|
evap_stpt_manager.addToNode(air_loop.supplyOutletNode)
|
318
|
-
|
319
|
-
# Store info for HVAC Sizing measure
|
320
|
-
evap_cooler.additionalProperties.setFeature(Constants.SizingInfoHVACFracCoolLoadServed, cooling_system.fraction_cool_load_served)
|
321
|
-
evap_cooler.additionalProperties.setFeature(Constants.SizingInfoHVACCoolType, Constants.ObjectNameEvaporativeCooler)
|
322
247
|
end
|
323
248
|
|
324
249
|
def self.apply_central_air_to_air_heat_pump(model, runner, heat_pump,
|
@@ -330,205 +255,91 @@ class HVAC
|
|
330
255
|
obj_name = Constants.ObjectNameAirSourceHeatPump
|
331
256
|
sequential_heat_load_frac = calc_sequential_load_fraction(heat_pump.fraction_heat_load_served, remaining_heat_load_frac)
|
332
257
|
sequential_cool_load_frac = calc_sequential_load_fraction(heat_pump.fraction_cool_load_served, remaining_cool_load_frac)
|
333
|
-
if heat_pump.compressor_type == HPXML::HVACCompressorTypeSingleStage
|
334
|
-
num_speeds = 1
|
335
|
-
elsif heat_pump.compressor_type == HPXML::HVACCompressorTypeTwoStage
|
336
|
-
num_speeds = 2
|
337
|
-
elsif heat_pump.compressor_type == HPXML::HVACCompressorTypeVariableSpeed
|
338
|
-
num_speeds = 4
|
339
|
-
end
|
340
|
-
fan_power_rated = get_fan_power_rated(heat_pump.cooling_efficiency_seer)
|
341
|
-
if heat_pump.fraction_heat_load_served <= 0
|
342
|
-
crankcase_kw, crankcase_temp = 0, nil
|
343
|
-
else
|
344
|
-
crankcase_kw, crankcase_temp = get_crankcase_assumptions(heat_pump.fraction_cool_load_served)
|
345
|
-
end
|
346
|
-
hp_min_temp, supp_max_temp = get_heat_pump_temp_assumptions(heat_pump)
|
347
258
|
|
348
|
-
|
259
|
+
hp_ap = heat_pump.additional_properties
|
349
260
|
|
350
|
-
|
351
|
-
|
352
|
-
cool_rated_airflow_rate = 394.2 # cfm/ton
|
353
|
-
cool_capacity_ratios = [1.0]
|
354
|
-
cool_fan_speed_ratios = [1.0]
|
355
|
-
cool_shrs = [heat_pump.cooling_shr]
|
356
|
-
cool_cap_ft_spec = [[3.68637657, -0.098352478, 0.000956357, 0.005838141, -0.0000127, -0.000131702]]
|
357
|
-
cool_eir_ft_spec = [[-3.437356399, 0.136656369, -0.001049231, -0.0079378, 0.000185435, -0.0001441]]
|
358
|
-
cool_cap_fflow_spec = [[0.718664047, 0.41797409, -0.136638137]]
|
359
|
-
cool_eir_fflow_spec = [[1.143487507, -0.13943972, -0.004047787]]
|
360
|
-
cool_eers = [calc_eer_cooling_1speed(heat_pump.cooling_efficiency_seer, fan_power_rated, cool_eir_ft_spec)]
|
361
|
-
elsif num_speeds == 2
|
362
|
-
cool_rated_airflow_rate = 344.1 # cfm/ton
|
363
|
-
cool_capacity_ratios = [0.72, 1.0]
|
364
|
-
cool_fan_speed_ratios = [0.86, 1.0]
|
365
|
-
cool_shrs = [heat_pump.cooling_shr - 0.014, heat_pump.cooling_shr] # TODO: is the following assumption correct (revisit Dylan's data?)? OR should value from HPXML be used for both stages?
|
366
|
-
cool_cap_ft_spec = [[3.998418659, -0.108728222, 0.001056818, 0.007512314, -0.0000139, -0.000164716],
|
367
|
-
[3.466810106, -0.091476056, 0.000901205, 0.004163355, -0.00000919, -0.000110829]]
|
368
|
-
cool_eir_ft_spec = [[-4.282911381, 0.181023691, -0.001357391, -0.026310378, 0.000333282, -0.000197405],
|
369
|
-
[-3.557757517, 0.112737397, -0.000731381, 0.013184877, 0.000132645, -0.000338716]]
|
370
|
-
cool_cap_fflow_spec = [[0.655239515, 0.511655216, -0.166894731],
|
371
|
-
[0.618281092, 0.569060264, -0.187341356]]
|
372
|
-
cool_eir_fflow_spec = [[1.639108268, -0.998953996, 0.359845728],
|
373
|
-
[1.570774717, -0.914152018, 0.343377302]]
|
374
|
-
cool_eers = calc_eers_cooling_2speed(runner, heat_pump.cooling_efficiency_seer, cool_c_d, cool_capacity_ratios, cool_fan_speed_ratios, fan_power_rated, cool_eir_ft_spec, cool_cap_ft_spec, true)
|
375
|
-
elsif num_speeds == 4
|
376
|
-
cool_rated_airflow_rate = 411.0 # cfm/ton
|
377
|
-
cool_capacity_ratios = [0.36, 0.51, 0.67, 1.0]
|
378
|
-
cool_fan_speed_ratios = [0.42, 0.54, 0.68, 1.0]
|
379
|
-
cool_shrs = [1.115, 1.026, 1.013, 1.0].map { |mult| heat_pump.cooling_shr * mult }
|
380
|
-
# The following coefficients were generated using NREL experimental performance mapping for the Carrier unit
|
381
|
-
cool_cap_coeff_perf_map = [[1.6516044444444447, 0.0698916049382716, -0.0005546296296296296, -0.08870160493827162, 0.0004135802469135802, 0.00029077160493827157],
|
382
|
-
[-6.84948049382716, 0.26946, -0.0019413580246913577, -0.03281469135802469, 0.00015694444444444442, 3.32716049382716e-05],
|
383
|
-
[-4.53543086419753, 0.15358543209876546, -0.0009345679012345678, 0.002666913580246914, -7.993827160493826e-06, -0.00011617283950617283],
|
384
|
-
[-3.500948395061729, 0.11738987654320988, -0.0006580246913580248, 0.007003148148148148, -2.8518518518518517e-05, -0.0001284259259259259],
|
385
|
-
[1.8769221728395058, -0.04768641975308643, 0.0006885802469135801, 0.006643395061728395, 1.4209876543209876e-05, -0.00024043209876543206]]
|
386
|
-
cool_cap_ft_spec = cool_cap_coeff_perf_map.select { |i| [0, 1, 2, 4].include? cool_cap_coeff_perf_map.index(i) }
|
387
|
-
cool_cap_ft_spec_3 = cool_cap_coeff_perf_map.select { |i| [0, 1, 4].include? cool_cap_coeff_perf_map.index(i) }
|
388
|
-
cool_eir_coeff_perf_map = [[2.896298765432099, -0.12487654320987657, 0.0012148148148148148, 0.04492037037037037, 8.734567901234567e-05, -0.0006348765432098764],
|
389
|
-
[6.428076543209876, -0.20913209876543212, 0.0018521604938271604, 0.024392592592592594, 0.00019691358024691356, -0.0006012345679012346],
|
390
|
-
[5.136356049382716, -0.1591530864197531, 0.0014151234567901232, 0.018665555555555557, 0.00020398148148148147, -0.0005407407407407407],
|
391
|
-
[1.3823471604938273, -0.02875123456790123, 0.00038302469135802463, 0.006344814814814816, 0.00024836419753086417, -0.00047469135802469134],
|
392
|
-
[-1.0411735802469133, 0.055261604938271605, -0.0004404320987654321, 0.0002154938271604939, 0.00017484567901234564, -0.0002017901234567901]]
|
393
|
-
cool_eir_ft_spec = cool_eir_coeff_perf_map.select { |i| [0, 1, 2, 4].include? cool_eir_coeff_perf_map.index(i) }
|
394
|
-
cool_eir_ft_spec_3 = cool_eir_coeff_perf_map.select { |i| [0, 1, 4].include? cool_eir_coeff_perf_map.index(i) }
|
395
|
-
cool_eir_fflow_spec = [[1, 0, 0]] * 4
|
396
|
-
cool_cap_fflow_spec = [[1, 0, 0]] * 4
|
397
|
-
cap_ratio_seer_3 = cool_capacity_ratios.select { |i| [0, 1, 3].include? cool_capacity_ratios.index(i) }
|
398
|
-
fan_speed_seer_3 = cool_fan_speed_ratios.select { |i| [0, 1, 3].include? cool_fan_speed_ratios.index(i) }
|
399
|
-
cool_eers = calc_eers_cooling_4speed(runner, heat_pump.cooling_efficiency_seer, cool_c_d, cap_ratio_seer_3, fan_speed_seer_3, fan_power_rated, cool_eir_ft_spec_3, cool_cap_ft_spec_3)
|
400
|
-
end
|
401
|
-
cool_cfms_ton_rated = calc_cfms_ton_rated(cool_rated_airflow_rate, cool_fan_speed_ratios, cool_capacity_ratios)
|
402
|
-
cool_shrs_rated_gross = calc_shrs_rated_gross(num_speeds, cool_shrs, fan_power_rated, cool_cfms_ton_rated)
|
403
|
-
cool_eirs = calc_cool_eirs(num_speeds, cool_eers, fan_power_rated)
|
404
|
-
cool_closs_fplr_spec = [calc_plr_coefficients(cool_c_d)] * num_speeds
|
405
|
-
clg_coil = create_dx_cooling_coil(model, obj_name, (0...num_speeds).to_a, cool_eirs, cool_cap_ft_spec, cool_eir_ft_spec, cool_closs_fplr_spec, cool_cap_fflow_spec, cool_eir_fflow_spec, cool_shrs_rated_gross, heat_pump.cooling_capacity, 0, nil, fan_power_rated)
|
261
|
+
# Cooling Coil
|
262
|
+
clg_coil = create_dx_cooling_coil(model, obj_name, heat_pump)
|
406
263
|
hvac_map[heat_pump.id] << clg_coil
|
407
264
|
|
408
265
|
# Heating Coil
|
409
|
-
|
410
|
-
heat_c_d = get_heat_c_d(num_speeds, heat_pump.heating_efficiency_hspf)
|
411
|
-
if num_speeds == 1
|
412
|
-
heat_rated_airflow_rate = 384.1 # cfm/ton
|
413
|
-
heat_capacity_ratios = [1.0]
|
414
|
-
heat_fan_speed_ratios = [1.0]
|
415
|
-
heat_eir_ft_spec = [[0.718398423, 0.003498178, 0.000142202, -0.005724331, 0.00014085, -0.000215321]]
|
416
|
-
heat_cap_fflow_spec = [[0.694045465, 0.474207981, -0.168253446]]
|
417
|
-
heat_eir_fflow_spec = [[2.185418751, -1.942827919, 0.757409168]]
|
418
|
-
if heat_pump.heating_capacity_17F.nil?
|
419
|
-
heat_cap_ft_spec = [[0.566333415, -0.000744164, -0.0000103, 0.009414634, 0.0000506, -0.00000675]]
|
420
|
-
else
|
421
|
-
heat_cap_ft_spec = calc_heat_cap_ft_spec_using_capacity_17F(num_speeds, heat_pump)
|
422
|
-
end
|
423
|
-
heat_cops = [calc_cop_heating_1speed(heat_pump.heating_efficiency_hspf, heat_c_d, fan_power_rated, heat_eir_ft_spec, heat_cap_ft_spec)]
|
424
|
-
elsif num_speeds == 2
|
425
|
-
heat_rated_airflow_rate = 352.2 # cfm/ton
|
426
|
-
heat_capacity_ratios = [0.72, 1.0]
|
427
|
-
heat_fan_speed_ratios = [0.8, 1.0]
|
428
|
-
heat_eir_ft_spec = [[0.36338171, 0.013523725, 0.000258872, -0.009450269, 0.000439519, -0.000653723],
|
429
|
-
[0.981100941, -0.005158493, 0.000243416, -0.005274352, 0.000230742, -0.000336954]]
|
430
|
-
heat_cap_fflow_spec = [[0.741466907, 0.378645444, -0.119754733],
|
431
|
-
[0.76634609, 0.32840943, -0.094701495]]
|
432
|
-
heat_eir_fflow_spec = [[2.153618211, -1.737190609, 0.584269478],
|
433
|
-
[2.001041353, -1.58869128, 0.587593517]]
|
434
|
-
if heat_pump.heating_capacity_17F.nil?
|
435
|
-
heat_cap_ft_spec = [[0.335690634, 0.002405123, -0.0000464, 0.013498735, 0.0000499, -0.00000725],
|
436
|
-
[0.306358843, 0.005376987, -0.0000579, 0.011645092, 0.0000591, -0.0000203]]
|
437
|
-
else
|
438
|
-
heat_cap_ft_spec = calc_heat_cap_ft_spec_using_capacity_17F(num_speeds, heat_pump)
|
439
|
-
end
|
440
|
-
heat_cops = calc_cops_heating_2speed(heat_pump.heating_efficiency_hspf, heat_c_d, heat_capacity_ratios, heat_fan_speed_ratios, fan_power_rated, heat_eir_ft_spec, heat_cap_ft_spec)
|
441
|
-
elsif num_speeds == 4
|
442
|
-
heat_rated_airflow_rate = 296.9 # cfm/ton
|
443
|
-
heat_capacity_ratios = [0.33, 0.56, 1.0, 1.17]
|
444
|
-
heat_fan_speed_ratios = [0.63, 0.76, 1.0, 1.19]
|
445
|
-
heat_eir_ft_spec = [[0.708311527, 0.020732093, 0.000391479, -0.037640031, 0.000979937, -0.001079042],
|
446
|
-
[0.025480155, 0.020169585, 0.000121341, -0.004429789, 0.000166472, -0.00036447],
|
447
|
-
[0.379003189, 0.014195012, 0.0000821046, -0.008894061, 0.000151519, -0.000210299],
|
448
|
-
[0.690404655, 0.00616619, 0.000137643, -0.009350199, 0.000153427, -0.000213258]]
|
449
|
-
heat_cap_fflow_spec = [[1, 0, 0]] * 4
|
450
|
-
heat_eir_fflow_spec = [[1, 0, 0]] * 4
|
451
|
-
if heat_pump.heating_capacity_17F.nil?
|
452
|
-
heat_cap_ft_spec = [[0.304192655, -0.003972566, 0.0000196432, 0.024471251, -0.000000774126, -0.0000841323],
|
453
|
-
[0.496381324, -0.00144792, 0.0, 0.016020855, 0.0000203447, -0.0000584118],
|
454
|
-
[0.697171186, -0.006189599, 0.0000337077, 0.014291981, 0.0000105633, -0.0000387956],
|
455
|
-
[0.555513805, -0.001337363, -0.00000265117, 0.014328826, 0.0000163849, -0.0000480711]]
|
456
|
-
else
|
457
|
-
heat_cap_ft_spec = calc_heat_cap_ft_spec_using_capacity_17F(num_speeds, heat_pump)
|
458
|
-
end
|
459
|
-
heat_cops = calc_cops_heating_4speed(runner, heat_pump.heating_efficiency_hspf, heat_c_d, heat_capacity_ratios, heat_fan_speed_ratios, fan_power_rated, heat_eir_ft_spec, heat_cap_ft_spec)
|
460
|
-
end
|
461
|
-
heat_cfms_ton_rated = calc_cfms_ton_rated(heat_rated_airflow_rate, heat_fan_speed_ratios, heat_capacity_ratios)
|
462
|
-
heat_eirs = calc_heat_eirs(num_speeds, heat_cops, fan_power_rated)
|
463
|
-
heat_closs_fplr_spec = [calc_plr_coefficients(heat_c_d)] * num_speeds
|
464
|
-
htg_coil = create_dx_heating_coil(model, obj_name, (0...num_speeds).to_a, heat_eirs, heat_cap_ft_spec, heat_eir_ft_spec, heat_closs_fplr_spec, heat_cap_fflow_spec, heat_eir_fflow_spec, heat_pump.heating_capacity, crankcase_kw, crankcase_temp, fan_power_rated, hp_min_temp, heat_pump.fraction_heat_load_served)
|
266
|
+
htg_coil = create_dx_heating_coil(model, obj_name, heat_pump)
|
465
267
|
hvac_map[heat_pump.id] << htg_coil
|
466
268
|
|
467
269
|
# Supplemental Heating Coil
|
468
|
-
|
469
270
|
htg_supp_coil = create_supp_heating_coil(model, obj_name, heat_pump)
|
470
271
|
hvac_map[heat_pump.id] << htg_supp_coil
|
471
272
|
|
472
273
|
# Fan
|
473
|
-
|
474
|
-
|
274
|
+
num_speeds = hp_ap.num_speeds
|
275
|
+
htg_cfm = heat_pump.heating_airflow_cfm
|
276
|
+
clg_cfm = heat_pump.cooling_airflow_cfm
|
277
|
+
fan_cfm = hp_ap.cool_fan_speed_ratios.max * [htg_cfm, clg_cfm].max
|
278
|
+
fan = create_supply_fan(model, obj_name, num_speeds, heat_pump.fan_watts_per_cfm, fan_cfm)
|
475
279
|
hvac_map[heat_pump.id] += disaggregate_fan_or_pump(model, fan, htg_coil, clg_coil, htg_supp_coil)
|
476
280
|
|
477
281
|
# Unitary System
|
478
|
-
|
479
|
-
air_loop_unitary = create_air_loop_unitary_system(model, obj_name, fan, htg_coil, clg_coil, htg_supp_coil, supp_max_temp)
|
282
|
+
air_loop_unitary = create_air_loop_unitary_system(model, obj_name, fan, htg_coil, clg_coil, htg_supp_coil, htg_cfm, clg_cfm, hp_ap.supp_max_temp)
|
480
283
|
hvac_map[heat_pump.id] << air_loop_unitary
|
481
284
|
|
285
|
+
# Unitary System Performance
|
482
286
|
if num_speeds > 1
|
483
|
-
# Unitary System Performance
|
484
287
|
perf = OpenStudio::Model::UnitarySystemPerformanceMultispeed.new(model)
|
485
288
|
perf.setSingleModeOperation(false)
|
486
289
|
for speed in 1..num_speeds
|
487
|
-
f = OpenStudio::Model::SupplyAirflowRatioField.new(heat_fan_speed_ratios[speed - 1], cool_fan_speed_ratios[speed - 1])
|
290
|
+
f = OpenStudio::Model::SupplyAirflowRatioField.new(hp_ap.heat_fan_speed_ratios[speed - 1], hp_ap.cool_fan_speed_ratios[speed - 1])
|
488
291
|
perf.addSupplyAirflowRatioField(f)
|
489
292
|
end
|
490
293
|
air_loop_unitary.setDesignSpecificationMultispeedObject(perf)
|
491
294
|
end
|
492
295
|
|
493
296
|
# Air Loop
|
494
|
-
|
495
|
-
air_loop = create_air_loop(model, obj_name, air_loop_unitary, control_zone, sequential_heat_load_frac, sequential_cool_load_frac)
|
297
|
+
air_loop = create_air_loop(model, obj_name, air_loop_unitary, control_zone, sequential_heat_load_frac, sequential_cool_load_frac, fan_cfm)
|
496
298
|
hvac_map[heat_pump.id] << air_loop
|
497
299
|
|
498
|
-
#
|
499
|
-
|
500
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACCapacityRatioCooling, cool_capacity_ratios.join(','))
|
501
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACRatedCFMperTonHeating, heat_cfms_ton_rated.join(','))
|
502
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACRatedCFMperTonCooling, cool_cfms_ton_rated.join(','))
|
503
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACFracHeatLoadServed, heat_pump.fraction_heat_load_served)
|
504
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACFracCoolLoadServed, heat_pump.fraction_cool_load_served)
|
505
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACCoolType, Constants.ObjectNameAirSourceHeatPump)
|
506
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACHeatType, Constants.ObjectNameAirSourceHeatPump)
|
300
|
+
# HVAC Installation Quality
|
301
|
+
apply_installation_quality(model, heat_pump, heat_pump, air_loop_unitary, htg_coil, clg_coil, control_zone)
|
507
302
|
end
|
508
303
|
|
509
304
|
def self.apply_mini_split_air_conditioner(model, runner, cooling_system,
|
510
305
|
remaining_cool_load_frac,
|
511
306
|
control_zone, hvac_map)
|
512
307
|
|
513
|
-
|
514
|
-
|
515
|
-
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
308
|
+
hvac_map[cooling_system.id] = []
|
309
|
+
obj_name = Constants.ObjectNameMiniSplitAirConditioner
|
310
|
+
sequential_cool_load_frac = calc_sequential_load_fraction(cooling_system.fraction_cool_load_served, remaining_cool_load_frac)
|
311
|
+
|
312
|
+
clg_ap = cooling_system.additional_properties
|
313
|
+
|
314
|
+
# Cooling Coil
|
315
|
+
clg_coil = create_dx_cooling_coil(model, obj_name, cooling_system)
|
316
|
+
hvac_map[cooling_system.id] << clg_coil
|
317
|
+
|
318
|
+
# Fan
|
319
|
+
num_speeds = clg_ap.num_speeds
|
320
|
+
clg_cfm = cooling_system.cooling_airflow_cfm
|
321
|
+
fan = create_supply_fan(model, obj_name, num_speeds, cooling_system.fan_watts_per_cfm, clg_cfm)
|
322
|
+
hvac_map[cooling_system.id] += disaggregate_fan_or_pump(model, fan, nil, clg_coil, nil)
|
323
|
+
|
324
|
+
# Unitary System
|
325
|
+
air_loop_unitary = create_air_loop_unitary_system(model, obj_name, fan, nil, clg_coil, nil, nil, clg_cfm)
|
326
|
+
hvac_map[cooling_system.id] << air_loop_unitary
|
327
|
+
|
328
|
+
# Unitary System Performance
|
329
|
+
perf = OpenStudio::Model::UnitarySystemPerformanceMultispeed.new(model)
|
330
|
+
perf.setSingleModeOperation(false)
|
331
|
+
for i in 0..(num_speeds - 1)
|
332
|
+
f = OpenStudio::Model::SupplyAirflowRatioField.new(1.0, clg_ap.cool_fan_speed_ratios[i])
|
333
|
+
perf.addSupplyAirflowRatioField(f)
|
334
|
+
end
|
335
|
+
air_loop_unitary.setDesignSpecificationMultispeedObject(perf)
|
336
|
+
|
337
|
+
# Air Loop
|
338
|
+
air_loop = create_air_loop(model, obj_name, air_loop_unitary, control_zone, 0, sequential_cool_load_frac, clg_cfm)
|
339
|
+
hvac_map[cooling_system.id] << air_loop
|
340
|
+
|
341
|
+
# HVAC Installation Quality
|
342
|
+
apply_installation_quality(model, nil, cooling_system, air_loop_unitary, nil, clg_coil, control_zone)
|
532
343
|
end
|
533
344
|
|
534
345
|
def self.apply_mini_split_heat_pump(model, runner, heat_pump,
|
@@ -540,197 +351,48 @@ class HVAC
|
|
540
351
|
obj_name = Constants.ObjectNameMiniSplitHeatPump
|
541
352
|
sequential_heat_load_frac = calc_sequential_load_fraction(heat_pump.fraction_heat_load_served, remaining_heat_load_frac)
|
542
353
|
sequential_cool_load_frac = calc_sequential_load_fraction(heat_pump.fraction_cool_load_served, remaining_cool_load_frac)
|
543
|
-
num_speeds = 10
|
544
|
-
mshp_indices = [1, 3, 5, 9]
|
545
|
-
hp_min_temp, supp_max_temp = get_heat_pump_temp_assumptions(heat_pump)
|
546
|
-
fan_power_installed = 0.07 # W/cfm
|
547
|
-
pan_heater_power = 0.0 # W, disabled
|
548
|
-
|
549
|
-
# Calculate generic inputs
|
550
|
-
min_cooling_capacity = 0.4 # frac
|
551
|
-
max_cooling_capacity = 1.2 # frac
|
552
|
-
min_cooling_airflow_rate = 200.0
|
553
|
-
max_cooling_airflow_rate = 425.0
|
554
|
-
min_heating_capacity = 0.3 # frac
|
555
|
-
max_heating_capacity = 1.2 # frac
|
556
|
-
min_heating_airflow_rate = 200.0
|
557
|
-
max_heating_airflow_rate = 400.0
|
558
|
-
if heat_pump.heating_capacity.nil?
|
559
|
-
heating_capacity_offset = 2300.0 # Btu/hr
|
560
|
-
else
|
561
|
-
heating_capacity_offset = heat_pump.heating_capacity - heat_pump.cooling_capacity
|
562
|
-
end
|
563
|
-
if heat_pump.heating_capacity_17F.nil?
|
564
|
-
cap_retention_frac = 0.25 # frac
|
565
|
-
cap_retention_temp = -5.0 # deg-F
|
566
|
-
else
|
567
|
-
cap_retention_frac = heat_pump.heating_capacity_17F / heat_pump.heating_capacity
|
568
|
-
cap_retention_temp = 17.0 # deg-F
|
569
|
-
end
|
570
354
|
|
571
|
-
|
355
|
+
hp_ap = heat_pump.additional_properties
|
572
356
|
|
573
|
-
|
574
|
-
|
575
|
-
cool_cap_fflow_spec = [[1, 0, 0]] * num_speeds
|
576
|
-
cool_eir_fflow_spec = [[1, 0, 0]] * num_speeds
|
577
|
-
cool_c_d = get_cool_c_d(num_speeds, heat_pump.cooling_efficiency_seer)
|
578
|
-
cool_closs_fplr_spec = [calc_plr_coefficients(cool_c_d)] * num_speeds
|
579
|
-
dB_rated = 80.0 # deg-F
|
580
|
-
wB_rated = 67.0 # deg-F
|
581
|
-
cool_cfms_ton_rated, cool_capacity_ratios, cool_shrs_rated_gross = calc_mshp_cfms_ton_cooling(min_cooling_capacity, max_cooling_capacity, min_cooling_airflow_rate, max_cooling_airflow_rate, num_speeds, dB_rated, wB_rated, heat_pump.cooling_shr)
|
582
|
-
cool_eirs = calc_mshp_cool_eirs(runner, heat_pump.cooling_efficiency_seer, fan_power_installed, cool_c_d, num_speeds, cool_capacity_ratios, cool_cfms_ton_rated, cool_eir_ft_spec, cool_cap_ft_spec)
|
583
|
-
clg_coil = create_dx_cooling_coil(model, obj_name, mshp_indices, cool_eirs, cool_cap_ft_spec, cool_eir_ft_spec, cool_closs_fplr_spec, cool_cap_fflow_spec, cool_eir_fflow_spec, cool_shrs_rated_gross, heat_pump.cooling_capacity, 0.0, nil, nil)
|
357
|
+
# Cooling Coil
|
358
|
+
clg_coil = create_dx_cooling_coil(model, obj_name, heat_pump)
|
584
359
|
hvac_map[heat_pump.id] << clg_coil
|
585
360
|
|
586
361
|
# Heating Coil
|
587
|
-
|
588
|
-
# cop/eir as a function of temperature
|
589
|
-
# Generic curves (=Daikin from lab data)
|
590
|
-
heat_eir_ft_spec = [[0.9999941697687026, 0.004684593830254383, 5.901286675833333e-05, -0.0028624467783091973, 1.3041120194135802e-05, -0.00016172918478765433]] * num_speeds
|
591
|
-
heat_cap_fflow_spec = [[1, 0, 0]] * num_speeds
|
592
|
-
heat_eir_fflow_spec = [[1, 0, 0]] * num_speeds
|
593
|
-
|
594
|
-
# Derive coefficients from user input for capacity retention at outdoor drybulb temperature X [C].
|
595
|
-
# Biquadratic: capacity multiplier = a + b*IAT + c*IAT^2 + d*OAT + e*OAT^2 + f*IAT*OAT
|
596
|
-
x_A = UnitConversions.convert(cap_retention_temp, 'F', 'C')
|
597
|
-
y_A = cap_retention_frac
|
598
|
-
x_B = UnitConversions.convert(47.0, 'F', 'C') # 47F is the rating point
|
599
|
-
y_B = 1.0 # Maximum capacity factor is 1 at the rating point, by definition (this is maximum capacity, not nominal capacity)
|
600
|
-
oat_slope = (y_B - y_A) / (x_B - x_A)
|
601
|
-
oat_intercept = y_A - (x_A * oat_slope)
|
602
|
-
|
603
|
-
# Coefficients for the indoor temperature relationship are retained from the generic curve (Daikin lab data).
|
604
|
-
iat_slope = -0.010386676170938
|
605
|
-
iat_intercept = 0.219274275
|
606
|
-
a = oat_intercept + iat_intercept
|
607
|
-
b = iat_slope
|
608
|
-
c = 0
|
609
|
-
d = oat_slope
|
610
|
-
e = 0
|
611
|
-
f = 0
|
612
|
-
heat_cap_ft_spec = [convert_curve_biquadratic([a, b, c, d, e, f], false)] * num_speeds
|
613
|
-
|
614
|
-
heat_c_d = get_heat_c_d(num_speeds, heat_pump.heating_efficiency_hspf)
|
615
|
-
heat_closs_fplr_spec = [calc_plr_coefficients(heat_c_d)] * num_speeds
|
616
|
-
heat_cfms_ton_rated, heat_capacity_ratios = calc_mshp_cfms_ton_heating(min_heating_capacity, max_heating_capacity, min_heating_airflow_rate, max_heating_airflow_rate, num_speeds)
|
617
|
-
heat_eirs = calc_mshp_heat_eirs(runner, heat_pump.heating_efficiency_hspf, fan_power_installed, hp_min_temp, heat_c_d, cool_cfms_ton_rated, num_speeds, heat_capacity_ratios, heat_cfms_ton_rated, heat_eir_ft_spec, heat_cap_ft_spec)
|
618
|
-
htg_coil = create_dx_heating_coil(model, obj_name, mshp_indices, heat_eirs, heat_cap_ft_spec, heat_eir_ft_spec, heat_closs_fplr_spec, heat_cap_fflow_spec, heat_eir_fflow_spec, heat_pump.heating_capacity, 0.0, nil, nil, hp_min_temp, heat_pump.fraction_heat_load_served)
|
362
|
+
htg_coil = create_dx_heating_coil(model, obj_name, heat_pump)
|
619
363
|
hvac_map[heat_pump.id] << htg_coil
|
620
364
|
|
621
365
|
# Supplemental Heating Coil
|
622
|
-
|
623
366
|
htg_supp_coil = create_supp_heating_coil(model, obj_name, heat_pump)
|
624
367
|
hvac_map[heat_pump.id] << htg_supp_coil
|
625
368
|
|
626
369
|
# Fan
|
627
|
-
|
628
|
-
|
629
|
-
|
630
|
-
|
631
|
-
fan
|
632
|
-
fan.setEndUseSubcategory('supply fan')
|
633
|
-
fan.setFanEfficiency(fan_eff)
|
634
|
-
fan.setPressureRise(calc_fan_pressure_rise(fan_eff, fan_power_installed))
|
635
|
-
fan.setMotorEfficiency(1.0)
|
636
|
-
fan.setMotorInAirstreamFraction(1.0)
|
370
|
+
num_speeds = hp_ap.num_speeds
|
371
|
+
htg_cfm = heat_pump.heating_airflow_cfm
|
372
|
+
clg_cfm = heat_pump.cooling_airflow_cfm
|
373
|
+
fan_cfm = hp_ap.cool_fan_speed_ratios.max * [htg_cfm, clg_cfm].max
|
374
|
+
fan = create_supply_fan(model, obj_name, num_speeds, heat_pump.fan_watts_per_cfm, fan_cfm)
|
637
375
|
hvac_map[heat_pump.id] += disaggregate_fan_or_pump(model, fan, htg_coil, clg_coil, htg_supp_coil)
|
638
376
|
|
639
377
|
# Unitary System
|
640
|
-
|
641
|
-
air_loop_unitary = create_air_loop_unitary_system(model, obj_name, fan, htg_coil, clg_coil, htg_supp_coil, supp_max_temp)
|
378
|
+
air_loop_unitary = create_air_loop_unitary_system(model, obj_name, fan, htg_coil, clg_coil, htg_supp_coil, htg_cfm, clg_cfm, hp_ap.supp_max_temp)
|
642
379
|
hvac_map[heat_pump.id] << air_loop_unitary
|
643
380
|
|
381
|
+
# Unitary System Performance
|
644
382
|
perf = OpenStudio::Model::UnitarySystemPerformanceMultispeed.new(model)
|
645
383
|
perf.setSingleModeOperation(false)
|
646
|
-
|
647
|
-
|
648
|
-
ratio_cooling = cool_cfms_ton_rated[mshp_index] / cool_cfms_ton_rated[mshp_indices[-1]]
|
649
|
-
f = OpenStudio::Model::SupplyAirflowRatioField.new(ratio_heating, ratio_cooling)
|
384
|
+
for i in 0..(num_speeds - 1)
|
385
|
+
f = OpenStudio::Model::SupplyAirflowRatioField.new(hp_ap.heat_fan_speed_ratios[i], hp_ap.cool_fan_speed_ratios[i])
|
650
386
|
perf.addSupplyAirflowRatioField(f)
|
651
387
|
end
|
652
388
|
air_loop_unitary.setDesignSpecificationMultispeedObject(perf)
|
653
389
|
|
654
390
|
# Air Loop
|
655
|
-
|
656
|
-
air_loop = create_air_loop(model, obj_name, air_loop_unitary, control_zone, sequential_heat_load_frac, sequential_cool_load_frac)
|
391
|
+
air_loop = create_air_loop(model, obj_name, air_loop_unitary, control_zone, sequential_heat_load_frac, sequential_cool_load_frac, fan_cfm)
|
657
392
|
hvac_map[heat_pump.id] << air_loop
|
658
393
|
|
659
|
-
|
660
|
-
|
661
|
-
mshp_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Heating Coil Electric Energy')
|
662
|
-
mshp_sensor.setName("#{obj_name} vrf energy sensor")
|
663
|
-
mshp_sensor.setKeyName(obj_name + ' coil')
|
664
|
-
|
665
|
-
equip_def = OpenStudio::Model::ElectricEquipmentDefinition.new(model)
|
666
|
-
equip_def.setName(obj_name + ' pan heater equip')
|
667
|
-
equip = OpenStudio::Model::ElectricEquipment.new(equip_def)
|
668
|
-
equip.setName(equip_def.name.to_s)
|
669
|
-
equip.setSpace(control_zone.spaces[0])
|
670
|
-
equip_def.setFractionRadiant(0)
|
671
|
-
equip_def.setFractionLatent(0)
|
672
|
-
equip_def.setFractionLost(1)
|
673
|
-
equip.setSchedule(model.alwaysOnDiscreteSchedule)
|
674
|
-
equip.setEndUseSubcategory(obj_name + ' pan heater')
|
675
|
-
|
676
|
-
pan_heater_actuator = OpenStudio::Model::EnergyManagementSystemActuator.new(equip, 'ElectricEquipment', 'Electric Power Level')
|
677
|
-
pan_heater_actuator.setName("#{obj_name} pan heater actuator")
|
678
|
-
|
679
|
-
tout_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Zone Outdoor Air Drybulb Temperature')
|
680
|
-
tout_sensor.setName("#{obj_name} tout sensor")
|
681
|
-
thermal_zones.each do |thermal_zone|
|
682
|
-
if Geometry.is_living(thermal_zone)
|
683
|
-
tout_sensor.setKeyName(thermal_zone.name.to_s)
|
684
|
-
break
|
685
|
-
end
|
686
|
-
end
|
687
|
-
|
688
|
-
program = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
|
689
|
-
program.setName(obj_name + ' pan heater program')
|
690
|
-
if not heat_pump.cooling_capacity.nil?
|
691
|
-
num_outdoor_units = (UnitConversions.convert([heat_pump.cooling_capacity, Constants.small].max, 'Btu/hr', 'ton') / 1.5).ceil # Assume 1.5 tons max per outdoor unit
|
692
|
-
else
|
693
|
-
num_outdoor_units = 2
|
694
|
-
end
|
695
|
-
pan_heater_power *= num_outdoor_units # W
|
696
|
-
program.addLine("Set #{pan_heater_actuator.name} = 0")
|
697
|
-
program.addLine("If #{mshp_sensor.name} > 0")
|
698
|
-
program.addLine(" If #{tout_sensor.name} <= #{UnitConversions.convert(32.0, 'F', 'C').round(3)}")
|
699
|
-
program.addLine(" Set #{pan_heater_actuator.name} = #{pan_heater_power}")
|
700
|
-
program.addLine(' EndIf')
|
701
|
-
program.addLine('EndIf')
|
702
|
-
|
703
|
-
program_calling_manager = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
|
704
|
-
program_calling_manager.setName(obj_name + ' pan heater program calling manager')
|
705
|
-
program_calling_manager.setCallingPoint('BeginTimestepBeforePredictor')
|
706
|
-
program_calling_manager.addProgram(program)
|
707
|
-
|
708
|
-
end
|
709
|
-
|
710
|
-
# Store info for HVAC Sizing measure
|
711
|
-
heat_capacity_ratios_4 = []
|
712
|
-
cool_capacity_ratios_4 = []
|
713
|
-
heat_cfms_ton_rated_4 = []
|
714
|
-
cool_cfms_ton_rated_4 = []
|
715
|
-
cool_shrs_rated_gross_4 = []
|
716
|
-
mshp_indices.each do |mshp_index|
|
717
|
-
heat_capacity_ratios_4 << heat_capacity_ratios[mshp_index]
|
718
|
-
cool_capacity_ratios_4 << cool_capacity_ratios[mshp_index]
|
719
|
-
heat_cfms_ton_rated_4 << heat_cfms_ton_rated[mshp_index]
|
720
|
-
cool_cfms_ton_rated_4 << cool_cfms_ton_rated[mshp_index]
|
721
|
-
cool_shrs_rated_gross_4 << cool_shrs_rated_gross[mshp_index]
|
722
|
-
end
|
723
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACSystemIsDucted, !heat_pump.distribution_system_idref.nil?)
|
724
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACCapacityRatioHeating, heat_capacity_ratios_4.join(','))
|
725
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACCapacityRatioCooling, cool_capacity_ratios_4.join(','))
|
726
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACHeatingCFMs, heat_cfms_ton_rated_4.join(','))
|
727
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACCoolingCFMs, cool_cfms_ton_rated_4.join(','))
|
728
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACHeatingCapacityOffset, heating_capacity_offset)
|
729
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACFracHeatLoadServed, heat_pump.fraction_heat_load_served)
|
730
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACFracCoolLoadServed, heat_pump.fraction_cool_load_served)
|
731
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACSHR, cool_shrs_rated_gross_4.join(','))
|
732
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACCoolType, Constants.ObjectNameMiniSplitHeatPump)
|
733
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACHeatType, Constants.ObjectNameMiniSplitHeatPump)
|
394
|
+
# HVAC Installation Quality
|
395
|
+
apply_installation_quality(model, heat_pump, heat_pump, air_loop_unitary, htg_coil, clg_coil, control_zone)
|
734
396
|
end
|
735
397
|
|
736
398
|
def self.apply_ground_to_air_heat_pump(model, runner, weather, heat_pump,
|
@@ -741,181 +403,101 @@ class HVAC
|
|
741
403
|
obj_name = Constants.ObjectNameGroundSourceHeatPump
|
742
404
|
sequential_heat_load_frac = calc_sequential_load_fraction(heat_pump.fraction_heat_load_served, remaining_heat_load_frac)
|
743
405
|
sequential_cool_load_frac = calc_sequential_load_fraction(heat_pump.fraction_cool_load_served, remaining_cool_load_frac)
|
744
|
-
pipe_cond = 0.23 # Pipe thermal conductivity, default to high density polyethylene
|
745
|
-
ground_conductivity = 0.6
|
746
|
-
grout_conductivity = 0.4
|
747
|
-
bore_config = nil # Autosize
|
748
|
-
bore_holes = nil # Autosize
|
749
|
-
bore_depth = nil # Autosize
|
750
|
-
bore_spacing = 20.0
|
751
|
-
bore_diameter = 5.0
|
752
|
-
pipe_size = 0.75
|
753
|
-
ground_diffusivity = 0.0208
|
754
|
-
fluid_type = Constants.FluidPropyleneGlycol
|
755
|
-
frac_glycol = 0.3
|
756
|
-
design_delta_t = 10.0
|
757
|
-
chw_design = [85.0, weather.design.CoolingDrybulb - 15.0, weather.data.AnnualAvgDrybulb + 10.0].max # Temperature of water entering indoor coil,use 85F as lower bound
|
758
|
-
if fluid_type == Constants.FluidWater
|
759
|
-
hw_design = [45.0, weather.design.HeatingDrybulb + 35.0, weather.data.AnnualAvgDrybulb - 10.0].max # Temperature of fluid entering indoor coil, use 45F as lower bound for water
|
760
|
-
else
|
761
|
-
hw_design = [35.0, weather.design.HeatingDrybulb + 35.0, weather.data.AnnualAvgDrybulb - 10.0].min # Temperature of fluid entering indoor coil, use 35F as upper bound
|
762
|
-
end
|
763
|
-
# Pipe nominal size conversion to pipe outside diameter and inside diameter,
|
764
|
-
# only pipe sizes <= 2" are used here with DR11 (dimension ratio),
|
765
|
-
if pipe_size == 0.75 # 3/4" pipe
|
766
|
-
pipe_od = 1.050
|
767
|
-
pipe_id = 0.859
|
768
|
-
elsif pipe_size == 1.0 # 1" pipe
|
769
|
-
pipe_od = 1.315
|
770
|
-
pipe_id = 1.076
|
771
|
-
elsif pipe_size == 1.25 # 1-1/4" pipe
|
772
|
-
pipe_od = 1.660
|
773
|
-
pipe_id = 1.358
|
774
|
-
end
|
775
|
-
u_tube_spacing_type = 'b'
|
776
|
-
# Calculate distance between pipes
|
777
|
-
if u_tube_spacing_type == 'as'
|
778
|
-
# Two tubes, spaced 1/8” apart at the center of the borehole
|
779
|
-
u_tube_spacing = 0.125
|
780
|
-
elsif u_tube_spacing_type == 'b'
|
781
|
-
# Two tubes equally spaced between the borehole edges
|
782
|
-
u_tube_spacing = 0.9661
|
783
|
-
elsif u_tube_spacing_type == 'c'
|
784
|
-
# Both tubes placed against outer edge of borehole
|
785
|
-
u_tube_spacing = bore_diameter - 2 * pipe_od
|
786
|
-
end
|
787
|
-
shank_spacing = u_tube_spacing + pipe_od # Distance from center of pipe to center of pipe
|
788
406
|
|
789
|
-
|
790
|
-
|
791
|
-
|
407
|
+
hp_ap = heat_pump.additional_properties
|
408
|
+
htg_cfm = heat_pump.heating_airflow_cfm
|
409
|
+
clg_cfm = heat_pump.cooling_airflow_cfm
|
410
|
+
|
411
|
+
if hp_ap.frac_glycol == 0
|
412
|
+
hp_ap.fluid_type = Constants.FluidWater
|
413
|
+
runner.registerWarning("Specified #{hp_ap.fluid_type} fluid type and 0 fraction of glycol, so assuming #{Constants.FluidWater} fluid type.")
|
792
414
|
end
|
793
415
|
|
794
416
|
# Cooling Coil
|
795
|
-
|
796
|
-
|
797
|
-
|
798
|
-
|
799
|
-
cool_power_ft_spec = [0.01717338, 0.00316077, 0.00000000, 0.01043792, 0.00000000, 0.00000000]
|
800
|
-
coil_bf_ft_spec = [1.21005458, -0.00664200, 0.00000000, 0.00348246, 0.00000000, 0.00000000]
|
801
|
-
gshp_cool_cap_fT_coeff = convert_curve_gshp(cool_cap_ft_spec, false)
|
802
|
-
gshp_cool_power_fT_coeff = convert_curve_gshp(cool_power_ft_spec, false)
|
803
|
-
gshp_cool_SH_fT_coeff = convert_curve_gshp(cool_SH_ft_spec, false)
|
804
|
-
|
805
|
-
# FUTURE: Reconcile these adjustments with ANSI/RESNET/ICC 301-2019 Section 4.4.5
|
806
|
-
fan_adjust_kw = UnitConversions.convert(400.0, 'Btu/hr', 'ton') * UnitConversions.convert(1.0, 'cfm', 'm^3/s') * 1000.0 * 0.35 * 249.0 / 300.0 # Adjustment per ISO 13256-1 Internal pressure drop across heat pump assumed to be 0.5 in. w.g.
|
807
|
-
pump_adjust_kw = UnitConversions.convert(3.0, 'Btu/hr', 'ton') * UnitConversions.convert(1.0, 'gal/min', 'm^3/s') * 1000.0 * 6.0 * 2990.0 / 3000.0 # Adjustment per ISO 13256-1 Internal Pressure drop across heat pump coil assumed to be 11ft w.g.
|
808
|
-
cooling_eir = UnitConversions.convert((1.0 - heat_pump.cooling_efficiency_eer * (fan_adjust_kw + pump_adjust_kw)) / (heat_pump.cooling_efficiency_eer * (1.0 + UnitConversions.convert(fan_adjust_kw, 'Wh', 'Btu'))), 'Wh', 'Btu')
|
809
|
-
|
810
|
-
clg_coil = OpenStudio::Model::CoilCoolingWaterToAirHeatPumpEquationFit.new(model)
|
417
|
+
clg_total_cap_curve = create_curve_quad_linear(model, hp_ap.cool_cap_ft_spec[0], obj_name + ' clg total cap curve')
|
418
|
+
clg_sens_cap_curve = create_curve_quint_linear(model, hp_ap.cool_sh_ft_spec[0], obj_name + ' clg sens cap curve')
|
419
|
+
clg_power_curve = create_curve_quad_linear(model, hp_ap.cool_power_ft_spec[0], obj_name + ' clg power curve')
|
420
|
+
clg_coil = OpenStudio::Model::CoilCoolingWaterToAirHeatPumpEquationFit.new(model, clg_total_cap_curve, clg_sens_cap_curve, clg_power_curve)
|
811
421
|
clg_coil.setName(obj_name + ' clg coil')
|
812
|
-
|
813
|
-
clg_coil.setRatedTotalCoolingCapacity(UnitConversions.convert([heat_pump.cooling_capacity, Constants.small].max, 'Btu/hr', 'W')) # Used by HVACSizing measure
|
814
|
-
end
|
815
|
-
clg_coil.setRatedCoolingCoefficientofPerformance(1.0 / cooling_eir)
|
816
|
-
clg_coil.setTotalCoolingCapacityCoefficient1(gshp_cool_cap_fT_coeff[0])
|
817
|
-
clg_coil.setTotalCoolingCapacityCoefficient2(gshp_cool_cap_fT_coeff[1])
|
818
|
-
clg_coil.setTotalCoolingCapacityCoefficient3(gshp_cool_cap_fT_coeff[2])
|
819
|
-
clg_coil.setTotalCoolingCapacityCoefficient4(gshp_cool_cap_fT_coeff[3])
|
820
|
-
clg_coil.setTotalCoolingCapacityCoefficient5(gshp_cool_cap_fT_coeff[4])
|
821
|
-
clg_coil.setSensibleCoolingCapacityCoefficient1(gshp_cool_SH_fT_coeff[0])
|
822
|
-
clg_coil.setSensibleCoolingCapacityCoefficient2(0)
|
823
|
-
clg_coil.setSensibleCoolingCapacityCoefficient3(gshp_cool_SH_fT_coeff[1])
|
824
|
-
clg_coil.setSensibleCoolingCapacityCoefficient4(gshp_cool_SH_fT_coeff[2])
|
825
|
-
clg_coil.setSensibleCoolingCapacityCoefficient5(gshp_cool_SH_fT_coeff[3])
|
826
|
-
clg_coil.setSensibleCoolingCapacityCoefficient6(gshp_cool_SH_fT_coeff[4])
|
827
|
-
clg_coil.setCoolingPowerConsumptionCoefficient1(gshp_cool_power_fT_coeff[0])
|
828
|
-
clg_coil.setCoolingPowerConsumptionCoefficient2(gshp_cool_power_fT_coeff[1])
|
829
|
-
clg_coil.setCoolingPowerConsumptionCoefficient3(gshp_cool_power_fT_coeff[2])
|
830
|
-
clg_coil.setCoolingPowerConsumptionCoefficient4(gshp_cool_power_fT_coeff[3])
|
831
|
-
clg_coil.setCoolingPowerConsumptionCoefficient5(gshp_cool_power_fT_coeff[4])
|
422
|
+
clg_coil.setRatedCoolingCoefficientofPerformance(1.0 / hp_ap.cool_rated_eirs[0])
|
832
423
|
clg_coil.setNominalTimeforCondensateRemovaltoBegin(1000)
|
833
424
|
clg_coil.setRatioofInitialMoistureEvaporationRateandSteadyStateLatentCapacity(1.5)
|
425
|
+
clg_coil.setRatedAirFlowRate(UnitConversions.convert(clg_cfm, 'cfm', 'm^3/s'))
|
426
|
+
clg_coil.setRatedWaterFlowRate(UnitConversions.convert(hp_ap.GSHP_Loop_flow, 'gal/min', 'm^3/s'))
|
427
|
+
clg_coil.setRatedTotalCoolingCapacity(UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'W'))
|
428
|
+
clg_coil.setRatedSensibleCoolingCapacity(UnitConversions.convert(hp_ap.cooling_capacity_sensible, 'Btu/hr', 'W'))
|
834
429
|
hvac_map[heat_pump.id] << clg_coil
|
835
430
|
|
836
431
|
# Heating Coil
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
gshp_heat_cap_fT_coeff = convert_curve_gshp(heat_cap_ft_spec, false)
|
841
|
-
gshp_heat_power_fT_coeff = convert_curve_gshp(heat_power_ft_spec, false)
|
842
|
-
|
843
|
-
heating_eir = (1.0 - heat_pump.heating_efficiency_cop * (fan_adjust_kw + pump_adjust_kw)) / (heat_pump.heating_efficiency_cop * (1.0 - fan_adjust_kw))
|
844
|
-
|
845
|
-
htg_coil = OpenStudio::Model::CoilHeatingWaterToAirHeatPumpEquationFit.new(model)
|
432
|
+
htg_cap_curve = create_curve_quad_linear(model, hp_ap.heat_cap_ft_spec[0], obj_name + ' htg cap curve')
|
433
|
+
htg_power_curve = create_curve_quad_linear(model, hp_ap.heat_power_ft_spec[0], obj_name + ' htg power curve')
|
434
|
+
htg_coil = OpenStudio::Model::CoilHeatingWaterToAirHeatPumpEquationFit.new(model, htg_cap_curve, htg_power_curve)
|
846
435
|
htg_coil.setName(obj_name + ' htg coil')
|
847
|
-
|
848
|
-
|
849
|
-
|
850
|
-
htg_coil.
|
851
|
-
htg_coil.setHeatingCapacityCoefficient1(gshp_heat_cap_fT_coeff[0])
|
852
|
-
htg_coil.setHeatingCapacityCoefficient2(gshp_heat_cap_fT_coeff[1])
|
853
|
-
htg_coil.setHeatingCapacityCoefficient3(gshp_heat_cap_fT_coeff[2])
|
854
|
-
htg_coil.setHeatingCapacityCoefficient4(gshp_heat_cap_fT_coeff[3])
|
855
|
-
htg_coil.setHeatingCapacityCoefficient5(gshp_heat_cap_fT_coeff[4])
|
856
|
-
htg_coil.setHeatingPowerConsumptionCoefficient1(gshp_heat_power_fT_coeff[0])
|
857
|
-
htg_coil.setHeatingPowerConsumptionCoefficient2(gshp_heat_power_fT_coeff[1])
|
858
|
-
htg_coil.setHeatingPowerConsumptionCoefficient3(gshp_heat_power_fT_coeff[2])
|
859
|
-
htg_coil.setHeatingPowerConsumptionCoefficient4(gshp_heat_power_fT_coeff[3])
|
860
|
-
htg_coil.setHeatingPowerConsumptionCoefficient5(gshp_heat_power_fT_coeff[4])
|
436
|
+
htg_coil.setRatedHeatingCoefficientofPerformance(1.0 / hp_ap.heat_rated_eirs[0])
|
437
|
+
htg_coil.setRatedAirFlowRate(UnitConversions.convert(htg_cfm, 'cfm', 'm^3/s'))
|
438
|
+
htg_coil.setRatedWaterFlowRate(UnitConversions.convert(hp_ap.GSHP_Loop_flow, 'gal/min', 'm^3/s'))
|
439
|
+
htg_coil.setRatedHeatingCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W'))
|
861
440
|
hvac_map[heat_pump.id] << htg_coil
|
862
441
|
|
863
442
|
# Supplemental Heating Coil
|
864
|
-
|
865
443
|
htg_supp_coil = create_supp_heating_coil(model, obj_name, heat_pump)
|
866
444
|
hvac_map[heat_pump.id] << htg_supp_coil
|
867
445
|
|
868
446
|
# Ground Heat Exchanger
|
869
|
-
|
870
447
|
ground_heat_exch_vert = OpenStudio::Model::GroundHeatExchangerVertical.new(model)
|
871
448
|
ground_heat_exch_vert.setName(obj_name + ' exchanger')
|
872
|
-
ground_heat_exch_vert.setBoreHoleRadius(UnitConversions.convert(bore_diameter / 2.0, 'in', 'm'))
|
873
|
-
ground_heat_exch_vert.setGroundThermalConductivity(UnitConversions.convert(ground_conductivity, 'Btu/(hr*ft*R)', 'W/(m*K)'))
|
874
|
-
ground_heat_exch_vert.setGroundThermalHeatCapacity(UnitConversions.convert(ground_conductivity / ground_diffusivity, 'Btu/(ft^3*F)', 'J/(m^3*K)'))
|
449
|
+
ground_heat_exch_vert.setBoreHoleRadius(UnitConversions.convert(hp_ap.bore_diameter / 2.0, 'in', 'm'))
|
450
|
+
ground_heat_exch_vert.setGroundThermalConductivity(UnitConversions.convert(hp_ap.ground_conductivity, 'Btu/(hr*ft*R)', 'W/(m*K)'))
|
451
|
+
ground_heat_exch_vert.setGroundThermalHeatCapacity(UnitConversions.convert(hp_ap.ground_conductivity / hp_ap.ground_diffusivity, 'Btu/(ft^3*F)', 'J/(m^3*K)'))
|
875
452
|
ground_heat_exch_vert.setGroundTemperature(UnitConversions.convert(weather.data.AnnualAvgDrybulb, 'F', 'C'))
|
876
|
-
ground_heat_exch_vert.setGroutThermalConductivity(UnitConversions.convert(grout_conductivity, 'Btu/(hr*ft*R)', 'W/(m*K)'))
|
877
|
-
ground_heat_exch_vert.setPipeThermalConductivity(UnitConversions.convert(pipe_cond, 'Btu/(hr*ft*R)', 'W/(m*K)'))
|
878
|
-
ground_heat_exch_vert.setPipeOutDiameter(UnitConversions.convert(pipe_od, 'in', 'm'))
|
879
|
-
ground_heat_exch_vert.setUTubeDistance(UnitConversions.convert(shank_spacing, 'in', 'm'))
|
880
|
-
ground_heat_exch_vert.setPipeThickness(UnitConversions.convert((pipe_od - pipe_id) / 2.0, 'in', 'm'))
|
453
|
+
ground_heat_exch_vert.setGroutThermalConductivity(UnitConversions.convert(hp_ap.grout_conductivity, 'Btu/(hr*ft*R)', 'W/(m*K)'))
|
454
|
+
ground_heat_exch_vert.setPipeThermalConductivity(UnitConversions.convert(hp_ap.pipe_cond, 'Btu/(hr*ft*R)', 'W/(m*K)'))
|
455
|
+
ground_heat_exch_vert.setPipeOutDiameter(UnitConversions.convert(hp_ap.pipe_od, 'in', 'm'))
|
456
|
+
ground_heat_exch_vert.setUTubeDistance(UnitConversions.convert(hp_ap.shank_spacing, 'in', 'm'))
|
457
|
+
ground_heat_exch_vert.setPipeThickness(UnitConversions.convert((hp_ap.pipe_od - hp_ap.pipe_id) / 2.0, 'in', 'm'))
|
881
458
|
ground_heat_exch_vert.setMaximumLengthofSimulation(1)
|
882
459
|
ground_heat_exch_vert.setGFunctionReferenceRatio(0.0005)
|
460
|
+
ground_heat_exch_vert.setDesignFlowRate(UnitConversions.convert(hp_ap.GSHP_Loop_flow, 'gal/min', 'm^3/s'))
|
461
|
+
ground_heat_exch_vert.setNumberofBoreHoles(hp_ap.GSHP_Bore_Holes.to_i)
|
462
|
+
ground_heat_exch_vert.setBoreHoleLength(UnitConversions.convert(hp_ap.GSHP_Bore_Depth, 'ft', 'm'))
|
463
|
+
ground_heat_exch_vert.removeAllGFunctions
|
464
|
+
for i in 0..(hp_ap.GSHP_G_Functions[0].size - 1)
|
465
|
+
ground_heat_exch_vert.addGFunction(hp_ap.GSHP_G_Functions[0][i], hp_ap.GSHP_G_Functions[1][i])
|
466
|
+
end
|
883
467
|
|
884
468
|
# Plant Loop
|
885
|
-
|
886
469
|
plant_loop = OpenStudio::Model::PlantLoop.new(model)
|
887
470
|
plant_loop.setName(obj_name + ' condenser loop')
|
888
|
-
if fluid_type == Constants.FluidWater
|
471
|
+
if hp_ap.fluid_type == Constants.FluidWater
|
889
472
|
plant_loop.setFluidType('Water')
|
890
473
|
else
|
891
|
-
plant_loop.setFluidType({ Constants.FluidPropyleneGlycol => 'PropyleneGlycol', Constants.FluidEthyleneGlycol => 'EthyleneGlycol' }[fluid_type])
|
892
|
-
plant_loop.setGlycolConcentration((frac_glycol * 100).to_i)
|
474
|
+
plant_loop.setFluidType({ Constants.FluidPropyleneGlycol => 'PropyleneGlycol', Constants.FluidEthyleneGlycol => 'EthyleneGlycol' }[hp_ap.fluid_type])
|
475
|
+
plant_loop.setGlycolConcentration((hp_ap.frac_glycol * 100).to_i)
|
893
476
|
end
|
894
477
|
plant_loop.setMaximumLoopTemperature(48.88889)
|
895
|
-
plant_loop.setMinimumLoopTemperature(UnitConversions.convert(
|
478
|
+
plant_loop.setMinimumLoopTemperature(UnitConversions.convert(hp_ap.design_hw, 'F', 'C'))
|
896
479
|
plant_loop.setMinimumLoopFlowRate(0)
|
897
480
|
plant_loop.setLoadDistributionScheme('SequentialLoad')
|
898
481
|
plant_loop.addSupplyBranchForComponent(ground_heat_exch_vert)
|
899
482
|
plant_loop.addDemandBranchForComponent(htg_coil)
|
900
483
|
plant_loop.addDemandBranchForComponent(clg_coil)
|
484
|
+
plant_loop.setMaximumLoopFlowRate(UnitConversions.convert(hp_ap.GSHP_Loop_flow, 'gal/min', 'm^3/s'))
|
901
485
|
hvac_map[heat_pump.id] << plant_loop
|
902
486
|
|
903
487
|
sizing_plant = plant_loop.sizingPlant
|
904
488
|
sizing_plant.setLoopType('Condenser')
|
905
|
-
sizing_plant.setDesignLoopExitTemperature(UnitConversions.convert(
|
906
|
-
sizing_plant.setLoopDesignTemperatureDifference(UnitConversions.convert(design_delta_t, 'R', 'K'))
|
489
|
+
sizing_plant.setDesignLoopExitTemperature(UnitConversions.convert(hp_ap.design_chw, 'F', 'C'))
|
490
|
+
sizing_plant.setLoopDesignTemperatureDifference(UnitConversions.convert(hp_ap.design_delta_t, 'R', 'K'))
|
907
491
|
|
908
492
|
setpoint_mgr_follow_ground_temp = OpenStudio::Model::SetpointManagerFollowGroundTemperature.new(model)
|
909
493
|
setpoint_mgr_follow_ground_temp.setName(obj_name + ' condenser loop temp')
|
910
494
|
setpoint_mgr_follow_ground_temp.setControlVariable('Temperature')
|
911
495
|
setpoint_mgr_follow_ground_temp.setMaximumSetpointTemperature(48.88889)
|
912
|
-
setpoint_mgr_follow_ground_temp.setMinimumSetpointTemperature(UnitConversions.convert(
|
496
|
+
setpoint_mgr_follow_ground_temp.setMinimumSetpointTemperature(UnitConversions.convert(hp_ap.design_hw, 'F', 'C'))
|
913
497
|
setpoint_mgr_follow_ground_temp.setReferenceGroundTemperatureObjectType('Site:GroundTemperature:Deep')
|
914
498
|
setpoint_mgr_follow_ground_temp.addToNode(plant_loop.supplyOutletNode)
|
915
499
|
|
916
500
|
# Pump
|
917
|
-
|
918
|
-
# Pump power set in hvac_sizing.rb
|
919
501
|
pump = OpenStudio::Model::PumpVariableSpeed.new(model)
|
920
502
|
pump.setName(obj_name + ' pump')
|
921
503
|
pump.setMotorEfficiency(0.85)
|
@@ -928,11 +510,18 @@ class HVAC
|
|
928
510
|
pump.setMinimumFlowRate(0)
|
929
511
|
pump.setPumpControlType('Intermittent')
|
930
512
|
pump.addToNode(plant_loop.supplyInletNode)
|
513
|
+
if heat_pump.cooling_capacity > 1.0
|
514
|
+
pump_w = heat_pump.pump_watts_per_ton * UnitConversions.convert(heat_pump.cooling_capacity, 'Btu/hr', 'ton')
|
515
|
+
else
|
516
|
+
pump_w = heat_pump.pump_watts_per_ton * UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'ton')
|
517
|
+
end
|
518
|
+
pump_w = [pump_w, 1.0].max # prevent error if zero
|
519
|
+
pump.setRatedPowerConsumption(pump_w)
|
520
|
+
pump.setRatedFlowRate(calc_pump_rated_flow_rate(0.75, pump_w, pump.ratedPumpHead))
|
931
521
|
hvac_map[heat_pump.id] << pump
|
932
522
|
hvac_map[heat_pump.id] += disaggregate_fan_or_pump(model, pump, htg_coil, clg_coil, htg_supp_coil)
|
933
523
|
|
934
524
|
# Pipes
|
935
|
-
|
936
525
|
chiller_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
|
937
526
|
plant_loop.addSupplyBranchForComponent(chiller_bypass_pipe)
|
938
527
|
coil_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
|
@@ -945,14 +534,14 @@ class HVAC
|
|
945
534
|
demand_outlet_pipe.addToNode(plant_loop.demandOutletNode)
|
946
535
|
|
947
536
|
# Fan
|
948
|
-
|
949
|
-
fan = create_supply_fan(model, obj_name, 1, heat_pump.fan_watts_per_cfm)
|
537
|
+
fan_cfm = [htg_cfm, clg_cfm].max
|
538
|
+
fan = create_supply_fan(model, obj_name, 1, heat_pump.fan_watts_per_cfm, fan_cfm)
|
950
539
|
hvac_map[heat_pump.id] += disaggregate_fan_or_pump(model, fan, htg_coil, clg_coil, htg_supp_coil)
|
951
540
|
|
952
541
|
# Unitary System
|
953
|
-
|
954
|
-
air_loop_unitary = create_air_loop_unitary_system(model, obj_name, fan, htg_coil, clg_coil, htg_supp_coil, 40.0)
|
542
|
+
air_loop_unitary = create_air_loop_unitary_system(model, obj_name, fan, htg_coil, clg_coil, htg_supp_coil, htg_cfm, clg_cfm, 40.0)
|
955
543
|
hvac_map[heat_pump.id] << air_loop_unitary
|
544
|
+
set_pump_power_ems_program(model, pump_w, pump, air_loop_unitary)
|
956
545
|
|
957
546
|
if heat_pump.is_shared_system
|
958
547
|
# Shared pump power per ANSI/RESNET/ICC 301-2019 Section 4.4.5.1 (pump runs 8760)
|
@@ -976,24 +565,11 @@ class HVAC
|
|
976
565
|
end
|
977
566
|
|
978
567
|
# Air Loop
|
979
|
-
|
980
|
-
air_loop = create_air_loop(model, obj_name, air_loop_unitary, control_zone, sequential_heat_load_frac, sequential_cool_load_frac)
|
568
|
+
air_loop = create_air_loop(model, obj_name, air_loop_unitary, control_zone, sequential_heat_load_frac, sequential_cool_load_frac, fan_cfm)
|
981
569
|
hvac_map[heat_pump.id] << air_loop
|
982
570
|
|
983
|
-
#
|
984
|
-
|
985
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoGSHPCoil_BF_FT_SPEC, coil_bf_ft_spec.join(','))
|
986
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoGSHPCoilBF, coil_bf)
|
987
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACFracHeatLoadServed, heat_pump.fraction_heat_load_served)
|
988
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACFracCoolLoadServed, heat_pump.fraction_cool_load_served)
|
989
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoGSHPBoreSpacing, bore_spacing)
|
990
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoGSHPBoreHoles, bore_holes.to_s)
|
991
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoGSHPBoreDepth, bore_depth.to_s)
|
992
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoGSHPBoreConfig, bore_config.to_s)
|
993
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoGSHPUTubeSpacingType, u_tube_spacing_type)
|
994
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACCoolType, Constants.ObjectNameGroundSourceHeatPump)
|
995
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACHeatType, Constants.ObjectNameGroundSourceHeatPump)
|
996
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACPumpPower, heat_pump.pump_watts_per_ton)
|
571
|
+
# HVAC Installation Quality
|
572
|
+
apply_installation_quality(model, heat_pump, heat_pump, air_loop_unitary, htg_coil, clg_coil, control_zone)
|
997
573
|
end
|
998
574
|
|
999
575
|
def self.apply_water_loop_to_air_heat_pump(model, runner, heat_pump,
|
@@ -1009,10 +585,11 @@ class HVAC
|
|
1009
585
|
obj_name = Constants.ObjectNameWaterLoopHeatPump
|
1010
586
|
sequential_heat_load_frac = calc_sequential_load_fraction(heat_pump.fraction_heat_load_served, remaining_heat_load_frac)
|
1011
587
|
sequential_cool_load_frac = 0.0
|
1012
|
-
hp_min_temp, supp_max_temp = get_heat_pump_temp_assumptions(heat_pump)
|
1013
588
|
|
1014
|
-
|
589
|
+
hp_ap = heat_pump.additional_properties
|
590
|
+
htg_cfm = heat_pump.heating_airflow_cfm
|
1015
591
|
|
592
|
+
# Cooling Coil (none)
|
1016
593
|
clg_coil = nil
|
1017
594
|
|
1018
595
|
# Heating Coil (model w/ constant efficiency)
|
@@ -1022,35 +599,27 @@ class HVAC
|
|
1022
599
|
htg_coil.setName(obj_name + ' htg coil')
|
1023
600
|
htg_coil.setRatedCOP(heat_pump.heating_efficiency_cop)
|
1024
601
|
htg_coil.setDefrostTimePeriodFraction(0.00001) # Disable defrost; avoid E+ warning w/ value of zero
|
1025
|
-
htg_coil.setMinimumOutdoorDryBulbTemperatureforCompressorOperation(UnitConversions.convert(hp_min_temp, 'F', 'C'))
|
602
|
+
htg_coil.setMinimumOutdoorDryBulbTemperatureforCompressorOperation(UnitConversions.convert(hp_ap.hp_min_temp, 'F', 'C'))
|
603
|
+
htg_coil.setRatedTotalHeatingCapacity(UnitConversions.convert(heat_pump.heating_capacity, 'Btu/hr', 'W'))
|
604
|
+
htg_coil.setRatedAirFlowRate(htg_cfm)
|
1026
605
|
hvac_map[heat_pump.id] << htg_coil
|
1027
606
|
|
1028
607
|
# Supplemental Heating Coil
|
1029
|
-
|
1030
608
|
htg_supp_coil = create_supp_heating_coil(model, obj_name, heat_pump)
|
1031
609
|
hvac_map[heat_pump.id] << htg_supp_coil
|
1032
610
|
|
1033
611
|
# Fan
|
1034
|
-
|
1035
|
-
|
1036
|
-
fan = create_supply_fan(model, obj_name, 1, fan_power_installed)
|
612
|
+
fan_power_installed = 0.0 # Use provided net COP
|
613
|
+
fan = create_supply_fan(model, obj_name, 1, fan_power_installed, htg_cfm)
|
1037
614
|
hvac_map[heat_pump.id] += disaggregate_fan_or_pump(model, fan, htg_coil, clg_coil, htg_supp_coil)
|
1038
615
|
|
1039
616
|
# Unitary System
|
1040
|
-
|
1041
|
-
air_loop_unitary = create_air_loop_unitary_system(model, obj_name, fan, htg_coil, clg_coil, htg_supp_coil, supp_max_temp)
|
617
|
+
air_loop_unitary = create_air_loop_unitary_system(model, obj_name, fan, htg_coil, clg_coil, htg_supp_coil, htg_cfm, nil, hp_ap.supp_max_temp)
|
1042
618
|
hvac_map[heat_pump.id] << air_loop_unitary
|
1043
619
|
|
1044
620
|
# Air Loop
|
1045
|
-
|
1046
|
-
air_loop = create_air_loop(model, obj_name, air_loop_unitary, control_zone, sequential_heat_load_frac, sequential_cool_load_frac)
|
621
|
+
air_loop = create_air_loop(model, obj_name, air_loop_unitary, control_zone, sequential_heat_load_frac, sequential_cool_load_frac, htg_cfm)
|
1047
622
|
hvac_map[heat_pump.id] << air_loop
|
1048
|
-
|
1049
|
-
# Store info for HVAC Sizing measure
|
1050
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACFracHeatLoadServed, heat_pump.fraction_heat_load_served)
|
1051
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACFracCoolLoadServed, heat_pump.fraction_cool_load_served)
|
1052
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACCoolType, Constants.ObjectNameWaterLoopHeatPump)
|
1053
|
-
air_loop_unitary.additionalProperties.setFeature(Constants.SizingInfoHVACHeatType, Constants.ObjectNameWaterLoopHeatPump)
|
1054
623
|
end
|
1055
624
|
|
1056
625
|
def self.apply_boiler(model, runner, heating_system,
|
@@ -1076,7 +645,6 @@ class HVAC
|
|
1076
645
|
end
|
1077
646
|
|
1078
647
|
# Plant Loop
|
1079
|
-
|
1080
648
|
plant_loop = OpenStudio::Model::PlantLoop.new(model)
|
1081
649
|
plant_loop.setName(obj_name + ' hydronic heat loop')
|
1082
650
|
plant_loop.setFluidType('Water')
|
@@ -1092,8 +660,8 @@ class HVAC
|
|
1092
660
|
loop_sizing.setLoopDesignTemperatureDifference(UnitConversions.convert(20.0, 'R', 'K'))
|
1093
661
|
|
1094
662
|
# Pump
|
1095
|
-
|
1096
663
|
pump_w = heating_system.electric_auxiliary_energy / 2.08
|
664
|
+
pump_w = [pump_w, 1.0].max # prevent error if zero
|
1097
665
|
pump = OpenStudio::Model::PumpVariableSpeed.new(model)
|
1098
666
|
pump.setName(obj_name + ' hydronic pump')
|
1099
667
|
pump.setRatedPowerConsumption(pump_w)
|
@@ -1110,13 +678,9 @@ class HVAC
|
|
1110
678
|
hvac_map[heating_system.id] << pump
|
1111
679
|
|
1112
680
|
# Boiler
|
1113
|
-
|
1114
681
|
boiler = OpenStudio::Model::BoilerHotWater.new(model)
|
1115
682
|
boiler.setName(obj_name)
|
1116
|
-
boiler.setFuelType(EPlus.
|
1117
|
-
if not heating_system.heating_capacity.nil?
|
1118
|
-
boiler.setNominalCapacity(UnitConversions.convert([heating_system.heating_capacity, Constants.small].max, 'Btu/hr', 'W')) # Used by HVACSizing measure
|
1119
|
-
end
|
683
|
+
boiler.setFuelType(EPlus.fuel_type(heating_system.heating_system_fuel))
|
1120
684
|
if is_condensing
|
1121
685
|
# Convert Rated Efficiency at 80F and 1.0PLR where the performance curves are derived from to Design condition as input
|
1122
686
|
boiler_RatedHWRT = UnitConversions.convert(80.0 - 32.0, 'R', 'K')
|
@@ -1142,6 +706,7 @@ class HVAC
|
|
1142
706
|
boiler.setOptimumPartLoadRatio(1.0)
|
1143
707
|
boiler.setWaterOutletUpperTemperatureLimit(99.9)
|
1144
708
|
boiler.setParasiticElectricLoad(0)
|
709
|
+
boiler.setNominalCapacity(UnitConversions.convert(heating_system.heating_capacity, 'Btu/hr', 'W'))
|
1145
710
|
plant_loop.addSupplyBranchForComponent(boiler)
|
1146
711
|
hvac_map[heating_system.id] << boiler
|
1147
712
|
set_pump_power_ems_program(model, pump_w, pump, boiler)
|
@@ -1177,16 +742,21 @@ class HVAC
|
|
1177
742
|
pipe_demand_outlet = OpenStudio::Model::PipeAdiabatic.new(model)
|
1178
743
|
pipe_demand_outlet.addToNode(plant_loop.demandOutletNode)
|
1179
744
|
|
1180
|
-
|
745
|
+
bb_ua = UnitConversions.convert(heating_system.heating_capacity, 'Btu/hr', 'W') / UnitConversions.convert(UnitConversions.convert(loop_sizing.designLoopExitTemperature, 'C', 'F') - 10.0 - 95.0, 'R', 'K') * 3.0 # W/K
|
746
|
+
max_water_flow = UnitConversions.convert(heating_system.heating_capacity, 'Btu/hr', 'W') / UnitConversions.convert(20.0, 'R', 'K') / 4.186 / 998.2 / 1000.0 * 2.0 # m^3/s
|
747
|
+
fan_cfm = 400.0 * UnitConversions.convert(heating_system.heating_capacity, 'Btu/hr', 'ton') # CFM; assumes 400 cfm/ton
|
748
|
+
|
749
|
+
if heating_system.distribution_system.air_type.to_s == HPXML::AirTypeFanCoil
|
1181
750
|
# Fan
|
1182
|
-
fan = create_supply_fan(model, obj_name, 1, 0.0) # fan energy included in above pump via
|
751
|
+
fan = create_supply_fan(model, obj_name, 1, 0.0, fan_cfm) # fan energy included in above pump via Electric Auxiliary Energy (EAE)
|
1183
752
|
|
1184
753
|
# Heating Coil
|
1185
754
|
htg_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule)
|
755
|
+
htg_coil.setRatedCapacity(UnitConversions.convert(heating_system.heating_capacity, 'Btu/hr', 'W'))
|
756
|
+
htg_coil.setUFactorTimesAreaValue(bb_ua)
|
757
|
+
htg_coil.setMaximumWaterFlowRate(max_water_flow)
|
758
|
+
htg_coil.setPerformanceInputMethod('NominalCapacity')
|
1186
759
|
htg_coil.setName(obj_name + ' htg coil')
|
1187
|
-
if not heating_system.heating_capacity.nil?
|
1188
|
-
htg_coil.setRatedCapacity(UnitConversions.convert([heating_system.heating_capacity, Constants.small].max, 'Btu/hr', 'W')) # Used by HVACSizing measure
|
1189
|
-
end
|
1190
760
|
plant_loop.addDemandBranchForComponent(htg_coil)
|
1191
761
|
|
1192
762
|
# Cooling Coil (always off)
|
@@ -1210,6 +780,8 @@ class HVAC
|
|
1210
780
|
zone_hvac.setMaximumColdWaterFlowRate(0.0)
|
1211
781
|
zone_hvac.setCoolingConvergenceTolerance(0.001)
|
1212
782
|
zone_hvac.setMaximumOutdoorAirFlowRate(0.0)
|
783
|
+
zone_hvac.setMaximumSupplyAirFlowRate(UnitConversions.convert(fan_cfm, 'cfm', 'm^3/s'))
|
784
|
+
zone_hvac.setMaximumHotWaterFlowRate(max_water_flow)
|
1213
785
|
zone_hvac.addToThermalZone(control_zone)
|
1214
786
|
hvac_map[heating_system.id] << zone_hvac
|
1215
787
|
hvac_map[heating_system.id] += disaggregate_fan_or_pump(model, pump, zone_hvac, nil, nil)
|
@@ -1217,10 +789,11 @@ class HVAC
|
|
1217
789
|
# Heating Coil
|
1218
790
|
htg_coil = OpenStudio::Model::CoilHeatingWaterBaseboard.new(model)
|
1219
791
|
htg_coil.setName(obj_name + ' htg coil')
|
1220
|
-
if not heating_system.heating_capacity.nil?
|
1221
|
-
htg_coil.setHeatingDesignCapacity(UnitConversions.convert([heating_system.heating_capacity, Constants.small].max, 'Btu/hr', 'W')) # Used by HVACSizing measure
|
1222
|
-
end
|
1223
792
|
htg_coil.setConvergenceTolerance(0.001)
|
793
|
+
htg_coil.setHeatingDesignCapacity(UnitConversions.convert(heating_system.heating_capacity, 'Btu/hr', 'W'))
|
794
|
+
htg_coil.setUFactorTimesAreaValue(bb_ua)
|
795
|
+
htg_coil.setMaximumWaterFlowRate(max_water_flow)
|
796
|
+
htg_coil.setHeatingDesignCapacityMethod('HeatingDesignCapacity')
|
1224
797
|
plant_loop.addDemandBranchForComponent(htg_coil)
|
1225
798
|
hvac_map[heating_system.id] << htg_coil
|
1226
799
|
|
@@ -1234,10 +807,6 @@ class HVAC
|
|
1234
807
|
|
1235
808
|
control_zone.setSequentialHeatingFractionSchedule(zone_hvac, get_sequential_load_schedule(model, sequential_heat_load_frac))
|
1236
809
|
control_zone.setSequentialCoolingFractionSchedule(zone_hvac, get_sequential_load_schedule(model, 0))
|
1237
|
-
|
1238
|
-
# Store info for HVAC Sizing measure
|
1239
|
-
zone_hvac.additionalProperties.setFeature(Constants.SizingInfoHVACFracHeatLoadServed, heating_system.fraction_heat_load_served)
|
1240
|
-
zone_hvac.additionalProperties.setFeature(Constants.SizingInfoHVACHeatType, Constants.ObjectNameBoiler)
|
1241
810
|
end
|
1242
811
|
|
1243
812
|
def self.apply_electric_baseboard(model, runner, heating_system,
|
@@ -1249,22 +818,15 @@ class HVAC
|
|
1249
818
|
sequential_heat_load_frac = calc_sequential_load_fraction(heating_system.fraction_heat_load_served, remaining_heat_load_frac)
|
1250
819
|
|
1251
820
|
# Baseboard
|
1252
|
-
|
1253
821
|
zone_hvac = OpenStudio::Model::ZoneHVACBaseboardConvectiveElectric.new(model)
|
1254
822
|
zone_hvac.setName(obj_name)
|
1255
|
-
if not heating_system.heating_capacity.nil?
|
1256
|
-
zone_hvac.setNominalCapacity(UnitConversions.convert([heating_system.heating_capacity, Constants.small].max, 'Btu/hr', 'W')) # Used by HVACSizing measure
|
1257
|
-
end
|
1258
823
|
zone_hvac.setEfficiency(heating_system.heating_efficiency_percent)
|
824
|
+
zone_hvac.setNominalCapacity(UnitConversions.convert(heating_system.heating_capacity, 'Btu/hr', 'W'))
|
1259
825
|
zone_hvac.addToThermalZone(control_zone)
|
1260
826
|
hvac_map[heating_system.id] << zone_hvac
|
1261
827
|
|
1262
828
|
control_zone.setSequentialHeatingFractionSchedule(zone_hvac, get_sequential_load_schedule(model, sequential_heat_load_frac))
|
1263
829
|
control_zone.setSequentialCoolingFractionSchedule(zone_hvac, get_sequential_load_schedule(model, 0))
|
1264
|
-
|
1265
|
-
# Store info for HVAC Sizing measure
|
1266
|
-
zone_hvac.additionalProperties.setFeature(Constants.SizingInfoHVACFracHeatLoadServed, heating_system.fraction_heat_load_served)
|
1267
|
-
zone_hvac.additionalProperties.setFeature(Constants.SizingInfoHVACHeatType, Constants.ObjectNameElectricBaseboard)
|
1268
830
|
end
|
1269
831
|
|
1270
832
|
def self.apply_unit_heater(model, runner, heating_system,
|
@@ -1274,15 +836,10 @@ class HVAC
|
|
1274
836
|
hvac_map[heating_system.id] = []
|
1275
837
|
obj_name = Constants.ObjectNameUnitHeater
|
1276
838
|
sequential_heat_load_frac = calc_sequential_load_fraction(heating_system.fraction_heat_load_served, remaining_heat_load_frac)
|
1277
|
-
fan_power_installed = 0.5 # W/cfm # For fuel equipment, will be overridden by EAE later
|
1278
|
-
airflow_rate = 125.0 # cfm/ton; doesn't affect energy consumption
|
1279
839
|
|
1280
|
-
|
1281
|
-
fail 'If Fan Power > 0, then Airflow Rate cannot be zero.'
|
1282
|
-
end
|
840
|
+
htg_ap = heating_system.additional_properties
|
1283
841
|
|
1284
842
|
# Heating Coil
|
1285
|
-
|
1286
843
|
efficiency = heating_system.heating_efficiency_afue
|
1287
844
|
efficiency = heating_system.heating_efficiency_percent if efficiency.nil?
|
1288
845
|
if heating_system.heating_system_fuel == HPXML::FuelTypeElectricity
|
@@ -1293,40 +850,32 @@ class HVAC
|
|
1293
850
|
htg_coil.setGasBurnerEfficiency(efficiency)
|
1294
851
|
htg_coil.setParasiticElectricLoad(0.0)
|
1295
852
|
htg_coil.setParasiticGasLoad(0)
|
1296
|
-
htg_coil.setFuelType(EPlus.
|
853
|
+
htg_coil.setFuelType(EPlus.fuel_type(heating_system.heating_system_fuel))
|
1297
854
|
end
|
855
|
+
htg_coil.setNominalCapacity(UnitConversions.convert(heating_system.heating_capacity, 'Btu/hr', 'W'))
|
1298
856
|
htg_coil.setName(obj_name + ' htg coil')
|
1299
|
-
if not heating_system.heating_capacity.nil?
|
1300
|
-
htg_coil.setNominalCapacity(UnitConversions.convert([heating_system.heating_capacity, Constants.small].max, 'Btu/hr', 'W')) # Used by HVACSizing measure
|
1301
|
-
end
|
1302
857
|
hvac_map[heating_system.id] << htg_coil
|
1303
858
|
|
1304
859
|
# Fan
|
1305
|
-
|
1306
|
-
|
860
|
+
htg_cfm = heating_system.heating_airflow_cfm
|
861
|
+
fan_watts_per_cfm = heating_system.fan_watts / htg_cfm
|
862
|
+
fan = create_supply_fan(model, obj_name, 1, fan_watts_per_cfm, htg_cfm)
|
1307
863
|
hvac_map[heating_system.id] += disaggregate_fan_or_pump(model, fan, htg_coil, nil, nil)
|
1308
864
|
|
1309
865
|
# Unitary System
|
1310
|
-
|
1311
|
-
unitary_system = create_air_loop_unitary_system(model, obj_name, fan, htg_coil, nil, nil)
|
866
|
+
unitary_system = create_air_loop_unitary_system(model, obj_name, fan, htg_coil, nil, nil, htg_cfm, nil)
|
1312
867
|
unitary_system.setControllingZoneorThermostatLocation(control_zone)
|
1313
868
|
unitary_system.addToThermalZone(control_zone)
|
1314
869
|
hvac_map[heating_system.id] << unitary_system
|
1315
870
|
|
1316
871
|
control_zone.setSequentialHeatingFractionSchedule(unitary_system, get_sequential_load_schedule(model, sequential_heat_load_frac))
|
1317
872
|
control_zone.setSequentialCoolingFractionSchedule(unitary_system, get_sequential_load_schedule(model, 0))
|
1318
|
-
|
1319
|
-
# Store info for HVAC Sizing measure
|
1320
|
-
unitary_system.additionalProperties.setFeature(Constants.SizingInfoHVACRatedCFMperTonHeating, airflow_rate.to_s)
|
1321
|
-
unitary_system.additionalProperties.setFeature(Constants.SizingInfoHVACFracHeatLoadServed, heating_system.fraction_heat_load_served)
|
1322
|
-
unitary_system.additionalProperties.setFeature(Constants.SizingInfoHVACHeatType, Constants.ObjectNameUnitHeater)
|
1323
873
|
end
|
1324
874
|
|
1325
875
|
def self.apply_ideal_air_loads(model, runner, obj_name, sequential_cool_load_frac,
|
1326
876
|
sequential_heat_load_frac, control_zone)
|
1327
877
|
|
1328
878
|
# Ideal Air System
|
1329
|
-
|
1330
879
|
ideal_air = OpenStudio::Model::ZoneHVACIdealLoadsAirSystem.new(model)
|
1331
880
|
ideal_air.setName(obj_name)
|
1332
881
|
ideal_air.setMaximumHeatingSupplyAirTemperature(50)
|
@@ -1351,62 +900,70 @@ class HVAC
|
|
1351
900
|
|
1352
901
|
control_zone.setSequentialCoolingFractionSchedule(ideal_air, get_sequential_load_schedule(model, sequential_cool_load_frac))
|
1353
902
|
control_zone.setSequentialHeatingFractionSchedule(ideal_air, get_sequential_load_schedule(model, sequential_heat_load_frac))
|
1354
|
-
|
1355
|
-
# Store info for HVAC Sizing measure
|
1356
|
-
ideal_air.additionalProperties.setFeature(Constants.SizingInfoHVACCoolType, Constants.ObjectNameIdealAirSystem)
|
1357
|
-
ideal_air.additionalProperties.setFeature(Constants.SizingInfoHVACHeatType, Constants.ObjectNameIdealAirSystem)
|
1358
903
|
end
|
1359
904
|
|
1360
|
-
def self.
|
1361
|
-
|
1362
|
-
|
1363
|
-
water_removal_rate = dehumidifier.capacity
|
1364
|
-
energy_factor = dehumidifier.energy_factor
|
1365
|
-
|
1366
|
-
control_zone = living_space.thermalZone.get
|
1367
|
-
obj_name = Constants.ObjectNameDehumidifier
|
905
|
+
def self.apply_dehumidifiers(model, runner, dehumidifiers, living_space, hvac_map)
|
906
|
+
dehumidifier_id = dehumidifiers[0].id # Syncs with SimulationOutputReport, which only looks at first dehumidifier ID
|
907
|
+
hvac_map[dehumidifier_id] = []
|
1368
908
|
|
1369
|
-
|
1370
|
-
|
1371
|
-
|
1372
|
-
relative_humidity_setpoint_sch.setValue(avg_rh_setpoint)
|
909
|
+
if dehumidifiers.map { |d| d.rh_setpoint }.uniq.size > 1
|
910
|
+
fail 'All dehumidifiers must have the same setpoint but multiple setpoints were specified.'
|
911
|
+
end
|
1373
912
|
|
1374
913
|
# Dehumidifier coefficients
|
1375
914
|
# Generic model coefficients from Winkler, Christensen, and Tomerlin (2011)
|
1376
915
|
w_coeff = [-1.162525707, 0.02271469, -0.000113208, 0.021110538, -0.0000693034, 0.000378843]
|
1377
916
|
ef_coeff = [-1.902154518, 0.063466565, -0.000622839, 0.039540407, -0.000125637, -0.000176722]
|
1378
917
|
pl_coeff = [0.90, 0.10, 0.0]
|
1379
|
-
|
1380
|
-
|
1381
|
-
|
1382
|
-
|
918
|
+
|
919
|
+
dehumidifiers.each do |d|
|
920
|
+
next unless d.energy_factor.nil?
|
921
|
+
|
1383
922
|
# shift inputs tested under IEF test conditions to those under EF test conditions with performance curves
|
1384
|
-
energy_factor,
|
923
|
+
d.energy_factor, d.capacity = apply_dehumidifier_ief_to_ef_inputs(d.type, w_coeff, ef_coeff, d.integrated_energy_factor, d.capacity)
|
1385
924
|
end
|
1386
925
|
|
926
|
+
total_capacity = dehumidifiers.map { |d| d.capacity }.sum
|
927
|
+
avg_energy_factor = dehumidifiers.map { |d| d.energy_factor * d.capacity }.sum / total_capacity
|
928
|
+
total_fraction_served = dehumidifiers.map { |d| d.fraction_served }.sum
|
929
|
+
|
930
|
+
control_zone = living_space.thermalZone.get
|
931
|
+
obj_name = Constants.ObjectNameDehumidifier
|
932
|
+
|
933
|
+
rh_setpoint = dehumidifiers[0].rh_setpoint * 100.0 # (EnergyPlus uses 60 for 60% RH)
|
934
|
+
relative_humidity_setpoint_sch = OpenStudio::Model::ScheduleConstant.new(model)
|
935
|
+
relative_humidity_setpoint_sch.setName(Constants.ObjectNameRelativeHumiditySetpoint)
|
936
|
+
relative_humidity_setpoint_sch.setValue(rh_setpoint)
|
937
|
+
|
938
|
+
capacity_curve = create_curve_biquadratic(model, w_coeff, 'DXDH-CAP-fT', -100, 100, -100, 100)
|
939
|
+
energy_factor_curve = create_curve_biquadratic(model, ef_coeff, 'DXDH-EF-fT', -100, 100, -100, 100)
|
940
|
+
part_load_frac_curve = create_curve_quadratic(model, pl_coeff, 'DXDH-PLF-fPLR', 0, 1, 0.7, 1)
|
941
|
+
|
1387
942
|
# Calculate air flow rate by assuming 2.75 cfm/pint/day (based on experimental test data)
|
1388
|
-
air_flow_rate = 2.75 *
|
943
|
+
air_flow_rate = 2.75 * total_capacity
|
1389
944
|
|
945
|
+
# Humidity Setpoint
|
1390
946
|
humidistat = OpenStudio::Model::ZoneControlHumidistat.new(model)
|
1391
947
|
humidistat.setName(obj_name + ' humidistat')
|
1392
948
|
humidistat.setHumidifyingRelativeHumiditySetpointSchedule(relative_humidity_setpoint_sch)
|
1393
949
|
humidistat.setDehumidifyingRelativeHumiditySetpointSchedule(relative_humidity_setpoint_sch)
|
1394
950
|
control_zone.setZoneControlHumidistat(humidistat)
|
1395
951
|
|
1396
|
-
|
952
|
+
# Dehumidifier
|
953
|
+
zone_hvac = OpenStudio::Model::ZoneHVACDehumidifierDX.new(model, capacity_curve, energy_factor_curve, part_load_frac_curve)
|
1397
954
|
zone_hvac.setName(obj_name)
|
1398
955
|
zone_hvac.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
1399
|
-
zone_hvac.setRatedWaterRemoval(UnitConversions.convert(
|
1400
|
-
zone_hvac.setRatedEnergyFactor(
|
956
|
+
zone_hvac.setRatedWaterRemoval(UnitConversions.convert(total_capacity, 'pint', 'L'))
|
957
|
+
zone_hvac.setRatedEnergyFactor(avg_energy_factor / total_fraction_served)
|
1401
958
|
zone_hvac.setRatedAirFlowRate(UnitConversions.convert(air_flow_rate, 'cfm', 'm^3/s'))
|
1402
959
|
zone_hvac.setMinimumDryBulbTemperatureforDehumidifierOperation(10)
|
1403
960
|
zone_hvac.setMaximumDryBulbTemperatureforDehumidifierOperation(40)
|
1404
961
|
|
1405
962
|
zone_hvac.addToThermalZone(control_zone)
|
1406
963
|
|
1407
|
-
hvac_map[
|
1408
|
-
if
|
1409
|
-
adjust_dehumidifier_load_EMS(
|
964
|
+
hvac_map[dehumidifier_id] << zone_hvac
|
965
|
+
if total_fraction_served < 1.0
|
966
|
+
adjust_dehumidifier_load_EMS(total_fraction_served, zone_hvac, model, living_space)
|
1410
967
|
end
|
1411
968
|
end
|
1412
969
|
|
@@ -1445,56 +1002,77 @@ class HVAC
|
|
1445
1002
|
equip.setSchedule(ceiling_fan_sch)
|
1446
1003
|
end
|
1447
1004
|
|
1448
|
-
def self.apply_setpoints(model, runner, weather, hvac_control, living_zone)
|
1005
|
+
def self.apply_setpoints(model, runner, weather, hvac_control, living_zone, has_ceiling_fan)
|
1449
1006
|
# Assume heating/cooling seasons are year-round
|
1450
1007
|
htg_start_month = 1
|
1451
1008
|
htg_end_month = 12
|
1452
1009
|
clg_start_month = 1
|
1453
1010
|
clg_end_month = 12
|
1454
1011
|
|
1455
|
-
|
1456
|
-
|
1457
|
-
|
1458
|
-
|
1459
|
-
|
1460
|
-
|
1461
|
-
|
1462
|
-
|
1463
|
-
|
1464
|
-
|
1465
|
-
for
|
1466
|
-
|
1012
|
+
if hvac_control.weekday_heating_setpoints.nil? || hvac_control.weekend_heating_setpoints.nil?
|
1013
|
+
# Base heating setpoint
|
1014
|
+
htg_setpoint = hvac_control.heating_setpoint_temp
|
1015
|
+
htg_weekday_setpoints = [[htg_setpoint] * 24] * 12
|
1016
|
+
|
1017
|
+
# Apply heating setback?
|
1018
|
+
htg_setback = hvac_control.heating_setback_temp
|
1019
|
+
if not htg_setback.nil?
|
1020
|
+
htg_setback_hrs_per_week = hvac_control.heating_setback_hours_per_week
|
1021
|
+
htg_setback_start_hr = hvac_control.heating_setback_start_hour
|
1022
|
+
for m in 1..12
|
1023
|
+
for hr in htg_setback_start_hr..htg_setback_start_hr + Integer(htg_setback_hrs_per_week / 7.0) - 1
|
1024
|
+
htg_weekday_setpoints[m - 1][hr % 24] = htg_setback
|
1025
|
+
end
|
1467
1026
|
end
|
1468
1027
|
end
|
1469
|
-
|
1470
|
-
|
1471
|
-
|
1472
|
-
|
1473
|
-
|
1474
|
-
|
1475
|
-
|
1476
|
-
|
1477
|
-
|
1478
|
-
|
1479
|
-
|
1480
|
-
|
1481
|
-
|
1482
|
-
|
1483
|
-
|
1028
|
+
htg_weekend_setpoints = htg_weekday_setpoints.dup
|
1029
|
+
else
|
1030
|
+
# 24-hr weekday/weekend heating setpoint schedules
|
1031
|
+
htg_weekday_setpoints = hvac_control.weekday_heating_setpoints.split(',').map { |i| Float(i) }
|
1032
|
+
htg_weekday_setpoints = [htg_weekday_setpoints] * 12
|
1033
|
+
|
1034
|
+
htg_weekend_setpoints = hvac_control.weekend_heating_setpoints.split(',').map { |i| Float(i) }
|
1035
|
+
htg_weekend_setpoints = [htg_weekend_setpoints] * 12
|
1036
|
+
end
|
1037
|
+
|
1038
|
+
if hvac_control.weekday_cooling_setpoints.nil? || hvac_control.weekend_cooling_setpoints.nil?
|
1039
|
+
# Base cooling setpoint
|
1040
|
+
clg_setpoint = hvac_control.cooling_setpoint_temp
|
1041
|
+
clg_weekday_setpoints = [[clg_setpoint] * 24] * 12
|
1042
|
+
|
1043
|
+
# Apply cooling setup?
|
1044
|
+
clg_setup = hvac_control.cooling_setup_temp
|
1045
|
+
if not clg_setup.nil?
|
1046
|
+
clg_setup_hrs_per_week = hvac_control.cooling_setup_hours_per_week
|
1047
|
+
clg_setup_start_hr = hvac_control.cooling_setup_start_hour
|
1048
|
+
for m in 1..12
|
1049
|
+
for hr in clg_setup_start_hr..clg_setup_start_hr + Integer(clg_setup_hrs_per_week / 7.0) - 1
|
1050
|
+
clg_weekday_setpoints[m - 1][hr % 24] = clg_setup
|
1051
|
+
end
|
1484
1052
|
end
|
1485
1053
|
end
|
1054
|
+
clg_weekend_setpoints = clg_weekday_setpoints.dup
|
1055
|
+
else
|
1056
|
+
# 24-hr weekday/weekend cooling setpoint schedules
|
1057
|
+
clg_weekday_setpoints = hvac_control.weekday_cooling_setpoints.split(',').map { |i| Float(i) }
|
1058
|
+
clg_weekday_setpoints = [clg_weekday_setpoints] * 12
|
1059
|
+
|
1060
|
+
clg_weekend_setpoints = hvac_control.weekend_cooling_setpoints.split(',').map { |i| Float(i) }
|
1061
|
+
clg_weekend_setpoints = [clg_weekend_setpoints] * 12
|
1486
1062
|
end
|
1487
1063
|
|
1488
1064
|
# Apply cooling setpoint offset due to ceiling fan?
|
1489
|
-
|
1490
|
-
|
1491
|
-
|
1492
|
-
|
1493
|
-
|
1494
|
-
|
1065
|
+
if has_ceiling_fan
|
1066
|
+
clg_ceiling_fan_offset = hvac_control.ceiling_fan_cooling_setpoint_temp_offset
|
1067
|
+
if not clg_ceiling_fan_offset.nil?
|
1068
|
+
get_default_ceiling_fan_months(weather).each_with_index do |operation, m|
|
1069
|
+
next unless operation == 1
|
1070
|
+
|
1071
|
+
clg_weekday_setpoints[m] = [clg_weekday_setpoints[m], Array.new(24, clg_ceiling_fan_offset)].transpose.map { |i| i.reduce(:+) }
|
1072
|
+
clg_weekend_setpoints[m] = [clg_weekend_setpoints[m], Array.new(24, clg_ceiling_fan_offset)].transpose.map { |i| i.reduce(:+) }
|
1073
|
+
end
|
1495
1074
|
end
|
1496
1075
|
end
|
1497
|
-
clg_weekend_setpoints = clg_weekday_setpoints
|
1498
1076
|
|
1499
1077
|
# Create heating season schedule
|
1500
1078
|
if htg_start_month <= htg_end_month
|
@@ -1553,48 +1131,6 @@ class HVAC
|
|
1553
1131
|
living_zone.setThermostatSetpointDualSetpoint(thermostat_setpoint)
|
1554
1132
|
end
|
1555
1133
|
|
1556
|
-
def self.apply_eae_to_heating_fan(runner, hvac_objects, heating_system)
|
1557
|
-
# Applies Electric Auxiliary Energy (EAE) for fuel heating equipment to fan/pump power.
|
1558
|
-
|
1559
|
-
eae = heating_system.electric_auxiliary_energy
|
1560
|
-
|
1561
|
-
unitary_systems = []
|
1562
|
-
hvac_objects.each do |hvac_object|
|
1563
|
-
if hvac_object.is_a? OpenStudio::Model::AirLoopHVAC # Furnace
|
1564
|
-
unitary_systems << get_unitary_system_from_air_loop_hvac(hvac_object)
|
1565
|
-
elsif hvac_object.is_a? OpenStudio::Model::AirLoopHVACUnitarySystem # WallFurnace/FloorFurnace/Stove
|
1566
|
-
unitary_systems << hvac_object
|
1567
|
-
end
|
1568
|
-
end
|
1569
|
-
|
1570
|
-
unitary_systems.each do |unitary_system|
|
1571
|
-
if eae.nil?
|
1572
|
-
htg_coil = unitary_system.heatingCoil.get.to_CoilHeatingGas.get
|
1573
|
-
htg_capacity = UnitConversions.convert(htg_coil.nominalCapacity.get, 'W', 'kBtu/hr')
|
1574
|
-
eae = get_electric_auxiliary_energy(heating_system, htg_capacity)
|
1575
|
-
end
|
1576
|
-
elec_power = eae / 2.08 # W
|
1577
|
-
|
1578
|
-
htg_coil = unitary_system.heatingCoil.get.to_CoilHeatingGas.get
|
1579
|
-
htg_coil.setParasiticElectricLoad(0.0)
|
1580
|
-
|
1581
|
-
htg_cfm = UnitConversions.convert(unitary_system.supplyAirFlowRateDuringHeatingOperation.get, 'm^3/s', 'cfm')
|
1582
|
-
|
1583
|
-
fan = unitary_system.supplyFan.get.to_FanOnOff.get
|
1584
|
-
if elec_power > 0
|
1585
|
-
fan_eff = 0.75 # Overall Efficiency of the Fan, Motor and Drive
|
1586
|
-
fan_w_cfm = elec_power / htg_cfm # W/cfm
|
1587
|
-
fan.setFanEfficiency(fan_eff)
|
1588
|
-
fan.setPressureRise(calc_fan_pressure_rise(fan_eff, fan_w_cfm))
|
1589
|
-
else
|
1590
|
-
fan.setFanEfficiency(1)
|
1591
|
-
fan.setPressureRise(0)
|
1592
|
-
end
|
1593
|
-
fan.setMotorEfficiency(1.0)
|
1594
|
-
fan.setMotorInAirstreamFraction(1.0)
|
1595
|
-
end
|
1596
|
-
end
|
1597
|
-
|
1598
1134
|
def self.get_default_heating_setpoint(control_type)
|
1599
1135
|
# Per ANSI/RESNET/ICC 301
|
1600
1136
|
htg_sp = 68 # F
|
@@ -1627,22 +1163,242 @@ class HVAC
|
|
1627
1163
|
return clg_sp, clg_setup_sp, clg_setup_hrs_per_week, clg_setup_start_hr
|
1628
1164
|
end
|
1629
1165
|
|
1630
|
-
def self.
|
1631
|
-
|
1632
|
-
|
1633
|
-
|
1634
|
-
|
1635
|
-
|
1636
|
-
|
1166
|
+
def self.set_cool_curves_ashp(heat_pump)
|
1167
|
+
hp_ap = heat_pump.additional_properties
|
1168
|
+
if hp_ap.num_speeds == 1
|
1169
|
+
# From "Improved Modeling of Residential Air Conditioners and Heat Pumps for Energy Calculations", Cutler at al
|
1170
|
+
# https://www.nrel.gov/docs/fy13osti/56354.pdf
|
1171
|
+
hp_ap.cool_rated_airflow_rate = 394.2 # cfm/ton of rated capacity
|
1172
|
+
hp_ap.cool_capacity_ratios = [1.0]
|
1173
|
+
hp_ap.cool_fan_speed_ratios = [1.0]
|
1174
|
+
hp_ap.cool_rated_shrs_net = [heat_pump.cooling_shr]
|
1175
|
+
hp_ap.cool_cap_ft_spec = [[3.68637657, -0.098352478, 0.000956357, 0.005838141, -0.0000127, -0.000131702]]
|
1176
|
+
hp_ap.cool_eir_ft_spec = [[-3.437356399, 0.136656369, -0.001049231, -0.0079378, 0.000185435, -0.0001441]]
|
1177
|
+
# Single stage systems have PSC or constant torque ECM blowers, so the airflow rate is affected by the static pressure losses.
|
1178
|
+
hp_ap.cool_cap_fflow_spec = [[0.718664047, 0.41797409, -0.136638137]]
|
1179
|
+
hp_ap.cool_eir_fflow_spec = [[1.143487507, -0.13943972, -0.004047787]]
|
1180
|
+
hp_ap.cool_eers = [calc_eer_cooling_1speed(heat_pump.cooling_efficiency_seer, hp_ap.cool_c_d, hp_ap.fan_power_rated, hp_ap.cool_eir_ft_spec)]
|
1181
|
+
elsif hp_ap.num_speeds == 2
|
1182
|
+
# From "Improved Modeling of Residential Air Conditioners and Heat Pumps for Energy Calculations", Cutler at al
|
1183
|
+
# https://www.nrel.gov/docs/fy13osti/56354.pdf
|
1184
|
+
hp_ap.cool_rated_airflow_rate = 344.1 # cfm/ton
|
1185
|
+
hp_ap.cool_capacity_ratios = [0.72, 1.0]
|
1186
|
+
hp_ap.cool_fan_speed_ratios = [0.86, 1.0]
|
1187
|
+
hp_ap.cool_rated_shrs_net = [heat_pump.cooling_shr - 0.014, heat_pump.cooling_shr] # TODO: is the following assumption correct (revisit Dylan's data?)? OR should value from HPXML be used for both stages?
|
1188
|
+
hp_ap.cool_cap_ft_spec = [[3.998418659, -0.108728222, 0.001056818, 0.007512314, -0.0000139, -0.000164716],
|
1189
|
+
[3.466810106, -0.091476056, 0.000901205, 0.004163355, -0.00000919, -0.000110829]]
|
1190
|
+
hp_ap.cool_eir_ft_spec = [[-4.282911381, 0.181023691, -0.001357391, -0.026310378, 0.000333282, -0.000197405],
|
1191
|
+
[-3.557757517, 0.112737397, -0.000731381, 0.013184877, 0.000132645, -0.000338716]]
|
1192
|
+
# Most two stage systems have PSC or constant torque ECM blowers, so the airflow rate is affected by the static pressure losses.
|
1193
|
+
hp_ap.cool_cap_fflow_spec = [[0.655239515, 0.511655216, -0.166894731],
|
1194
|
+
[0.618281092, 0.569060264, -0.187341356]]
|
1195
|
+
hp_ap.cool_eir_fflow_spec = [[1.639108268, -0.998953996, 0.359845728],
|
1196
|
+
[1.570774717, -0.914152018, 0.343377302]]
|
1197
|
+
hp_ap.cool_eers = calc_eers_cooling_2speed(heat_pump.cooling_efficiency_seer, hp_ap.cool_c_d, hp_ap.cool_capacity_ratios, hp_ap.cool_fan_speed_ratios, hp_ap.fan_power_rated, hp_ap.cool_eir_ft_spec, hp_ap.cool_cap_ft_spec)
|
1198
|
+
elsif hp_ap.num_speeds == 4
|
1199
|
+
# From Carrier heat pump lab testing
|
1200
|
+
hp_ap.cool_rated_airflow_rate = 411.0 # cfm/ton
|
1201
|
+
hp_ap.cool_capacity_ratios = [0.36, 0.51, 0.67, 1.0]
|
1202
|
+
hp_ap.cool_fan_speed_ratios = [0.42, 0.54, 0.68, 1.0]
|
1203
|
+
hp_ap.cool_rated_shrs_net = [1.115, 1.026, 1.013, 1.0].map { |mult| heat_pump.cooling_shr * mult }
|
1204
|
+
hp_ap.cool_cap_coeff_perf_map = [[1.6516044444444447, 0.0698916049382716, -0.0005546296296296296, -0.08870160493827162, 0.0004135802469135802, 0.00029077160493827157],
|
1205
|
+
[-6.84948049382716, 0.26946, -0.0019413580246913577, -0.03281469135802469, 0.00015694444444444442, 3.32716049382716e-05],
|
1206
|
+
[-4.53543086419753, 0.15358543209876546, -0.0009345679012345678, 0.002666913580246914, -7.993827160493826e-06, -0.00011617283950617283],
|
1207
|
+
[-3.500948395061729, 0.11738987654320988, -0.0006580246913580248, 0.007003148148148148, -2.8518518518518517e-05, -0.0001284259259259259],
|
1208
|
+
[1.8769221728395058, -0.04768641975308643, 0.0006885802469135801, 0.006643395061728395, 1.4209876543209876e-05, -0.00024043209876543206]]
|
1209
|
+
hp_ap.cool_cap_ft_spec = hp_ap.cool_cap_coeff_perf_map.select { |i| [0, 1, 2, 4].include? hp_ap.cool_cap_coeff_perf_map.index(i) }
|
1210
|
+
hp_ap.cool_cap_ft_spec_3 = hp_ap.cool_cap_coeff_perf_map.select { |i| [0, 1, 4].include? hp_ap.cool_cap_coeff_perf_map.index(i) }
|
1211
|
+
hp_ap.cool_eir_coeff_perf_map = [[2.896298765432099, -0.12487654320987657, 0.0012148148148148148, 0.04492037037037037, 8.734567901234567e-05, -0.0006348765432098764],
|
1212
|
+
[6.428076543209876, -0.20913209876543212, 0.0018521604938271604, 0.024392592592592594, 0.00019691358024691356, -0.0006012345679012346],
|
1213
|
+
[5.136356049382716, -0.1591530864197531, 0.0014151234567901232, 0.018665555555555557, 0.00020398148148148147, -0.0005407407407407407],
|
1214
|
+
[1.3823471604938273, -0.02875123456790123, 0.00038302469135802463, 0.006344814814814816, 0.00024836419753086417, -0.00047469135802469134],
|
1215
|
+
[-1.0411735802469133, 0.055261604938271605, -0.0004404320987654321, 0.0002154938271604939, 0.00017484567901234564, -0.0002017901234567901]]
|
1216
|
+
hp_ap.cool_eir_ft_spec = hp_ap.cool_eir_coeff_perf_map.select { |i| [0, 1, 2, 4].include? hp_ap.cool_eir_coeff_perf_map.index(i) }
|
1217
|
+
hp_ap.cool_eir_ft_spec_3 = hp_ap.cool_eir_coeff_perf_map.select { |i| [0, 1, 4].include? hp_ap.cool_eir_coeff_perf_map.index(i) }
|
1218
|
+
# Variable speed systems have constant flow ECM blowers, so the air handler can always achieve the design airflow rate by sacrificing blower power.
|
1219
|
+
# So we assume that there is only one corresponding airflow rate for each compressor speed.
|
1220
|
+
hp_ap.cool_eir_fflow_spec = [[1, 0, 0]] * 4
|
1221
|
+
hp_ap.cool_cap_fflow_spec = [[1, 0, 0]] * 4
|
1222
|
+
hp_ap.cap_ratio_seer_3 = hp_ap.cool_capacity_ratios.select { |i| [0, 1, 3].include? hp_ap.cool_capacity_ratios.index(i) }
|
1223
|
+
hp_ap.fan_speed_seer_3 = hp_ap.cool_fan_speed_ratios.select { |i| [0, 1, 3].include? hp_ap.cool_fan_speed_ratios.index(i) }
|
1224
|
+
hp_ap.cool_eers = calc_eers_cooling_4speed(heat_pump.cooling_efficiency_seer, hp_ap.cool_c_d, hp_ap.cap_ratio_seer_3, hp_ap.fan_speed_seer_3, hp_ap.fan_power_rated, hp_ap.cool_eir_ft_spec_3, hp_ap.cool_cap_ft_spec_3)
|
1637
1225
|
end
|
1638
1226
|
end
|
1639
1227
|
|
1640
|
-
def self.
|
1641
|
-
|
1642
|
-
|
1643
|
-
|
1644
|
-
|
1645
|
-
|
1228
|
+
def self.set_ashp_htg_curves(heat_pump)
|
1229
|
+
hp_ap = heat_pump.additional_properties
|
1230
|
+
if hp_ap.num_speeds == 1
|
1231
|
+
# From "Improved Modeling of Residential Air Conditioners and Heat Pumps for Energy Calculations", Cutler at al
|
1232
|
+
# https://www.nrel.gov/docs/fy13osti/56354.pdf
|
1233
|
+
hp_ap.heat_rated_airflow_rate = 384.1 # cfm/ton
|
1234
|
+
hp_ap.heat_capacity_ratios = [1.0]
|
1235
|
+
hp_ap.heat_fan_speed_ratios = [1.0]
|
1236
|
+
hp_ap.heat_eir_ft_spec = [[0.718398423, 0.003498178, 0.000142202, -0.005724331, 0.00014085, -0.000215321]]
|
1237
|
+
hp_ap.heat_cap_fflow_spec = [[0.694045465, 0.474207981, -0.168253446]]
|
1238
|
+
hp_ap.heat_eir_fflow_spec = [[2.185418751, -1.942827919, 0.757409168]]
|
1239
|
+
if heat_pump.heating_capacity_17F.nil?
|
1240
|
+
hp_ap.heat_cap_ft_spec = [[0.566333415, -0.000744164, -0.0000103, 0.009414634, 0.0000506, -0.00000675]]
|
1241
|
+
else
|
1242
|
+
hp_ap.heat_cap_ft_spec = calc_heat_cap_ft_spec_using_capacity_17F(heat_pump)
|
1243
|
+
end
|
1244
|
+
hp_ap.heat_cops = [calc_cop_heating_1speed(heat_pump.heating_efficiency_hspf, hp_ap.heat_c_d, hp_ap.fan_power_rated, hp_ap.heat_eir_ft_spec, hp_ap.heat_cap_ft_spec)]
|
1245
|
+
elsif hp_ap.num_speeds == 2
|
1246
|
+
# From "Improved Modeling of Residential Air Conditioners and Heat Pumps for Energy Calculations", Cutler at al
|
1247
|
+
# https://www.nrel.gov/docs/fy13osti/56354.pdf
|
1248
|
+
hp_ap.heat_rated_airflow_rate = 352.2 # cfm/ton
|
1249
|
+
hp_ap.heat_capacity_ratios = [0.72, 1.0]
|
1250
|
+
hp_ap.heat_fan_speed_ratios = [0.8, 1.0]
|
1251
|
+
hp_ap.heat_eir_ft_spec = [[0.36338171, 0.013523725, 0.000258872, -0.009450269, 0.000439519, -0.000653723],
|
1252
|
+
[0.981100941, -0.005158493, 0.000243416, -0.005274352, 0.000230742, -0.000336954]]
|
1253
|
+
hp_ap.heat_cap_fflow_spec = [[0.741466907, 0.378645444, -0.119754733],
|
1254
|
+
[0.76634609, 0.32840943, -0.094701495]]
|
1255
|
+
hp_ap.heat_eir_fflow_spec = [[2.153618211, -1.737190609, 0.584269478],
|
1256
|
+
[2.001041353, -1.58869128, 0.587593517]]
|
1257
|
+
if heat_pump.heating_capacity_17F.nil?
|
1258
|
+
hp_ap.heat_cap_ft_spec = [[0.335690634, 0.002405123, -0.0000464, 0.013498735, 0.0000499, -0.00000725],
|
1259
|
+
[0.306358843, 0.005376987, -0.0000579, 0.011645092, 0.0000591, -0.0000203]]
|
1260
|
+
else
|
1261
|
+
hp_ap.heat_cap_ft_spec = calc_heat_cap_ft_spec_using_capacity_17F(heat_pump)
|
1262
|
+
end
|
1263
|
+
hp_ap.heat_cops = calc_cops_heating_2speed(heat_pump.heating_efficiency_hspf, hp_ap.heat_c_d, hp_ap.heat_capacity_ratios, hp_ap.heat_fan_speed_ratios, hp_ap.fan_power_rated, hp_ap.heat_eir_ft_spec, hp_ap.heat_cap_ft_spec)
|
1264
|
+
elsif hp_ap.num_speeds == 4
|
1265
|
+
# From Carrier heat pump lab testing
|
1266
|
+
hp_ap.heat_rated_airflow_rate = 296.9 # cfm/ton
|
1267
|
+
hp_ap.heat_capacity_ratios = [0.33, 0.56, 1.0, 1.17]
|
1268
|
+
hp_ap.heat_fan_speed_ratios = [0.63, 0.76, 1.0, 1.19]
|
1269
|
+
hp_ap.heat_eir_ft_spec = [[0.708311527, 0.020732093, 0.000391479, -0.037640031, 0.000979937, -0.001079042],
|
1270
|
+
[0.025480155, 0.020169585, 0.000121341, -0.004429789, 0.000166472, -0.00036447],
|
1271
|
+
[0.379003189, 0.014195012, 0.0000821046, -0.008894061, 0.000151519, -0.000210299],
|
1272
|
+
[0.690404655, 0.00616619, 0.000137643, -0.009350199, 0.000153427, -0.000213258]]
|
1273
|
+
hp_ap.heat_cap_fflow_spec = [[1, 0, 0]] * 4
|
1274
|
+
hp_ap.heat_eir_fflow_spec = [[1, 0, 0]] * 4
|
1275
|
+
if heat_pump.heating_capacity_17F.nil?
|
1276
|
+
hp_ap.heat_cap_ft_spec = [[0.304192655, -0.003972566, 0.0000196432, 0.024471251, -0.000000774126, -0.0000841323],
|
1277
|
+
[0.496381324, -0.00144792, 0.0, 0.016020855, 0.0000203447, -0.0000584118],
|
1278
|
+
[0.697171186, -0.006189599, 0.0000337077, 0.014291981, 0.0000105633, -0.0000387956],
|
1279
|
+
[0.555513805, -0.001337363, -0.00000265117, 0.014328826, 0.0000163849, -0.0000480711]]
|
1280
|
+
else
|
1281
|
+
hp_ap.heat_cap_ft_spec = calc_heat_cap_ft_spec_using_capacity_17F(heat_pump)
|
1282
|
+
end
|
1283
|
+
hp_ap.heat_cops = calc_cops_heating_4speed(heat_pump.heating_efficiency_hspf, hp_ap.heat_c_d, hp_ap.heat_capacity_ratios, hp_ap.heat_fan_speed_ratios, hp_ap.fan_power_rated, hp_ap.heat_eir_ft_spec, hp_ap.heat_cap_ft_spec)
|
1284
|
+
end
|
1285
|
+
end
|
1286
|
+
|
1287
|
+
def self.set_cool_curves_room_ac(cooling_system)
|
1288
|
+
clg_ap = cooling_system.additional_properties
|
1289
|
+
|
1290
|
+
# From "Improved Modeling of Residential Air Conditioners and Heat Pumps for Energy Calculations", Cutler at al
|
1291
|
+
# https://www.nrel.gov/docs/fy13osti/56354.pdf
|
1292
|
+
clg_ap.cool_cap_ft_spec = [[3.68637657, -0.098352478, 0.000956357, 0.005838141, -0.0000127, -0.000131702]]
|
1293
|
+
clg_ap.cool_eir_ft_spec = [[-3.437356399, 0.136656369, -0.001049231, -0.0079378, 0.000185435, -0.0001441]]
|
1294
|
+
clg_ap.cool_cap_fflow_spec = [[1, 0, 0]]
|
1295
|
+
clg_ap.cool_eir_fflow_spec = [[1, 0, 0]]
|
1296
|
+
end
|
1297
|
+
|
1298
|
+
def self.set_cool_curves_mshp(heat_pump, num_speeds)
|
1299
|
+
hp_ap = heat_pump.additional_properties
|
1300
|
+
|
1301
|
+
# From Daikin mini-split lab testing
|
1302
|
+
hp_ap.cool_cap_ft_spec = [[0.7531983499655835, 0.003618193903031667, 0.0, 0.006574385031351544, -6.87181191015432e-05, 0.0]] * num_speeds
|
1303
|
+
hp_ap.cool_eir_ft_spec = [[-0.06376924779982301, -0.0013360593470367282, 1.413060577993827e-05, 0.019433076486584752, -4.91395947154321e-05, -4.909341249475308e-05]] * num_speeds
|
1304
|
+
hp_ap.cool_cap_fflow_spec = [[1, 0, 0]] * num_speeds
|
1305
|
+
hp_ap.cool_eir_fflow_spec = [[1, 0, 0]] * num_speeds
|
1306
|
+
|
1307
|
+
hp_ap.cool_min_capacity_ratio = 0.4 # frac
|
1308
|
+
hp_ap.cool_max_capacity_ratio = 1.2 # frac
|
1309
|
+
hp_ap.cool_min_cfm_per_ton = 200.0 / hp_ap.cool_min_capacity_ratio # Convert cfm/ton of nominal rated capacity to cfm/ton of min capacity
|
1310
|
+
hp_ap.cool_max_cfm_per_ton = 425.0 / hp_ap.cool_max_capacity_ratio # Convert cfm/ton of nominal rated capacity to cfm/ton of max capacity
|
1311
|
+
end
|
1312
|
+
|
1313
|
+
def self.set_heat_curves_mshp(heat_pump, num_speeds)
|
1314
|
+
hp_ap = heat_pump.additional_properties
|
1315
|
+
|
1316
|
+
# From Daikin mini-split lab testing
|
1317
|
+
hp_ap.heat_eir_ft_spec = [[0.9999941697687026, 0.004684593830254383, 5.901286675833333e-05, -0.0028624467783091973, 1.3041120194135802e-05, -0.00016172918478765433]] * num_speeds
|
1318
|
+
hp_ap.heat_cap_fflow_spec = [[1, 0, 0]] * num_speeds
|
1319
|
+
hp_ap.heat_eir_fflow_spec = [[1, 0, 0]] * num_speeds
|
1320
|
+
|
1321
|
+
# Derive coefficients from user input for capacity retention at outdoor drybulb temperature X [C].
|
1322
|
+
if heat_pump.heating_capacity_17F.nil? || ((heat_pump.heating_capacity_17F == 0) && (heat_pump.heating_capacity == 0))
|
1323
|
+
cap_retention_frac = 0.25 # frac
|
1324
|
+
cap_retention_temp = -5.0 # deg-F
|
1325
|
+
else
|
1326
|
+
cap_retention_frac = heat_pump.heating_capacity_17F / heat_pump.heating_capacity
|
1327
|
+
cap_retention_temp = 17.0 # deg-F
|
1328
|
+
end
|
1329
|
+
|
1330
|
+
# Biquadratic: capacity multiplier = a + b*IAT + c*IAT^2 + d*OAT + e*OAT^2 + f*IAT*OAT
|
1331
|
+
x_A = UnitConversions.convert(cap_retention_temp, 'F', 'C')
|
1332
|
+
y_A = cap_retention_frac
|
1333
|
+
x_B = UnitConversions.convert(47.0, 'F', 'C') # 47F is the rating point
|
1334
|
+
y_B = 1.0 # Maximum capacity factor is 1 at the rating point, by definition (this is maximum capacity, not nominal capacity)
|
1335
|
+
oat_slope = (y_B - y_A) / (x_B - x_A)
|
1336
|
+
oat_intercept = y_A - (x_A * oat_slope)
|
1337
|
+
|
1338
|
+
# Coefficients for the indoor temperature relationship are retained from the generic curve (Daikin lab data).
|
1339
|
+
iat_slope = -0.010386676170938
|
1340
|
+
iat_intercept = 0.219274275
|
1341
|
+
a = oat_intercept + iat_intercept
|
1342
|
+
b = iat_slope
|
1343
|
+
c = 0
|
1344
|
+
d = oat_slope
|
1345
|
+
e = 0
|
1346
|
+
f = 0
|
1347
|
+
hp_ap.heat_cap_ft_spec = [HVAC.convert_curve_biquadratic([a, b, c, d, e, f], false)] * num_speeds
|
1348
|
+
|
1349
|
+
hp_ap.heat_min_capacity_ratio = 0.3 # frac
|
1350
|
+
hp_ap.heat_max_capacity_ratio = 1.2 # frac
|
1351
|
+
hp_ap.heat_min_cfm_per_ton = 200.0 / hp_ap.heat_min_capacity_ratio # Convert cfm/ton of nominal rated capacity to cfm/ton of min capacity
|
1352
|
+
hp_ap.heat_max_cfm_per_ton = 400.0 / hp_ap.heat_max_capacity_ratio # Convert cfm/ton of nominal rated capacity to cfm/ton of min capacity
|
1353
|
+
end
|
1354
|
+
|
1355
|
+
def self.set_curves_gshp(heat_pump)
|
1356
|
+
hp_ap = heat_pump.additional_properties
|
1357
|
+
|
1358
|
+
# E+ equation fit coil coefficients generated following approach in Tang's thesis:
|
1359
|
+
# See Appendix B of https://hvac.okstate.edu/sites/default/files/pubs/theses/MS/27-Tang_Thesis_05.pdf
|
1360
|
+
# Coefficients generated by catalog data: https://files.climatemaster.com/Genesis-GS-Series-Product-Catalog.pdf, p180
|
1361
|
+
# Data point taken as rated condition:
|
1362
|
+
# EWT: 80F EAT:80/67F, AFR: 1200cfm, WFR: 4.5gpm
|
1363
|
+
hp_ap.cool_cap_ft_spec = [[-1.57177156131221, 4.60343712716819, -2.15976622898044, 0.0590964827802021, 0.0194696644460315]]
|
1364
|
+
hp_ap.cool_power_ft_spec = [[-4.42471086639888, 0.658017281046304, 4.37331801294626, 0.174096187531254, -0.0526514790164159]]
|
1365
|
+
hp_ap.cool_sh_ft_spec = [[4.54172823345154, 14.7653304889134, -18.3541272090485, -0.74401391092935, 0.545560799548833, 0.0182620032235494]]
|
1366
|
+
hp_ap.cool_rated_shrs_gross = [heat_pump.cooling_shr]
|
1367
|
+
# FUTURE: Reconcile these fan/pump adjustments with ANSI/RESNET/ICC 301-2019 Section 4.4.5
|
1368
|
+
fan_adjust_kw = UnitConversions.convert(400.0, 'Btu/hr', 'ton') * UnitConversions.convert(1.0, 'cfm', 'm^3/s') * 1000.0 * 0.35 * 249.0 / 300.0 # Adjustment per ISO 13256-1 Internal pressure drop across heat pump assumed to be 0.5 in. w.g.
|
1369
|
+
pump_adjust_kw = UnitConversions.convert(3.0, 'Btu/hr', 'ton') * UnitConversions.convert(1.0, 'gal/min', 'm^3/s') * 1000.0 * 6.0 * 2990.0 / 3000.0 # Adjustment per ISO 13256-1 Internal Pressure drop across heat pump coil assumed to be 11ft w.g.
|
1370
|
+
cool_eir = UnitConversions.convert((1.0 - heat_pump.cooling_efficiency_eer * (fan_adjust_kw + pump_adjust_kw)) / (heat_pump.cooling_efficiency_eer * (1.0 + UnitConversions.convert(fan_adjust_kw, 'Wh', 'Btu'))), 'Wh', 'Btu')
|
1371
|
+
hp_ap.cool_rated_eirs = [cool_eir]
|
1372
|
+
|
1373
|
+
# E+ equation fit coil coefficients from Tang's thesis:
|
1374
|
+
# See Appendix B Figure B.3 of https://hvac.okstate.edu/sites/default/files/pubs/theses/MS/27-Tang_Thesis_05.pdf
|
1375
|
+
# Coefficients generated by catalog data
|
1376
|
+
hp_ap.heat_cap_ft_spec = [[-5.12650150, -0.93997630, 7.21443206, 0.121065721, 0.051809805]]
|
1377
|
+
hp_ap.heat_power_ft_spec = [[-7.73235249, 6.43390775, 2.29152262, -0.175598629, 0.005888871]]
|
1378
|
+
heat_eir = (1.0 - heat_pump.heating_efficiency_cop * (fan_adjust_kw + pump_adjust_kw)) / (heat_pump.heating_efficiency_cop * (1.0 - fan_adjust_kw))
|
1379
|
+
hp_ap.heat_rated_eirs = [heat_eir]
|
1380
|
+
end
|
1381
|
+
|
1382
|
+
def self.get_default_compressor_type(hvac_type, seer)
|
1383
|
+
if [HPXML::HVACTypeCentralAirConditioner,
|
1384
|
+
HPXML::HVACTypeHeatPumpAirToAir].include? hvac_type
|
1385
|
+
if seer <= 15
|
1386
|
+
return HPXML::HVACCompressorTypeSingleStage
|
1387
|
+
elsif seer <= 21
|
1388
|
+
return HPXML::HVACCompressorTypeTwoStage
|
1389
|
+
elsif seer > 21
|
1390
|
+
return HPXML::HVACCompressorTypeVariableSpeed
|
1391
|
+
end
|
1392
|
+
end
|
1393
|
+
return
|
1394
|
+
end
|
1395
|
+
|
1396
|
+
def self.get_default_ceiling_fan_power()
|
1397
|
+
# Per ANSI/RESNET/ICC 301
|
1398
|
+
return 42.6 # W
|
1399
|
+
end
|
1400
|
+
|
1401
|
+
def self.get_default_ceiling_fan_quantity(nbeds)
|
1646
1402
|
# Per ANSI/RESNET/ICC 301
|
1647
1403
|
return nbeds + 1
|
1648
1404
|
end
|
@@ -1740,12 +1496,12 @@ class HVAC
|
|
1740
1496
|
pump_mfr_sensor.setKeyName(pump.name.to_s)
|
1741
1497
|
|
1742
1498
|
# Internal variable
|
1743
|
-
pump_rated_mfr_var = OpenStudio::Model::EnergyManagementSystemInternalVariable.new(model,
|
1499
|
+
pump_rated_mfr_var = OpenStudio::Model::EnergyManagementSystemInternalVariable.new(model, EPlus::EMSIntVarPumpMFR)
|
1744
1500
|
pump_rated_mfr_var.setName("#{pump.name} rated mfr")
|
1745
1501
|
pump_rated_mfr_var.setInternalDataIndexKeyName(pump.name.to_s)
|
1746
1502
|
|
1747
1503
|
# Actuator
|
1748
|
-
pump_pressure_rise_act = OpenStudio::Model::EnergyManagementSystemActuator.new(pump,
|
1504
|
+
pump_pressure_rise_act = OpenStudio::Model::EnergyManagementSystemActuator.new(pump, *EPlus::EMSActuatorPumpPressureRise)
|
1749
1505
|
pump_pressure_rise_act.setName("#{pump.name} pressure rise act")
|
1750
1506
|
|
1751
1507
|
# Program
|
@@ -1774,11 +1530,11 @@ class HVAC
|
|
1774
1530
|
hvac_objects = []
|
1775
1531
|
|
1776
1532
|
if fan_or_pump.is_a?(OpenStudio::Model::FanOnOff) || fan_or_pump.is_a?(OpenStudio::Model::FanVariableVolume)
|
1777
|
-
fan_or_pump_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model,
|
1533
|
+
fan_or_pump_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, "Fan #{EPlus::FuelTypeElectricity} Energy")
|
1778
1534
|
elsif fan_or_pump.is_a? OpenStudio::Model::PumpVariableSpeed
|
1779
|
-
fan_or_pump_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model,
|
1535
|
+
fan_or_pump_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, "Pump #{EPlus::FuelTypeElectricity} Energy")
|
1780
1536
|
elsif fan_or_pump.is_a? OpenStudio::Model::ElectricEquipment
|
1781
|
-
fan_or_pump_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model,
|
1537
|
+
fan_or_pump_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, "Electric Equipment #{EPlus::FuelTypeElectricity} Energy")
|
1782
1538
|
else
|
1783
1539
|
fail "Unexpected fan/pump object '#{fan_or_pump.name}'."
|
1784
1540
|
end
|
@@ -1792,7 +1548,7 @@ class HVAC
|
|
1792
1548
|
if clg_object.is_a? OpenStudio::Model::EvaporativeCoolerDirectResearchSpecial
|
1793
1549
|
var = 'Evaporative Cooler Water Volume'
|
1794
1550
|
else
|
1795
|
-
var =
|
1551
|
+
var = "Cooling Coil #{EPlus::FuelTypeElectricity} Energy"
|
1796
1552
|
end
|
1797
1553
|
clg_object_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
1798
1554
|
clg_object_sensor.setName("#{clg_object.name} s")
|
@@ -1803,9 +1559,9 @@ class HVAC
|
|
1803
1559
|
if htg_object.nil?
|
1804
1560
|
htg_object_sensor = nil
|
1805
1561
|
else
|
1806
|
-
var = "Heating Coil #{EPlus
|
1562
|
+
var = "Heating Coil #{EPlus::FuelTypeElectricity} Energy"
|
1807
1563
|
if htg_object.is_a? OpenStudio::Model::CoilHeatingGas
|
1808
|
-
var = "Heating Coil #{
|
1564
|
+
var = "Heating Coil #{htg_object.fuelType} Energy"
|
1809
1565
|
elsif htg_object.is_a? OpenStudio::Model::ZoneHVACBaseboardConvectiveWater
|
1810
1566
|
var = 'Baseboard Total Heating Energy'
|
1811
1567
|
elsif htg_object.is_a? OpenStudio::Model::ZoneHVACFourPipeFanCoil
|
@@ -1821,9 +1577,9 @@ class HVAC
|
|
1821
1577
|
if backup_htg_object.nil?
|
1822
1578
|
backup_htg_object_sensor = nil
|
1823
1579
|
else
|
1824
|
-
var = "Heating Coil #{EPlus
|
1580
|
+
var = "Heating Coil #{EPlus::FuelTypeElectricity} Energy"
|
1825
1581
|
if backup_htg_object.is_a? OpenStudio::Model::CoilHeatingGas
|
1826
|
-
var = "Heating Coil #{
|
1582
|
+
var = "Heating Coil #{backup_htg_object.fuelType} Energy"
|
1827
1583
|
end
|
1828
1584
|
|
1829
1585
|
backup_htg_object_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, var)
|
@@ -1835,32 +1591,36 @@ class HVAC
|
|
1835
1591
|
sensors = { 'clg' => clg_object_sensor,
|
1836
1592
|
'primary_htg' => htg_object_sensor,
|
1837
1593
|
'backup_htg' => backup_htg_object_sensor }
|
1594
|
+
sensors = sensors.select { |m, s| !s.nil? }
|
1838
1595
|
|
1839
1596
|
fan_or_pump_var = fan_or_pump.name.to_s.gsub(' ', '_')
|
1840
1597
|
|
1841
1598
|
# Disaggregate electric fan/pump energy
|
1842
1599
|
fan_or_pump_program = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
|
1843
1600
|
fan_or_pump_program.setName("#{fan_or_pump_var} disaggregate program")
|
1844
|
-
|
1845
|
-
|
1846
|
-
|
1847
|
-
|
1848
|
-
|
1849
|
-
i = 0
|
1850
|
-
sensors.each do |mode, sensor|
|
1851
|
-
next if sensor.nil?
|
1852
|
-
|
1853
|
-
if i == 0
|
1854
|
-
fan_or_pump_program.addLine("If #{sensor.name} > 0")
|
1855
|
-
elsif i == 2
|
1856
|
-
fan_or_pump_program.addLine('Else')
|
1857
|
-
else
|
1858
|
-
fan_or_pump_program.addLine("ElseIf #{sensor.name} > 0")
|
1601
|
+
if htg_object.is_a?(OpenStudio::Model::ZoneHVACBaseboardConvectiveWater) || htg_object.is_a?(OpenStudio::Model::ZoneHVACFourPipeFanCoil)
|
1602
|
+
# Pump may occassionally run when baseboard isn't, so just assign all pump energy here
|
1603
|
+
mode, sensor = sensors.first
|
1604
|
+
if (sensors.size != 1) || (mode != 'primary_htg')
|
1605
|
+
fail 'Unexpected situation.'
|
1859
1606
|
end
|
1860
1607
|
fan_or_pump_program.addLine(" Set #{fan_or_pump_var}_#{mode} = #{fan_or_pump_sensor.name}")
|
1861
|
-
|
1608
|
+
else
|
1609
|
+
sensors.each do |mode, sensor|
|
1610
|
+
fan_or_pump_program.addLine("Set #{fan_or_pump_var}_#{mode} = 0")
|
1611
|
+
end
|
1612
|
+
sensors.each_with_index do |(mode, sensor), i|
|
1613
|
+
if i == 0
|
1614
|
+
fan_or_pump_program.addLine("If #{sensor.name} > 0")
|
1615
|
+
elsif i == 2
|
1616
|
+
fan_or_pump_program.addLine('Else')
|
1617
|
+
else
|
1618
|
+
fan_or_pump_program.addLine("ElseIf #{sensor.name} > 0")
|
1619
|
+
end
|
1620
|
+
fan_or_pump_program.addLine(" Set #{fan_or_pump_var}_#{mode} = #{fan_or_pump_sensor.name}")
|
1621
|
+
end
|
1622
|
+
fan_or_pump_program.addLine('EndIf')
|
1862
1623
|
end
|
1863
|
-
fan_or_pump_program.addLine('EndIf')
|
1864
1624
|
hvac_objects << fan_or_pump_program
|
1865
1625
|
|
1866
1626
|
fan_or_pump_program_calling_manager = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
|
@@ -1882,12 +1642,6 @@ class HVAC
|
|
1882
1642
|
fan_or_pump_ems_output_var.setEMSProgramOrSubroutineName(fan_or_pump_program)
|
1883
1643
|
fan_or_pump_ems_output_var.setUnits('J')
|
1884
1644
|
hvac_objects << fan_or_pump_ems_output_var
|
1885
|
-
|
1886
|
-
# Used by HEScore
|
1887
|
-
# TODO: Move to HEScore project or reporting measure
|
1888
|
-
outputVariable = OpenStudio::Model::OutputVariable.new(fan_or_pump_ems_output_var.name.to_s, model)
|
1889
|
-
outputVariable.setReportingFrequency('monthly')
|
1890
|
-
outputVariable.setKeyValue('*')
|
1891
1645
|
end
|
1892
1646
|
|
1893
1647
|
return hvac_objects
|
@@ -1900,7 +1654,7 @@ class HVAC
|
|
1900
1654
|
dehumidifier_sens_htg = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Zone Dehumidifier Sensible Heating Rate')
|
1901
1655
|
dehumidifier_sens_htg.setName("#{zone_hvac.name} sens htg")
|
1902
1656
|
dehumidifier_sens_htg.setKeyName(zone_hvac.name.to_s)
|
1903
|
-
dehumidifier_power = OpenStudio::Model::EnergyManagementSystemSensor.new(model,
|
1657
|
+
dehumidifier_power = OpenStudio::Model::EnergyManagementSystemSensor.new(model, "Zone Dehumidifier #{EPlus::FuelTypeElectricity} Rate")
|
1904
1658
|
dehumidifier_power.setName("#{zone_hvac.name} power htg")
|
1905
1659
|
dehumidifier_power.setKeyName(zone_hvac.name.to_s)
|
1906
1660
|
|
@@ -1916,7 +1670,7 @@ class HVAC
|
|
1916
1670
|
dehumidifier_load_adj.setSpace(living_space)
|
1917
1671
|
dehumidifier_load_adj.setSchedule(model.alwaysOnDiscreteSchedule)
|
1918
1672
|
|
1919
|
-
dehumidifier_load_adj_act = OpenStudio::Model::EnergyManagementSystemActuator.new(dehumidifier_load_adj,
|
1673
|
+
dehumidifier_load_adj_act = OpenStudio::Model::EnergyManagementSystemActuator.new(dehumidifier_load_adj, *EPlus::EMSActuatorOtherEquipmentPower)
|
1920
1674
|
dehumidifier_load_adj_act.setName("#{zone_hvac.name} sens htg adj act")
|
1921
1675
|
|
1922
1676
|
# EMS program
|
@@ -1954,16 +1708,14 @@ class HVAC
|
|
1954
1708
|
htg_supp_coil.setGasBurnerEfficiency(efficiency)
|
1955
1709
|
htg_supp_coil.setParasiticElectricLoad(0)
|
1956
1710
|
htg_supp_coil.setParasiticGasLoad(0)
|
1957
|
-
htg_supp_coil.setFuelType(EPlus.
|
1711
|
+
htg_supp_coil.setFuelType(EPlus.fuel_type(fuel))
|
1958
1712
|
end
|
1713
|
+
htg_supp_coil.setNominalCapacity(UnitConversions.convert(capacity, 'Btu/hr', 'W'))
|
1959
1714
|
htg_supp_coil.setName(obj_name + ' ' + Constants.ObjectNameBackupHeatingCoil)
|
1960
|
-
if not capacity.nil?
|
1961
|
-
htg_supp_coil.setNominalCapacity(UnitConversions.convert([capacity, Constants.small].max, 'Btu/hr', 'W')) # Used by HVACSizing measure
|
1962
|
-
end
|
1963
1715
|
return htg_supp_coil
|
1964
1716
|
end
|
1965
1717
|
|
1966
|
-
def self.create_supply_fan(model, obj_name, num_speeds,
|
1718
|
+
def self.create_supply_fan(model, obj_name, num_speeds, fan_watts_per_cfm, fan_cfm)
|
1967
1719
|
if num_speeds == 1
|
1968
1720
|
fan = OpenStudio::Model::FanOnOff.new(model, model.alwaysOnDiscreteSchedule)
|
1969
1721
|
else
|
@@ -1971,37 +1723,35 @@ class HVAC
|
|
1971
1723
|
fan_eff_curve = create_curve_cubic(model, [0, 1, 0, 0], obj_name + ' fan eff curve', 0, 1, 0.01, 1)
|
1972
1724
|
fan = OpenStudio::Model::FanOnOff.new(model, model.alwaysOnDiscreteSchedule, fan_power_curve, fan_eff_curve)
|
1973
1725
|
end
|
1974
|
-
|
1975
|
-
fan_eff = 0.75 # Overall Efficiency of the Fan, Motor and Drive
|
1976
|
-
fan.setFanEfficiency(fan_eff)
|
1977
|
-
fan.setPressureRise(calc_fan_pressure_rise(fan_eff, fan_power_installed))
|
1978
|
-
else
|
1979
|
-
fan.setFanEfficiency(1)
|
1980
|
-
fan.setPressureRise(0)
|
1981
|
-
end
|
1726
|
+
set_fan_power(fan, fan_watts_per_cfm)
|
1982
1727
|
fan.setName(obj_name + ' supply fan')
|
1983
1728
|
fan.setEndUseSubcategory('supply fan')
|
1984
1729
|
fan.setMotorEfficiency(1.0)
|
1985
1730
|
fan.setMotorInAirstreamFraction(1.0)
|
1731
|
+
fan.setMaximumFlowRate(UnitConversions.convert(fan_cfm, 'cfm', 'm^3/s'))
|
1986
1732
|
return fan
|
1987
1733
|
end
|
1988
1734
|
|
1989
|
-
def self.create_air_loop_unitary_system(model, obj_name, fan, htg_coil, clg_coil, htg_supp_coil,
|
1735
|
+
def self.create_air_loop_unitary_system(model, obj_name, fan, htg_coil, clg_coil, htg_supp_coil, htg_cfm, clg_cfm, supp_max_temp = nil)
|
1990
1736
|
air_loop_unitary = OpenStudio::Model::AirLoopHVACUnitarySystem.new(model)
|
1991
1737
|
air_loop_unitary.setName(obj_name + ' unitary system')
|
1992
1738
|
air_loop_unitary.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
1993
1739
|
air_loop_unitary.setSupplyFan(fan)
|
1994
1740
|
air_loop_unitary.setFanPlacement('BlowThrough')
|
1995
1741
|
air_loop_unitary.setSupplyAirFanOperatingModeSchedule(model.alwaysOffDiscreteSchedule)
|
1742
|
+
air_loop_unitary.setSupplyAirFlowRateMethodDuringHeatingOperation('SupplyAirFlowRate')
|
1996
1743
|
if htg_coil.nil?
|
1997
1744
|
air_loop_unitary.setSupplyAirFlowRateDuringHeatingOperation(0.0)
|
1998
1745
|
else
|
1999
1746
|
air_loop_unitary.setHeatingCoil(htg_coil)
|
1747
|
+
air_loop_unitary.setSupplyAirFlowRateDuringHeatingOperation(UnitConversions.convert(htg_cfm, 'cfm', 'm^3/s'))
|
2000
1748
|
end
|
1749
|
+
air_loop_unitary.setSupplyAirFlowRateMethodDuringCoolingOperation('SupplyAirFlowRate')
|
2001
1750
|
if clg_coil.nil?
|
2002
1751
|
air_loop_unitary.setSupplyAirFlowRateDuringCoolingOperation(0.0)
|
2003
1752
|
else
|
2004
1753
|
air_loop_unitary.setCoolingCoil(clg_coil)
|
1754
|
+
air_loop_unitary.setSupplyAirFlowRateDuringCoolingOperation(UnitConversions.convert(clg_cfm, 'cfm', 'm^3/s'))
|
2005
1755
|
end
|
2006
1756
|
if htg_supp_coil.nil?
|
2007
1757
|
air_loop_unitary.setMaximumSupplyAirTemperature(UnitConversions.convert(120.0, 'F', 'C'))
|
@@ -2011,23 +1761,16 @@ class HVAC
|
|
2011
1761
|
air_loop_unitary.setMaximumOutdoorDryBulbTemperatureforSupplementalHeaterOperation(UnitConversions.convert(supp_max_temp, 'F', 'C'))
|
2012
1762
|
end
|
2013
1763
|
air_loop_unitary.setSupplyAirFlowRateWhenNoCoolingorHeatingisRequired(0)
|
2014
|
-
if not clg_cfm.nil? # Hidden feature; used only for HERS DSE test
|
2015
|
-
air_loop_unitary.setSupplyAirFlowRateMethodDuringCoolingOperation('SupplyAirFlowRate')
|
2016
|
-
air_loop_unitary.setSupplyAirFlowRateDuringCoolingOperation(UnitConversions.convert(clg_cfm, 'cfm', 'm^3/s'))
|
2017
|
-
end
|
2018
|
-
if not htg_cfm.nil? # Hidden feature; used only for HERS DSE test
|
2019
|
-
air_loop_unitary.setSupplyAirFlowRateMethodDuringHeatingOperation('SupplyAirFlowRate')
|
2020
|
-
air_loop_unitary.setSupplyAirFlowRateDuringHeatingOperation(UnitConversions.convert(htg_cfm, 'cfm', 'm^3/s'))
|
2021
|
-
end
|
2022
1764
|
return air_loop_unitary
|
2023
1765
|
end
|
2024
1766
|
|
2025
|
-
def self.create_air_loop(model, obj_name, system, control_zone, sequential_heat_load_frac, sequential_cool_load_frac)
|
1767
|
+
def self.create_air_loop(model, obj_name, system, control_zone, sequential_heat_load_frac, sequential_cool_load_frac, airflow_cfm)
|
2026
1768
|
air_loop = OpenStudio::Model::AirLoopHVAC.new(model)
|
2027
1769
|
air_loop.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
2028
1770
|
air_loop.setName(obj_name + ' airloop')
|
2029
1771
|
air_loop.zoneSplitter.setName(obj_name + ' zone splitter')
|
2030
1772
|
air_loop.zoneMixer.setName(obj_name + ' zone mixer')
|
1773
|
+
air_loop.setDesignSupplyAirFlowRate(UnitConversions.convert(airflow_cfm, 'cfm', 'm^3/s'))
|
2031
1774
|
system.addToNode(air_loop.supplyInletNode)
|
2032
1775
|
|
2033
1776
|
if system.is_a? OpenStudio::Model::AirLoopHVACUnitarySystem
|
@@ -2038,6 +1781,7 @@ class HVAC
|
|
2038
1781
|
air_terminal.setConstantMinimumAirFlowFraction(0)
|
2039
1782
|
air_terminal.setFixedMinimumAirFlowRate(0)
|
2040
1783
|
end
|
1784
|
+
air_terminal.setMaximumAirFlowRate(UnitConversions.convert(airflow_cfm, 'cfm', 'm^3/s'))
|
2041
1785
|
air_terminal.setName(obj_name + ' terminal')
|
2042
1786
|
air_loop.multiAddBranchForZone(control_zone, air_terminal)
|
2043
1787
|
|
@@ -2047,10 +1791,14 @@ class HVAC
|
|
2047
1791
|
return air_loop
|
2048
1792
|
end
|
2049
1793
|
|
2050
|
-
def self.apply_dehumidifier_ief_to_ef_inputs(w_coeff, ef_coeff, ief, water_removal_rate)
|
1794
|
+
def self.apply_dehumidifier_ief_to_ef_inputs(dh_type, w_coeff, ef_coeff, ief, water_removal_rate)
|
2051
1795
|
# Shift inputs under IEF test conditions to E+ supported EF test conditions
|
2052
1796
|
# test conditions
|
2053
|
-
|
1797
|
+
if dh_type == HPXML::DehumidifierTypePortable
|
1798
|
+
ief_db = UnitConversions.convert(65.0, 'F', 'C') # degree C
|
1799
|
+
elsif dh_type == HPXML::DehumidifierTypeWholeHome
|
1800
|
+
ief_db = UnitConversions.convert(73.0, 'F', 'C') # degree C
|
1801
|
+
end
|
2054
1802
|
rh = 60.0 # for both EF and IEF test conditions, %
|
2055
1803
|
|
2056
1804
|
# Independent variables applied to curve equations
|
@@ -2069,9 +1817,10 @@ class HVAC
|
|
2069
1817
|
return ef_input, water_removal_rate_input
|
2070
1818
|
end
|
2071
1819
|
|
2072
|
-
def self.
|
2073
|
-
|
2074
|
-
|
1820
|
+
def self.get_default_boiler_eae(heating_system)
|
1821
|
+
if heating_system.heating_system_type != HPXML::HVACTypeBoiler
|
1822
|
+
return
|
1823
|
+
end
|
2075
1824
|
if not heating_system.electric_auxiliary_energy.nil?
|
2076
1825
|
return heating_system.electric_auxiliary_energy
|
2077
1826
|
end
|
@@ -2079,82 +1828,41 @@ class HVAC
|
|
2079
1828
|
# From ANSI/RESNET/ICC 301-2019 Standard
|
2080
1829
|
fuel = heating_system.heating_system_fuel
|
2081
1830
|
|
2082
|
-
if heating_system.
|
2083
|
-
|
2084
|
-
|
2085
|
-
distribution_type = distribution_system.distribution_system_type
|
1831
|
+
if heating_system.is_shared_system
|
1832
|
+
distribution_system = heating_system.distribution_system
|
1833
|
+
distribution_type = distribution_system.distribution_system_type
|
2086
1834
|
|
2087
|
-
|
2088
|
-
|
2089
|
-
|
2090
|
-
|
2091
|
-
|
2092
|
-
sp_kw = UnitConversions.convert(heating_system.shared_loop_watts, 'W', 'kW')
|
2093
|
-
n_dweq = heating_system.number_of_units_served.to_f
|
2094
|
-
aux_in = 0.0
|
2095
|
-
end
|
2096
|
-
elsif distribution_type == HPXML::HVACDistributionTypeHydronicAndAir
|
2097
|
-
hydronic_and_air_type = distribution_system.hydronic_and_air_type
|
2098
|
-
if hydronic_and_air_type == HPXML::HydronicAndAirTypeFanCoil
|
2099
|
-
# Shared boiler w/ fan coil
|
2100
|
-
if heating_system.shared_loop_watts.nil? || heating_system.fan_coil_watts.nil?
|
2101
|
-
return 438.0 # kWh/yr, per ANSI/RESNET/ICC 301-2019 Table 4.5.2(5)
|
2102
|
-
else
|
2103
|
-
sp_kw = UnitConversions.convert(heating_system.shared_loop_watts, 'W', 'kW')
|
2104
|
-
n_dweq = heating_system.number_of_units_served.to_f
|
2105
|
-
aux_in = UnitConversions.convert(heating_system.fan_coil_watts, 'W', 'kW')
|
2106
|
-
end
|
2107
|
-
elsif hydronic_and_air_type == HPXML::HydronicAndAirTypeWaterLoopHeatPump
|
2108
|
-
# Shared boiler w/ WLHP
|
2109
|
-
if heating_system.shared_loop_watts.nil?
|
2110
|
-
return 265.0 # kWh/yr, per ANSI/RESNET/ICC 301-2019 Table 4.5.2(5)
|
2111
|
-
else
|
2112
|
-
sp_kw = UnitConversions.convert(heating_system.shared_loop_watts, 'W', 'kW')
|
2113
|
-
n_dweq = heating_system.number_of_units_served.to_f
|
2114
|
-
aux_in = 0.0 # ANSI/RESNET/ICC 301-2019 Section 4.4.7.2
|
2115
|
-
end
|
2116
|
-
else
|
2117
|
-
fail "Unexpected distribution type '#{hydronic_and_air_type}' for shared boiler."
|
2118
|
-
end
|
1835
|
+
if not heating_system.shared_loop_watts.nil?
|
1836
|
+
sp_kw = UnitConversions.convert(heating_system.shared_loop_watts, 'W', 'kW')
|
1837
|
+
n_dweq = heating_system.number_of_units_served.to_f
|
1838
|
+
if distribution_system.air_type == HPXML::AirTypeFanCoil
|
1839
|
+
aux_in = UnitConversions.convert(heating_system.fan_coil_watts, 'W', 'kW')
|
2119
1840
|
else
|
2120
|
-
|
1841
|
+
aux_in = 0.0 # ANSI/RESNET/ICC 301-2019 Section 4.4.7.2
|
2121
1842
|
end
|
2122
|
-
|
2123
1843
|
# ANSI/RESNET/ICC 301-2019 Equation 4.4-5
|
2124
|
-
return ((sp_kw / n_dweq) + aux_in) * 2080.0 # kWh/yr
|
2125
|
-
|
2126
|
-
|
2127
|
-
|
2128
|
-
|
2129
|
-
|
2130
|
-
|
2131
|
-
|
2132
|
-
|
2133
|
-
|
2134
|
-
|
2135
|
-
HPXML::FuelTypeOil1,
|
2136
|
-
HPXML::FuelTypeOil2,
|
2137
|
-
HPXML::FuelTypeOil4,
|
2138
|
-
HPXML::FuelTypeOil5or6,
|
2139
|
-
HPXML::FuelTypeDiesel,
|
2140
|
-
HPXML::FuelTypeKerosene,
|
2141
|
-
HPXML::FuelTypeCoal,
|
2142
|
-
HPXML::FuelTypeCoalAnthracite,
|
2143
|
-
HPXML::FuelTypeCoalBituminous,
|
2144
|
-
HPXML::FuelTypeCoke].include? fuel
|
2145
|
-
return 330.0 # kWh/yr
|
1844
|
+
return (((sp_kw / n_dweq) + aux_in) * 2080.0).round(2) # kWh/yr
|
1845
|
+
elsif distribution_type == HPXML::HVACDistributionTypeHydronic
|
1846
|
+
# kWh/yr, per ANSI/RESNET/ICC 301-2019 Table 4.5.2(5)
|
1847
|
+
if distribution_system.hydronic_type == HPXML::HydronicTypeWaterLoop # Shared boiler w/ WLHP
|
1848
|
+
return 265.0
|
1849
|
+
else # Shared boiler w/ baseboard/radiators/etc
|
1850
|
+
return 220.0
|
1851
|
+
end
|
1852
|
+
elsif distribution_type == HPXML::HVACDistributionTypeAir
|
1853
|
+
if distribution_system.air_type == HPXML::AirTypeFanCoil # Shared boiler w/ fan coil
|
1854
|
+
return 438.0
|
2146
1855
|
end
|
2147
|
-
|
2148
1856
|
end
|
2149
|
-
elsif heating_system.heating_system_type == HPXML::HVACTypeFurnace
|
2150
1857
|
|
2151
|
-
|
1858
|
+
else # In-unit boilers
|
1859
|
+
|
2152
1860
|
if [HPXML::FuelTypeNaturalGas,
|
2153
1861
|
HPXML::FuelTypePropane,
|
2154
1862
|
HPXML::FuelTypeElectricity,
|
2155
1863
|
HPXML::FuelTypeWoodCord,
|
2156
1864
|
HPXML::FuelTypeWoodPellets].include? fuel
|
2157
|
-
return
|
1865
|
+
return 170.0 # kWh/yr
|
2158
1866
|
elsif [HPXML::FuelTypeOil,
|
2159
1867
|
HPXML::FuelTypeOil1,
|
2160
1868
|
HPXML::FuelTypeOil2,
|
@@ -2166,14 +1874,15 @@ class HVAC
|
|
2166
1874
|
HPXML::FuelTypeCoalAnthracite,
|
2167
1875
|
HPXML::FuelTypeCoalBituminous,
|
2168
1876
|
HPXML::FuelTypeCoke].include? fuel
|
2169
|
-
return
|
1877
|
+
return 330.0 # kWh/yr
|
2170
1878
|
end
|
2171
1879
|
|
2172
1880
|
end
|
2173
|
-
return 0.0
|
2174
1881
|
end
|
2175
1882
|
|
2176
|
-
def self.calc_heat_cap_ft_spec_using_capacity_17F(
|
1883
|
+
def self.calc_heat_cap_ft_spec_using_capacity_17F(heat_pump)
|
1884
|
+
num_speeds = heat_pump.additional_properties.num_speeds
|
1885
|
+
|
2177
1886
|
# Indoor temperature slope and intercept used if Q_17 is specified (derived using heat_cap_ft_spec)
|
2178
1887
|
# NOTE: Using Q_17 assumes the same curve for all speeds
|
2179
1888
|
if num_speeds == 1
|
@@ -2190,7 +1899,11 @@ class HVAC
|
|
2190
1899
|
# Derive coefficients from user input for heating capacity at 47F and 17F
|
2191
1900
|
# Biquadratic: capacity multiplier = a + b*IAT + c*IAT^2 + d*OAT + e*OAT^2 + f*IAT*OAT
|
2192
1901
|
x_A = 17.0
|
2193
|
-
|
1902
|
+
if heat_pump.heating_capacity > 0
|
1903
|
+
y_A = heat_pump.heating_capacity_17F / heat_pump.heating_capacity
|
1904
|
+
else
|
1905
|
+
y_A = 0.5 # Arbitrary
|
1906
|
+
end
|
2194
1907
|
x_B = 47.0 # 47F is the rating point
|
2195
1908
|
y_B = 1.0
|
2196
1909
|
|
@@ -2219,22 +1932,18 @@ class HVAC
|
|
2219
1932
|
return ((1.0 - 3.412 * (fan_power_rated * cfm_per_btuh)) / (eir / 3.412 + (fan_power_rated * cfm_per_btuh)))
|
2220
1933
|
end
|
2221
1934
|
|
2222
|
-
def self.calc_eers_from_eir_2speed(eer_2, fan_power_rated
|
2223
|
-
# Returns low and high stage
|
1935
|
+
def self.calc_eers_from_eir_2speed(eer_2, fan_power_rated)
|
1936
|
+
# Returns low and high stage EER A given high stage EER A
|
2224
1937
|
|
2225
1938
|
eir_2_a = calc_eir_from_eer(eer_2, fan_power_rated)
|
2226
1939
|
|
2227
|
-
|
2228
|
-
eir_1_a = 0.8691 * eir_2_a + 0.0127 # Relationship derived using Dylan's data for two stage air conditioners
|
2229
|
-
else
|
2230
|
-
eir_1_a = 0.8887 * eir_2_a + 0.0083 # Relationship derived using Dylan's data for two stage heat pumps
|
2231
|
-
end
|
1940
|
+
eir_1_a = 0.8887 * eir_2_a + 0.0083 # Relationship derived using Dylan's data for two stage heat pumps
|
2232
1941
|
|
2233
1942
|
return [calc_eer_from_eir(eir_1_a, fan_power_rated), eer_2]
|
2234
1943
|
end
|
2235
1944
|
|
2236
1945
|
def self.calc_eers_from_eir_4speed(eer_nom, fan_power_rated, calc_type = 'seer')
|
2237
|
-
# Returns
|
1946
|
+
# Returns EER A at minimum, intermediate, and nominal speed given EER A (and a fourth speed if calc_type != 'seer')
|
2238
1947
|
|
2239
1948
|
eir_nom = calc_eir_from_eer(eer_nom, fan_power_rated)
|
2240
1949
|
|
@@ -2286,9 +1995,9 @@ class HVAC
|
|
2286
1995
|
cop_ratios = [1.385171617, 1.183214059, 1.0, 0.95544453] # Updated based on Nordyne 3 ton heat pump
|
2287
1996
|
|
2288
1997
|
# HSPF calculation is based on performance at three speeds
|
2289
|
-
if calc_type
|
1998
|
+
if calc_type == 'hspf'
|
2290
1999
|
indices = [0, 1, 2]
|
2291
|
-
|
2000
|
+
elsif calc_type == 'model'
|
2292
2001
|
indices = [0, 1, 2, 3]
|
2293
2002
|
end
|
2294
2003
|
|
@@ -2301,33 +2010,26 @@ class HVAC
|
|
2301
2010
|
return cops_net
|
2302
2011
|
end
|
2303
2012
|
|
2304
|
-
def self.
|
2305
|
-
|
2306
|
-
return result
|
2307
|
-
end
|
2308
|
-
|
2309
|
-
def self.calc_eer_cooling_1speed(seer, fan_power_rated, coeff_eir)
|
2310
|
-
# Directly calculate cooling coil net eer at condition A (95/80/67) using Seer
|
2013
|
+
def self.calc_eer_cooling_1speed(seer, c_d, fan_power_rated, coeff_eir)
|
2014
|
+
# Directly calculate cooling coil net EER at condition A (95/80/67) using SEER
|
2311
2015
|
|
2312
|
-
|
2313
|
-
|
2314
|
-
# 1. Calculate eer_b using Seer and c_d
|
2016
|
+
# 1. Calculate EER_b using SEER and c_d
|
2315
2017
|
eer_b = seer / (1.0 - 0.5 * c_d)
|
2316
2018
|
|
2317
|
-
# 2. Calculate
|
2019
|
+
# 2. Calculate EIR_b
|
2318
2020
|
eir_b = calc_eir_from_eer(eer_b, fan_power_rated)
|
2319
2021
|
|
2320
|
-
# 3. Calculate
|
2321
|
-
eir_a = eir_b /
|
2022
|
+
# 3. Calculate EIR_a using performance curves
|
2023
|
+
eir_a = eir_b / MathTools.biquadratic(67.0, 82.0, coeff_eir[0])
|
2322
2024
|
eer_a = calc_eer_from_eir(eir_a, fan_power_rated)
|
2323
2025
|
|
2324
2026
|
return eer_a
|
2325
2027
|
end
|
2326
2028
|
|
2327
|
-
def self.calc_eers_cooling_2speed(
|
2328
|
-
# Iterate to find rated net
|
2029
|
+
def self.calc_eers_cooling_2speed(seer, c_d, capacity_ratios, fanspeed_ratios, fan_power_rated, coeff_eir, coeff_q)
|
2030
|
+
# Iterate to find rated net EERs given SEER using simple bisection method for two stage heat pumps
|
2329
2031
|
|
2330
|
-
# Initial large bracket of
|
2032
|
+
# Initial large bracket of EER (A condition) to span possible SEER range
|
2331
2033
|
eer_a = 5.0
|
2332
2034
|
eer_b = 20.0
|
2333
2035
|
|
@@ -2338,10 +2040,10 @@ class HVAC
|
|
2338
2040
|
err = 1
|
2339
2041
|
eer_c = (eer_a + eer_b) / 2.0
|
2340
2042
|
(1..iter_max).each do |n|
|
2341
|
-
eers = calc_eers_from_eir_2speed(eer_a, fan_power_rated
|
2043
|
+
eers = calc_eers_from_eir_2speed(eer_a, fan_power_rated)
|
2342
2044
|
f_a = calc_seer_2speed(eers, c_d, capacity_ratios, fanspeed_ratios, fan_power_rated, coeff_eir, coeff_q) - seer
|
2343
2045
|
|
2344
|
-
eers = calc_eers_from_eir_2speed(eer_c, fan_power_rated
|
2046
|
+
eers = calc_eers_from_eir_2speed(eer_c, fan_power_rated)
|
2345
2047
|
f_c = calc_seer_2speed(eers, c_d, capacity_ratios, fanspeed_ratios, fan_power_rated, coeff_eir, coeff_q) - seer
|
2346
2048
|
|
2347
2049
|
if f_c == 0
|
@@ -2364,10 +2066,10 @@ class HVAC
|
|
2364
2066
|
fail 'Two-speed cooling eers iteration failed to converge.'
|
2365
2067
|
end
|
2366
2068
|
|
2367
|
-
return calc_eers_from_eir_2speed(eer_c, fan_power_rated
|
2069
|
+
return calc_eers_from_eir_2speed(eer_c, fan_power_rated)
|
2368
2070
|
end
|
2369
2071
|
|
2370
|
-
def self.calc_eers_cooling_4speed(
|
2072
|
+
def self.calc_eers_cooling_4speed(seer, c_d, capacity_ratios, fanspeed_ratios, fan_power_rated, coeff_eir, coeff_q)
|
2371
2073
|
# Iterate to find rated net eers given Seer using simple bisection method for two stage and variable speed air conditioners
|
2372
2074
|
|
2373
2075
|
# Initial large bracket of eer (A condition) to span possible seer range
|
@@ -2412,17 +2114,17 @@ class HVAC
|
|
2412
2114
|
|
2413
2115
|
def self.calc_seer_2speed(eers, c_d, capacity_ratios, fanspeed_ratios, fan_power_rated, coeff_eir, coeff_q)
|
2414
2116
|
eir_A2 = calc_eir_from_eer(eers[1], fan_power_rated)
|
2415
|
-
eir_B2 = eir_A2 *
|
2117
|
+
eir_B2 = eir_A2 * MathTools.biquadratic(67.0, 82.0, coeff_eir[1])
|
2416
2118
|
|
2417
2119
|
eir_A1 = calc_eir_from_eer(eers[0], fan_power_rated)
|
2418
|
-
eir_B1 = eir_A1 *
|
2419
|
-
eir_F1 = eir_A1 *
|
2120
|
+
eir_B1 = eir_A1 * MathTools.biquadratic(67.0, 82.0, coeff_eir[0])
|
2121
|
+
eir_F1 = eir_A1 * MathTools.biquadratic(67.0, 67.0, coeff_eir[0])
|
2420
2122
|
|
2421
2123
|
q_A2 = 1.0
|
2422
|
-
q_B2 = q_A2 *
|
2124
|
+
q_B2 = q_A2 * MathTools.biquadratic(67.0, 82.0, coeff_q[1])
|
2423
2125
|
|
2424
|
-
q_B1 = q_A2 * capacity_ratios[0] *
|
2425
|
-
q_F1 = q_A2 * capacity_ratios[0] *
|
2126
|
+
q_B1 = q_A2 * capacity_ratios[0] * MathTools.biquadratic(67.0, 82.0, coeff_q[0])
|
2127
|
+
q_F1 = q_A2 * capacity_ratios[0] * MathTools.biquadratic(67.0, 67.0, coeff_q[0])
|
2426
2128
|
|
2427
2129
|
cfm_Btu_h = 400.0 / 12000.0
|
2428
2130
|
|
@@ -2479,20 +2181,20 @@ class HVAC
|
|
2479
2181
|
tout_F = 67.0
|
2480
2182
|
|
2481
2183
|
eir_A2 = calc_eir_from_eer(eers[n_max], fan_power_rated)
|
2482
|
-
eir_B2 = eir_A2 *
|
2184
|
+
eir_B2 = eir_A2 * MathTools.biquadratic(wBin, tout_B, coeff_eir[n_max])
|
2483
2185
|
|
2484
2186
|
eir_Av = calc_eir_from_eer(eers[n_int], fan_power_rated)
|
2485
|
-
eir_Ev = eir_Av *
|
2187
|
+
eir_Ev = eir_Av * MathTools.biquadratic(wBin, tout_E, coeff_eir[n_int])
|
2486
2188
|
|
2487
2189
|
eir_A1 = calc_eir_from_eer(eers[n_min], fan_power_rated)
|
2488
|
-
eir_B1 = eir_A1 *
|
2489
|
-
eir_F1 = eir_A1 *
|
2190
|
+
eir_B1 = eir_A1 * MathTools.biquadratic(wBin, tout_B, coeff_eir[n_min])
|
2191
|
+
eir_F1 = eir_A1 * MathTools.biquadratic(wBin, tout_F, coeff_eir[n_min])
|
2490
2192
|
|
2491
2193
|
q_A2 = capacity_ratios[n_max]
|
2492
|
-
q_B2 = q_A2 *
|
2493
|
-
q_Ev = capacity_ratios[n_int] *
|
2494
|
-
q_B1 = capacity_ratios[n_min] *
|
2495
|
-
q_F1 = capacity_ratios[n_min] *
|
2194
|
+
q_B2 = q_A2 * MathTools.biquadratic(wBin, tout_B, coeff_q[n_max])
|
2195
|
+
q_Ev = capacity_ratios[n_int] * MathTools.biquadratic(wBin, tout_E, coeff_q[n_int])
|
2196
|
+
q_B1 = capacity_ratios[n_min] * MathTools.biquadratic(wBin, tout_B, coeff_q[n_min])
|
2197
|
+
q_F1 = capacity_ratios[n_min] * MathTools.biquadratic(wBin, tout_F, coeff_q[n_min])
|
2496
2198
|
|
2497
2199
|
cfm_Btu_h = 400.0 / 12000.0
|
2498
2200
|
|
@@ -2659,7 +2361,7 @@ class HVAC
|
|
2659
2361
|
return calc_cops_from_eir_2speed(cop_c, fan_power_rated)
|
2660
2362
|
end
|
2661
2363
|
|
2662
|
-
def self.calc_cops_heating_4speed(
|
2364
|
+
def self.calc_cops_heating_4speed(hspf, c_d, capacity_ratios, fanspeed_ratios, fan_power_rated, coeff_eir, coeff_q)
|
2663
2365
|
# Iterate to find rated net cops given HSPF using simple bisection method for variable speed heat pumps
|
2664
2366
|
|
2665
2367
|
# Initial large bracket of cop to span possible hspf range
|
@@ -2704,12 +2406,12 @@ class HVAC
|
|
2704
2406
|
|
2705
2407
|
def self.calc_hspf_1speed(cop_47, c_d, fan_power_rated, coeff_eir, coeff_q)
|
2706
2408
|
eir_47 = calc_eir_from_cop(cop_47, fan_power_rated)
|
2707
|
-
eir_35 = eir_47 *
|
2708
|
-
eir_17 = eir_47 *
|
2409
|
+
eir_35 = eir_47 * MathTools.biquadratic(70.0, 35.0, coeff_eir[0])
|
2410
|
+
eir_17 = eir_47 * MathTools.biquadratic(70.0, 17.0, coeff_eir[0])
|
2709
2411
|
|
2710
2412
|
q_47 = 1.0
|
2711
2413
|
q_35 = 0.7519
|
2712
|
-
q_17 = q_47 *
|
2414
|
+
q_17 = q_47 * MathTools.biquadratic(70.0, 17.0, coeff_q[0])
|
2713
2415
|
|
2714
2416
|
cfm_Btu_h = 400.0 / 12000.0
|
2715
2417
|
|
@@ -2767,22 +2469,22 @@ class HVAC
|
|
2767
2469
|
|
2768
2470
|
def self.calc_hspf_2speed(cops, c_d, capacity_ratios, fanspeed_ratios, fan_power_rated, coeff_eir, coeff_q)
|
2769
2471
|
eir_47_H = calc_eir_from_cop(cops[1], fan_power_rated)
|
2770
|
-
eir_35_H = eir_47_H *
|
2771
|
-
eir_17_H = eir_47_H *
|
2472
|
+
eir_35_H = eir_47_H * MathTools.biquadratic(70.0, 35.0, coeff_eir[1])
|
2473
|
+
eir_17_H = eir_47_H * MathTools.biquadratic(70.0, 17.0, coeff_eir[1])
|
2772
2474
|
|
2773
2475
|
eir_47_L = calc_eir_from_cop(cops[0], fan_power_rated)
|
2774
|
-
eir_62_L = eir_47_L *
|
2775
|
-
eir_35_L = eir_47_L *
|
2776
|
-
eir_17_L = eir_47_L *
|
2476
|
+
eir_62_L = eir_47_L * MathTools.biquadratic(70.0, 62.0, coeff_eir[0])
|
2477
|
+
eir_35_L = eir_47_L * MathTools.biquadratic(70.0, 35.0, coeff_eir[0])
|
2478
|
+
eir_17_L = eir_47_L * MathTools.biquadratic(70.0, 17.0, coeff_eir[0])
|
2777
2479
|
|
2778
2480
|
q_H47 = 1.0
|
2779
|
-
q_H35 = q_H47 *
|
2780
|
-
q_H17 = q_H47 *
|
2481
|
+
q_H35 = q_H47 * MathTools.biquadratic(70.0, 35.0, coeff_q[1])
|
2482
|
+
q_H17 = q_H47 * MathTools.biquadratic(70.0, 17.0, coeff_q[1])
|
2781
2483
|
|
2782
2484
|
q_L47 = q_H47 * capacity_ratios[0]
|
2783
|
-
q_L62 = q_L47 *
|
2784
|
-
q_L35 = q_L47 *
|
2785
|
-
q_L17 = q_L47 *
|
2485
|
+
q_L62 = q_L47 * MathTools.biquadratic(70.0, 62.0, coeff_q[0])
|
2486
|
+
q_L35 = q_L47 * MathTools.biquadratic(70.0, 35.0, coeff_q[0])
|
2487
|
+
q_L17 = q_L47 * MathTools.biquadratic(70.0, 17.0, coeff_q[0])
|
2786
2488
|
|
2787
2489
|
cfm_Btu_h = 400.0 / 12000.0
|
2788
2490
|
|
@@ -2887,21 +2589,21 @@ class HVAC
|
|
2887
2589
|
tout_0 = 62.0
|
2888
2590
|
|
2889
2591
|
eir_H1_2 = calc_eir_from_cop(cop_47[n_max], fan_power_rated)
|
2890
|
-
eir_H3_2 = eir_H1_2 *
|
2592
|
+
eir_H3_2 = eir_H1_2 * MathTools.biquadratic(tin, tout_3, coeff_eir[n_max])
|
2891
2593
|
|
2892
2594
|
eir_adjv = calc_eir_from_cop(cop_47[n_int], fan_power_rated)
|
2893
|
-
eir_H2_v = eir_adjv *
|
2595
|
+
eir_H2_v = eir_adjv * MathTools.biquadratic(tin, tout_2, coeff_eir[n_int])
|
2894
2596
|
|
2895
2597
|
eir_H1_1 = calc_eir_from_cop(cop_47[n_min], fan_power_rated)
|
2896
|
-
eir_H0_1 = eir_H1_1 *
|
2598
|
+
eir_H0_1 = eir_H1_1 * MathTools.biquadratic(tin, tout_0, coeff_eir[n_min])
|
2897
2599
|
|
2898
2600
|
q_H1_2 = capacity_ratios[n_max]
|
2899
|
-
q_H3_2 = q_H1_2 *
|
2601
|
+
q_H3_2 = q_H1_2 * MathTools.biquadratic(tin, tout_3, coeff_q[n_max])
|
2900
2602
|
|
2901
|
-
q_H2_v = capacity_ratios[n_int] *
|
2603
|
+
q_H2_v = capacity_ratios[n_int] * MathTools.biquadratic(tin, tout_2, coeff_q[n_int])
|
2902
2604
|
|
2903
2605
|
q_H1_1 = capacity_ratios[n_min]
|
2904
|
-
q_H0_1 = q_H1_1 *
|
2606
|
+
q_H0_1 = q_H1_1 * MathTools.biquadratic(tin, tout_0, coeff_q[n_min])
|
2905
2607
|
|
2906
2608
|
cfm_Btu_h = 400.0 / 12000.0
|
2907
2609
|
|
@@ -3004,29 +2706,46 @@ class HVAC
|
|
3004
2706
|
return hspf
|
3005
2707
|
end
|
3006
2708
|
|
3007
|
-
def self.
|
3008
|
-
|
3009
|
-
|
3010
|
-
|
3011
|
-
|
2709
|
+
def self.set_cool_rated_cfm_per_ton(cooling_system)
|
2710
|
+
clg_ap = cooling_system.additional_properties
|
2711
|
+
|
2712
|
+
if cooling_system.is_a?(HPXML::CoolingSystem) && (cooling_system.cooling_system_type == HPXML::HVACTypeRoomAirConditioner)
|
2713
|
+
clg_ap.cool_rated_cfm_per_ton = [312.0] # medium speed
|
2714
|
+
else
|
2715
|
+
clg_ap.cool_rated_cfm_per_ton = []
|
2716
|
+
clg_ap.cool_fan_speed_ratios.each_with_index do |fanspeed_ratio, i|
|
2717
|
+
clg_ap.cool_rated_cfm_per_ton << fanspeed_ratio * clg_ap.cool_rated_airflow_rate / clg_ap.cool_capacity_ratios[i]
|
2718
|
+
end
|
2719
|
+
end
|
2720
|
+
end
|
2721
|
+
|
2722
|
+
def self.set_heat_rated_cfm_per_ton(heating_system)
|
2723
|
+
htg_ap = heating_system.additional_properties
|
2724
|
+
|
2725
|
+
if heating_system.is_a? HPXML::HeatingSystem
|
2726
|
+
htg_ap.heat_rated_cfm_per_ton = [350.0]
|
2727
|
+
else
|
2728
|
+
htg_ap.heat_rated_cfm_per_ton = []
|
2729
|
+
htg_ap.heat_fan_speed_ratios.each_with_index do |fanspeed_ratio, i|
|
2730
|
+
htg_ap.heat_rated_cfm_per_ton << fanspeed_ratio * htg_ap.heat_rated_airflow_rate / htg_ap.heat_capacity_ratios[i]
|
2731
|
+
end
|
3012
2732
|
end
|
3013
|
-
return array
|
3014
2733
|
end
|
3015
2734
|
|
3016
2735
|
def self.create_curve_biquadratic_constant(model)
|
3017
|
-
|
3018
|
-
|
3019
|
-
|
3020
|
-
|
3021
|
-
|
3022
|
-
|
3023
|
-
|
3024
|
-
|
3025
|
-
|
3026
|
-
|
3027
|
-
|
3028
|
-
|
3029
|
-
return
|
2736
|
+
curve = OpenStudio::Model::CurveBiquadratic.new(model)
|
2737
|
+
curve.setName('ConstantBiquadratic')
|
2738
|
+
curve.setCoefficient1Constant(1)
|
2739
|
+
curve.setCoefficient2x(0)
|
2740
|
+
curve.setCoefficient3xPOW2(0)
|
2741
|
+
curve.setCoefficient4y(0)
|
2742
|
+
curve.setCoefficient5yPOW2(0)
|
2743
|
+
curve.setCoefficient6xTIMESY(0)
|
2744
|
+
curve.setMinimumValueofx(-100)
|
2745
|
+
curve.setMaximumValueofx(100)
|
2746
|
+
curve.setMinimumValueofy(-100)
|
2747
|
+
curve.setMaximumValueofy(100)
|
2748
|
+
return curve
|
3030
2749
|
end
|
3031
2750
|
|
3032
2751
|
def self.create_curve_quadratic_constant(model)
|
@@ -3043,15 +2762,15 @@ class HVAC
|
|
3043
2762
|
end
|
3044
2763
|
|
3045
2764
|
def self.create_curve_cubic_constant(model)
|
3046
|
-
|
3047
|
-
|
3048
|
-
|
3049
|
-
|
3050
|
-
|
3051
|
-
|
3052
|
-
|
3053
|
-
|
3054
|
-
return
|
2765
|
+
curve = OpenStudio::Model::CurveCubic.new(model)
|
2766
|
+
curve.setName('ConstantCubic')
|
2767
|
+
curve.setCoefficient1Constant(1)
|
2768
|
+
curve.setCoefficient2x(0)
|
2769
|
+
curve.setCoefficient3xPOW2(0)
|
2770
|
+
curve.setCoefficient4xPOW3(0)
|
2771
|
+
curve.setMinimumValueofx(-100)
|
2772
|
+
curve.setMaximumValueofx(100)
|
2773
|
+
return curve
|
3055
2774
|
end
|
3056
2775
|
|
3057
2776
|
def self.convert_curve_biquadratic(coeff, ip_to_si = true)
|
@@ -3078,29 +2797,6 @@ class HVAC
|
|
3078
2797
|
end
|
3079
2798
|
end
|
3080
2799
|
|
3081
|
-
def self.convert_curve_gshp(coeff, gshp_to_biquadratic)
|
3082
|
-
m1 = 32 - 273.15 * 1.8
|
3083
|
-
m2 = 283 * 1.8
|
3084
|
-
if gshp_to_biquadratic
|
3085
|
-
biq_coeff = []
|
3086
|
-
biq_coeff << coeff[0] - m1 * ((coeff[1] + coeff[2]) / m2)
|
3087
|
-
biq_coeff << coeff[1] / m2
|
3088
|
-
biq_coeff << 0
|
3089
|
-
biq_coeff << coeff[2] / m2
|
3090
|
-
biq_coeff << 0
|
3091
|
-
biq_coeff << 0
|
3092
|
-
return biq_coeff
|
3093
|
-
else
|
3094
|
-
gsph_coeff = []
|
3095
|
-
gsph_coeff << coeff[0] + m1 * (coeff[1] + coeff[3])
|
3096
|
-
gsph_coeff << m2 * coeff[1]
|
3097
|
-
gsph_coeff << m2 * coeff[3]
|
3098
|
-
gsph_coeff << 0
|
3099
|
-
gsph_coeff << 0
|
3100
|
-
return gsph_coeff
|
3101
|
-
end
|
3102
|
-
end
|
3103
|
-
|
3104
2800
|
def self.create_curve_biquadratic(model, coeff, name, min_x, max_x, min_y, max_y)
|
3105
2801
|
curve = OpenStudio::Model::CurveBiquadratic.new(model)
|
3106
2802
|
curve.setName(name)
|
@@ -3183,40 +2879,67 @@ class HVAC
|
|
3183
2879
|
return curve
|
3184
2880
|
end
|
3185
2881
|
|
3186
|
-
def self.
|
3187
|
-
|
2882
|
+
def self.create_curve_quad_linear(model, coeff, name)
|
2883
|
+
curve = OpenStudio::Model::CurveQuadLinear.new(model)
|
2884
|
+
curve.setName(name)
|
2885
|
+
curve.setCoefficient1Constant(coeff[0])
|
2886
|
+
curve.setCoefficient2w(coeff[1])
|
2887
|
+
curve.setCoefficient3x(coeff[2])
|
2888
|
+
curve.setCoefficient4y(coeff[3])
|
2889
|
+
curve.setCoefficient5z(coeff[4])
|
2890
|
+
return curve
|
2891
|
+
end
|
3188
2892
|
|
3189
|
-
|
2893
|
+
def self.create_curve_quint_linear(model, coeff, name)
|
2894
|
+
curve = OpenStudio::Model::CurveQuintLinear.new(model)
|
2895
|
+
curve.setName(name)
|
2896
|
+
curve.setCoefficient1Constant(coeff[0])
|
2897
|
+
curve.setCoefficient2v(coeff[1])
|
2898
|
+
curve.setCoefficient3w(coeff[2])
|
2899
|
+
curve.setCoefficient4x(coeff[3])
|
2900
|
+
curve.setCoefficient5y(coeff[4])
|
2901
|
+
curve.setCoefficient6z(coeff[5])
|
2902
|
+
return curve
|
2903
|
+
end
|
2904
|
+
|
2905
|
+
def self.create_dx_cooling_coil(model, obj_name, cooling_system)
|
2906
|
+
clg_ap = cooling_system.additional_properties
|
2907
|
+
|
2908
|
+
if cooling_system.is_a? HPXML::CoolingSystem
|
2909
|
+
clg_type = cooling_system.cooling_system_type
|
2910
|
+
elsif cooling_system.is_a? HPXML::HeatPump
|
2911
|
+
clg_type = cooling_system.heat_pump_type
|
2912
|
+
end
|
2913
|
+
|
2914
|
+
if clg_ap.num_speeds > 1
|
3190
2915
|
constant_biquadratic = create_curve_biquadratic_constant(model)
|
3191
2916
|
end
|
3192
2917
|
|
3193
2918
|
clg_coil = nil
|
3194
2919
|
|
3195
|
-
for
|
3196
|
-
|
3197
|
-
|
3198
|
-
|
3199
|
-
|
3200
|
-
|
3201
|
-
|
3202
|
-
|
3203
|
-
|
3204
|
-
|
3205
|
-
if num_speeds == 1
|
2920
|
+
for i in 0..(clg_ap.num_speeds - 1)
|
2921
|
+
cap_ft_spec_si = convert_curve_biquadratic(clg_ap.cool_cap_ft_spec[i])
|
2922
|
+
eir_ft_spec_si = convert_curve_biquadratic(clg_ap.cool_eir_ft_spec[i])
|
2923
|
+
cap_ft_curve = create_curve_biquadratic(model, cap_ft_spec_si, "Cool-CAP-fT#{i + 1}", 13.88, 23.88, 18.33, 51.66)
|
2924
|
+
eir_ft_curve = create_curve_biquadratic(model, eir_ft_spec_si, "Cool-EIR-fT#{i + 1}", 13.88, 23.88, 18.33, 51.66)
|
2925
|
+
plf_fplr_curve = create_curve_quadratic(model, clg_ap.cool_plf_fplr_spec[i], "Cool-PLF-fPLR#{i + 1}", 0, 1, 0.7, 1)
|
2926
|
+
cap_fff_curve = create_curve_quadratic(model, clg_ap.cool_cap_fflow_spec[i], "Cool-CAP-fFF#{i + 1}", 0, 2, 0, 2)
|
2927
|
+
eir_fff_curve = create_curve_quadratic(model, clg_ap.cool_eir_fflow_spec[i], "Cool-EIR-fFF#{i + 1}", 0, 2, 0, 2)
|
2928
|
+
|
2929
|
+
if clg_ap.num_speeds == 1
|
3206
2930
|
clg_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(model, model.alwaysOnDiscreteSchedule, cap_ft_curve, cap_fff_curve, eir_ft_curve, eir_fff_curve, plf_fplr_curve)
|
3207
|
-
clg_coil.setRatedEvaporatorFanPowerPerVolumeFlowRate(fan_power_rated / UnitConversions.convert(1.0, 'cfm', 'm^3/s'))
|
3208
|
-
if not crankcase_temp.nil?
|
3209
|
-
clg_coil.setMaximumOutdoorDryBulbTemperatureForCrankcaseHeaterOperation(UnitConversions.convert(crankcase_temp, 'F', 'C'))
|
3210
|
-
end
|
3211
|
-
clg_coil.setRatedCOP(1.0 / eirs[speed_idx])
|
3212
|
-
clg_coil.setRatedSensibleHeatRatio(shrs_rated_gross[speed_idx])
|
3213
|
-
if not capacity.nil?
|
3214
|
-
clg_coil.setRatedTotalCoolingCapacity(UnitConversions.convert([capacity, Constants.small].max, 'Btu/hr', 'W')) # Used by HVACSizing measure
|
2931
|
+
clg_coil.setRatedEvaporatorFanPowerPerVolumeFlowRate(clg_ap.fan_power_rated / UnitConversions.convert(1.0, 'cfm', 'm^3/s'))
|
2932
|
+
if not clg_ap.crankcase_temp.nil?
|
2933
|
+
clg_coil.setMaximumOutdoorDryBulbTemperatureForCrankcaseHeaterOperation(UnitConversions.convert(clg_ap.crankcase_temp, 'F', 'C'))
|
3215
2934
|
end
|
2935
|
+
clg_coil.setRatedCOP(1.0 / clg_ap.cool_rated_eirs[i])
|
2936
|
+
clg_coil.setRatedSensibleHeatRatio(clg_ap.cool_rated_shrs_gross[i])
|
3216
2937
|
clg_coil.setNominalTimeForCondensateRemovalToBegin(1000.0)
|
3217
2938
|
clg_coil.setRatioOfInitialMoistureEvaporationRateAndSteadyStateLatentCapacity(1.5)
|
3218
2939
|
clg_coil.setMaximumCyclingRate(3.0)
|
3219
2940
|
clg_coil.setLatentCapacityTimeConstant(45.0)
|
2941
|
+
clg_coil.setRatedTotalCoolingCapacity(UnitConversions.convert(cooling_system.cooling_capacity, 'Btu/hr', 'W'))
|
2942
|
+
clg_coil.setRatedAirFlowRate(calc_rated_airflow(cooling_system.cooling_capacity, clg_ap.cool_rated_cfm_per_ton[0], 1.0))
|
3220
2943
|
else
|
3221
2944
|
if clg_coil.nil?
|
3222
2945
|
clg_coil = OpenStudio::Model::CoilCoolingDXMultiSpeed.new(model)
|
@@ -3224,331 +2947,225 @@ class HVAC
|
|
3224
2947
|
clg_coil.setApplyLatentDegradationtoSpeedsGreaterthan1(false)
|
3225
2948
|
clg_coil.setFuelType(EPlus::FuelTypeElectricity)
|
3226
2949
|
clg_coil.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
3227
|
-
if not crankcase_temp.nil?
|
3228
|
-
clg_coil.setMaximumOutdoorDryBulbTemperatureforCrankcaseHeaterOperation(UnitConversions.convert(crankcase_temp, 'F', 'C'))
|
2950
|
+
if not clg_ap.crankcase_temp.nil?
|
2951
|
+
clg_coil.setMaximumOutdoorDryBulbTemperatureforCrankcaseHeaterOperation(UnitConversions.convert(clg_ap.crankcase_temp, 'F', 'C'))
|
3229
2952
|
end
|
3230
2953
|
end
|
3231
2954
|
stage = OpenStudio::Model::CoilCoolingDXMultiSpeedStageData.new(model, cap_ft_curve, cap_fff_curve, eir_ft_curve, eir_fff_curve, plf_fplr_curve, constant_biquadratic)
|
3232
|
-
stage.setGrossRatedCoolingCOP(1.0 /
|
3233
|
-
stage.setGrossRatedSensibleHeatRatio(
|
3234
|
-
if not capacity.nil?
|
3235
|
-
stage.setGrossRatedTotalCoolingCapacity(UnitConversions.convert([capacity, Constants.small].max, 'Btu/hr', 'W')) # Used by HVACSizing measure
|
3236
|
-
end
|
2955
|
+
stage.setGrossRatedCoolingCOP(1.0 / clg_ap.cool_rated_eirs[i])
|
2956
|
+
stage.setGrossRatedSensibleHeatRatio(clg_ap.cool_rated_shrs_gross[i])
|
3237
2957
|
stage.setNominalTimeforCondensateRemovaltoBegin(1000)
|
3238
2958
|
stage.setRatioofInitialMoistureEvaporationRateandSteadyStateLatentCapacity(1.5)
|
3239
2959
|
stage.setRatedWasteHeatFractionofPowerInput(0.2)
|
3240
2960
|
stage.setMaximumCyclingRate(3.0)
|
3241
2961
|
stage.setLatentCapacityTimeConstant(45.0)
|
2962
|
+
stage.setGrossRatedTotalCoolingCapacity(UnitConversions.convert(cooling_system.cooling_capacity, 'Btu/hr', 'W') * clg_ap.cool_capacity_ratios[i])
|
2963
|
+
stage.setRatedAirFlowRate(calc_rated_airflow(cooling_system.cooling_capacity, clg_ap.cool_rated_cfm_per_ton[i], clg_ap.cool_capacity_ratios[i]))
|
3242
2964
|
clg_coil.addStage(stage)
|
3243
2965
|
end
|
3244
2966
|
end
|
3245
2967
|
|
3246
2968
|
clg_coil.setName(obj_name + ' clg coil')
|
3247
2969
|
clg_coil.setCondenserType('AirCooled')
|
3248
|
-
clg_coil.setCrankcaseHeaterCapacity(UnitConversions.convert(crankcase_kw, 'kW', 'W'))
|
2970
|
+
clg_coil.setCrankcaseHeaterCapacity(UnitConversions.convert(clg_ap.crankcase_kw, 'kW', 'W'))
|
3249
2971
|
|
3250
2972
|
return clg_coil
|
3251
2973
|
end
|
3252
2974
|
|
3253
|
-
def self.create_dx_heating_coil(model, obj_name,
|
3254
|
-
|
3255
|
-
num_speeds = speed_indices.size
|
2975
|
+
def self.create_dx_heating_coil(model, obj_name, heating_system)
|
2976
|
+
htg_ap = heating_system.additional_properties
|
3256
2977
|
|
3257
|
-
if
|
2978
|
+
if heating_system.is_a? HPXML::HeatingSystem
|
2979
|
+
htg_type = heating_system.heating_system_type
|
2980
|
+
elsif heating_system.is_a? HPXML::HeatPump
|
2981
|
+
htg_type = heating_system.heat_pump_type
|
2982
|
+
end
|
2983
|
+
|
2984
|
+
if htg_ap.num_speeds > 1
|
3258
2985
|
constant_biquadratic = create_curve_biquadratic_constant(model)
|
3259
2986
|
end
|
3260
2987
|
|
3261
2988
|
htg_coil = nil
|
3262
2989
|
|
3263
|
-
for
|
3264
|
-
|
3265
|
-
|
3266
|
-
|
3267
|
-
|
3268
|
-
|
3269
|
-
|
3270
|
-
|
3271
|
-
|
3272
|
-
|
3273
|
-
if num_speeds == 1
|
2990
|
+
for i in 0..(htg_ap.num_speeds - 1)
|
2991
|
+
cap_ft_spec_si = convert_curve_biquadratic(htg_ap.heat_cap_ft_spec[i])
|
2992
|
+
eir_ft_spec_si = convert_curve_biquadratic(htg_ap.heat_eir_ft_spec[i])
|
2993
|
+
cap_ft_curve = create_curve_biquadratic(model, cap_ft_spec_si, "Heat-CAP-fT#{i + 1}", -100, 100, -100, 100)
|
2994
|
+
eir_ft_curve = create_curve_biquadratic(model, eir_ft_spec_si, "Heat-EIR-fT#{i + 1}", -100, 100, -100, 100)
|
2995
|
+
plf_fplr_curve = create_curve_quadratic(model, htg_ap.heat_plf_fplr_spec[i], "Heat-PLF-fPLR#{i + 1}", 0, 1, 0.7, 1)
|
2996
|
+
cap_fff_curve = create_curve_quadratic(model, htg_ap.heat_cap_fflow_spec[i], "Heat-CAP-fFF#{i + 1}", 0, 2, 0, 2)
|
2997
|
+
eir_fff_curve = create_curve_quadratic(model, htg_ap.heat_eir_fflow_spec[i], "Heat-EIR-fFF#{i + 1}", 0, 2, 0, 2)
|
2998
|
+
|
2999
|
+
if htg_ap.num_speeds == 1
|
3274
3000
|
htg_coil = OpenStudio::Model::CoilHeatingDXSingleSpeed.new(model, model.alwaysOnDiscreteSchedule, cap_ft_curve, cap_fff_curve, eir_ft_curve, eir_fff_curve, plf_fplr_curve)
|
3275
|
-
htg_coil.setRatedSupplyFanPowerPerVolumeFlowRate(fan_power_rated / UnitConversions.convert(1.0, 'cfm', 'm^3/s'))
|
3276
|
-
htg_coil.setRatedCOP(1.0 /
|
3277
|
-
if not
|
3278
|
-
htg_coil.
|
3279
|
-
end
|
3280
|
-
if not crankcase_temp.nil?
|
3281
|
-
htg_coil.setMaximumOutdoorDryBulbTemperatureforCrankcaseHeaterOperation(UnitConversions.convert(crankcase_temp, 'F', 'C'))
|
3001
|
+
htg_coil.setRatedSupplyFanPowerPerVolumeFlowRate(htg_ap.fan_power_rated / UnitConversions.convert(1.0, 'cfm', 'm^3/s'))
|
3002
|
+
htg_coil.setRatedCOP(1.0 / htg_ap.heat_rated_eirs[i])
|
3003
|
+
if not htg_ap.crankcase_temp.nil?
|
3004
|
+
htg_coil.setMaximumOutdoorDryBulbTemperatureforCrankcaseHeaterOperation(UnitConversions.convert(htg_ap.crankcase_temp, 'F', 'C'))
|
3282
3005
|
end
|
3006
|
+
htg_coil.setRatedTotalHeatingCapacity(UnitConversions.convert(heating_system.heating_capacity, 'Btu/hr', 'W'))
|
3007
|
+
htg_coil.setRatedAirFlowRate(calc_rated_airflow(heating_system.heating_capacity, htg_ap.heat_rated_cfm_per_ton[0], 1.0))
|
3283
3008
|
else
|
3284
3009
|
if htg_coil.nil?
|
3285
3010
|
htg_coil = OpenStudio::Model::CoilHeatingDXMultiSpeed.new(model)
|
3286
3011
|
htg_coil.setFuelType(EPlus::FuelTypeElectricity)
|
3287
3012
|
htg_coil.setApplyPartLoadFractiontoSpeedsGreaterthan1(false)
|
3288
3013
|
htg_coil.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
|
3289
|
-
if not crankcase_temp.nil?
|
3290
|
-
htg_coil.setMaximumOutdoorDryBulbTemperatureforCrankcaseHeaterOperation(UnitConversions.convert(crankcase_temp, 'F', 'C'))
|
3014
|
+
if not htg_ap.crankcase_temp.nil?
|
3015
|
+
htg_coil.setMaximumOutdoorDryBulbTemperatureforCrankcaseHeaterOperation(UnitConversions.convert(htg_ap.crankcase_temp, 'F', 'C'))
|
3291
3016
|
end
|
3292
3017
|
end
|
3293
3018
|
stage = OpenStudio::Model::CoilHeatingDXMultiSpeedStageData.new(model, cap_ft_curve, cap_fff_curve, eir_ft_curve, eir_fff_curve, plf_fplr_curve, constant_biquadratic)
|
3294
|
-
stage.setGrossRatedHeatingCOP(1.0 /
|
3295
|
-
if not capacity.nil?
|
3296
|
-
stage.setGrossRatedHeatingCapacity(UnitConversions.convert([capacity, Constants.small].max, 'Btu/hr', 'W')) # Used by HVACSizing measure
|
3297
|
-
end
|
3019
|
+
stage.setGrossRatedHeatingCOP(1.0 / htg_ap.heat_rated_eirs[i])
|
3298
3020
|
stage.setRatedWasteHeatFractionofPowerInput(0.2)
|
3021
|
+
stage.setGrossRatedHeatingCapacity(UnitConversions.convert(heating_system.heating_capacity, 'Btu/hr', 'W') * htg_ap.heat_capacity_ratios[i])
|
3022
|
+
stage.setRatedAirFlowRate(calc_rated_airflow(heating_system.heating_capacity, htg_ap.heat_rated_cfm_per_ton[i], htg_ap.heat_capacity_ratios[i]))
|
3299
3023
|
htg_coil.addStage(stage)
|
3300
3024
|
end
|
3301
3025
|
end
|
3302
3026
|
|
3303
3027
|
htg_coil.setName(obj_name + ' htg coil')
|
3304
|
-
htg_coil.setMinimumOutdoorDryBulbTemperatureforCompressorOperation(UnitConversions.convert(hp_min_temp, 'F', 'C'))
|
3028
|
+
htg_coil.setMinimumOutdoorDryBulbTemperatureforCompressorOperation(UnitConversions.convert(htg_ap.hp_min_temp, 'F', 'C'))
|
3305
3029
|
htg_coil.setMaximumOutdoorDryBulbTemperatureforDefrostOperation(UnitConversions.convert(40.0, 'F', 'C'))
|
3306
|
-
|
3307
|
-
|
3308
|
-
|
3309
|
-
|
3310
|
-
|
3311
|
-
|
3312
|
-
htg_coil.setDefrostTimePeriodFraction(0)
|
3030
|
+
defrost_eir_curve = create_curve_biquadratic(model, [0.1528, 0, 0, 0, 0, 0], 'Defrosteir', -100, 100, -100, 100) # Heating defrost curve for reverse cycle
|
3031
|
+
htg_coil.setDefrostEnergyInputRatioFunctionofTemperatureCurve(defrost_eir_curve)
|
3032
|
+
htg_coil.setDefrostStrategy('ReverseCycle')
|
3033
|
+
htg_coil.setDefrostControl('Timed')
|
3034
|
+
if heating_system.fraction_heat_load_served == 0
|
3035
|
+
htg_coil.setResistiveDefrostHeaterCapacity(0)
|
3313
3036
|
end
|
3314
|
-
htg_coil.setCrankcaseHeaterCapacity(UnitConversions.convert(crankcase_kw, 'kW', 'W'))
|
3037
|
+
htg_coil.setCrankcaseHeaterCapacity(UnitConversions.convert(htg_ap.crankcase_kw, 'kW', 'W'))
|
3315
3038
|
|
3316
3039
|
return htg_coil
|
3317
3040
|
end
|
3318
3041
|
|
3319
|
-
def self.
|
3320
|
-
|
3321
|
-
|
3322
|
-
|
3323
|
-
|
3042
|
+
def self.set_cool_rated_eirs(cooling_system)
|
3043
|
+
clg_ap = cooling_system.additional_properties
|
3044
|
+
|
3045
|
+
clg_ap.cool_rated_eirs = []
|
3046
|
+
(0...clg_ap.num_speeds).to_a.each do |speed|
|
3047
|
+
clg_ap.cool_rated_eirs << calc_eir_from_eer(clg_ap.cool_eers[speed], clg_ap.fan_power_rated)
|
3324
3048
|
end
|
3325
|
-
return cool_eirs
|
3326
3049
|
end
|
3327
3050
|
|
3328
|
-
def self.
|
3329
|
-
|
3330
|
-
|
3331
|
-
|
3332
|
-
|
3051
|
+
def self.set_heat_rated_eirs(heating_system)
|
3052
|
+
htg_ap = heating_system.additional_properties
|
3053
|
+
|
3054
|
+
htg_ap.heat_rated_eirs = []
|
3055
|
+
(0...htg_ap.num_speeds).to_a.each do |speed|
|
3056
|
+
htg_ap.heat_rated_eirs << calc_eir_from_cop(htg_ap.heat_cops[speed], htg_ap.fan_power_rated)
|
3333
3057
|
end
|
3334
|
-
return heat_eirs
|
3335
3058
|
end
|
3336
3059
|
|
3337
|
-
def self.
|
3338
|
-
|
3339
|
-
|
3340
|
-
|
3341
|
-
|
3342
|
-
|
3343
|
-
|
3344
|
-
|
3345
|
-
|
3346
|
-
|
3347
|
-
|
3348
|
-
|
3349
|
-
|
3350
|
-
|
3351
|
-
|
3352
|
-
|
3353
|
-
|
3354
|
-
|
3355
|
-
|
3060
|
+
def self.set_cool_rated_shrs_gross(cooling_system)
|
3061
|
+
clg_ap = cooling_system.additional_properties
|
3062
|
+
|
3063
|
+
# Convert SHRs from net to gross.
|
3064
|
+
if cooling_system.is_a?(HPXML::CoolingSystem) && (cooling_system.cooling_system_type == HPXML::HVACTypeRoomAirConditioner)
|
3065
|
+
clg_ap.cool_rated_shrs_gross = [cooling_system.cooling_shr] # We don't model the fan separately, so set gross == net
|
3066
|
+
else
|
3067
|
+
clg_ap.cool_rated_shrs_gross = []
|
3068
|
+
(0...clg_ap.num_speeds).to_a.each do |speed|
|
3069
|
+
qtot_net_nominal = 12000.0
|
3070
|
+
qsens_net_nominal = qtot_net_nominal * clg_ap.cool_rated_shrs_net[speed]
|
3071
|
+
qtot_gross_nominal = qtot_net_nominal + UnitConversions.convert(clg_ap.cool_rated_cfm_per_ton[speed] * clg_ap.fan_power_rated, 'Wh', 'Btu')
|
3072
|
+
qsens_gross_nominal = qsens_net_nominal + UnitConversions.convert(clg_ap.cool_rated_cfm_per_ton[speed] * clg_ap.fan_power_rated, 'Wh', 'Btu')
|
3073
|
+
clg_ap.cool_rated_shrs_gross << (qsens_gross_nominal / qtot_gross_nominal)
|
3074
|
+
|
3075
|
+
# Make sure SHR's are in valid range based on E+ model limits.
|
3076
|
+
# The following correlation was developed by Jon Winkler to test for maximum allowed SHR based on the 300 - 450 cfm/ton limits in E+
|
3077
|
+
max_shr = 0.3821066 + 0.001050652 * clg_ap.cool_rated_cfm_per_ton[speed] - 0.01
|
3078
|
+
clg_ap.cool_rated_shrs_gross[speed] = [clg_ap.cool_rated_shrs_gross[speed], max_shr].min
|
3079
|
+
min_shr = 0.60 # Approximate minimum SHR such that an ADP exists
|
3080
|
+
clg_ap.cool_rated_shrs_gross[speed] = [clg_ap.cool_rated_shrs_gross[speed], min_shr].max
|
3081
|
+
end
|
3082
|
+
end
|
3356
3083
|
end
|
3357
3084
|
|
3358
3085
|
def self.calc_plr_coefficients(c_d)
|
3359
3086
|
return [(1.0 - c_d), c_d, 0.0] # Linear part load model
|
3360
3087
|
end
|
3361
3088
|
|
3362
|
-
def self.
|
3089
|
+
def self.set_cool_c_d(cooling_system, num_speeds)
|
3090
|
+
clg_ap = cooling_system.additional_properties
|
3091
|
+
|
3363
3092
|
# Degradation coefficient for cooling
|
3364
|
-
if
|
3365
|
-
|
3366
|
-
|
3093
|
+
if cooling_system.is_a?(HPXML::CoolingSystem) && (cooling_system.cooling_system_type == HPXML::HVACTypeRoomAirConditioner)
|
3094
|
+
clg_ap.cool_c_d = 0.22
|
3095
|
+
elsif num_speeds == 1
|
3096
|
+
if cooling_system.cooling_efficiency_seer < 13.0
|
3097
|
+
clg_ap.cool_c_d = 0.20
|
3367
3098
|
else
|
3368
|
-
|
3099
|
+
clg_ap.cool_c_d = 0.07
|
3369
3100
|
end
|
3370
3101
|
elsif num_speeds == 2
|
3371
|
-
|
3372
|
-
elsif num_speeds
|
3373
|
-
|
3374
|
-
elsif num_speeds == 10
|
3375
|
-
return 0.25
|
3102
|
+
clg_ap.cool_c_d = 0.11
|
3103
|
+
elsif num_speeds >= 4
|
3104
|
+
clg_ap.cool_c_d = 0.25
|
3376
3105
|
end
|
3106
|
+
|
3107
|
+
# PLF curve
|
3108
|
+
clg_ap.cool_plf_fplr_spec = [calc_plr_coefficients(clg_ap.cool_c_d)] * num_speeds
|
3377
3109
|
end
|
3378
3110
|
|
3379
|
-
def self.
|
3111
|
+
def self.set_heat_c_d(heating_system, num_speeds)
|
3112
|
+
htg_ap = heating_system.additional_properties
|
3113
|
+
|
3380
3114
|
# Degradation coefficient for heating
|
3381
3115
|
if num_speeds == 1
|
3382
|
-
if
|
3383
|
-
|
3116
|
+
if heating_system.heating_efficiency_hspf < 7.0
|
3117
|
+
htg_ap.heat_c_d = 0.20
|
3384
3118
|
else
|
3385
|
-
|
3119
|
+
htg_ap.heat_c_d = 0.11
|
3386
3120
|
end
|
3387
3121
|
elsif num_speeds == 2
|
3388
|
-
|
3122
|
+
htg_ap.heat_c_d = 0.11
|
3389
3123
|
elsif num_speeds == 4
|
3390
|
-
|
3391
|
-
elsif num_speeds == 10
|
3392
|
-
|
3124
|
+
htg_ap.heat_c_d = 0.24
|
3125
|
+
elsif num_speeds == 10 # mini-split heat pump
|
3126
|
+
htg_ap.heat_c_d = 0.40
|
3393
3127
|
end
|
3128
|
+
|
3129
|
+
htg_ap.heat_plf_fplr_spec = [calc_plr_coefficients(htg_ap.heat_c_d)] * num_speeds
|
3394
3130
|
end
|
3395
3131
|
|
3396
|
-
def self.
|
3397
|
-
|
3398
|
-
|
3132
|
+
def self.set_fan_power_rated(hvac_system)
|
3133
|
+
hvac_ap = hvac_system.additional_properties
|
3134
|
+
|
3135
|
+
if (hvac_system.is_a?(HPXML::CoolingSystem) && (hvac_system.cooling_system_type == HPXML::HVACTypeMiniSplitAirConditioner)) ||
|
3136
|
+
(hvac_system.is_a?(HPXML::HeatPump) && (hvac_system.heat_pump_type == HPXML::HVACTypeHeatPumpMiniSplit))
|
3137
|
+
if not hvac_system.distribution_system.nil?
|
3138
|
+
# Ducted, installed fan power may differ from rated fan power
|
3139
|
+
hvac_ap.fan_power_rated = 0.18 # W/cfm, ducted
|
3140
|
+
else
|
3141
|
+
# Ductless, installed and rated value should be equal
|
3142
|
+
hvac_ap.fan_power_rated = 0.07 # W/cfm
|
3143
|
+
hvac_system.fan_watts_per_cfm = hvac_ap.fan_power_rated # W/cfm
|
3144
|
+
end
|
3145
|
+
elsif hvac_system.cooling_efficiency_seer <= 15
|
3146
|
+
hvac_ap.fan_power_rated = 0.365 # W/cfm
|
3399
3147
|
else
|
3400
|
-
|
3148
|
+
hvac_ap.fan_power_rated = 0.14 # W/cfm
|
3401
3149
|
end
|
3402
3150
|
end
|
3403
3151
|
|
3404
|
-
def self.
|
3405
|
-
if
|
3406
|
-
|
3152
|
+
def self.set_fan_power(fan, fan_watts_per_cfm)
|
3153
|
+
if fan_watts_per_cfm > 0
|
3154
|
+
fan_eff = 0.75 # Overall Efficiency of the Fan, Motor and Drive
|
3155
|
+
fan.setFanEfficiency(fan_eff)
|
3156
|
+
fan.setPressureRise(fan_eff * fan_watts_per_cfm / UnitConversions.convert(1.0, 'cfm', 'm^3/s')) # Pa
|
3407
3157
|
else
|
3408
|
-
|
3158
|
+
fan.setFanEfficiency(1)
|
3159
|
+
fan.setPressureRise(0)
|
3409
3160
|
end
|
3410
3161
|
end
|
3411
3162
|
|
3412
|
-
def self.calc_fan_pressure_rise(fan_eff, fan_power)
|
3413
|
-
# Calculates needed fan pressure rise to achieve a given fan power with an assumed efficiency.
|
3414
|
-
# Previously we calculated the fan efficiency from an assumed pressure rise, which could lead to
|
3415
|
-
# errors (fan efficiencies > 1).
|
3416
|
-
return fan_eff * fan_power / UnitConversions.convert(1.0, 'cfm', 'm^3/s') # Pa
|
3417
|
-
end
|
3418
|
-
|
3419
3163
|
def self.calc_pump_rated_flow_rate(pump_eff, pump_w, pump_head_pa)
|
3420
3164
|
# Calculate needed pump rated flow rate to achieve a given pump power with an assumed
|
3421
3165
|
# efficiency and pump head.
|
3422
3166
|
return pump_eff * pump_w / pump_head_pa # m3/s
|
3423
3167
|
end
|
3424
3168
|
|
3425
|
-
def self.existing_equipment(model, thermal_zone, runner)
|
3426
|
-
# Returns a list of equipment objects
|
3427
|
-
|
3428
|
-
equipment = []
|
3429
|
-
hvac_types = []
|
3430
|
-
|
3431
|
-
unitary_system_air_loops = get_unitary_system_air_loops(model, thermal_zone)
|
3432
|
-
unitary_system_air_loops.each do |unitary_system_air_loop|
|
3433
|
-
system, clg_coil, htg_coil, air_loop = unitary_system_air_loop
|
3434
|
-
equipment << system
|
3435
|
-
|
3436
|
-
hvac_type_cool = system.additionalProperties.getFeatureAsString(Constants.SizingInfoHVACCoolType)
|
3437
|
-
hvac_types << hvac_type_cool.get if hvac_type_cool.is_initialized
|
3438
|
-
|
3439
|
-
hvac_type_heat = system.additionalProperties.getFeatureAsString(Constants.SizingInfoHVACHeatType)
|
3440
|
-
hvac_types << hvac_type_heat.get if hvac_type_heat.is_initialized
|
3441
|
-
end
|
3442
|
-
|
3443
|
-
ptacs = get_ptacs(model, thermal_zone)
|
3444
|
-
ptacs.each do |ptac|
|
3445
|
-
equipment << ptac
|
3446
|
-
hvac_types << ptac.additionalProperties.getFeatureAsString(Constants.SizingInfoHVACCoolType).get
|
3447
|
-
end
|
3448
|
-
|
3449
|
-
evap_coolers = get_evap_coolers(model, thermal_zone)
|
3450
|
-
evap_coolers.each do |evap_cooler|
|
3451
|
-
equipment << evap_cooler
|
3452
|
-
hvac_types << evap_cooler.additionalProperties.getFeatureAsString(Constants.SizingInfoHVACCoolType).get
|
3453
|
-
end
|
3454
|
-
|
3455
|
-
baseboards = get_baseboard_waters(model, thermal_zone)
|
3456
|
-
baseboards.each do |baseboard|
|
3457
|
-
equipment << baseboard
|
3458
|
-
hvac_types << baseboard.additionalProperties.getFeatureAsString(Constants.SizingInfoHVACHeatType).get
|
3459
|
-
end
|
3460
|
-
|
3461
|
-
fancoils = get_fan_coils(model, thermal_zone)
|
3462
|
-
fancoils.each do |fancoil|
|
3463
|
-
equipment << fancoil
|
3464
|
-
hvac_types << fancoil.additionalProperties.getFeatureAsString(Constants.SizingInfoHVACHeatType).get
|
3465
|
-
end
|
3466
|
-
|
3467
|
-
baseboards = get_baseboard_electrics(model, thermal_zone)
|
3468
|
-
baseboards.each do |baseboard|
|
3469
|
-
equipment << baseboard
|
3470
|
-
hvac_types << baseboard.additionalProperties.getFeatureAsString(Constants.SizingInfoHVACHeatType).get
|
3471
|
-
end
|
3472
|
-
|
3473
|
-
unitary_system_hvac_map = get_unitary_system_hvac_map(model, thermal_zone)
|
3474
|
-
unitary_system_hvac_map.each do |unitary_system_zone_hvac|
|
3475
|
-
system, clg_coil, htg_coil = unitary_system_zone_hvac
|
3476
|
-
next if htg_coil.nil?
|
3477
|
-
|
3478
|
-
equipment << system
|
3479
|
-
hvac_types << system.additionalProperties.getFeatureAsString(Constants.SizingInfoHVACHeatType).get
|
3480
|
-
end
|
3481
|
-
|
3482
|
-
ideal_air = get_ideal_air(model, thermal_zone)
|
3483
|
-
if not ideal_air.nil?
|
3484
|
-
equipment << ideal_air
|
3485
|
-
hvac_types << ideal_air.additionalProperties.getFeatureAsString(Constants.SizingInfoHVACCoolType).get
|
3486
|
-
hvac_types << ideal_air.additionalProperties.getFeatureAsString(Constants.SizingInfoHVACHeatType).get
|
3487
|
-
end
|
3488
|
-
return equipment
|
3489
|
-
end
|
3490
|
-
|
3491
|
-
def self.get_coils_from_hvac_equip(model, hvac_equip)
|
3492
|
-
# Returns the clg coil, htg coil, and supp htg coil as applicable
|
3493
|
-
clg_coil = nil
|
3494
|
-
htg_coil = nil
|
3495
|
-
supp_htg_coil = nil
|
3496
|
-
if hvac_equip.is_a? OpenStudio::Model::AirLoopHVACUnitarySystem
|
3497
|
-
htg_coil = get_coil_from_hvac_component(hvac_equip.heatingCoil)
|
3498
|
-
clg_coil = get_coil_from_hvac_component(hvac_equip.coolingCoil)
|
3499
|
-
supp_htg_coil = get_coil_from_hvac_component(hvac_equip.supplementalHeatingCoil)
|
3500
|
-
elsif hvac_equip.is_a? OpenStudio::Model::ZoneHVACBaseboardConvectiveWater
|
3501
|
-
htg_coil = get_coil_from_hvac_component(hvac_equip.heatingCoil)
|
3502
|
-
elsif hvac_equip.is_a? OpenStudio::Model::ZoneHVACFourPipeFanCoil
|
3503
|
-
htg_coil = get_coil_from_hvac_component(hvac_equip.heatingCoil)
|
3504
|
-
elsif hvac_equip.is_a? OpenStudio::Model::ZoneHVACPackagedTerminalAirConditioner
|
3505
|
-
htg_coil = get_coil_from_hvac_component(hvac_equip.heatingCoil)
|
3506
|
-
if (not htg_coil.nil?) && (htg_coil.availabilitySchedule == model.alwaysOffDiscreteSchedule)
|
3507
|
-
# Don't return coil if it is unused
|
3508
|
-
htg_coil = nil
|
3509
|
-
end
|
3510
|
-
clg_coil = get_coil_from_hvac_component(hvac_equip.coolingCoil)
|
3511
|
-
end
|
3512
|
-
return clg_coil, htg_coil, supp_htg_coil
|
3513
|
-
end
|
3514
|
-
|
3515
|
-
def self.get_coil_from_hvac_component(hvac_component)
|
3516
|
-
# Check for optional objects
|
3517
|
-
if hvac_component.is_a? OpenStudio::Model::OptionalHVACComponent
|
3518
|
-
return if not hvac_component.is_initialized
|
3519
|
-
|
3520
|
-
hvac_component = hvac_component.get
|
3521
|
-
end
|
3522
|
-
|
3523
|
-
# Cooling coils
|
3524
|
-
if hvac_component.to_CoilCoolingDXSingleSpeed.is_initialized
|
3525
|
-
return hvac_component.to_CoilCoolingDXSingleSpeed.get
|
3526
|
-
elsif hvac_component.to_CoilCoolingDXMultiSpeed.is_initialized
|
3527
|
-
return hvac_component.to_CoilCoolingDXMultiSpeed.get
|
3528
|
-
elsif hvac_component.to_CoilCoolingWaterToAirHeatPumpEquationFit.is_initialized
|
3529
|
-
return hvac_component.to_CoilCoolingWaterToAirHeatPumpEquationFit.get
|
3530
|
-
end
|
3531
|
-
|
3532
|
-
# Heating coils
|
3533
|
-
if hvac_component.to_CoilHeatingDXSingleSpeed.is_initialized
|
3534
|
-
return hvac_component.to_CoilHeatingDXSingleSpeed.get
|
3535
|
-
elsif hvac_component.to_CoilHeatingDXMultiSpeed.is_initialized
|
3536
|
-
return hvac_component.to_CoilHeatingDXMultiSpeed.get
|
3537
|
-
elsif hvac_component.to_CoilHeatingGas.is_initialized
|
3538
|
-
return hvac_component.to_CoilHeatingGas.get
|
3539
|
-
elsif hvac_component.to_CoilHeatingElectric.is_initialized
|
3540
|
-
return hvac_component.to_CoilHeatingElectric.get
|
3541
|
-
elsif hvac_component.to_CoilHeatingWaterBaseboard.is_initialized
|
3542
|
-
return hvac_component.to_CoilHeatingWaterBaseboard.get
|
3543
|
-
elsif hvac_component.to_CoilHeatingWater.is_initialized
|
3544
|
-
return hvac_component.to_CoilHeatingWater.get
|
3545
|
-
elsif hvac_component.to_CoilHeatingWaterToAirHeatPumpEquationFit.is_initialized
|
3546
|
-
return hvac_component.to_CoilHeatingWaterToAirHeatPumpEquationFit.get
|
3547
|
-
end
|
3548
|
-
|
3549
|
-
return hvac_component
|
3550
|
-
end
|
3551
|
-
|
3552
3169
|
def self.get_unitary_system_from_air_loop_hvac(air_loop)
|
3553
3170
|
# Returns the unitary system or nil
|
3554
3171
|
air_loop.supplyComponents.each do |comp|
|
@@ -3559,201 +3176,52 @@ class HVAC
|
|
3559
3176
|
return
|
3560
3177
|
end
|
3561
3178
|
|
3562
|
-
def self.
|
3563
|
-
|
3564
|
-
air_loop.supplyComponents.each do |comp|
|
3565
|
-
next unless comp.to_EvaporativeCoolerDirectResearchSpecial.is_initialized
|
3179
|
+
def self.set_cool_rated_cfm_per_ton_mshp(heat_pump, num_speeds)
|
3180
|
+
hp_ap = heat_pump.additional_properties
|
3566
3181
|
|
3567
|
-
|
3568
|
-
|
3569
|
-
return
|
3570
|
-
end
|
3571
|
-
|
3572
|
-
def self.get_unitary_system_air_loops(model, thermal_zone)
|
3573
|
-
# Returns the unitary system(s), cooling coil(s), heating coil(s), and air loops(s) if available
|
3574
|
-
unitary_system_air_loops = []
|
3575
|
-
thermal_zone.airLoopHVACs.each do |air_loop|
|
3576
|
-
system = get_unitary_system_from_air_loop_hvac(air_loop)
|
3577
|
-
next if system.nil?
|
3578
|
-
|
3579
|
-
clg_coil = nil
|
3580
|
-
htg_coil = nil
|
3581
|
-
if system.coolingCoil.is_initialized
|
3582
|
-
clg_coil = system.coolingCoil.get
|
3583
|
-
end
|
3584
|
-
if system.heatingCoil.is_initialized
|
3585
|
-
htg_coil = system.heatingCoil.get
|
3586
|
-
end
|
3587
|
-
unitary_system_air_loops << [system, clg_coil, htg_coil, air_loop]
|
3588
|
-
end
|
3589
|
-
return unitary_system_air_loops
|
3590
|
-
end
|
3591
|
-
|
3592
|
-
def self.get_unitary_system_hvac_map(model, thermal_zone)
|
3593
|
-
# Returns the unitary system, cooling coil, and heating coil if available
|
3594
|
-
unitary_system_hvac_map = []
|
3595
|
-
thermal_zone.equipment.each do |equipment|
|
3596
|
-
next unless equipment.to_AirLoopHVACUnitarySystem.is_initialized
|
3597
|
-
|
3598
|
-
system = equipment.to_AirLoopHVACUnitarySystem.get
|
3599
|
-
clg_coil = nil
|
3600
|
-
htg_coil = nil
|
3601
|
-
if system.coolingCoil.is_initialized
|
3602
|
-
clg_coil = system.coolingCoil.get
|
3603
|
-
end
|
3604
|
-
if system.heatingCoil.is_initialized
|
3605
|
-
htg_coil = system.heatingCoil.get
|
3606
|
-
end
|
3607
|
-
unitary_system_hvac_map << [system, clg_coil, htg_coil]
|
3608
|
-
end
|
3609
|
-
return unitary_system_hvac_map
|
3610
|
-
end
|
3611
|
-
|
3612
|
-
def self.get_ptacs(model, thermal_zone)
|
3613
|
-
# Returns the PTAC(s) if available
|
3614
|
-
ptacs = []
|
3615
|
-
model.getZoneHVACPackagedTerminalAirConditioners.each do |ptac|
|
3616
|
-
next unless thermal_zone.handle.to_s == ptac.thermalZone.get.handle.to_s
|
3617
|
-
|
3618
|
-
ptacs << ptac
|
3619
|
-
end
|
3620
|
-
return ptacs
|
3621
|
-
end
|
3622
|
-
|
3623
|
-
def self.get_evap_coolers(model, thermal_zone)
|
3624
|
-
# Returns the evaporative cooler if available
|
3625
|
-
evap_coolers = []
|
3626
|
-
thermal_zone.airLoopHVACs.each do |air_loop|
|
3627
|
-
evap_cooler = get_evap_cooler_from_air_loop_hvac(air_loop)
|
3628
|
-
next if evap_cooler.nil?
|
3629
|
-
|
3630
|
-
evap_coolers << evap_cooler
|
3631
|
-
end
|
3632
|
-
return evap_coolers
|
3633
|
-
end
|
3634
|
-
|
3635
|
-
def self.get_baseboard_waters(model, thermal_zone)
|
3636
|
-
# Returns the water baseboard if available
|
3637
|
-
baseboards = []
|
3638
|
-
model.getZoneHVACBaseboardConvectiveWaters.each do |baseboard|
|
3639
|
-
next unless thermal_zone.handle.to_s == baseboard.thermalZone.get.handle.to_s
|
3640
|
-
|
3641
|
-
baseboards << baseboard
|
3642
|
-
end
|
3643
|
-
return baseboards
|
3644
|
-
end
|
3645
|
-
|
3646
|
-
def self.get_fan_coils(model, thermal_zone)
|
3647
|
-
# Returns the fan coil if available
|
3648
|
-
fancoils = []
|
3649
|
-
model.getZoneHVACFourPipeFanCoils.each do |fancoil|
|
3650
|
-
next unless thermal_zone.handle.to_s == fancoil.thermalZone.get.handle.to_s
|
3651
|
-
|
3652
|
-
fancoils << fancoil
|
3653
|
-
end
|
3654
|
-
return fancoils
|
3655
|
-
end
|
3656
|
-
|
3657
|
-
def self.get_baseboard_electrics(model, thermal_zone)
|
3658
|
-
# Returns the electric baseboard if available
|
3659
|
-
baseboards = []
|
3660
|
-
model.getZoneHVACBaseboardConvectiveElectrics.each do |baseboard|
|
3661
|
-
next unless thermal_zone.handle.to_s == baseboard.thermalZone.get.handle.to_s
|
3662
|
-
|
3663
|
-
baseboards << baseboard
|
3664
|
-
end
|
3665
|
-
return baseboards
|
3666
|
-
end
|
3667
|
-
|
3668
|
-
def self.get_dehumidifiers(model, runner, thermal_zone)
|
3669
|
-
# Returns the dehumidifier if available
|
3670
|
-
dehums = []
|
3671
|
-
model.getZoneHVACDehumidifierDXs.each do |dehum|
|
3672
|
-
next unless thermal_zone.handle.to_s == dehum.thermalZone.get.handle.to_s
|
3673
|
-
|
3674
|
-
dehums << dehum
|
3675
|
-
end
|
3676
|
-
return dehums
|
3677
|
-
end
|
3678
|
-
|
3679
|
-
def self.get_ideal_air(model, thermal_zone)
|
3680
|
-
# Returns the heating ideal air loads system if available
|
3681
|
-
model.getZoneHVACIdealLoadsAirSystems.each do |ideal_air|
|
3682
|
-
next unless thermal_zone.handle.to_s == ideal_air.thermalZone.get.handle.to_s
|
3683
|
-
|
3684
|
-
return ideal_air
|
3685
|
-
end
|
3686
|
-
return
|
3687
|
-
end
|
3688
|
-
|
3689
|
-
def self.has_ducted_equipment(model, air_loop)
|
3690
|
-
if air_loop.name.to_s.include? Constants.ObjectNameEvaporativeCooler
|
3691
|
-
system = air_loop
|
3692
|
-
else
|
3693
|
-
system = get_unitary_system_from_air_loop_hvac(air_loop)
|
3694
|
-
end
|
3695
|
-
|
3696
|
-
hvac_type_cool = system.additionalProperties.getFeatureAsString(Constants.SizingInfoHVACCoolType)
|
3697
|
-
hvac_type_cool = hvac_type_cool.get if hvac_type_cool.is_initialized
|
3698
|
-
hvac_type_heat = system.additionalProperties.getFeatureAsString(Constants.SizingInfoHVACHeatType)
|
3699
|
-
hvac_type_heat = hvac_type_heat.get if hvac_type_heat.is_initialized
|
3700
|
-
|
3701
|
-
if [Constants.ObjectNameCentralAirConditioner,
|
3702
|
-
Constants.ObjectNameAirSourceHeatPump,
|
3703
|
-
Constants.ObjectNameGroundSourceHeatPump].include? hvac_type_cool
|
3704
|
-
return true
|
3705
|
-
elsif Constants.ObjectNameFurnace == hvac_type_heat
|
3706
|
-
return true
|
3707
|
-
elsif [Constants.ObjectNameMiniSplitHeatPump, Constants.ObjectNameEvaporativeCooler].include? hvac_type_cool
|
3708
|
-
is_ducted = system.additionalProperties.getFeatureAsBoolean(Constants.SizingInfoHVACSystemIsDucted).get
|
3709
|
-
if is_ducted
|
3710
|
-
return true
|
3711
|
-
end
|
3712
|
-
end
|
3713
|
-
|
3714
|
-
return false
|
3715
|
-
end
|
3716
|
-
|
3717
|
-
def self.calc_mshp_cfms_ton_cooling(cap_min_per, cap_max_per, cfm_ton_min, cfm_ton_max, num_speeds, dB_rated, wB_rated, shr)
|
3718
|
-
cool_capacity_ratios = [0.0] * num_speeds
|
3719
|
-
cool_cfms_ton_rated = [0.0] * num_speeds
|
3720
|
-
cool_shrs_rated = [0.0] * num_speeds
|
3182
|
+
dB_rated = 80.0 # deg-F
|
3183
|
+
wB_rated = 67.0 # deg-F
|
3721
3184
|
|
3722
|
-
|
3723
|
-
|
3185
|
+
cool_nominal_capacity_ratio = 1.0
|
3186
|
+
cool_nominal_cfm_per_ton = ((hp_ap.cool_max_cfm_per_ton * hp_ap.cool_max_capacity_ratio - hp_ap.cool_min_cfm_per_ton * hp_ap.cool_min_capacity_ratio) /
|
3187
|
+
(hp_ap.cool_max_capacity_ratio - hp_ap.cool_min_capacity_ratio)) *
|
3188
|
+
(cool_nominal_capacity_ratio - hp_ap.cool_min_capacity_ratio) + hp_ap.cool_min_cfm_per_ton * hp_ap.cool_min_capacity_ratio
|
3724
3189
|
|
3725
3190
|
p_atm = 14.696 # standard atmospheric pressure (psia)
|
3726
3191
|
|
3727
|
-
ao = Psychrometrics.CoilAoFactor(dB_rated, wB_rated, p_atm, UnitConversions.convert(1, 'ton', 'kBtu/hr'),
|
3192
|
+
ao = Psychrometrics.CoilAoFactor(dB_rated, wB_rated, p_atm, UnitConversions.convert(1, 'ton', 'kBtu/hr'), cool_nominal_cfm_per_ton, heat_pump.cooling_shr)
|
3193
|
+
|
3194
|
+
hp_ap.cool_capacity_ratios = []
|
3195
|
+
hp_ap.cool_rated_cfm_per_ton = []
|
3196
|
+
hp_ap.cool_rated_shrs_gross = []
|
3728
3197
|
|
3729
3198
|
(0...num_speeds).each do |i|
|
3730
|
-
cool_capacity_ratios
|
3731
|
-
|
3199
|
+
hp_ap.cool_capacity_ratios << hp_ap.cool_min_capacity_ratio + i * (hp_ap.cool_max_capacity_ratio - hp_ap.cool_min_capacity_ratio) / (num_speeds - 1)
|
3200
|
+
hp_ap.cool_rated_cfm_per_ton << (hp_ap.cool_min_cfm_per_ton * hp_ap.cool_min_capacity_ratio + i * (hp_ap.cool_max_cfm_per_ton * hp_ap.cool_max_capacity_ratio - hp_ap.cool_min_cfm_per_ton * hp_ap.cool_min_capacity_ratio) / (num_speeds - 1)) / hp_ap.cool_capacity_ratios[-1]
|
3732
3201
|
# Calculate the SHR for each speed. Use minimum value of 0.98 to prevent E+ bypass factor calculation errors
|
3733
|
-
|
3202
|
+
hp_ap.cool_rated_shrs_gross[i] = [Psychrometrics.CalculateSHR(dB_rated, wB_rated, p_atm, UnitConversions.convert(hp_ap.cool_capacity_ratios[i], 'ton', 'kBtu/hr'), hp_ap.cool_rated_cfm_per_ton[i] * hp_ap.cool_capacity_ratios[i], ao), 0.98].min
|
3734
3203
|
end
|
3735
|
-
|
3736
|
-
return cool_cfms_ton_rated, cool_capacity_ratios, cool_shrs_rated
|
3737
3204
|
end
|
3738
3205
|
|
3739
|
-
def self.
|
3206
|
+
def self.set_cool_rated_eirs_mshp(cooling_system, num_speeds)
|
3207
|
+
clg_ap = cooling_system.additional_properties
|
3208
|
+
|
3740
3209
|
cops_norm = [1.901, 1.859, 1.746, 1.609, 1.474, 1.353, 1.247, 1.156, 1.079, 1.0]
|
3741
3210
|
fan_powers_norm = [0.604, 0.634, 0.670, 0.711, 0.754, 0.800, 0.848, 0.898, 0.948, 1.0]
|
3742
3211
|
|
3743
|
-
|
3744
|
-
fan_powers_rated = [0.0] * num_speeds
|
3745
|
-
eers_Rated = [0.0] * num_speeds
|
3212
|
+
cop_max_speed = 3.5 # 3.5 is an initial guess, final value solved for below
|
3746
3213
|
|
3747
|
-
|
3214
|
+
fan_powers_rated = []
|
3215
|
+
eers_rated = []
|
3748
3216
|
|
3749
3217
|
(0...num_speeds).each do |i|
|
3750
|
-
fan_powers_rated
|
3751
|
-
|
3218
|
+
fan_powers_rated << clg_ap.fan_power_rated * fan_powers_norm[i]
|
3219
|
+
eers_rated << UnitConversions.convert(cop_max_speed, 'W', 'Btu/hr') * cops_norm[i]
|
3752
3220
|
end
|
3753
3221
|
|
3754
|
-
|
3755
|
-
|
3756
|
-
error =
|
3222
|
+
cop_max_speed_1 = cop_max_speed
|
3223
|
+
cop_max_speed_2 = cop_max_speed
|
3224
|
+
error = cooling_system.cooling_efficiency_seer - calc_mshp_seer(eers_rated, clg_ap.cool_c_d, clg_ap.cool_capacity_ratios, clg_ap.cool_rated_cfm_per_ton, fan_powers_rated, clg_ap.cool_eir_ft_spec, clg_ap.cool_cap_ft_spec)
|
3757
3225
|
error1 = error
|
3758
3226
|
error2 = error
|
3759
3227
|
|
@@ -3764,12 +3232,12 @@ class HVAC
|
|
3764
3232
|
(1...itmax + 1).each do |n|
|
3765
3233
|
final_n = n
|
3766
3234
|
(0...num_speeds).each do |i|
|
3767
|
-
|
3235
|
+
eers_rated[i] = UnitConversions.convert(cop_max_speed, 'W', 'Btu/hr') * cops_norm[i]
|
3768
3236
|
end
|
3769
3237
|
|
3770
|
-
error =
|
3238
|
+
error = cooling_system.cooling_efficiency_seer - calc_mshp_seer(eers_rated, clg_ap.cool_c_d, clg_ap.cool_capacity_ratios, clg_ap.cool_rated_cfm_per_ton, fan_powers_rated, clg_ap.cool_eir_ft_spec, clg_ap.cool_cap_ft_spec)
|
3771
3239
|
|
3772
|
-
|
3240
|
+
cop_max_speed, cvg, cop_max_speed_1, error1, cop_max_speed_2, error2 = MathTools.Iterate(cop_max_speed, error, cop_max_speed_1, error1, cop_max_speed_2, error2, n, cvg)
|
3773
3241
|
|
3774
3242
|
if cvg
|
3775
3243
|
break
|
@@ -3777,19 +3245,55 @@ class HVAC
|
|
3777
3245
|
end
|
3778
3246
|
|
3779
3247
|
if (not cvg) || (final_n > itmax)
|
3780
|
-
|
3781
|
-
runner.registerWarning('Mini-split heat pump cop iteration failed to converge. Setting to default value.')
|
3248
|
+
cop_max_speed = UnitConversions.convert(0.547 * cooling_system.cooling_efficiency_seer - 0.104, 'Btu/hr', 'W') # Correlation developed from JonW's MatLab scripts. Only used if an eer cannot be found.
|
3782
3249
|
end
|
3783
3250
|
|
3251
|
+
clg_ap.cool_rated_eirs = []
|
3252
|
+
|
3784
3253
|
(0...num_speeds).each do |i|
|
3785
|
-
|
3254
|
+
clg_ap.cool_rated_eirs << calc_eir_from_eer(UnitConversions.convert(cop_max_speed, 'W', 'Btu/hr') * cops_norm[i], fan_powers_rated[i])
|
3786
3255
|
end
|
3256
|
+
end
|
3787
3257
|
|
3788
|
-
|
3258
|
+
def self.set_mshp_downselected_speed_indices(heat_pump)
|
3259
|
+
hp_ap = heat_pump.additional_properties
|
3260
|
+
|
3261
|
+
# Down-select to speed indices
|
3262
|
+
|
3263
|
+
# Cooling
|
3264
|
+
hp_ap.cool_cap_ft_spec = hp_ap.cool_cap_ft_spec.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3265
|
+
hp_ap.cool_eir_ft_spec = hp_ap.cool_eir_ft_spec.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3266
|
+
hp_ap.cool_cap_fflow_spec = hp_ap.cool_cap_fflow_spec.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3267
|
+
hp_ap.cool_eir_fflow_spec = hp_ap.cool_eir_fflow_spec.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3268
|
+
hp_ap.cool_plf_fplr_spec = hp_ap.cool_plf_fplr_spec.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3269
|
+
hp_ap.cool_rated_cfm_per_ton = hp_ap.cool_rated_cfm_per_ton.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3270
|
+
hp_ap.cool_capacity_ratios = hp_ap.cool_capacity_ratios.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3271
|
+
hp_ap.cool_rated_shrs_gross = hp_ap.cool_rated_shrs_gross.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3272
|
+
hp_ap.cool_rated_eirs = hp_ap.cool_rated_eirs.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3273
|
+
hp_ap.cool_fan_speed_ratios = []
|
3274
|
+
for i in 0..(hp_ap.speed_indices.size - 1)
|
3275
|
+
hp_ap.cool_fan_speed_ratios << hp_ap.cool_rated_cfm_per_ton[i] * hp_ap.cool_capacity_ratios[i] / (hp_ap.cool_rated_cfm_per_ton[-1] * hp_ap.cool_capacity_ratios[-1])
|
3276
|
+
end
|
3277
|
+
|
3278
|
+
if heat_pump.is_a? HPXML::HeatPump # Skip for mini-split air conditioner
|
3279
|
+
# Heating
|
3280
|
+
hp_ap.heat_eir_ft_spec = hp_ap.heat_eir_ft_spec.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3281
|
+
hp_ap.heat_cap_fflow_spec = hp_ap.heat_cap_fflow_spec.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3282
|
+
hp_ap.heat_eir_fflow_spec = hp_ap.heat_eir_fflow_spec.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3283
|
+
hp_ap.heat_cap_ft_spec = hp_ap.heat_cap_ft_spec.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3284
|
+
hp_ap.heat_plf_fplr_spec = hp_ap.heat_plf_fplr_spec.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3285
|
+
hp_ap.heat_rated_cfm_per_ton = hp_ap.heat_rated_cfm_per_ton.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3286
|
+
hp_ap.heat_capacity_ratios = hp_ap.heat_capacity_ratios.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3287
|
+
hp_ap.heat_rated_eirs = hp_ap.heat_rated_eirs.select.with_index { |x, i| hp_ap.speed_indices.include? i }
|
3288
|
+
hp_ap.heat_fan_speed_ratios = []
|
3289
|
+
for i in 0..(hp_ap.speed_indices.size - 1)
|
3290
|
+
hp_ap.heat_fan_speed_ratios << hp_ap.heat_rated_cfm_per_ton[i] * hp_ap.heat_capacity_ratios[i] / (hp_ap.heat_rated_cfm_per_ton[-1] * hp_ap.heat_capacity_ratios[-1])
|
3291
|
+
end
|
3292
|
+
end
|
3789
3293
|
end
|
3790
3294
|
|
3791
|
-
def self.
|
3792
|
-
n_max = (eer_a.length - 1.0) - 3.0 # Don't use max speed; FIXME: this is different than
|
3295
|
+
def self.calc_mshp_seer(eer_a, c_d, capacity_ratio, cfm_tons, fan_power_rated, cool_eir_ft_spec, cool_cap_ft_spec)
|
3296
|
+
n_max = (eer_a.length - 1.0) - 3.0 # Don't use max speed; FIXME: this is different than calc_mshp_hspf?
|
3793
3297
|
n_min = 0
|
3794
3298
|
n_int = (n_min + (n_max - n_min) / 3.0).ceil.to_i
|
3795
3299
|
|
@@ -3814,17 +3318,17 @@ class HVAC
|
|
3814
3318
|
q_B1 = capacity_ratio[n_min] * MathTools.biquadratic(wBin, tout_B, cool_cap_ft_spec[n_min])
|
3815
3319
|
q_F1 = capacity_ratio[n_min] * MathTools.biquadratic(wBin, tout_F, cool_cap_ft_spec[n_min])
|
3816
3320
|
|
3817
|
-
q_A2_net = q_A2 - fan_power_rated[n_max] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_max] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3818
|
-
q_B2_net = q_B2 - fan_power_rated[n_max] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_max] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3819
|
-
q_Ev_net = q_Ev - fan_power_rated[n_int] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_int] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3820
|
-
q_B1_net = q_B1 - fan_power_rated[n_min] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_min] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3821
|
-
q_F1_net = q_F1 - fan_power_rated[n_min] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_min] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3321
|
+
q_A2_net = q_A2 - fan_power_rated[n_max] * UnitConversions.convert(1, 'W', 'Btu/hr') * (cfm_tons[n_max] * capacity_ratio[n_max]) / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3322
|
+
q_B2_net = q_B2 - fan_power_rated[n_max] * UnitConversions.convert(1, 'W', 'Btu/hr') * (cfm_tons[n_max] * capacity_ratio[n_max]) / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3323
|
+
q_Ev_net = q_Ev - fan_power_rated[n_int] * UnitConversions.convert(1, 'W', 'Btu/hr') * (cfm_tons[n_int] * capacity_ratio[n_int]) / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3324
|
+
q_B1_net = q_B1 - fan_power_rated[n_min] * UnitConversions.convert(1, 'W', 'Btu/hr') * (cfm_tons[n_min] * capacity_ratio[n_min]) / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3325
|
+
q_F1_net = q_F1 - fan_power_rated[n_min] * UnitConversions.convert(1, 'W', 'Btu/hr') * (cfm_tons[n_min] * capacity_ratio[n_min]) / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3822
3326
|
|
3823
|
-
p_A2 = UnitConversions.convert(q_A2 * eir_A2, 'Btu', 'Wh') + fan_power_rated[n_max] * cfm_tons[n_max] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3824
|
-
p_B2 = UnitConversions.convert(q_B2 * eir_B2, 'Btu', 'Wh') + fan_power_rated[n_max] * cfm_tons[n_max] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3825
|
-
p_Ev = UnitConversions.convert(q_Ev * eir_Ev, 'Btu', 'Wh') + fan_power_rated[n_int] * cfm_tons[n_int] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3826
|
-
p_B1 = UnitConversions.convert(q_B1 * eir_B1, 'Btu', 'Wh') + fan_power_rated[n_min] * cfm_tons[n_min] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3827
|
-
p_F1 = UnitConversions.convert(q_F1 * eir_F1, 'Btu', 'Wh') + fan_power_rated[n_min] * cfm_tons[n_min] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3327
|
+
p_A2 = UnitConversions.convert(q_A2 * eir_A2, 'Btu', 'Wh') + fan_power_rated[n_max] * (cfm_tons[n_max] * capacity_ratio[n_max]) / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3328
|
+
p_B2 = UnitConversions.convert(q_B2 * eir_B2, 'Btu', 'Wh') + fan_power_rated[n_max] * (cfm_tons[n_max] * capacity_ratio[n_max]) / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3329
|
+
p_Ev = UnitConversions.convert(q_Ev * eir_Ev, 'Btu', 'Wh') + fan_power_rated[n_int] * (cfm_tons[n_int] * capacity_ratio[n_int]) / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3330
|
+
p_B1 = UnitConversions.convert(q_B1 * eir_B1, 'Btu', 'Wh') + fan_power_rated[n_min] * (cfm_tons[n_min] * capacity_ratio[n_min]) / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3331
|
+
p_F1 = UnitConversions.convert(q_F1 * eir_F1, 'Btu', 'Wh') + fan_power_rated[n_min] * (cfm_tons[n_min] * capacity_ratio[n_min]) / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3828
3332
|
|
3829
3333
|
q_k1_87 = q_F1_net + (q_B1_net - q_F1_net) / (82.0 - 67.0) * (87 - 67.0)
|
3830
3334
|
q_k2_87 = q_B2_net + (q_A2_net - q_B2_net) / (95.0 - 82.0) * (87.0 - 82.0)
|
@@ -3894,36 +3398,37 @@ class HVAC
|
|
3894
3398
|
return seer
|
3895
3399
|
end
|
3896
3400
|
|
3897
|
-
def self.
|
3898
|
-
|
3899
|
-
|
3401
|
+
def self.set_heat_rated_cfm_per_ton_mshp(heat_pump, num_speeds)
|
3402
|
+
hp_ap = heat_pump.additional_properties
|
3403
|
+
|
3404
|
+
hp_ap.heat_capacity_ratios = []
|
3405
|
+
hp_ap.heat_rated_cfm_per_ton = []
|
3900
3406
|
|
3901
3407
|
(0...num_speeds).each do |i|
|
3902
|
-
heat_capacity_ratios
|
3903
|
-
|
3408
|
+
hp_ap.heat_capacity_ratios << hp_ap.heat_min_capacity_ratio + i * (hp_ap.heat_max_capacity_ratio - hp_ap.heat_min_capacity_ratio) / (num_speeds - 1)
|
3409
|
+
hp_ap.heat_rated_cfm_per_ton << (hp_ap.heat_min_cfm_per_ton * hp_ap.heat_min_capacity_ratio + i * (hp_ap.heat_max_cfm_per_ton * hp_ap.heat_max_capacity_ratio - hp_ap.heat_min_cfm_per_ton * hp_ap.heat_min_capacity_ratio) / (num_speeds - 1)) / hp_ap.heat_capacity_ratios[-1]
|
3904
3410
|
end
|
3905
|
-
|
3906
|
-
return heat_cfms_ton_rated, heat_capacity_ratios
|
3907
3411
|
end
|
3908
3412
|
|
3909
|
-
def self.
|
3910
|
-
|
3911
|
-
fan_powers_norm = [0.577, 0.625, 0.673, 0.720, 0.768, 0.814, 0.861, 0.907, 0.954, 1]
|
3413
|
+
def self.set_heat_rated_eirs_mshp(heat_pump, num_speeds)
|
3414
|
+
hp_ap = heat_pump.additional_properties
|
3912
3415
|
|
3913
|
-
|
3914
|
-
|
3915
|
-
cops_rated = [0.0] * num_speeds
|
3416
|
+
cops_norm = [1.792, 1.502, 1.308, 1.207, 1.145, 1.105, 1.077, 1.056, 1.041, 1.0]
|
3417
|
+
fan_powers_norm = [0.577, 0.625, 0.673, 0.720, 0.768, 0.814, 0.861, 0.907, 0.954, 1.0]
|
3916
3418
|
|
3917
|
-
|
3419
|
+
cop_max_speed = 3.25 # 3.35 is an initial guess, final value solved for below
|
3420
|
+
|
3421
|
+
fan_powers_rated = []
|
3422
|
+
cops_rated = []
|
3918
3423
|
|
3919
3424
|
(0...num_speeds).each do |i|
|
3920
|
-
fan_powers_rated
|
3921
|
-
cops_rated
|
3425
|
+
fan_powers_rated << hp_ap.fan_power_rated * fan_powers_norm[i]
|
3426
|
+
cops_rated << cop_max_speed * cops_norm[i]
|
3922
3427
|
end
|
3923
3428
|
|
3924
|
-
|
3925
|
-
|
3926
|
-
error =
|
3429
|
+
cop_max_speed_1 = cop_max_speed
|
3430
|
+
cop_max_speed_2 = cop_max_speed
|
3431
|
+
error = heat_pump.heating_efficiency_hspf - calc_mshp_hspf(cops_rated, hp_ap.heat_c_d, hp_ap.heat_capacity_ratios, hp_ap.heat_rated_cfm_per_ton, fan_powers_rated, hp_ap.hp_min_temp, hp_ap.heat_eir_ft_spec, hp_ap.heat_cap_ft_spec)
|
3927
3432
|
|
3928
3433
|
error1 = error
|
3929
3434
|
error2 = error
|
@@ -3935,12 +3440,12 @@ class HVAC
|
|
3935
3440
|
(1...itmax + 1).each do |n|
|
3936
3441
|
final_n = n
|
3937
3442
|
(0...num_speeds).each do |i|
|
3938
|
-
cops_rated[i] =
|
3443
|
+
cops_rated[i] = cop_max_speed * cops_norm[i]
|
3939
3444
|
end
|
3940
3445
|
|
3941
|
-
error =
|
3446
|
+
error = heat_pump.heating_efficiency_hspf - calc_mshp_hspf(cops_rated, hp_ap.heat_c_d, hp_ap.heat_capacity_ratios, hp_ap.heat_rated_cfm_per_ton, fan_powers_rated, hp_ap.hp_min_temp, hp_ap.heat_eir_ft_spec, hp_ap.heat_cap_ft_spec)
|
3942
3447
|
|
3943
|
-
|
3448
|
+
cop_max_speed, cvg, cop_max_speed_1, error1, cop_max_speed_2, error2 = MathTools.Iterate(cop_max_speed, error, cop_max_speed_1, error1, cop_max_speed_2, error2, n, cvg)
|
3944
3449
|
|
3945
3450
|
if cvg
|
3946
3451
|
break
|
@@ -3948,19 +3453,62 @@ class HVAC
|
|
3948
3453
|
end
|
3949
3454
|
|
3950
3455
|
if (not cvg) || (final_n > itmax)
|
3951
|
-
|
3952
|
-
runner.registerWarning('Mini-split heat pump cop iteration failed to converge. Setting to default value.')
|
3456
|
+
cop_max_speed = UnitConversions.convert(0.4174 * hspf - 1.1134, 'Btu/hr', 'W') # Correlation developed from JonW's MatLab scripts. Only used if a cop cannot be found.
|
3953
3457
|
end
|
3954
3458
|
|
3459
|
+
hp_ap.heat_rated_eirs = []
|
3955
3460
|
(0...num_speeds).each do |i|
|
3956
|
-
|
3461
|
+
hp_ap.heat_rated_eirs << calc_eir_from_cop(cop_max_speed * cops_norm[i], fan_powers_rated[i])
|
3957
3462
|
end
|
3463
|
+
end
|
3464
|
+
|
3465
|
+
def self.set_gshp_assumptions(heat_pump, weather)
|
3466
|
+
hp_ap = heat_pump.additional_properties
|
3958
3467
|
|
3959
|
-
|
3468
|
+
hp_ap.design_chw = [85.0, weather.design.CoolingDrybulb - 15.0, weather.data.AnnualAvgDrybulb + 10.0].max # Temperature of water entering indoor coil,use 85F as lower bound
|
3469
|
+
hp_ap.design_delta_t = 10.0
|
3470
|
+
hp_ap.fluid_type = Constants.FluidPropyleneGlycol
|
3471
|
+
hp_ap.frac_glycol = 0.3
|
3472
|
+
if hp_ap.fluid_type == Constants.FluidWater
|
3473
|
+
hp_ap.design_hw = [45.0, weather.design.HeatingDrybulb + 35.0, weather.data.AnnualAvgDrybulb - 10.0].max # Temperature of fluid entering indoor coil, use 45F as lower bound for water
|
3474
|
+
else
|
3475
|
+
hp_ap.design_hw = [35.0, weather.design.HeatingDrybulb + 35.0, weather.data.AnnualAvgDrybulb - 10.0].min # Temperature of fluid entering indoor coil, use 35F as upper bound
|
3476
|
+
end
|
3477
|
+
hp_ap.ground_conductivity = 0.6 # Btu/h-ft-R
|
3478
|
+
hp_ap.ground_diffusivity = 0.0208
|
3479
|
+
hp_ap.grout_conductivity = 0.4 # Btu/h-ft-R
|
3480
|
+
hp_ap.bore_diameter = 5.0 # in
|
3481
|
+
hp_ap.pipe_size = 0.75 # in
|
3482
|
+
# Pipe nominal size conversion to pipe outside diameter and inside diameter,
|
3483
|
+
# only pipe sizes <= 2" are used here with DR11 (dimension ratio),
|
3484
|
+
if hp_ap.pipe_size == 0.75 # 3/4" pipe
|
3485
|
+
hp_ap.pipe_od = 1.050 # in
|
3486
|
+
hp_ap.pipe_id = 0.859 # in
|
3487
|
+
elsif hp_ap.pipe_size == 1.0 # 1" pipe
|
3488
|
+
hp_ap.pipe_od = 1.315 # in
|
3489
|
+
hp_ap.pipe_id = 1.076 # in
|
3490
|
+
elsif hp_ap.pipe_size == 1.25 # 1-1/4" pipe
|
3491
|
+
hp_ap.pipe_od = 1.660 # in
|
3492
|
+
hp_ap.pipe_id = 1.358 # in
|
3493
|
+
end
|
3494
|
+
hp_ap.pipe_cond = 0.23 # Btu/h-ft-R; Pipe thermal conductivity, default to high density polyethylene
|
3495
|
+
hp_ap.u_tube_spacing_type = 'b'
|
3496
|
+
# Calculate distance between pipes
|
3497
|
+
if hp_ap.u_tube_spacing_type == 'as'
|
3498
|
+
# Two tubes, spaced 1/8” apart at the center of the borehole
|
3499
|
+
hp_ap.u_tube_spacing = 0.125
|
3500
|
+
elsif hp_ap.u_tube_spacing_type == 'b'
|
3501
|
+
# Two tubes equally spaced between the borehole edges
|
3502
|
+
hp_ap.u_tube_spacing = 0.9661
|
3503
|
+
elsif hp_ap.u_tube_spacing_type == 'c'
|
3504
|
+
# Both tubes placed against outer edge of borehole
|
3505
|
+
hp_ap.u_tube_spacing = hp_ap.bore_diameter - 2 * hp_ap.pipe_od
|
3506
|
+
end
|
3507
|
+
hp_ap.shank_spacing = hp_ap.u_tube_spacing + hp_ap.pipe_od # Distance from center of pipe to center of pipe
|
3960
3508
|
end
|
3961
3509
|
|
3962
|
-
def self.
|
3963
|
-
n_max = (cop_47.length - 1.0) #-3 # Don't use max speed; FIXME: this is different than
|
3510
|
+
def self.calc_mshp_hspf(cop_47, c_d, capacity_ratio, cfm_tons, fan_power_rated, hp_min_temp, heat_eir_ft_spec, heat_cap_ft_spec)
|
3511
|
+
n_max = (cop_47.length - 1.0) #-3 # Don't use max speed; FIXME: this is different than calc_mshp_seer?
|
3964
3512
|
n_min = 0
|
3965
3513
|
n_int = (n_min + (n_max - n_min) / 3.0).ceil.to_i
|
3966
3514
|
|
@@ -3986,17 +3534,17 @@ class HVAC
|
|
3986
3534
|
q_H1_1 = capacity_ratio[n_min]
|
3987
3535
|
q_H0_1 = q_H1_1 * MathTools.biquadratic(tin, tout_0, heat_cap_ft_spec[n_min])
|
3988
3536
|
|
3989
|
-
q_H1_2_net = q_H1_2 + fan_power_rated[n_max] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_max] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3990
|
-
q_H3_2_net = q_H3_2 + fan_power_rated[n_max] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_max] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3991
|
-
q_H2_v_net = q_H2_v + fan_power_rated[n_int] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_int] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3992
|
-
q_H1_1_net = q_H1_1 + fan_power_rated[n_min] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_min] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3993
|
-
q_H0_1_net = q_H0_1 + fan_power_rated[n_min] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_min] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3537
|
+
q_H1_2_net = q_H1_2 + fan_power_rated[n_max] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_max] * capacity_ratio[n_max] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3538
|
+
q_H3_2_net = q_H3_2 + fan_power_rated[n_max] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_max] * capacity_ratio[n_max] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3539
|
+
q_H2_v_net = q_H2_v + fan_power_rated[n_int] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_int] * capacity_ratio[n_int] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3540
|
+
q_H1_1_net = q_H1_1 + fan_power_rated[n_min] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_min] * capacity_ratio[n_min] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3541
|
+
q_H0_1_net = q_H0_1 + fan_power_rated[n_min] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_min] * capacity_ratio[n_min] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3994
3542
|
|
3995
|
-
p_H1_2 = q_H1_2 * eir_H1_2 + fan_power_rated[n_max] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_max] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3996
|
-
p_H3_2 = q_H3_2 * eir_H3_2 + fan_power_rated[n_max] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_max] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3997
|
-
p_H2_v = q_H2_v * eir_H2_v + fan_power_rated[n_int] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_int] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3998
|
-
p_H1_1 = q_H1_1 * eir_H1_1 + fan_power_rated[n_min] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_min] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3999
|
-
p_H0_1 = q_H0_1 * eir_H0_1 + fan_power_rated[n_min] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_min] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3543
|
+
p_H1_2 = q_H1_2 * eir_H1_2 + fan_power_rated[n_max] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_max] * capacity_ratio[n_max] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3544
|
+
p_H3_2 = q_H3_2 * eir_H3_2 + fan_power_rated[n_max] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_max] * capacity_ratio[n_max] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3545
|
+
p_H2_v = q_H2_v * eir_H2_v + fan_power_rated[n_int] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_int] * capacity_ratio[n_int] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3546
|
+
p_H1_1 = q_H1_1 * eir_H1_1 + fan_power_rated[n_min] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_min] * capacity_ratio[n_min] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
3547
|
+
p_H0_1 = q_H0_1 * eir_H0_1 + fan_power_rated[n_min] * UnitConversions.convert(1, 'W', 'Btu/hr') * cfm_tons[n_min] * capacity_ratio[n_min] / UnitConversions.convert(1, 'ton', 'Btu/hr')
|
4000
3548
|
|
4001
3549
|
q_H35_2 = 0.9 * (q_H3_2_net + 0.6 * (q_H1_2_net - q_H3_2_net))
|
4002
3550
|
p_H35_2 = 0.985 * (p_H3_2 + 0.6 * (p_H1_2 - p_H3_2))
|
@@ -4109,34 +3657,42 @@ class HVAC
|
|
4109
3657
|
return s
|
4110
3658
|
end
|
4111
3659
|
|
4112
|
-
def self.
|
4113
|
-
|
4114
|
-
|
4115
|
-
|
3660
|
+
def self.set_crankcase_assumptions(hvac_system)
|
3661
|
+
hvac_ap = hvac_system.additional_properties
|
3662
|
+
|
3663
|
+
if hvac_system.is_a?(HPXML::HeatPump) && (hvac_system.fraction_heat_load_served <= 0)
|
3664
|
+
hvac_ap.crankcase_kw = 0.0
|
3665
|
+
hvac_ap.crankcase_temp = nil
|
3666
|
+
elsif hvac_system.is_a?(HPXML::HeatPump) && (hvac_system.heat_pump_type == HPXML::HVACTypeHeatPumpMiniSplit)
|
3667
|
+
hvac_ap.crankcase_kw = 0.0
|
3668
|
+
hvac_ap.crankcase_temp = nil
|
3669
|
+
elsif hvac_system.is_a?(HPXML::CoolingSystem) && (hvac_system.cooling_system_type == HPXML::HVACTypeMiniSplitAirConditioner)
|
3670
|
+
hvac_ap.crankcase_kw = 0.0
|
3671
|
+
hvac_ap.crankcase_temp = nil
|
3672
|
+
else
|
3673
|
+
hvac_ap.crankcase_kw = 0.05 * hvac_system.fraction_cool_load_served # From RESNET Publication No. 002-2017
|
3674
|
+
hvac_ap.crankcase_temp = 50.0 # From RESNET Publication No. 002-2017
|
3675
|
+
end
|
4116
3676
|
end
|
4117
3677
|
|
4118
|
-
def self.
|
4119
|
-
|
4120
|
-
|
4121
|
-
#
|
3678
|
+
def self.set_heat_pump_temperatures(heat_pump)
|
3679
|
+
hp_ap = heat_pump.additional_properties
|
3680
|
+
|
3681
|
+
# Sets:
|
3682
|
+
# 1. Minimum temperature (deg-F) for HP compressor operation
|
3683
|
+
# 2. Maximum temperature (deg-F) for HP supplemental heating operation
|
4122
3684
|
if not heat_pump.backup_heating_switchover_temp.nil?
|
4123
|
-
hp_min_temp = heat_pump.backup_heating_switchover_temp
|
4124
|
-
supp_max_temp = heat_pump.backup_heating_switchover_temp
|
3685
|
+
hp_ap.hp_min_temp = heat_pump.backup_heating_switchover_temp
|
3686
|
+
hp_ap.supp_max_temp = heat_pump.backup_heating_switchover_temp
|
4125
3687
|
else
|
4126
|
-
supp_max_temp = 40.0
|
4127
|
-
|
4128
|
-
if heat_pump.heat_pump_type == HPXML::HVACTypeHeatPumpMiniSplit
|
4129
|
-
hp_min_temp = -30.0 # deg-F
|
4130
|
-
else
|
4131
|
-
hp_min_temp = 0.0 # deg-F
|
4132
|
-
end
|
3688
|
+
hp_ap.supp_max_temp = 40.0
|
3689
|
+
hp_ap.hp_min_temp = -40.0
|
4133
3690
|
end
|
4134
|
-
return hp_min_temp, supp_max_temp
|
4135
3691
|
end
|
4136
3692
|
|
4137
3693
|
def self.get_default_duct_surface_area(duct_type, ncfl_ag, cfa_served, n_returns)
|
4138
3694
|
# Fraction of primary ducts (ducts outside conditioned space)
|
4139
|
-
f_out = (ncfl_ag
|
3695
|
+
f_out = (ncfl_ag <= 1) ? 1.0 : 0.75
|
4140
3696
|
|
4141
3697
|
if duct_type == HPXML::DuctTypeSupply
|
4142
3698
|
primary_duct_area = 0.27 * cfa_served * f_out
|
@@ -4171,25 +3727,271 @@ class HVAC
|
|
4171
3727
|
return primary_duct_location, secondary_duct_location
|
4172
3728
|
end
|
4173
3729
|
|
3730
|
+
def self.get_installation_quality_cooling_coeff(f_chg)
|
3731
|
+
if f_chg <= 0
|
3732
|
+
qgr_values = [-9.46E-01, 4.93E-02, -1.18E-03, -1.15E+00]
|
3733
|
+
p_values = [-3.13E-01, 1.15E-02, 2.66E-03, -1.16E-01]
|
3734
|
+
else
|
3735
|
+
qgr_values = [-1.63E-01, 1.14E-02, -2.10E-04, -1.40E-01]
|
3736
|
+
p_values = [2.19E-01, -5.01E-03, 9.89E-04, 2.84E-01]
|
3737
|
+
end
|
3738
|
+
ff_chg_values = [26.67, 35.0]
|
3739
|
+
return qgr_values, p_values, ff_chg_values
|
3740
|
+
end
|
3741
|
+
|
3742
|
+
def self.get_installation_quality_heating_coeff(f_chg)
|
3743
|
+
if f_chg <= 0
|
3744
|
+
qgr_values = [-0.0338595, 0.0202827, -2.6226343]
|
3745
|
+
p_values = [0.0615649, 0.0044554, -0.2598507]
|
3746
|
+
else
|
3747
|
+
qgr_values = [-0.0029514, 0.0007379, -0.0064112]
|
3748
|
+
p_values = [-0.0594134, 0.0159205, 1.8872153]
|
3749
|
+
end
|
3750
|
+
ff_chg_values = [8.33]
|
3751
|
+
return qgr_values, p_values, ff_chg_values
|
3752
|
+
end
|
3753
|
+
|
3754
|
+
def self.apply_installation_quality(model, heating_system, cooling_system, unitary_system, htg_coil, clg_coil, control_zone)
|
3755
|
+
if not cooling_system.nil?
|
3756
|
+
charge_defect_ratio = cooling_system.charge_defect_ratio
|
3757
|
+
cool_airflow_defect_ratio = cooling_system.airflow_defect_ratio
|
3758
|
+
end
|
3759
|
+
if not heating_system.nil?
|
3760
|
+
heat_airflow_defect_ratio = heating_system.airflow_defect_ratio
|
3761
|
+
end
|
3762
|
+
return if (charge_defect_ratio.to_f.abs < 0.001) && (cool_airflow_defect_ratio.to_f.abs < 0.001) && (heat_airflow_defect_ratio.to_f.abs < 0.001)
|
3763
|
+
|
3764
|
+
cool_airflow_rated_defect_ratio = []
|
3765
|
+
if (not clg_coil.nil?) && (cooling_system.fraction_cool_load_served > 0)
|
3766
|
+
clg_ap = cooling_system.additional_properties
|
3767
|
+
clg_cfm = cooling_system.cooling_airflow_cfm
|
3768
|
+
if clg_coil.to_CoilCoolingDXSingleSpeed.is_initialized
|
3769
|
+
cool_airflow_rated_defect_ratio = [UnitConversions.convert(clg_cfm, 'cfm', 'm^3/s') / clg_coil.ratedAirFlowRate.get - 1.0]
|
3770
|
+
elsif clg_coil.to_CoilCoolingDXMultiSpeed.is_initialized
|
3771
|
+
cool_airflow_rated_defect_ratio = clg_coil.stages.zip(clg_ap.cool_fan_speed_ratios).map { |stage, speed_ratio| UnitConversions.convert(clg_cfm * speed_ratio, 'cfm', 'm^3/s') / stage.ratedAirFlowRate.get - 1.0 }
|
3772
|
+
end
|
3773
|
+
end
|
3774
|
+
|
3775
|
+
heat_airflow_rated_defect_ratio = []
|
3776
|
+
if (not htg_coil.nil?) && (heating_system.fraction_heat_load_served > 0)
|
3777
|
+
htg_ap = heating_system.additional_properties
|
3778
|
+
htg_cfm = heating_system.heating_airflow_cfm
|
3779
|
+
if htg_coil.to_CoilHeatingDXSingleSpeed.is_initialized
|
3780
|
+
heat_airflow_rated_defect_ratio = [UnitConversions.convert(htg_cfm, 'cfm', 'm^3/s') / htg_coil.ratedAirFlowRate.get - 1.0]
|
3781
|
+
elsif htg_coil.to_CoilHeatingDXMultiSpeed.is_initialized
|
3782
|
+
heat_airflow_rated_defect_ratio = htg_coil.stages.zip(htg_ap.heat_fan_speed_ratios).map { |stage, speed_ratio| UnitConversions.convert(htg_cfm * speed_ratio, 'cfm', 'm^3/s') / stage.ratedAirFlowRate.get - 1.0 }
|
3783
|
+
end
|
3784
|
+
end
|
3785
|
+
|
3786
|
+
return if cool_airflow_rated_defect_ratio.empty? && heat_airflow_rated_defect_ratio.empty?
|
3787
|
+
|
3788
|
+
obj_name = "#{unitary_system.name} install quality"
|
3789
|
+
|
3790
|
+
tin_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Zone Mean Air Temperature')
|
3791
|
+
tin_sensor.setName("#{obj_name} tin s")
|
3792
|
+
tin_sensor.setKeyName(control_zone.name.to_s)
|
3793
|
+
|
3794
|
+
tout_sensor = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Zone Outdoor Air Drybulb Temperature')
|
3795
|
+
tout_sensor.setName("#{obj_name} tt s")
|
3796
|
+
tout_sensor.setKeyName(control_zone.name.to_s)
|
3797
|
+
|
3798
|
+
fault_program = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
|
3799
|
+
fault_program.setName("#{obj_name} program")
|
3800
|
+
|
3801
|
+
f_chg = charge_defect_ratio.to_f
|
3802
|
+
fault_program.addLine("Set F_CH = #{f_chg.round(3)}")
|
3803
|
+
|
3804
|
+
if not cool_airflow_rated_defect_ratio.empty?
|
3805
|
+
if clg_coil.is_a? OpenStudio::Model::CoilCoolingDXSingleSpeed
|
3806
|
+
num_speeds = 1
|
3807
|
+
cool_cap_fff_curves = [clg_coil.totalCoolingCapacityFunctionOfFlowFractionCurve.to_CurveQuadratic.get]
|
3808
|
+
cool_eir_fff_curves = [clg_coil.energyInputRatioFunctionOfFlowFractionCurve.to_CurveQuadratic.get]
|
3809
|
+
elsif clg_coil.is_a? OpenStudio::Model::CoilCoolingDXMultiSpeed
|
3810
|
+
num_speeds = clg_coil.stages.size
|
3811
|
+
cool_cap_fff_curves = clg_coil.stages.map { |stage| stage.totalCoolingCapacityFunctionofFlowFractionCurve.to_CurveQuadratic.get }
|
3812
|
+
cool_eir_fff_curves = clg_coil.stages.map { |stage| stage.energyInputRatioFunctionofFlowFractionCurve.to_CurveQuadratic.get }
|
3813
|
+
else
|
3814
|
+
fail 'cooling coil not supported'
|
3815
|
+
end
|
3816
|
+
for speed in 0..(num_speeds - 1)
|
3817
|
+
cool_cap_fff_curve = cool_cap_fff_curves[speed]
|
3818
|
+
cool_cap_fff_act = OpenStudio::Model::EnergyManagementSystemActuator.new(cool_cap_fff_curve, 'Curve', 'Curve Result')
|
3819
|
+
cool_cap_fff_act.setName("#{obj_name} cap clg act")
|
3820
|
+
|
3821
|
+
cool_eir_fff_curve = cool_eir_fff_curves[speed]
|
3822
|
+
cool_eir_fff_act = OpenStudio::Model::EnergyManagementSystemActuator.new(cool_eir_fff_curve, 'Curve', 'Curve Result')
|
3823
|
+
cool_eir_fff_act.setName("#{obj_name} eir clg act")
|
3824
|
+
|
3825
|
+
# NOTE: heat pump (cooling) curves don't exhibit expected trends at extreme faults;
|
3826
|
+
fault_program.addLine("Set a1_AF_Qgr_c = #{cool_cap_fff_curve.coefficient1Constant}")
|
3827
|
+
fault_program.addLine("Set a2_AF_Qgr_c = #{cool_cap_fff_curve.coefficient2x}")
|
3828
|
+
fault_program.addLine("Set a3_AF_Qgr_c = #{cool_cap_fff_curve.coefficient3xPOW2}")
|
3829
|
+
fault_program.addLine("Set a1_AF_EIR_c = #{cool_eir_fff_curve.coefficient1Constant}")
|
3830
|
+
fault_program.addLine("Set a2_AF_EIR_c = #{cool_eir_fff_curve.coefficient2x}")
|
3831
|
+
fault_program.addLine("Set a3_AF_EIR_c = #{cool_eir_fff_curve.coefficient3xPOW2}")
|
3832
|
+
|
3833
|
+
qgr_values, p_values, ff_chg_values = get_installation_quality_cooling_coeff(f_chg)
|
3834
|
+
|
3835
|
+
fault_program.addLine("Set a1_CH_Qgr_c = #{qgr_values[0]}")
|
3836
|
+
fault_program.addLine("Set a2_CH_Qgr_c = #{qgr_values[1]}")
|
3837
|
+
fault_program.addLine("Set a3_CH_Qgr_c = #{qgr_values[2]}")
|
3838
|
+
fault_program.addLine("Set a4_CH_Qgr_c = #{qgr_values[3]}")
|
3839
|
+
|
3840
|
+
fault_program.addLine("Set a1_CH_P_c = #{p_values[0]}")
|
3841
|
+
fault_program.addLine("Set a2_CH_P_c = #{p_values[1]}")
|
3842
|
+
fault_program.addLine("Set a3_CH_P_c = #{p_values[2]}")
|
3843
|
+
fault_program.addLine("Set a4_CH_P_c = #{p_values[3]}")
|
3844
|
+
|
3845
|
+
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_chg)) * f_chg)
|
3846
|
+
fault_program.addLine("Set FF_CH_c = #{ff_ch_c.round(3)}")
|
3847
|
+
|
3848
|
+
fault_program.addLine('Set q0_CH = a1_CH_Qgr_c')
|
3849
|
+
fault_program.addLine("Set q1_CH = a2_CH_Qgr_c*#{tin_sensor.name}")
|
3850
|
+
fault_program.addLine("Set q2_CH = a3_CH_Qgr_c*#{tout_sensor.name}")
|
3851
|
+
fault_program.addLine('Set q3_CH = a4_CH_Qgr_c*F_CH')
|
3852
|
+
fault_program.addLine('Set Y_CH_Q_c = 1 + ((q0_CH+(q1_CH)+(q2_CH)+(q3_CH))*F_CH)')
|
3853
|
+
|
3854
|
+
fault_program.addLine('Set q0_AF_CH = a1_AF_Qgr_c')
|
3855
|
+
fault_program.addLine('Set q1_AF_CH = a2_AF_Qgr_c*FF_CH_c')
|
3856
|
+
fault_program.addLine('Set q2_AF_CH = a3_AF_Qgr_c*FF_CH_c*FF_CH_c')
|
3857
|
+
fault_program.addLine('Set p_CH_Q_c = Y_CH_Q_c/(q0_AF_CH+(q1_AF_CH)+(q2_AF_CH))')
|
3858
|
+
|
3859
|
+
fault_program.addLine('Set p1_CH = a1_CH_P_c')
|
3860
|
+
fault_program.addLine("Set p2_CH = a2_CH_P_c*#{tin_sensor.name}")
|
3861
|
+
fault_program.addLine("Set p3_CH = a3_CH_P_c*#{tout_sensor.name}")
|
3862
|
+
fault_program.addLine('Set p4_CH = a4_CH_P_c*F_CH')
|
3863
|
+
fault_program.addLine('Set Y_CH_COP_c = Y_CH_Q_c/(1 + (p1_CH+(p2_CH)+(p3_CH)+(p4_CH))*F_CH)')
|
3864
|
+
|
3865
|
+
fault_program.addLine('Set eir0_AF_CH = a1_AF_EIR_c')
|
3866
|
+
fault_program.addLine('Set eir1_AF_CH = a2_AF_EIR_c*FF_CH_c')
|
3867
|
+
fault_program.addLine('Set eir2_AF_CH = a3_AF_EIR_c*FF_CH_c*FF_CH_c')
|
3868
|
+
fault_program.addLine('Set p_CH_COP_c = Y_CH_COP_c*(eir0_AF_CH+(eir1_AF_CH)+(eir2_AF_CH))')
|
3869
|
+
|
3870
|
+
fault_program.addLine("Set FF_AF_c = 1.0 + #{cool_airflow_rated_defect_ratio[speed].round(3)}")
|
3871
|
+
fault_program.addLine('Set FF_AF_comb_c = FF_CH_c * FF_AF_c')
|
3872
|
+
|
3873
|
+
fault_program.addLine('Set q0_AF_comb = a1_AF_Qgr_c')
|
3874
|
+
fault_program.addLine('Set q1_AF_comb = a2_AF_Qgr_c*FF_AF_comb_c')
|
3875
|
+
fault_program.addLine('Set q2_AF_comb = a3_AF_Qgr_c*FF_AF_comb_c*FF_AF_comb_c')
|
3876
|
+
fault_program.addLine('Set p_AF_Q_c = q0_AF_comb+(q1_AF_comb)+(q2_AF_comb)')
|
3877
|
+
|
3878
|
+
fault_program.addLine('Set eir0_AF_comb = a1_AF_EIR_c')
|
3879
|
+
fault_program.addLine('Set eir1_AF_comb = a2_AF_EIR_c*FF_AF_comb_c')
|
3880
|
+
fault_program.addLine('Set eir2_AF_comb = a3_AF_EIR_c*FF_AF_comb_c*FF_AF_comb_c')
|
3881
|
+
fault_program.addLine('Set p_AF_COP_c = 1.0/(eir0_AF_comb+(eir1_AF_comb)+(eir2_AF_comb))')
|
3882
|
+
|
3883
|
+
fault_program.addLine("Set #{cool_cap_fff_act.name} = (p_CH_Q_c * p_AF_Q_c)")
|
3884
|
+
fault_program.addLine("Set #{cool_eir_fff_act.name} = (1.0 / (p_CH_COP_c * p_AF_COP_c))")
|
3885
|
+
end
|
3886
|
+
end
|
3887
|
+
|
3888
|
+
if not heat_airflow_rated_defect_ratio.empty?
|
3889
|
+
|
3890
|
+
if htg_coil.is_a? OpenStudio::Model::CoilHeatingDXSingleSpeed
|
3891
|
+
num_speeds = 1
|
3892
|
+
heat_cap_fff_curves = [htg_coil.totalHeatingCapacityFunctionofFlowFractionCurve.to_CurveQuadratic.get]
|
3893
|
+
heat_eir_fff_curves = [htg_coil.energyInputRatioFunctionofFlowFractionCurve.to_CurveQuadratic.get]
|
3894
|
+
elsif htg_coil.is_a? OpenStudio::Model::CoilHeatingDXMultiSpeed
|
3895
|
+
num_speeds = htg_coil.stages.size
|
3896
|
+
heat_cap_fff_curves = htg_coil.stages.map { |stage| stage.heatingCapacityFunctionofFlowFractionCurve.to_CurveQuadratic.get }
|
3897
|
+
heat_eir_fff_curves = htg_coil.stages.map { |stage| stage.energyInputRatioFunctionofFlowFractionCurve.to_CurveQuadratic.get }
|
3898
|
+
else
|
3899
|
+
fail 'heating coil not supported'
|
3900
|
+
end
|
3901
|
+
for speed in 0..(num_speeds - 1)
|
3902
|
+
heat_cap_fff_curve = heat_cap_fff_curves[speed]
|
3903
|
+
heat_cap_fff_act = OpenStudio::Model::EnergyManagementSystemActuator.new(heat_cap_fff_curve, 'Curve', 'Curve Result')
|
3904
|
+
heat_cap_fff_act.setName("#{obj_name} cap htg act")
|
3905
|
+
|
3906
|
+
heat_eir_fff_curve = heat_eir_fff_curves[speed]
|
3907
|
+
heat_eir_fff_act = OpenStudio::Model::EnergyManagementSystemActuator.new(heat_eir_fff_curve, 'Curve', 'Curve Result')
|
3908
|
+
heat_eir_fff_act.setName("#{obj_name} eir htg act")
|
3909
|
+
|
3910
|
+
fault_program.addLine("Set a1_AF_Qgr_h = #{heat_cap_fff_curve.coefficient1Constant}")
|
3911
|
+
fault_program.addLine("Set a2_AF_Qgr_h = #{heat_cap_fff_curve.coefficient2x}")
|
3912
|
+
fault_program.addLine("Set a3_AF_Qgr_h = #{heat_cap_fff_curve.coefficient3xPOW2}")
|
3913
|
+
fault_program.addLine("Set a1_AF_EIR_h = #{heat_eir_fff_curve.coefficient1Constant}")
|
3914
|
+
fault_program.addLine("Set a2_AF_EIR_h = #{heat_eir_fff_curve.coefficient2x}")
|
3915
|
+
fault_program.addLine("Set a3_AF_EIR_h = #{heat_eir_fff_curve.coefficient3xPOW2}")
|
3916
|
+
|
3917
|
+
qgr_values, p_values, ff_chg_values = get_installation_quality_heating_coeff(f_chg)
|
3918
|
+
|
3919
|
+
fault_program.addLine("Set a1_CH_Qgr_h = #{qgr_values[0]}")
|
3920
|
+
fault_program.addLine("Set a2_CH_Qgr_h = #{qgr_values[1]}")
|
3921
|
+
fault_program.addLine("Set a3_CH_Qgr_h = #{qgr_values[2]}")
|
3922
|
+
|
3923
|
+
fault_program.addLine("Set a1_CH_P_h = #{p_values[0]}")
|
3924
|
+
fault_program.addLine("Set a2_CH_P_h = #{p_values[1]}")
|
3925
|
+
fault_program.addLine("Set a3_CH_P_h = #{p_values[2]}")
|
3926
|
+
|
3927
|
+
ff_ch_h = 1 / (1 + (qgr_values[0] + qgr_values[1] * ff_chg_values[0] + qgr_values[2] * f_chg) * f_chg)
|
3928
|
+
fault_program.addLine("Set FF_CH_h = #{ff_ch_h.round(3)}")
|
3929
|
+
|
3930
|
+
fault_program.addLine('Set qh1_CH = a1_CH_Qgr_h')
|
3931
|
+
fault_program.addLine("Set qh2_CH = a2_CH_Qgr_h*#{tout_sensor.name}")
|
3932
|
+
fault_program.addLine('Set qh3_CH = a3_CH_Qgr_h*F_CH')
|
3933
|
+
fault_program.addLine('Set Y_CH_Q_h = 1 + ((qh1_CH+(qh2_CH)+(qh3_CH))*F_CH)')
|
3934
|
+
|
3935
|
+
fault_program.addLine('Set qh0_AF_CH = a1_AF_Qgr_h')
|
3936
|
+
fault_program.addLine('Set qh1_AF_CH = a2_AF_Qgr_h*FF_CH_h')
|
3937
|
+
fault_program.addLine('Set qh2_AF_CH = a3_AF_Qgr_h*FF_CH_h*FF_CH_h')
|
3938
|
+
fault_program.addLine('Set p_CH_Q_h = Y_CH_Q_h/(qh0_AF_CH + (qh1_AF_CH) +(qh2_AF_CH))')
|
3939
|
+
|
3940
|
+
fault_program.addLine('Set ph1_CH = a1_CH_P_h')
|
3941
|
+
fault_program.addLine("Set ph2_CH = a2_CH_P_h*#{tout_sensor.name}")
|
3942
|
+
fault_program.addLine('Set ph3_CH = a3_CH_P_h*F_CH')
|
3943
|
+
fault_program.addLine('Set Y_CH_COP_h = Y_CH_Q_h/(1 + ((ph1_CH+(ph2_CH)+(ph3_CH))*F_CH))')
|
3944
|
+
|
3945
|
+
fault_program.addLine('Set eirh0_AF_CH = a1_AF_EIR_h')
|
3946
|
+
fault_program.addLine('Set eirh1_AF_CH = a2_AF_EIR_h*FF_CH_h')
|
3947
|
+
fault_program.addLine('Set eirh2_AF_CH = a3_AF_EIR_h*FF_CH_h*FF_CH_h')
|
3948
|
+
fault_program.addLine('Set p_CH_COP_h = Y_CH_COP_h*(eirh0_AF_CH + (eirh1_AF_CH) + (eirh2_AF_CH))')
|
3949
|
+
|
3950
|
+
fault_program.addLine("Set FF_AF_h = 1.0 + #{heat_airflow_rated_defect_ratio[speed].round(3)}")
|
3951
|
+
fault_program.addLine('Set FF_AF_comb_h = FF_CH_h * FF_AF_h')
|
3952
|
+
|
3953
|
+
fault_program.addLine('Set qh0_AF_comb = a1_AF_Qgr_h')
|
3954
|
+
fault_program.addLine('Set qh1_AF_comb = a2_AF_Qgr_h*FF_AF_comb_h')
|
3955
|
+
fault_program.addLine('Set qh2_AF_comb = a3_AF_Qgr_h*FF_AF_comb_h*FF_AF_comb_h')
|
3956
|
+
fault_program.addLine('Set p_AF_Q_h = qh0_AF_comb+(qh1_AF_comb)+(qh2_AF_comb)')
|
3957
|
+
|
3958
|
+
fault_program.addLine('Set eirh0_AF_comb = a1_AF_EIR_h')
|
3959
|
+
fault_program.addLine('Set eirh1_AF_comb = a2_AF_EIR_h*FF_AF_comb_h')
|
3960
|
+
fault_program.addLine('Set eirh2_AF_comb = a3_AF_EIR_h*FF_AF_comb_h*FF_AF_comb_h')
|
3961
|
+
fault_program.addLine('Set p_AF_COP_h = 1.0/(eirh0_AF_comb+(eirh1_AF_comb)+(eirh2_AF_comb))')
|
3962
|
+
|
3963
|
+
fault_program.addLine("Set #{heat_cap_fff_act.name} = (p_CH_Q_h * p_AF_Q_h)")
|
3964
|
+
fault_program.addLine("Set #{heat_eir_fff_act.name} = 1.0 / (p_CH_COP_h * p_AF_COP_h)")
|
3965
|
+
end
|
3966
|
+
end
|
3967
|
+
program_calling_manager = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
|
3968
|
+
program_calling_manager.setName("#{obj_name} program manager")
|
3969
|
+
program_calling_manager.setCallingPoint('BeginTimestepBeforePredictor')
|
3970
|
+
program_calling_manager.addProgram(fault_program)
|
3971
|
+
end
|
3972
|
+
|
4174
3973
|
def self.get_default_gshp_pump_power()
|
4175
3974
|
return 30.0 # W/ton, per ANSI/RESNET/ICC 301-2019 Section 4.4.5 (closed loop)
|
4176
3975
|
end
|
4177
3976
|
|
4178
|
-
def self.
|
4179
|
-
|
4180
|
-
|
4181
|
-
return
|
4182
|
-
end
|
3977
|
+
def self.apply_shared_systems(hpxml = true)
|
3978
|
+
applied_clg = apply_shared_cooling_systems(hpxml)
|
3979
|
+
applied_htg = apply_shared_heating_systems(hpxml)
|
3980
|
+
return unless (applied_clg || applied_htg)
|
4183
3981
|
|
4184
|
-
|
4185
|
-
|
4186
|
-
|
4187
|
-
|
3982
|
+
# Remove WLHP if not serving heating nor cooling
|
3983
|
+
hpxml.heat_pumps.each do |hp|
|
3984
|
+
next unless hp.heat_pump_type == HPXML::HVACTypeHeatPumpWaterLoopToAir
|
3985
|
+
next if hp.fraction_heat_load_served > 0
|
3986
|
+
next if hp.fraction_cool_load_served > 0
|
3987
|
+
|
3988
|
+
hp.delete
|
3989
|
+
end
|
4188
3990
|
|
4189
3991
|
# Remove any orphaned HVAC distributions
|
4190
3992
|
hpxml.hvac_distributions.each do |hvac_distribution|
|
4191
3993
|
hvac_systems = []
|
4192
|
-
|
3994
|
+
hpxml.hvac_systems.each do |hvac_system|
|
4193
3995
|
next if hvac_system.distribution_system_idref.nil?
|
4194
3996
|
next unless hvac_system.distribution_system_idref == hvac_distribution.id
|
4195
3997
|
|
@@ -4202,12 +4004,14 @@ class HVAC
|
|
4202
4004
|
end
|
4203
4005
|
|
4204
4006
|
def self.apply_shared_cooling_systems(hpxml)
|
4007
|
+
applied = false
|
4205
4008
|
hpxml.cooling_systems.each do |cooling_system|
|
4206
4009
|
next unless cooling_system.is_shared_system
|
4207
4010
|
|
4011
|
+
applied = true
|
4012
|
+
wlhp = nil
|
4208
4013
|
distribution_system = cooling_system.distribution_system
|
4209
4014
|
distribution_type = distribution_system.distribution_system_type
|
4210
|
-
hydronic_and_air_type = distribution_system.hydronic_and_air_type
|
4211
4015
|
|
4212
4016
|
# Calculate air conditioner SEER equivalent
|
4213
4017
|
n_dweq = cooling_system.number_of_units_served.to_f
|
@@ -4219,17 +4023,16 @@ class HVAC
|
|
4219
4023
|
cap = cooling_system.cooling_capacity
|
4220
4024
|
chiller_input = UnitConversions.convert(cooling_system.cooling_efficiency_kw_per_ton * UnitConversions.convert(cap, 'Btu/hr', 'ton'), 'kW', 'W')
|
4221
4025
|
if distribution_type == HPXML::HVACDistributionTypeHydronic
|
4222
|
-
|
4223
|
-
|
4224
|
-
|
4225
|
-
aux_dweq = cooling_system.fan_coil_watts
|
4226
|
-
elsif hydronic_and_air_type == HPXML::HydronicAndAirTypeWaterLoopHeatPump
|
4227
|
-
aux_dweq = cooling_system.wlhp_cooling_capacity / cooling_system.wlhp_cooling_efficiency_eer
|
4026
|
+
if distribution_system.hydronic_type == HPXML::HydronicTypeWaterLoop
|
4027
|
+
wlhp = hpxml.heat_pumps.select { |hp| hp.heat_pump_type == HPXML::HVACTypeHeatPumpWaterLoopToAir }[0]
|
4028
|
+
aux_dweq = wlhp.cooling_capacity / wlhp.cooling_efficiency_eer
|
4228
4029
|
else
|
4229
|
-
|
4030
|
+
aux_dweq = 0.0
|
4031
|
+
end
|
4032
|
+
elsif distribution_type == HPXML::HVACDistributionTypeAir
|
4033
|
+
if distribution_system.air_type == HPXML::AirTypeFanCoil
|
4034
|
+
aux_dweq = cooling_system.fan_coil_watts
|
4230
4035
|
end
|
4231
|
-
else
|
4232
|
-
fail "Unexpected distribution type '#{distribution_type}' for chiller."
|
4233
4036
|
end
|
4234
4037
|
# ANSI/RESNET/ICC 301-2019 Equation 4.4-2
|
4235
4038
|
seer_eq = (cap - 3.41 * aux - 3.41 * aux_dweq * n_dweq) / (chiller_input + aux + aux_dweq * n_dweq)
|
@@ -4237,16 +4040,12 @@ class HVAC
|
|
4237
4040
|
elsif cooling_system.cooling_system_type == HPXML::HVACTypeCoolingTower
|
4238
4041
|
|
4239
4042
|
# Cooling tower w/ water loop heat pump
|
4240
|
-
if distribution_type == HPXML::
|
4241
|
-
|
4242
|
-
|
4243
|
-
wlhp_cap =
|
4244
|
-
wlhp_input = wlhp_cap /
|
4245
|
-
else
|
4246
|
-
fail "Unexpected distribution type '#{hydronic_and_air_type}' for cooling tower."
|
4043
|
+
if distribution_type == HPXML::HVACDistributionTypeHydronic
|
4044
|
+
if distribution_system.hydronic_type == HPXML::HydronicTypeWaterLoop
|
4045
|
+
wlhp = hpxml.heat_pumps.select { |hp| hp.heat_pump_type == HPXML::HVACTypeHeatPumpWaterLoopToAir }[0]
|
4046
|
+
wlhp_cap = wlhp.cooling_capacity
|
4047
|
+
wlhp_input = wlhp_cap / wlhp.cooling_efficiency_eer
|
4247
4048
|
end
|
4248
|
-
else
|
4249
|
-
fail "Unexpected hydronic distribution type '#{distribution_type}' for cooling tower."
|
4250
4049
|
end
|
4251
4050
|
# ANSI/RESNET/ICC 301-2019 Equation 4.4-3
|
4252
4051
|
seer_eq = (wlhp_cap - 3.41 * aux / n_dweq) / (wlhp_input + aux / n_dweq)
|
@@ -4255,36 +4054,75 @@ class HVAC
|
|
4255
4054
|
fail "Unexpected cooling system type '#{cooling_system.cooling_system_type}'."
|
4256
4055
|
end
|
4257
4056
|
|
4057
|
+
if seer_eq <= 0
|
4058
|
+
fail "Negative SEER equivalent calculated for cooling system '#{cooling_system.id}', double check inputs."
|
4059
|
+
end
|
4060
|
+
|
4258
4061
|
cooling_system.cooling_system_type = HPXML::HVACTypeCentralAirConditioner
|
4259
|
-
cooling_system.cooling_efficiency_seer = seer_eq
|
4062
|
+
cooling_system.cooling_efficiency_seer = seer_eq.round(2)
|
4063
|
+
cooling_system.cooling_efficiency_kw_per_ton = nil
|
4260
4064
|
cooling_system.cooling_capacity = nil # Autosize the equipment
|
4065
|
+
cooling_system.is_shared_system = false
|
4066
|
+
cooling_system.number_of_units_served = nil
|
4067
|
+
cooling_system.shared_loop_watts = nil
|
4068
|
+
cooling_system.shared_loop_motor_efficiency = nil
|
4069
|
+
cooling_system.fan_coil_watts = nil
|
4261
4070
|
|
4262
4071
|
# Assign new distribution system to air conditioner
|
4263
4072
|
if distribution_type == HPXML::HVACDistributionTypeHydronic
|
4264
|
-
|
4265
|
-
|
4266
|
-
|
4267
|
-
|
4268
|
-
|
4269
|
-
|
4270
|
-
|
4271
|
-
|
4272
|
-
|
4273
|
-
|
4274
|
-
|
4073
|
+
if distribution_system.hydronic_type == HPXML::HydronicTypeWaterLoop
|
4074
|
+
# Assign WLHP air distribution
|
4075
|
+
cooling_system.distribution_system_idref = wlhp.distribution_system_idref
|
4076
|
+
wlhp.fraction_cool_load_served = 0.0
|
4077
|
+
wlhp.fraction_heat_load_served = 0.0
|
4078
|
+
else
|
4079
|
+
# Assign DSE=1
|
4080
|
+
hpxml.hvac_distributions.add(id: "#{cooling_system.id}AirDistributionSystem",
|
4081
|
+
distribution_system_type: HPXML::HVACDistributionTypeDSE,
|
4082
|
+
annual_cooling_dse: 1.0,
|
4083
|
+
annual_heating_dse: 1.0)
|
4084
|
+
cooling_system.distribution_system_idref = hpxml.hvac_distributions[-1].id
|
4085
|
+
end
|
4086
|
+
elsif (distribution_type == HPXML::HVACDistributionTypeAir) && (distribution_system.air_type == HPXML::AirTypeFanCoil)
|
4087
|
+
# Convert "fan coil" air distribution system to "regular velocity"
|
4088
|
+
if distribution_system.hvac_systems.size > 1
|
4089
|
+
# Has attached heating system, so create a copy specifically for the cooling system
|
4090
|
+
hpxml.hvac_distributions << distribution_system.dup
|
4091
|
+
hpxml.hvac_distributions[-1].id += "#{cooling_system.id}AirDistributionSystem"
|
4092
|
+
cooling_system.distribution_system_idref = hpxml.hvac_distributions[-1].id
|
4093
|
+
end
|
4094
|
+
hpxml.hvac_distributions[-1].air_type = HPXML::AirTypeRegularVelocity
|
4095
|
+
if hpxml.hvac_distributions[-1].duct_leakage_measurements.select { |lm| (lm.duct_type == HPXML::DuctTypeSupply) && (lm.duct_leakage_total_or_to_outside == HPXML::DuctLeakageToOutside) }.size == 0
|
4096
|
+
# Assign zero supply leakage
|
4097
|
+
hpxml.hvac_distributions[-1].duct_leakage_measurements.add(duct_type: HPXML::DuctTypeSupply,
|
4098
|
+
duct_leakage_units: HPXML::UnitsCFM25,
|
4099
|
+
duct_leakage_value: 0,
|
4100
|
+
duct_leakage_total_or_to_outside: HPXML::DuctLeakageToOutside)
|
4101
|
+
end
|
4102
|
+
if hpxml.hvac_distributions[-1].duct_leakage_measurements.select { |lm| (lm.duct_type == HPXML::DuctTypeReturn) && (lm.duct_leakage_total_or_to_outside == HPXML::DuctLeakageToOutside) }.size == 0
|
4103
|
+
# Assign zero return leakage
|
4104
|
+
hpxml.hvac_distributions[-1].duct_leakage_measurements.add(duct_type: HPXML::DuctTypeReturn,
|
4105
|
+
duct_leakage_units: HPXML::UnitsCFM25,
|
4106
|
+
duct_leakage_value: 0,
|
4107
|
+
duct_leakage_total_or_to_outside: HPXML::DuctLeakageToOutside)
|
4108
|
+
end
|
4275
4109
|
end
|
4276
4110
|
end
|
4111
|
+
|
4112
|
+
return applied
|
4277
4113
|
end
|
4278
4114
|
|
4279
4115
|
def self.apply_shared_heating_systems(hpxml)
|
4116
|
+
applied = false
|
4280
4117
|
hpxml.heating_systems.each do |heating_system|
|
4281
4118
|
next unless heating_system.is_shared_system
|
4282
4119
|
|
4120
|
+
applied = true
|
4283
4121
|
distribution_system = heating_system.distribution_system
|
4284
4122
|
distribution_type = distribution_system.distribution_system_type
|
4285
|
-
|
4123
|
+
hydronic_type = distribution_system.hydronic_type
|
4286
4124
|
|
4287
|
-
if heating_system.heating_system_type == HPXML::HVACTypeBoiler &&
|
4125
|
+
if heating_system.heating_system_type == HPXML::HVACTypeBoiler && hydronic_type.to_s == HPXML::HydronicTypeWaterLoop
|
4288
4126
|
|
4289
4127
|
# Shared boiler w/ water loop heat pump
|
4290
4128
|
# Per ANSI/RESNET/ICC 301-2019 Section 4.4.7.2, model as:
|
@@ -4293,24 +4131,125 @@ class HVAC
|
|
4293
4131
|
fraction_heat_load_served = heating_system.fraction_heat_load_served
|
4294
4132
|
|
4295
4133
|
# Heat pump
|
4296
|
-
|
4297
|
-
|
4298
|
-
|
4299
|
-
|
4300
|
-
heating_efficiency_cop: heating_system.wlhp_heating_efficiency_cop,
|
4301
|
-
fraction_heat_load_served: fraction_heat_load_served * (1.0 / heating_system.wlhp_heating_efficiency_cop),
|
4302
|
-
fraction_cool_load_served: 0.0)
|
4134
|
+
# If this approach is ever removed, also remove code in HVACSizing.apply_hvac_loads()
|
4135
|
+
wlhp = hpxml.heat_pumps.select { |hp| hp.heat_pump_type == HPXML::HVACTypeHeatPumpWaterLoopToAir }[0]
|
4136
|
+
wlhp.fraction_heat_load_served = fraction_heat_load_served * (1.0 / wlhp.heating_efficiency_cop)
|
4137
|
+
wlhp.fraction_cool_load_served = 0.0
|
4303
4138
|
|
4304
4139
|
# Boiler
|
4305
|
-
heating_system.
|
4306
|
-
heating_system.fraction_heat_load_served = fraction_heat_load_served * (1.0 - 1.0 / heating_system.wlhp_heating_efficiency_cop)
|
4307
|
-
heating_system.distribution_system_idref = "#{heating_system.id}_Baseboard"
|
4308
|
-
hpxml.hvac_distributions.add(id: heating_system.distribution_system_idref,
|
4309
|
-
distribution_system_type: HPXML::HVACDistributionTypeHydronic,
|
4310
|
-
hydronic_type: HPXML::HydronicTypeBaseboard)
|
4140
|
+
heating_system.fraction_heat_load_served = fraction_heat_load_served * (1.0 - 1.0 / wlhp.heating_efficiency_cop)
|
4311
4141
|
end
|
4312
4142
|
|
4313
4143
|
heating_system.heating_capacity = nil # Autosize the equipment
|
4314
4144
|
end
|
4145
|
+
|
4146
|
+
return applied
|
4147
|
+
end
|
4148
|
+
|
4149
|
+
def self.set_num_speeds(hvac_system)
|
4150
|
+
hvac_ap = hvac_system.additional_properties
|
4151
|
+
|
4152
|
+
if hvac_system.is_a?(HPXML::CoolingSystem) && (hvac_system.cooling_system_type == HPXML::HVACTypeRoomAirConditioner)
|
4153
|
+
hvac_ap.num_speeds = 1
|
4154
|
+
elsif (hvac_system.is_a?(HPXML::CoolingSystem) && (hvac_system.cooling_system_type == HPXML::HVACTypeMiniSplitAirConditioner)) ||
|
4155
|
+
(hvac_system.is_a?(HPXML::HeatPump) && (hvac_system.heat_pump_type == HPXML::HVACTypeHeatPumpMiniSplit))
|
4156
|
+
hvac_ap.speed_indices = [1, 3, 5, 9] # Speeds we model
|
4157
|
+
hvac_ap.num_speeds = hvac_ap.speed_indices.size
|
4158
|
+
elsif hvac_system.compressor_type == HPXML::HVACCompressorTypeSingleStage
|
4159
|
+
hvac_ap.num_speeds = 1
|
4160
|
+
elsif hvac_system.compressor_type == HPXML::HVACCompressorTypeTwoStage
|
4161
|
+
hvac_ap.num_speeds = 2
|
4162
|
+
elsif hvac_system.compressor_type == HPXML::HVACCompressorTypeVariableSpeed
|
4163
|
+
hvac_ap.num_speeds = 4
|
4164
|
+
end
|
4165
|
+
end
|
4166
|
+
|
4167
|
+
def self.calc_rated_airflow(capacity, rated_cfm_per_ton, capacity_ratio)
|
4168
|
+
return UnitConversions.convert(capacity, 'Btu/hr', 'ton') * UnitConversions.convert(rated_cfm_per_ton, 'cfm', 'm^3/s') * capacity_ratio
|
4169
|
+
end
|
4170
|
+
|
4171
|
+
def self.is_central_air_conditioner_and_furnace(hpxml, heating_system, cooling_system)
|
4172
|
+
if not (hpxml.heating_systems.include?(heating_system) && (heating_system.heating_system_type == HPXML::HVACTypeFurnace))
|
4173
|
+
return false
|
4174
|
+
end
|
4175
|
+
if not (hpxml.cooling_systems.include?(cooling_system) && (cooling_system.cooling_system_type == HPXML::HVACTypeCentralAirConditioner))
|
4176
|
+
return false
|
4177
|
+
end
|
4178
|
+
|
4179
|
+
return true
|
4180
|
+
end
|
4181
|
+
|
4182
|
+
def self.get_hpxml_hvac_systems(hpxml)
|
4183
|
+
# Returns a list of heating/cooling systems, incorporating whether
|
4184
|
+
# multiple systems are connected to the same distribution system
|
4185
|
+
# (e.g., a furnace + central air conditioner w/ the same ducts).
|
4186
|
+
hvac_systems = []
|
4187
|
+
|
4188
|
+
hpxml.cooling_systems.each do |cooling_system|
|
4189
|
+
heating_system = nil
|
4190
|
+
if is_central_air_conditioner_and_furnace(hpxml, cooling_system.attached_heating_system, cooling_system)
|
4191
|
+
heating_system = cooling_system.attached_heating_system
|
4192
|
+
end
|
4193
|
+
hvac_systems << { cooling: cooling_system,
|
4194
|
+
heating: heating_system }
|
4195
|
+
end
|
4196
|
+
|
4197
|
+
hpxml.heating_systems.each do |heating_system|
|
4198
|
+
if is_central_air_conditioner_and_furnace(hpxml, heating_system, heating_system.attached_cooling_system)
|
4199
|
+
next # Already processed combined AC+furnace
|
4200
|
+
end
|
4201
|
+
hvac_systems << { cooling: nil,
|
4202
|
+
heating: heating_system }
|
4203
|
+
end
|
4204
|
+
|
4205
|
+
hpxml.heat_pumps.each do |heat_pump|
|
4206
|
+
hvac_systems << { cooling: heat_pump,
|
4207
|
+
heating: heat_pump }
|
4208
|
+
end
|
4209
|
+
|
4210
|
+
return hvac_systems
|
4211
|
+
end
|
4212
|
+
|
4213
|
+
def self.ensure_nonzero_sizing_values(hpxml)
|
4214
|
+
min_capacity = 1.0 # Btuh
|
4215
|
+
min_airflow = 3.0 # cfm; E+ min airflow is 0.001 m3/s
|
4216
|
+
hpxml.heating_systems.each do |htg_sys|
|
4217
|
+
htg_sys.heating_capacity = [htg_sys.heating_capacity, min_capacity].max
|
4218
|
+
htg_sys.heating_airflow_cfm = [htg_sys.heating_airflow_cfm, min_airflow].max
|
4219
|
+
end
|
4220
|
+
hpxml.cooling_systems.each do |clg_sys|
|
4221
|
+
clg_sys.cooling_capacity = [clg_sys.cooling_capacity, min_capacity].max
|
4222
|
+
clg_sys.cooling_airflow_cfm = [clg_sys.cooling_airflow_cfm, min_airflow].max
|
4223
|
+
end
|
4224
|
+
hpxml.heat_pumps.each do |hp_sys|
|
4225
|
+
hp_sys.cooling_capacity = [hp_sys.cooling_capacity, min_capacity].max
|
4226
|
+
hp_sys.cooling_airflow_cfm = [hp_sys.cooling_airflow_cfm, min_airflow].max
|
4227
|
+
hp_sys.additional_properties.cooling_capacity_sensible = [hp_sys.additional_properties.cooling_capacity_sensible, min_capacity].max
|
4228
|
+
hp_sys.heating_capacity = [hp_sys.heating_capacity, min_capacity].max
|
4229
|
+
hp_sys.heating_airflow_cfm = [hp_sys.heating_airflow_cfm, min_airflow].max
|
4230
|
+
if not hp_sys.heating_capacity_17F.nil?
|
4231
|
+
hp_sys.heating_capacity_17F = [hp_sys.heating_capacity_17F, min_capacity].max
|
4232
|
+
end
|
4233
|
+
if not hp_sys.backup_heating_capacity.nil?
|
4234
|
+
hp_sys.backup_heating_capacity = [hp_sys.backup_heating_capacity, min_capacity].max
|
4235
|
+
end
|
4236
|
+
end
|
4237
|
+
end
|
4238
|
+
|
4239
|
+
def self.get_dehumidifier_default_values(capacity)
|
4240
|
+
rh_setpoint = 0.6
|
4241
|
+
if capacity <= 25.0
|
4242
|
+
ief = 0.79
|
4243
|
+
elsif capacity <= 35.0
|
4244
|
+
ief = 0.95
|
4245
|
+
elsif capacity <= 54.0
|
4246
|
+
ief = 1.04
|
4247
|
+
elsif capacity < 75.0
|
4248
|
+
ief = 1.20
|
4249
|
+
else
|
4250
|
+
ief = 1.82
|
4251
|
+
end
|
4252
|
+
|
4253
|
+
return { rh_setpoint: rh_setpoint, ief: ief }
|
4315
4254
|
end
|
4316
4255
|
end
|