openstudio-standards 0.8.3 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/lib/openstudio-standards/btap/costing/README.md +502 -0
  3. data/lib/openstudio-standards/btap/costing/btap_costing.rb +473 -0
  4. data/lib/openstudio-standards/btap/costing/btap_measure_helper.rb +359 -0
  5. data/lib/openstudio-standards/btap/costing/btap_workflow.rb +117 -0
  6. data/lib/openstudio-standards/btap/costing/common_paths.rb +78 -0
  7. data/lib/openstudio-standards/btap/costing/common_resources/ConstructionProperties.csv +52 -0
  8. data/lib/openstudio-standards/btap/costing/common_resources/Constructions.csv +37 -0
  9. data/lib/openstudio-standards/btap/costing/common_resources/construction_sets.csv +1270 -0
  10. data/lib/openstudio-standards/btap/costing/common_resources/constructions_glazing.csv +61 -0
  11. data/lib/openstudio-standards/btap/costing/common_resources/constructions_opaque.csv +2256 -0
  12. data/lib/openstudio-standards/btap/costing/common_resources/costs.csv +1904 -0
  13. data/lib/openstudio-standards/btap/costing/common_resources/costs_local_factors.csv +2315 -0
  14. data/lib/openstudio-standards/btap/costing/common_resources/hvac_vent_ahu.csv +925 -0
  15. data/lib/openstudio-standards/btap/costing/common_resources/lighting.csv +364 -0
  16. data/lib/openstudio-standards/btap/costing/common_resources/lighting_sets.csv +2667 -0
  17. data/lib/openstudio-standards/btap/costing/common_resources/locations.csv +75 -0
  18. data/lib/openstudio-standards/btap/costing/common_resources/materials_glazing.csv +35 -0
  19. data/lib/openstudio-standards/btap/costing/common_resources/materials_hvac.csv +1699 -0
  20. data/lib/openstudio-standards/btap/costing/common_resources/materials_lighting.csv +267 -0
  21. data/lib/openstudio-standards/btap/costing/common_resources/materials_opaque.csv +164 -0
  22. data/lib/openstudio-standards/btap/costing/copy_test_results_files_to_expected_results.rb +11 -0
  23. data/lib/openstudio-standards/btap/costing/cost_building_from_file.rb +136 -0
  24. data/lib/openstudio-standards/btap/costing/costing_database_wrapper.rb +177 -0
  25. data/lib/openstudio-standards/btap/costing/daylighting_sensor_control_costing.rb +353 -0
  26. data/lib/openstudio-standards/btap/costing/dcv_costing.rb +314 -0
  27. data/lib/openstudio-standards/btap/costing/dummy.epw +8768 -0
  28. data/lib/openstudio-standards/btap/costing/dummy.osm +5320 -0
  29. data/lib/openstudio-standards/btap/costing/envelope_costing.rb +284 -0
  30. data/lib/openstudio-standards/btap/costing/heating_cooling_costing.rb +2584 -0
  31. data/lib/openstudio-standards/btap/costing/led_lighting_costing.rb +155 -0
  32. data/lib/openstudio-standards/btap/costing/lighting_costing.rb +209 -0
  33. data/lib/openstudio-standards/btap/costing/mech_sizing.json +502 -0
  34. data/lib/openstudio-standards/btap/costing/neb_end_use_prices.csv +42 -0
  35. data/lib/openstudio-standards/btap/costing/necb_2011_spacetype_info.csv +225 -0
  36. data/lib/openstudio-standards/btap/costing/necb_reference_runs.csv +28705 -0
  37. data/lib/openstudio-standards/btap/costing/nv_costing.rb +547 -0
  38. data/lib/openstudio-standards/btap/costing/parallel_tests.rb +92 -0
  39. data/lib/openstudio-standards/btap/costing/pv_ground_costing.rb +687 -0
  40. data/lib/openstudio-standards/btap/costing/shw_costing.rb +705 -0
  41. data/lib/openstudio-standards/btap/costing/test_list.txt +17 -0
  42. data/lib/openstudio-standards/btap/costing/test_run_all_test_locally.rb +26 -0
  43. data/lib/openstudio-standards/btap/costing/test_run_costing_tests.rb +80 -0
  44. data/lib/openstudio-standards/btap/costing/ventilation_costing.rb +2616 -0
  45. data/lib/openstudio-standards/constructions/modify.rb +2 -1
  46. data/lib/openstudio-standards/standards/Standards.Model.rb +39 -9
  47. data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +2 -2
  48. data/lib/openstudio-standards/standards/ashrae_90_1_prm/userdata_csv/ashrae_90_1_prm.UserData.rb +6 -1
  49. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/btap_pre1980.rb +2 -27
  50. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_3_and_8_single_speed.rb +68 -27
  51. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_4.rb +64 -25
  52. data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +9 -14
  53. data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +46 -20
  54. data/lib/openstudio-standards/standards/necb/NECB2011/autozone.rb +635 -248
  55. data/lib/openstudio-standards/standards/necb/NECB2011/data/constants.json +43 -7
  56. data/lib/openstudio-standards/standards/necb/NECB2011/data/fuel_type_sets.json +7 -1
  57. data/lib/openstudio-standards/standards/necb/NECB2011/data/geometry/HighriseApartmentMult.osm +14272 -0
  58. data/lib/openstudio-standards/standards/necb/NECB2011/data/necb_2015_table_c1.json +1 -1
  59. data/lib/openstudio-standards/standards/necb/NECB2011/data/space_types.json +437 -437
  60. data/lib/openstudio-standards/standards/necb/NECB2011/data/systems.json +516 -0
  61. data/lib/openstudio-standards/standards/necb/NECB2011/data/systems_including_sys5.json +588 -0
  62. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_namer.rb +489 -0
  63. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_1_single_speed.rb +16 -6
  64. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_2_and_5.rb +48 -5
  65. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_multi_speed.rb +2 -2
  66. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_3_and_8_single_speed.rb +35 -27
  67. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_4.rb +34 -23
  68. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_system_6.rb +8 -6
  69. data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +42 -13
  70. data/lib/openstudio-standards/standards/necb/NECB2011/necb_2011.rb +214 -25
  71. data/lib/openstudio-standards/standards/necb/NECB2011/system_fuels.rb +61 -1
  72. data/lib/openstudio-standards/standards/necb/NECB2015/data/space_types.json +636 -636
  73. data/lib/openstudio-standards/standards/necb/NECB2015/data/unitary_acs.json +38 -38
  74. data/lib/openstudio-standards/standards/necb/NECB2015/hvac_systems.rb +15 -6
  75. data/lib/openstudio-standards/standards/necb/NECB2017/data/space_types.json +636 -636
  76. data/lib/openstudio-standards/standards/necb/NECB2020/data/chillers.json +71 -71
  77. data/lib/openstudio-standards/standards/necb/README.md +343 -0
  78. data/lib/openstudio-standards/standards/necb/common/btap_data.rb +190 -28
  79. data/lib/openstudio-standards/standards/necb/common/btap_datapoint.rb +14 -5
  80. data/lib/openstudio-standards/standards/necb/common/eccc_electric_grid_intensity_20250311.csv +14 -0
  81. data/lib/openstudio-standards/standards/necb/common/nir_gas_grid_intensity_20250311.csv +14 -0
  82. data/lib/openstudio-standards/standards/necb/common/system_types.yaml +0 -0
  83. data/lib/openstudio-standards/utilities/logging.rb +18 -14
  84. data/lib/openstudio-standards/version.rb +1 -1
  85. data/lib/openstudio-standards/weather/modify.rb +2 -2
  86. data/lib/openstudio-standards.rb +12 -0
  87. metadata +53 -2
@@ -69,11 +69,9 @@ class NECB2011
69
69
  # Remove any Thermal zones assigned before
70
70
  model.getThermalZones.each(&:remove)
71
71
  # create new thermal zones one to one with spaces.
72
- model_create_thermal_zones(model)
72
+ model_create_thermal_zones(model, space_multiplier_map)
73
73
  # do a sizing run.
74
- if model_run_sizing_run(model, "#{sizing_run_dir}/autozone") == false
75
- raise('autorun sizing run failed!')
76
- end
74
+ try_sizing_run(model: model, sizing_run_dir: sizing_run_dir, sizing_run_subdir: 'autozone')
77
75
 
78
76
  # collect sizing information on each space.
79
77
  store_space_sizing_loads(model)
@@ -94,11 +92,17 @@ class NECB2011
94
92
  # Organizes Zones and assigns them to appropriate systems according to NECB 2011-17 systems spacetype rules in Sec 8.
95
93
  # requires requires fuel type to be assigned for each system aspect. Defaults to gas hydronic.
96
94
  def apply_systems(model:,
95
+ hvac_system_primary:,
96
+ hvac_system_dwelling_units:,
97
+ hvac_system_washrooms:,
98
+ hvac_system_corridor:,
99
+ hvac_system_storage:,
97
100
  sizing_run_dir:,
98
101
  shw_scale:,
99
102
  baseline_system_zones_map_option:)
100
103
  raise('validation of model failed.') unless validate_initial_model(model)
101
-
104
+ # Store fuel type information in case hvac_system_primary requires a reset
105
+ init_fuel_type = get_fuel_type_information()
102
106
  # Check to see if model is using another vintage of spacetypes. If so overwrite the @standards for the object with the
103
107
  # other spacetype data. This is required for correct system mapping.
104
108
  template = determine_spacetype_vintage(model)
@@ -108,23 +112,33 @@ class NECB2011
108
112
  end
109
113
 
110
114
  # do a sizing run.
111
- if model_run_sizing_run(model, "#{sizing_run_dir}/autozone_systems") == false
112
- raise('autorun sizing run failed!')
113
- end
115
+ try_sizing_run(model: model, sizing_run_dir: sizing_run_dir, sizing_run_subdir: 'autozone_systems')
114
116
 
115
117
  # collect sizing information on each space.
116
118
  store_space_sizing_loads(model)
117
119
 
118
-
119
120
  # remove idealair from zones if any.
120
121
  model.getZoneHVACIdealLoadsAirSystems.each(&:remove)
121
- @hw_loop = create_hw_loop_if_required(self.fuel_type_set.baseboard_type,
122
- self.fuel_type_set.boiler_fueltype,
123
- self.fuel_type_set.backup_boiler_fueltype,
124
- self.fuel_type_set.mau_heating_coil_type,
125
- model)
122
+ @hw_loop = create_hw_loop_if_required(baseboard_type: self.fuel_type_set.baseboard_type,
123
+ boiler_fueltype: self.fuel_type_set.boiler_fueltype,
124
+ backup_boiler_fueltype: self.fuel_type_set.backup_boiler_fueltype,
125
+ mau_heating_coil_type: self.fuel_type_set.mau_heating_coil_type,
126
+ heating_coil_type_sys2: self.fuel_type_set.heating_coil_type_sys2,
127
+ heating_coil_type_sys3: self.fuel_type_set.heating_coil_type_sys3,
128
+ heating_coil_type_sys4: self.fuel_type_set.heating_coil_type_sys4,
129
+ heating_coil_type_sys6: self.fuel_type_set.heating_coil_type_sys6,
130
+ model: model,
131
+ hvac_system_primary: hvac_system_primary,
132
+ hvac_system_dwelling_units: hvac_system_dwelling_units,
133
+ hvac_system_washrooms: hvac_system_washrooms,
134
+ hvac_system_corridor: hvac_system_corridor,
135
+ hvac_system_storage: hvac_system_storage
136
+ )
137
+ # Determine if dwelling units, wet spaces, storage spaces, and wild spaces should have their own space or be part of common spaces
138
+ common_system_spaces = spaces_to_add_to_common_system(model: model, hvac_system_dwelling_units: hvac_system_dwelling_units, hvac_system_washrooms: hvac_system_washrooms, hvac_system_corridor: hvac_system_corridor, hvac_system_storage: hvac_system_storage)
126
139
  # Rule that all dwelling units have their own zone and system.
127
140
  auto_system_dwelling_units(model: model,
141
+ hvac_system_dwelling_units: hvac_system_dwelling_units,
128
142
  necb_reference_hp: self.fuel_type_set.necb_reference_hp,
129
143
  necb_reference_hp_supp_fuel: self.fuel_type_set.necb_reference_hp_supp_fuel,
130
144
  baseboard_type: self.fuel_type_set.baseboard_type,
@@ -138,45 +152,56 @@ class NECB2011
138
152
  mau_cooling_type: self.fuel_type_set.mau_cooling_type,
139
153
  mau_heating_coil_type: self.fuel_type_set.mau_heating_coil_type,
140
154
  mau_type: self.fuel_type_set.mau_type,
141
- baseline_system_zones_map_option: baseline_system_zones_map_option)
155
+ baseline_system_zones_map_option: baseline_system_zones_map_option,
156
+ init_fuel_type: init_fuel_type)
142
157
 
143
158
  # Assign a single system 4 for all wet spaces.. and assign the control zone to the one with the largest load.
144
- auto_system_wet_spaces(baseboard_type: self.fuel_type_set.baseboard_type,
159
+ auto_system_wet_spaces(hvac_system_washrooms: hvac_system_washrooms,
160
+ baseboard_type: self.fuel_type_set.baseboard_type,
145
161
  necb_reference_hp: self.fuel_type_set.necb_reference_hp,
146
162
  necb_reference_hp_supp_fuel: self.fuel_type_set.necb_reference_hp_supp_fuel,
147
163
  boiler_fueltype: self.fuel_type_set.boiler_fueltype,
148
164
  heating_coil_type_sys4: self.fuel_type_set.heating_coil_type_sys4,
149
- model: model)
165
+ model: model,
166
+ init_fuel_type: init_fuel_type)
150
167
 
151
168
  # Assign a single system 4 for all storage spaces.. and assign the control zone to the one with the largest load.
152
- auto_system_storage_spaces(baseboard_type: self.fuel_type_set.baseboard_type,
169
+ auto_system_storage_spaces(hvac_system_storage: hvac_system_storage,
170
+ baseboard_type: self.fuel_type_set.baseboard_type,
153
171
  necb_reference_hp: self.fuel_type_set.necb_reference_hp,
154
172
  necb_reference_hp_supp_fuel: self.fuel_type_set.necb_reference_hp_supp_fuel,
155
173
  boiler_fueltype: self.fuel_type_set.boiler_fueltype,
156
174
  heating_coil_type_sys4: self.fuel_type_set.heating_coil_type_sys4,
157
- model: model)
175
+ model: model,
176
+ init_fuel_type: init_fuel_type)
158
177
 
159
178
  # Assign the wild spaces to a single system 4 system with a control zone with the largest load.
160
- auto_system_wild_spaces(baseboard_type: self.fuel_type_set.baseboard_type,
179
+ auto_system_wild_spaces(hvac_system_corridor: hvac_system_corridor,
180
+ baseboard_type: self.fuel_type_set.baseboard_type,
161
181
  necb_reference_hp: self.fuel_type_set.necb_reference_hp,
162
182
  necb_reference_hp_supp_fuel: self.fuel_type_set.necb_reference_hp_supp_fuel,
163
183
  heating_coil_type_sys4: self.fuel_type_set.heating_coil_type_sys4,
164
- model: model)
184
+ model: model,
185
+ init_fuel_type: init_fuel_type)
165
186
  # do the regular assignment for the rest and group where possible.
166
187
  auto_system_all_other_spaces(model: model,
188
+ hvac_system_primary: hvac_system_primary,
167
189
  necb_reference_hp: self.fuel_type_set.necb_reference_hp,
168
190
  necb_reference_hp_supp_fuel: self.fuel_type_set.necb_reference_hp_supp_fuel,
169
191
  baseboard_type: self.fuel_type_set.baseboard_type,
170
192
  boiler_fueltype: self.fuel_type_set.boiler_fueltype,
171
193
  chiller_type: self.fuel_type_set.chiller_type,
172
194
  fan_type: self.fuel_type_set.fan_type,
195
+ heating_coil_type_sys2: self.fuel_type_set.heating_coil_type_sys2,
173
196
  heating_coil_type_sys3: self.fuel_type_set.heating_coil_type_sys3,
174
197
  heating_coil_type_sys4: self.fuel_type_set.heating_coil_type_sys4,
175
198
  hw_loop: @hw_loop,
176
199
  heating_coil_type_sys6: self.fuel_type_set.heating_coil_type_sys6,
177
200
  mau_cooling_type: self.fuel_type_set.mau_cooling_type,
178
201
  mau_heating_coil_type: self.fuel_type_set.mau_heating_coil_type,
179
- mau_type: self.fuel_type_set.mau_type
202
+ mau_type: self.fuel_type_set.mau_type,
203
+ common_system_spaces: common_system_spaces,
204
+ init_fuel_type: init_fuel_type
180
205
  )
181
206
  model_add_swh(model: model,
182
207
  shw_scale: shw_scale)
@@ -207,7 +232,7 @@ class NECB2011
207
232
  def stored_space_heating_load(space)
208
233
  if @stored_space_heating_sizing_loads.nil?
209
234
  # do a sizing run.
210
- raise('autorun sizing run failed!') if model_run_sizing_run(space.model, "#{Dir.pwd}/autozone") == false
235
+ try_sizing_run(model: space.model, sizing_run_dir: "#{Dir.pwd}", sizing_run_subdir: 'autozone')
211
236
 
212
237
  # collect sizing information on each space.
213
238
  store_space_sizing_loads(space.model)
@@ -219,7 +244,7 @@ class NECB2011
219
244
  def stored_space_cooling_load(space)
220
245
  if @stored_space_cooling_sizing_loads.nil?
221
246
  # do a sizing run.
222
- raise('autorun sizing run failed!') if model_run_sizing_run(space.model, "#{Dir.pwd}/autozone") == false
247
+ try_sizing_run(model: space.model, sizing_run_dir: "#{Dir.pwd}", sizing_run_subdir: 'autozone')
223
248
 
224
249
  # collect sizing information on each space.
225
250
  store_space_sizing_loads(space.model)
@@ -317,15 +342,6 @@ class NECB2011
317
342
  ideal_loads = OpenStudio::Model::ZoneHVACIdealLoadsAirSystem.new(model)
318
343
  ideal_loads.addToThermalZone(zone)
319
344
  end
320
- # Go through other spaces to see if there are similar spaces with similar loads on the same floor that can be grouped.
321
- model.getSpaces.select { |s| is_an_necb_wet_space?(s) }.each do |space_target|
322
- if space_target.thermalZone.empty?
323
- if are_space_loads_similar?(space_1: space, space_2: space_target) && space.buildingStory.get == space_target.buildingStory.get # added since chris needs zones to not span floors for costing.
324
- adjust_wildcard_spacetype_schedule(space: space_target, schedule: dominant_schedule, lights_type: lights_type, lights_scale: lights_scale)
325
- space_target.setThermalZone(zone)
326
- end
327
- end
328
- end
329
345
  wet_zone_array << zone
330
346
  end
331
347
  return wet_zone_array
@@ -366,14 +382,6 @@ class NECB2011
366
382
  ideal_loads = OpenStudio::Model::ZoneHVACIdealLoadsAirSystem.new(model)
367
383
  ideal_loads.addToThermalZone(zone)
368
384
  end
369
- # Go through other spaces and if you find something with similar loads on the same floor, add it to the zone.
370
- model.getSpaces.select { |curr_space| !is_a_necb_dwelling_unit?(curr_space) && !is_an_necb_wildcard_space?(curr_space) }.each do |space_target|
371
- if space_target.thermalZone.empty?
372
- if are_space_loads_similar?(space_1: space, space_2: space_target) && space.buildingStory.get == space_target.buildingStory.get # added since chris needs zones to not span floors for costing.
373
- space_target.setThermalZone(zone)
374
- end
375
- end
376
- end
377
385
  other_tz_array << zone
378
386
  end
379
387
  return other_tz_array
@@ -421,15 +429,6 @@ class NECB2011
421
429
  ideal_loads = OpenStudio::Model::ZoneHVACIdealLoadsAirSystem.new(model)
422
430
  ideal_loads.addToThermalZone(zone)
423
431
  end
424
- # Go through other spaces and if you find something with similar loads on the same floor, add it to the zone.
425
- model.getSpaces.select { |curr_space| is_an_necb_wildcard_space?(curr_space) && !is_an_necb_wet_space?(curr_space) }.each do |space_target|
426
- if space_target.thermalZone.empty?
427
- if are_space_loads_similar?(space_1: space, space_2: space_target) &&
428
- (space.buildingStory.get == space_target.buildingStory.get) # added since chris needs zones to not span floors for costing.
429
- space_target.setThermalZone(zone)
430
- end
431
- end
432
- end
433
432
  other_tz_array << zone
434
433
  end
435
434
  return other_tz_array
@@ -504,16 +503,6 @@ class NECB2011
504
503
  ideal_loads = OpenStudio::Model::ZoneHVACIdealLoadsAirSystem.new(model)
505
504
  ideal_loads.addToThermalZone(zone)
506
505
  end
507
- # Go through other spaces to see if there are similar spaces with similar loads on the same floor that can be grouped.
508
- model.getSpaces.select { |s| is_an_necb_wildcard_space?(s) && !is_an_necb_wet_space?(s) }.each do |space_target|
509
- if space_target.thermalZone.empty?
510
- if are_space_loads_similar?(space_1: space, space_2: space_target) &&
511
- space.buildingStory.get == space_target.buildingStory.get # added since chris needs zones to not span floors for costing.
512
- adjust_wildcard_spacetype_schedule(space: space_target, schedule: dominant_floor_schedule, lights_type: @lights_type, lights_scale: @lights_scale)
513
- space_target.setThermalZone(zone)
514
- end
515
- end
516
- end
517
506
  wild_zone_array << zone
518
507
  end
519
508
  return wild_zone_array
@@ -636,6 +625,8 @@ class NECB2011
636
625
 
637
626
  # Check to see if this is a wildcard space that the NECB does not have a specified schedule or system for.
638
627
  def is_an_necb_wildcard_space?(space)
628
+ # Avoid including washrooms and locker rooms as both wildcard and wet spaces
629
+ return nil if space.spaceType.get.standardsSpaceType.get.include?('Locker room') || space.spaceType.get.standardsSpaceType.get.include?('Washroom')
639
630
  space_type_table = @standards_data['space_types']
640
631
  space_type_data = model_find_object(space_type_table,
641
632
  'template' => self.class.name,
@@ -822,35 +813,92 @@ class NECB2011
822
813
  ################################################# NECB Systems
823
814
 
824
815
  # Method will create a hot water loop if systems default fuel and medium sources require it.
825
- def create_hw_loop_if_required(baseboard_type, boiler_fueltype, backup_boiler_fueltype, mau_heating_coil_type, model)
816
+ def create_hw_loop_if_required(baseboard_type:, boiler_fueltype:, backup_boiler_fueltype:, mau_heating_coil_type:, model:, hvac_system_primary: nil, hvac_system_dwelling_units: nil, hvac_system_washrooms: nil, hvac_system_corridor: nil, hvac_system_storage: nil, heating_coil_type_sys2:, heating_coil_type_sys3:, heating_coil_type_sys4:, heating_coil_type_sys6:)
826
817
  # get systems that will be used in the model based on the space types to determine if a hw_loop is required.
827
- systems_used = []
828
- model.getSpaces.sort.each do |space|
829
- systems_used << get_necb_spacetype_system_selection(space)
830
- systems_used.uniq!
831
- end
832
818
 
833
- # See if we need to create a hot water loop based on fueltype and systems used.
834
819
  hw_loop_needed = false
835
- systems_used.each do |system|
836
- case system.to_s
837
- when '2', '5', '7'
838
- hw_loop_needed = true
839
- when '1', '6'
840
- if (mau_heating_coil_type == 'Hot Water') || (baseboard_type == 'Hot Water')
841
- hw_loop_needed = true
842
- end
843
- when '3', '4'
844
- if (mau_heating_coil_type == 'Hot Water') || (baseboard_type == 'Hot Water')
845
- hw_loop_needed = true if baseboard_type == 'Hot Water'
846
- end
820
+
821
+ # Create a boiler if the air loop will use fancoils for heating
822
+ hw_loop_needed = true if self.fuel_type_set.force_airloop_hot_water
823
+
824
+ # Create a boiler if one is forced by the user
825
+ hw_loop_needed = true if self.fuel_type_set.force_boiler
826
+
827
+ # Find Dwelling Units and determine if a HW loop is needed
828
+ dwelling_units = model.getSpaces.select { |space| is_a_necb_dwelling_unit?(space) }
829
+ unless dwelling_units.empty?
830
+ # If no dwelling unit hvac system is defined then check if a HW loop is needed based on the system type.
831
+ if hvac_system_dwelling_units.nil? || hvac_system_dwelling_units.to_s.downcase == 'necb_default'
832
+ hw_loop_needed = hw_loop_required_from_spaces(spaces: dwelling_units, mau_heating_coil_type: mau_heating_coil_type, baseboard_type: baseboard_type, heating_coil_type_sys2: heating_coil_type_sys2, heating_coil_type_sys3: heating_coil_type_sys3, heating_coil_type_sys4: heating_coil_type_sys4, heating_coil_type_sys6: heating_coil_type_sys6) unless hw_loop_needed
833
+ else
834
+ # If a dwelling unit hvac system is defined then find it in the hvac_types array and check if it requires a HW loop based on the 'needs_boiler' item.
835
+ hvac_system_data = self.standards_data['hvac_types'].find { |system| system['description'] == hvac_system_dwelling_units }
836
+ hw_loop_needed = true if hvac_system_data["needs_boiler"].to_bool unless hw_loop_needed
837
+ hw_loop_needed = boiler_required_from_heating_coils(sys_type: hvac_system_data["system"].to_s, mau_heating_coil_type: mau_heating_coil_type, heating_coil_type_sys2: heating_coil_type_sys2, heating_coil_type_sys3: heating_coil_type_sys3, heating_coil_type_sys4: heating_coil_type_sys4, heating_coil_type_sys6: heating_coil_type_sys6) unless hw_loop_needed
847
838
  end
848
- if hw_loop_needed
849
- # just need one true condition to need a boiler.
850
- break
839
+ end
840
+
841
+ # Find washrooms and determine if a HW loop is needed
842
+ washroom_spaces = model.getSpaces.select { |space| is_an_necb_wet_space?(space) }
843
+ unless washroom_spaces.empty?
844
+ # If no washroom hvac system is defined then check if a HW loop is needed based on the system type.
845
+ if hvac_system_washrooms.nil? || hvac_system_washrooms.to_s.downcase == 'necb_default'
846
+ hw_loop_needed = hw_loop_required_from_spaces(spaces: washroom_spaces, mau_heating_coil_type: mau_heating_coil_type, baseboard_type: baseboard_type, heating_coil_type_sys2: heating_coil_type_sys2, heating_coil_type_sys3: heating_coil_type_sys3, heating_coil_type_sys4: heating_coil_type_sys4, heating_coil_type_sys6: heating_coil_type_sys6) unless hw_loop_needed
847
+ else
848
+ # If a washroom hvac system is defined then find it in the hvac_types array and check if it requires a HW loop based on the 'needs_boiler' item.
849
+ hvac_system_data = self.standards_data['hvac_types'].find { |system| system['description'] == hvac_system_washrooms }
850
+ hw_loop_needed = true if hvac_system_data["needs_boiler"].to_bool unless hw_loop_needed
851
+ hw_loop_needed = boiler_required_from_heating_coils(sys_type: hvac_system_data["system"].to_s, mau_heating_coil_type: mau_heating_coil_type, heating_coil_type_sys2: heating_coil_type_sys2, heating_coil_type_sys3: heating_coil_type_sys3, heating_coil_type_sys4: heating_coil_type_sys4, heating_coil_type_sys6: heating_coil_type_sys6) unless hw_loop_needed
851
852
  end
852
- # each
853
853
  end
854
+
855
+ # Find corridors and determine if a HW loop is needed
856
+ corridor_spaces = model.getSpaces.select { |space| is_an_necb_wildcard_space?(space) }
857
+ unless corridor_spaces.empty?
858
+ # If no corridor hvac system is defined then check if a HW loop is needed based on the system type.
859
+ if hvac_system_corridor.nil? || hvac_system_corridor.to_s.downcase == 'necb_default'
860
+ hw_loop_needed = hw_loop_required_from_spaces(spaces: corridor_spaces, mau_heating_coil_type: mau_heating_coil_type, baseboard_type: baseboard_type, heating_coil_type_sys2: heating_coil_type_sys2, heating_coil_type_sys3: heating_coil_type_sys3, heating_coil_type_sys4: heating_coil_type_sys4, heating_coil_type_sys6: heating_coil_type_sys6) unless hw_loop_needed
861
+ else
862
+ # If a corridor hvac system is defined then find it in the hvac_types array and check if it requires a HW loop based on the 'needs_boiler' item.
863
+ hvac_system_data = self.standards_data['hvac_types'].find { |system| system['description'] == hvac_system_corridor }
864
+ hw_loop_needed = true if hvac_system_data["needs_boiler"].to_bool unless hw_loop_needed
865
+ hw_loop_needed = boiler_required_from_heating_coils(sys_type: hvac_system_data["system"].to_s, mau_heating_coil_type: mau_heating_coil_type, heating_coil_type_sys2: heating_coil_type_sys2, heating_coil_type_sys3: heating_coil_type_sys3, heating_coil_type_sys4: heating_coil_type_sys4, heating_coil_type_sys6: heating_coil_type_sys6) unless hw_loop_needed
866
+ end
867
+ end
868
+
869
+ # Find storage spaces and determine if a HW loop is needed
870
+ storage_spaces = model.getSpaces.select { |space| is_an_necb_storage_space?(space) }
871
+ unless storage_spaces.empty?
872
+ # If no storage space hvac system is defined then check if a HW loop is needed based on the system type.
873
+ if hvac_system_storage.nil? || hvac_system_storage.to_s.downcase == 'necb_default'
874
+ hw_loop_needed = hw_loop_required_from_spaces(spaces: storage_spaces, mau_heating_coil_type: mau_heating_coil_type, baseboard_type: baseboard_type, heating_coil_type_sys2: heating_coil_type_sys2, heating_coil_type_sys3: heating_coil_type_sys3, heating_coil_type_sys4: heating_coil_type_sys4, heating_coil_type_sys6: heating_coil_type_sys6) unless hw_loop_needed
875
+ else
876
+ # If a storage space hvac system is defined then find it in the hvac_types array and check if it requires a HW loop based on the 'needs_boiler' item.
877
+ hvac_system_data = self.standards_data['hvac_types'].find { |system| system['description'] == hvac_system_storage }
878
+ hw_loop_needed = true if hvac_system_data["needs_boiler"].to_bool unless hw_loop_needed
879
+ hw_loop_needed = boiler_required_from_heating_coils(sys_type: hvac_system_data["system"].to_s, mau_heating_coil_type: mau_heating_coil_type, heating_coil_type_sys2: heating_coil_type_sys2, heating_coil_type_sys3: heating_coil_type_sys3, heating_coil_type_sys4: heating_coil_type_sys4, heating_coil_type_sys6: heating_coil_type_sys6) unless hw_loop_needed
880
+ end
881
+ end
882
+
883
+ # Find if a HW loop is needed for the remaining spaces
884
+ other_spaces = model.getSpaces.select do |space|
885
+ !is_an_necb_wet_space?(space) &&
886
+ !is_a_necb_dwelling_unit?(space) &&
887
+ !is_an_necb_wildcard_space?(space) &&
888
+ !is_an_necb_storage_space?(space)
889
+ end
890
+ unless other_spaces.empty?
891
+ # If a hvac system is defined for the remaining spaces then check if a HW loop is needed based on the system type
892
+ if hvac_system_primary.nil? || hvac_system_primary.to_s.downcase == 'necb_default'
893
+ hw_loop_needed = hw_loop_required_from_spaces(spaces: other_spaces, mau_heating_coil_type: mau_heating_coil_type, baseboard_type: baseboard_type, heating_coil_type_sys2: heating_coil_type_sys2, heating_coil_type_sys3: heating_coil_type_sys3, heating_coil_type_sys4: heating_coil_type_sys4, heating_coil_type_sys6: heating_coil_type_sys6) unless hw_loop_needed
894
+ else
895
+ # If an hvac system is defined for the remaining spaces then find it in the hvac_types array and check if it requires a HW loop based on the 'needs_boiler' item.
896
+ hvac_system_data = self.standards_data['hvac_types'].find { |system| system['description'] == hvac_system_primary }
897
+ hw_loop_needed = true if hvac_system_data["needs_boiler"].to_bool unless hw_loop_needed
898
+ hw_loop_needed = boiler_required_from_heating_coils(sys_type: hvac_system_data["system"].to_s, mau_heating_coil_type: mau_heating_coil_type, heating_coil_type_sys2: heating_coil_type_sys2, heating_coil_type_sys3: heating_coil_type_sys3, heating_coil_type_sys4: heating_coil_type_sys4, heating_coil_type_sys6: heating_coil_type_sys6) unless hw_loop_needed
899
+ end
900
+ end
901
+
854
902
  # create hw_loop as needed.. Assuming one loop per model.
855
903
  if hw_loop_needed
856
904
  @hw_loop = OpenStudio::Model::PlantLoop.new(model)
@@ -863,14 +911,16 @@ class NECB2011
863
911
  # Default method to create a necb system and assign array of zones to be supported by it. It will try to bring zones with
864
912
  # similar loads on the same airloops and set control zones where possible for single zone systems and will create monolithic
865
913
  # system 6 multizones where possible.
866
- def create_necb_system(baseboard_type:,
914
+ def create_necb_system(hvac_system_primary: 'NECB_Default',
915
+ baseboard_type:,
867
916
  boiler_fueltype:,
868
917
  chiller_type:,
869
918
  fan_type:,
919
+ hw_loop:,
920
+ heating_coil_type_sys2:,
870
921
  heating_coil_type_sys3:,
871
922
  heating_coil_type_sys4:,
872
923
  heating_coil_type_sys6:,
873
- hw_loop:,
874
924
  mau_cooling_type:,
875
925
  mau_heating_coil_type:,
876
926
  mau_type:,
@@ -880,9 +930,28 @@ class NECB2011
880
930
  necb_reference_hp_supp_fuel:'DefaultFuel')
881
931
  # The goal is to minimize the number of system when possible.
882
932
  system_zones_hash = {}
933
+ system_selection = nil
883
934
  zones.each do |zone|
884
- system_zones_hash[get_necb_thermal_zone_system_selection(zone)] = [] if system_zones_hash[get_necb_thermal_zone_system_selection(zone)].nil?
885
- system_zones_hash[get_necb_thermal_zone_system_selection(zone)] << zone
935
+ # Define the system type based on the space type data or use the custom one (hvac_system_primary) if is defined.
936
+ if hvac_system_primary.nil? || hvac_system_primary.to_s.downcase == 'necb_default'
937
+ system_selection = get_necb_thermal_zone_system_selection(zone)
938
+ else
939
+ zone_space_count = 0
940
+ null_space_count = 0
941
+ zone.spaces.sort.each do |space|
942
+ zone_space_count += 1
943
+ null_space_count += 1 if space.spaceType.get.name.to_s.downcase.include?("undefined")
944
+ end
945
+ system_data = @standards_data['hvac_types']
946
+ selected_systems = system_data.select { |ind_system| ind_system["description"].to_s.downcase == hvac_system_primary.to_s.downcase }
947
+ raise ("Could not find the provided HVAC system name in the HVAC system library. Please check the spelling of HVAC system name you defined. Provided HVAC system name: #{hvac_system_primary}") if selected_systems.empty?
948
+ raise ("More than one HVAC systems match the provided HVAC system name. Please check the spelling of the provided HVAC system name. Provided HVAC system name: #{hvac_system_primary}") if selected_systems.size > 1
949
+ system_selection = selected_systems[0]["system"][4].to_i
950
+ # Do not inculde zones exclusively containing undefined spaces
951
+ system_selection = nil if null_space_count > 0 && zone_space_count == null_space_count
952
+ end
953
+ system_zones_hash[system_selection] = [] if system_zones_hash[system_selection].nil?
954
+ system_zones_hash[system_selection] << zone
886
955
  end
887
956
  # puts JSON.pretty_generate(system_zones_hash)
888
957
  # go through each system and zones pairs to
@@ -892,86 +961,141 @@ class NECB2011
892
961
  # Do nothing no system assigned to zone. Used for Unconditioned spaces
893
962
  when 1
894
963
  group_similar_zones_together(sys_zones).each do |curr_zones|
895
- mau_air_loop = add_sys1_unitary_ac_baseboard_heating(model: model,
896
- necb_reference_hp: necb_reference_hp,
897
- necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
898
- zones: curr_zones,
899
- mau_type: mau_type,
900
- mau_heating_coil_type: mau_heating_coil_type,
901
- baseboard_type: baseboard_type,
902
- hw_loop: @hw_loop,
903
- multispeed: false)
964
+ if hvac_system_primary == 'NECB_Default' or hvac_system_primary.nil?
965
+ mau_air_loop = add_sys1_unitary_ac_baseboard_heating(model: model,
966
+ necb_reference_hp: necb_reference_hp,
967
+ necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
968
+ zones: curr_zones,
969
+ mau_type: mau_type,
970
+ mau_heating_coil_type: mau_heating_coil_type,
971
+ baseboard_type: baseboard_type,
972
+ hw_loop: @hw_loop,
973
+ multispeed: false)
974
+ else
975
+ create_hvac_by_name( model: model,
976
+ hvac_system_name: hvac_system_primary,
977
+ hw_loop: @hw_loop,
978
+ zones: curr_zones
979
+ )
980
+ end
904
981
  end
982
+
905
983
  when 2
906
984
  group_similar_zones_together(sys_zones).each do |curr_zones|
907
- add_sys2_FPFC_sys5_TPFC(model: model,
908
- zones: curr_zones,
909
- chiller_type: chiller_type,
910
- mau_cooling_type: mau_cooling_type,
911
- fan_coil_type: 'FPFC',
912
- hw_loop: @hw_loop)
985
+ if hvac_system_primary == 'NECB_Default' or hvac_system_primary.nil?
986
+ add_sys2_FPFC_sys5_TPFC(model: model,
987
+ zones: curr_zones,
988
+ chiller_type: chiller_type,
989
+ mau_cooling_type: mau_cooling_type,
990
+ fan_coil_type: 'FPFC',
991
+ hw_loop: @hw_loop)
992
+ else
993
+ create_hvac_by_name( model: model,
994
+ hvac_system_name: hvac_system_primary,
995
+ hw_loop: @hw_loop,
996
+ zones: curr_zones
997
+ )
998
+ end
913
999
  end
914
1000
  when 3
915
1001
  group_similar_zones_together(sys_zones).each do |curr_zones|
916
- add_sys3and8_single_zone_packaged_rooftop_unit_with_baseboard_heating(model: model,
917
- necb_reference_hp: necb_reference_hp,
918
- necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
919
- zones: curr_zones,
920
- heating_coil_type: heating_coil_type_sys3,
921
- baseboard_type: baseboard_type,
922
- hw_loop: @hw_loop,
923
- multispeed: false)
1002
+ if hvac_system_primary == 'NECB_Default' or hvac_system_primary.nil?
1003
+ add_sys3and8_single_zone_packaged_rooftop_unit_with_baseboard_heating(model: model,
1004
+ necb_reference_hp: necb_reference_hp,
1005
+ necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1006
+ zones: curr_zones,
1007
+ heating_coil_type: heating_coil_type_sys3,
1008
+ baseboard_type: baseboard_type,
1009
+ hw_loop: @hw_loop,
1010
+ multispeed: false)
1011
+ else
1012
+ create_hvac_by_name( model: model,
1013
+ hvac_system_name: hvac_system_primary,
1014
+ hw_loop: @hw_loop,
1015
+ zones: curr_zones
1016
+ )
1017
+ end
924
1018
  end
1019
+
925
1020
  when 4
926
1021
  group_similar_zones_together(sys_zones).each do |curr_zones|
927
- add_sys4_single_zone_make_up_air_unit_with_baseboard_heating(model: model,
928
- necb_reference_hp: necb_reference_hp,
929
- necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
930
- zones: curr_zones,
931
- heating_coil_type: heating_coil_type_sys4,
932
- baseboard_type: baseboard_type,
933
- hw_loop: @hw_loop)
934
- # add_sys3and8_single_zone_packaged_rooftop_unit_with_baseboard_heating(model: model,
935
- # zones: zones,
936
- # heating_coil_type: heating_coil_type_sys4,
937
- # baseboard_type: baseboard_type,
938
- # hw_loop: @hw_loop,
939
- # multispeed: false)
1022
+ if hvac_system_primary == 'NECB_Default' or hvac_system_primary.nil?
1023
+ add_sys4_single_zone_make_up_air_unit_with_baseboard_heating(model: model,
1024
+ necb_reference_hp: necb_reference_hp,
1025
+ necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1026
+ zones: curr_zones,
1027
+ heating_coil_type: heating_coil_type_sys4,
1028
+ baseboard_type: baseboard_type,
1029
+ hw_loop: @hw_loop)
1030
+ else
1031
+ create_hvac_by_name( model: model,
1032
+ hvac_system_name: hvac_system_primary,
1033
+ hw_loop: @hw_loop,
1034
+ zones: curr_zones
1035
+ )
1036
+ end
940
1037
  end
1038
+
941
1039
  when 5
942
1040
  group_similar_zones_together(sys_zones).each do |curr_zones|
943
- add_sys2_FPFC_sys5_TPFC(model: model,
944
- zones: curr_zones,
945
- chiller_type: chiller_type,
946
- mau_cooling_type: mau_cooling_type,
947
- fan_coil_type: 'TPFC',
948
- hw_loop: @hw_loop)
1041
+ if hvac_system_primary == 'NECB_Default' or hvac_system_primary.nil?
1042
+ add_sys2_FPFC_sys5_TPFC(model: model,
1043
+ zones: curr_zones,
1044
+ chiller_type: chiller_type,
1045
+ mau_cooling_type: mau_cooling_type,
1046
+ fan_coil_type: 'TPFC',
1047
+ hw_loop: @hw_loop)
1048
+ else
1049
+ create_hvac_by_name( model: model,
1050
+ hvac_system_name: hvac_system_primary,
1051
+ hw_loop: @hw_loop,
1052
+ zones: curr_zones
1053
+ )
1054
+ end
949
1055
  end
1056
+
950
1057
  when 6
951
- if necb_reference_hp
952
- add_sys6_multi_zone_reference_hp_with_baseboard_heating(model: model,
953
- zones: sys_zones,
954
- heating_coil_type: heating_coil_type_sys6,
955
- baseboard_type: baseboard_type,
956
- hw_loop:@hw_loop,
957
- necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel)
958
- else
959
- add_sys6_multi_zone_built_up_system_with_baseboard_heating(model: model,
1058
+ if hvac_system_primary == 'NECB_Default' or hvac_system_primary.nil?
1059
+ if necb_reference_hp
1060
+ add_sys6_multi_zone_reference_hp_with_baseboard_heating(model: model,
960
1061
  zones: sys_zones,
961
1062
  heating_coil_type: heating_coil_type_sys6,
962
1063
  baseboard_type: baseboard_type,
963
- chiller_type: chiller_type,
964
- fan_type: fan_type,
965
- hw_loop: @hw_loop)
1064
+ hw_loop:@hw_loop,
1065
+ necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel)
1066
+ else
1067
+ add_sys6_multi_zone_built_up_system_with_baseboard_heating(model: model,
1068
+ zones: sys_zones,
1069
+ heating_coil_type: heating_coil_type_sys6,
1070
+ baseboard_type: baseboard_type,
1071
+ chiller_type: chiller_type,
1072
+ fan_type: fan_type,
1073
+ hw_loop: @hw_loop)
1074
+ end
1075
+ else
1076
+ create_hvac_by_name( model: model,
1077
+ hvac_system_name: hvac_system_primary,
1078
+ hw_loop: @hw_loop,
1079
+ zones: sys_zones
1080
+ )
966
1081
  end
1082
+
967
1083
  when 7
968
1084
  group_similar_zones_together(sys_zones).each do |curr_zones|
969
- add_sys2_FPFC_sys5_TPFC(model: model,
970
- zones: curr_zones,
971
- chiller_type: chiller_type,
972
- fan_coil_type: 'FPFC',
973
- mau_cooling_type: mau_cooling_type,
974
- hw_loop: @hw_loop)
1085
+ if hvac_system_primary == 'NECB_Default' or hvac_system_primary.nil?
1086
+ add_sys2_FPFC_sys5_TPFC(model: model,
1087
+ zones: curr_zones,
1088
+ chiller_type: chiller_type,
1089
+ fan_coil_type: 'FPFC',
1090
+ mau_cooling_type: mau_cooling_type,
1091
+ hw_loop: @hw_loop)
1092
+ else
1093
+ create_hvac_by_name( model: model,
1094
+ hvac_system_name: hvac_system_primary,
1095
+ hw_loop: @hw_loop,
1096
+ zones: curr_zones
1097
+ )
1098
+ end
975
1099
  end
976
1100
  end
977
1101
  end
@@ -979,11 +1103,13 @@ class NECB2011
979
1103
 
980
1104
  # This method will deal with all non wet, non-wild, and non-dwelling units thermal zones.
981
1105
  def auto_system_all_other_spaces(baseboard_type:,
982
- necb_reference_hp:false,
983
- necb_reference_hp_supp_fuel:'DefaultFuel',
1106
+ hvac_system_primary:,
1107
+ necb_reference_hp: false,
1108
+ necb_reference_hp_supp_fuel: 'DefaultFuel',
984
1109
  boiler_fueltype:,
985
1110
  chiller_type:,
986
1111
  fan_type:,
1112
+ heating_coil_type_sys2:,
987
1113
  heating_coil_type_sys3:,
988
1114
  heating_coil_type_sys4:,
989
1115
  heating_coil_type_sys6:,
@@ -991,24 +1117,43 @@ class NECB2011
991
1117
  mau_cooling_type:,
992
1118
  mau_heating_coil_type:,
993
1119
  mau_type:,
994
- model:)
995
-
1120
+ model:,
1121
+ common_system_spaces: [],
1122
+ init_fuel_type:)
1123
+ # Reset fuel type set to those defined by the user
1124
+ fuel_type_set.reset_default_fuel_info(init_fuel_type: init_fuel_type)
1125
+ # Set fuel type info based on hvac_system_primary (if set)
1126
+ unless hvac_system_primary.nil? || hvac_system_primary.to_s.downcase == 'necb_default'
1127
+ fuel_type_set.set_fuel_to_hvac_system_primary(hvac_system_primary: hvac_system_primary, standards_data: @standards_data)
1128
+ mau_type = fuel_type_set.mau_type unless fuel_type_set.mau_type.nil?
1129
+ mau_heating_coil_type = fuel_type_set.mau_heating_coil_type unless fuel_type_set.mau_heating_coil_type.nil? || fuel_type_set.force_airloop_hot_water
1130
+ necb_reference_hp = fuel_type_set.necb_reference_hp unless fuel_type_set.necb_reference_hp.nil?
1131
+ necb_reference_hp_supp_fuel = fuel_type_set.necb_reference_hp_supp_fuel unless fuel_type_set.necb_reference_hp_supp_fuel.nil? || fuel_type_set.force_airloop_hot_water
1132
+ heating_coil_type_sys4 = fuel_type_set.heating_coil_type_sys4 unless fuel_type_set.heating_coil_type_sys4.nil? || fuel_type_set.force_airloop_hot_water
1133
+ end
996
1134
  zones = []
997
1135
  other_spaces = model.getSpaces.select do |space|
1136
+ !is_an_necb_wet_space?(space) &&
998
1137
  !is_a_necb_dwelling_unit?(space) &&
999
1138
  !is_an_necb_wildcard_space?(space) &&
1000
1139
  !is_an_necb_storage_space?(space)
1001
1140
  end
1141
+ # Add any dwelling units, washrooms, cooridors, or storage spaces to the list of other spaces if a non-default system type was assigned to them
1142
+ unless common_system_spaces.empty? || common_system_spaces.nil?
1143
+ other_spaces = other_spaces + common_system_spaces
1144
+ end
1002
1145
  other_spaces.each do |space|
1003
1146
  zones << space.thermalZone.get
1004
1147
  end
1005
1148
  zones.uniq!
1006
1149
 
1007
1150
  # since dwelling units are all zoned 1:1 to space:zone we simply add the zone to the appropriate btap system.
1008
- create_necb_system(baseboard_type: baseboard_type,
1151
+ create_necb_system(hvac_system_primary: hvac_system_primary,
1152
+ baseboard_type: baseboard_type,
1009
1153
  boiler_fueltype: boiler_fueltype,
1010
1154
  chiller_type: chiller_type,
1011
1155
  fan_type: fan_type,
1156
+ heating_coil_type_sys2: heating_coil_type_sys2,
1012
1157
  heating_coil_type_sys3: heating_coil_type_sys3,
1013
1158
  heating_coil_type_sys4: heating_coil_type_sys4,
1014
1159
  heating_coil_type_sys6: heating_coil_type_sys6,
@@ -1020,12 +1165,16 @@ class NECB2011
1020
1165
  zones: zones,
1021
1166
  necb_reference_hp: necb_reference_hp,
1022
1167
  necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel)
1168
+ # Reset fuel type set back to those defined by the user
1169
+ fuel_type_set.reset_default_fuel_info(init_fuel_type: init_fuel_type)
1023
1170
  end
1024
1171
 
1025
1172
  # This method will ensure that all dwelling units are assigned to a system 1 or 3.
1026
1173
  # There is an option to have a shared AHU or not.
1027
1174
 
1028
- def auto_system_dwelling_units(baseboard_type:,
1175
+ def auto_system_dwelling_units(
1176
+ hvac_system_dwelling_units:,
1177
+ baseboard_type:,
1029
1178
  necb_reference_hp:false,
1030
1179
  necb_reference_hp_supp_fuel:'DefaultFuel',
1031
1180
  boiler_fueltype:,
@@ -1039,7 +1188,10 @@ class NECB2011
1039
1188
  mau_heating_coil_type:,
1040
1189
  mau_type:,
1041
1190
  model:,
1042
- baseline_system_zones_map_option:)
1191
+ baseline_system_zones_map_option:,
1192
+ init_fuel_type:)
1193
+ # Reset fuel type set to those defined by the user
1194
+ fuel_type_set.reset_default_fuel_info(init_fuel_type: init_fuel_type)
1043
1195
  system_zones_hash = {}
1044
1196
  # Determine if dwelling units have a shared AHU. If user entered building stories > 4 then set to true.
1045
1197
  if baseline_system_zones_map_option == 'one_sys_per_dwelling_unit'
@@ -1054,75 +1206,100 @@ class NECB2011
1054
1206
  end
1055
1207
  zones.uniq!
1056
1208
 
1057
- # sort system 1 or 3 used for each dwelling unit as per T8.4.4.8.A NECB 2011-17
1058
- zones.each do |zone|
1059
- system_zones_hash[get_necb_thermal_zone_system_selection(zone)] = [] if system_zones_hash[get_necb_thermal_zone_system_selection(zone)].nil?
1060
- system_zones_hash[get_necb_thermal_zone_system_selection(zone)] << zone
1061
- end
1209
+ if hvac_system_dwelling_units.to_s.downcase == 'necb_default' || hvac_system_dwelling_units.nil?
1062
1210
 
1063
- # go through each system and zones pairs to
1064
- system_zones_hash.each_pair do |system, sys_zones|
1065
- case system
1066
- when 1
1067
- if dwelling_shared_ahu
1068
- add_sys1_unitary_ac_baseboard_heating(model: model,
1069
- necb_reference_hp: necb_reference_hp,
1070
- necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1071
- zones: sys_zones,
1072
- mau_type: mau_type,
1073
- mau_heating_coil_type: mau_heating_coil_type,
1074
- baseboard_type: baseboard_type,
1075
- hw_loop: @hw_loop,
1076
- multispeed: false)
1077
- else
1078
- # Create a separate air loop for each unit.
1079
- sys_zones.each do |zone|
1211
+ # sort system 1 or 3 used for each dwelling unit as per T8.4.4.8.A NECB 2011-17
1212
+ zones.each do |zone|
1213
+ system_zones_hash[get_necb_thermal_zone_system_selection(zone)] = [] if system_zones_hash[get_necb_thermal_zone_system_selection(zone)].nil?
1214
+ system_zones_hash[get_necb_thermal_zone_system_selection(zone)] << zone
1215
+ end # zone
1216
+
1217
+ # go through each system and zones pairs to
1218
+ system_zones_hash.each_pair do |system, sys_zones|
1219
+ case system
1220
+ when 1
1221
+ if dwelling_shared_ahu
1080
1222
  add_sys1_unitary_ac_baseboard_heating(model: model,
1081
1223
  necb_reference_hp: necb_reference_hp,
1082
1224
  necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1083
- zones: [zone],
1225
+ zones: sys_zones,
1084
1226
  mau_type: mau_type,
1085
1227
  mau_heating_coil_type: mau_heating_coil_type,
1086
1228
  baseboard_type: baseboard_type,
1087
1229
  hw_loop: @hw_loop,
1088
1230
  multispeed: false)
1089
- end
1090
- end
1091
-
1092
- when 3
1093
- if dwelling_shared_ahu
1094
- add_sys3and8_single_zone_packaged_rooftop_unit_with_baseboard_heating(model: model,
1095
- necb_reference_hp: necb_reference_hp,
1096
- necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1097
- zones: sys_zones,
1098
- heating_coil_type: heating_coil_type_sys3,
1099
- baseboard_type: baseboard_type,
1100
- hw_loop: @hw_loop,
1101
- multispeed: false)
1102
- else
1103
- # Create a separate air loop for each unit.
1104
- sys_zones.each do |zone|
1231
+ else
1232
+ # Create a separate air loop for each unit.
1233
+ sys_zones.each do |zone|
1234
+ add_sys1_unitary_ac_baseboard_heating(model: model,
1235
+ necb_reference_hp: necb_reference_hp,
1236
+ necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1237
+ zones: [zone],
1238
+ mau_type: mau_type,
1239
+ mau_heating_coil_type: mau_heating_coil_type,
1240
+ baseboard_type: baseboard_type,
1241
+ hw_loop: @hw_loop,
1242
+ multispeed: false)
1243
+ end # if
1244
+ end # when 1
1245
+
1246
+ when 3
1247
+ if dwelling_shared_ahu
1105
1248
  add_sys3and8_single_zone_packaged_rooftop_unit_with_baseboard_heating(model: model,
1106
1249
  necb_reference_hp: necb_reference_hp,
1107
1250
  necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1108
- zones: [zone],
1251
+ zones: sys_zones,
1109
1252
  heating_coil_type: heating_coil_type_sys3,
1110
1253
  baseboard_type: baseboard_type,
1111
1254
  hw_loop: @hw_loop,
1112
1255
  multispeed: false)
1113
- end
1114
- end
1115
- end
1116
- end
1256
+ else
1257
+
1258
+ # Create a separate air loop for each unit.
1259
+ sys_zones.each do |zone|
1260
+ add_sys3and8_single_zone_packaged_rooftop_unit_with_baseboard_heating(model: model,
1261
+ necb_reference_hp: necb_reference_hp,
1262
+ necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1263
+ zones: [zone],
1264
+ heating_coil_type: heating_coil_type_sys3,
1265
+ baseboard_type: baseboard_type,
1266
+ hw_loop: @hw_loop,
1267
+ multispeed: false)
1268
+ end # end zone
1269
+ end # end if
1270
+ end # end when 3
1271
+ end # Sys_zone loop
1272
+ # else # New HVAC system
1273
+ # system_zones_hash.each_pair do |system, sys_zones|
1274
+ # if dwelling_shared_ahu
1275
+ # create_hvac_by_name( model: model,
1276
+ # hvac_system_name: hvac_system_dwelling_units,
1277
+ # zones: sys_zones,
1278
+ # hw_loop: @hw_loop) # Add this method to create the system.
1279
+ # else
1280
+ # # Create a separate air loop for each unit.
1281
+ # sys_zones.each do |zone|
1282
+ # create_hvac_by_name( model: model,
1283
+ # hvac_system_name: hvac_system_dwelling_units,
1284
+ # zones: [zone],
1285
+ # hw_loop: @hw_loop) # Add this method to create the system.
1286
+ # end # zone
1287
+ # end # if
1288
+ # end # Sys_zone loop
1289
+ end # if new HVAC system
1117
1290
  end
1118
1291
 
1119
1292
  # All wet spaces will be on their own system 4 AHU.
1120
- def auto_system_wet_spaces(baseboard_type:,
1293
+ def auto_system_wet_spaces(hvac_system_washrooms: 'NECB_Default',
1294
+ baseboard_type:,
1121
1295
  necb_reference_hp:false,
1122
1296
  necb_reference_hp_supp_fuel:'DefaultFuel',
1123
1297
  boiler_fueltype:,
1124
1298
  heating_coil_type_sys4:,
1125
- model:)
1299
+ model:,
1300
+ init_fuel_type:)
1301
+ # Reset fuel type set to those defined by the user
1302
+ fuel_type_set.reset_default_fuel_info(init_fuel_type: init_fuel_type)
1126
1303
  # Determine what zones are wet zones.
1127
1304
  wet_tz = []
1128
1305
  wet_spaces = model.getSpaces.select { |space| is_an_necb_wet_space?(space) }
@@ -1130,29 +1307,33 @@ class NECB2011
1130
1307
  wet_tz.uniq!
1131
1308
  # create a system 4 for the wet zones.
1132
1309
  return if wet_tz.empty?
1133
-
1134
- add_sys4_single_zone_make_up_air_unit_with_baseboard_heating(model: model,
1135
- necb_reference_hp: necb_reference_hp,
1136
- necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1137
- zones: wet_tz,
1138
- heating_coil_type: heating_coil_type_sys4,
1139
- baseboard_type: baseboard_type,
1140
- hw_loop: @hw_loop)
1141
- # add_sys3and8_single_zone_packaged_rooftop_unit_with_baseboard_heating(model: model,
1142
- # zones: wet_tz,
1143
- # heating_coil_type: heating_coil_type_sys4,
1144
- # baseboard_type: baseboard_type,
1145
- # hw_loop: @hw_loop,
1146
- # multispeed: false)
1310
+ if hvac_system_washrooms.to_s.downcase == 'necb_default' || hvac_system_washrooms.nil?
1311
+ add_sys4_single_zone_make_up_air_unit_with_baseboard_heating(model: model,
1312
+ necb_reference_hp: necb_reference_hp,
1313
+ necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1314
+ zones: wet_tz,
1315
+ heating_coil_type: heating_coil_type_sys4,
1316
+ baseboard_type: baseboard_type,
1317
+ hw_loop: @hw_loop)
1318
+ #else
1319
+ # create_hvac_by_name( model: model,
1320
+ # hvac_system_name: hvac_system_washrooms,
1321
+ # zones: wet_tz,
1322
+ # hw_loop: @hw_loop) # Add this method to create the system.
1323
+ end
1147
1324
  end
1148
1325
 
1149
1326
  # All wet spaces will be on their own system 4 AHU.
1150
- def auto_system_storage_spaces(baseboard_type:,
1327
+ def auto_system_storage_spaces(hvac_system_storage: 'NECB_Default',
1328
+ baseboard_type:,
1151
1329
  necb_reference_hp:false,
1152
1330
  necb_reference_hp_supp_fuel:'DefaultFuel',
1153
1331
  boiler_fueltype:,
1154
1332
  heating_coil_type_sys4:,
1155
- model:)
1333
+ model:,
1334
+ init_fuel_type:)
1335
+ # Reset fuel type set to those defined by the user
1336
+ fuel_type_set.reset_default_fuel_info(init_fuel_type: init_fuel_type)
1156
1337
  # Determine what zones are storage zones.
1157
1338
  tz = []
1158
1339
  storage_spaces = model.getSpaces.select { |space| is_an_necb_storage_space?(space) }
@@ -1160,29 +1341,34 @@ class NECB2011
1160
1341
  tz.uniq!
1161
1342
 
1162
1343
  return if tz.empty?
1344
+ if hvac_system_storage.to_s.downcase == 'necb_default' || hvac_system_storage.nil?
1345
+ # create a system 4 for the zones.
1346
+ add_sys4_single_zone_make_up_air_unit_with_baseboard_heating(model: model,
1347
+ necb_reference_hp: necb_reference_hp,
1348
+ necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1349
+ zones: tz,
1350
+ heating_coil_type: heating_coil_type_sys4,
1351
+ baseboard_type: baseboard_type,
1352
+ hw_loop: @hw_loop)
1353
+ #else
1354
+ # create_hvac_by_name(model: model,
1355
+ # hvac_system_name: hvac_system_storage,
1356
+ # zones: tz,
1357
+ # hw_loop: @hw_loop) # Add this method to create the system.
1358
+ end
1163
1359
 
1164
- # create a system 4 for the zones.
1165
- add_sys4_single_zone_make_up_air_unit_with_baseboard_heating(model: model,
1166
- necb_reference_hp: necb_reference_hp,
1167
- necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1168
- zones: tz,
1169
- heating_coil_type: heating_coil_type_sys4,
1170
- baseboard_type: baseboard_type,
1171
- hw_loop: @hw_loop)
1172
- # add_sys3and8_single_zone_packaged_rooftop_unit_with_baseboard_heating(model: model,
1173
- # zones: tz,
1174
- # heating_coil_type: heating_coil_type_sys4,
1175
- # baseboard_type: baseboard_type,
1176
- # hw_loop: @hw_loop,
1177
- # multispeed: true)
1178
1360
  end
1179
1361
 
1180
1362
  # All wild spaces will be on a single system 4 ahu with the largests heating load zone being the control zone.
1181
- def auto_system_wild_spaces(baseboard_type:,
1182
- necb_reference_hp:false,
1183
- necb_reference_hp_supp_fuel:'Defaultfuel',
1363
+ def auto_system_wild_spaces(hvac_system_corridor: 'NECB_Default',
1364
+ baseboard_type:,
1365
+ necb_reference_hp: false,
1366
+ necb_reference_hp_supp_fuel: 'Defaultfuel',
1184
1367
  heating_coil_type_sys4:,
1185
- model:)
1368
+ model:,
1369
+ init_fuel_type:)
1370
+ # Reset fuel type set to those defined by the user
1371
+ fuel_type_set.reset_default_fuel_info(init_fuel_type: init_fuel_type)
1186
1372
 
1187
1373
  zones = []
1188
1374
  wild_spaces = model.getSpaces.select { |space| !is_an_necb_wet_space?(space) && is_an_necb_wildcard_space?(space) }
@@ -1191,20 +1377,21 @@ class NECB2011
1191
1377
 
1192
1378
  return if zones.empty?
1193
1379
 
1194
- # create a system 4 for the wild zones.
1195
- add_sys4_single_zone_make_up_air_unit_with_baseboard_heating(model: model,
1196
- necb_reference_hp: necb_reference_hp,
1197
- necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1198
- zones: zones,
1199
- heating_coil_type: heating_coil_type_sys4,
1200
- baseboard_type: baseboard_type,
1201
- hw_loop: @hw_loop)
1202
- # add_sys3and8_single_zone_packaged_rooftop_unit_with_baseboard_heating(model: model,
1203
- # zones: zones,
1204
- # heating_coil_type: heating_coil_type_sys4,
1205
- # baseboard_type: baseboard_type,
1206
- # hw_loop: @hw_loop,
1207
- # multispeed: true)
1380
+ if hvac_system_corridor.to_s.downcase == 'necb_default' || hvac_system_corridor.nil?
1381
+ # create a system 4 for the wild zones.
1382
+ add_sys4_single_zone_make_up_air_unit_with_baseboard_heating(model: model,
1383
+ necb_reference_hp: necb_reference_hp,
1384
+ necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1385
+ zones: zones,
1386
+ heating_coil_type: heating_coil_type_sys4,
1387
+ baseboard_type: baseboard_type,
1388
+ hw_loop: @hw_loop)
1389
+ #else
1390
+ # create_hvac_by_name( model: model,
1391
+ # hvac_system_name: hvac_system_corridor,
1392
+ # zones: zones,
1393
+ # hw_loop: @hw_loop) # Add this method to create the system.
1394
+ end
1208
1395
  end
1209
1396
 
1210
1397
  # This method will determine the control zone from the last sizing run space loads.
@@ -1265,4 +1452,204 @@ class NECB2011
1265
1452
  rendering_color.setRenderingBlueValue(random.rand(255))
1266
1453
  return rendering_color
1267
1454
  end
1455
+
1456
+ def create_hvac_by_name(model:, hvac_system_name:, zones:, hw_loop: nil)
1457
+ # Get the HVAC system properties
1458
+ # Get the HVAC system properties from lib/openstudio-standards/standards/necb/NECB2011/data/systems.json from description field.
1459
+ hvac_system_data = self.standards_data['hvac_types'].find { |system| system['description'] == hvac_system_name }
1460
+ raise("Could not find hvac_system_data for #{hvac_system_name}") if hvac_system_data.nil?
1461
+ necb_reference_hp_supp_fuel = hvac_system_data['necb_reference_hp_supp_fuel']
1462
+ necb_reference_hp_supp_fuel = 'Hot Water' if self.fuel_type_set.force_airloop_hot_water
1463
+ mau_heating_coil_type = hvac_system_data['mau_heating_type']
1464
+ baseboard_type = hvac_system_data['baseboard_type']
1465
+ baseboard_type = self.fuel_type_set.baseboard_type if self.fuel_type_set.force_boiler
1466
+ heating_coil_type = hvac_system_data['heating_coil_type']
1467
+
1468
+ case hvac_system_data['system']
1469
+ when 'sys_1'
1470
+ mau_heating_coil_type = self.fuel_type_set.mau_heating_coil_type if self.fuel_type_set.force_airloop_hot_water && mau_heating_coil_type != 'DX'
1471
+ add_sys1_unitary_ac_baseboard_heating_single_speed(
1472
+ model: model,
1473
+ necb_reference_hp: hvac_system_data['necb_reference_hp'],
1474
+ necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1475
+ zones: zones,
1476
+ mau_type: hvac_system_data['mau_type'],
1477
+ mau_heating_coil_type: mau_heating_coil_type,
1478
+ baseboard_type: baseboard_type,
1479
+ hw_loop: hw_loop
1480
+ )
1481
+ when 'sys_2'
1482
+ add_sys2_FPFC_sys5_TPFC( model: model,
1483
+ zones:zones,
1484
+ chiller_type: hvac_system_data['chiller_type'],
1485
+ fan_coil_type: hvac_system_data['fan_coil_type'],
1486
+ mau_cooling_type: hvac_system_data['mau_cooling_type'],
1487
+ hw_loop: hw_loop)
1488
+ when 'sys_3'
1489
+ heating_coil_type = self.fuel_type_set.heating_coil_type_sys3 if self.fuel_type_set.force_airloop_hot_water && heating_coil_type != 'DX'
1490
+ add_sys3and8_single_zone_packaged_rooftop_unit_with_baseboard_heating_single_speed(
1491
+ model: model,
1492
+ necb_reference_hp: hvac_system_data['necb_reference_hp'],
1493
+ necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1494
+ zones: zones,
1495
+ heating_coil_type: heating_coil_type,
1496
+ baseboard_type: baseboard_type,
1497
+ hw_loop: hw_loop,
1498
+ new_auto_zoner: true)
1499
+ when 'sys_4'
1500
+ heating_coil_type = self.fuel_type_set.heating_coil_type_sys4 if self.fuel_type_set.force_airloop_hot_water && heating_coil_type != 'DX'
1501
+ add_sys4_single_zone_make_up_air_unit_with_baseboard_heating(model: model,
1502
+ necb_reference_hp: hvac_system_data['necb_reference_hp'],
1503
+ necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel,
1504
+ zones: zones,
1505
+ heating_coil_type: heating_coil_type,
1506
+ baseboard_type: baseboard_type,
1507
+ hw_loop: hw_loop)
1508
+ when 'sys_5'
1509
+ add_sys2_FPFC_sys5_TPFC( model: model,
1510
+ zones:zones,
1511
+ chiller_type: hvac_system_data['chiller_type'],
1512
+ fan_coil_type: hvac_system_data['fan_coil_type'],
1513
+ mau_cooling_type: hvac_system_data['mau_cooling_type'],
1514
+ hw_loop: hw_loop)
1515
+ when 'sys_6'
1516
+ heating_coil_type = self.fuel_type_set.heating_coil_type_sys6 if self.fuel_type_set.force_airloop_hot_water && heating_coil_type != 'DX'
1517
+ if heating_coil_type == 'DX'
1518
+ add_sys6_multi_zone_reference_hp_with_baseboard_heating(model: model,
1519
+ zones: zones,
1520
+ heating_coil_type: heating_coil_type,
1521
+ baseboard_type: baseboard_type,
1522
+ hw_loop: hw_loop,
1523
+ necb_reference_hp_supp_fuel: necb_reference_hp_supp_fuel)
1524
+ else
1525
+ add_sys6_multi_zone_built_up_system_with_baseboard_heating(
1526
+ model:model,
1527
+ zones:zones,
1528
+ heating_coil_type: heating_coil_type,
1529
+ baseboard_type: baseboard_type,
1530
+ chiller_type: hvac_system_data['chiller_type'],
1531
+ fan_type: hvac_system_data['fan_type'],
1532
+ hw_loop: hw_loop
1533
+ )
1534
+ end
1535
+ end
1536
+
1537
+ end
1538
+
1539
+ # Method will check if the spaces passed to it will require a hot water loop based on their associated system type.
1540
+ def hw_loop_required_from_spaces(spaces:, mau_heating_coil_type:, baseboard_type:, heating_coil_type_sys2:, heating_coil_type_sys3:, heating_coil_type_sys4:, heating_coil_type_sys6:)
1541
+ hw_loop_needed = false
1542
+ systems_used = []
1543
+
1544
+ # Find the space type for each space and get the system type associated with each space type
1545
+ spaces.sort.each do |space|
1546
+ space_system = get_necb_spacetype_system_selection(space)
1547
+ space_system = 4 if space_system.nil? && (is_an_necb_storage_space?(space) || is_an_necb_wet_space?(space) || is_an_necb_wildcard_space?(space))
1548
+ systems_used << space_system
1549
+ systems_used.uniq!
1550
+ end
1551
+
1552
+ # See if we need to create a hot water loop based on fueltype and systems used.
1553
+ systems_used.each do |system|
1554
+ case system.to_s
1555
+ when '2', '5', '7'
1556
+ hw_loop_needed = true
1557
+ when '1', '6'
1558
+ if (mau_heating_coil_type == 'Hot Water') || (baseboard_type == 'Hot Water') || (mau_heating_coil_type == 'HotWater') || baseboard_type == 'HotWater' || (heating_coil_type_sys6 == 'HotWater') || (heating_coil_type_sys6 == 'Hot Water')
1559
+ hw_loop_needed = true
1560
+ end
1561
+ when '3', '4'
1562
+ if (mau_heating_coil_type == 'Hot Water') || (baseboard_type == 'Hot Water') || (mau_heating_coil_type == 'HotWater') || baseboard_type == 'HotWater' || (heating_coil_type_sys4 == 'HotWater') || (heating_coil_type_sys4 == 'Hot Water') || (heating_coil_type_sys3 == 'HotWater') || (heating_coil_type_sys3 == 'Hot Water')
1563
+ hw_loop_needed = true if baseboard_type == 'Hot Water'
1564
+ hw_loop_needed = true if (mau_heating_coil_type == 'Hot Water') || (mau_heating_coil_type == 'HotWater') || (heating_coil_type_sys4 == 'HotWater') || (heating_coil_type_sys4 == 'Hot Water') || (heating_coil_type_sys3 == 'HotWater') || (heating_coil_type_sys3 == 'Hot Water')
1565
+ end
1566
+ end
1567
+ if hw_loop_needed
1568
+ # just need one true condition to need a boiler.
1569
+ break
1570
+ end
1571
+ # each
1572
+ end
1573
+ return hw_loop_needed
1574
+ end
1575
+
1576
+ # Method to determine if dwelling_units, washrooms, corridors, or storage spaces should be added to the common HVAC system.
1577
+ def spaces_to_add_to_common_system(model:, hvac_system_dwelling_units: nil, hvac_system_washrooms: nil, hvac_system_corridor: nil, hvac_system_storage: nil)
1578
+ common_spaces = []
1579
+ # Find Dwelling Units and determine if they should be added
1580
+ dwelling_units = model.getSpaces.select { |space| is_a_necb_dwelling_unit?(space) }
1581
+ unless dwelling_units.empty? || hvac_system_dwelling_units.nil? || hvac_system_dwelling_units.to_s.downcase == 'necb_default'
1582
+ # If a dwelling unit hvac system is defined and dwelling units are present then add them to them to the common_spaces
1583
+ common_spaces = common_spaces + dwelling_units
1584
+ end
1585
+
1586
+ # Find washrooms and determine if they should be added
1587
+ washroom_spaces = model.getSpaces.select { |space| is_an_necb_wet_space?(space) }
1588
+ unless washroom_spaces.empty? || hvac_system_washrooms.nil? || hvac_system_washrooms.to_s.downcase == 'necb_default'
1589
+ # If a washroom hvac system is defined and washrooms/wet spaces are present then add them to the common_spaces
1590
+ common_spaces = common_spaces + washroom_spaces
1591
+ end
1592
+
1593
+ # Find corridors and determine if they should be added
1594
+ corridor_spaces = model.getSpaces.select { |space| is_an_necb_wildcard_space?(space) }
1595
+ unless corridor_spaces.empty? || hvac_system_corridor.nil? || hvac_system_corridor.to_s.downcase == 'necb_default'
1596
+ # If a corridor hvac system is defined and corridors are present then add them to the common spaces
1597
+ common_spaces = common_spaces + corridor_spaces
1598
+ end
1599
+
1600
+ # Find storage spaces and determine if they should be added
1601
+ storage_spaces = model.getSpaces.select { |space| is_an_necb_storage_space?(space) }
1602
+ unless storage_spaces.empty? || hvac_system_storage.nil? || hvac_system_storage.to_s.downcase == 'necb_default'
1603
+ # If a storage space hvac system is defined and storage spaces are present then add them to the common spaces
1604
+ common_spaces = common_spaces + storage_spaces
1605
+ end
1606
+ return common_spaces
1607
+ end
1608
+
1609
+ def get_fuel_type_information()
1610
+ init_fuel_type = {
1611
+ name: fuel_type_set.name,
1612
+ boiler_fueltype: fuel_type_set.boiler_fueltype,
1613
+ backup_boiler_fueltype: fuel_type_set.backup_boiler_fueltype,
1614
+ primary_boiler_cap_frac: fuel_type_set.primary_boiler_cap_frac,
1615
+ secondary_boiler_cap_frac: fuel_type_set.secondary_boiler_cap_frac,
1616
+ baseboard_type: fuel_type_set.baseboard_type,
1617
+ mau_type: fuel_type_set.mau_type,
1618
+ mau_heating_coil_type: fuel_type_set.mau_heating_coil_type,
1619
+ mau_cooling_type: fuel_type_set.mau_cooling_type,
1620
+ chiller_type: fuel_type_set.chiller_type,
1621
+ heating_coil_type_sys2: fuel_type_set.heating_coil_type_sys2,
1622
+ heating_coil_type_sys3: fuel_type_set.heating_coil_type_sys3,
1623
+ heating_coil_type_sys4: fuel_type_set.heating_coil_type_sys4,
1624
+ heating_coil_type_sys6: fuel_type_set.heating_coil_type_sys6,
1625
+ necb_reference_hp: fuel_type_set.necb_reference_hp,
1626
+ necb_reference_hp_supp_fuel: fuel_type_set.necb_reference_hp_supp_fuel,
1627
+ fan_type: fuel_type_set.fan_type,
1628
+ ecm_fueltype: fuel_type_set.ecm_fueltype,
1629
+ swh_fueltype: fuel_type_set.swh_fueltype,
1630
+ force_boiler: fuel_type_set.force_boiler,
1631
+ force_airloop_hot_water: fuel_type_set.force_airloop_hot_water
1632
+ }
1633
+ return init_fuel_type
1634
+ end
1635
+
1636
+ def boiler_required_from_heating_coils(sys_type:, mau_heating_coil_type:, heating_coil_type_sys2:, heating_coil_type_sys3:, heating_coil_type_sys4:, heating_coil_type_sys6:)
1637
+ requires_boiler = false
1638
+ case sys_type.to_s
1639
+ when 'sys_1'
1640
+ requires_boiler = true if mau_heating_coil_type.to_s == "Hot Water" || mau_heating_coil_type.to_s == "HotWater"
1641
+ when 'sys_2'
1642
+ requires_boiler = true if heating_coil_type_sys2.to_s == "Hot Water" || heating_coil_type_sys2.to_s == "HotWater"
1643
+ when 'sys_3'
1644
+ requires_boiler = true if heating_coil_type_sys3.to_s == "Hot Water" || heating_coil_type_sys3.to_s == "HotWater"
1645
+ when 'sys_4'
1646
+ requires_boiler = true if heating_coil_type_sys4.to_s == "Hot Water" || heating_coil_type_sys4.to_s == "HotWater"
1647
+ when 'sys_6'
1648
+ requires_boiler = true if heating_coil_type_sys6.to_s == "Hot Water" || heating_coil_type_sys6.to_s == "HotWater"
1649
+ else
1650
+ requires_boiler = false
1651
+ end
1652
+ return requires_boiler
1653
+ end
1654
+
1268
1655
  end