openstudio-standards 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. checksums.yaml +4 -4
  2. data/data/geometry/Geometry.hospital.osm +118 -109
  3. data/data/geometry/Geometry.hospital_original.osm +8947 -0
  4. data/data/geometry/Geometry.large_office_2010.osm +118 -102
  5. data/data/standards/OpenStudio_Standards.xlsx +0 -0
  6. data/data/standards/OpenStudio_Standards_construction_properties.json +1993 -1959
  7. data/data/standards/OpenStudio_Standards_construction_sets.json +18 -18
  8. data/data/standards/OpenStudio_Standards_constructions.json +28 -0
  9. data/data/standards/OpenStudio_Standards_ground_temperatures.json +561 -1071
  10. data/data/standards/OpenStudio_Standards_materials.json +2 -2
  11. data/data/standards/OpenStudio_Standards_prototype_inputs.json +32 -32
  12. data/data/standards/OpenStudio_Standards_schedules.json +435 -20
  13. data/data/standards/OpenStudio_Standards_space_types.json +2005 -614
  14. data/lib/openstudio-standards/hvac_sizing/HVACSizing.CoilCoolingWaterToAirHeatPumpEquationFit.rb +49 -7
  15. data/lib/openstudio-standards/hvac_sizing/HVACSizing.CoilHeatingWaterToAirHeatPumpEquationFit.rb +37 -7
  16. data/lib/openstudio-standards/hvac_sizing/HVACSizing.Model.rb +7 -0
  17. data/lib/openstudio-standards/hvac_sizing/HVACSizing.PumpVariableSpeed.rb +1 -1
  18. data/lib/openstudio-standards/prototypes/Prototype.AirTerminalSingleDuctVAVReheat.rb +14 -5
  19. data/lib/openstudio-standards/prototypes/Prototype.Model.hvac.rb +15 -5
  20. data/lib/openstudio-standards/prototypes/Prototype.Model.rb +59 -37
  21. data/lib/openstudio-standards/prototypes/Prototype.Model.swh.rb +5 -3
  22. data/lib/openstudio-standards/prototypes/Prototype.hospital.rb +86 -26
  23. data/lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb +97 -16
  24. data/lib/openstudio-standards/prototypes/Prototype.outpatient.rb +217 -6
  25. data/lib/openstudio-standards/prototypes/Prototype.warehouse.rb +48 -1
  26. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +126 -27
  27. data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +1 -1
  28. data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +14 -1
  29. data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +40 -1
  30. data/lib/openstudio-standards/standards/Standards.SpaceType.rb +4 -2
  31. data/lib/openstudio-standards/version.rb +1 -1
  32. metadata +3 -2
@@ -12,7 +12,10 @@ class OpenStudio::Model::Model
12
12
  end
13
13
 
14
14
  def define_hvac_system_map(building_type, building_vintage, climate_zone)
15
- system_to_space_map = [
15
+
16
+ case building_vintage
17
+ when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
18
+ system_to_space_map = [
16
19
  {
17
20
  'type' => 'PSZ-AC',
18
21
  'name' => 'HVAC_1',
@@ -27,8 +30,52 @@ class OpenStudio::Model::Model
27
30
  'type' => 'UnitHeater',
28
31
  'name' => 'HVAC_3',
29
32
  'space_names' => ['Zone3 Bulk Storage']
33
+ },
34
+ {
35
+ 'type' => 'Zone Ventilation',
36
+ 'name' => 'Bulk Storage Zone Ventilation - Intake',
37
+ 'availability_sch_name' => 'Warehouse MinOA_Sched',
38
+ 'flow_rate' => 0.00025, # in m^3/s-m^2
39
+ 'ventilation_type' => 'Intake',
40
+ 'space_names' => ['Zone3 Bulk Storage']
30
41
  }
31
42
  ]
43
+ when '90.1-2004','90.1-2007','90.1-2010','90.1-2013'
44
+ system_to_space_map = [
45
+ {
46
+ 'type' => 'PSZ-AC',
47
+ 'name' => 'HVAC_1',
48
+ 'space_names' => ['Zone1 Office']
49
+ },
50
+ {
51
+ 'type' => 'PSZ-AC',
52
+ 'name' => 'HVAC_2',
53
+ 'space_names' => ['Zone2 Fine Storage']
54
+ },
55
+ {
56
+ 'type' => 'UnitHeater',
57
+ 'name' => 'HVAC_3',
58
+ 'space_names' => ['Zone3 Bulk Storage']
59
+ },
60
+ {
61
+ 'type' => 'Zone Ventilation',
62
+ 'name' => 'Bulk Storage Zone Ventilation - Exhaust',
63
+ 'availability_sch_name' => 'Always On',
64
+ 'flow_rate' => OpenStudio.convert(80008.9191,'cfm','m^3/s').get,
65
+ 'ventilation_type' => 'Exhaust',
66
+ 'space_names' => ['Zone3 Bulk Storage']
67
+ },
68
+ {
69
+ 'type' => 'Zone Ventilation',
70
+ 'name' => 'Bulk Storage Zone Ventilation - Natural',
71
+ 'availability_sch_name' => 'Always On',
72
+ 'flow_rate' => OpenStudio.convert(2000,'cfm','m^3/s').get,
73
+ 'ventilation_type' => 'Natural',
74
+ 'space_names' => ['Zone3 Bulk Storage']
75
+ },
76
+ ]
77
+ end
78
+
32
79
  return system_to_space_map
33
80
  end
34
81
 
@@ -546,6 +546,16 @@ class OpenStudio::Model::AirLoopHVAC
546
546
  else
547
547
  OpenStudio::logFree(OpenStudio::Warn, 'openstudio.standards.AirLoopHVAC', "For #{self.name} capacity of #{coil.name} is not available, total cooling capacity of air loop will be incorrect when applying standard.")
548
548
  end
549
+ # CoilCoolingWaterToAirHeatPumpEquationFit
550
+ elsif sc.to_CoilCoolingWaterToAirHeatPumpEquationFit.is_initialized
551
+ coil = sc.to_CoilCoolingWaterToAirHeatPumpEquationFit.get
552
+ if coil.ratedTotalCoolingCapacity.is_initialized
553
+ total_cooling_capacity_w += coil.ratedTotalCoolingCapacity.get
554
+ elsif coil.autosizedRatedTotalCoolingCapacity.is_initialized
555
+ total_cooling_capacity_w += coil.autosizedRatedTotalCoolingCapacity.get
556
+ else
557
+ OpenStudio::logFree(OpenStudio::Warn, 'openstudio.standards.AirLoopHVAC', "For #{self.name} capacity of #{coil.name} is not available, total cooling capacity of air loop will be incorrect when applying standard.")
558
+ end
549
559
  elsif sc.to_AirLoopHVACUnitarySystem.is_initialized
550
560
  unitary = sc.to_AirLoopHVACUnitarySystem.get
551
561
  if unitary.coolingCoil.is_initialized
@@ -578,6 +588,16 @@ class OpenStudio::Model::AirLoopHVAC
578
588
  else
579
589
  OpenStudio::logFree(OpenStudio::Warn, 'openstudio.standards.AirLoopHVAC', "For #{self.name} capacity of #{coil.name} is not available, total cooling capacity of air loop will be incorrect when applying standard.")
580
590
  end
591
+ # CoilCoolingWaterToAirHeatPumpEquationFit
592
+ elsif clg_coil.to_CoilCoolingWaterToAirHeatPumpEquationFit.is_initialized
593
+ coil = clg_coil.to_CoilCoolingWaterToAirHeatPumpEquationFit.get
594
+ if coil.ratedTotalCoolingCapacity.is_initialized
595
+ total_cooling_capacity_w += coil.ratedTotalCoolingCapacity.get
596
+ elsif coil.autosizedRatedTotalCoolingCapacity.is_initialized
597
+ total_cooling_capacity_w += coil.autosizedRatedTotalCoolingCapacity.get
598
+ else
599
+ OpenStudio::logFree(OpenStudio::Warn, 'openstudio.standards.AirLoopHVAC', "For #{self.name} capacity of #{coil.name} is not available, total cooling capacity of air loop will be incorrect when applying standard.")
600
+ end
581
601
  end
582
602
  end
583
603
  elsif sc.to_AirLoopHVACUnitaryHeatPumpAirToAir.is_initialized
@@ -614,7 +634,6 @@ class OpenStudio::Model::AirLoopHVAC
614
634
  end
615
635
  elsif sc.to_CoilCoolingDXMultiSpeed.is_initialized ||
616
636
  sc.to_CoilCoolingCooledBeam.is_initialized ||
617
- sc.to_CoilCoolingWaterToAirHeatPumpEquationFit.is_initialized ||
618
637
  sc.to_AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.is_initialized ||
619
638
  sc.to_AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.is_initialized ||
620
639
  sc.to_AirLoopHVACUnitarySystem.is_initialized
@@ -650,6 +669,13 @@ class OpenStudio::Model::AirLoopHVAC
650
669
  infinity_btu_per_hr = 999999999999
651
670
  minimum_capacity_btu_per_hr = infinity_btu_per_hr
652
671
 
672
+ # Determine if the airloop serves any computer rooms
673
+ # / data centers, which changes the economizer.
674
+ is_dc = false
675
+ if self.data_center_area_served > 0
676
+ is_dc = true
677
+ end
678
+
653
679
  # Determine the minimum capacity that requires an economizer
654
680
  case template
655
681
  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004', '90.1-2004', '90.1-2007'
@@ -678,28 +704,55 @@ class OpenStudio::Model::AirLoopHVAC
678
704
  minimum_capacity_btu_per_hr = 65000
679
705
  end
680
706
  when '90.1-2010', '90.1-2013'
681
- case climate_zone
682
- when 'ASHRAE 169-2006-1A',
683
- 'ASHRAE 169-2006-1B'
684
- minimum_capacity_btu_per_hr = infinity_btu_per_hr # No requirement
685
- when 'ASHRAE 169-2006-2A',
686
- 'ASHRAE 169-2006-3A',
687
- 'ASHRAE 169-2006-4A',
688
- 'ASHRAE 169-2006-2B',
689
- 'ASHRAE 169-2006-5A',
690
- 'ASHRAE 169-2006-6A',
691
- 'ASHRAE 169-2006-7A',
692
- 'ASHRAE 169-2006-7B',
693
- 'ASHRAE 169-2006-8A',
694
- 'ASHRAE 169-2006-8B',
695
- 'ASHRAE 169-2006-3B',
696
- 'ASHRAE 169-2006-3C',
697
- 'ASHRAE 169-2006-4B',
698
- 'ASHRAE 169-2006-4C',
699
- 'ASHRAE 169-2006-5B',
700
- 'ASHRAE 169-2006-5C',
701
- 'ASHRAE 169-2006-6B'
702
- minimum_capacity_btu_per_hr = 54000
707
+ if is_dc # data center / computer room
708
+ case climate_zone
709
+ when 'ASHRAE 169-2006-1A',
710
+ 'ASHRAE 169-2006-1B',
711
+ 'ASHRAE 169-2006-2A',
712
+ 'ASHRAE 169-2006-3A',
713
+ 'ASHRAE 169-2006-4A'
714
+ minimum_capacity_btu_per_hr = infinity_btu_per_hr # No requirement
715
+ when 'ASHRAE 169-2006-2B',
716
+ 'ASHRAE 169-2006-5A',
717
+ 'ASHRAE 169-2006-6A',
718
+ 'ASHRAE 169-2006-7A',
719
+ 'ASHRAE 169-2006-7B',
720
+ 'ASHRAE 169-2006-8A',
721
+ 'ASHRAE 169-2006-8B'
722
+ minimum_capacity_btu_per_hr = 135000
723
+ when 'ASHRAE 169-2006-3B',
724
+ 'ASHRAE 169-2006-3C',
725
+ 'ASHRAE 169-2006-4B',
726
+ 'ASHRAE 169-2006-4C',
727
+ 'ASHRAE 169-2006-5B',
728
+ 'ASHRAE 169-2006-5C',
729
+ 'ASHRAE 169-2006-6B'
730
+ minimum_capacity_btu_per_hr = 65000
731
+ end
732
+ else
733
+ case climate_zone
734
+ when 'ASHRAE 169-2006-1A',
735
+ 'ASHRAE 169-2006-1B'
736
+ minimum_capacity_btu_per_hr = infinity_btu_per_hr # No requirement
737
+ when 'ASHRAE 169-2006-2A',
738
+ 'ASHRAE 169-2006-3A',
739
+ 'ASHRAE 169-2006-4A',
740
+ 'ASHRAE 169-2006-2B',
741
+ 'ASHRAE 169-2006-5A',
742
+ 'ASHRAE 169-2006-6A',
743
+ 'ASHRAE 169-2006-7A',
744
+ 'ASHRAE 169-2006-7B',
745
+ 'ASHRAE 169-2006-8A',
746
+ 'ASHRAE 169-2006-8B',
747
+ 'ASHRAE 169-2006-3B',
748
+ 'ASHRAE 169-2006-3C',
749
+ 'ASHRAE 169-2006-4B',
750
+ 'ASHRAE 169-2006-4C',
751
+ 'ASHRAE 169-2006-5B',
752
+ 'ASHRAE 169-2006-5C',
753
+ 'ASHRAE 169-2006-6B'
754
+ minimum_capacity_btu_per_hr = 54000
755
+ end
703
756
  end
704
757
  when 'NECB 2011'
705
758
  minimum_capacity_btu_per_hr = 68243 # NECB requires economizer for cooling cap > 20 kW
@@ -707,9 +760,21 @@ class OpenStudio::Model::AirLoopHVAC
707
760
 
708
761
  # Check whether the system requires an economizer by comparing
709
762
  # the system capacity to the minimum capacity.
710
- minimum_capacity_w = OpenStudio.convert(minimum_capacity_btu_per_hr, "Btu/hr", "W").get
711
- if self.total_cooling_capacity >= minimum_capacity_w
763
+ total_cooling_capacity_w = self.total_cooling_capacity
764
+ total_cooling_capacity_btu_per_hr = OpenStudio.convert(total_cooling_capacity_w, "W", "Btu/hr").get
765
+ if total_cooling_capacity_btu_per_hr >= minimum_capacity_btu_per_hr
766
+ if is_dc
767
+ OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "#{self.name} requires an economizer because the total cooling capacity of #{total_cooling_capacity_btu_per_hr.round} Btu/hr exceeds the minimum capacity of #{minimum_capacity_btu_per_hr.round} Btu/hr for data centers.")
768
+ else
769
+ OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "#{self.name} requires an economizer because the total cooling capacity of #{total_cooling_capacity_btu_per_hr.round} Btu/hr exceeds the minimum capacity of #{minimum_capacity_btu_per_hr.round} Btu/hr.")
770
+ end
712
771
  economizer_required = true
772
+ else
773
+ if is_dc
774
+ OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "#{self.name} does not require an economizer because the total cooling capacity of #{total_cooling_capacity_btu_per_hr.round} Btu/hr is less than the minimum capacity of #{minimum_capacity_btu_per_hr.round} Btu/hr for data centers.")
775
+ else
776
+ OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "#{self.name} does not require an economizer because the total cooling capacity of #{total_cooling_capacity_btu_per_hr.round} Btu/hr is less than the minimum capacity of #{minimum_capacity_btu_per_hr.round} Btu/hr.")
777
+ end
713
778
  end
714
779
 
715
780
  return economizer_required
@@ -1804,7 +1869,7 @@ class OpenStudio::Model::AirLoopHVAC
1804
1869
  v_ou += zone.outdoor_airflow_rate
1805
1870
  end
1806
1871
  v_ou_cfm = OpenStudio.convert(v_ou, 'm^3/s', 'cfm').get
1807
-
1872
+
1808
1873
  # System primary airflow rate (whether autosized or hard-sized)
1809
1874
  v_ps = 0.0
1810
1875
  if self.autosizedDesignSupplyAirFlowRate.is_initialized
@@ -2219,7 +2284,11 @@ class OpenStudio::Model::AirLoopHVAC
2219
2284
  # linearly when outdoor air is between 50F and 70F.
2220
2285
  #
2221
2286
  # @return [Bool] Returns true if successful, false if not.
2287
+
2222
2288
  def enable_supply_air_temperature_reset_outdoor_temperature()
2289
+
2290
+ # for AHU1 in Outpatient, SAT is 52F constant, no reset
2291
+ return true if self.name.get == 'PVAV Outpatient F1'
2223
2292
 
2224
2293
  # Get the current setpoint and calculate
2225
2294
  # the new setpoint.
@@ -2386,7 +2455,7 @@ class OpenStudio::Model::AirLoopHVAC
2386
2455
  OpenStudio::logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "For #{self.name}: Because the system has an economizer, it requires a motorized OA damper.")
2387
2456
  return motorized_oa_damper_required
2388
2457
  end
2389
-
2458
+
2390
2459
  # Determine the exceptions based on
2391
2460
  # number of stories, climate zone, and
2392
2461
  # outdoor air intake rates.
@@ -3316,4 +3385,34 @@ class OpenStudio::Model::AirLoopHVAC
3316
3385
 
3317
3386
  end
3318
3387
 
3388
+ # Determine how much data center
3389
+ # area the airloop serves.
3390
+ #
3391
+ # @return [Double] the area of data center is served,
3392
+ # in m^2.
3393
+ # @todo Add an is_data_center field to the
3394
+ # standards space type spreadsheet instead
3395
+ # of relying on the standards space type name to
3396
+ # identify a data center.
3397
+ def data_center_area_served()
3398
+
3399
+ dc_area_m2 = 0.0
3400
+
3401
+ self.thermalZones.each do |zone|
3402
+ zone.spaces.each do |space|
3403
+ # Skip spaces with no space type
3404
+ next if space.spaceType.empty?
3405
+ space_type = space.spaceType.get
3406
+ next if space_type.standardsSpaceType.empty?
3407
+ standards_space_type = space_type.standardsSpaceType.get
3408
+ # Counts as a data center if the name includes 'data'
3409
+ next unless standards_space_type.downcase.include?('data')
3410
+ dc_area_m2 += space.floorArea
3411
+ end
3412
+ end
3413
+
3414
+ return dc_area_m2
3415
+
3416
+ end
3417
+
3319
3418
  end
@@ -193,7 +193,7 @@ class OpenStudio::Model::ChillerElectricEIR
193
193
  # which may be either a CurveBicubic or a CurveQuadratic based on chiller type
194
194
  cool_plf_fplr = self.model.add_curve(chlr_props['eirfplr'])
195
195
  if cool_plf_fplr
196
- #self.setElectricInputToCoolingOutputRatioFunctionOfPLR(cool_plf_fplr)
196
+ self.setElectricInputToCoolingOutputRatioFunctionOfPLR(cool_plf_fplr)
197
197
  else
198
198
  OpenStudio::logFree(OpenStudio::Warn, "openstudio.standards.ChillerElectricEIR", "For #{self.name}, cannot find cool_plf_fplr curve, will not be set.")
199
199
  successfully_set_all_properties = false
@@ -14,6 +14,19 @@ class OpenStudio::Model::ScheduleConstant
14
14
 
15
15
  return annual_flh = self.value * 8760
16
16
 
17
- end
17
+ end
18
+
19
+ # Returns the min and max value for this schedule.
20
+ # It doesn't evaluate design days only run-period conditions
21
+ #
22
+ # @author David Goldwasser, NREL.
23
+ # return [Hash] Hash has two keys, min and max.
24
+ def annual_min_max_value()
25
+
26
+ result = { 'min' => self.value, 'max' => self.value }
27
+
28
+ return result
29
+
30
+ end
18
31
 
19
32
  end
@@ -110,6 +110,45 @@ class OpenStudio::Model::ScheduleRuleset
110
110
 
111
111
  return annual_flh
112
112
 
113
- end
113
+ end
114
+
115
+ # Returns the min and max value for this schedule.
116
+ # It doesn't evaluate design days only run-period conditions
117
+ #
118
+ # @author David Goldwasser, NREL.
119
+ # return [Hash] Hash has two keys, min and max.
120
+ def annual_min_max_value()
121
+
122
+ # gather profiles
123
+ profiles = []
124
+ defaultProfile = self.defaultDaySchedule
125
+ profiles << defaultProfile
126
+ rules = self.scheduleRules
127
+ rules.each do |rule|
128
+ profiles << rule.daySchedule
129
+ end
130
+
131
+ # test profiles
132
+ min = nil
133
+ max = nil
134
+ profiles.each do |profile|
135
+ profile.values.each do |value|
136
+ if min.nil?
137
+ min = value
138
+ else
139
+ if min > value then min = value end
140
+ end
141
+ if max.nil?
142
+ max = value
143
+ else
144
+ if max < value then max = value end
145
+ end
146
+ end
147
+ end
148
+ result = { 'min' => min, 'max' => max }
149
+
150
+ return result
151
+
152
+ end
114
153
 
115
154
  end
@@ -18,7 +18,7 @@ class OpenStudio::Model::SpaceType
18
18
  else
19
19
  standards_space_type = nil
20
20
  end
21
-
21
+
22
22
  # populate search hash
23
23
  search_criteria = {
24
24
  "template" => template,
@@ -395,7 +395,9 @@ class OpenStudio::Model::SpaceType
395
395
  infiltration_per_area_ext = space_type_properties['infiltration_per_exterior_area'].to_f
396
396
  infiltration_per_area_ext_wall = space_type_properties['infiltration_per_exterior_wall_area'].to_f
397
397
  infiltration_ach = space_type_properties['infiltration_air_changes'].to_f
398
- make_infiltration = true unless infiltration_per_area_ext == 0
398
+ unless infiltration_per_area_ext == 0 && infiltration_per_area_ext_wall == 0 && infiltration_ach == 0
399
+ infiltration_have_info = true
400
+ end
399
401
 
400
402
  if set_infiltration && infiltration_have_info
401
403
 
@@ -1,3 +1,3 @@
1
1
  module OpenstudioStandards
2
- VERSION = "0.1.0"
2
+ VERSION = "0.1.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openstudio-standards
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Parker
@@ -20,7 +20,7 @@ authors:
20
20
  autorequire:
21
21
  bindir: bin
22
22
  cert_chain: []
23
- date: 2016-03-19 00:00:00.000000000 Z
23
+ date: 2016-04-13 00:00:00.000000000 Z
24
24
  dependencies:
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: bundler
@@ -302,6 +302,7 @@ files:
302
302
  - data/geometry/Geometry.full_service_restaurant_pre1980.osm
303
303
  - data/geometry/Geometry.high_rise_apartment.osm
304
304
  - data/geometry/Geometry.hospital.osm
305
+ - data/geometry/Geometry.hospital_original.osm
305
306
  - data/geometry/Geometry.large_hotel.2004_2007.osm
306
307
  - data/geometry/Geometry.large_hotel.2010.osm
307
308
  - data/geometry/Geometry.large_hotel.2013.osm