openstudio-extension 0.7.1 → 0.8.0

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 (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +14 -0
  4. data/LICENSE.md +1 -1
  5. data/README.md +2 -0
  6. data/lib/openstudio/extension/runner.rb +12 -8
  7. data/lib/openstudio/extension/runner_config.rb +33 -6
  8. data/lib/openstudio/extension/version.rb +1 -1
  9. data/openstudio-extension.gemspec +6 -6
  10. metadata +15 -66
  11. data/lib/openstudio/extension/core/CreateResults.rb +0 -1033
  12. data/lib/openstudio/extension/core/check_air_sys_temps.rb +0 -160
  13. data/lib/openstudio/extension/core/check_calibration.rb +0 -125
  14. data/lib/openstudio/extension/core/check_cond_zns.rb +0 -54
  15. data/lib/openstudio/extension/core/check_domestic_hot_water.rb +0 -304
  16. data/lib/openstudio/extension/core/check_envelope_conductance.rb +0 -423
  17. data/lib/openstudio/extension/core/check_eui_by_end_use.rb +0 -132
  18. data/lib/openstudio/extension/core/check_eui_reasonableness.rb +0 -105
  19. data/lib/openstudio/extension/core/check_fan_pwr.rb +0 -68
  20. data/lib/openstudio/extension/core/check_internal_loads.rb +0 -363
  21. data/lib/openstudio/extension/core/check_mech_sys_capacity.rb +0 -196
  22. data/lib/openstudio/extension/core/check_mech_sys_efficiency.rb +0 -296
  23. data/lib/openstudio/extension/core/check_mech_sys_part_load_eff.rb +0 -434
  24. data/lib/openstudio/extension/core/check_mech_sys_type.rb +0 -109
  25. data/lib/openstudio/extension/core/check_part_loads.rb +0 -421
  26. data/lib/openstudio/extension/core/check_placeholder.rb +0 -45
  27. data/lib/openstudio/extension/core/check_plant_cap.rb +0 -93
  28. data/lib/openstudio/extension/core/check_plant_temps.rb +0 -129
  29. data/lib/openstudio/extension/core/check_plenum_loads.rb +0 -57
  30. data/lib/openstudio/extension/core/check_pump_pwr.rb +0 -78
  31. data/lib/openstudio/extension/core/check_sch_coord.rb +0 -211
  32. data/lib/openstudio/extension/core/check_schedules.rb +0 -281
  33. data/lib/openstudio/extension/core/check_simultaneous_heating_and_cooling.rb +0 -128
  34. data/lib/openstudio/extension/core/check_supply_air_and_thermostat_temp_difference.rb +0 -118
  35. data/lib/openstudio/extension/core/check_weather_files.rb +0 -102
  36. data/lib/openstudio/extension/core/deer_vintages.rb +0 -281
  37. data/lib/openstudio/extension/core/os_lib_aedg_measures.rb +0 -461
  38. data/lib/openstudio/extension/core/os_lib_constructions.rb +0 -353
  39. data/lib/openstudio/extension/core/os_lib_geometry.rb +0 -1169
  40. data/lib/openstudio/extension/core/os_lib_helper_methods.rb +0 -383
  41. data/lib/openstudio/extension/core/os_lib_hvac.rb +0 -2163
  42. data/lib/openstudio/extension/core/os_lib_lighting_and_equipment.rb +0 -184
  43. data/lib/openstudio/extension/core/os_lib_model_generation.rb +0 -3584
  44. data/lib/openstudio/extension/core/os_lib_model_simplification.rb +0 -1019
  45. data/lib/openstudio/extension/core/os_lib_outdoorair_and_infiltration.rb +0 -135
  46. data/lib/openstudio/extension/core/os_lib_reporting_qaqc.rb +0 -170
  47. data/lib/openstudio/extension/core/os_lib_schedules.rb +0 -933
@@ -1,2163 +0,0 @@
1
- # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
- # See also https://openstudio.net/license
4
- # *******************************************************************************
5
-
6
- module OsLib_HVAC
7
- # do something
8
- def self.doSomething(input)
9
- # do something
10
- output = input
11
-
12
- result = output
13
- return result
14
- end
15
-
16
- # validate and make plenum zones
17
- def self.validateAndAddPlenumZonesToSystem(model, runner, options = {})
18
- # set defaults to use if user inputs not passed in
19
- defaults = {
20
- 'zonesPlenum' => nil,
21
- 'zonesPrimary' => nil,
22
- 'type' => 'ceilingReturn'
23
- }
24
-
25
- # merge user inputs with defaults
26
- options = defaults.merge(options)
27
-
28
- # array of valid ceiling plenums
29
- zoneSurfaceHash = {}
30
- zonePlenumHash = {}
31
-
32
- if options['zonesPlenum'].nil?
33
- runner.registerWarning('No plenum zones were passed in, validateAndAddPlenumZonesToSystem will not alter the model.')
34
- else
35
- options['zonesPlenum'].each do |zone|
36
- # get spaces in zone
37
- spaces = zone.spaces
38
- # get adjacent spaces
39
- spaces.each do |space|
40
- # get surfaces
41
- surfaces = space.surfaces
42
- # loop through surfaces looking for floors with surface boundary condition, grab zone that surface's parent space is in.
43
- surfaces.each do |surface|
44
- if (surface.outsideBoundaryCondition == 'Surface') && (surface.surfaceType == 'Floor')
45
- next if surface.adjacentSurface.empty?
46
- adjacentSurface = surface.adjacentSurface.get
47
- next if adjacentSurface.space.empty?
48
- adjacentSurfaceSpace = adjacentSurface.space.get
49
- next if adjacentSurfaceSpace.thermalZone.empty?
50
- adjacentSurfaceSpaceZone = adjacentSurfaceSpace.thermalZone.get
51
- if options['zonesPrimary'].include? adjacentSurfaceSpaceZone
52
- if zoneSurfaceHash[adjacentSurfaceSpaceZone].nil? || (surface.grossArea > zoneSurfaceHash[adjacentSurfaceSpaceZone])
53
- adjacentSurfaceSpaceZone.setReturnPlenum(zone)
54
- zoneSurfaceHash[adjacentSurfaceSpaceZone] = surface.grossArea
55
- zonePlenumHash[adjacentSurfaceSpaceZone] = zone
56
- end
57
- end
58
- end
59
- end
60
- end
61
- end
62
- end
63
-
64
- # report out results of zone-plenum hash
65
- zonePlenumHash.each do |zone, plenum|
66
- runner.registerInfo("#{plenum.name} has been set as a return air plenum for #{zone.name}.")
67
- end
68
-
69
- # pass back zone-plenum hash
70
- result = zonePlenumHash
71
- return result
72
- end
73
-
74
- def self.sortZones(model, runner, options = {})
75
- # set defaults to use if user inputs not passed in
76
- defaults = { 'standardBuildingTypeTest' => nil, # not used for now
77
- 'secondarySpaceTypeTest' => nil,
78
- 'ceilingReturnPlenumSpaceType' => nil }
79
-
80
- # merge user inputs with defaults
81
- options = defaults.merge(options)
82
-
83
- # set up zone type arrays
84
- zonesPrimary = []
85
- zonesSecondary = []
86
- zonesPlenum = []
87
- zonesUnconditioned = []
88
-
89
- # get thermal zones
90
- zones = model.getThermalZones.sort
91
- zones.each do |zone|
92
- # assign appropriate zones to zonesPlenum or zonesUnconditioned (those that don't have thermostats or zone HVAC equipment)
93
- # if not conditioned then add to zonesPlenum or zonesUnconditioned
94
- if zone.thermostatSetpointDualSetpoint.is_initialized || !zone.equipment.empty?
95
- # zone is conditioned. check if its space type is secondary or primary
96
- spaces = zone.spaces
97
- spaces.each do |space|
98
- # if a zone has already been assigned as secondary, skip
99
- next if zonesSecondary.include? zone
100
- # get space type if it exists
101
- next if space.spaceType.empty?
102
- spaceType = space.spaceType.get
103
- # get standards information
104
- # for now skip standardsBuildingType and just rely on the standardsSpaceType. Seems like enough.
105
- next if spaceType.standardsSpaceType.empty?
106
- standardSpaceType = spaceType.standardsSpaceType.get
107
- # test space type against secondary space type array
108
- # if any space type in zone is secondary, assign zone as secondary
109
- if options['secondarySpaceTypeTest'].include? standardSpaceType
110
- zonesSecondary << zone
111
- end
112
- end
113
- # if zone not assigned as secondary, assign as primary
114
- unless zonesSecondary.include? zone
115
- zonesPrimary << zone
116
- end
117
- else
118
- # determine if zone is a plenum zone or general unconditioned zone
119
- # assume it is a plenum if it has at least one planum space
120
- zone.spaces.each do |space|
121
- # if a zone has already been assigned as a plenum, skip
122
- next if zonesPlenum.include? zone
123
- # if zone not assigned as a plenum, get space type if it exists
124
- # compare to plenum space type if it has been assigned
125
- if space.spaceType.is_initialized && (options['ceilingReturnPlenumSpaceType'].nil? == false)
126
- spaceType = space.spaceType.get
127
- if spaceType == options['ceilingReturnPlenumSpaceType']
128
- zonesPlenum << zone # zone has a plenum space; assign it as a plenum
129
- end
130
- end
131
- end
132
- # if zone not assigned as a plenum, assign it as unconditioned
133
- unless zonesPlenum.include? zone
134
- zonesUnconditioned << zone
135
- end
136
- end
137
- end
138
-
139
- zonesSorted = { 'zonesPrimary' => zonesPrimary,
140
- 'zonesSecondary' => zonesSecondary,
141
- 'zonesPlenum' => zonesPlenum,
142
- 'zonesUnconditioned' => zonesUnconditioned }
143
- # pass back zonesSorted hash
144
- result = zonesSorted
145
- return result
146
- end
147
-
148
- def self.reportConditions(model, runner, condition,extra_string = '')
149
-
150
- airloops = model.getAirLoopHVACs.sort
151
- plantLoops = model.getPlantLoops.sort
152
- zones = model.getThermalZones.sort
153
-
154
- # count up zone equipment (not counting zone exhaust fans)
155
- zoneHasEquip = false
156
- zonesWithEquipCounter = 0
157
-
158
- zones.each do |zone|
159
- if zone.equipment.size > 0
160
- zone.equipment.each do |equip|
161
- unless equip.to_FanZoneExhaust.is_initialized
162
- zonesWithEquipCounter += 1
163
- break
164
- end
165
- end
166
- end
167
- end
168
-
169
- if condition == "initial"
170
- runner.registerInitialCondition("The building started with #{airloops.size} air loops and #{plantLoops.size} plant loops. #{zonesWithEquipCounter} zones were conditioned with zone equipment.")
171
- elsif condition == "final"
172
- runner.registerFinalCondition("The building finished with #{airloops.size} air loops and #{plantLoops.size} plant loops. #{zonesWithEquipCounter} zones are conditioned with zone equipment. #{extra_string}")
173
- end
174
-
175
- end
176
-
177
- def self.removeEquipment(model, runner)
178
- airloops = model.getAirLoopHVACs.sort
179
- plantLoops = model.getPlantLoops.sort
180
- zones = model.getThermalZones.sort
181
-
182
- # remove all airloops
183
- airloops.each(&:remove)
184
-
185
- # remove all zone equipment except zone exhaust fans
186
- zones.each do |zone|
187
- zone.equipment.each do |equip|
188
- if equip.to_FanZoneExhaust.is_initialized
189
- else
190
- equip.remove
191
- end
192
- end
193
- end
194
-
195
- # remove plant loops
196
- plantLoops.each do |plantloop|
197
- # get the demand components and see if water use connection, then save it
198
- # notify user with info statement if supply side of plant loop had heat exchanger for refrigeration
199
- usedForSHWorRefrigeration = false
200
- plantloop.demandComponents.each do |comp| # AP code to check your comments above
201
- if comp.to_WaterUseConnections.is_initialized || comp.to_CoilWaterHeatingDesuperheater.is_initialized
202
- usedForSHWorRefrigeration = true
203
- end
204
- end
205
- if usedForSHWorRefrigeration == false
206
- plantloop.remove
207
- else
208
- runner.registerWarning("#{plantloop.name} is used for SHW or refrigeration heat reclaim. Loop will not be deleted")
209
- end
210
- end
211
- end
212
-
213
- def self.assignHVACSchedules(model, runner, options = {})
214
- require "#{File.dirname(__FILE__)}/os_lib_schedules"
215
-
216
- schedulesHVAC = {}
217
- airloops = model.getAirLoopHVACs.sort
218
-
219
- # find airloop with most primary spaces
220
- max_primary_spaces = 0
221
- representative_airloop = false
222
- building_HVAC_schedule = false
223
- building_ventilation_schedule = false
224
- unless options['remake_schedules']
225
- # if remake schedules not selected, get relevant schedules from model if they exist
226
- airloops.each do |air_loop|
227
- primary_spaces = 0
228
- air_loop.thermalZones.each do |thermal_zone|
229
- thermal_zone.spaces.each do |space|
230
- if space.spaceType.is_initialized
231
- if space.spaceType.get.name.get.include? options['primarySpaceType']
232
- primary_spaces += 1
233
- end
234
- end
235
- end
236
- end
237
- if primary_spaces > max_primary_spaces
238
- max_primary_spaces = primary_spaces
239
- representative_airloop = air_loop
240
- end
241
- end
242
- end
243
- if representative_airloop
244
- building_HVAC_schedule = representative_airloop.availabilitySchedule
245
- building_ventilation_schedule_optional = representative_airloop.airLoopHVACOutdoorAirSystem.get.getControllerOutdoorAir.maximumFractionofOutdoorAirSchedule
246
- if building_ventilation_schedule_optional.is_initialized
247
- building_ventilation_schedule = building_ventilation_schedule.get
248
- end
249
- end
250
- # build new airloop schedules if existing model doesn't have them
251
- if options['primarySpaceType'] == 'Classroom'
252
- # ventilation schedule
253
- unless building_ventilation_schedule
254
- ruleset_name = 'AEDG K-12 Ventilation Schedule'
255
- winter_design_day = [[24, 1]]
256
- summer_design_day = [[24, 1]]
257
- default_day = ['Weekday', [6, 0], [18, 1], [24, 0]]
258
- rules = []
259
- rules << ['Weekend', '1/1-12/31', 'Sat/Sun', [24, 0]]
260
- rules << ['Summer Weekday', '7/1-8/31', 'Mon/Tue/Wed/Thu/Fri', [8, 0], [13, 1], [24, 0]]
261
- options_ventilation = { 'name' => ruleset_name,
262
- 'winter_design_day' => winter_design_day,
263
- 'summer_design_day' => summer_design_day,
264
- 'default_day' => default_day,
265
- 'rules' => rules }
266
- building_ventilation_schedule = OsLib_Schedules.createComplexSchedule(model, options_ventilation)
267
- end
268
- # HVAC availability schedule
269
- unless building_HVAC_schedule
270
- ruleset_name = 'AEDG K-12 HVAC Availability Schedule'
271
- winter_design_day = [[24, 1]]
272
- summer_design_day = [[24, 1]]
273
- default_day = ['Weekday', [6, 0], [18, 1], [24, 0]]
274
- rules = []
275
- rules << ['Weekend', '1/1-12/31', 'Sat/Sun', [24, 0]]
276
- rules << ['Summer Weekday', '7/1-8/31', 'Mon/Tue/Wed/Thu/Fri', [8, 0], [13, 1], [24, 0]]
277
- options_hvac = { 'name' => ruleset_name,
278
- 'winter_design_day' => winter_design_day,
279
- 'summer_design_day' => summer_design_day,
280
- 'default_day' => default_day,
281
- 'rules' => rules }
282
- building_HVAC_schedule = OsLib_Schedules.createComplexSchedule(model, options_hvac)
283
- end
284
- elsif options['primarySpaceType'] == 'Office'
285
- # ventilation schedule
286
- unless building_ventilation_schedule
287
- ruleset_name = 'AEDG Office Ventilation Schedule'
288
- winter_design_day = [[24, 1]] # ML These are not always on in PNNL model
289
- summer_design_day = [[24, 1]] # ML These are not always on in PNNL model
290
- default_day = ['Weekday', [7, 0], [22, 1], [24, 0]] # ML PNNL has a one hour ventilation offset
291
- rules = []
292
- rules << ['Saturday', '1/1-12/31', 'Sat', [7, 0], [18, 1], [24, 0]] # ML PNNL has a one hour ventilation offset
293
- rules << ['Sunday', '1/1-12/31', 'Sun', [24, 0]]
294
- options_ventilation = { 'name' => ruleset_name,
295
- 'winter_design_day' => winter_design_day,
296
- 'summer_design_day' => summer_design_day,
297
- 'default_day' => default_day,
298
- 'rules' => rules }
299
- building_ventilation_schedule = OsLib_Schedules.createComplexSchedule(model, options_ventilation)
300
- end
301
- # HVAC availability schedule
302
- unless building_HVAC_schedule
303
- ruleset_name = 'AEDG Office HVAC Availability Schedule'
304
- winter_design_day = [[24, 1]] # ML These are not always on in PNNL model
305
- summer_design_day = [[24, 1]] # ML These are not always on in PNNL model
306
- default_day = ['Weekday', [6, 0], [22, 1], [24, 0]] # ML PNNL has a one hour ventilation offset
307
- rules = []
308
- rules << ['Saturday', '1/1-12/31', 'Sat', [6, 0], [18, 1], [24, 0]] # ML PNNL has a one hour ventilation offset
309
- rules << ['Sunday', '1/1-12/31', 'Sun', [24, 0]]
310
- options_hvac = { 'name' => ruleset_name,
311
- 'winter_design_day' => winter_design_day,
312
- 'summer_design_day' => summer_design_day,
313
- 'default_day' => default_day,
314
- 'rules' => rules }
315
- building_HVAC_schedule = OsLib_Schedules.createComplexSchedule(model, options_hvac)
316
- end
317
- # special loops for radiant system (different temperature setpoints)
318
- if options['allHVAC']['zone'] == 'Radiant'
319
- # create hot water schedule for radiant heating loop
320
- schedulesHVAC['radiant_hot_water'] = OsLib_Schedules.createComplexSchedule(model, 'name' => 'AEDG HW-Radiant-Loop-Temp-Schedule',
321
- 'default_day' => ['All Days', [24, 45.0]])
322
- # create hot water schedule for radiant cooling loop
323
- schedulesHVAC['radiant_chilled_water'] = OsLib_Schedules.createComplexSchedule(model, 'name' => 'AEDG CW-Radiant-Loop-Temp-Schedule',
324
- 'default_day' => ['All Days', [24, 15.0]])
325
- # create mean radiant heating and cooling setpoint schedules
326
- # ML ideally, should grab schedules tied to zone thermostat and make modified versions that follow the setback pattern
327
- # for now, create new ones that match the recommended HVAC schedule
328
- # mean radiant heating setpoint schedule (PNNL values)
329
- ruleset_name = 'AEDG Office Mean Radiant Heating Setpoint Schedule'
330
- winter_design_day = [[24, 18.8]]
331
- summer_design_day = [[6, 18.3], [22, 18.8], [24, 18.3]]
332
- default_day = ['Weekday', [6, 18.3], [22, 18.8], [24, 18.3]]
333
- rules = []
334
- rules << ['Saturday', '1/1-12/31', 'Sat', [6, 18.3], [18, 18.8], [24, 18.3]]
335
- rules << ['Sunday', '1/1-12/31', 'Sun', [24, 18.3]]
336
- options_radiant_heating = { 'name' => ruleset_name,
337
- 'winter_design_day' => winter_design_day,
338
- 'summer_design_day' => summer_design_day,
339
- 'default_day' => default_day,
340
- 'rules' => rules }
341
- mean_radiant_heating_schedule = OsLib_Schedules.createComplexSchedule(model, options_radiant_heating)
342
- schedulesHVAC['mean_radiant_heating'] = mean_radiant_heating_schedule
343
- # mean radiant cooling setpoint schedule (PNNL values)
344
- ruleset_name = 'AEDG Office Mean Radiant Cooling Setpoint Schedule'
345
- winter_design_day = [[6, 26.7], [22, 24.0], [24, 26.7]]
346
- summer_design_day = [[24, 24.0]]
347
- default_day = ['Weekday', [6, 26.7], [22, 24.0], [24, 26.7]]
348
- rules = []
349
- rules << ['Saturday', '1/1-12/31', 'Sat', [6, 26.7], [18, 24.0], [24, 26.7]]
350
- rules << ['Sunday', '1/1-12/31', 'Sun', [24, 26.7]]
351
- options_radiant_cooling = { 'name' => ruleset_name,
352
- 'winter_design_day' => winter_design_day,
353
- 'summer_design_day' => summer_design_day,
354
- 'default_day' => default_day,
355
- 'rules' => rules }
356
- mean_radiant_cooling_schedule = OsLib_Schedules.createComplexSchedule(model, options_radiant_cooling)
357
- schedulesHVAC['mean_radiant_cooling'] = mean_radiant_cooling_schedule
358
- end
359
- end
360
- # SAT schedule
361
- if options['allHVAC']['primary']['doas']
362
- # primary airloop is DOAS
363
- schedulesHVAC['primary_sat'] = sch_ruleset_DOAS_setpoint = OsLib_Schedules.createComplexSchedule(model, 'name' => 'AEDG DOAS Temperature Setpoint Schedule',
364
- 'default_day' => ['All Days', [24, 20.0]])
365
- else
366
- # primary airloop is multizone VAV that cools
367
- schedulesHVAC['primary_sat'] = sch_ruleset_DOAS_setpoint = OsLib_Schedules.createComplexSchedule(model, 'name' => 'AEDG Cold Deck Temperature Setpoint Schedule',
368
- 'default_day' => ['All Days', [24, 12.8]])
369
- end
370
- schedulesHVAC['ventilation'] = building_ventilation_schedule
371
- schedulesHVAC['hvac'] = building_HVAC_schedule
372
- # build new plant schedules as needed
373
- zoneHVACHotWaterPlant = ['FanCoil', 'DualDuct', 'Baseboard'] # dual duct has fan coil and baseboard
374
- zoneHVACChilledWaterPlant = ['FanCoil', 'DualDuct'] # dual duct has fan coil
375
- # hot water
376
- if (options['allHVAC']['primary']['heat'] == 'Water') || (options['allHVAC']['secondary']['heat'] == 'Water') || zoneHVACHotWaterPlant.include?(options['allHVAC']['zone'])
377
- schedulesHVAC['hot_water'] = OsLib_Schedules.createComplexSchedule(model, 'name' => 'AEDG HW-Loop-Temp-Schedule',
378
- 'default_day' => ['All Days', [24, 67.0]])
379
- end
380
- # chilled water
381
- if (options['allHVAC']['primary']['cool'] == 'Water') || (options['allHVAC']['secondary']['cool'] == 'Water') || zoneHVACChilledWaterPlant.include?(options['allHVAC']['zone'])
382
- schedulesHVAC['chilled_water'] = OsLib_Schedules.createComplexSchedule(model, 'name' => 'AEDG CW-Loop-Temp-Schedule',
383
- 'default_day' => ['All Days', [24, 6.7]])
384
- end
385
- # heat pump condenser loop schedules
386
- if options['allHVAC']['zone'] == 'GSHP'
387
- # there will be a heat pump condenser loop
388
- # loop setpoint schedule
389
- schedulesHVAC['hp_loop'] = OsLib_Schedules.createComplexSchedule(model, 'name' => 'AEDG HP-Loop-Temp-Schedule',
390
- 'default_day' => ['All Days', [24, 21]])
391
- # cooling component schedule (#ML won't need this if a ground loop is actually modeled)
392
- schedulesHVAC['hp_loop_cooling'] = OsLib_Schedules.createComplexSchedule(model, 'name' => 'AEDG HP-Loop-Clg-Temp-Schedule',
393
- 'default_day' => ['All Days', [24, 21]])
394
- # heating component schedule
395
- schedulesHVAC['hp_loop_heating'] = OsLib_Schedules.createComplexSchedule(model, 'name' => 'AEDG HP-Loop-Htg-Temp-Schedule',
396
- 'default_day' => ['All Days', [24, 5]])
397
- end
398
- if options['allHVAC']['zone'] == 'WSHP'
399
- # there will be a heat pump condenser loop
400
- # loop setpoint schedule
401
- schedulesHVAC['hp_loop'] = OsLib_Schedules.createComplexSchedule(model, 'name' => 'AEDG HP-Loop-Temp-Schedule',
402
- 'default_day' => ['All Days', [24, 30]]) # PNNL
403
- # cooling component schedule (#ML won't need this if a ground loop is actually modeled)
404
- schedulesHVAC['hp_loop_cooling'] = OsLib_Schedules.createComplexSchedule(model, 'name' => 'AEDG HP-Loop-Clg-Temp-Schedule',
405
- 'default_day' => ['All Days', [24, 30]]) # PNNL
406
- # heating component schedule
407
- schedulesHVAC['hp_loop_heating'] = OsLib_Schedules.createComplexSchedule(model, 'name' => 'AEDG HP-Loop-Htg-Temp-Schedule',
408
- 'default_day' => ['All Days', [24, 20]]) # PNNL
409
- end
410
-
411
- # pass back schedulesHVAC hash
412
- result = schedulesHVAC
413
- return result
414
- end
415
-
416
- def self.createHotWaterPlant(model, runner, hot_water_setpoint_schedule, loop_type)
417
- hot_water_plant = OpenStudio::Model::PlantLoop.new(model)
418
- hot_water_plant.setName("AEDG #{loop_type} Loop")
419
- hot_water_plant.setMaximumLoopTemperature(100)
420
- hot_water_plant.setMinimumLoopTemperature(10)
421
- loop_sizing = hot_water_plant.sizingPlant
422
- loop_sizing.setLoopType('Heating')
423
- if loop_type == 'Hot Water'
424
- loop_sizing.setDesignLoopExitTemperature(82)
425
- elsif loop_type == 'Radiant Hot Water'
426
- loop_sizing.setDesignLoopExitTemperature(60) # ML follows convention of sizing temp being larger than supplu temp
427
- end
428
- loop_sizing.setLoopDesignTemperatureDifference(11)
429
- # create a pump
430
- pump = OpenStudio::Model::PumpVariableSpeed.new(model)
431
- pump.setRatedPumpHead(119563) # Pa
432
- pump.setMotorEfficiency(0.9)
433
- pump.setCoefficient1ofthePartLoadPerformanceCurve(0)
434
- pump.setCoefficient2ofthePartLoadPerformanceCurve(0.0216)
435
- pump.setCoefficient3ofthePartLoadPerformanceCurve(-0.0325)
436
- pump.setCoefficient4ofthePartLoadPerformanceCurve(1.0095)
437
- # create a boiler
438
- boiler = OpenStudio::Model::BoilerHotWater.new(model)
439
- boiler.setNominalThermalEfficiency(0.9)
440
- # create a scheduled setpoint manager
441
- setpoint_manager_scheduled = OpenStudio::Model::SetpointManagerScheduled.new(model, hot_water_setpoint_schedule)
442
- # create a supply bypass pipe
443
- pipe_supply_bypass = OpenStudio::Model::PipeAdiabatic.new(model)
444
- # create a supply outlet pipe
445
- pipe_supply_outlet = OpenStudio::Model::PipeAdiabatic.new(model)
446
- # create a demand bypass pipe
447
- pipe_demand_bypass = OpenStudio::Model::PipeAdiabatic.new(model)
448
- # create a demand inlet pipe
449
- pipe_demand_inlet = OpenStudio::Model::PipeAdiabatic.new(model)
450
- # create a demand outlet pipe
451
- pipe_demand_outlet = OpenStudio::Model::PipeAdiabatic.new(model)
452
- # connect components to plant loop
453
- # supply side components
454
- hot_water_plant.addSupplyBranchForComponent(boiler)
455
- hot_water_plant.addSupplyBranchForComponent(pipe_supply_bypass)
456
- pump.addToNode(hot_water_plant.supplyInletNode)
457
- pipe_supply_outlet.addToNode(hot_water_plant.supplyOutletNode)
458
- setpoint_manager_scheduled.addToNode(hot_water_plant.supplyOutletNode)
459
- # demand side components (water coils are added as they are added to airloops and zoneHVAC)
460
- hot_water_plant.addDemandBranchForComponent(pipe_demand_bypass)
461
- pipe_demand_inlet.addToNode(hot_water_plant.demandInletNode)
462
- pipe_demand_outlet.addToNode(hot_water_plant.demandOutletNode)
463
-
464
- # pass back hot water plant
465
- result = hot_water_plant
466
- return result
467
- end
468
-
469
- def self.createChilledWaterPlant(model, runner, chilled_water_setpoint_schedule, loop_type, chillerType)
470
- # chilled water plant
471
- chilled_water_plant = OpenStudio::Model::PlantLoop.new(model)
472
- chilled_water_plant.setName("AEDG #{loop_type} Loop")
473
- chilled_water_plant.setMaximumLoopTemperature(98)
474
- chilled_water_plant.setMinimumLoopTemperature(1)
475
- loop_sizing = chilled_water_plant.sizingPlant
476
- loop_sizing.setLoopType('Cooling')
477
- if loop_type == 'Chilled Water'
478
- loop_sizing.setDesignLoopExitTemperature(6.7)
479
- elsif loop_type == 'Radiant Chilled Water'
480
- loop_sizing.setDesignLoopExitTemperature(15)
481
- end
482
- loop_sizing.setLoopDesignTemperatureDifference(6.7)
483
- # create a pump
484
- pump = OpenStudio::Model::PumpVariableSpeed.new(model)
485
- pump.setRatedPumpHead(149453) # Pa
486
- pump.setMotorEfficiency(0.9)
487
- pump.setCoefficient1ofthePartLoadPerformanceCurve(0)
488
- pump.setCoefficient2ofthePartLoadPerformanceCurve(0.0216)
489
- pump.setCoefficient3ofthePartLoadPerformanceCurve(-0.0325)
490
- pump.setCoefficient4ofthePartLoadPerformanceCurve(1.0095)
491
- # create a chiller
492
- if chillerType == 'WaterCooled'
493
- # create clgCapFuncTempCurve
494
- clgCapFuncTempCurve = OpenStudio::Model::CurveBiquadratic.new(model)
495
- clgCapFuncTempCurve.setCoefficient1Constant(1.07E+00)
496
- clgCapFuncTempCurve.setCoefficient2x(4.29E-02)
497
- clgCapFuncTempCurve.setCoefficient3xPOW2(4.17E-04)
498
- clgCapFuncTempCurve.setCoefficient4y(-8.10E-03)
499
- clgCapFuncTempCurve.setCoefficient5yPOW2(-4.02E-05)
500
- clgCapFuncTempCurve.setCoefficient6xTIMESY(-3.86E-04)
501
- clgCapFuncTempCurve.setMinimumValueofx(0)
502
- clgCapFuncTempCurve.setMaximumValueofx(20)
503
- clgCapFuncTempCurve.setMinimumValueofy(0)
504
- clgCapFuncTempCurve.setMaximumValueofy(50)
505
- # create eirFuncTempCurve
506
- eirFuncTempCurve = OpenStudio::Model::CurveBiquadratic.new(model)
507
- eirFuncTempCurve.setCoefficient1Constant(4.68E-01)
508
- eirFuncTempCurve.setCoefficient2x(-1.38E-02)
509
- eirFuncTempCurve.setCoefficient3xPOW2(6.98E-04)
510
- eirFuncTempCurve.setCoefficient4y(1.09E-02)
511
- eirFuncTempCurve.setCoefficient5yPOW2(4.62E-04)
512
- eirFuncTempCurve.setCoefficient6xTIMESY(-6.82E-04)
513
- eirFuncTempCurve.setMinimumValueofx(0)
514
- eirFuncTempCurve.setMaximumValueofx(20)
515
- eirFuncTempCurve.setMinimumValueofy(0)
516
- eirFuncTempCurve.setMaximumValueofy(50)
517
- # create eirFuncPlrCurve
518
- eirFuncPlrCurve = OpenStudio::Model::CurveQuadratic.new(model)
519
- eirFuncPlrCurve.setCoefficient1Constant(1.41E-01)
520
- eirFuncPlrCurve.setCoefficient2x(6.55E-01)
521
- eirFuncPlrCurve.setCoefficient3xPOW2(2.03E-01)
522
- eirFuncPlrCurve.setMinimumValueofx(0)
523
- eirFuncPlrCurve.setMaximumValueofx(1.2)
524
- # construct chiller
525
- chiller = OpenStudio::Model::ChillerElectricEIR.new(model, clgCapFuncTempCurve, eirFuncTempCurve, eirFuncPlrCurve)
526
- chiller.setReferenceCOP(6.1)
527
- chiller.setCondenserType('WaterCooled')
528
- chiller.setChillerFlowMode('ConstantFlow')
529
- elsif chillerType == 'AirCooled'
530
- # create clgCapFuncTempCurve
531
- clgCapFuncTempCurve = OpenStudio::Model::CurveBiquadratic.new(model)
532
- clgCapFuncTempCurve.setCoefficient1Constant(1.05E+00)
533
- clgCapFuncTempCurve.setCoefficient2x(3.36E-02)
534
- clgCapFuncTempCurve.setCoefficient3xPOW2(2.15E-04)
535
- clgCapFuncTempCurve.setCoefficient4y(-5.18E-03)
536
- clgCapFuncTempCurve.setCoefficient5yPOW2(-4.42E-05)
537
- clgCapFuncTempCurve.setCoefficient6xTIMESY(-2.15E-04)
538
- clgCapFuncTempCurve.setMinimumValueofx(0)
539
- clgCapFuncTempCurve.setMaximumValueofx(20)
540
- clgCapFuncTempCurve.setMinimumValueofy(0)
541
- clgCapFuncTempCurve.setMaximumValueofy(50)
542
- # create eirFuncTempCurve
543
- eirFuncTempCurve = OpenStudio::Model::CurveBiquadratic.new(model)
544
- eirFuncTempCurve.setCoefficient1Constant(5.83E-01)
545
- eirFuncTempCurve.setCoefficient2x(-4.04E-03)
546
- eirFuncTempCurve.setCoefficient3xPOW2(4.68E-04)
547
- eirFuncTempCurve.setCoefficient4y(-2.24E-04)
548
- eirFuncTempCurve.setCoefficient5yPOW2(4.81E-04)
549
- eirFuncTempCurve.setCoefficient6xTIMESY(-6.82E-04)
550
- eirFuncTempCurve.setMinimumValueofx(0)
551
- eirFuncTempCurve.setMaximumValueofx(20)
552
- eirFuncTempCurve.setMinimumValueofy(0)
553
- eirFuncTempCurve.setMaximumValueofy(50)
554
- # create eirFuncPlrCurve
555
- eirFuncPlrCurve = OpenStudio::Model::CurveQuadratic.new(model)
556
- eirFuncPlrCurve.setCoefficient1Constant(4.19E-02)
557
- eirFuncPlrCurve.setCoefficient2x(6.25E-01)
558
- eirFuncPlrCurve.setCoefficient3xPOW2(3.23E-01)
559
- eirFuncPlrCurve.setMinimumValueofx(0)
560
- eirFuncPlrCurve.setMaximumValueofx(1.2)
561
- # construct chiller
562
- chiller = OpenStudio::Model::ChillerElectricEIR.new(model, clgCapFuncTempCurve, eirFuncTempCurve, eirFuncPlrCurve)
563
- chiller.setReferenceCOP(2.93)
564
- chiller.setCondenserType('AirCooled')
565
- chiller.setChillerFlowMode('ConstantFlow')
566
- end
567
- # create a scheduled setpoint manager
568
- setpoint_manager_scheduled = OpenStudio::Model::SetpointManagerScheduled.new(model, chilled_water_setpoint_schedule)
569
- # create a supply bypass pipe
570
- pipe_supply_bypass = OpenStudio::Model::PipeAdiabatic.new(model)
571
- # create a supply outlet pipe
572
- pipe_supply_outlet = OpenStudio::Model::PipeAdiabatic.new(model)
573
- # create a demand bypass pipe
574
- pipe_demand_bypass = OpenStudio::Model::PipeAdiabatic.new(model)
575
- # create a demand inlet pipe
576
- pipe_demand_inlet = OpenStudio::Model::PipeAdiabatic.new(model)
577
- # create a demand outlet pipe
578
- pipe_demand_outlet = OpenStudio::Model::PipeAdiabatic.new(model)
579
- # connect components to plant loop
580
- # supply side components
581
- chilled_water_plant.addSupplyBranchForComponent(chiller)
582
- chilled_water_plant.addSupplyBranchForComponent(pipe_supply_bypass)
583
- pump.addToNode(chilled_water_plant.supplyInletNode)
584
- pipe_supply_outlet.addToNode(chilled_water_plant.supplyOutletNode)
585
- setpoint_manager_scheduled.addToNode(chilled_water_plant.supplyOutletNode)
586
- # demand side components (water coils are added as they are added to airloops and ZoneHVAC)
587
- chilled_water_plant.addDemandBranchForComponent(pipe_demand_bypass)
588
- pipe_demand_inlet.addToNode(chilled_water_plant.demandInletNode)
589
- pipe_demand_outlet.addToNode(chilled_water_plant.demandOutletNode)
590
-
591
- # pass back chilled water plant
592
- result = chilled_water_plant
593
- return result
594
- end
595
-
596
- def self.createCondenserLoop(model, runner, options)
597
- condenserLoops = {}
598
-
599
- # check for water-cooled chillers
600
- waterCooledChiller = false
601
- model.getChillerElectricEIRs.sort.each do |chiller|
602
- next if waterCooledChiller == true
603
- if chiller.condenserType == 'WaterCooled'
604
- waterCooledChiller = true
605
- end
606
- end
607
- # create condenser loop for water-cooled chillers
608
- if waterCooledChiller
609
- # create condenser loop for water-cooled chiller(s)
610
- condenser_loop = OpenStudio::Model::PlantLoop.new(model)
611
- condenser_loop.setName('AEDG Condenser Loop')
612
- condenser_loop.setMaximumLoopTemperature(80)
613
- condenser_loop.setMinimumLoopTemperature(5)
614
- loop_sizing = condenser_loop.sizingPlant
615
- loop_sizing.setLoopType('Condenser')
616
- loop_sizing.setDesignLoopExitTemperature(29.4)
617
- loop_sizing.setLoopDesignTemperatureDifference(5.6)
618
- # create a pump
619
- pump = OpenStudio::Model::PumpVariableSpeed.new(model)
620
- pump.setRatedPumpHead(134508) # Pa
621
- pump.setMotorEfficiency(0.9)
622
- pump.setCoefficient1ofthePartLoadPerformanceCurve(0)
623
- pump.setCoefficient2ofthePartLoadPerformanceCurve(0.0216)
624
- pump.setCoefficient3ofthePartLoadPerformanceCurve(-0.0325)
625
- pump.setCoefficient4ofthePartLoadPerformanceCurve(1.0095)
626
- # create a cooling tower
627
- tower = OpenStudio::Model::CoolingTowerVariableSpeed.new(model)
628
- # create a supply bypass pipe
629
- pipe_supply_bypass = OpenStudio::Model::PipeAdiabatic.new(model)
630
- # create a supply outlet pipe
631
- pipe_supply_outlet = OpenStudio::Model::PipeAdiabatic.new(model)
632
- # create a demand bypass pipe
633
- pipe_demand_bypass = OpenStudio::Model::PipeAdiabatic.new(model)
634
- # create a demand inlet pipe
635
- pipe_demand_inlet = OpenStudio::Model::PipeAdiabatic.new(model)
636
- # create a demand outlet pipe
637
- pipe_demand_outlet = OpenStudio::Model::PipeAdiabatic.new(model)
638
- # create a setpoint manager
639
- setpoint_manager_follow_oa = OpenStudio::Model::SetpointManagerFollowOutdoorAirTemperature.new(model)
640
- setpoint_manager_follow_oa.setOffsetTemperatureDifference(0)
641
- setpoint_manager_follow_oa.setMaximumSetpointTemperature(80)
642
- setpoint_manager_follow_oa.setMinimumSetpointTemperature(5)
643
- # connect components to plant loop
644
- # supply side components
645
- condenser_loop.addSupplyBranchForComponent(tower)
646
- condenser_loop.addSupplyBranchForComponent(pipe_supply_bypass)
647
- pump.addToNode(condenser_loop.supplyInletNode)
648
- pipe_supply_outlet.addToNode(condenser_loop.supplyOutletNode)
649
- setpoint_manager_follow_oa.addToNode(condenser_loop.supplyOutletNode)
650
- # demand side components
651
- model.getChillerElectricEIRs.sort.each do |chiller|
652
- if chiller.condenserType == 'WaterCooled' # works only if chillers not already connected to condenser loop(s)
653
- condenser_loop.addDemandBranchForComponent(chiller)
654
- end
655
- end
656
- condenser_loop.addDemandBranchForComponent(pipe_demand_bypass)
657
- pipe_demand_inlet.addToNode(condenser_loop.demandInletNode)
658
- pipe_demand_outlet.addToNode(condenser_loop.demandOutletNode)
659
- condenserLoops['condenser_loop'] = condenser_loop
660
- end
661
- if options['zoneHVAC'].include? 'GSHP'
662
- # create condenser loop for heat pumps
663
- condenser_loop = OpenStudio::Model::PlantLoop.new(model)
664
- condenser_loop.setName('AEDG Heat Pump Loop')
665
- condenser_loop.setMaximumLoopTemperature(80)
666
- condenser_loop.setMinimumLoopTemperature(1)
667
- loop_sizing = condenser_loop.sizingPlant
668
- loop_sizing.setLoopType('Condenser')
669
- if options['zoneHVAC'] == 'GSHP'
670
- loop_sizing.setDesignLoopExitTemperature(21)
671
- loop_sizing.setLoopDesignTemperatureDifference(5)
672
- elsif options['zoneHVAC'] == 'WSHP'
673
- loop_sizing.setDesignLoopExitTemperature(30) # PNNL
674
- loop_sizing.setLoopDesignTemperatureDifference(20) # PNNL
675
- end
676
- # create a pump
677
- pump = OpenStudio::Model::PumpVariableSpeed.new(model)
678
- pump.setRatedPumpHead(134508) # Pa
679
- pump.setMotorEfficiency(0.9)
680
- pump.setCoefficient1ofthePartLoadPerformanceCurve(0)
681
- pump.setCoefficient2ofthePartLoadPerformanceCurve(0.0216)
682
- pump.setCoefficient3ofthePartLoadPerformanceCurve(-0.0325)
683
- pump.setCoefficient4ofthePartLoadPerformanceCurve(1.0095)
684
- # create a supply bypass pipe
685
- pipe_supply_bypass = OpenStudio::Model::PipeAdiabatic.new(model)
686
- # create a supply outlet pipe
687
- pipe_supply_outlet = OpenStudio::Model::PipeAdiabatic.new(model)
688
- # create a demand bypass pipe
689
- pipe_demand_bypass = OpenStudio::Model::PipeAdiabatic.new(model)
690
- # create a demand inlet pipe
691
- pipe_demand_inlet = OpenStudio::Model::PipeAdiabatic.new(model)
692
- # create a demand outlet pipe
693
- pipe_demand_outlet = OpenStudio::Model::PipeAdiabatic.new(model)
694
- # create setpoint managers
695
- setpoint_manager_scheduled_loop = OpenStudio::Model::SetpointManagerScheduled.new(model, options['loop_setpoint_schedule'])
696
- setpoint_manager_scheduled_cooling = OpenStudio::Model::SetpointManagerScheduled.new(model, options['cooling_setpoint_schedule'])
697
- setpoint_manager_scheduled_heating = OpenStudio::Model::SetpointManagerScheduled.new(model, options['heating_setpoint_schedule'])
698
- # connect components to plant loop
699
- # supply side components
700
- condenser_loop.addSupplyBranchForComponent(pipe_supply_bypass)
701
- pump.addToNode(condenser_loop.supplyInletNode)
702
- pipe_supply_outlet.addToNode(condenser_loop.supplyOutletNode)
703
- setpoint_manager_scheduled_loop.addToNode(condenser_loop.supplyOutletNode)
704
- # demand side components
705
- condenser_loop.addDemandBranchForComponent(pipe_demand_bypass)
706
- pipe_demand_inlet.addToNode(condenser_loop.demandInletNode)
707
- pipe_demand_outlet.addToNode(condenser_loop.demandOutletNode)
708
- # add additional components according to specific system type
709
- if options['zoneHVAC'] == 'GSHP'
710
- # add district cooling and heating to supply side
711
- district_cooling = OpenStudio::Model::DistrictCooling.new(model)
712
- district_cooling.setNominalCapacity(1000000000000) # large number; no autosizing
713
- condenser_loop.addSupplyBranchForComponent(district_cooling)
714
- setpoint_manager_scheduled_cooling.addToNode(district_cooling.outletModelObject.get.to_Node.get)
715
- district_heating = OpenStudio::Model::DistrictHeating.new(model)
716
- district_heating.setNominalCapacity(1000000000000) # large number; no autosizing
717
- district_heating.addToNode(district_cooling.outletModelObject.get.to_Node.get)
718
- setpoint_manager_scheduled_heating.addToNode(district_heating.outletModelObject.get.to_Node.get)
719
- # add heat pumps to demand side after they get created
720
- elsif options['zoneHVAC'] == 'WSHP'
721
- # add a boiler and cooling tower to supply side
722
- # create a boiler
723
- boiler = OpenStudio::Model::BoilerHotWater.new(model)
724
- boiler.setNominalThermalEfficiency(0.9)
725
- condenser_loop.addSupplyBranchForComponent(boiler)
726
- setpoint_manager_scheduled_heating.addToNode(boiler.outletModelObject.get.to_Node.get)
727
- # create a cooling tower
728
- tower = OpenStudio::Model::CoolingTowerSingleSpeed.new(model)
729
- tower.addToNode(boiler.outletModelObject.get.to_Node.get)
730
- setpoint_manager_scheduled_cooling.addToNode(tower.outletModelObject.get.to_Node.get)
731
- end
732
- condenserLoops['heat_pump_loop'] = condenser_loop
733
- end
734
-
735
- # pass back condenser loop(s)
736
- result = condenserLoops
737
- return result
738
- end
739
-
740
- def self.createPrimaryAirLoops(model, runner, options)
741
- primary_airloops = []
742
- # create primary airloop for each story
743
- assignedThermalZones = []
744
- model.getBuildingStorys.sort.each do |building_story|
745
- # ML stories need to be reordered from the ground up
746
- thermalZonesToAdd = []
747
- building_story.spaces.each do |space|
748
- # make sure spaces are assigned to thermal zones
749
- # otherwise might want to send a warning
750
- if space.thermalZone
751
- thermal_zone = space.thermalZone.get
752
- # grab primary zones
753
- if options['zonesPrimary'].include? thermal_zone
754
- # make sure zone was not already assigned to another air loop
755
- unless assignedThermalZones.include? thermal_zone
756
- # make sure thermal zones are not duplicated (spaces can share thermal zones)
757
- unless thermalZonesToAdd.include? thermal_zone
758
- thermalZonesToAdd << thermal_zone
759
- end
760
- end
761
- end
762
- end
763
- end
764
- # make sure thermal zones don't get added to more than one air loop
765
- assignedThermalZones << thermalZonesToAdd
766
-
767
- # create new air loop if story contains primary zones
768
- unless thermalZonesToAdd.empty?
769
- airloop_primary = OpenStudio::Model::AirLoopHVAC.new(model)
770
- airloop_primary.setName("AEDG Air Loop HVAC #{building_story.name}")
771
- # modify system sizing properties
772
- sizing_system = airloop_primary.sizingSystem
773
- # set central heating and cooling temperatures for sizing
774
- sizing_system.setCentralCoolingDesignSupplyAirTemperature(12.8)
775
- sizing_system.setCentralHeatingDesignSupplyAirTemperature(40) # ML OS default is 16.7
776
- # load specification
777
- sizing_system.setSystemOutdoorAirMethod('VentilationRateProcedure') # ML OS default is ZoneSum
778
- if options['primaryHVAC']['doas']
779
- sizing_system.setTypeofLoadtoSizeOn('VentilationRequirement') # DOAS
780
- sizing_system.setAllOutdoorAirinCooling(true) # DOAS
781
- sizing_system.setAllOutdoorAirinHeating(true) # DOAS
782
- else
783
- sizing_system.setTypeofLoadtoSizeOn('Sensible') # VAV
784
- sizing_system.setAllOutdoorAirinCooling(false) # VAV
785
- sizing_system.setAllOutdoorAirinHeating(false) # VAV
786
- end
787
-
788
- air_loop_comps = []
789
- # set availability schedule
790
- airloop_primary.setAvailabilitySchedule(options['hvac_schedule'])
791
- # create air loop fan
792
- if options['primaryHVAC']['fan'] == 'Variable'
793
- # create variable speed fan and set system sizing accordingly
794
- sizing_system.setCentralHeatingMaximumSystemAirFlowRatio(0.3) # DCV
795
- # variable speed fan
796
- fan = OpenStudio::Model::FanVariableVolume.new(model, model.alwaysOnDiscreteSchedule)
797
- fan.setFanEfficiency(0.69)
798
- fan.setPressureRise(1125) # Pa
799
- fan.autosizeMaximumFlowRate
800
- fan.setFanPowerMinimumFlowFraction(0.6)
801
- fan.setMotorEfficiency(0.9)
802
- fan.setMotorInAirstreamFraction(1.0)
803
- air_loop_comps << fan
804
- else
805
- sizing_system.setCentralHeatingMaximumSystemAirFlowRatio(1.0) # No DCV
806
- # constant speed fan
807
- fan = OpenStudio::Model::FanConstantVolume.new(model, model.alwaysOnDiscreteSchedule)
808
- fan.setFanEfficiency(0.6)
809
- fan.setPressureRise(500) # Pa
810
- fan.autosizeMaximumFlowRate
811
- fan.setMotorEfficiency(0.9)
812
- fan.setMotorInAirstreamFraction(1.0)
813
- air_loop_comps << fan
814
- end
815
- # create heating coil
816
- if options['primaryHVAC']['heat'] == 'Water'
817
- # water coil
818
- heating_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule)
819
- air_loop_comps << heating_coil
820
- else
821
- # gas coil
822
- heating_coil = OpenStudio::Model::CoilHeatingGas.new(model, model.alwaysOnDiscreteSchedule)
823
- air_loop_comps << heating_coil
824
- end
825
- # create cooling coil
826
- if options['primaryHVAC']['cool'] == 'Water'
827
- # water coil
828
- cooling_coil = OpenStudio::Model::CoilCoolingWater.new(model, model.alwaysOnDiscreteSchedule)
829
- air_loop_comps << cooling_coil
830
- elsif options['primaryHVAC']['cool'] == 'SingleDX'
831
- # single speed DX coil
832
- # create cooling coil
833
- # create clgCapFuncTempCurve
834
- clgCapFuncTempCurve = OpenStudio::Model::CurveBiquadratic.new(model)
835
- clgCapFuncTempCurve.setCoefficient1Constant(0.42415)
836
- clgCapFuncTempCurve.setCoefficient2x(0.04426)
837
- clgCapFuncTempCurve.setCoefficient3xPOW2(-0.00042)
838
- clgCapFuncTempCurve.setCoefficient4y(0.00333)
839
- clgCapFuncTempCurve.setCoefficient5yPOW2(-0.00008)
840
- clgCapFuncTempCurve.setCoefficient6xTIMESY(-0.00021)
841
- clgCapFuncTempCurve.setMinimumValueofx(17)
842
- clgCapFuncTempCurve.setMaximumValueofx(22)
843
- clgCapFuncTempCurve.setMinimumValueofy(13)
844
- clgCapFuncTempCurve.setMaximumValueofy(46)
845
- # create clgCapFuncFlowFracCurve
846
- clgCapFuncFlowFracCurve = OpenStudio::Model::CurveQuadratic.new(model)
847
- clgCapFuncFlowFracCurve.setCoefficient1Constant(0.77136)
848
- clgCapFuncFlowFracCurve.setCoefficient2x(0.34053)
849
- clgCapFuncFlowFracCurve.setCoefficient3xPOW2(-0.11088)
850
- clgCapFuncFlowFracCurve.setMinimumValueofx(0.75918)
851
- clgCapFuncFlowFracCurve.setMaximumValueofx(1.13877)
852
- # create clgEirFuncTempCurve
853
- clgEirFuncTempCurve = OpenStudio::Model::CurveBiquadratic.new(model)
854
- clgEirFuncTempCurve.setCoefficient1Constant(1.23649)
855
- clgEirFuncTempCurve.setCoefficient2x(-0.02431)
856
- clgEirFuncTempCurve.setCoefficient3xPOW2(0.00057)
857
- clgEirFuncTempCurve.setCoefficient4y(-0.01434)
858
- clgEirFuncTempCurve.setCoefficient5yPOW2(0.00063)
859
- clgEirFuncTempCurve.setCoefficient6xTIMESY(-0.00038)
860
- clgEirFuncTempCurve.setMinimumValueofx(17)
861
- clgEirFuncTempCurve.setMaximumValueofx(22)
862
- clgEirFuncTempCurve.setMinimumValueofy(13)
863
- clgEirFuncTempCurve.setMaximumValueofy(46)
864
- # create clgEirFuncFlowFracCurve
865
- clgEirFuncFlowFracCurve = OpenStudio::Model::CurveQuadratic.new(model)
866
- clgEirFuncFlowFracCurve.setCoefficient1Constant(1.20550)
867
- clgEirFuncFlowFracCurve.setCoefficient2x(-0.32953)
868
- clgEirFuncFlowFracCurve.setCoefficient3xPOW2(0.12308)
869
- clgEirFuncFlowFracCurve.setMinimumValueofx(0.75918)
870
- clgEirFuncFlowFracCurve.setMaximumValueofx(1.13877)
871
- # create clgPlrCurve
872
- clgPlrCurve = OpenStudio::Model::CurveQuadratic.new(model)
873
- clgPlrCurve.setCoefficient1Constant(0.77100)
874
- clgPlrCurve.setCoefficient2x(0.22900)
875
- clgPlrCurve.setCoefficient3xPOW2(0.0)
876
- clgPlrCurve.setMinimumValueofx(0.0)
877
- clgPlrCurve.setMaximumValueofx(1.0)
878
- # cooling coil
879
- cooling_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(model,
880
- model.alwaysOnDiscreteSchedule,
881
- clgCapFuncTempCurve,
882
- clgCapFuncFlowFracCurve,
883
- clgEirFuncTempCurve,
884
- clgEirFuncFlowFracCurve,
885
- clgPlrCurve)
886
- cooling_coil.setRatedCOP(OpenStudio::OptionalDouble.new(4))
887
- air_loop_comps << cooling_coil
888
- else
889
- # two speed DX coil (PNNL curves)
890
- # create cooling coil
891
- # create clgCapFuncTempCurve
892
- clgCapFuncTempCurve = OpenStudio::Model::CurveBiquadratic.new(model)
893
- clgCapFuncTempCurve.setCoefficient1Constant(1.39072)
894
- clgCapFuncTempCurve.setCoefficient2x(-0.0529058)
895
- clgCapFuncTempCurve.setCoefficient3xPOW2(0.0018423)
896
- clgCapFuncTempCurve.setCoefficient4y(0.00058267)
897
- clgCapFuncTempCurve.setCoefficient5yPOW2(-0.000186814)
898
- clgCapFuncTempCurve.setCoefficient6xTIMESY(0.000265159)
899
- clgCapFuncTempCurve.setMinimumValueofx(16.5556)
900
- clgCapFuncTempCurve.setMaximumValueofx(22.1111)
901
- clgCapFuncTempCurve.setMinimumValueofy(23.7778)
902
- clgCapFuncTempCurve.setMaximumValueofy(47.66)
903
- # create clgCapFuncFlowFracCurve
904
- clgCapFuncFlowFracCurve = OpenStudio::Model::CurveQuadratic.new(model)
905
- clgCapFuncFlowFracCurve.setCoefficient1Constant(0.718954)
906
- clgCapFuncFlowFracCurve.setCoefficient2x(0.435436)
907
- clgCapFuncFlowFracCurve.setCoefficient3xPOW2(-0.154193)
908
- clgCapFuncFlowFracCurve.setMinimumValueofx(0.75)
909
- clgCapFuncFlowFracCurve.setMaximumValueofx(1.25)
910
- # create clgEirFuncTempCurve
911
- clgEirFuncTempCurve = OpenStudio::Model::CurveBiquadratic.new(model)
912
- clgEirFuncTempCurve.setCoefficient1Constant(-0.536161)
913
- clgEirFuncTempCurve.setCoefficient2x(0.105138)
914
- clgEirFuncTempCurve.setCoefficient3xPOW2(-0.00172659)
915
- clgEirFuncTempCurve.setCoefficient4y(0.0149848)
916
- clgEirFuncTempCurve.setCoefficient5yPOW2(0.000659948)
917
- clgEirFuncTempCurve.setCoefficient6xTIMESY(-0.0017385)
918
- clgEirFuncTempCurve.setMinimumValueofx(16.5556)
919
- clgEirFuncTempCurve.setMaximumValueofx(22.1111)
920
- clgEirFuncTempCurve.setMinimumValueofy(23.7778)
921
- clgEirFuncTempCurve.setMaximumValueofy(47.66)
922
- # create clgEirFuncFlowFracCurve
923
- clgEirFuncFlowFracCurve = OpenStudio::Model::CurveQuadratic.new(model)
924
- clgEirFuncFlowFracCurve.setCoefficient1Constant(1.19525)
925
- clgEirFuncFlowFracCurve.setCoefficient2x(-0.306138)
926
- clgEirFuncFlowFracCurve.setCoefficient3xPOW2(0.110973)
927
- clgEirFuncFlowFracCurve.setMinimumValueofx(0.75)
928
- clgEirFuncFlowFracCurve.setMaximumValueofx(1.25)
929
- # create clgPlrCurve
930
- clgPlrCurve = OpenStudio::Model::CurveQuadratic.new(model)
931
- clgPlrCurve.setCoefficient1Constant(0.77100)
932
- clgPlrCurve.setCoefficient2x(0.22900)
933
- clgPlrCurve.setCoefficient3xPOW2(0.0)
934
- clgPlrCurve.setMinimumValueofx(0.0)
935
- clgPlrCurve.setMaximumValueofx(1.0)
936
- # cooling coil
937
- cooling_coil = OpenStudio::Model::CoilCoolingDXTwoSpeed.new(model,
938
- model.alwaysOnDiscreteSchedule,
939
- clgCapFuncTempCurve,
940
- clgCapFuncFlowFracCurve,
941
- clgEirFuncTempCurve,
942
- clgEirFuncFlowFracCurve,
943
- clgPlrCurve,
944
- clgCapFuncTempCurve,
945
- clgEirFuncTempCurve)
946
- cooling_coil.setRatedHighSpeedCOP(4)
947
- cooling_coil.setRatedLowSpeedCOP(4)
948
- air_loop_comps << cooling_coil
949
- end
950
- unless options['zoneHVAC'] == 'DualDuct'
951
- # create controller outdoor air
952
- controller_OA = OpenStudio::Model::ControllerOutdoorAir.new(model)
953
- controller_OA.autosizeMinimumOutdoorAirFlowRate
954
- controller_OA.autosizeMaximumOutdoorAirFlowRate
955
- # create ventilation schedules and assign to OA controller
956
- if options['primaryHVAC']['doas']
957
- controller_OA.setMinimumFractionofOutdoorAirSchedule(model.alwaysOnDiscreteSchedule)
958
- controller_OA.setMaximumFractionofOutdoorAirSchedule(model.alwaysOnDiscreteSchedule)
959
- else
960
- # multizone VAV that ventilates
961
- controller_OA.setMaximumFractionofOutdoorAirSchedule(options['ventilation_schedule'])
962
- controller_OA.setEconomizerControlType('DifferentialEnthalpy')
963
- # add night cycling (ML would people actually do this for a VAV system?))
964
- airloop_primary.setNightCycleControlType('CycleOnAny') # ML Does this work with variable speed fans?
965
- end
966
- controller_OA.setHeatRecoveryBypassControlType('BypassWhenOAFlowGreaterThanMinimum')
967
- # create outdoor air system
968
- system_OA = OpenStudio::Model::AirLoopHVACOutdoorAirSystem.new(model, controller_OA)
969
- air_loop_comps << system_OA
970
- # create ERV
971
- heat_exchanger = OpenStudio::Model::HeatExchangerAirToAirSensibleAndLatent.new(model)
972
- heat_exchanger.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
973
- sensible_eff = 0.75
974
- latent_eff = 0.69
975
- heat_exchanger.setSensibleEffectivenessat100CoolingAirFlow(sensible_eff)
976
- heat_exchanger.setSensibleEffectivenessat100HeatingAirFlow(sensible_eff)
977
- heat_exchanger.setSensibleEffectivenessat75CoolingAirFlow(sensible_eff)
978
- heat_exchanger.setSensibleEffectivenessat75HeatingAirFlow(sensible_eff)
979
- heat_exchanger.setLatentEffectivenessat100CoolingAirFlow(latent_eff)
980
- heat_exchanger.setLatentEffectivenessat100HeatingAirFlow(latent_eff)
981
- heat_exchanger.setLatentEffectivenessat75CoolingAirFlow(latent_eff)
982
- heat_exchanger.setLatentEffectivenessat75HeatingAirFlow(latent_eff)
983
- heat_exchanger.setFrostControlType('ExhaustOnly')
984
- heat_exchanger.setThresholdTemperature(-12.2)
985
- heat_exchanger.setInitialDefrostTimeFraction(0.1670)
986
- heat_exchanger.setRateofDefrostTimeFractionIncrease(0.0240)
987
- heat_exchanger.setEconomizerLockout(false)
988
- end
989
- # create scheduled setpoint manager for airloop
990
- if options['primaryHVAC']['doas'] || (options['zoneHVAC'] == 'DualDuct')
991
- # DOAS or VAV for cooling and not ventilation
992
- setpoint_manager = OpenStudio::Model::SetpointManagerScheduled.new(model, options['primary_sat_schedule'])
993
- else
994
- # VAV for cooling and ventilation
995
- setpoint_manager = OpenStudio::Model::SetpointManagerOutdoorAirReset.new(model)
996
- setpoint_manager.setSetpointatOutdoorLowTemperature(15.6)
997
- setpoint_manager.setOutdoorLowTemperature(14.4)
998
- setpoint_manager.setSetpointatOutdoorHighTemperature(12.8)
999
- setpoint_manager.setOutdoorHighTemperature(21.1)
1000
- end
1001
- # connect components to airloop
1002
- # find the supply inlet node of the airloop
1003
- airloop_supply_inlet = airloop_primary.supplyInletNode
1004
- # add the components to the airloop
1005
- air_loop_comps.each do |comp|
1006
- comp.addToNode(airloop_supply_inlet)
1007
- if comp.to_CoilHeatingWater.is_initialized
1008
- options['hot_water_plant'].addDemandBranchForComponent(comp)
1009
- elsif comp.to_CoilCoolingWater.is_initialized
1010
- options['chilled_water_plant'].addDemandBranchForComponent(comp)
1011
- end
1012
- end
1013
- # add erv to outdoor air system
1014
- unless options['zoneHVAC'] == 'DualDuct'
1015
- heat_exchanger.addToNode(system_OA.outboardOANode.get)
1016
- end
1017
- # add setpoint manager to supply equipment outlet node
1018
- setpoint_manager.addToNode(airloop_primary.supplyOutletNode)
1019
- # add thermal zones to airloop
1020
- thermalZonesToAdd.each do |zone|
1021
- # make an air terminal for the zone
1022
- if options['primaryHVAC']['fan'] == 'Variable'
1023
- air_terminal = OpenStudio::Model::AirTerminalSingleDuctVAVNoReheat.new(model, model.alwaysOnDiscreteSchedule)
1024
- else
1025
- air_terminal = OpenStudio::Model::AirTerminalSingleDuctUncontrolled.new(model, model.alwaysOnDiscreteSchedule)
1026
- end
1027
- # attach new terminal to the zone and to the airloop
1028
- airloop_primary.addBranchForZone(zone, air_terminal.to_StraightComponent)
1029
- end
1030
- primary_airloops << airloop_primary
1031
- end
1032
- end
1033
-
1034
- # pass back primary airloops
1035
- result = primary_airloops
1036
- return result
1037
- end
1038
-
1039
- def self.createSecondaryAirLoops(model, runner, options)
1040
- secondary_airloops = []
1041
- # create secondary airloop for each secondary zone
1042
- model.getThermalZones.sort.each do |zone|
1043
- if options['zonesSecondary'].include? zone
1044
- # create secondary airloop
1045
- airloop_secondary = OpenStudio::Model::AirLoopHVAC.new(model)
1046
- airloop_secondary.setName("AEDG Air Loop HVAC #{zone.name}")
1047
- # modify system sizing properties
1048
- sizing_system = airloop_secondary.sizingSystem
1049
- # set central heating and cooling temperatures for sizing
1050
- sizing_system.setCentralCoolingDesignSupplyAirTemperature(12.8)
1051
- sizing_system.setCentralHeatingDesignSupplyAirTemperature(40) # ML OS default is 16.7
1052
- # load specification
1053
- sizing_system.setSystemOutdoorAirMethod('VentilationRateProcedure') # ML OS default is ZoneSum
1054
- sizing_system.setTypeofLoadtoSizeOn('Sensible') # PSZ
1055
- sizing_system.setAllOutdoorAirinCooling(false) # PSZ
1056
- sizing_system.setAllOutdoorAirinHeating(false) # PSZ
1057
- sizing_system.setCentralHeatingMaximumSystemAirFlowRatio(1.0) # Constant volume fan
1058
- air_loop_comps = []
1059
- # set availability schedule (HVAC operation schedule)
1060
- airloop_secondary.setAvailabilitySchedule(options['hvac_schedule'])
1061
- if options['secondaryHVAC']['fan'] == 'Variable'
1062
- # create variable speed fan and set system sizing accordingly
1063
- sizing_system.setCentralHeatingMaximumSystemAirFlowRatio(0.3) # DCV
1064
- # variable speed fan
1065
- fan = OpenStudio::Model::FanVariableVolume.new(model, model.alwaysOnDiscreteSchedule)
1066
- fan.setFanEfficiency(0.69)
1067
- fan.setPressureRise(1125) # Pa
1068
- fan.autosizeMaximumFlowRate
1069
- fan.setFanPowerMinimumFlowFraction(0.6)
1070
- fan.setMotorEfficiency(0.9)
1071
- fan.setMotorInAirstreamFraction(1.0)
1072
- air_loop_comps << fan
1073
- else
1074
- sizing_system.setCentralHeatingMaximumSystemAirFlowRatio(1.0) # No DCV
1075
- # constant speed fan
1076
- fan = OpenStudio::Model::FanConstantVolume.new(model, model.alwaysOnDiscreteSchedule)
1077
- fan.setFanEfficiency(0.6)
1078
- fan.setPressureRise(500) # Pa
1079
- fan.autosizeMaximumFlowRate
1080
- fan.setMotorEfficiency(0.9)
1081
- fan.setMotorInAirstreamFraction(1.0)
1082
- air_loop_comps << fan
1083
- end
1084
- # create cooling coil
1085
- if options['secondaryHVAC']['cool'] == 'Water'
1086
- # water coil
1087
- cooling_coil = OpenStudio::Model::CoilCoolingWater.new(model, model.alwaysOnDiscreteSchedule)
1088
- air_loop_comps << cooling_coil
1089
- elsif options['secondaryHVAC']['cool'] == 'SingleDX'
1090
- # single speed DX coil
1091
- # create cooling coil
1092
- # create clgCapFuncTempCurve
1093
- clgCapFuncTempCurve = OpenStudio::Model::CurveBiquadratic.new(model)
1094
- clgCapFuncTempCurve.setCoefficient1Constant(0.42415)
1095
- clgCapFuncTempCurve.setCoefficient2x(0.04426)
1096
- clgCapFuncTempCurve.setCoefficient3xPOW2(-0.00042)
1097
- clgCapFuncTempCurve.setCoefficient4y(0.00333)
1098
- clgCapFuncTempCurve.setCoefficient5yPOW2(-0.00008)
1099
- clgCapFuncTempCurve.setCoefficient6xTIMESY(-0.00021)
1100
- clgCapFuncTempCurve.setMinimumValueofx(17)
1101
- clgCapFuncTempCurve.setMaximumValueofx(22)
1102
- clgCapFuncTempCurve.setMinimumValueofy(13)
1103
- clgCapFuncTempCurve.setMaximumValueofy(46)
1104
- # create clgCapFuncFlowFracCurve
1105
- clgCapFuncFlowFracCurve = OpenStudio::Model::CurveQuadratic.new(model)
1106
- clgCapFuncFlowFracCurve.setCoefficient1Constant(0.77136)
1107
- clgCapFuncFlowFracCurve.setCoefficient2x(0.34053)
1108
- clgCapFuncFlowFracCurve.setCoefficient3xPOW2(-0.11088)
1109
- clgCapFuncFlowFracCurve.setMinimumValueofx(0.75918)
1110
- clgCapFuncFlowFracCurve.setMaximumValueofx(1.13877)
1111
- # create clgEirFuncTempCurve
1112
- clgEirFuncTempCurve = OpenStudio::Model::CurveBiquadratic.new(model)
1113
- clgEirFuncTempCurve.setCoefficient1Constant(1.23649)
1114
- clgEirFuncTempCurve.setCoefficient2x(-0.02431)
1115
- clgEirFuncTempCurve.setCoefficient3xPOW2(0.00057)
1116
- clgEirFuncTempCurve.setCoefficient4y(-0.01434)
1117
- clgEirFuncTempCurve.setCoefficient5yPOW2(0.00063)
1118
- clgEirFuncTempCurve.setCoefficient6xTIMESY(-0.00038)
1119
- clgEirFuncTempCurve.setMinimumValueofx(17)
1120
- clgEirFuncTempCurve.setMaximumValueofx(22)
1121
- clgEirFuncTempCurve.setMinimumValueofy(13)
1122
- clgEirFuncTempCurve.setMaximumValueofy(46)
1123
- # create clgEirFuncFlowFracCurve
1124
- clgEirFuncFlowFracCurve = OpenStudio::Model::CurveQuadratic.new(model)
1125
- clgEirFuncFlowFracCurve.setCoefficient1Constant(1.20550)
1126
- clgEirFuncFlowFracCurve.setCoefficient2x(-0.32953)
1127
- clgEirFuncFlowFracCurve.setCoefficient3xPOW2(0.12308)
1128
- clgEirFuncFlowFracCurve.setMinimumValueofx(0.75918)
1129
- clgEirFuncFlowFracCurve.setMaximumValueofx(1.13877)
1130
- # create clgPlrCurve
1131
- clgPlrCurve = OpenStudio::Model::CurveQuadratic.new(model)
1132
- clgPlrCurve.setCoefficient1Constant(0.77100)
1133
- clgPlrCurve.setCoefficient2x(0.22900)
1134
- clgPlrCurve.setCoefficient3xPOW2(0.0)
1135
- clgPlrCurve.setMinimumValueofx(0.0)
1136
- clgPlrCurve.setMaximumValueofx(1.0)
1137
- # cooling coil
1138
- cooling_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(model,
1139
- model.alwaysOnDiscreteSchedule,
1140
- clgCapFuncTempCurve,
1141
- clgCapFuncFlowFracCurve,
1142
- clgEirFuncTempCurve,
1143
- clgEirFuncFlowFracCurve,
1144
- clgPlrCurve)
1145
- cooling_coil.setRatedCOP(OpenStudio::OptionalDouble.new(4))
1146
- air_loop_comps << cooling_coil
1147
- else
1148
- # two speed DX coil (PNNL curves)
1149
- # create cooling coil
1150
- # create clgCapFuncTempCurve
1151
- clgCapFuncTempCurve = OpenStudio::Model::CurveBiquadratic.new(model)
1152
- clgCapFuncTempCurve.setCoefficient1Constant(1.39072)
1153
- clgCapFuncTempCurve.setCoefficient2x(-0.0529058)
1154
- clgCapFuncTempCurve.setCoefficient3xPOW2(0.0018423)
1155
- clgCapFuncTempCurve.setCoefficient4y(0.00058267)
1156
- clgCapFuncTempCurve.setCoefficient5yPOW2(-0.000186814)
1157
- clgCapFuncTempCurve.setCoefficient6xTIMESY(0.000265159)
1158
- clgCapFuncTempCurve.setMinimumValueofx(16.5556)
1159
- clgCapFuncTempCurve.setMaximumValueofx(22.1111)
1160
- clgCapFuncTempCurve.setMinimumValueofy(23.7778)
1161
- clgCapFuncTempCurve.setMaximumValueofy(47.66)
1162
- # create clgCapFuncFlowFracCurve
1163
- clgCapFuncFlowFracCurve = OpenStudio::Model::CurveQuadratic.new(model)
1164
- clgCapFuncFlowFracCurve.setCoefficient1Constant(0.718954)
1165
- clgCapFuncFlowFracCurve.setCoefficient2x(0.435436)
1166
- clgCapFuncFlowFracCurve.setCoefficient3xPOW2(-0.154193)
1167
- clgCapFuncFlowFracCurve.setMinimumValueofx(0.75)
1168
- clgCapFuncFlowFracCurve.setMaximumValueofx(1.25)
1169
- # create clgEirFuncTempCurve
1170
- clgEirFuncTempCurve = OpenStudio::Model::CurveBiquadratic.new(model)
1171
- clgEirFuncTempCurve.setCoefficient1Constant(-0.536161)
1172
- clgEirFuncTempCurve.setCoefficient2x(0.105138)
1173
- clgEirFuncTempCurve.setCoefficient3xPOW2(-0.00172659)
1174
- clgEirFuncTempCurve.setCoefficient4y(0.0149848)
1175
- clgEirFuncTempCurve.setCoefficient5yPOW2(0.000659948)
1176
- clgEirFuncTempCurve.setCoefficient6xTIMESY(-0.0017385)
1177
- clgEirFuncTempCurve.setMinimumValueofx(16.5556)
1178
- clgEirFuncTempCurve.setMaximumValueofx(22.1111)
1179
- clgEirFuncTempCurve.setMinimumValueofy(23.7778)
1180
- clgEirFuncTempCurve.setMaximumValueofy(47.66)
1181
- # create clgEirFuncFlowFracCurve
1182
- clgEirFuncFlowFracCurve = OpenStudio::Model::CurveQuadratic.new(model)
1183
- clgEirFuncFlowFracCurve.setCoefficient1Constant(1.19525)
1184
- clgEirFuncFlowFracCurve.setCoefficient2x(-0.306138)
1185
- clgEirFuncFlowFracCurve.setCoefficient3xPOW2(0.110973)
1186
- clgEirFuncFlowFracCurve.setMinimumValueofx(0.75)
1187
- clgEirFuncFlowFracCurve.setMaximumValueofx(1.25)
1188
- # create clgPlrCurve
1189
- clgPlrCurve = OpenStudio::Model::CurveQuadratic.new(model)
1190
- clgPlrCurve.setCoefficient1Constant(0.77100)
1191
- clgPlrCurve.setCoefficient2x(0.22900)
1192
- clgPlrCurve.setCoefficient3xPOW2(0.0)
1193
- clgPlrCurve.setMinimumValueofx(0.0)
1194
- clgPlrCurve.setMaximumValueofx(1.0)
1195
- # cooling coil
1196
- cooling_coil = OpenStudio::Model::CoilCoolingDXTwoSpeed.new(model,
1197
- model.alwaysOnDiscreteSchedule,
1198
- clgCapFuncTempCurve,
1199
- clgCapFuncFlowFracCurve,
1200
- clgEirFuncTempCurve,
1201
- clgEirFuncFlowFracCurve,
1202
- clgPlrCurve,
1203
- clgCapFuncTempCurve,
1204
- clgEirFuncTempCurve)
1205
- cooling_coil.setRatedHighSpeedCOP(4)
1206
- cooling_coil.setRatedLowSpeedCOP(4)
1207
- air_loop_comps << cooling_coil
1208
- end
1209
- if options['secondaryHVAC']['heat'] == 'Water'
1210
- # water coil
1211
- heating_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule)
1212
- air_loop_comps << heating_coil
1213
- else
1214
- # gas coil
1215
- heating_coil = OpenStudio::Model::CoilHeatingGas.new(model, model.alwaysOnDiscreteSchedule)
1216
- air_loop_comps << heating_coil
1217
- end
1218
- # create controller outdoor air
1219
- controller_OA = OpenStudio::Model::ControllerOutdoorAir.new(model)
1220
- controller_OA.autosizeMinimumOutdoorAirFlowRate
1221
- controller_OA.autosizeMaximumOutdoorAirFlowRate
1222
- controller_OA.setEconomizerControlType('DifferentialEnthalpy')
1223
- controller_OA.setMaximumFractionofOutdoorAirSchedule(options['ventilation_schedule'])
1224
- controller_OA.setHeatRecoveryBypassControlType('BypassWhenOAFlowGreaterThanMinimum')
1225
- # create outdoor air system
1226
- system_OA = OpenStudio::Model::AirLoopHVACOutdoorAirSystem.new(model, controller_OA)
1227
- air_loop_comps << system_OA
1228
- # create ERV
1229
- heat_exchanger = OpenStudio::Model::HeatExchangerAirToAirSensibleAndLatent.new(model)
1230
- heat_exchanger.setAvailabilitySchedule(model.alwaysOnDiscreteSchedule)
1231
- sensible_eff = 0.75
1232
- latent_eff = 0.69
1233
- heat_exchanger.setSensibleEffectivenessat100CoolingAirFlow(sensible_eff)
1234
- heat_exchanger.setSensibleEffectivenessat100HeatingAirFlow(sensible_eff)
1235
- heat_exchanger.setSensibleEffectivenessat75CoolingAirFlow(sensible_eff)
1236
- heat_exchanger.setSensibleEffectivenessat75HeatingAirFlow(sensible_eff)
1237
- heat_exchanger.setLatentEffectivenessat100CoolingAirFlow(latent_eff)
1238
- heat_exchanger.setLatentEffectivenessat100HeatingAirFlow(latent_eff)
1239
- heat_exchanger.setLatentEffectivenessat75CoolingAirFlow(latent_eff)
1240
- heat_exchanger.setLatentEffectivenessat75HeatingAirFlow(latent_eff)
1241
- heat_exchanger.setFrostControlType('ExhaustOnly')
1242
- heat_exchanger.setThresholdTemperature(-12.2)
1243
- heat_exchanger.setInitialDefrostTimeFraction(0.1670)
1244
- heat_exchanger.setRateofDefrostTimeFractionIncrease(0.0240)
1245
- heat_exchanger.setEconomizerLockout(false)
1246
- # create setpoint manager for airloop
1247
- setpoint_manager = OpenStudio::Model::SetpointManagerSingleZoneReheat.new(model)
1248
- setpoint_manager.setMinimumSupplyAirTemperature(10)
1249
- setpoint_manager.setMaximumSupplyAirTemperature(50)
1250
- setpoint_manager.setControlZone(zone)
1251
- # connect components to airloop
1252
- # find the supply inlet node of the airloop
1253
- airloop_supply_inlet = airloop_secondary.supplyInletNode
1254
- # add the components to the airloop
1255
- air_loop_comps.each do |comp|
1256
- comp.addToNode(airloop_supply_inlet)
1257
- if comp.to_CoilHeatingWater.is_initialized
1258
- options['hot_water_plant'].addDemandBranchForComponent(comp)
1259
- elsif comp.to_CoilCoolingWater.is_initialized
1260
- options['chilled_water_plant'].addDemandBranchForComponent(comp)
1261
- end
1262
- end
1263
- # add erv to outdoor air system
1264
- heat_exchanger.addToNode(system_OA.outboardOANode.get)
1265
- # add setpoint manager to supply equipment outlet node
1266
- setpoint_manager.addToNode(airloop_secondary.supplyOutletNode)
1267
- # add thermal zone to airloop
1268
- if options['secondaryHVAC']['fan'] == 'Variable'
1269
- air_terminal = OpenStudio::Model::AirTerminalSingleDuctVAVNoReheat.new(model, model.alwaysOnDiscreteSchedule)
1270
- else
1271
- air_terminal = OpenStudio::Model::AirTerminalSingleDuctUncontrolled.new(model, model.alwaysOnDiscreteSchedule)
1272
- end
1273
- # attach new terminal to the zone and to the airloop
1274
- airloop_secondary.addBranchForZone(zone, air_terminal.to_StraightComponent)
1275
- # add night cycling
1276
- airloop_secondary.setNightCycleControlType('CycleOnAny') # ML Does this work with variable speed fans?
1277
- secondary_airloops << airloop_secondary
1278
- end
1279
- end
1280
-
1281
- # pass back secondary airloops
1282
- result = secondary_airloops
1283
- return result
1284
- end
1285
-
1286
- def self.createPrimaryZoneEquipment(model, runner, options)
1287
- model.getThermalZones.sort.each do |zone|
1288
- if options['zonesPrimary'].include? zone
1289
- if options['zoneHVAC'] == 'FanCoil'
1290
- # create fan coil
1291
- # create fan
1292
- fan = OpenStudio::Model::FanOnOff.new(model, model.alwaysOnDiscreteSchedule)
1293
- fan.setFanEfficiency(0.5)
1294
- fan.setPressureRise(75) # Pa
1295
- fan.autosizeMaximumFlowRate
1296
- fan.setMotorEfficiency(0.9)
1297
- fan.setMotorInAirstreamFraction(1.0)
1298
- # create cooling coil and connect to chilled water plant
1299
- cooling_coil = OpenStudio::Model::CoilCoolingWater.new(model, model.alwaysOnDiscreteSchedule)
1300
- options['chilled_water_plant'].addDemandBranchForComponent(cooling_coil)
1301
- # create heating coil and connect to hot water plant
1302
- heating_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule)
1303
- options['hot_water_plant'].addDemandBranchForComponent(heating_coil)
1304
- # construct fan coil
1305
- fan_coil = OpenStudio::Model::ZoneHVACFourPipeFanCoil.new(model,
1306
- model.alwaysOnDiscreteSchedule,
1307
- fan,
1308
- cooling_coil,
1309
- heating_coil)
1310
- fan_coil.setMaximumOutdoorAirFlowRate(0)
1311
- # add fan coil to thermal zone
1312
- fan_coil.addToThermalZone(zone)
1313
- elsif options['zoneHVAC'].include? 'GSHP'
1314
- # create water source heat pump and attach to heat pump loop
1315
- # create fan
1316
- fan = OpenStudio::Model::FanOnOff.new(model, model.alwaysOnDiscreteSchedule)
1317
- fan.setFanEfficiency(0.5)
1318
- fan.setPressureRise(75) # Pa
1319
- fan.autosizeMaximumFlowRate
1320
- fan.setMotorEfficiency(0.9)
1321
- fan.setMotorInAirstreamFraction(1.0)
1322
- # create cooling coil and connect to heat pump loop
1323
- cooling_coil = OpenStudio::Model::CoilCoolingWaterToAirHeatPumpEquationFit.new(model)
1324
- cooling_coil.setRatedCoolingCoefficientofPerformance(6.45)
1325
-
1326
- curve = OpenStudio::Model::CurveQuadLinear.new(model)
1327
- curve.setName("#{cooling_coil.name}_tot_clg_cap_curve")
1328
- curve.setCoefficient1Constant(-9.149069561)
1329
- curve.setCoefficient2w(10.87814026)
1330
- curve.setCoefficient3x(-1.718780157)
1331
- curve.setCoefficient4y(0.746414818)
1332
- curve.setCoefficient5z(0.0)
1333
- cooling_coil.setTotalCoolingCapacityCurve(curve)
1334
-
1335
- curve = OpenStudio::Model::CurveQuintLinear.new(model)
1336
- curve.setName("#{cooling_coil.name}_sens_clg_cap_curve")
1337
- curve.setCoefficient1Constant(-5.462690012)
1338
- curve.setCoefficient2v(17.95968138)
1339
- curve.setCoefficient3w(-11.87818402)
1340
- curve.setCoefficient4x(-0.980163419)
1341
- curve.setCoefficient5y(0.767285761)
1342
- curve.setCoefficient6z(0.0)
1343
- cooling_coil.setSensibleCoolingCapacityCurve(curve)
1344
-
1345
- curve = OpenStudio::Model::CurveQuadLinear.new(model)
1346
- curve.setName("#{cooling_coil.name}_clg_pwr_consu_curve")
1347
- curve.setCoefficient1Constant(-3.205409884)
1348
- curve.setCoefficient2w(-0.976409399)
1349
- curve.setCoefficient3x(3.97892546)
1350
- curve.setCoefficient4y(0.938181818)
1351
- curve.setCoefficient5z(0.0)
1352
- cooling_coil.setCoolingPowerConsumptionCurve(curve)
1353
-
1354
- options['heat_pump_loop'].addDemandBranchForComponent(cooling_coil)
1355
- # create heating coil and connect to heat pump loop
1356
- heating_coil = OpenStudio::Model::CoilHeatingWaterToAirHeatPumpEquationFit.new(model)
1357
- heating_coil.setRatedHeatingCoefficientofPerformance(4.0)
1358
-
1359
- curve = OpenStudio::Model::CurveQuadLinear.new(model)
1360
- curve.setName("#{heating_coil.name}_htg_cap_curve")
1361
- curve.setCoefficient1Constant(-1.361311959)
1362
- curve.setCoefficient2w(-2.471798046)
1363
- curve.setCoefficient3x(4.173164514)
1364
- curve.setCoefficient4y(0.640757401)
1365
- curve.setCoefficient5z(0.0)
1366
- heating_coil.setHeatingCapacityCurve(curve)
1367
-
1368
- curve = OpenStudio::Model::CurveQuadLinear.new(model)
1369
- curve.setName("#{heating_coil.name}_htg_pwr_consu_curve")
1370
- curve.setCoefficient1Constant(-2.176941116)
1371
- curve.setCoefficient2w(0.832114286)
1372
- curve.setCoefficient3x(1.570743399)
1373
- curve.setCoefficient4y(0.690793651)
1374
- curve.setCoefficient5z(0.0)
1375
- heating_coil.setHeatingPowerConsumptionCurve(curve)
1376
-
1377
- options['heat_pump_loop'].addDemandBranchForComponent(heating_coil)
1378
- # create supplemental heating coil
1379
- supplemental_heating_coil = OpenStudio::Model::CoilHeatingElectric.new(model, model.alwaysOnDiscreteSchedule)
1380
- # construct heat pump
1381
- heat_pump = OpenStudio::Model::ZoneHVACWaterToAirHeatPump.new(model,
1382
- model.alwaysOnDiscreteSchedule,
1383
- fan,
1384
- heating_coil,
1385
- cooling_coil,
1386
- supplemental_heating_coil)
1387
- heat_pump.setSupplyAirFlowRateWhenNoCoolingorHeatingisNeeded(OpenStudio::OptionalDouble.new(0))
1388
- heat_pump.setOutdoorAirFlowRateDuringCoolingOperation(OpenStudio::OptionalDouble.new(0))
1389
- heat_pump.setOutdoorAirFlowRateDuringHeatingOperation(OpenStudio::OptionalDouble.new(0))
1390
- heat_pump.setOutdoorAirFlowRateWhenNoCoolingorHeatingisNeeded(OpenStudio::OptionalDouble.new(0))
1391
- # add heat pump to thermal zone
1392
- heat_pump.addToThermalZone(zone)
1393
- elsif options['zoneHVAC'] == 'Baseboard'
1394
- # create baseboard heater add add to thermal zone and hot water loop
1395
- baseboard_coil = OpenStudio::Model::CoilHeatingWaterBaseboard.new(model)
1396
- baseboard_heater = OpenStudio::Model::ZoneHVACBaseboardConvectiveWater.new(model, model.alwaysOnDiscreteSchedule, baseboard_coil)
1397
- baseboard_heater.addToThermalZone(zone)
1398
- options['hot_water_plant'].addDemandBranchForComponent(baseboard_coil)
1399
- elsif options['zoneHVAC'] == 'Radiant'
1400
- # create low temperature radiant object and add to thermal zone and radiant plant loops
1401
- # create hot water coil and attach to radiant hot water loop
1402
- heating_coil = OpenStudio::Model::CoilHeatingLowTempRadiantVarFlow.new(model, options['mean_radiant_heating_setpoint_schedule'])
1403
- options['radiant_hot_water_plant'].addDemandBranchForComponent(heating_coil)
1404
- # create chilled water coil and attach to radiant chilled water loop
1405
- cooling_coil = OpenStudio::Model::CoilCoolingLowTempRadiantVarFlow.new(model, options['mean_radiant_cooling_setpoint_schedule'])
1406
- options['radiant_chilled_water_plant'].addDemandBranchForComponent(cooling_coil)
1407
- low_temp_radiant = OpenStudio::Model::ZoneHVACLowTempRadiantVarFlow.new(model,
1408
- model.alwaysOnDiscreteSchedule,
1409
- heating_coil,
1410
- cooling_coil)
1411
- low_temp_radiant.setRadiantSurfaceType('Floors')
1412
- low_temp_radiant.setHydronicTubingInsideDiameter(0.012)
1413
- low_temp_radiant.setTemperatureControlType('MeanRadiantTemperature')
1414
- low_temp_radiant.addToThermalZone(zone)
1415
- # create radiant floor construction and substitute for existing floor (interior or exterior) constructions
1416
- # create materials for radiant floor construction
1417
- layers = []
1418
- # ignore layer below insulation, which will depend on boundary condition
1419
- layers << rigid_insulation_1in = OpenStudio::Model::StandardOpaqueMaterial.new(model, 'Rough', 0.0254, 0.02, 56.06, 1210)
1420
- layers << concrete_2in = OpenStudio::Model::StandardOpaqueMaterial.new(model, 'MediumRough', 0.0508, 2.31, 2322, 832)
1421
- layers << concrete_2in
1422
- # create radiant floor construction from materials
1423
- radiant_floor = OpenStudio::Model::ConstructionWithInternalSource.new(layers)
1424
- radiant_floor.setSourcePresentAfterLayerNumber(2)
1425
- radiant_floor.setSourcePresentAfterLayerNumber(2)
1426
- # assign radiant construction to zone floor
1427
- zone.spaces.each do |space|
1428
- space.surfaces.each do |surface|
1429
- if surface.surfaceType == 'Floor'
1430
- surface.setConstruction(radiant_floor)
1431
- end
1432
- end
1433
- end
1434
- elsif options['zoneHVAC'] == 'DualDuct'
1435
- # create baseboard heater add add to thermal zone and hot water loop
1436
- baseboard_coil = OpenStudio::Model::CoilHeatingWaterBaseboard.new(model)
1437
- baseboard_heater = OpenStudio::Model::ZoneHVACBaseboardConvectiveWater.new(model, model.alwaysOnDiscreteSchedule, baseboard_coil)
1438
- baseboard_heater.addToThermalZone(zone)
1439
- options['hot_water_plant'].addDemandBranchForComponent(baseboard_coil)
1440
- # create fan coil (to mimic functionality of DOAS)
1441
- # variable speed fan
1442
- fan = OpenStudio::Model::FanVariableVolume.new(model, model.alwaysOnDiscreteSchedule)
1443
- fan.setFanEfficiency(0.69)
1444
- fan.setPressureRise(75) # Pa #ML This number is a guess; zone equipment pretending to be a DOAS
1445
- fan.autosizeMaximumFlowRate
1446
- fan.setFanPowerMinimumFlowFraction(0.6)
1447
- fan.setMotorEfficiency(0.9)
1448
- fan.setMotorInAirstreamFraction(1.0)
1449
- # create chilled water coil and attach to chilled water loop
1450
- cooling_coil = OpenStudio::Model::CoilCoolingWater.new(model, model.alwaysOnDiscreteSchedule)
1451
- options['chilled_water_plant'].addDemandBranchForComponent(cooling_coil)
1452
- # create hot water coil and attach to hot water loop
1453
- heating_coil = OpenStudio::Model::CoilHeatingWater.new(model, model.alwaysOnDiscreteSchedule)
1454
- options['hot_water_plant'].addDemandBranchForComponent(heating_coil)
1455
- # construct fan coil (DOAS) and attach to thermal zone
1456
- fan_coil_doas = OpenStudio::Model::ZoneHVACFourPipeFanCoil.new(model,
1457
- options['ventilation_schedule'],
1458
- fan,
1459
- cooling_coil,
1460
- heating_coil)
1461
- fan_coil_doas.setCapacityControlMethod('VariableFanVariableFlow')
1462
- fan_coil_doas.addToThermalZone(zone)
1463
- end
1464
- end
1465
- end
1466
- end
1467
-
1468
- def self.addDCV(model, runner, options)
1469
- unless options['primary_airloops'].nil?
1470
- options['primary_airloops'].each do |airloop|
1471
- if options['allHVAC']['primary']['fan'] == 'Variable'
1472
- controller_mv = airloop.airLoopHVACOutdoorAirSystem.get.getControllerOutdoorAir.controllerMechanicalVentilation
1473
- controller_mv.setDemandControlledVentilation(true)
1474
- runner.registerInfo("Enabling demand control ventilation for #{airloop.name}")
1475
- end
1476
- end
1477
- end
1478
-
1479
- unless options['secondary_airloops'].nil?
1480
- options['secondary_airloops'].each do |airloop|
1481
- if options['allHVAC']['secondary']['fan'] == 'Variable'
1482
- controller_mv = airloop.airLoopHVACOutdoorAirSystem.get.getControllerOutdoorAir.controllerMechanicalVentilation
1483
- controller_mv.setDemandControlledVentilation(true)
1484
- runner.registerInfo("Enabling demand control ventilation for #{airloop.name}")
1485
- end
1486
- end
1487
- end
1488
- end
1489
-
1490
- def self.getSpacesAndSpaceTypesFromThermalZone(zone, runner)
1491
- # set flag
1492
- space_type_hash = {}
1493
-
1494
- # check if zone has spaces
1495
- if zone.spaces.empty?
1496
- runner.registerWarning("#{zone.name} doesn't have any spaces.")
1497
- else
1498
- # check if all spaces have the same space type
1499
- zone.spaces.each do |space|
1500
- if !space.spaceType.is_initialized
1501
- runner.registerWarning("One or more spaces in #{zone.name} doesn't have a space type assigned.")
1502
- space_type_hash[space] = false
1503
- return space_type
1504
- else
1505
- space_type_hash[space] = space.spaceType.get
1506
- end
1507
- end
1508
- end
1509
-
1510
- return space_type_hash
1511
- end
1512
-
1513
- def self.get_or_add_hot_water_loop(model)
1514
- # How water loop
1515
- hw_loop = nil
1516
- model.getLoops.sort.each do |loop|
1517
- if loop.name.to_s == 'Hot Water Loop' # sizingPlant has loopType method to do this better
1518
- hw_loop = loop.to_PlantLoop.get
1519
- end
1520
- end
1521
-
1522
- if hw_loop.nil?
1523
- hw_loop = OpenStudio::Model::PlantLoop.new(model)
1524
- hw_loop.setName('Hot Water Loop')
1525
- hw_sizing_plant = hw_loop.sizingPlant
1526
- hw_sizing_plant.setLoopType('Heating')
1527
- hw_sizing_plant.setDesignLoopExitTemperature(82.0) # TODO: units
1528
- hw_sizing_plant.setLoopDesignTemperatureDifference(11.0)
1529
-
1530
- hw_pump = OpenStudio::Model::PumpVariableSpeed.new(model)
1531
-
1532
- boiler = OpenStudio::Model::BoilerHotWater.new(model)
1533
-
1534
- boiler_eff_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(model)
1535
- boiler_eff_f_of_temp.setName('Boiler Efficiency')
1536
- boiler_eff_f_of_temp.setCoefficient1Constant(1.0)
1537
- boiler_eff_f_of_temp.setInputUnitTypeforX('Dimensionless')
1538
- boiler_eff_f_of_temp.setInputUnitTypeforY('Dimensionless')
1539
- boiler_eff_f_of_temp.setOutputUnitType('Dimensionless')
1540
-
1541
- boiler.setNormalizedBoilerEfficiencyCurve(boiler_eff_f_of_temp)
1542
- boiler.setEfficiencyCurveTemperatureEvaluationVariable('LeavingBoiler')
1543
-
1544
- boiler_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
1545
-
1546
- hw_supply_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
1547
-
1548
- # Add the components to the hot water loop
1549
- hw_supply_inlet_node = hw_loop.supplyInletNode
1550
- hw_supply_outlet_node = hw_loop.supplyOutletNode
1551
- hw_pump.addToNode(hw_supply_inlet_node)
1552
- hw_loop.addSupplyBranchForComponent(boiler)
1553
- hw_loop.addSupplyBranchForComponent(boiler_bypass_pipe)
1554
- hw_supply_outlet_pipe.addToNode(hw_supply_outlet_node)
1555
-
1556
- # Add a setpoint manager to control the
1557
- # hot water to a constant temperature
1558
- hw_t_c = OpenStudio.convert(153, 'F', 'C').get
1559
- hw_t_sch = OpenStudio::Model::ScheduleRuleset.new(model)
1560
- hw_t_sch.setName('HW Temp')
1561
- hw_t_sch.defaultDaySchedule.setName('HW Temp Default')
1562
- hw_t_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), hw_t_c)
1563
- hw_t_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(model, hw_t_sch)
1564
- hw_t_stpt_manager.addToNode(hw_supply_outlet_node)
1565
-
1566
- end
1567
-
1568
- return hw_loop
1569
- end
1570
-
1571
- def self.get_or_add_water_cooled_chiller_loops(model)
1572
- # Chilled Water Plant
1573
- # todo - add in logic here that if existing chw_loop is air cooled, replace it with this one.
1574
- chw_loop = nil
1575
- model.getLoops.sort.each do |loop|
1576
- if loop.name.to_s == 'Chilled Water Loop'
1577
- chw_loop = loop.to_PlantLoop.get
1578
- end
1579
- end
1580
-
1581
- if chw_loop.nil?
1582
- chw_loop = OpenStudio::Model::PlantLoop.new(model)
1583
- chw_loop.setName('Chilled Water Loop')
1584
- chw_sizing_plant = chw_loop.sizingPlant
1585
- chw_sizing_plant.setLoopType('Cooling')
1586
- chw_sizing_plant.setDesignLoopExitTemperature(7.22) # TODO: units
1587
- chw_sizing_plant.setLoopDesignTemperatureDifference(6.67)
1588
-
1589
- chw_pump = OpenStudio::Model::PumpVariableSpeed.new(model)
1590
-
1591
- clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(model)
1592
- clg_cap_f_of_temp.setCoefficient1Constant(1.0215158)
1593
- clg_cap_f_of_temp.setCoefficient2x(0.037035864)
1594
- clg_cap_f_of_temp.setCoefficient3xPOW2(0.0002332476)
1595
- clg_cap_f_of_temp.setCoefficient4y(-0.003894048)
1596
- clg_cap_f_of_temp.setCoefficient5yPOW2(-6.52536e-005)
1597
- clg_cap_f_of_temp.setCoefficient6xTIMESY(-0.0002680452)
1598
- clg_cap_f_of_temp.setMinimumValueofx(5.0)
1599
- clg_cap_f_of_temp.setMaximumValueofx(10.0)
1600
- clg_cap_f_of_temp.setMinimumValueofy(24.0)
1601
- clg_cap_f_of_temp.setMaximumValueofy(35.0)
1602
-
1603
- eir_f_of_avail_to_nom_cap = OpenStudio::Model::CurveBiquadratic.new(model)
1604
- eir_f_of_avail_to_nom_cap.setCoefficient1Constant(0.70176857)
1605
- eir_f_of_avail_to_nom_cap.setCoefficient2x(-0.00452016)
1606
- eir_f_of_avail_to_nom_cap.setCoefficient3xPOW2(0.0005331096)
1607
- eir_f_of_avail_to_nom_cap.setCoefficient4y(-0.005498208)
1608
- eir_f_of_avail_to_nom_cap.setCoefficient5yPOW2(0.0005445792)
1609
- eir_f_of_avail_to_nom_cap.setCoefficient6xTIMESY(-0.0007290324)
1610
- eir_f_of_avail_to_nom_cap.setMinimumValueofx(5.0)
1611
- eir_f_of_avail_to_nom_cap.setMaximumValueofx(10.0)
1612
- eir_f_of_avail_to_nom_cap.setMinimumValueofy(24.0)
1613
- eir_f_of_avail_to_nom_cap.setMaximumValueofy(35.0)
1614
-
1615
- eir_f_of_plr = OpenStudio::Model::CurveQuadratic.new(model)
1616
- eir_f_of_plr.setCoefficient1Constant(0.06369119)
1617
- eir_f_of_plr.setCoefficient2x(0.58488832)
1618
- eir_f_of_plr.setCoefficient3xPOW2(0.35280274)
1619
- eir_f_of_plr.setMinimumValueofx(0.0)
1620
- eir_f_of_plr.setMaximumValueofx(1.0)
1621
-
1622
- chiller = OpenStudio::Model::ChillerElectricEIR.new(model,
1623
- clg_cap_f_of_temp,
1624
- eir_f_of_avail_to_nom_cap,
1625
- eir_f_of_plr)
1626
-
1627
- chiller_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
1628
-
1629
- chw_supply_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
1630
-
1631
- # Add the components to the chilled water loop
1632
- chw_supply_inlet_node = chw_loop.supplyInletNode
1633
- chw_supply_outlet_node = chw_loop.supplyOutletNode
1634
- chw_pump.addToNode(chw_supply_inlet_node)
1635
- chw_loop.addSupplyBranchForComponent(chiller)
1636
- chw_loop.addSupplyBranchForComponent(chiller_bypass_pipe)
1637
- chw_supply_outlet_pipe.addToNode(chw_supply_outlet_node)
1638
-
1639
- # Add a setpoint manager to control the
1640
- # chilled water to a constant temperature
1641
- chw_t_c = OpenStudio.convert(44, 'F', 'C').get
1642
- chw_t_sch = OpenStudio::Model::ScheduleRuleset.new(model)
1643
- chw_t_sch.setName('CHW Temp')
1644
- chw_t_sch.defaultDaySchedule.setName('HW Temp Default')
1645
- chw_t_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), chw_t_c)
1646
- chw_t_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(model, chw_t_sch)
1647
- chw_t_stpt_manager.addToNode(chw_supply_outlet_node)
1648
-
1649
- end
1650
-
1651
- # Condenser System
1652
- cw_loop = nil
1653
- model.getLoops.sort.each do |loop|
1654
- if loop.name.to_s == 'Condenser Water Loop'
1655
- cw_loop = loop.to_PlantLoop.get
1656
- end
1657
- end
1658
-
1659
- if cw_loop.nil?
1660
- cw_loop = OpenStudio::Model::PlantLoop.new(model)
1661
- cw_loop.setName('Condenser Water Loop')
1662
- cw_sizing_plant = cw_loop.sizingPlant
1663
- cw_sizing_plant.setLoopType('Condenser')
1664
- cw_sizing_plant.setDesignLoopExitTemperature(29.4) # TODO: units
1665
- cw_sizing_plant.setLoopDesignTemperatureDifference(5.6)
1666
-
1667
- cw_pump = OpenStudio::Model::PumpVariableSpeed.new(model)
1668
-
1669
- clg_tower = OpenStudio::Model::CoolingTowerSingleSpeed.new(model)
1670
-
1671
- clg_tower_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
1672
-
1673
- cw_supply_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
1674
-
1675
- # Add the components to the condenser water loop
1676
- cw_supply_inlet_node = cw_loop.supplyInletNode
1677
- cw_supply_outlet_node = cw_loop.supplyOutletNode
1678
- cw_pump.addToNode(cw_supply_inlet_node)
1679
- cw_loop.addSupplyBranchForComponent(clg_tower)
1680
- cw_loop.addSupplyBranchForComponent(clg_tower_bypass_pipe)
1681
- cw_supply_outlet_pipe.addToNode(cw_supply_outlet_node)
1682
- cw_loop.addDemandBranchForComponent(chiller)
1683
-
1684
- # Add a setpoint manager to control the
1685
- # condenser water to follow the OA temp
1686
- cw_t_stpt_manager = OpenStudio::Model::SetpointManagerFollowOutdoorAirTemperature.new(model)
1687
- cw_t_stpt_manager.addToNode(cw_supply_outlet_node)
1688
-
1689
- end
1690
-
1691
- return chw_loop
1692
- end
1693
-
1694
- def self.get_or_add_air_cooled_chiller_loop(model)
1695
- # Chilled Water Plant
1696
- chw_loop = nil
1697
- model.getLoops.sort.each do |loop|
1698
- if loop.name.to_s == 'Chilled Water Loop'
1699
- chw_loop = loop.to_PlantLoop.get
1700
- end
1701
- end
1702
-
1703
- if chw_loop.nil?
1704
- chw_loop = OpenStudio::Model::PlantLoop.new(model)
1705
- chw_loop.setName('Chilled Water Loop')
1706
- chw_sizing_plant = chw_loop.sizingPlant
1707
- chw_sizing_plant.setLoopType('Cooling')
1708
- chw_sizing_plant.setDesignLoopExitTemperature(7.22) # TODO: units
1709
- chw_sizing_plant.setLoopDesignTemperatureDifference(6.67)
1710
-
1711
- chw_pump = OpenStudio::Model::PumpVariableSpeed.new(model)
1712
-
1713
- clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(model)
1714
- clg_cap_f_of_temp.setCoefficient1Constant(1.0215158)
1715
- clg_cap_f_of_temp.setCoefficient2x(0.037035864)
1716
- clg_cap_f_of_temp.setCoefficient3xPOW2(0.0002332476)
1717
- clg_cap_f_of_temp.setCoefficient4y(-0.003894048)
1718
- clg_cap_f_of_temp.setCoefficient5yPOW2(-6.52536e-005)
1719
- clg_cap_f_of_temp.setCoefficient6xTIMESY(-0.0002680452)
1720
- clg_cap_f_of_temp.setMinimumValueofx(5.0)
1721
- clg_cap_f_of_temp.setMaximumValueofx(10.0)
1722
- clg_cap_f_of_temp.setMinimumValueofy(24.0)
1723
- clg_cap_f_of_temp.setMaximumValueofy(35.0)
1724
-
1725
- eir_f_of_avail_to_nom_cap = OpenStudio::Model::CurveBiquadratic.new(model)
1726
- eir_f_of_avail_to_nom_cap.setCoefficient1Constant(0.70176857)
1727
- eir_f_of_avail_to_nom_cap.setCoefficient2x(-0.00452016)
1728
- eir_f_of_avail_to_nom_cap.setCoefficient3xPOW2(0.0005331096)
1729
- eir_f_of_avail_to_nom_cap.setCoefficient4y(-0.005498208)
1730
- eir_f_of_avail_to_nom_cap.setCoefficient5yPOW2(0.0005445792)
1731
- eir_f_of_avail_to_nom_cap.setCoefficient6xTIMESY(-0.0007290324)
1732
- eir_f_of_avail_to_nom_cap.setMinimumValueofx(5.0)
1733
- eir_f_of_avail_to_nom_cap.setMaximumValueofx(10.0)
1734
- eir_f_of_avail_to_nom_cap.setMinimumValueofy(24.0)
1735
- eir_f_of_avail_to_nom_cap.setMaximumValueofy(35.0)
1736
-
1737
- eir_f_of_plr = OpenStudio::Model::CurveQuadratic.new(model)
1738
- eir_f_of_plr.setCoefficient1Constant(0.06369119)
1739
- eir_f_of_plr.setCoefficient2x(0.58488832)
1740
- eir_f_of_plr.setCoefficient3xPOW2(0.35280274)
1741
- eir_f_of_plr.setMinimumValueofx(0.0)
1742
- eir_f_of_plr.setMaximumValueofx(1.0)
1743
-
1744
- chiller = OpenStudio::Model::ChillerElectricEIR.new(model,
1745
- clg_cap_f_of_temp,
1746
- eir_f_of_avail_to_nom_cap,
1747
- eir_f_of_plr)
1748
-
1749
- chiller_bypass_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
1750
-
1751
- chw_supply_outlet_pipe = OpenStudio::Model::PipeAdiabatic.new(model)
1752
-
1753
- # Add the components to the chilled water loop
1754
- chw_supply_inlet_node = chw_loop.supplyInletNode
1755
- chw_supply_outlet_node = chw_loop.supplyOutletNode
1756
- chw_pump.addToNode(chw_supply_inlet_node)
1757
- chw_loop.addSupplyBranchForComponent(chiller)
1758
- chw_loop.addSupplyBranchForComponent(chiller_bypass_pipe)
1759
- chw_supply_outlet_pipe.addToNode(chw_supply_outlet_node)
1760
-
1761
- # Add a setpoint manager to control the
1762
- # chilled water to a constant temperature
1763
- chw_t_c = OpenStudio.convert(44, 'F', 'C').get
1764
- chw_t_sch = OpenStudio::Model::ScheduleRuleset.new(model)
1765
- chw_t_sch.setName('CHW Temp')
1766
- chw_t_sch.defaultDaySchedule.setName('HW Temp Default')
1767
- chw_t_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), chw_t_c)
1768
- chw_t_stpt_manager = OpenStudio::Model::SetpointManagerScheduled.new(model, chw_t_sch)
1769
- chw_t_stpt_manager.addToNode(chw_supply_outlet_node)
1770
-
1771
- end
1772
-
1773
- return chw_loop
1774
- end
1775
-
1776
- def self._add_coil_cooling_dx_two_speed(model)
1777
- clg_coil = nil
1778
-
1779
- always_on = model.alwaysOnDiscreteSchedule
1780
-
1781
- clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(model)
1782
- clg_cap_f_of_temp.setCoefficient1Constant(0.42415)
1783
- clg_cap_f_of_temp.setCoefficient2x(0.04426)
1784
- clg_cap_f_of_temp.setCoefficient3xPOW2(-0.00042)
1785
- clg_cap_f_of_temp.setCoefficient4y(0.00333)
1786
- clg_cap_f_of_temp.setCoefficient5yPOW2(-0.00008)
1787
- clg_cap_f_of_temp.setCoefficient6xTIMESY(-0.00021)
1788
- clg_cap_f_of_temp.setMinimumValueofx(17.0)
1789
- clg_cap_f_of_temp.setMaximumValueofx(22.0)
1790
- clg_cap_f_of_temp.setMinimumValueofy(13.0)
1791
- clg_cap_f_of_temp.setMaximumValueofy(46.0)
1792
-
1793
- clg_cap_f_of_flow = OpenStudio::Model::CurveQuadratic.new(model)
1794
- clg_cap_f_of_flow.setCoefficient1Constant(0.77136)
1795
- clg_cap_f_of_flow.setCoefficient2x(0.34053)
1796
- clg_cap_f_of_flow.setCoefficient3xPOW2(-0.11088)
1797
- clg_cap_f_of_flow.setMinimumValueofx(0.75918)
1798
- clg_cap_f_of_flow.setMaximumValueofx(1.13877)
1799
-
1800
- clg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(model)
1801
- clg_energy_input_ratio_f_of_temp.setCoefficient1Constant(1.23649)
1802
- clg_energy_input_ratio_f_of_temp.setCoefficient2x(-0.02431)
1803
- clg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(0.00057)
1804
- clg_energy_input_ratio_f_of_temp.setCoefficient4y(-0.01434)
1805
- clg_energy_input_ratio_f_of_temp.setCoefficient5yPOW2(0.00063)
1806
- clg_energy_input_ratio_f_of_temp.setCoefficient6xTIMESY(-0.00038)
1807
- clg_energy_input_ratio_f_of_temp.setMinimumValueofx(17.0)
1808
- clg_energy_input_ratio_f_of_temp.setMaximumValueofx(22.0)
1809
- clg_energy_input_ratio_f_of_temp.setMinimumValueofy(13.0)
1810
- clg_energy_input_ratio_f_of_temp.setMaximumValueofy(46.0)
1811
-
1812
- clg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(model)
1813
- clg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.20550)
1814
- clg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.32953)
1815
- clg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.12308)
1816
- clg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.75918)
1817
- clg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.13877)
1818
-
1819
- clg_part_load_ratio = OpenStudio::Model::CurveQuadratic.new(model)
1820
- clg_part_load_ratio.setCoefficient1Constant(0.77100)
1821
- clg_part_load_ratio.setCoefficient2x(0.22900)
1822
- clg_part_load_ratio.setCoefficient3xPOW2(0.0)
1823
- clg_part_load_ratio.setMinimumValueofx(0.0)
1824
- clg_part_load_ratio.setMaximumValueofx(1.0)
1825
-
1826
- clg_cap_f_of_temp_low_spd = OpenStudio::Model::CurveBiquadratic.new(model)
1827
- clg_cap_f_of_temp_low_spd.setCoefficient1Constant(0.42415)
1828
- clg_cap_f_of_temp_low_spd.setCoefficient2x(0.04426)
1829
- clg_cap_f_of_temp_low_spd.setCoefficient3xPOW2(-0.00042)
1830
- clg_cap_f_of_temp_low_spd.setCoefficient4y(0.00333)
1831
- clg_cap_f_of_temp_low_spd.setCoefficient5yPOW2(-0.00008)
1832
- clg_cap_f_of_temp_low_spd.setCoefficient6xTIMESY(-0.00021)
1833
- clg_cap_f_of_temp_low_spd.setMinimumValueofx(17.0)
1834
- clg_cap_f_of_temp_low_spd.setMaximumValueofx(22.0)
1835
- clg_cap_f_of_temp_low_spd.setMinimumValueofy(13.0)
1836
- clg_cap_f_of_temp_low_spd.setMaximumValueofy(46.0)
1837
-
1838
- clg_energy_input_ratio_f_of_temp_low_spd = OpenStudio::Model::CurveBiquadratic.new(model)
1839
- clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient1Constant(1.23649)
1840
- clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient2x(-0.02431)
1841
- clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient3xPOW2(0.00057)
1842
- clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient4y(-0.01434)
1843
- clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient5yPOW2(0.00063)
1844
- clg_energy_input_ratio_f_of_temp_low_spd.setCoefficient6xTIMESY(-0.00038)
1845
- clg_energy_input_ratio_f_of_temp_low_spd.setMinimumValueofx(17.0)
1846
- clg_energy_input_ratio_f_of_temp_low_spd.setMaximumValueofx(22.0)
1847
- clg_energy_input_ratio_f_of_temp_low_spd.setMinimumValueofy(13.0)
1848
- clg_energy_input_ratio_f_of_temp_low_spd.setMaximumValueofy(46.0)
1849
-
1850
- clg_coil = OpenStudio::Model::CoilCoolingDXTwoSpeed.new(model,
1851
- always_on,
1852
- clg_cap_f_of_temp,
1853
- clg_cap_f_of_flow,
1854
- clg_energy_input_ratio_f_of_temp,
1855
- clg_energy_input_ratio_f_of_flow,
1856
- clg_part_load_ratio,
1857
- clg_cap_f_of_temp_low_spd,
1858
- clg_energy_input_ratio_f_of_temp_low_spd)
1859
-
1860
- clg_coil.setRatedLowSpeedSensibleHeatRatio(OpenStudio::OptionalDouble.new(0.69))
1861
- clg_coil.setBasinHeaterCapacity(10)
1862
- clg_coil.setBasinHeaterSetpointTemperature(2.0)
1863
-
1864
- return clg_coil
1865
- end
1866
-
1867
- def self._add_coil_cooling_dx_single_speed_sys_type_1(model)
1868
- clg_coil = nil
1869
-
1870
- always_on = model.alwaysOnDiscreteSchedule
1871
-
1872
- clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(model)
1873
- clg_cap_f_of_temp.setCoefficient1Constant(0.942587793)
1874
- clg_cap_f_of_temp.setCoefficient2x(0.009543347)
1875
- clg_cap_f_of_temp.setCoefficient3xPOW2(0.000683770)
1876
- clg_cap_f_of_temp.setCoefficient4y(-0.011042676)
1877
- clg_cap_f_of_temp.setCoefficient5yPOW2(0.000005249)
1878
- clg_cap_f_of_temp.setCoefficient6xTIMESY(-0.000009720)
1879
- clg_cap_f_of_temp.setMinimumValueofx(17.0)
1880
- clg_cap_f_of_temp.setMaximumValueofx(22.0)
1881
- clg_cap_f_of_temp.setMinimumValueofy(13.0)
1882
- clg_cap_f_of_temp.setMaximumValueofy(46.0)
1883
-
1884
- clg_cap_f_of_flow = OpenStudio::Model::CurveQuadratic.new(model)
1885
- clg_cap_f_of_flow.setCoefficient1Constant(0.8)
1886
- clg_cap_f_of_flow.setCoefficient2x(0.2)
1887
- clg_cap_f_of_flow.setCoefficient3xPOW2(0.0)
1888
- clg_cap_f_of_flow.setMinimumValueofx(0.5)
1889
- clg_cap_f_of_flow.setMaximumValueofx(1.5)
1890
-
1891
- energy_input_ratio_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(model)
1892
- energy_input_ratio_f_of_temp.setCoefficient1Constant(0.342414409)
1893
- energy_input_ratio_f_of_temp.setCoefficient2x(0.034885008)
1894
- energy_input_ratio_f_of_temp.setCoefficient3xPOW2(-0.000623700)
1895
- energy_input_ratio_f_of_temp.setCoefficient4y(0.004977216)
1896
- energy_input_ratio_f_of_temp.setCoefficient5yPOW2(0.000437951)
1897
- energy_input_ratio_f_of_temp.setCoefficient6xTIMESY(-0.000728028)
1898
- energy_input_ratio_f_of_temp.setMinimumValueofx(17.0)
1899
- energy_input_ratio_f_of_temp.setMaximumValueofx(22.0)
1900
- energy_input_ratio_f_of_temp.setMinimumValueofy(13.0)
1901
- energy_input_ratio_f_of_temp.setMaximumValueofy(46.0)
1902
-
1903
- energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(model)
1904
- energy_input_ratio_f_of_flow.setCoefficient1Constant(1.1552)
1905
- energy_input_ratio_f_of_flow.setCoefficient2x(-0.1808)
1906
- energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.0256)
1907
- energy_input_ratio_f_of_flow.setMinimumValueofx(0.5)
1908
- energy_input_ratio_f_of_flow.setMaximumValueofx(1.5)
1909
-
1910
- part_load_fraction = OpenStudio::Model::CurveQuadratic.new(model)
1911
- part_load_fraction.setCoefficient1Constant(0.85)
1912
- part_load_fraction.setCoefficient2x(0.15)
1913
- part_load_fraction.setCoefficient3xPOW2(0.0)
1914
- part_load_fraction.setMinimumValueofx(0.0)
1915
- part_load_fraction.setMaximumValueofx(1.0)
1916
-
1917
- clg_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(model,
1918
- always_on,
1919
- clg_cap_f_of_temp,
1920
- clg_cap_f_of_flow,
1921
- energy_input_ratio_f_of_temp,
1922
- energy_input_ratio_f_of_flow,
1923
- part_load_fraction)
1924
-
1925
- return clg_coil
1926
- end
1927
-
1928
- def self._add_coil_cooling_dx_single_speed_sys_type_2(model)
1929
- clg_coil = nil
1930
-
1931
- always_on = model.alwaysOnDiscreteSchedule
1932
-
1933
- clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(model)
1934
- clg_cap_f_of_temp.setCoefficient1Constant(0.942587793)
1935
- clg_cap_f_of_temp.setCoefficient2x(0.009543347)
1936
- clg_cap_f_of_temp.setCoefficient3xPOW2(0.0018423)
1937
- clg_cap_f_of_temp.setCoefficient4y(-0.011042676)
1938
- clg_cap_f_of_temp.setCoefficient5yPOW2(0.000005249)
1939
- clg_cap_f_of_temp.setCoefficient6xTIMESY(-0.000009720)
1940
- clg_cap_f_of_temp.setMinimumValueofx(17.0)
1941
- clg_cap_f_of_temp.setMaximumValueofx(22.0)
1942
- clg_cap_f_of_temp.setMinimumValueofy(13.0)
1943
- clg_cap_f_of_temp.setMaximumValueofy(46.0)
1944
-
1945
- clg_cap_f_of_flow = OpenStudio::Model::CurveQuadratic.new(model)
1946
- clg_cap_f_of_flow.setCoefficient1Constant(0.718954)
1947
- clg_cap_f_of_flow.setCoefficient2x(0.435436)
1948
- clg_cap_f_of_flow.setCoefficient3xPOW2(-0.154193)
1949
- clg_cap_f_of_flow.setMinimumValueofx(0.75)
1950
- clg_cap_f_of_flow.setMaximumValueofx(1.25)
1951
-
1952
- clg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(model)
1953
- clg_energy_input_ratio_f_of_temp.setCoefficient1Constant(0.342414409)
1954
- clg_energy_input_ratio_f_of_temp.setCoefficient2x(0.034885008)
1955
- clg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(-0.000623700)
1956
- clg_energy_input_ratio_f_of_temp.setCoefficient4y(0.004977216)
1957
- clg_energy_input_ratio_f_of_temp.setCoefficient5yPOW2(0.000437951)
1958
- clg_energy_input_ratio_f_of_temp.setCoefficient6xTIMESY(-0.000728028)
1959
- clg_energy_input_ratio_f_of_temp.setMinimumValueofx(17.0)
1960
- clg_energy_input_ratio_f_of_temp.setMaximumValueofx(22.0)
1961
- clg_energy_input_ratio_f_of_temp.setMinimumValueofy(13.0)
1962
- clg_energy_input_ratio_f_of_temp.setMaximumValueofy(46.0)
1963
-
1964
- clg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(model)
1965
- clg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.1552)
1966
- clg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.1808)
1967
- clg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.0256)
1968
- clg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.5)
1969
- clg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.5)
1970
-
1971
- clg_part_load_fraction = OpenStudio::Model::CurveQuadratic.new(model)
1972
- clg_part_load_fraction.setCoefficient1Constant(0.75)
1973
- clg_part_load_fraction.setCoefficient2x(0.25)
1974
- clg_part_load_fraction.setCoefficient3xPOW2(0.0)
1975
- clg_part_load_fraction.setMinimumValueofx(0.0)
1976
- clg_part_load_fraction.setMaximumValueofx(1.0)
1977
-
1978
- clg_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(model,
1979
- always_on,
1980
- clg_cap_f_of_temp,
1981
- clg_cap_f_of_flow,
1982
- clg_energy_input_ratio_f_of_temp,
1983
- clg_energy_input_ratio_f_of_flow,
1984
- clg_part_load_fraction)
1985
-
1986
- return clg_coil
1987
- end
1988
-
1989
- def self._add_coil_cooling_dx_single_speed_sys_type_3(model)
1990
- clg_coil = nil
1991
-
1992
- always_on = model.alwaysOnDiscreteSchedule
1993
-
1994
- clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(model)
1995
- clg_cap_f_of_temp.setCoefficient1Constant(0.42415)
1996
- clg_cap_f_of_temp.setCoefficient2x(0.04426)
1997
- clg_cap_f_of_temp.setCoefficient3xPOW2(-0.00042)
1998
- clg_cap_f_of_temp.setCoefficient4y(0.00333)
1999
- clg_cap_f_of_temp.setCoefficient5yPOW2(-0.00008)
2000
- clg_cap_f_of_temp.setCoefficient6xTIMESY(-0.00021)
2001
- clg_cap_f_of_temp.setMinimumValueofx(17.0)
2002
- clg_cap_f_of_temp.setMaximumValueofx(22.0)
2003
- clg_cap_f_of_temp.setMinimumValueofy(13.0)
2004
- clg_cap_f_of_temp.setMaximumValueofy(46.0)
2005
-
2006
- clg_cap_f_of_flow = OpenStudio::Model::CurveQuadratic.new(model)
2007
- clg_cap_f_of_flow.setCoefficient1Constant(0.77136)
2008
- clg_cap_f_of_flow.setCoefficient2x(0.34053)
2009
- clg_cap_f_of_flow.setCoefficient3xPOW2(-0.11088)
2010
- clg_cap_f_of_flow.setMinimumValueofx(0.75918)
2011
- clg_cap_f_of_flow.setMaximumValueofx(1.13877)
2012
-
2013
- clg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(model)
2014
- clg_energy_input_ratio_f_of_temp.setCoefficient1Constant(1.23649)
2015
- clg_energy_input_ratio_f_of_temp.setCoefficient2x(-0.02431)
2016
- clg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(0.00057)
2017
- clg_energy_input_ratio_f_of_temp.setCoefficient4y(-0.01434)
2018
- clg_energy_input_ratio_f_of_temp.setCoefficient5yPOW2(0.00063)
2019
- clg_energy_input_ratio_f_of_temp.setCoefficient6xTIMESY(-0.00038)
2020
- clg_energy_input_ratio_f_of_temp.setMinimumValueofx(17.0)
2021
- clg_energy_input_ratio_f_of_temp.setMaximumValueofx(22.0)
2022
- clg_energy_input_ratio_f_of_temp.setMinimumValueofy(13.0)
2023
- clg_energy_input_ratio_f_of_temp.setMaximumValueofy(46.0)
2024
-
2025
- clg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(model)
2026
- clg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.20550)
2027
- clg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.32953)
2028
- clg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.12308)
2029
- clg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.75918)
2030
- clg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.13877)
2031
-
2032
- clg_part_load_ratio = OpenStudio::Model::CurveQuadratic.new(model)
2033
- clg_part_load_ratio.setCoefficient1Constant(0.77100)
2034
- clg_part_load_ratio.setCoefficient2x(0.22900)
2035
- clg_part_load_ratio.setCoefficient3xPOW2(0.0)
2036
- clg_part_load_ratio.setMinimumValueofx(0.0)
2037
- clg_part_load_ratio.setMaximumValueofx(1.0)
2038
-
2039
- clg_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(model,
2040
- always_on,
2041
- clg_cap_f_of_temp,
2042
- clg_cap_f_of_flow,
2043
- clg_energy_input_ratio_f_of_temp,
2044
- clg_energy_input_ratio_f_of_flow,
2045
- clg_part_load_ratio)
2046
-
2047
- return clg_coil
2048
- end
2049
-
2050
- def self._add_coil_cooling_dx_single_speed_sys_type_4(model)
2051
- clg_coil = nil
2052
-
2053
- always_on = model.alwaysOnDiscreteSchedule
2054
-
2055
- clg_cap_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(model)
2056
- clg_cap_f_of_temp.setCoefficient1Constant(0.766956)
2057
- clg_cap_f_of_temp.setCoefficient2x(0.0107756)
2058
- clg_cap_f_of_temp.setCoefficient3xPOW2(-0.0000414703)
2059
- clg_cap_f_of_temp.setCoefficient4y(0.00134961)
2060
- clg_cap_f_of_temp.setCoefficient5yPOW2(-0.000261144)
2061
- clg_cap_f_of_temp.setCoefficient6xTIMESY(0.000457488)
2062
- clg_cap_f_of_temp.setMinimumValueofx(17.0)
2063
- clg_cap_f_of_temp.setMaximumValueofx(22.0)
2064
- clg_cap_f_of_temp.setMinimumValueofy(13.0)
2065
- clg_cap_f_of_temp.setMaximumValueofy(46.0)
2066
-
2067
- clg_cap_f_of_flow = OpenStudio::Model::CurveQuadratic.new(model)
2068
- clg_cap_f_of_flow.setCoefficient1Constant(0.8)
2069
- clg_cap_f_of_flow.setCoefficient2x(0.2)
2070
- clg_cap_f_of_flow.setCoefficient3xPOW2(0.0)
2071
- clg_cap_f_of_flow.setMinimumValueofx(0.5)
2072
- clg_cap_f_of_flow.setMaximumValueofx(1.5)
2073
-
2074
- clg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveBiquadratic.new(model)
2075
- clg_energy_input_ratio_f_of_temp.setCoefficient1Constant(0.297145)
2076
- clg_energy_input_ratio_f_of_temp.setCoefficient2x(0.0430933)
2077
- clg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(-0.000748766)
2078
- clg_energy_input_ratio_f_of_temp.setCoefficient4y(0.00597727)
2079
- clg_energy_input_ratio_f_of_temp.setCoefficient5yPOW2(0.000482112)
2080
- clg_energy_input_ratio_f_of_temp.setCoefficient6xTIMESY(-0.000956448)
2081
- clg_energy_input_ratio_f_of_temp.setMinimumValueofx(17.0)
2082
- clg_energy_input_ratio_f_of_temp.setMaximumValueofx(22.0)
2083
- clg_energy_input_ratio_f_of_temp.setMinimumValueofy(13.0)
2084
- clg_energy_input_ratio_f_of_temp.setMaximumValueofy(46.0)
2085
-
2086
- clg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(model)
2087
- clg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.156)
2088
- clg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.1816)
2089
- clg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.0256)
2090
- clg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.5)
2091
- clg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.5)
2092
-
2093
- clg_part_load_ratio = OpenStudio::Model::CurveQuadratic.new(model)
2094
- clg_part_load_ratio.setCoefficient1Constant(0.75)
2095
- clg_part_load_ratio.setCoefficient2x(0.25)
2096
- clg_part_load_ratio.setCoefficient3xPOW2(0.0)
2097
- clg_part_load_ratio.setMinimumValueofx(0.0)
2098
- clg_part_load_ratio.setMaximumValueofx(1.0)
2099
-
2100
- clg_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(model,
2101
- always_on,
2102
- clg_cap_f_of_temp,
2103
- clg_cap_f_of_flow,
2104
- clg_energy_input_ratio_f_of_temp,
2105
- clg_energy_input_ratio_f_of_flow,
2106
- clg_part_load_ratio)
2107
- return clg_coil
2108
- end
2109
-
2110
- def self._add_coil_heating_dx_single_speed(model)
2111
- htg_coil = nil
2112
-
2113
- always_on = model.alwaysOnDiscreteSchedule
2114
-
2115
- htg_cap_f_of_temp = OpenStudio::Model::CurveCubic.new(model)
2116
- htg_cap_f_of_temp.setCoefficient1Constant(0.758746)
2117
- htg_cap_f_of_temp.setCoefficient2x(0.027626)
2118
- htg_cap_f_of_temp.setCoefficient3xPOW2(0.000148716)
2119
- htg_cap_f_of_temp.setCoefficient4xPOW3(0.0000034992)
2120
- htg_cap_f_of_temp.setMinimumValueofx(-20.0)
2121
- htg_cap_f_of_temp.setMaximumValueofx(20.0)
2122
-
2123
- htg_cap_f_of_flow = OpenStudio::Model::CurveCubic.new(model)
2124
- htg_cap_f_of_flow.setCoefficient1Constant(0.84)
2125
- htg_cap_f_of_flow.setCoefficient2x(0.16)
2126
- htg_cap_f_of_flow.setCoefficient3xPOW2(0.0)
2127
- htg_cap_f_of_flow.setCoefficient4xPOW3(0.0)
2128
- htg_cap_f_of_flow.setMinimumValueofx(0.5)
2129
- htg_cap_f_of_flow.setMaximumValueofx(1.5)
2130
-
2131
- htg_energy_input_ratio_f_of_temp = OpenStudio::Model::CurveCubic.new(model)
2132
- htg_energy_input_ratio_f_of_temp.setCoefficient1Constant(1.19248)
2133
- htg_energy_input_ratio_f_of_temp.setCoefficient2x(-0.0300438)
2134
- htg_energy_input_ratio_f_of_temp.setCoefficient3xPOW2(0.00103745)
2135
- htg_energy_input_ratio_f_of_temp.setCoefficient4xPOW3(-0.000023328)
2136
- htg_energy_input_ratio_f_of_temp.setMinimumValueofx(-20.0)
2137
- htg_energy_input_ratio_f_of_temp.setMaximumValueofx(20.0)
2138
-
2139
- htg_energy_input_ratio_f_of_flow = OpenStudio::Model::CurveQuadratic.new(model)
2140
- htg_energy_input_ratio_f_of_flow.setCoefficient1Constant(1.3824)
2141
- htg_energy_input_ratio_f_of_flow.setCoefficient2x(-0.4336)
2142
- htg_energy_input_ratio_f_of_flow.setCoefficient3xPOW2(0.0512)
2143
- htg_energy_input_ratio_f_of_flow.setMinimumValueofx(0.0)
2144
- htg_energy_input_ratio_f_of_flow.setMaximumValueofx(1.0)
2145
-
2146
- htg_part_load_fraction = OpenStudio::Model::CurveQuadratic.new(model)
2147
- htg_part_load_fraction.setCoefficient1Constant(0.75)
2148
- htg_part_load_fraction.setCoefficient2x(0.25)
2149
- htg_part_load_fraction.setCoefficient3xPOW2(0.0)
2150
- htg_part_load_fraction.setMinimumValueofx(0.0)
2151
- htg_part_load_fraction.setMaximumValueofx(1.0)
2152
-
2153
- htg_coil = OpenStudio::Model::CoilHeatingDXSingleSpeed.new(model,
2154
- always_on,
2155
- htg_cap_f_of_temp,
2156
- htg_cap_f_of_flow,
2157
- htg_energy_input_ratio_f_of_temp,
2158
- htg_energy_input_ratio_f_of_flow,
2159
- htg_part_load_fraction)
2160
-
2161
- return htg_coil
2162
- end
2163
- end