openstudio-geb 0.0.2 → 0.0.3r

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b4fdc606895d1c09377ee2006ac33a6ee08e8b5d1b2b39a7b7cdf30dd4f1a670
4
- data.tar.gz: e79afcd13e858096851fd8d53234fa23cb2f3c6d85c65635b3209a007416aad1
3
+ metadata.gz: 95736fe58727e0f60da222a3f643c02dc5e5465dc77b5e6513012a59949d9d85
4
+ data.tar.gz: 55105af8ce0bf75e1005123a36f77e61268136554663d6b476091e1995396bae
5
5
  SHA512:
6
- metadata.gz: 5af05c44e546a83fdbabd60c633c5cb07ea3ff8ea80929df22b98a4c5edf2604ff312bcece947ee04d0d15dc86421a3e35d3f571b93f11ae31a12c0ea492b847
7
- data.tar.gz: 1da5382c95a52c84d562947b3637efa61f259793b4034febf99bb2d48b441183165a4b185a74e089faaf77b4650056dca08c8088f945118a188ce20abf7cb4f9
6
+ metadata.gz: 63d3ff9b2cc8415a52ba1906a61146ed28ba6a977da91393e84fa0ed7e6845240beea11c03d20483b86f92b56b4f779fff42a08f093544bc59e43dcce0453605
7
+ data.tar.gz: 02f4cfd1f7b5e87d3c14c142a15cf370aa19793a3f280fd772b39a972c844680d817fb40123caf7c8f914a4686c85a14de4375078de197c77196b79a619ef390
data/.gitignore CHANGED
@@ -33,4 +33,6 @@ lib/measures/*/tests/baseline
33
33
  runner.conf
34
34
 
35
35
  # built gem file
36
- *.gem
36
+ *.gem
37
+
38
+ .DS_Store
@@ -673,7 +673,7 @@ class AdjustThermostatSetpointsByDegreesForPeakHours < OpenStudio::Measure::Mode
673
673
  elsif vec_time[i]>time_begin && vec_time[i]<=time_end && count==1
674
674
  sch_day.addValue(vec_time[i], vec_value[i])
675
675
  elsif vec_time[i]>time_end && count == 1
676
- sch_day.addValue(time_end, target_temp_si)
676
+ sch_day.addValue(time_end, target_temp_si.value)
677
677
  sch_day.addValue(vec_time[i], vec_value[i])
678
678
  count = 2
679
679
  else
@@ -49,9 +49,9 @@ class AddChilledWaterStorageTank < OpenStudio::Measure::ModelMeasure
49
49
  loop_choices << loop.name.to_s
50
50
  end
51
51
  end
52
-
52
+ loop_choices << ""
53
53
  # Make choice argument for primary loop selection
54
- selected_primary_loop_name = OpenStudio::Measure::OSArgument.makeChoiceArgument('selected_primary_loop_name', loop_choices, true)
54
+ selected_primary_loop_name = OpenStudio::Measure::OSArgument.makeChoiceArgument('selected_primary_loop_name', loop_choices, false)
55
55
  selected_primary_loop_name.setDisplayName('Select Primary Loop:')
56
56
  selected_primary_loop_name.setDescription('This is the primary cooling loop on which the chilled water tank will be added.')
57
57
  pri_loop_name = nil
@@ -62,6 +62,7 @@ class AddChilledWaterStorageTank < OpenStudio::Measure::ModelMeasure
62
62
  selected_primary_loop_name.setDefaultValue(pri_loop_name)
63
63
  else
64
64
  selected_primary_loop_name.setDescription('Error: No Cooling Loop Found')
65
+ selected_primary_loop_name.setDefaultValue("")
65
66
  end
66
67
  args << selected_primary_loop_name
67
68
 
@@ -156,12 +157,13 @@ class AddChilledWaterStorageTank < OpenStudio::Measure::ModelMeasure
156
157
  args << wknds
157
158
 
158
159
  # Output path, for sizing run
159
- run_output_path = OpenStudio::Measure::OSArgument.makePathArgument('run_output_path', true, "")
160
+ run_output_path = OpenStudio::Measure::OSArgument.makePathArgument('run_output_path', true, "", false)
160
161
  run_output_path.setDisplayName('Output path for tank sizing run (if tank volume is not provided)')
162
+ run_output_path.setDefaultValue(".")
161
163
  args << run_output_path
162
164
 
163
165
  # epw file path, for sizing run
164
- epw_path = OpenStudio::Measure::OSArgument.makePathArgument('epw_path', true, "")
166
+ epw_path = OpenStudio::Measure::OSArgument.makePathArgument('epw_path', true, "", false)
165
167
  epw_path.setDisplayName('epw file path for tank sizing run (if tank volume is not provided)')
166
168
  args << epw_path
167
169
 
@@ -187,6 +189,36 @@ class AddChilledWaterStorageTank < OpenStudio::Measure::ModelMeasure
187
189
  # assign the user inputs to variables
188
190
  objective = runner.getStringArgumentValue('objective', user_arguments)
189
191
  selected_primary_loop_name = runner.getStringArgumentValue('selected_primary_loop_name', user_arguments)
192
+ # if user_arguments['selected_primary_loop_name'].hasValue
193
+ # selected_primary_loop_name = runner.getStringArgumentValue('selected_primary_loop_name', user_arguments)
194
+ if !selected_primary_loop_name.empty?
195
+ # get the primary cooling loop
196
+ selected_primary_loop = model.getModelObjectByName(selected_primary_loop_name)
197
+ if selected_primary_loop.is_initialized
198
+ selected_primary_loop = selected_primary_loop.get.to_PlantLoop.get
199
+ else
200
+ # The provided value is not a plant loop in the model
201
+ runner.registerError("The provided primary loop name doesn't exist in the model.")
202
+ return false
203
+ end
204
+ else
205
+ loop_choices = []
206
+ model.getPlantLoops.each do |loop|
207
+ if loop.sizingPlant.loopType.to_s == 'Cooling'
208
+ loop_choices << loop.name.to_s
209
+ end
210
+ end
211
+ if loop_choices.empty?
212
+ # No cooling loop; the measure is not applicable
213
+ runner.registerAsNotApplicable("No cooling loop in the model. The measure is not applicable.")
214
+ return true
215
+ else
216
+ # There is cooling loop in the model but user didn't specify one,
217
+ # and the cooling loop name does not include 'chilled water loop'
218
+ runner.registerError("Please select a primary loop name to run the measure. The available cooling loop(s) in the model is #{loop_choices.join(', ')}")
219
+ return false
220
+ end
221
+ end
190
222
  primary_loop_sp = runner.getDoubleArgumentValue('primary_loop_sp', user_arguments)
191
223
  secondary_loop_sp = runner.getDoubleArgumentValue('secondary_loop_sp', user_arguments)
192
224
  tank_charge_sp = runner.getDoubleArgumentValue('tank_charge_sp', user_arguments)
@@ -199,6 +231,7 @@ class AddChilledWaterStorageTank < OpenStudio::Measure::ModelMeasure
199
231
  charge_end = runner.getStringArgumentValue('charge_end', user_arguments)
200
232
  wknds = runner.getBoolArgumentValue('wknds', user_arguments)
201
233
 
234
+
202
235
  # check time format
203
236
  begin
204
237
  discharge_start = Time.strptime(discharge_start, '%H:%M')
@@ -293,14 +326,7 @@ class AddChilledWaterStorageTank < OpenStudio::Measure::ModelMeasure
293
326
  return false
294
327
  end
295
328
 
296
- # get the primary cooling loop
297
- selected_primary_loop = model.getModelObjectByName(selected_primary_loop_name)
298
- if selected_primary_loop.is_initialized
299
- selected_primary_loop = selected_primary_loop.get.to_PlantLoop.get
300
- else
301
- runner.registerError("Error: No Primary Cooling Loop Found. ")
302
- return false
303
- end
329
+
304
330
  # report initial condition of model
305
331
  runner.registerInitialCondition("Original primary chilled water loop: #{selected_primary_loop.name}.")
306
332
 
@@ -312,17 +338,112 @@ class AddChilledWaterStorageTank < OpenStudio::Measure::ModelMeasure
312
338
  primary_delta_t = selected_primary_loop.sizingPlant.loopDesignTemperatureDifference
313
339
  end
314
340
 
341
+ # get the condenser water loop
342
+ cw_loop = nil
343
+ model.getPlantLoops.each do |loop|
344
+ if loop.sizingPlant.loopType.to_s.downcase == 'condenser'
345
+ cw_loop = loop if cw_loop.nil?
346
+ # confirm if this condenser loop contains demand component of chiller that is in the selected_primary_loop
347
+ common_comps = cw_loop.demandComponents & selected_primary_loop.supplyComponents
348
+ chiller_in_both_loops = false
349
+ common_comps.each do |comp|
350
+ chiller_in_both_loops = true if comp.to_ChillerElectricEIR.is_initialized || comp.to_ChillerAbsorption.is_initialized || comp.to_ChillerAbsorptionIndirect.is_initialized
351
+ end
352
+ cw_loop = nil unless chiller_in_both_loops
353
+ end
354
+ end
355
+ # not necessarily can find a cw_loop as the existing primary chiller might be air cooled.
356
+
357
+ def hardsize_cooling_tower_two_speed(tower)
358
+ # implement the applySizingValues function for CoolingTowerTwoSpeed here since it's not yet implemented in OS standards
359
+ rated_water_flow_rate = tower.autosizedDesignWaterFlowRate
360
+ if rated_water_flow_rate.is_initialized
361
+ tower.setDesignWaterFlowRate(rated_water_flow_rate.get)
362
+ end
363
+
364
+ high_fan_speed_fan_power = tower.autosizedHighFanSpeedFanPower
365
+ if high_fan_speed_fan_power.is_initialized
366
+ tower.setHighFanSpeedFanPower(high_fan_speed_fan_power.get)
367
+ end
368
+
369
+ high_fan_speed_air_flow_rate = tower.autosizedHighFanSpeedAirFlowRate
370
+ if high_fan_speed_air_flow_rate.is_initialized
371
+ tower.setHighFanSpeedAirFlowRate(high_fan_speed_air_flow_rate.get)
372
+ end
373
+
374
+ high_fan_speed_u_factor_times_area_value = tower.autosizedHighFanSpeedUFactorTimesAreaValue
375
+ if high_fan_speed_u_factor_times_area_value.is_initialized
376
+ tower.setHighFanSpeedUFactorTimesAreaValue(high_fan_speed_u_factor_times_area_value.get)
377
+ end
378
+
379
+ low_fan_speed_air_flow_rate = tower.autosizedLowFanSpeedAirFlowRate
380
+ if low_fan_speed_air_flow_rate.is_initialized
381
+ tower.setLowFanSpeedAirFlowRate(low_fan_speed_air_flow_rate.get)
382
+ end
383
+
384
+ low_fan_speed_fan_power = tower.autosizedLowFanSpeedFanPower
385
+ if low_fan_speed_fan_power.is_initialized
386
+ tower.setLowFanSpeedFanPower(low_fan_speed_fan_power.get)
387
+ end
388
+
389
+ low_fan_speed_u_factor_times_area_value = tower.autosizedLowFanSpeedUFactorTimesAreaValue
390
+ if low_fan_speed_u_factor_times_area_value.is_initialized
391
+ tower.setLowFanSpeedUFactorTimesAreaValue(low_fan_speed_u_factor_times_area_value.get)
392
+ end
393
+
394
+ free_convection_regime_air_flow_rate = tower.autosizedFreeConvectionRegimeAirFlowRate
395
+ if free_convection_regime_air_flow_rate.is_initialized
396
+ tower.setFreeConvectionRegimeAirFlowRate(free_convection_regime_air_flow_rate.get)
397
+ end
398
+
399
+ free_convection_regime_u_factor_times_area_value = tower.autosizedFreeConvectionRegimeUFactorTimesAreaValue
400
+ if free_convection_regime_u_factor_times_area_value.is_initialized
401
+ tower.setFreeConvectionRegimeUFactorTimesAreaValue(free_convection_regime_u_factor_times_area_value.get)
402
+ end
403
+ end
404
+
315
405
  # if user provides this input, if not, do autosizing
316
406
  if user_arguments['tank_vol'].hasValue
317
407
  tank_vol = runner.getDoubleArgumentValue('tank_vol', user_arguments)
318
- else
319
- unless user_arguments['run_output_path'].hasValue
320
- runner.registerError("Need to provide run output path for sizing run of tank volume. ")
321
- return false
408
+ if cw_loop
409
+ # autosize cooling tower in the condenser loop to avoid invalid hard-sized parameters
410
+ cw_loop.supplyComponents.each do |comp|
411
+ if comp.to_CoolingTowerSingleSpeed.is_initialized
412
+ cooling_tower = comp.to_CoolingTowerSingleSpeed.get
413
+ cooling_tower.autosizeDesignWaterFlowRate
414
+ cooling_tower.autosizeFanPoweratDesignAirFlowRate
415
+ cooling_tower.autosizeDesignAirFlowRate
416
+ cooling_tower.autosizeUFactorTimesAreaValueatDesignAirFlowRate
417
+ cooling_tower.autosizeAirFlowRateinFreeConvectionRegime
418
+ cooling_tower.autosizeUFactorTimesAreaValueatFreeConvectionAirFlowRate
419
+ runner.registerInfo("CoolingTowerSingleSpeed #{cooling_tower.name} has been set to autosize.")
420
+ elsif comp.to_CoolingTowerTwoSpeed.is_initialized
421
+ cooling_tower = comp.to_CoolingTowerTwoSpeed.get
422
+ cooling_tower.autosizeDesignWaterFlowRate
423
+ cooling_tower.autosizeHighFanSpeedFanPower
424
+ cooling_tower.autosizeHighFanSpeedAirFlowRate
425
+ cooling_tower.autosizeHighFanSpeedUFactorTimesAreaValue
426
+ cooling_tower.autosizeLowFanSpeedAirFlowRate
427
+ cooling_tower.autosizeLowFanSpeedFanPower
428
+ cooling_tower.autosizeLowFanSpeedUFactorTimesAreaValue
429
+ cooling_tower.autosizeFreeConvectionRegimeAirFlowRate
430
+ cooling_tower.autosizeFreeConvectionRegimeUFactorTimesAreaValue
431
+ runner.registerInfo("CoolingTowerTwoSpeed #{cooling_tower.name} has been set to autosize.")
432
+ elsif comp.to_CoolingTowerVariableSpeed.is_initialized
433
+ cooling_tower = comp.to_CoolingTowerVariableSpeed.get
434
+ cooling_tower.autosize
435
+ runner.registerInfo("CoolingTowerVariableSpeed #{cooling_tower.name} has been set to autosize.")
436
+ end
437
+ end
322
438
  end
439
+ else
440
+ # unless user_arguments['run_output_path'].hasValue
441
+ # runner.registerError("Need to provide run output path for sizing run of tank volume. ")
442
+ # return false
443
+ # end
323
444
  run_output_path = runner.getPathArgumentValue('run_output_path', user_arguments)
324
445
  Dir.mkdir(run_output_path.to_s) unless File.exists?(run_output_path.to_s)
325
- sizing_output_path = File.join(run_output_path.to_s, 'sizing_run')
446
+ sizing_output_path = File.expand_path(File.join(run_output_path.to_s, 'sizing_run'))
326
447
  Dir.mkdir(sizing_output_path.to_s) unless File.exists?(sizing_output_path.to_s)
327
448
 
328
449
  # Change the simulation to only run the sizing days
@@ -351,11 +472,18 @@ class AddChilledWaterStorageTank < OpenStudio::Measure::ModelMeasure
351
472
  File.open(osw_path, 'w') do |f|
352
473
  f << JSON.pretty_generate(osw)
353
474
  end
475
+ model.resetSqlFile
354
476
  run_osw(osw_path)
355
477
  sleep(1)
356
- sql = model.sqlFile
357
- unless sql.is_initialized
358
- model.setSqlFile(OpenStudio::SqlFile.new(OpenStudio::Path.new(File.join(sizing_output_path.to_s, "run", "eplusout.sql"))))
478
+ sql_path = OpenStudio::Path.new(File.join(sizing_output_path.to_s, "run", "eplusout.sql"))
479
+ if OpenStudio.exists(sql_path)
480
+ sql = OpenStudio::SqlFile.new(sql_path)
481
+ unless sql.connectionOpen
482
+ runner.registerError("The sizing run failed without valid a sql file. Look at the eplusout.err file in #{File.dirname(sql_path.to_s)} to see the cause.")
483
+ return false
484
+ end
485
+ # Attach the sql file from the run to the model
486
+ model.setSqlFile(sql)
359
487
  end
360
488
 
361
489
  total_cooling_cap = 0 # initial
@@ -368,6 +496,24 @@ class AddChilledWaterStorageTank < OpenStudio::Measure::ModelMeasure
368
496
  total_cooling_cap += comp.to_ChillerAbsorptionIndirect.get.autosizedNominalCapacity.get
369
497
  end
370
498
  end
499
+ if cw_loop
500
+ # hard size cooling tower in the condenser loop
501
+ cw_loop.supplyComponents.each do |comp|
502
+ if comp.to_CoolingTowerSingleSpeed.is_initialized
503
+ cooling_tower = comp.to_CoolingTowerSingleSpeed.get
504
+ cooling_tower.applySizingValues
505
+ runner.registerInfo("Autosized parameters from the sizing run have been set to CoolingTowerSingleSpeed #{cooling_tower.name}")
506
+ elsif comp.to_CoolingTowerTwoSpeed.is_initialized
507
+ cooling_tower = comp.to_CoolingTowerTwoSpeed.get
508
+ hardsize_cooling_tower_two_speed(cooling_tower)
509
+ runner.registerInfo("Autosized parameters from the sizing run have been set to CoolingTowerTwoSpeed #{cooling_tower.name}")
510
+ elsif comp.to_CoolingTowerVariableSpeed.is_initialized
511
+ cooling_tower = comp.to_CoolingTowerVariableSpeed.get
512
+ cooling_tower.applySizingValues
513
+ runner.registerInfo("Autosized parameters from the sizing run have been set to CoolingTowerVariableSpeed #{cooling_tower.name}")
514
+ end
515
+ end
516
+ end
371
517
 
372
518
  # assuming average load ratio of chiller is 1/3 throughout the day
373
519
  tank_vol = total_cooling_cap/3.0 * 3600 * lasting_hrs / (4182 * 1000 * secondary_delta_t) # heat capacity of water 4182J/kg.K, water density 1000g/m3, lasting 8 hours
@@ -380,7 +526,6 @@ class AddChilledWaterStorageTank < OpenStudio::Measure::ModelMeasure
380
526
 
381
527
  sec_loop = OpenStudio::Model::PlantLoop.new(model)
382
528
  sec_loop.setName("Chilled Water Secondary Loop")
383
- selected_primary_loop = model.getPlantLoopByName("Chilled Water Loop").get
384
529
  selected_primary_loop.setName("Chilled Water Primary Loop")
385
530
  sizing_sec_plant = sec_loop.sizingPlant
386
531
  sizing_sec_plant.setLoopType('Cooling')
@@ -391,21 +536,7 @@ class AddChilledWaterStorageTank < OpenStudio::Measure::ModelMeasure
391
536
  sizing_pri_plant.setDesignLoopExitTemperature(primary_loop_sp)
392
537
  sizing_pri_plant.setLoopDesignTemperatureDifference(primary_delta_t)
393
538
 
394
- # get the condenser water loop
395
- cw_loop = nil
396
- model.getPlantLoops.each do |loop|
397
- if loop.sizingPlant.loopType.to_s.downcase == 'condenser'
398
- cw_loop = loop if cw_loop.nil?
399
- # confirm if this condenser loop contains demand component of chiller that is in the selected_primary_loop
400
- common_comps = cw_loop.demandComponents & selected_primary_loop.supplyComponents
401
- chiller_in_both_loops = false
402
- common_comps.each do |comp|
403
- chiller_in_both_loops = true if comp.to_ChillerElectricEIR.is_initialized || comp.to_ChillerAbsorption.is_initialized || comp.to_ChillerAbsorptionIndirect.is_initialized
404
- end
405
- cw_loop = nil unless chiller_in_both_loops
406
- end
407
- end
408
- # not necessarily can find a cw_loop as the existing primary chiller might be air cooled.
539
+
409
540
 
410
541
  # add chilled water tank to the primary loop as demand and secondary loop as supply
411
542
  chw_storage_tank = OpenStudio::Model::ThermalStorageChilledWaterStratified.new(model)