Skip to content

Commit fc43787

Browse files
committed
Squashed 'resources/hpxml-measures/' changes from 5184e01c5e..5554ec0524
5554ec0524 didn't save conflict fix fabacd22e3 Merge remote-tracking branch 'origin/build-res-hpxml-v3' into build-res-hpxml-v3-hes 48a69e938a bugfix for subsurfaces on adiabatic surfaces d7fa5bd3f5 Remove water heater first hour rating argument. 448937b2e7 add puma argument and pass to xml 68ec5a9755 Remove invalid roof material type choices. e2cef45d28 Merge branch 'master' into build-res-hpxml-v3 412c1536b8 Improve a few argument descriptions. 8ff9f1b44e Merge pull request #784 from NREL/dhw_usage_bin 26fe68b8cf Latest results. 318431de2d Revise orientation argument description. 2b6749e7f1 Fix sample files. e4727623fa Small change to docs. 4087b3150b Update changelog. 592e122bc4 First pass. 5569f43051 Latest results. 6ca25b50b0 Merge branch 'master' into build-res-hpxml-v3 ce85f47bb6 Merge pull request #778 from NREL/interior_finish 9dd9d9d992 Merge branch 'interior_finish' of https://github.com/NREL/OpenStudio-HPXML into interior_finish 8a33ac674d Simplify a little. 621e2aeb78 Latest results. ae48c12615 Bugfix. fc647c58b9 Merge branch 'interior_finish' of https://github.com/NREL/OpenStudio-HPXML into interior_finish 760a6ef959 Update a couple sample files. 0bdfcdeacd Latest results. de32dc887e Clean up Material classes and switch to kwargs. c99acebdf5 Exclude warning. 6101a68a3c Merge branch 'interior_finish' of https://github.com/NREL/OpenStudio-HPXML into interior_finish 2d39a47bb6 Simplify code. Use solar abs and emittance values from ASHRAE 140 for interior finish materials. 464cccfff0 Merge remote-tracking branch 'origin/build-res-hpxml-v3' into build-res-hpxml-v3-hes ef7e042b8d Latest results. d58542baa0 Update test values. 768ff3ccc1 Tweak sample files. 5d4e5f7404 First pass. 216e7b13c9 Merge branch 'master' into build-res-hpxml-v3 1522f9e298 Merge pull request #771 from NREL/build-res-hpxml-v3-windows 6d27600714 Merge pull request #770 from NREL/tweak_sample_files fac5a44fd9 Latest results. 551e336261 Merge branch 'build-res-hpxml-v3' of https://github.com/NREL/OpenStudio-HPXML into build-res-hpxml-v3-windows 32e2c7287f Latest results. 0ed7e855bc Merge branch 'tweak_sample_files' of https://github.com/NREL/OpenStudio-HPXML into build-res-hpxml-v3-windows 70ec879bcf Try to generate measure xml multiple times. 524ca98e6b Fix test. 0b16236638 Merge branch 'tweak_sample_files' of https://github.com/NREL/OpenStudio-HPXML into build-res-hpxml-v3-windows d65fd6afe3 Ports over the latest window area code from ResStock (including the small bugfix in #597). c84e98c7c4 Minor tweaks to sample files. 644dd3f041 Latest results. 0636162450 Merge branch 'master' into build-res-hpxml-v3 39eaf1b6d9 Merge pull request #769 from NREL/siding_none f1b536ccce Latest results. 305ba2b54d Fix sample file and update EPvalidator.xml. a0b65fd971 First pass. fa8693e595 Merge pull request #762 from NREL/fan_system_model ca2e7819e9 Remove FIXMEs d08b8e6065 Re-enable asserts. c6bc835744 Merge branch 'fan_system_model' of https://github.com/NREL/OpenStudio-HPXML into fan_system_model b917947559 Update Changelog.md and add TODOs. 1daf1c7cf7 Latest results. 6eb2a8eaba Latest results. 00801cf912 Ensure we never do integer division. a71015e6bd Merge branch 'fan_system_model' of https://github.com/NREL/OpenStudio-HPXML into fan_system_model ff1dfaadda Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into fan_system_model 9924018eaf Fix fan operate for fan coil. 7618bc1f83 Merge pull request #768 from NREL/build-res-hpxml-v3-vacancy-fixes e6a340834a Merge branch 'build-res-hpxml-v3-vacancy-fixes' of github.com:NREL/OpenStudio-HPXML into build-res-hpxml-v3-vacancy-fixes d2140b8b81 Improve vacancy testing even further. 34a69cc2b1 Latest results. 32e18bb685 Update tasks and test files. fad659a939 Update vacancy method for wrap around years. 3591d1c840 Error checking for incomplete vacancy args. 2848e0fca2 Merge branch 'master' into build-res-hpxml-v3 5d318cd6f9 Merge pull request #767 from NREL/reporting_measure_register_values 6781ab87a0 Merge branch 'master' into build-res-hpxml-v3 01d6b1b6cd Need to update outputs section too. c058375f41 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into reporting_measure_register_values 11e31275ba Fix measures.xmls and add better error checking. b240cac6eb Update Changelog.md e9444dbe6f Merge pull request #764 from NREL/allow_ceer 46c758c36c Latest results. a04aab0bbf address comments 642947059f Update new HVAC test. 0d486dc1cd Clarify docs. 72649984de Fix EMS sensor name. a41eb40353 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into fan_system_model 642acf1b43 No longer using FanVariableVolume object. aa622c4474 Handle multi-speed systems. 09e04a3292 Update Changelog.md aea6428aa4 Register all outputs from the annual CSV with the OS runner (for use in, e.g., PAT). 62ed038f58 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into allow_ceer a02e9c3a06 Merge branch 'master' into build-res-hpxml-v3 c9e17fa25f Update to most recent create multifamily geometry method. 5e7ab71182 Merge pull request #707 from NREL/gshp-installation-quality 0ba6d727dd Latest results. 5967f50b3b Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into gshp-installation-quality 7023de2595 Removes a few HVAC IQ sample files and renames hvac-install-quality-all-foo.xml files to hvac-install-quality-foo.xml 63ae696601 doc updates and bugfix 40792de798 Simplify logic. cd54d03eff Adjustments to test osws and mech vent args. 862d056638 Minor docs update. 8601b1021f fix changes caused by merging de053f828b Cleanup comments 6698525204 Simplified code similarly for other HVAC IQ inputs (blower fan, airflow). fc8b4d3120 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into gshp-installation-quality 713e829aa1 Removes IsPackagedSystem since split systems can still have pre-charged line sets. We'll just assume that if someone is providing a non-zero value, it makes sense for their system type. Added some documentation to clarify. 3e3ee5719c Merge branch 'master' into build-res-hpxml-v3 fc08a1433f Merge pull request #765 from NREL/default_vent_fan_power c0b0d06a48 Latest results. 7f04359348 minor change and Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into allow_ceer 8e56249cd3 Allows defaulting of mechanical ventilation fan power (by type). e6e5c15e28 Merge pull request #674 from NREL/hvac_dhw_default_efficiencies 08db7a78c6 Update Changelog.md 47c8de4a6e Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies 7befb82d26 Update projects 3df7ce7b06 Latest results. c4228096c6 update the default efficiency of the electric type heating systems a7813c5a9b Latest results. ef6cdab2f6 allow ceer 18024d07f4 Latest results. 9c280897cf Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into fan_system_model 17f6ebc698 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies 8512de8c1c Temporarily disable asserts so all tests run. 1f8403e4fc Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into gshp-installation-quality f53765eff2 Merge pull request #763 from NREL/mech_vent_precond_energy_only 3ce2810d6a Latest results. a2c4fb5ddb Code changes from NREL/OpenStudio-HPXML#753, energy impact only. 87c2b51cdc Fix test. 5cac9dbd2a address comments f315cd2153 Try replacing evap cooler VariableVolume fan too. aadfde3b04 First pass. c8872d6cb7 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies 95409f512f address comments 4c8870a3ca Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies ce42985088 doc update 824d6959e5 add invalid test 31901ae871 Update Changelog.md 87144acbab Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into gshp-installation-quality 3cdc84532b Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies 6e5f10028e fix test_fireplaces 183acefa2d update test_defaults fe1e69a8b0 Merge branch 'hvac_dhw_default_efficiencies' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies ecae4c26e4 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies dd56e58a76 update fireplace/stove efficiency defaulting 19e7ad5b0c Latest results. 3a69e94324 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into gshp-installation-quality 276f9403e8 Latest results. 8601281b4e Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies 3911009322 Latest results. 6d0c3755a0 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies 277d71c55c cleanup + fix 7a55ea4b01 Merge branch 'gshp-installation-quality' of https://github.com/NREL/OpenStudio-HPXML into gshp-installation-quality d50bdd14e1 cleanup 440f6eeccd cleanup for heating hvacsizing method a274d8ef9b Latest results. 7a20077d2c One more. 5f2a4b8620 Manually fix code that was previously accidentally reverted. cb9962ec3e Merge branch 'os_v320' of https://github.com/NREL/OpenStudio-HPXML into gshp-installation-quality 7b8bb7ca92 Merge branch 'os_v320' of https://github.com/NREL/OpenStudio-HPXML into gshp-installation-quality 4976c3dcf0 Merge branch 'os_v320' of https://github.com/NREL/OpenStudio-HPXML into gshp-installation-quality 544a15ad35 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies beefde88b6 update documentation 4948ed5edc Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies fc1faeb7f0 coarse efficiency defaulting for fireplace/stove Use energyplus.rb for fuel type mapping a8f7a9304c revert merging 814183b017 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into gshp-installation-quality 0e94275b49 Add configuration of packaged system with 0 charge defect for schematron test ca2a92b9d6 Merge branch 'os_v320' of https://github.com/NREL/OpenStudio-HPXML into gshp-installation-quality f7fb92967c delete repeating rule 6f9f06da1d only gshp to use is_packaged_system 0ab14df133 fix validator. 53b1794cf2 update test file multiple 5cb9bd19e4 Add packaged system element c3a0676212 Add test for gshp iq a531df874d Merge branch 'os_v320' of https://github.com/NREL/OpenStudio-HPXML into gshp-installation-quality 370299fbc1 Latest results. 09efbc4f09 Merge branch 'os_v320' of https://github.com/NREL/OpenStudio-HPXML into gshp-installation-quality 05c5934a46 Latest results. 48da5c8314 Merge branch 'hvac_dhw_default_efficiencies' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies b9d4fd4e21 code cleanup and add more tests 4ca0de4789 Latest results. bb4e923461 fix test_furnaces 4e2f3ab4c3 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies a25e7204cc Merge branch 'os_v320' of https://github.com/NREL/OpenStudio-HPXML into gshp-installation-quality 72ed16096e Added clarification to the docs about packaged vs split GSHPs systems. (Also updated it to remove the "zero only" limitation while I'm in there.) cdc0bc8028 add charge defect ratio to gshp ee5afad48a fix base-misc-defaults.xml 631235b169 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies 4bdbd77d33 pick up the rest of the initial comments 2255a1a293 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies 3ad035b7e8 pick up some of the initial comments 21d7ecb8e9 another documentation update f6c4f7c3dd update documentation f0e0c56b5e revert assertions for tankless and heatpump water heaters 8a0d1acd33 remove Fixmes 072c0f2ea4 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies 5955f3ea88 update hpxml for water heaters and change the assertions for water heater efficiencies 0728f7a1f9 update EPvalidator for water heating systems 861ef8a7b5 Bugfix and update EPvalidator.xml and hpxml.rb 8bf095e758 update test_defaults 2b0fe12a1e run tasks.rb fdc7aadff6 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies 6a477f99a8 Merge branch 'master' of https://github.com/NREL/OpenStudio-HPXML into hvac_dhw_default_efficiencies 2e50326547 first pass git-subtree-dir: resources/hpxml-measures git-subtree-split: 5554ec0524f8c64f64bb5dd6e44e220549b33496
1 parent 702d2e2 commit fc43787

File tree

804 files changed

+21726
-16766
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

804 files changed

+21726
-16766
lines changed

BuildResidentialHPXML/measure.rb

Lines changed: 75 additions & 37 deletions
Large diffs are not rendered by default.

BuildResidentialHPXML/measure.xml

Lines changed: 657 additions & 675 deletions
Large diffs are not rendered by default.

BuildResidentialHPXML/resources/geometry.rb

Lines changed: 128 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -910,20 +910,14 @@ def self.create_windows_and_skylights(runner:,
910910

911911
# Split any surfaces that have doors so that we can ignore them when adding windows
912912
facades.each do |facade|
913-
surfaces_to_add = []
914913
wall_surfaces[facade].each do |surface|
915914
next if surface.subSurfaces.size == 0
916915

917916
new_surfaces = surface.splitSurfaceForSubSurfaces
918917
new_surfaces.each do |new_surface|
919-
next if new_surface.subSurfaces.size > 0
920-
921-
surfaces_to_add << new_surface
918+
wall_surfaces[facade] << new_surface
922919
end
923920
end
924-
surfaces_to_add.each do |surface_to_add|
925-
wall_surfaces[facade] << surface_to_add
926-
end
927921
end
928922

929923
# Windows
@@ -945,7 +939,6 @@ def self.create_windows_and_skylights(runner:,
945939
if not surface_avail_area.include? surface
946940
surface_avail_area[surface] = 0
947941
end
948-
next if surface.subSurfaces.size > 0
949942

950943
area = get_wall_area_for_windows(surface, min_wall_height_for_window, min_window_width, runner)
951944
surface_avail_area[surface] += area
@@ -974,69 +967,124 @@ def self.create_windows_and_skylights(runner:,
974967
else
975968
target_facade_areas[facade] += window_areas[facade]
976969
end
970+
end
977971

978-
next if target_facade_areas[facade] == 0
979-
980-
if target_facade_areas[facade] < min_single_window_area
981-
# If the total window area for the facade is less than the minimum window area,
982-
# set all of the window area to the surface with the greatest available wall area on any facade
983-
surface = surface_avail_area.max_by { |k, v| v }[0]
984-
next if get_facade_for_surface(surface) == facade
985-
next if surface_avail_area[surface] == facade_avail_area[facade]
986-
987-
surface_window_area[surface] += target_facade_areas[facade]
988-
989-
new_facade = get_facade_for_surface(surface)
990-
area_moved = target_facade_areas[facade]
991-
target_facade_areas[facade] = 0
992-
target_facade_areas[new_facade] = surface_window_area[surface]
993-
994-
runner.registerWarning("The #{facade} facade window area (#{area_moved.round(2)} ft2) is less than the minimum window area allowed (#{min_single_window_area.round(2)} ft2), and has been added to the #{new_facade} facade.")
995-
next
996-
end
997-
972+
facades.each do |facade|
998973
# Initial guess for wall of this facade
974+
next if facade_avail_area[facade] == 0
975+
999976
wall_surfaces[facade].each do |surface|
1000977
surface_window_area[surface] += surface_avail_area[surface] / facade_avail_area[facade] * target_facade_areas[facade]
1001978
end
1002979

1003980
# If window area for a surface is less than the minimum window area,
1004981
# set the window area to zero and proportionally redistribute to the
1005-
# other surfaces.
1006-
wall_surfaces[facade].each_with_index do |surface, surface_num|
1007-
next if surface_window_area[surface] >= min_single_window_area
982+
# other surfaces on that facade and unit.
983+
984+
# Check wall surface areas (by unit/space)
985+
model.getBuildingUnits.each do |unit|
986+
wall_surfaces[facade].each_with_index do |surface, surface_num|
987+
next if surface_window_area[surface] == 0
988+
next unless unit.spaces.include? surface.space.get # surface belongs to this unit
989+
next unless surface_window_area[surface] < min_single_window_area
990+
991+
# Future surfaces are those that have not yet been compared to min_single_window_area
992+
future_surfaces_area = 0
993+
wall_surfaces[facade].each_with_index do |future_surface, future_surface_num|
994+
next if future_surface_num <= surface_num
995+
next unless unit.spaces.include? future_surface.space.get
996+
997+
future_surfaces_area += surface_avail_area[future_surface]
998+
end
999+
next if future_surfaces_area == 0
10081000

1009-
removed_window_area = surface_window_area[surface]
1010-
surface_window_area[surface] = 0
1001+
removed_window_area = surface_window_area[surface]
1002+
surface_window_area[surface] = 0
10111003

1012-
# Future surfaces are those that have not yet been compared to min_single_window_area
1013-
future_surfaces_area = 0
1014-
wall_surfaces[facade].each_with_index do |future_surface, future_surface_num|
1015-
next if future_surface_num <= surface_num
1004+
wall_surfaces[facade].each_with_index do |future_surface, future_surface_num|
1005+
next if future_surface_num <= surface_num
1006+
next unless unit.spaces.include? future_surface.space.get
10161007

1017-
future_surfaces_area += surface_avail_area[future_surface]
1008+
surface_window_area[future_surface] += removed_window_area * surface_avail_area[future_surface] / future_surfaces_area
1009+
end
10181010
end
1019-
next if future_surfaces_area == 0
1011+
end
1012+
end
10201013

1021-
wall_surfaces[facade].each_with_index do |future_surface, future_surface_num|
1022-
next if future_surface_num <= surface_num
1014+
# Calculate facade areas for each unit
1015+
unit_facade_areas = {}
1016+
unit_wall_surfaces = {}
1017+
model.getBuildingUnits.each do |unit|
1018+
unit_facade_areas[unit] = {}
1019+
unit_wall_surfaces[unit] = {}
1020+
facades.each do |facade|
1021+
unit_facade_areas[unit][facade] = 0
1022+
unit_wall_surfaces[unit][facade] = []
1023+
wall_surfaces[facade].each do |surface|
1024+
next unless unit.spaces.include? surface.space.get
10231025

1024-
surface_window_area[future_surface] += removed_window_area * surface_window_area[future_surface] / future_surfaces_area
1026+
unit_facade_areas[unit][facade] += surface_window_area[surface]
1027+
unit_wall_surfaces[unit][facade] << surface
10251028
end
10261029
end
1030+
end
10271031

1028-
# Because the above process is calculated based on the order of surfaces, it's possible
1029-
# that we have less area for this facade than we should. If so, redistribute proportionally
1030-
# to all surfaces that have window area.
1031-
sum_window_area = 0
1032-
wall_surfaces[facade].each do |surface|
1033-
sum_window_area += surface_window_area[surface]
1032+
# if the sum of the window areas on the facade are < minimum, move to different facade
1033+
facades.each do |facade|
1034+
model.getBuildingUnits.each do |unit|
1035+
next if unit_facade_areas[unit][facade] == 0
1036+
next unless unit_facade_areas[unit][facade] < min_single_window_area
1037+
1038+
new_facade = unit_facade_areas[unit].max_by { |k, v| v }[0] # move to facade with largest window area
1039+
next if new_facade == facade # can't move to same facade
1040+
next if unit_facade_areas[unit][new_facade] <= unit_facade_areas[unit][facade] # only move to facade with >= window area
1041+
1042+
area_moved = unit_facade_areas[unit][facade]
1043+
unit_facade_areas[unit][facade] = 0
1044+
wall_surfaces[facade].each do |surface|
1045+
next unless unit.spaces.include? surface.space.get # surface is in this unit
1046+
1047+
surface_window_area[surface] = 0
1048+
end
1049+
1050+
unit_facade_areas[unit][new_facade] += area_moved
1051+
sum_window_area = 0
1052+
wall_surfaces[new_facade].each do |surface|
1053+
next unless unit.spaces.include? surface.space.get # surface is in this unit
1054+
1055+
sum_window_area += UnitConversions.convert(surface.grossArea, 'm^2', 'ft^2')
1056+
end
1057+
1058+
wall_surfaces[new_facade].each do |surface|
1059+
next unless unit.spaces.include? surface.space.get # surface is in this unit
1060+
1061+
split_window_area = area_moved * UnitConversions.convert(surface.grossArea, 'm^2', 'ft^2') / sum_window_area
1062+
surface_window_area[surface] += split_window_area
1063+
end
1064+
1065+
runner.registerWarning("The #{facade} facade window area (#{area_moved.round(2)} ft2) is less than the minimum window area allowed (#{min_single_window_area.round(2)} ft2), and has been added to the #{new_facade} facade.")
10341066
end
1035-
next if sum_window_area == 0
1036-
next if target_facade_areas[facade] < sum_window_area # for cases where window area was added from different facade
1067+
end
10371068

1038-
wall_surfaces[facade].each do |surface|
1039-
surface_window_area[surface] += surface_window_area[surface] / sum_window_area * (target_facade_areas[facade] - sum_window_area)
1069+
facades.each do |facade|
1070+
model.getBuildingUnits.each do |unit|
1071+
# Because the above process is calculated based on the order of surfaces, it's possible
1072+
# that we have less area for this facade than we should. If so, redistribute proportionally
1073+
# to all surfaces that have window area.
1074+
sum_window_area = 0
1075+
wall_surfaces[facade].each do |surface|
1076+
next unless unit.spaces.include? surface.space.get
1077+
1078+
sum_window_area += surface_window_area[surface]
1079+
end
1080+
next if sum_window_area == 0
1081+
next if unit_facade_areas[unit][facade] < sum_window_area # for cases where window area was added from different facade
1082+
1083+
wall_surfaces[facade].each do |surface|
1084+
next unless unit.spaces.include? surface.space.get
1085+
1086+
surface_window_area[surface] += surface_window_area[surface] / sum_window_area * (unit_facade_areas[unit][facade] - sum_window_area)
1087+
end
10401088
end
10411089
end
10421090

@@ -1137,6 +1185,11 @@ def self.create_windows_and_skylights(runner:,
11371185
end
11381186

11391187
def self.get_wall_area_for_windows(surface, min_wall_height_for_window, min_window_width, runner)
1188+
# Skip surfaces with doors
1189+
if surface.subSurfaces.size > 0
1190+
return 0.0
1191+
end
1192+
11401193
# Only allow on gable and rectangular walls
11411194
if not (is_rectangular_wall(surface) || is_gable_wall(surface))
11421195
return 0.0
@@ -1990,7 +2043,7 @@ def self.create_multifamily(runner:,
19902043
num_units_per_floor_actual = num_units_per_floor
19912044
above_ground_floors = num_floors
19922045

1993-
if (num_floors > 1) && (level != 'Bottom') && (foundation_height != 0.0)
2046+
if (num_floors > 1) && (level != 'Bottom') && (foundation_height > 0.0)
19942047
runner.registerWarning('Unit is not on the bottom floor, setting foundation height to 0.')
19952048
foundation_height = 0.0
19962049
end
@@ -1999,9 +2052,18 @@ def self.create_multifamily(runner:,
19992052
level = 'Bottom'
20002053
end
20012054

2002-
if (num_units_per_floor % 2 == 0) && ((corridor_position == 'Double-Loaded Interior') || (corridor_position == 'Double Exterior'))
2055+
if (num_floors <= 2) && (level == 'Middle')
2056+
runner.registerError("Building is #{num_floors} stories and does not have middle units")
2057+
return false
2058+
end
2059+
2060+
if (num_units_per_floor >= 4) && (corridor_position != 'Single Exterior (Front)') # assume double-loaded corridor
2061+
unit_depth = 2
2062+
unit_width = num_units_per_floor / 2.0
2063+
has_rear_units = true
2064+
elsif (num_units_per_floor == 2) && (horz_location == 'None') # double-loaded corridor for 2 units/story
20032065
unit_depth = 2
2004-
unit_width = num_units_per_floor / 2
2066+
unit_width = 1.0
20052067
has_rear_units = true
20062068
else
20072069
unit_depth = 1
@@ -2014,14 +2076,10 @@ def self.create_multifamily(runner:,
20142076
runner.registerError('Starting model is not empty.')
20152077
return false
20162078
end
2017-
if foundation_type.downcase.include?('crawlspace') && ((foundation_height < 1.5) || (foundation_height > 5.0))
2079+
if foundation_type.downcase.include?('crawlspace') && ((foundation_height < 1.5) || (foundation_height > 5.0)) && level == 'Bottom'
20182080
runner.registerError('The crawlspace height can be set between 1.5 and 5 ft.')
20192081
return false
20202082
end
2021-
if num_units % num_floors != 0
2022-
runner.registerError("The number of units (#{num_units}) must be divisible by the number of floors (#{num_floors}).")
2023-
return false
2024-
end
20252083
if !has_rear_units && ((corridor_position == 'Double-Loaded Interior') || (corridor_position == 'Double Exterior'))
20262084
runner.registerWarning("Specified incompatible corridor; setting corridor position to 'Single Exterior (Front)'.")
20272085
corridor_position = 'Single Exterior (Front)'
@@ -2044,16 +2102,20 @@ def self.create_multifamily(runner:,
20442102
runner.registerWarning('Specified a balcony, but there is no inset.')
20452103
balcony_depth = 0
20462104
end
2047-
if (unit_width == 1) && (horz_location != 'None')
2048-
runner.registerWarning("No #{horz_location} location exists, setting horizontal location to 'None'")
2105+
if (unit_width < 2) && (horz_location != 'None')
2106+
runner.registerWarning("No #{horz_location} location exists, setting horz_location to 'None'")
20492107
horz_location = 'None'
20502108
end
2109+
if (unit_width >= 2) && (horz_location == 'None')
2110+
runner.registerError('Specified incompatible horizontal location for the corridor and unit configuration.')
2111+
return false
2112+
end
20512113
if (unit_width > 1) && (horz_location == 'None')
20522114
runner.registerError('Specified incompatible horizontal location for the corridor and unit configuration.')
20532115
return false
20542116
end
2055-
if (unit_width < 3) && (horz_location == 'Middle')
2056-
runner.registerError('No middle horizontal location exists.')
2117+
if (unit_width <= 2) && (horz_location == 'Middle')
2118+
runner.registerError('Invalid horizontal location entered, no middle location exists.')
20572119
return false
20582120
end
20592121

@@ -2615,7 +2677,7 @@ def self.getSurfaceXValues(surfaceArray)
26152677
xValueArray = []
26162678
surfaceArray.each do |surface|
26172679
surface.vertices.each do |vertex|
2618-
xValueArray << UnitConversions.convert(vertex.x, 'm', 'ft')
2680+
xValueArray << UnitConversions.convert(vertex.x, 'm', 'ft').round(5)
26192681
end
26202682
end
26212683
return xValueArray
@@ -2626,7 +2688,7 @@ def self.getSurfaceYValues(surfaceArray)
26262688
yValueArray = []
26272689
surfaceArray.each do |surface|
26282690
surface.vertices.each do |vertex|
2629-
yValueArray << UnitConversions.convert(vertex.y, 'm', 'ft')
2691+
yValueArray << UnitConversions.convert(vertex.y, 'm', 'ft').round(5)
26302692
end
26312693
end
26322694
return yValueArray

BuildResidentialHPXML/resources/schedules.rb

Lines changed: 11 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -858,23 +858,18 @@ def create_stochastic_schedules(args:)
858858

859859
def set_vacancy(args:)
860860
if args[:schedules_vacancy_begin_month].is_initialized && args[:schedules_vacancy_begin_day_of_month].is_initialized && args[:schedules_vacancy_end_month].is_initialized && args[:schedules_vacancy_end_day_of_month].is_initialized
861-
begin
862-
vacancy_start_date = Time.new(@sim_year, args[:schedules_vacancy_begin_month].get, args[:schedules_vacancy_begin_day_of_month].get)
863-
vacancy_end_date = Time.new(@sim_year, args[:schedules_vacancy_end_month].get, args[:schedules_vacancy_end_day_of_month].get, 24)
864-
865-
sec_per_step = @minutes_per_step * 60.0
866-
ts = Time.new(@sim_year, 'Jan', 1)
867-
@schedules['vacancy'].each_with_index do |step, i|
868-
if vacancy_start_date <= ts && ts <= vacancy_end_date # in the vacancy period
869-
@schedules['vacancy'][i] = 1.0
870-
end
871-
ts += sec_per_step
872-
end
873-
874-
@runner.registerInfo("Set vacancy period from #{vacancy_start_date} to #{vacancy_end_date}.")
875-
rescue
876-
@runner.registerError('Invalid vacancy date(s) specified.')
861+
start_day_num = Schedule.get_day_num_from_month_day(@model, args[:schedules_vacancy_begin_month].get, args[:schedules_vacancy_begin_day_of_month].get)
862+
end_day_num = Schedule.get_day_num_from_month_day(@model, args[:schedules_vacancy_end_month].get, args[:schedules_vacancy_end_day_of_month].get)
863+
num_steps_per_day = @model.getSimulationControl.timestep.get.numberOfTimestepsPerHour * 24
864+
865+
vacancy = Array.new(@schedules['vacancy'].length, 0)
866+
if end_day_num >= start_day_num
867+
vacancy.fill(1.0, (start_day_num - 1) * num_steps_per_day, (end_day_num - start_day_num + 1) * num_steps_per_day) # Fill between start/end days
868+
else # Wrap around year
869+
vacancy.fill(1.0, (start_day_num - 1) * num_steps_per_day) # Fill between start day and end of year
870+
vacancy.fill(1.0, 0, end_day_num * num_steps_per_day) # Fill between start of year and end day
877871
end
872+
@schedules['vacancy'] = vacancy
878873
else
879874
@runner.registerInfo('No vacancy period set.')
880875
end

BuildResidentialHPXML/tests/base-appliances-coal.osw

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"dishwasher_location": "living space",
6767
"dishwasher_place_setting_capacity": "12",
6868
"dishwasher_usage_multiplier": 1.0,
69-
"door_area": 80.0,
69+
"door_area": 40.0,
7070
"door_rvalue": 4.4,
7171
"ducts_number_of_return_registers": "2",
7272
"ducts_return_insulation_r": 0.0,
@@ -187,14 +187,14 @@
187187
"lighting_usage_multiplier_exterior": 1.0,
188188
"lighting_usage_multiplier_garage": 1.0,
189189
"lighting_usage_multiplier_interior": 1.0,
190-
"mech_vent_fan_power": 30,
191-
"mech_vent_fan_power_2": 30,
190+
"mech_vent_fan_power": "30",
191+
"mech_vent_fan_power_2": "30",
192192
"mech_vent_fan_type": "none",
193193
"mech_vent_fan_type_2": "none",
194194
"mech_vent_flow_rate": 110,
195195
"mech_vent_flow_rate_2": 110,
196-
"mech_vent_hours_in_operation": 24,
197-
"mech_vent_hours_in_operation_2": 24,
196+
"mech_vent_hours_in_operation": "24",
197+
"mech_vent_hours_in_operation_2": "24",
198198
"mech_vent_num_units_served": 1,
199199
"mech_vent_recovery_efficiency_type": "Unadjusted",
200200
"mech_vent_recovery_efficiency_type_2": "Unadjusted",

BuildResidentialHPXML/tests/base-appliances-dehumidifier-ief-portable.osw

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@
6666
"dishwasher_location": "living space",
6767
"dishwasher_place_setting_capacity": "12",
6868
"dishwasher_usage_multiplier": 1.0,
69-
"door_area": 80.0,
69+
"door_area": 40.0,
7070
"door_rvalue": 4.4,
7171
"ducts_number_of_return_registers": "1",
7272
"ducts_return_insulation_r": 0.0,
@@ -187,14 +187,14 @@
187187
"lighting_usage_multiplier_exterior": 1.0,
188188
"lighting_usage_multiplier_garage": 1.0,
189189
"lighting_usage_multiplier_interior": 1.0,
190-
"mech_vent_fan_power": 30,
191-
"mech_vent_fan_power_2": 30,
190+
"mech_vent_fan_power": "30",
191+
"mech_vent_fan_power_2": "30",
192192
"mech_vent_fan_type": "none",
193193
"mech_vent_fan_type_2": "none",
194194
"mech_vent_flow_rate": 110,
195195
"mech_vent_flow_rate_2": 110,
196-
"mech_vent_hours_in_operation": 24,
197-
"mech_vent_hours_in_operation_2": 24,
196+
"mech_vent_hours_in_operation": "24",
197+
"mech_vent_hours_in_operation_2": "24",
198198
"mech_vent_num_units_served": 1,
199199
"mech_vent_recovery_efficiency_type": "Unadjusted",
200200
"mech_vent_recovery_efficiency_type_2": "Unadjusted",

0 commit comments

Comments
 (0)