openstudio-standards 0.1.0 → 0.1.1

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 (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