openstudio-standards 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/data/standards/OpenStudio_Standards.xlsx +0 -0
  3. data/data/standards/OpenStudio_Standards_boilers.json +62 -4
  4. data/data/standards/OpenStudio_Standards_chillers.json +778 -68
  5. data/data/standards/OpenStudio_Standards_construction_sets.json +52 -93
  6. data/data/standards/OpenStudio_Standards_curve_biquadratics.json +36 -36
  7. data/data/standards/OpenStudio_Standards_curve_quadratics.json +3 -3
  8. data/data/standards/OpenStudio_Standards_heat_pumps.json +840 -0
  9. data/data/standards/OpenStudio_Standards_heat_pumps_heating.json +352 -0
  10. data/data/standards/OpenStudio_Standards_heat_rejection.json +48 -0
  11. data/data/standards/OpenStudio_Standards_motors.json +270 -0
  12. data/data/standards/OpenStudio_Standards_space_types.json +10390 -2824
  13. data/data/standards/OpenStudio_Standards_unitary_acs.json +794 -18
  14. data/data/weather/USA_CO_Boulder-Broomfield-Jefferson.County.AP.724699_TMY3.ddy +538 -0
  15. data/data/weather/USA_CO_Boulder-Broomfield-Jefferson.County.AP.724699_TMY3.epw +8768 -0
  16. data/data/weather/USA_CO_Boulder-Broomfield-Jefferson.County.AP.724699_TMY3.stat +493 -0
  17. data/data/weather/USA_CO_Denver.Intl.AP.725650_TMY3.ddy +536 -0
  18. data/data/weather/USA_CO_Denver.Intl.AP.725650_TMY3.epw +8768 -0
  19. data/data/weather/USA_CO_Denver.Intl.AP.725650_TMY3.stat +554 -0
  20. data/data/weather/USA_CO_Fort.Collins.AWOS.724769_TMY3.ddy +536 -0
  21. data/data/weather/USA_CO_Fort.Collins.AWOS.724769_TMY3.epw +8768 -0
  22. data/data/weather/USA_CO_Fort.Collins.AWOS.724769_TMY3.stat +554 -0
  23. data/data/weather/envelope_info.csv +6 -0
  24. data/lib/openstudio-standards.rb +10 -11
  25. data/lib/openstudio-standards/btap/compliance.rb +251 -969
  26. data/lib/openstudio-standards/btap/envelope.rb +1 -1
  27. data/lib/openstudio-standards/btap/fileio.rb +37 -5
  28. data/lib/openstudio-standards/btap/geometry.rb +27 -17
  29. data/lib/openstudio-standards/btap/hvac.rb +80 -27
  30. data/lib/openstudio-standards/hvac_sizing/{HVACSizing.CoilHeatingDXMultiSpeed.rb → Siz.CoilHeatingDXMultiSpeed.rb} +0 -0
  31. data/lib/openstudio-standards/hvac_sizing/Siz.ControllerOutdoorAir.rb +30 -4
  32. data/lib/openstudio-standards/hvac_sizing/Siz.CoolingTowerTwoSpeed.rb +61 -5
  33. data/lib/openstudio-standards/hvac_sizing/Siz.CoolingTowerVariableSpeed.rb +37 -7
  34. data/lib/openstudio-standards/hvac_sizing/Siz.DistrictCooling.rb +27 -0
  35. data/lib/openstudio-standards/hvac_sizing/Siz.DistrictHeating.rb +27 -0
  36. data/lib/openstudio-standards/hvac_sizing/Siz.HeaderedPumpsConstantSpeed.rb +55 -0
  37. data/lib/openstudio-standards/hvac_sizing/Siz.HeaderedPumpsVariableSpeed.rb +55 -0
  38. data/lib/openstudio-standards/hvac_sizing/Siz.HeatingCoolingFuels.rb +51 -9
  39. data/lib/openstudio-standards/hvac_sizing/Siz.Model.rb +99 -17
  40. data/lib/openstudio-standards/hvac_sizing/Siz.PumpConstantSpeed.rb +1 -1
  41. data/lib/openstudio-standards/hvac_sizing/Siz.ThermalZone.rb +29 -6
  42. data/lib/openstudio-standards/hvac_sizing/Siz.WaterHeaterMixed.rb +16 -0
  43. data/lib/openstudio-standards/prototypes/Prototype.AirTerminalSingleDuctVAVReheat.rb +43 -48
  44. data/lib/openstudio-standards/prototypes/Prototype.ControllerWaterCoil.rb +5 -9
  45. data/lib/openstudio-standards/prototypes/Prototype.Fan.rb +68 -0
  46. data/lib/openstudio-standards/prototypes/Prototype.FanConstantVolume.rb +39 -43
  47. data/lib/openstudio-standards/prototypes/Prototype.FanOnOff.rb +49 -51
  48. data/lib/openstudio-standards/prototypes/Prototype.FanVariableVolume.rb +55 -61
  49. data/lib/openstudio-standards/prototypes/Prototype.FanZoneExhaust.rb +8 -10
  50. data/lib/openstudio-standards/prototypes/Prototype.HeatExchangerAirToAirSensibleAndLatent.rb +15 -20
  51. data/lib/openstudio-standards/prototypes/Prototype.Model.hvac.rb +330 -322
  52. data/lib/openstudio-standards/prototypes/Prototype.Model.rb +501 -446
  53. data/lib/openstudio-standards/prototypes/Prototype.Model.swh.rb +221 -230
  54. data/lib/openstudio-standards/prototypes/Prototype.add_objects.rb +0 -2
  55. data/lib/openstudio-standards/prototypes/Prototype.full_service_restaurant.rb +130 -137
  56. data/lib/openstudio-standards/prototypes/Prototype.high_rise_apartment.rb +374 -291
  57. data/lib/openstudio-standards/prototypes/Prototype.hospital.rb +146 -193
  58. data/lib/openstudio-standards/prototypes/Prototype.hvac_systems.rb +1315 -1113
  59. data/lib/openstudio-standards/prototypes/Prototype.large_hotel.rb +65 -88
  60. data/lib/openstudio-standards/prototypes/Prototype.large_office.rb +101 -156
  61. data/lib/openstudio-standards/prototypes/Prototype.medium_office.rb +46 -96
  62. data/lib/openstudio-standards/prototypes/Prototype.mid_rise_apartment.rb +113 -123
  63. data/lib/openstudio-standards/prototypes/Prototype.outpatient.rb +356 -345
  64. data/lib/openstudio-standards/prototypes/Prototype.primary_school.rb +48 -103
  65. data/lib/openstudio-standards/prototypes/Prototype.quick_service_restaurant.rb +115 -123
  66. data/lib/openstudio-standards/prototypes/Prototype.retail_standalone.rb +30 -39
  67. data/lib/openstudio-standards/prototypes/Prototype.retail_stripmall.rb +32 -45
  68. data/lib/openstudio-standards/prototypes/Prototype.secondary_school.rb +98 -258
  69. data/lib/openstudio-standards/prototypes/Prototype.small_hotel.rb +429 -474
  70. data/lib/openstudio-standards/prototypes/Prototype.small_office.rb +28 -36
  71. data/lib/openstudio-standards/prototypes/Prototype.strip_model.rb +7 -7
  72. data/lib/openstudio-standards/prototypes/Prototype.utilities.rb +172 -146
  73. data/lib/openstudio-standards/prototypes/Prototype.warehouse.rb +46 -53
  74. data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +885 -707
  75. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctParallelPIUReheat.rb +48 -57
  76. data/lib/openstudio-standards/standards/Standards.AirTerminalSingleDuctVAVReheat.rb +24 -31
  77. data/lib/openstudio-standards/standards/Standards.BoilerHotWater.rb +80 -93
  78. data/lib/openstudio-standards/standards/Standards.BuildingStory.rb +69 -0
  79. data/lib/openstudio-standards/standards/Standards.ChillerElectricEIR.rb +60 -72
  80. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXMultiSpeed.rb +104 -108
  81. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXSingleSpeed.rb +190 -198
  82. data/lib/openstudio-standards/standards/Standards.CoilCoolingDXTwoSpeed.rb +134 -146
  83. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXMultiSpeed.rb +56 -60
  84. data/lib/openstudio-standards/standards/Standards.CoilHeatingDXSingleSpeed.rb +151 -161
  85. data/lib/openstudio-standards/standards/Standards.CoilHeatingGasMultiStage.rb +30 -34
  86. data/lib/openstudio-standards/standards/Standards.Construction.rb +116 -132
  87. data/lib/openstudio-standards/standards/Standards.CoolingTower.rb +138 -0
  88. data/lib/openstudio-standards/standards/Standards.CoolingTowerSingleSpeed.rb +11 -0
  89. data/lib/openstudio-standards/standards/Standards.CoolingTowerTwoSpeed.rb +11 -0
  90. data/lib/openstudio-standards/standards/Standards.CoolingTowerVariableSpeed.rb +16 -0
  91. data/lib/openstudio-standards/standards/Standards.Fan.rb +190 -236
  92. data/lib/openstudio-standards/standards/Standards.FanConstantVolume.rb +0 -2
  93. data/lib/openstudio-standards/standards/Standards.FanOnOff.rb +0 -2
  94. data/lib/openstudio-standards/standards/Standards.FanVariableVolume.rb +168 -14
  95. data/lib/openstudio-standards/standards/Standards.FanZoneExhaust.rb +0 -2
  96. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsConstantSpeed.rb +33 -0
  97. data/lib/openstudio-standards/standards/Standards.HeaderedPumpsVariableSpeed.rb +83 -0
  98. data/lib/openstudio-standards/standards/Standards.HeatExchangerSensLat.rb +22 -0
  99. data/lib/openstudio-standards/standards/Standards.Model.rb +2385 -1622
  100. data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +83 -35
  101. data/lib/openstudio-standards/standards/Standards.PlantLoop.rb +805 -395
  102. data/lib/openstudio-standards/standards/Standards.Pump.rb +139 -119
  103. data/lib/openstudio-standards/standards/Standards.PumpConstantSpeed.rb +0 -2
  104. data/lib/openstudio-standards/standards/Standards.PumpVariableSpeed.rb +16 -15
  105. data/lib/openstudio-standards/standards/Standards.ScheduleCompact.rb +35 -0
  106. data/lib/openstudio-standards/standards/Standards.ScheduleConstant.rb +7 -13
  107. data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +144 -59
  108. data/lib/openstudio-standards/standards/Standards.Space.rb +1509 -1326
  109. data/lib/openstudio-standards/standards/Standards.SpaceType.rb +254 -262
  110. data/lib/openstudio-standards/standards/Standards.SubSurface.rb +105 -105
  111. data/lib/openstudio-standards/standards/Standards.Surface.rb +27 -31
  112. data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +882 -157
  113. data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +179 -69
  114. data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +75 -0
  115. data/lib/openstudio-standards/utilities/logging.rb +31 -38
  116. data/lib/openstudio-standards/utilities/simulation.rb +118 -82
  117. data/lib/openstudio-standards/version.rb +1 -1
  118. data/lib/openstudio-standards/weather/Weather.Model.rb +382 -390
  119. data/lib/openstudio-standards/weather/Weather.stat_file.rb +159 -78
  120. metadata +59 -6
@@ -1,8 +1,8 @@
1
1
 
2
2
  # open the class to add methods to size all HVAC equipment
3
3
  class OpenStudio::Model::Model
4
-
5
4
  # Load the helper libraries for
5
+ require_relative 'Prototype.Fan'
6
6
  require_relative 'Prototype.FanConstantVolume'
7
7
  require_relative 'Prototype.FanVariableVolume'
8
8
  require_relative 'Prototype.FanOnOff'
@@ -17,189 +17,157 @@ class OpenStudio::Model::Model
17
17
  # the current model with this model.
18
18
  #
19
19
  # @param building_type [String] the building type
20
- # @param building_vintage [String] the building vintage
20
+ # @param template [String] the template
21
21
  # @param climate_zone [String] the climate zone
22
22
  # @param debug [Boolean] If true, will report out more detailed debugging output
23
23
  # @return [Bool] returns true if successful, false if not
24
24
  # @example Create a Small Office, 90.1-2010, in ASHRAE Climate Zone 5A (Chicago)
25
25
  # model.create_prototype_building('SmallOffice', '90.1-2010', 'ASHRAE 169-2006-5A')
26
26
 
27
- def create_prototype_building(building_type, building_vintage, climate_zone, epw_file, sizing_run_dir = Dir.pwd, debug = false)
28
-
27
+ def create_prototype_building(building_type, template, climate_zone, epw_file, sizing_run_dir = Dir.pwd, debug = false)
29
28
  # There are no reference models for HighriseApartment at vintages Pre-1980 and 1980-2004, nor for NECB 2011. This is a quick check.
30
- if building_type == "HighriseApartment"
31
- if building_vintage == 'DOE Ref Pre-1980' or building_vintage == 'DOE Ref 1980-2004'
32
- OpenStudio::logFree(OpenStudio::Error, 'Not available', "DOE Reference models for #{building_type} at vintage #{building_vintage} are not available, the measure is disabled for this specific type.")
29
+ if building_type == 'HighriseApartment'
30
+ if template == 'DOE Ref Pre-1980' || template == 'DOE Ref 1980-2004'
31
+ OpenStudio.logFree(OpenStudio::Error, 'Not available', "DOE Reference models for #{building_type} at template #{template} are not available, the measure is disabled for this specific type.")
33
32
  return false
34
- elsif building_vintage == "NECB 2011"
35
- OpenStudio::logFree(OpenStudio::Error, 'Not available', "Reference model for #{building_type} at vintage #{building_vintage} is not available, the measure is disabled for this specific type.")
33
+ elsif template == 'NECB 2011'
34
+ OpenStudio.logFree(OpenStudio::Error, 'Not available', "Reference model for #{building_type} at template #{template} is not available, the measure is disabled for this specific type.")
36
35
  return false
37
36
  end
38
37
  end
39
38
 
40
- lookup_building_type = self.get_lookup_name(building_type)
39
+ lookup_building_type = get_lookup_name(building_type)
41
40
 
42
41
  # Retrieve the Prototype Inputs from JSON
43
42
  search_criteria = {
44
- 'template' => building_vintage,
43
+ 'template' => template,
45
44
  'building_type' => building_type
46
45
  }
47
46
 
48
- prototype_input = self.find_object($os_standards['prototype_inputs'], search_criteria,nil)
49
-
47
+ prototype_input = find_object($os_standards['prototype_inputs'], search_criteria, nil)
50
48
 
51
49
  if prototype_input.nil?
52
- OpenStudio::logFree(OpenStudio::Error, 'openstudio.standards.Model', "Could not find prototype inputs for #{search_criteria}, cannot create model.")
50
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Model', "Could not find prototype inputs for #{search_criteria}, cannot create model.")
53
51
  return false
54
52
  end
55
53
 
56
-
57
- case building_vintage
54
+ case template
58
55
  when 'NECB 2011'
59
- self.load_building_type_methods(building_type, building_vintage, climate_zone)
60
- self.load_geometry(building_type, building_vintage, climate_zone)
61
- self.getBuilding.setName("#{building_vintage}-#{building_type}-#{climate_zone}-#{epw_file} created: #{Time.new}")
62
- space_type_map = self.define_space_type_map(building_type, building_vintage, climate_zone)
63
- self.assign_space_type_stubs("Space Function", building_vintage, space_type_map) # TO DO: add support for defining NECB 2011 archetype by building type (versus space function)
64
- self.add_loads(building_vintage, climate_zone)
65
- self.modify_infiltration_coefficients(building_type, building_vintage, climate_zone) #does not apply to NECB 2011 but left here for consistency
66
- self.modify_surface_convection_algorithm(building_vintage)
67
-
68
- #Should this be the first thing done Maria?
69
- self.add_design_days_and_weather_file(building_type, building_vintage, climate_zone, epw_file)
70
- puts self.get_full_weather_file_path
71
- self.add_constructions(lookup_building_type, building_vintage, climate_zone) #set "dummy construction set
72
- #BTAP::Geometry::intersect_surfaces(self)
73
- #BTAP::Geometry::match_surfaces(self)
74
- BTAP::Compliance::NECB2011::set_necb_fwdr( self, true, runner=nil) # set FWDR
75
- BTAP::Compliance::NECB2011::set_all_construction_sets_to_necb!(self, runner=nil)
76
- #Getting System Fuel type types from BTAP::Environment.
77
- BTAP::Environment::get_canadian_system_defaults_by_weatherfile_name(epw_file)
78
- boiler_fueltype, baseboard_type, mau_type, mau_heating_coil_type, mua_cooling_type, chiller_type, heating_coil_types_sys3, heating_coil_types_sys4,heating_coil_types_sys6, fan_type = BTAP::Environment::get_canadian_system_defaults_by_weatherfile_name(epw_file)
79
- BTAP::Compliance::NECB2011::necb_autozone_and_autosystem(self, runner=nil, use_ideal_air_loads = false, boiler_fueltype, mau_type, mau_heating_coil_type, baseboard_type, chiller_type, mua_cooling_type, heating_coil_types_sys3, heating_coil_types_sys4, heating_coil_types_sys6, fan_type )
80
-
81
- self.set_sizing_parameters(building_type, building_vintage)
82
- self.yearDescription.get.setDayofWeekforStartDay('Sunday')
83
- self.add_swh(building_type, building_vintage, climate_zone, prototype_input) # note exhaust fan schedule for * common spaces.
84
- # TO DO: routine custom_swh_tweaks sets loss coefficient to ambient for water heater, differs for each archetype
85
- # NECB 2011 follows ASHRAE 90.1 for now, does this need to change?
86
- self.custom_swh_tweaks(building_type, building_vintage, climate_zone, prototype_input)
87
- # self.add_exterior_lights(building_type, building_vintage, climate_zone, prototype_input)
88
- # self.add_occupancy_sensors(building_type, building_vintage, climate_zone)
89
-
90
- #
91
-
56
+ load_building_type_methods(building_type, template, climate_zone)
57
+ load_geometry(building_type, template, climate_zone)
58
+ getBuilding.setName("#{template}-#{building_type}-#{climate_zone}-#{epw_file} created: #{Time.new}")
59
+ space_type_map = define_space_type_map(building_type, template, climate_zone)
60
+ assign_space_type_stubs('Space Function', template, space_type_map) # TO DO: add support for defining NECB 2011 archetype by building type (versus space function)
61
+ add_loads(template, climate_zone)
62
+ apply_infiltration_standard(template)
63
+ modify_infiltration_coefficients(building_type, template, climate_zone) # does not apply to NECB 2011 but left here for consistency
64
+ modify_surface_convection_algorithm(template)
65
+ add_constructions(lookup_building_type, template, climate_zone)
66
+ create_thermal_zones(building_type, template, climate_zone)
67
+ add_design_days_and_weather_file(building_type, template, climate_zone, epw_file)
68
+ return false if runSizingRun("#{sizing_run_dir}/SizingRun0") == false
69
+ add_hvac(building_type, template, climate_zone, prototype_input, epw_file)
70
+ add_swh(building_type, template, climate_zone, prototype_input)
71
+ apply_sizing_parameters(building_type, template)
72
+ yearDescription.get.setDayofWeekforStartDay('Sunday')
92
73
  else
93
74
 
94
- self.load_building_type_methods(building_type, building_vintage, climate_zone)
95
- self.load_geometry(building_type, building_vintage, climate_zone)
96
- self.getBuilding.setName("#{building_vintage}-#{building_type}-#{climate_zone} created: #{Time.new}")
97
- space_type_map = self.define_space_type_map(building_type, building_vintage, climate_zone)
98
- self.assign_space_type_stubs(lookup_building_type, building_vintage, space_type_map)
99
- self.add_loads(building_vintage, climate_zone)
100
- self.apply_infiltration_standard(building_vintage)
101
- self.modify_infiltration_coefficients(building_type, building_vintage, climate_zone)
102
- self.modify_surface_convection_algorithm(building_vintage)
103
- self.add_constructions(lookup_building_type, building_vintage, climate_zone)
104
- self.create_thermal_zones(building_type,building_vintage, climate_zone)
105
- self.add_hvac(building_type, building_vintage, climate_zone, prototype_input)
106
- self.custom_hvac_tweaks(building_type, building_vintage, climate_zone, prototype_input)
107
- self.add_swh(building_type, building_vintage, climate_zone, prototype_input)
108
- self.custom_swh_tweaks(building_type, building_vintage, climate_zone, prototype_input)
109
- self.add_exterior_lights(building_type, building_vintage, climate_zone, prototype_input)
110
- self.add_occupancy_sensors(building_type, building_vintage, climate_zone)
111
- self.add_design_days_and_weather_file(building_type, building_vintage, climate_zone, epw_file)
112
- self.set_sizing_parameters(building_type, building_vintage)
113
- self.yearDescription.get.setDayofWeekforStartDay('Sunday')
75
+ load_building_type_methods(building_type, template, climate_zone)
76
+ load_geometry(building_type, template, climate_zone)
77
+ getBuilding.setName("#{template}-#{building_type}-#{climate_zone} created: #{Time.new}")
78
+ space_type_map = define_space_type_map(building_type, template, climate_zone)
79
+ assign_space_type_stubs(lookup_building_type, template, space_type_map)
80
+ add_loads(template, climate_zone)
81
+ apply_infiltration_standard(template)
82
+ modify_infiltration_coefficients(building_type, template, climate_zone)
83
+ modify_surface_convection_algorithm(template)
84
+ add_constructions(lookup_building_type, template, climate_zone)
85
+ create_thermal_zones(building_type, template, climate_zone)
86
+ add_hvac(building_type, template, climate_zone, prototype_input, epw_file)
87
+ custom_hvac_tweaks(building_type, template, climate_zone, prototype_input)
88
+ add_swh(building_type, template, climate_zone, prototype_input)
89
+ custom_swh_tweaks(building_type, template, climate_zone, prototype_input)
90
+ add_exterior_lights(building_type, template, climate_zone, prototype_input)
91
+ add_occupancy_sensors(building_type, template, climate_zone)
92
+ add_design_days_and_weather_file(building_type, template, climate_zone, epw_file)
93
+ apply_sizing_parameters(building_type, template)
94
+ yearDescription.get.setDayofWeekforStartDay('Sunday')
114
95
 
115
96
  end
116
97
  # set climate zone and building type
117
- self.getBuilding.setStandardsBuildingType(building_type)
98
+ getBuilding.setStandardsBuildingType(building_type)
118
99
  if climate_zone.include? 'ASHRAE 169-2006-'
119
- self.getClimateZones.setClimateZone("ASHRAE",climate_zone.gsub('ASHRAE 169-2006-',''))
100
+ getClimateZones.setClimateZone('ASHRAE', climate_zone.gsub('ASHRAE 169-2006-', ''))
120
101
  end
121
102
 
122
103
  # Perform a sizing run
123
- if self.runSizingRun("#{sizing_run_dir}/SizingRun1") == false
104
+ if runSizingRun("#{sizing_run_dir}/SizingRun1") == false
124
105
  return false
125
106
  end
126
107
 
127
-
128
- # If there are any multizone systems, set damper positions
129
- # and perform a second sizing run
130
- has_multizone_systems = false
131
-
132
-
133
- self.getAirLoopHVACs.sort.each do |air_loop|
134
-
135
- if air_loop.is_multizone_vav_system
136
- self.apply_multizone_vav_outdoor_air_sizing(building_vintage)
137
- if self.runSizingRun("#{sizing_run_dir}/SizingRun2") == false
138
- return false
139
- end
140
- break
141
- end
142
- end
108
+ # If there are any multizone systems, reset damper positions
109
+ # to achieve a 60% ventilation effectiveness minimum for the system
110
+ # following the ventilation rate procedure from 62.1
111
+ apply_multizone_vav_outdoor_air_sizing(template)
143
112
 
144
113
  # Apply the prototype HVAC assumptions
145
114
  # which include sizing the fan pressure rises based
146
115
  # on the flow rate of the system.
147
- self.applyPrototypeHVACAssumptions(building_type, building_vintage, climate_zone)
116
+ apply_prototype_hvac_assumptions(building_type, template, climate_zone)
148
117
 
149
118
  # for 90.1-2010 Outpatient, AHU2 set minimum outdoor air flow rate as 0
150
119
  # AHU1 doesn't have economizer
151
- if building_type == "Outpatient"
152
- self.modify_OAcontroller(building_vintage)
120
+ if building_type == 'Outpatient'
121
+ modify_oa_controller(template)
153
122
  # For operating room 1&2 in 2010 and 2013, VAV minimum air flow is set by schedule
154
- self.reset_or_room_vav_minimum_damper(prototype_input, building_vintage)
123
+ reset_or_room_vav_minimum_damper(prototype_input, template)
155
124
  end
156
125
 
157
- if building_type == "Hospital"
158
- self.modify_hospital_OAcontroller(building_vintage)
126
+ if building_type == 'Hospital'
127
+ modify_hospital_oa_controller(template)
159
128
  end
160
129
 
161
130
  # Apply the HVAC efficiency standard
162
- self.applyHVACEfficiencyStandard(building_vintage, climate_zone)
131
+ apply_hvac_efficiency_standard(template, climate_zone)
163
132
 
164
133
  # Add daylighting controls per standard
165
134
  # only four zones in large hotel have daylighting controls
166
135
  # todo: YXC to merge to the main function
167
- if building_type == "LargeHotel"
168
- self.add_daylighting_controls(building_vintage)
169
- elsif building_type == "Hospital"
170
- self.hospital_add_daylighting_controls(building_vintage)
136
+ if building_type == 'LargeHotel'
137
+ large_hotel_add_daylighting_controls(template)
138
+ elsif building_type == 'Hospital'
139
+ hospital_add_daylighting_controls(template)
171
140
  else
172
- self.addDaylightingControls(building_vintage)
141
+ add_daylighting_controls(template)
173
142
  end
174
143
 
175
- if building_type == "QuickServiceRestaurant" || building_type == "FullServiceRestaurant" || building_type == "Outpatient"
176
- self.update_exhaust_fan_efficiency(building_vintage)
144
+ if building_type == 'QuickServiceRestaurant' || building_type == 'FullServiceRestaurant' || building_type == 'Outpatient'
145
+ update_exhaust_fan_efficiency(template)
177
146
  end
178
147
 
179
- if building_type == "HighriseApartment"
180
- self.update_fan_efficiency
148
+ if building_type == 'HighriseApartment'
149
+ update_fan_efficiency
181
150
  end
182
151
 
183
152
  # Add output variables for debugging
184
153
  # AHU1 doesn't have economizer
185
- if building_type == "Outpatient"
154
+ if building_type == 'Outpatient'
186
155
  # remove the controller:mechanical ventilation for AHU1 OA
187
- self.modify_OAcontroller(building_vintage)
156
+ modify_oa_controller(template)
188
157
  # For operating room 1&2 in 2010 and 2013, VAV minimum air flow is set by schedule
189
- self.reset_or_room_vav_minimum_damper(prototype_input, building_vintage)
158
+ reset_or_room_vav_minimum_damper(prototype_input, template)
190
159
  end
191
160
 
192
161
  # Add output variables for debugging
193
162
  if debug
194
- self.request_timeseries_outputs
163
+ request_timeseries_outputs
195
164
  end
196
165
 
197
166
  # Finished
198
167
  model_status = 'final'
199
- self.save(OpenStudio::Path.new("#{sizing_run_dir}/#{model_status}.osm"), true)
168
+ save(OpenStudio::Path.new("#{sizing_run_dir}/#{model_status}.osm"), true)
200
169
 
201
170
  return true
202
-
203
171
  end
204
172
 
205
173
  # Get the name of the building type used in lookups
@@ -209,7 +177,6 @@ class OpenStudio::Model::Model
209
177
  # @return [String] returns the lookup name as a string
210
178
  # @todo Unify the lookup names and eliminate this method
211
179
  def get_lookup_name(building_type)
212
-
213
180
  lookup_name = building_type
214
181
 
215
182
  case building_type
@@ -228,18 +195,15 @@ class OpenStudio::Model::Model
228
195
  end
229
196
 
230
197
  return lookup_name
231
-
232
198
  end
233
199
 
234
-
235
200
  # Loads the library of methods specific to this building type
236
201
  #
237
202
  # @param building_type [String] the building type
238
- # @param building_vintage [String] the building vintage
203
+ # @param template [String] the template
239
204
  # @param climate_zone [String] the climate zone
240
205
  # @return [Bool] returns true if successful, false if not
241
- def load_building_type_methods(building_type, building_vintage, climate_zone)
242
-
206
+ def load_building_type_methods(building_type, template, climate_zone)
243
207
  building_methods = nil
244
208
 
245
209
  case building_type
@@ -276,64 +240,61 @@ class OpenStudio::Model::Model
276
240
  when 'HighriseApartment'
277
241
  building_methods = 'Prototype.high_rise_apartment'
278
242
  else
279
- OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model',"Building Type = #{building_type} not recognized")
243
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "Building Type = #{building_type} not recognized")
280
244
  return false
281
245
  end
282
246
 
283
- lib_dir = File.expand_path( '../../..',File.dirname(__FILE__))
284
- require "#{lib_dir}/lib/openstudio-standards/prototypes/#{building_methods}"
247
+ require_relative "#{building_methods}"
285
248
 
286
249
  return true
287
-
288
250
  end
289
251
 
290
252
  # Loads a geometry-only .osm as a starting point.
291
253
  #
292
254
  # @param building_type [String] the building type
293
- # @param building_vintage [String] the building vintage
255
+ # @param template [String] the template
294
256
  # @param climate_zone [String] the climate zone
295
257
  # @return [Bool] returns true if successful, false if not
296
- def load_geometry(building_type, building_vintage, climate_zone)
297
-
298
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started adding geometry')
258
+ def load_geometry(building_type, template, climate_zone)
259
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started adding geometry')
299
260
 
300
261
  # Determine which geometry file to use
301
262
  # based on building_type and template
302
- # NECB 2011 geometry is not explicitly defined; for NECB 2011 vintage, latest ASHRAE 90.1 geometry file is assigned (implicitly)
263
+ # NECB 2011 geometry is not explicitly defined; for NECB 2011 template, latest ASHRAE 90.1 geometry file is assigned (implicitly)
303
264
 
304
265
  case building_type
305
266
  when 'SecondarySchool'
306
- if building_vintage == 'DOE Ref Pre-1980' || building_vintage == 'DOE Ref 1980-2004'
307
- geometry_file = 'Geometry.secondary_school_pre_1980_to_2004.osm'
308
- else
309
- geometry_file = 'Geometry.secondary_school.osm'
310
- end
267
+ geometry_file = if template == 'DOE Ref Pre-1980' || template == 'DOE Ref 1980-2004'
268
+ 'Geometry.secondary_school_pre_1980_to_2004.osm'
269
+ else
270
+ 'Geometry.secondary_school.osm'
271
+ end
311
272
  when 'PrimarySchool'
312
- if building_vintage == 'DOE Ref Pre-1980' || building_vintage == 'DOE Ref 1980-2004'
313
- geometry_file = 'Geometry.primary_school_pre_1980_to_2004.osm'
314
- else
315
- geometry_file = 'Geometry.primary_school.osm'
316
- end
273
+ geometry_file = if template == 'DOE Ref Pre-1980' || template == 'DOE Ref 1980-2004'
274
+ 'Geometry.primary_school_pre_1980_to_2004.osm'
275
+ else
276
+ 'Geometry.primary_school.osm'
277
+ end
317
278
  when 'SmallOffice'
318
- if building_vintage == 'DOE Ref Pre-1980'
319
- geometry_file = 'Geometry.small_office_pre_1980.osm'
320
- else
321
- geometry_file = 'Geometry.small_office.osm'
322
- end
279
+ geometry_file = if template == 'DOE Ref Pre-1980'
280
+ 'Geometry.small_office_pre_1980.osm'
281
+ else
282
+ 'Geometry.small_office.osm'
283
+ end
323
284
  alt_search_name = 'Office'
324
285
  when 'MediumOffice'
325
286
  geometry_file = 'Geometry.medium_office.osm'
326
287
  alt_search_name = 'Office'
327
288
  when 'LargeOffice'
328
289
  alt_search_name = 'Office'
329
- case building_vintage
330
- when 'DOE Ref Pre-1980','DOE Ref 1980-2004','DOE Ref 2004'
290
+ case template
291
+ when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004', 'DOE Ref 2004'
331
292
  geometry_file = 'Geometry.large_office_reference.osm'
332
293
  else
333
294
  geometry_file = 'Geometry.large_office_2010.osm'
334
295
  end
335
296
  when 'SmallHotel'
336
- case building_vintage
297
+ case template
337
298
  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
338
299
  geometry_file = 'Geometry.small_hotel_doe.osm'
339
300
  when '90.1-2004'
@@ -342,14 +303,14 @@ class OpenStudio::Model::Model
342
303
  geometry_file = 'Geometry.small_hotel_pnnl2007.osm'
343
304
  when '90.1-2010'
344
305
  geometry_file = 'Geometry.small_hotel_pnnl2010.osm'
345
- else #'90.1-2013'
306
+ else # '90.1-2013'
346
307
  geometry_file = 'Geometry.small_hotel_pnnl2013.osm'
347
308
  end
348
309
  when 'LargeHotel'
349
- case building_vintage
350
- when 'DOE Ref Pre-1980','DOE Ref 1980-2004','DOE Ref 2004'
310
+ case template
311
+ when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004', 'DOE Ref 2004'
351
312
  geometry_file = 'Geometry.large_hotel.doe.osm'
352
- when '90.1-2007','90.1-2004'
313
+ when '90.1-2007', '90.1-2004'
353
314
  geometry_file = 'Geometry.large_hotel.2004_2007.osm'
354
315
  when '90.1-2010'
355
316
  geometry_file = 'Geometry.large_hotel.2010.osm'
@@ -357,19 +318,19 @@ class OpenStudio::Model::Model
357
318
  geometry_file = 'Geometry.large_hotel.2013.osm'
358
319
  end
359
320
  when 'Warehouse'
360
- case building_vintage
361
- when 'DOE Ref Pre-1980','DOE Ref 1980-2004','DOE Ref 2004'
321
+ case template
322
+ when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004', 'DOE Ref 2004'
362
323
  geometry_file = 'Geometry.warehouse_pre_1980_to_2004.osm'
363
324
  else
364
325
  geometry_file = 'Geometry.warehouse.osm'
365
326
  end
366
327
  when 'RetailStandalone'
367
- case building_vintage
368
- when 'DOE Ref Pre-1980','DOE Ref 1980-2004','DOE Ref 2004'
328
+ case template
329
+ when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004', 'DOE Ref 2004'
369
330
  geometry_file = 'Geometry.retail_standalone.pre1980_post1980.osm'
370
- when '90.1-2004','90.1-2007'
331
+ when '90.1-2004', '90.1-2007'
371
332
  geometry_file = 'Geometry.retail_standalone.2004_2007.osm'
372
- else #'90.1-2010', '90.1-2013'
333
+ else # '90.1-2010', '90.1-2013'
373
334
  geometry_file = 'Geometry.retail_standalone.2010_2013.osm'
374
335
  end
375
336
  alt_search_name = 'Retail'
@@ -377,68 +338,85 @@ class OpenStudio::Model::Model
377
338
  geometry_file = 'Geometry.retail_stripmall.osm'
378
339
  alt_search_name = 'StripMall'
379
340
  when 'QuickServiceRestaurant'
380
- case building_vintage
341
+ geometry_file = case template
381
342
  when 'DOE Ref Pre-1980'
382
- geometry_file = 'Geometry.quick_service_restaurant_pre1980.osm'
383
- else #'DOE Ref 1980-2004','90.1-2010','90.1-2007','90.1-2004','90.1-2013'
384
- geometry_file = 'Geometry.quick_service_restaurant_allothers.osm'
385
- end
343
+ 'Geometry.quick_service_restaurant_pre1980.osm'
344
+ else # 'DOE Ref 1980-2004','90.1-2010','90.1-2007','90.1-2004','90.1-2013'
345
+ 'Geometry.quick_service_restaurant_allothers.osm'
346
+ end
386
347
  when 'FullServiceRestaurant'
387
- case building_vintage
348
+ geometry_file = case template
388
349
  when 'DOE Ref Pre-1980'
389
- geometry_file = 'Geometry.full_service_restaurant_pre1980.osm'
350
+ 'Geometry.full_service_restaurant_pre1980.osm'
390
351
  else # 'DOE Ref 1980-2004','90.1-2010','90.1-2007','90.1-2004','90.1-2013'
391
- geometry_file = 'Geometry.full_service_restaurant_allothers.osm'
392
- end
352
+ 'Geometry.full_service_restaurant_allothers.osm'
353
+ end
393
354
  when 'Hospital'
394
355
  geometry_file = 'Geometry.hospital.osm'
395
356
  when 'Outpatient'
396
357
  geometry_file = 'Geometry.outpatient.osm'
397
358
  when 'MidriseApartment'
398
359
  geometry_file = 'Geometry.mid_rise_apartment.osm'
399
- when 'Office' # For NECB 2011 prototypes (old)
360
+ when 'Office' # For NECB 2011 prototypes (old)
400
361
  geometry_file = 'Geometry.large_office_2010.osm'
401
362
  alt_search_name = 'Office'
402
363
  when 'HighriseApartment'
403
364
  geometry_file = 'Geometry.high_rise_apartment.osm'
404
365
  else
405
- OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model',"Building Type = #{building_type} not recognized")
366
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "Building Type = #{building_type} not recognized")
406
367
  return false
407
368
  end
408
369
 
409
370
  # Load the geometry .osm
410
- top_dir = File.expand_path( '../../..',File.dirname(__FILE__))
411
- geom_dir = "#{top_dir}/data/geometry"
412
- self.replace_model("#{geom_dir}/#{geometry_file}")
371
+ geom_dir = "../../../data/geometry"
372
+ replace_model("#{geom_dir}/#{geometry_file}")
413
373
 
414
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding geometry')
374
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding geometry')
415
375
 
416
376
  return true
417
-
418
377
  end
419
378
 
420
379
  # Replaces all objects in the current model
421
380
  # with the objects in the .osm. Typically used to
422
381
  # load a model as a starting point.
423
382
  #
424
- # @param path_to_osm [String] the path to a .osm file.
383
+ # @param rel_path_to_osm [String] the path to an .osm file, relative to this file
425
384
  # @return [Bool] returns true if successful, false if not
426
- def replace_model(path_to_osm)
427
-
385
+ def replace_model(rel_path_to_osm)
428
386
  # Take the existing model and remove all the objects
429
387
  # (this is cheesy), but need to keep the same memory block
430
388
  handles = OpenStudio::UUIDVector.new
431
- self.objects.each {|o| handles << o.handle}
432
- self.removeObjects(handles)
433
-
434
- # Load geometry from the saved geometry.osm
435
- geom_model = safe_load_model(path_to_osm)
389
+ objects.each { |o| handles << o.handle }
390
+ removeObjects(handles)
391
+
392
+ model = nil
393
+ if File.dirname(__FILE__)[0] == ':'
394
+ # running from embedded location
395
+
396
+ # Load geometry from the saved geometry.osm
397
+ geom_model_string = load_resource_relative(rel_path_to_osm)
398
+
399
+ # version translate from string
400
+ version_translator = OpenStudio::OSVersion::VersionTranslator.new
401
+ model = version_translator.loadModelFromString(geom_model_string)
402
+ else
403
+ abs_path = File.join(File.dirname(__FILE__), rel_path_to_osm)
404
+
405
+ # version translate from string
406
+ version_translator = OpenStudio::OSVersion::VersionTranslator.new
407
+ model = version_translator.loadModel(abs_path)
408
+ end
409
+
410
+ if model.empty?
411
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "Version translation failed for #{rel_path_to_osm}")
412
+ return false
413
+ end
414
+ model = model.get
436
415
 
437
416
  # Add the objects from the geometry model to the working model
438
- self.addObjects(geom_model.toIdfFile.objects)
439
-
417
+ addObjects(model.toIdfFile.objects)
418
+
440
419
  return true
441
-
442
420
  end
443
421
 
444
422
  # Reads in a mapping between names of space types and
@@ -454,44 +432,50 @@ class OpenStudio::Model::Model
454
432
  # The hash for each building is defined inside the Prototype.building_name
455
433
  # e.g. (Prototype.secondary_school.rb) file.
456
434
  # @return [Bool] returns true if successful, false if not
457
- def assign_space_type_stubs(building_type, building_vintage, space_type_map)
458
-
435
+ def assign_space_type_stubs(building_type, template, space_type_map)
459
436
  space_type_map.each do |space_type_name, space_names|
460
437
  # Create a new space type
461
438
  stub_space_type = OpenStudio::Model::SpaceType.new(self)
462
439
  stub_space_type.setStandardsBuildingType(building_type)
463
440
  stub_space_type.setStandardsSpaceType(space_type_name)
464
441
  stub_space_type.setName("#{building_type} #{space_type_name}")
465
- stub_space_type.set_rendering_color(building_vintage)
442
+ stub_space_type.apply_rendering_color(template)
466
443
 
467
444
  space_names.each do |space_name|
468
-
469
- space = self.getSpaceByName(space_name)
470
-
445
+ space = getSpaceByName(space_name)
471
446
  next if space.empty?
472
447
  space = space.get
473
448
  space.setSpaceType(stub_space_type)
474
-
475
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', "Setting #{space.name} to #{building_type}.#{space_type_name}")
449
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', "Setting #{space.name} to #{building_type}.#{space_type_name}")
476
450
  end
477
451
  end
478
-
479
452
  return true
480
453
  end
481
454
 
482
- def assign_building_story(building_type, building_vintage, climate_zone, building_story_map)
455
+ def add_full_space_type_libs(template)
456
+ space_type_properties_list = find_objects($os_standards['space_types'], 'template' => 'NECB 2011')
457
+ space_type_properties_list.each do |space_type_property|
458
+ stub_space_type = OpenStudio::Model::SpaceType.new(self)
459
+ stub_space_type.setStandardsBuildingType(space_type_property['building_type'])
460
+ stub_space_type.setStandardsSpaceType(space_type_property['space_type'])
461
+ stub_space_type.setName("#{template}-#{space_type_property['building_type']}-#{space_type_property['space_type']}")
462
+ stub_space_type.apply_rendering_color(template)
463
+ end
464
+ add_loads(template)
465
+ end
466
+
467
+ def assign_building_story(building_type, template, climate_zone, building_story_map)
483
468
  building_story_map.each do |building_story_name, space_names|
484
469
  stub_building_story = OpenStudio::Model::BuildingStory.new(self)
485
470
  stub_building_story.setName(building_story_name)
486
471
 
487
472
  space_names.each do |space_name|
488
- space = self.getSpaceByName(space_name)
473
+ space = getSpaceByName(space_name)
489
474
  next if space.empty?
490
475
  space = space.get
491
476
  space.setBuildingStory(stub_building_story)
492
477
  end
493
478
  end
494
-
495
479
  return true
496
480
  end
497
481
 
@@ -502,34 +486,29 @@ class OpenStudio::Model::Model
502
486
  # Some loads are governed by the standard, others are typical values
503
487
  # pulled from sources such as the DOE Reference and DOE Prototype Buildings.
504
488
  #
505
- # @param building_vintage [String] the template/standard to draw data from
489
+ # @param template [String] the template to draw data from
506
490
  # @param climate_zone [String] the name of the climate zone the building is in
507
491
  # @return [Bool] returns true if successful, false if not
508
492
 
509
- def add_loads(building_vintage, climate_zone)
510
-
511
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying space types (loads)')
493
+ def add_loads(template, climate_zone = nil)
494
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying space types (loads)')
512
495
 
513
496
  # Loop through all the space types currently in the model,
514
497
  # which are placeholders, and give them appropriate loads and schedules
515
- self.getSpaceTypes.sort.each do |space_type|
516
-
498
+ getSpaceTypes.sort.each do |space_type|
517
499
  # Rendering color
518
- space_type.set_rendering_color(building_vintage)
500
+ space_type.apply_rendering_color(template)
519
501
 
520
502
  # Loads
521
- space_type.set_internal_loads(building_vintage, true, true, true, true, true, true)
503
+ space_type.apply_internal_loads(template, true, true, true, true, true, true)
522
504
 
523
505
  # Schedules
524
- space_type.set_internal_load_schedules(building_vintage, true, true, true, true, true, true, true)
525
-
526
-
506
+ space_type.apply_internal_load_schedules(template, true, true, true, true, true, true, true)
527
507
  end
528
508
 
529
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying space types (loads)')
509
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying space types (loads)')
530
510
 
531
511
  return true
532
-
533
512
  end
534
513
 
535
514
  # Adds code-minimum constructions based on the building type
@@ -539,19 +518,18 @@ class OpenStudio::Model::Model
539
518
  # to this space type, overriding the whole-building construction set.
540
519
  #
541
520
  # @param building_type [String] the type of building
542
- # @param building_vintage [String] the template/standard to draw data from
521
+ # @param template [String] the template to draw data from
543
522
  # @param climate_zone [String] the name of the climate zone the building is in
544
523
  # @return [Bool] returns true if successful, false if not
545
- def add_constructions(building_type, building_vintage, climate_zone)
546
-
547
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying constructions')
548
- is_residential = "No" #default is nonresidential for building level
524
+ def add_constructions(building_type, template, climate_zone)
525
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying constructions')
526
+ is_residential = 'No' # default is nonresidential for building level
549
527
 
550
528
  # Assign construction to adiabatic construction
551
529
  # Assign a material to all internal mass objects
552
530
  cp02_carpet_pad = OpenStudio::Model::MasslessOpaqueMaterial.new(self)
553
531
  cp02_carpet_pad.setName('CP02 CARPET PAD')
554
- cp02_carpet_pad.setRoughness("VeryRough")
532
+ cp02_carpet_pad.setRoughness('VeryRough')
555
533
  cp02_carpet_pad.setThermalResistance(0.21648)
556
534
  cp02_carpet_pad.setThermalAbsorptance(0.9)
557
535
  cp02_carpet_pad.setSolarAbsorptance(0.7)
@@ -567,7 +545,7 @@ class OpenStudio::Model::Model
567
545
 
568
546
  nonres_floor_insulation = OpenStudio::Model::MasslessOpaqueMaterial.new(self)
569
547
  nonres_floor_insulation.setName('Nonres_Floor_Insulation')
570
- nonres_floor_insulation.setRoughness("MediumSmooth")
548
+ nonres_floor_insulation.setRoughness('MediumSmooth')
571
549
  nonres_floor_insulation.setThermalResistance(2.88291975297193)
572
550
  nonres_floor_insulation.setThermalAbsorptance(0.9)
573
551
  nonres_floor_insulation.setSolarAbsorptance(0.7)
@@ -599,7 +577,7 @@ class OpenStudio::Model::Model
599
577
  wall_layers << g01_13mm_gypsum_board
600
578
  wall_adiabatic_construction.setLayers(wall_layers)
601
579
 
602
- m10_200mm_concrete_block_basement_wall= OpenStudio::Model::StandardOpaqueMaterial.new(self)
580
+ m10_200mm_concrete_block_basement_wall = OpenStudio::Model::StandardOpaqueMaterial.new(self)
603
581
  m10_200mm_concrete_block_basement_wall.setName('M10 200mm concrete block basement wall')
604
582
  m10_200mm_concrete_block_basement_wall.setRoughness('MediumRough')
605
583
  m10_200mm_concrete_block_basement_wall.setThickness(0.2032)
@@ -620,44 +598,43 @@ class OpenStudio::Model::Model
620
598
  basement_floor_layers << cp02_carpet_pad
621
599
  basement_floor_construction.setLayers(basement_floor_layers)
622
600
 
623
- self.getSurfaces.each do |surface|
624
- if surface.outsideBoundaryCondition.to_s == "Adiabatic"
625
- if surface.surfaceType.to_s == "Wall"
601
+ getSurfaces.each do |surface|
602
+ if surface.outsideBoundaryCondition.to_s == 'Adiabatic'
603
+ if surface.surfaceType.to_s == 'Wall'
626
604
  surface.setConstruction(wall_adiabatic_construction)
627
605
  else
628
606
  surface.setConstruction(floor_adiabatic_construction)
629
607
  end
630
- elsif surface.outsideBoundaryCondition.to_s == "OtherSideCoefficients"
608
+ elsif surface.outsideBoundaryCondition.to_s == 'OtherSideCoefficients'
631
609
  # Ground
632
- if surface.surfaceType.to_s == "Wall"
633
- surface.setOutsideBoundaryCondition("Ground")
610
+ if surface.surfaceType.to_s == 'Wall'
611
+ surface.setOutsideBoundaryCondition('Ground')
634
612
  surface.setConstruction(basement_wall_construction)
635
613
  else
636
- surface.setOutsideBoundaryCondition("Ground")
614
+ surface.setOutsideBoundaryCondition('Ground')
637
615
  surface.setConstruction(basement_floor_construction)
638
616
  end
639
617
  end
640
618
  end
641
619
 
642
620
  # Make the default construction set for the building
643
- bldg_def_const_set = self.add_construction_set(building_vintage, climate_zone, building_type, nil, is_residential)
621
+ bldg_def_const_set = add_construction_set(template, climate_zone, building_type, nil, is_residential)
644
622
 
645
623
  if bldg_def_const_set.is_initialized
646
- self.getBuilding.setDefaultConstructionSet(bldg_def_const_set.get)
624
+ getBuilding.setDefaultConstructionSet(bldg_def_const_set.get)
647
625
  else
648
- OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', 'Could not create default construction set for the building.')
626
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', 'Could not create default construction set for the building.')
649
627
  return false
650
628
  end
651
629
 
652
630
  # Make a construction set for each space type, if one is specified
653
- self.getSpaceTypes.each do |space_type|
654
-
631
+ getSpaceTypes.each do |space_type|
655
632
  # Get the standards building type
656
633
  stds_building_type = nil
657
634
  if space_type.standardsBuildingType.is_initialized
658
635
  stds_building_type = space_type.standardsBuildingType.get
659
636
  else
660
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', "Space type called '#{space_type.name}' has no standards building type.")
637
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', "Space type called '#{space_type.name}' has no standards building type.")
661
638
  end
662
639
 
663
640
  # Get the standards space type
@@ -665,7 +642,7 @@ class OpenStudio::Model::Model
665
642
  if space_type.standardsSpaceType.is_initialized
666
643
  stds_spc_type = space_type.standardsSpaceType.get
667
644
  else
668
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', "Space type called '#{space_type.name}' has no standards space type.")
645
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', "Space type called '#{space_type.name}' has no standards space type.")
669
646
  end
670
647
 
671
648
  # If the standards space type is Attic,
@@ -676,40 +653,39 @@ class OpenStudio::Model::Model
676
653
 
677
654
  # Attempt to make a construction set for this space type
678
655
  # and assign it if it can be created.
679
- spc_type_const_set = self.add_construction_set(building_vintage, climate_zone, stds_building_type, stds_spc_type, is_residential)
656
+ spc_type_const_set = add_construction_set(template, climate_zone, stds_building_type, stds_spc_type, is_residential)
680
657
  if spc_type_const_set.is_initialized
681
658
  space_type.setDefaultConstructionSet(spc_type_const_set.get)
682
659
  end
683
-
684
660
  end
685
661
 
686
662
  # Add construction from story level, especially for the case when there are residential and nonresidential construction in the same building
687
663
  if building_type == 'SmallHotel'
688
- self.getBuildingStorys.each do |story|
664
+ getBuildingStorys.each do |story|
689
665
  next if story.name.get == 'AtticStory'
690
666
  puts "story = #{story.name}"
691
- is_residential = "No" #default for building story level
667
+ is_residential = 'No' # default for building story level
692
668
  exterior_spaces_area = 0
693
669
  story_exterior_residential_area = 0
694
670
 
695
671
  # calculate the propotion of residential area in exterior spaces, see if this story is residential or not
696
- story::spaces.each do |space|
697
- next if space.exteriorWallArea == 0
672
+ story.spaces.each do |space|
673
+ next if space.exteriorWallArea.zero?
698
674
  space_type = space.spaceType.get
699
675
  if space_type.standardsSpaceType.is_initialized
700
676
  space_type_name = space_type.standardsSpaceType.get
701
677
  end
702
- data = self.find_object($os_standards['space_types'], {'template'=>building_vintage, 'building_type'=>building_type, 'space_type'=>space_type_name})
678
+ data = find_object($os_standards['space_types'], 'template' => template, 'building_type' => building_type, 'space_type' => space_type_name)
703
679
  exterior_spaces_area += space.floorArea
704
- story_exterior_residential_area += space.floorArea if data['is_residential'] == "Yes" # "Yes" is residential, "No" or nil is nonresidential
680
+ story_exterior_residential_area += space.floorArea if data['is_residential'] == 'Yes' # "Yes" is residential, "No" or nil is nonresidential
705
681
  end
706
- is_residential = "Yes" if story_exterior_residential_area/exterior_spaces_area >= 0.5
707
- next if is_residential == "No"
682
+ is_residential = 'Yes' if story_exterior_residential_area / exterior_spaces_area >= 0.5
683
+ next if is_residential == 'No'
708
684
 
709
685
  # if the story is identified as residential, assign residential construction set to the spaces on this story.
710
- building_story_const_set = self.add_construction_set(building_vintage, climate_zone, building_type, nil, is_residential)
686
+ building_story_const_set = add_construction_set(template, climate_zone, building_type, nil, is_residential)
711
687
  if building_story_const_set.is_initialized
712
- story::spaces.each do |space|
688
+ story.spaces.each do |space|
713
689
  space.setDefaultConstructionSet(building_story_const_set.get)
714
690
  end
715
691
  end
@@ -723,7 +699,6 @@ class OpenStudio::Model::Model
723
699
  # window_construction = sub_surface.fixedWindowConstruction.get
724
700
  # sub_surface.setSkylightConstruction(window_construction)
725
701
 
726
-
727
702
  # Assign a material to all internal mass objects
728
703
  material = OpenStudio::Model::StandardOpaqueMaterial.new(self)
729
704
  material.setName('Std Wood 6inch')
@@ -742,7 +717,7 @@ class OpenStudio::Model::Model
742
717
  construction.setLayers(layers)
743
718
 
744
719
  # Assign the internal mass construction to existing internal mass objects
745
- self.getSpaces.each do |space|
720
+ getSpaces.each do |space|
746
721
  internal_masses = space.internalMass
747
722
  internal_masses.each do |internal_mass|
748
723
  internal_mass.internalMassDefinition.setConstruction(construction)
@@ -752,21 +727,20 @@ class OpenStudio::Model::Model
752
727
  # get all the space types that are conditioned
753
728
 
754
729
  # not required for NECB 2011
755
- unless (building_vintage == 'NECB 2011')
756
- conditioned_space_names = find_conditioned_space_names(building_type, building_vintage, climate_zone)
730
+ unless template == 'NECB 2011'
731
+ conditioned_space_names = find_conditioned_space_names(building_type, template, climate_zone)
757
732
  end
758
733
 
759
-
760
734
  # add internal mass
761
735
  # not required for NECB 2011
762
- unless ((building_vintage == 'NECB 2011') or
763
- ((building_type == 'SmallHotel') &&
764
- (building_vintage == '90.1-2004' or building_vintage == '90.1-2007' or building_vintage == '90.1-2010' or building_vintage == '90.1-2013')))
736
+ unless (template == 'NECB 2011') ||
737
+ ((building_type == 'SmallHotel') &&
738
+ (template == '90.1-2004' || template == '90.1-2007' || template == '90.1-2010' || template == '90.1-2013'))
765
739
  internal_mass_def = OpenStudio::Model::InternalMassDefinition.new(self)
766
740
  internal_mass_def.setSurfaceAreaperSpaceFloorArea(2.0)
767
741
  internal_mass_def.setConstruction(construction)
768
742
  conditioned_space_names.each do |conditioned_space_name|
769
- space = self.getSpaceByName(conditioned_space_name)
743
+ space = getSpaceByName(conditioned_space_name)
770
744
  if space.is_initialized
771
745
  space = space.get
772
746
  internal_mass = OpenStudio::Model::InternalMass.new(internal_mass_def)
@@ -776,10 +750,9 @@ class OpenStudio::Model::Model
776
750
  end
777
751
  end
778
752
 
779
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying constructions')
753
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying constructions')
780
754
 
781
755
  return true
782
-
783
756
  end
784
757
 
785
758
  # Get the list of all conditioned spaces, as defined for each building in the
@@ -788,8 +761,8 @@ class OpenStudio::Model::Model
788
761
  #
789
762
  # @param (see #add_constructions)
790
763
  # @return [Array<String>] returns an array of space names as strings
791
- def find_conditioned_space_names(building_type, building_vintage, climate_zone)
792
- system_to_space_map = define_hvac_system_map(building_type, building_vintage, climate_zone)
764
+ def find_conditioned_space_names(building_type, template, climate_zone)
765
+ system_to_space_map = define_hvac_system_map(building_type, template, climate_zone)
793
766
  conditioned_space_names = OpenStudio::StringVector.new
794
767
  system_to_space_map.each do |system|
795
768
  system['space_names'].each do |space_name|
@@ -805,23 +778,25 @@ class OpenStudio::Model::Model
805
778
  #
806
779
  # @param (see #add_constructions)
807
780
  # @return [Bool] returns true if successful, false if not
808
- def create_thermal_zones(building_type,building_vintage, climate_zone)
781
+ def create_thermal_zones(building_type, template, climate_zone)
782
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started creating thermal zones')
809
783
 
810
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started creating thermal zones')
784
+ # Remove any Thermal zones assigned
785
+ getThermalZones.each(&:remove)
811
786
 
812
787
  # This map define the multipliers for spaces with multipliers not equals to 1
813
788
  case building_type
814
- when 'LargeHotel', 'MidriseApartment','LargeOffice','Hospital'
815
- space_multiplier_map = self.define_space_multiplier
789
+ when 'LargeHotel', 'MidriseApartment', 'LargeOffice', 'Hospital'
790
+ space_multiplier_map = define_space_multiplier
816
791
  else
817
- space_multiplier_map ={}
792
+ space_multiplier_map = {}
818
793
  end
819
794
 
820
795
  # Create a thermal zone for each space in the self
821
- self.getSpaces.each do |space|
796
+ getSpaces.each do |space|
822
797
  zone = OpenStudio::Model::ThermalZone.new(self)
823
798
  zone.setName("#{space.name} ZN")
824
- if space_multiplier_map[space.name.to_s] != nil
799
+ unless space_multiplier_map[space.name.to_s].nil?
825
800
  zone.setMultiplier(space_multiplier_map[space.name.to_s])
826
801
  end
827
802
  space.setThermalZone(zone)
@@ -832,19 +807,19 @@ class OpenStudio::Model::Model
832
807
  # Add a thermostat
833
808
  space_type_name = space.spaceType.get.name.get
834
809
  thermostat_name = space_type_name + ' Thermostat'
835
- thermostat = self.getThermostatSetpointDualSetpointByName(thermostat_name)
810
+ thermostat = getThermostatSetpointDualSetpointByName(thermostat_name)
836
811
  if thermostat.empty?
837
- OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', "Thermostat #{thermostat_name} not found for space name: #{space.name}")
812
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "Thermostat #{thermostat_name} not found for space name: #{space.name}")
838
813
  else
839
- thermostatClone = thermostat.get.clone(self).to_ThermostatSetpointDualSetpoint.get
840
- zone.setThermostatSetpointDualSetpoint(thermostatClone)
814
+ thermostat_clone = thermostat.get.clone(self).to_ThermostatSetpointDualSetpoint.get
815
+ zone.setThermostatSetpointDualSetpoint(thermostat_clone)
816
+ # Set Ideal loads to thermal zone for sizing.
817
+ ideal_loads = OpenStudio::Model::ZoneHVACIdealLoadsAirSystem.new(self)
818
+ ideal_loads.addToThermalZone(zone)
841
819
  end
842
820
  end
843
821
 
844
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished creating thermal zones')
845
-
846
- return true
847
-
822
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished creating thermal zones')
848
823
  end
849
824
 
850
825
  # Adds occupancy sensors to certain space types per
@@ -853,23 +828,22 @@ class OpenStudio::Model::Model
853
828
  # @param (see #add_constructions)
854
829
  # @return [Bool] returns true if successful, false if not
855
830
  # @todo genericize and move this method to Standards.Space
856
- def add_occupancy_sensors(building_type, building_vintage, climate_zone)
857
-
831
+ def add_occupancy_sensors(building_type, template, climate_zone)
858
832
  # Only add occupancy sensors for 90.1-2010
859
- case building_vintage
833
+ case template
860
834
  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004', '90.1-2004', '90.1-2007'
861
835
  return true
862
836
  end
863
837
 
864
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started Adding Occupancy Sensors')
838
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started Adding Occupancy Sensors')
865
839
 
866
840
  space_type_reduction_map = {
867
- 'SecondarySchool' => {'Classroom' => 0.32, 'Restroom' => 0.34, 'Office' => 0.22},
868
- 'PrimarySchool' => {'Classroom' => 0.32, 'Restroom' => 0.34, 'Office' => 0.22}
841
+ 'SecondarySchool' => { 'Classroom' => 0.32, 'Restroom' => 0.34, 'Office' => 0.22 },
842
+ 'PrimarySchool' => { 'Classroom' => 0.32, 'Restroom' => 0.34, 'Office' => 0.22 }
869
843
  }
870
844
 
871
845
  # Loop through all the space types and reduce lighting operation schedule fractions as-specified
872
- self.getSpaceTypes.each do |space_type|
846
+ getSpaceTypes.each do |space_type|
873
847
  # Skip space types with no standards building type
874
848
  next if space_type.standardsBuildingType.empty?
875
849
  stds_bldg_type = space_type.standardsBuildingType.get
@@ -879,8 +853,8 @@ class OpenStudio::Model::Model
879
853
  stds_spc_type = space_type.standardsSpaceType.get
880
854
 
881
855
  # Skip building types and space types that aren't listed in the hash
882
- next unless space_type_reduction_map.has_key?(stds_bldg_type)
883
- next unless space_type_reduction_map[stds_bldg_type].has_key?(stds_spc_type)
856
+ next unless space_type_reduction_map.key?(stds_bldg_type)
857
+ next unless space_type_reduction_map[stds_bldg_type].key?(stds_spc_type)
884
858
 
885
859
  # Get the reduction fraction multiplier
886
860
  red_multiplier = 1 - space_type_reduction_map[stds_bldg_type][stds_spc_type]
@@ -912,33 +886,6 @@ class OpenStudio::Model::Model
912
886
  new_lights_sch.setName("#{lights_sch_name} OccSensor Reduction")
913
887
  reduced_lights_schs[lights_sch_name] = new_lights_sch
914
888
 
915
- # Method to multiply the values in a day schedule by a specified value
916
- # but only when the existing value is higher than a specified lower limit.
917
- # This limit prevents occupancy sensors from affecting unoccupied hours.
918
- def multiply_schedule(day_sch, multiplier, limit)
919
- # Record the original times and values
920
- times = day_sch.times
921
- values = day_sch.values
922
-
923
- # Remove the original times and values
924
- day_sch.clearValues
925
-
926
- # Create new values by using the multiplier on the original values
927
- new_values = []
928
- for i in 0..(values.length - 1)
929
- if values[i] > limit
930
- new_values << values[i] * multiplier
931
- else
932
- new_values << values[i]
933
- end
934
- end
935
-
936
- # Add the revised time/value pairs to the schedule
937
- for i in 0..(new_values.length - 1)
938
- day_sch.addValue(times[i], new_values[i])
939
- end
940
- end #end reduce schedule
941
-
942
889
  # Reduce default day schedule
943
890
  multiply_schedule(new_lights_sch.defaultDaySchedule, red_multiplier, 0.25)
944
891
 
@@ -946,8 +893,7 @@ class OpenStudio::Model::Model
946
893
  new_lights_sch.scheduleRules.each do |sch_rule|
947
894
  multiply_schedule(sch_rule.daySchedule, red_multiplier, 0.25)
948
895
  end
949
-
950
- end #end of lights_sch_names.uniq.each do
896
+ end # end of lights_sch_names.uniq.each do
951
897
 
952
898
  # Loop through all lights instances, replacing old lights
953
899
  # schedules with the reduced schedules.
@@ -957,17 +903,15 @@ class OpenStudio::Model::Model
957
903
  old_lights_sch_name = light.schedule.get.name.to_s
958
904
  if reduced_lights_schs[old_lights_sch_name]
959
905
  light.setSchedule(reduced_lights_schs[old_lights_sch_name])
960
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', "Occupancy sensor reduction added to '#{light.name}'")
906
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', "Occupancy sensor reduction added to '#{light.name}'")
961
907
  end
962
908
  end
963
-
964
909
  end
965
910
 
966
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished Adding Occupancy Sensors')
911
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished Adding Occupancy Sensors')
967
912
 
968
913
  return true
969
-
970
- end #add occupancy sensors
914
+ end # add occupancy sensors
971
915
 
972
916
  # Adds exterior lights to the building, as specified
973
917
  # in OpenStudio_Standards_prototype_inputs
@@ -977,11 +921,11 @@ class OpenStudio::Model::Model
977
921
  # @todo translate w/linear foot of facade, door, parking, etc
978
922
  # into lookup table and implement that way instead of hard-coding as
979
923
  # inputs in the spreadsheet.
980
- def add_exterior_lights(building_type, building_vintage, climate_zone, prototype_input)
981
- # TODO Standards - translate w/linear foot of facade, door, parking, etc
924
+ def add_exterior_lights(building_type, template, climate_zone, prototype_input)
925
+ # TODO: Standards - translate w/linear foot of facade, door, parking, etc
982
926
  # into lookup table and implement that way instead of hard-coding as
983
927
  # inputs in the spreadsheet.
984
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started adding exterior lights')
928
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started adding exterior lights')
985
929
 
986
930
  # Occupancy Sensing Exterior Lights
987
931
  # which reduce to 70% power when no one is around.
@@ -992,7 +936,7 @@ class OpenStudio::Model::Model
992
936
  occ_sens_ext_lts_def = OpenStudio::Model::ExteriorLightsDefinition.new(self)
993
937
  occ_sens_ext_lts_def.setName("#{occ_sens_ext_lts_name} Def")
994
938
  occ_sens_ext_lts_def.setDesignLevel(occ_sens_ext_lts_power)
995
- occ_sens_ext_lts_sch = self.add_schedule(occ_sens_ext_lts_sch_name)
939
+ occ_sens_ext_lts_sch = add_schedule(occ_sens_ext_lts_sch_name)
996
940
  occ_sens_ext_lts = OpenStudio::Model::ExteriorLights.new(occ_sens_ext_lts_def, occ_sens_ext_lts_sch)
997
941
  occ_sens_ext_lts.setName("#{occ_sens_ext_lts_name} Def")
998
942
  occ_sens_ext_lts.setControlOption('AstronomicalClock')
@@ -1007,7 +951,7 @@ class OpenStudio::Model::Model
1007
951
  nondimming_ext_lts_def = OpenStudio::Model::ExteriorLightsDefinition.new(self)
1008
952
  nondimming_ext_lts_def.setName("#{nondimming_ext_lts_name} Def")
1009
953
  nondimming_ext_lts_def.setDesignLevel(nondimming_ext_lts_power)
1010
- nondimming_ext_lts_sch = self.add_schedule(nondimming_ext_lts_sch_name)
954
+ nondimming_ext_lts_sch = add_schedule(nondimming_ext_lts_sch_name)
1011
955
  nondimming_ext_lts = OpenStudio::Model::ExteriorLights.new(nondimming_ext_lts_def, nondimming_ext_lts_sch)
1012
956
  nondimming_ext_lts.setName("#{nondimming_ext_lts_name} Def")
1013
957
  nondimming_ext_lts.setControlOption('AstronomicalClock')
@@ -1023,9 +967,9 @@ class OpenStudio::Model::Model
1023
967
  fuel_ext_def = OpenStudio::Model::ExteriorLightsDefinition.new(self)
1024
968
  fuel_ext_def.setName("#{fuel_ext_name} Def")
1025
969
  fuel_ext_def.setDesignLevel(fuel_ext_power)
1026
- fuel_ext_sch = self.add_schedule(fuel_ext_sch_name)
970
+ fuel_ext_sch = add_schedule(fuel_ext_sch_name)
1027
971
  fuel_ext_lts = OpenStudio::Model::ExteriorLights.new(fuel_ext_def, fuel_ext_sch)
1028
- fuel_ext_lts.setName("#{fuel_ext_name}")
972
+ fuel_ext_lts.setName(fuel_ext_name.to_s)
1029
973
  fuel_ext_lts.setControlOption('ScheduleNameOnly')
1030
974
  end
1031
975
 
@@ -1036,16 +980,16 @@ class OpenStudio::Model::Model
1036
980
  fuel_ext_def = OpenStudio::Model::ExteriorLightsDefinition.new(self)
1037
981
  fuel_ext_def.setName("#{fuel_ext_name} Def")
1038
982
  fuel_ext_def.setDesignLevel(fuel_ext_power)
1039
- fuel_ext_sch = self.add_schedule(fuel_ext_sch_name)
983
+ fuel_ext_sch = add_schedule(fuel_ext_sch_name)
1040
984
  fuel_ext_lts = OpenStudio::Model::ExteriorLights.new(fuel_ext_def, fuel_ext_sch)
1041
- fuel_ext_lts.setName("#{fuel_ext_name}")
985
+ fuel_ext_lts.setName(fuel_ext_name.to_s)
1042
986
  fuel_ext_lts.setControlOption('ScheduleNameOnly')
1043
987
  end
1044
988
 
1045
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding exterior lights')
989
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished adding exterior lights')
1046
990
 
1047
991
  return true
1048
- end #add exterior lights
992
+ end # add exterior lights
1049
993
 
1050
994
  # Changes the infiltration coefficients for the prototype vintages.
1051
995
  #
@@ -1053,41 +997,41 @@ class OpenStudio::Model::Model
1053
997
  # @return [Bool] returns true if successful, false if not
1054
998
  # @todo Consistency - make prototype and reference vintages consistent
1055
999
  # @todo Add 90.1-2013?
1056
- def modify_infiltration_coefficients(building_type, building_vintage, climate_zone)
1000
+ def modify_infiltration_coefficients(building_type, template, climate_zone)
1057
1001
  # Select the terrain type, which
1058
1002
  # impacts wind speed, and in turn infiltration
1059
1003
  terrain = 'City'
1060
- case building_vintage
1004
+ case template
1061
1005
  when '90.1-2004', '90.1-2007', '90.1-2010', '90.1-2013'
1062
1006
  case building_type
1063
1007
  when 'Warehouse'
1064
- terrain = 'Urban'
1008
+ terrain = 'Urban'
1065
1009
  when 'SmallHotel'
1066
- terrain = 'Suburbs'
1010
+ terrain = 'Suburbs'
1067
1011
  end
1068
1012
  end
1069
1013
  # Set the terrain type
1070
- self.getSite.setTerrain(terrain)
1071
-
1072
- # modify the infiltration coefficients for 90.1-2004, 90.1-2007, 90.1-2010, 90.1-2013
1073
- return true unless building_vintage == '90.1-2004' or building_vintage == '90.1-2007' or building_vintage == '90.1-2010' or building_vintage == '90.1-2013' or building_vintage == 'NECB 2011'
1074
-
1075
- # The pre-1980 and 1980-2004 buildings have this:
1076
- # 1.0000, !- Constant Term Coefficient
1077
- # 0.0000, !- Temperature Term Coefficient
1078
- # 0.0000, !- Velocity Term Coefficient
1079
- # 0.0000; !- Velocity Squared Term Coefficient
1080
- # The 90.1-2010 buildings have this:
1081
- # 0.0000, !- Constant Term Coefficient
1082
- # 0.0000, !- Temperature Term Coefficient
1083
- # 0.224, !- Velocity Term Coefficient
1084
- # 0.0000; !- Velocity Squared Term Coefficient
1085
- self.getSpaceInfiltrationDesignFlowRates.each do |infiltration|
1086
- infiltration.setConstantTermCoefficient(0.0)
1087
- infiltration.setTemperatureTermCoefficient(0.0)
1088
- infiltration.setVelocityTermCoefficient(0.224)
1089
- infiltration.setVelocitySquaredTermCoefficient(0.0)
1090
- end
1014
+ getSite.setTerrain(terrain)
1015
+
1016
+ # modify the infiltration coefficients for 90.1-2004, 90.1-2007, 90.1-2010, 90.1-2013
1017
+ return true unless template == '90.1-2004' || template == '90.1-2007' || template == '90.1-2010' || template == '90.1-2013' || template == 'NECB 2011'
1018
+
1019
+ # The pre-1980 and 1980-2004 buildings have this:
1020
+ # 1.0000, !- Constant Term Coefficient
1021
+ # 0.0000, !- Temperature Term Coefficient
1022
+ # 0.0000, !- Velocity Term Coefficient
1023
+ # 0.0000; !- Velocity Squared Term Coefficient
1024
+ # The 90.1-2010 buildings have this:
1025
+ # 0.0000, !- Constant Term Coefficient
1026
+ # 0.0000, !- Temperature Term Coefficient
1027
+ # 0.224, !- Velocity Term Coefficient
1028
+ # 0.0000; !- Velocity Squared Term Coefficient
1029
+ getSpaceInfiltrationDesignFlowRates.each do |infiltration|
1030
+ infiltration.setConstantTermCoefficient(0.0)
1031
+ infiltration.setTemperatureTermCoefficient(0.0)
1032
+ infiltration.setVelocityTermCoefficient(0.224)
1033
+ infiltration.setVelocitySquaredTermCoefficient(0.0)
1034
+ end
1091
1035
  end
1092
1036
 
1093
1037
  # Sets the inside and outside convection algorithms for different vintages
@@ -1095,12 +1039,11 @@ class OpenStudio::Model::Model
1095
1039
  # @param (see #add_constructions)
1096
1040
  # @return [Bool] returns true if successful, false if not
1097
1041
  # @todo Consistency - make prototype and reference vintages consistent
1098
- def modify_surface_convection_algorithm(building_vintage)
1099
-
1100
- inside = self.getInsideSurfaceConvectionAlgorithm
1101
- outside = self.getOutsideSurfaceConvectionAlgorithm
1042
+ def modify_surface_convection_algorithm(template)
1043
+ inside = getInsideSurfaceConvectionAlgorithm
1044
+ outside = getOutsideSurfaceConvectionAlgorithm
1102
1045
 
1103
- case building_vintage
1046
+ case template
1104
1047
  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
1105
1048
  inside.setAlgorithm('TARP')
1106
1049
  outside.setAlgorithm('DOE-2')
@@ -1108,22 +1051,19 @@ class OpenStudio::Model::Model
1108
1051
  inside.setAlgorithm('TARP')
1109
1052
  outside.setAlgorithm('TARP')
1110
1053
  end
1111
-
1112
1054
  end
1113
1055
 
1114
-
1115
1056
  # Changes the infiltration coefficients for the prototype vintages.
1116
1057
  #
1117
1058
  # @param (see #add_constructions)
1118
1059
  # @return [Bool] returns true if successful, false if not
1119
1060
  # @todo Consistency - make sizing factors consistent
1120
1061
  # between building types, climate zones, and vintages?
1121
- def set_sizing_parameters(building_type, building_vintage)
1122
-
1062
+ def apply_sizing_parameters(building_type, template)
1123
1063
  # Default unless otherwise specified
1124
1064
  clg = 1.2
1125
1065
  htg = 1.2
1126
- case building_vintage
1066
+ case template
1127
1067
  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004'
1128
1068
  case building_type
1129
1069
  when 'PrimarySchool', 'SecondarySchool', 'Outpatient'
@@ -1144,50 +1084,55 @@ class OpenStudio::Model::Model
1144
1084
  htg = 1.3
1145
1085
  end
1146
1086
 
1147
- sizing_params = self.getSizingParameters
1087
+ sizing_params = getSizingParameters
1148
1088
  sizing_params.setHeatingSizingFactor(htg)
1149
1089
  sizing_params.setCoolingSizingFactor(clg)
1150
1090
 
1151
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.prototype.Model', "Set sizing factors to #{htg} for heating and #{clg} for cooling.")
1152
-
1091
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.prototype.Model', "Set sizing factors to #{htg} for heating and #{clg} for cooling.")
1153
1092
  end
1154
1093
 
1155
- def applyPrototypeHVACAssumptions(building_type, building_vintage, climate_zone)
1156
-
1157
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying prototype HVAC assumptions.')
1094
+ def apply_prototype_hvac_assumptions(building_type, template, climate_zone)
1095
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Started applying prototype HVAC assumptions.')
1158
1096
 
1159
1097
  ##### Apply equipment efficiencies
1160
1098
 
1161
1099
  # Fans
1162
- self.getFanConstantVolumes.sort.each {|obj| obj.setPrototypeFanPressureRise(building_type, building_vintage, climate_zone)}
1163
- self.getFanVariableVolumes.sort.each {|obj| obj.setPrototypeFanPressureRise(building_type, building_vintage, climate_zone)}
1164
- self.getFanOnOffs.sort.each {|obj| obj.setPrototypeFanPressureRise(building_type, building_vintage, climate_zone)}
1165
- self.getFanZoneExhausts.sort.each {|obj| obj.setPrototypeFanPressureRise}
1100
+ # Pressure Rise
1101
+ getFanConstantVolumes.sort.each { |obj| obj.apply_prototype_fan_pressure_rise(building_type, template, climate_zone) }
1102
+ getFanVariableVolumes.sort.each { |obj| obj.apply_prototype_fan_pressure_rise(building_type, template, climate_zone) }
1103
+ getFanOnOffs.sort.each { |obj| obj.apply_prototype_fan_pressure_rise(building_type, template, climate_zone) }
1104
+ getFanZoneExhausts.sort.each(&:apply_prototype_fan_pressure_rise)
1105
+
1106
+ # Motor Efficiency
1107
+ getFanConstantVolumes.sort.each { |obj| obj.apply_prototype_fan_efficiency(template) }
1108
+ getFanVariableVolumes.sort.each { |obj| obj.apply_prototype_fan_efficiency(template) }
1109
+ getFanOnOffs.sort.each { |obj| obj.apply_prototype_fan_efficiency(template) }
1110
+ getFanZoneExhausts.sort.each { |obj| obj.apply_prototype_fan_efficiency(template) }
1166
1111
 
1167
1112
  ##### Add Economizers
1168
1113
 
1169
- if (building_vintage != 'NECB 2011') then
1114
+ if template != 'NECB 2011'
1170
1115
  # Create an economizer maximum OA fraction of 70%
1171
1116
  # to reflect damper leakage per PNNL
1172
1117
  econ_max_70_pct_oa_sch = OpenStudio::Model::ScheduleRuleset.new(self)
1173
- econ_max_70_pct_oa_sch.setName("Economizer Max OA Fraction 70 pct")
1174
- econ_max_70_pct_oa_sch.defaultDaySchedule.setName("Economizer Max OA Fraction 70 pct Default")
1175
- econ_max_70_pct_oa_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0), 0.7)
1118
+ econ_max_70_pct_oa_sch.setName('Economizer Max OA Fraction 70 pct')
1119
+ econ_max_70_pct_oa_sch.defaultDaySchedule.setName('Economizer Max OA Fraction 70 pct Default')
1120
+ econ_max_70_pct_oa_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 0.7)
1176
1121
  else
1177
1122
  # NECB 2011 prescribes ability to provide 100% OA (5.2.2.7-5.2.2.9)
1178
1123
  econ_max_100_pct_oa_sch = OpenStudio::Model::ScheduleRuleset.new(self)
1179
- econ_max_100_pct_oa_sch.setName("Economizer Max OA Fraction 100 pct")
1180
- econ_max_100_pct_oa_sch.defaultDaySchedule.setName("Economizer Max OA Fraction 100 pct Default")
1181
- econ_max_100_pct_oa_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0,24,0,0), 1.0)
1124
+ econ_max_100_pct_oa_sch.setName('Economizer Max OA Fraction 100 pct')
1125
+ econ_max_100_pct_oa_sch.defaultDaySchedule.setName('Economizer Max OA Fraction 100 pct Default')
1126
+ econ_max_100_pct_oa_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 1.0)
1182
1127
  end
1183
1128
 
1184
1129
  # Check each airloop
1185
- self.getAirLoopHVACs.each do |air_loop|
1186
- if air_loop.is_economizer_required(building_vintage, climate_zone) == true
1130
+ getAirLoopHVACs.each do |air_loop|
1131
+ if air_loop.economizer_required?(template, climate_zone) == true
1187
1132
  # If an economizer is required, determine the economizer type
1188
1133
  # in the prototype buildings, which depends on climate zone.
1189
1134
  economizer_type = nil
1190
- case building_vintage
1135
+ case template
1191
1136
  when 'DOE Ref Pre-1980', 'DOE Ref 1980-2004', '90.1-2004', '90.1-2007'
1192
1137
  economizer_type = 'DifferentialDryBulb'
1193
1138
  when '90.1-2010', '90.1-2013'
@@ -1213,37 +1158,33 @@ class OpenStudio::Model::Model
1213
1158
  if oa_sys.is_initialized
1214
1159
  oa_sys = oa_sys.get
1215
1160
  else
1216
- OpenStudio::logFree(OpenStudio::Error, "openstudio.prototype.Model", "#{air_loop.name} is required to have an economizer, but it has no OA system.")
1161
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.prototype.Model', "#{air_loop.name} is required to have an economizer, but it has no OA system.")
1217
1162
  next
1218
1163
  end
1219
1164
  oa_control = oa_sys.getControllerOutdoorAir
1220
1165
  oa_control.setEconomizerControlType(economizer_type)
1221
- if (building_vintage != 'NECB 2011') then
1222
- #oa_control.setMaximumFractionofOutdoorAirSchedule(econ_max_70_pct_oa_sch)
1223
- else
1224
- #oa_control.setMaximumFractionofOutdoorAirSchedule(econ_max_100_pct_oa_sch)
1166
+ if template != 'NECB 2011'
1167
+ # oa_control.setMaximumFractionofOutdoorAirSchedule(econ_max_70_pct_oa_sch)
1225
1168
  end
1226
1169
 
1227
1170
  # Check that the economizer type set by the prototypes
1228
1171
  # is not prohibited by code. If it is, change to no economizer.
1229
- unless air_loop.is_economizer_type_allowable(building_vintage, climate_zone)
1230
- OpenStudio::logFree(OpenStudio::Warn, "openstudio.prototype.Model", "#{air_loop.name} is required to have an economizer, but the type chosen, #{economizer_type} is prohibited by code for #{building_vintage}, climate zone #{climate_zone}. Economizer type will be switched to No Economizer.")
1172
+ unless air_loop.economizer_type_allowable?(template, climate_zone)
1173
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.prototype.Model', "#{air_loop.name} is required to have an economizer, but the type chosen, #{economizer_type} is prohibited by code for #{template}, climate zone #{climate_zone}. Economizer type will be switched to No Economizer.")
1231
1174
  oa_control.setEconomizerControlType('NoEconomizer')
1232
1175
  end
1233
1176
 
1234
1177
  end
1235
1178
  end
1236
1179
 
1237
- # TODO What is the logic behind hard-sizing
1180
+ # TODO: What is the logic behind hard-sizing
1238
1181
  # hot water coil convergence tolerances?
1239
- self.getControllerWaterCoils.sort.each {|obj| obj.set_convergence_limits}
1240
-
1241
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying prototype HVAC assumptions.')
1182
+ getControllerWaterCoils.sort.each(&:set_convergence_limits)
1242
1183
 
1184
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', 'Finished applying prototype HVAC assumptions.')
1243
1185
  end
1244
1186
 
1245
1187
  def add_debugging_variables(type)
1246
-
1247
1188
  # 'detailed'
1248
1189
  # 'timestep'
1249
1190
  # 'hourly'
@@ -1253,44 +1194,41 @@ class OpenStudio::Model::Model
1253
1194
  vars = []
1254
1195
  case type
1255
1196
  when 'service_water_heating'
1256
- var_names << ['Water Heater Water Volume Flow Rate','timestep']
1257
- var_names << ['Water Use Equipment Hot Water Volume Flow Rate','timestep']
1258
- var_names << ['Water Use Equipment Cold Water Volume Flow Rate','timestep']
1259
- var_names << ['Water Use Equipment Hot Water Temperature','timestep']
1260
- var_names << ['Water Use Equipment Cold Water Temperature','timestep']
1261
- var_names << ['Water Use Equipment Mains Water Volume','timestep']
1262
- var_names << ['Water Use Equipment Target Water Temperature','timestep']
1263
- var_names << ['Water Use Equipment Mixed Water Temperature','timestep']
1264
- var_names << ['Water Heater Tank Temperature','timestep']
1265
- var_names << ['Water Heater Use Side Mass Flow Rate','timestep']
1266
- var_names << ['Water Heater Heating Rate','timestep']
1267
- var_names << ['Water Heater Water Volume Flow Rate','timestep']
1268
- var_names << ['Water Heater Water Volume','timestep']
1197
+ var_names << ['Water Heater Water Volume Flow Rate', 'timestep']
1198
+ var_names << ['Water Use Equipment Hot Water Volume Flow Rate', 'timestep']
1199
+ var_names << ['Water Use Equipment Cold Water Volume Flow Rate', 'timestep']
1200
+ var_names << ['Water Use Equipment Hot Water Temperature', 'timestep']
1201
+ var_names << ['Water Use Equipment Cold Water Temperature', 'timestep']
1202
+ var_names << ['Water Use Equipment Mains Water Volume', 'timestep']
1203
+ var_names << ['Water Use Equipment Target Water Temperature', 'timestep']
1204
+ var_names << ['Water Use Equipment Mixed Water Temperature', 'timestep']
1205
+ var_names << ['Water Heater Tank Temperature', 'timestep']
1206
+ var_names << ['Water Heater Use Side Mass Flow Rate', 'timestep']
1207
+ var_names << ['Water Heater Heating Rate', 'timestep']
1208
+ var_names << ['Water Heater Water Volume Flow Rate', 'timestep']
1209
+ var_names << ['Water Heater Water Volume', 'timestep']
1269
1210
  end
1270
1211
 
1271
1212
  var_names.each do |var_name, reporting_frequency|
1272
- outputVariable = OpenStudio::Model::OutputVariable.new(var_name,self)
1273
- outputVariable.setReportingFrequency(reporting_frequency)
1213
+ output_var = OpenStudio::Model::OutputVariable.new(var_name, self)
1214
+ output_var.setReportingFrequency(reporting_frequency)
1274
1215
  end
1275
-
1276
-
1277
1216
  end
1278
1217
 
1279
1218
  def run(run_dir = "#{Dir.pwd}/Run")
1280
-
1281
1219
  # If the run directory is not specified
1282
1220
  # run in the current working directory
1283
1221
 
1284
1222
  # Make the directory if it doesn't exist
1285
- if !Dir.exists?(run_dir)
1223
+ unless Dir.exist?(run_dir)
1286
1224
  Dir.mkdir(run_dir)
1287
1225
  end
1288
1226
 
1289
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', "Started simulation in '#{run_dir}'")
1227
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', "Started simulation in '#{run_dir}'")
1290
1228
 
1291
1229
  # Change the simulation to only run the weather file
1292
1230
  # and not run the sizing day simulations
1293
- sim_control = self.getSimulationControl
1231
+ sim_control = getSimulationControl
1294
1232
  sim_control.setRunSimulationforSizingPeriods(false)
1295
1233
  sim_control.setRunSimulationforWeatherFileRunPeriods(true)
1296
1234
 
@@ -1301,34 +1239,34 @@ class OpenStudio::Model::Model
1301
1239
  idf = forward_translator.translateModel(self)
1302
1240
  idf_path = OpenStudio::Path.new("#{run_dir}/#{idf_name}")
1303
1241
  osm_path = OpenStudio::Path.new("#{run_dir}/#{osm_name}")
1304
- idf.save(idf_path,true)
1305
- self.save(osm_path,true)
1242
+ idf.save(idf_path, true)
1243
+ save(osm_path, true)
1306
1244
 
1307
1245
  # Set up the sizing simulation
1308
1246
  # Find the weather file
1309
1247
  epw_path = nil
1310
- if self.weatherFile.is_initialized
1311
- epw_path = self.weatherFile.get.path
1248
+ if weatherFile.is_initialized
1249
+ epw_path = weatherFile.get.path
1312
1250
  if epw_path.is_initialized
1313
1251
  if File.exist?(epw_path.get.to_s)
1314
1252
  epw_path = epw_path.get
1315
1253
  else
1316
1254
  # If this is an always-run Measure, need to check a different path
1317
- alt_weath_path = File.expand_path(File.join(File.dirname(__FILE__), "../../../resources"))
1255
+ alt_weath_path = File.expand_path(File.join(File.dirname(__FILE__), '../../../resources'))
1318
1256
  alt_epw_path = File.expand_path(File.join(alt_weath_path, epw_path.get.to_s))
1319
1257
  if File.exist?(alt_epw_path)
1320
1258
  epw_path = OpenStudio::Path.new(alt_epw_path)
1321
1259
  else
1322
- OpenStudio::logFree(OpenStudio::Error, "openstudio.prototype.Model", "Model has been assigned a weather file, but the file is not in the specified location of '#{epw_path.get}'.")
1260
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.prototype.Model', "Model has been assigned a weather file, but the file is not in the specified location of '#{epw_path.get}'.")
1323
1261
  return false
1324
1262
  end
1325
1263
  end
1326
1264
  else
1327
- OpenStudio::logFree(OpenStudio::Error, "openstudio.prototype.Model", "Model has a weather file assigned, but the weather file path has been deleted.")
1265
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.prototype.Model', 'Model has a weather file assigned, but the weather file path has been deleted.')
1328
1266
  return false
1329
1267
  end
1330
1268
  else
1331
- OpenStudio::logFree(OpenStudio::Error, "openstudio.prototype.Model", "Model has not been assigned a weather file.3")
1269
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.prototype.Model', 'Model has not been assigned a weather file.3')
1332
1270
  return false
1333
1271
  end
1334
1272
 
@@ -1346,38 +1284,38 @@ class OpenStudio::Model::Model
1346
1284
 
1347
1285
  sql_path = nil
1348
1286
  if use_runmanager == true
1349
- OpenStudio::logFree(OpenStudio::Info, "openstudio.prototype.Model", "Running sizing run with RunManager.")
1287
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.prototype.Model', 'Running sizing run with RunManager.')
1350
1288
 
1351
1289
  # Find EnergyPlus
1352
1290
  ep_dir = OpenStudio.getEnergyPlusDirectory
1353
1291
  ep_path = OpenStudio.getEnergyPlusExecutable
1354
1292
  ep_tool = OpenStudio::Runmanager::ToolInfo.new(ep_path)
1355
- idd_path = OpenStudio::Path.new(ep_dir.to_s + "/Energy+.idd")
1293
+ idd_path = OpenStudio::Path.new(ep_dir.to_s + '/Energy+.idd')
1356
1294
  output_path = OpenStudio::Path.new("#{run_dir}/")
1357
1295
 
1358
1296
  # Make a run manager and queue up the sizing run
1359
1297
  run_manager_db_path = OpenStudio::Path.new("#{run_dir}/run.db")
1360
1298
  run_manager = OpenStudio::Runmanager::RunManager.new(run_manager_db_path, true, false, false, false)
1361
- job = OpenStudio::Runmanager::JobFactory::createEnergyPlusJob(ep_tool,
1362
- idd_path,
1363
- idf_path,
1364
- epw_path,
1365
- output_path)
1299
+ job = OpenStudio::Runmanager::JobFactory.createEnergyPlusJob(ep_tool,
1300
+ idd_path,
1301
+ idf_path,
1302
+ epw_path,
1303
+ output_path)
1366
1304
 
1367
1305
  run_manager.enqueue(job, true)
1368
1306
 
1369
1307
  # Start the sizing run and wait for it to finish.
1370
1308
  while run_manager.workPending
1371
1309
  sleep 1
1372
- OpenStudio::Application::instance.processEvents
1310
+ OpenStudio::Application.instance.processEvents
1373
1311
  end
1374
1312
 
1375
1313
  sql_path = OpenStudio::Path.new("#{run_dir}/Energyplus/eplusout.sql")
1376
1314
 
1377
- OpenStudio::logFree(OpenStudio::Info, "openstudio.prototype.Model", "Finished sizing run in #{(Time.new - start_time).round}sec.")
1315
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.prototype.Model', "Finished sizing run in #{(Time.new - start_time).round}sec.")
1378
1316
 
1379
1317
  else # Use the openstudio-workflow gem
1380
- OpenStudio::logFree(OpenStudio::Info, "openstudio.prototype.Model", "Running sizing run with openstudio-workflow gem.")
1318
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.prototype.Model', 'Running sizing run with openstudio-workflow gem.')
1381
1319
 
1382
1320
  # Copy the weather file to this directory
1383
1321
  FileUtils.copy(epw_path.to_s, run_dir)
@@ -1387,7 +1325,7 @@ class OpenStudio::Model::Model
1387
1325
  final_state = sim.run
1388
1326
 
1389
1327
  if final_state == :finished
1390
- OpenStudio::logFree(OpenStudio::Info, "openstudio.prototype.Model", "Finished sizing run in #{(Time.new - start_time).round}sec.")
1328
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.prototype.Model', "Finished sizing run in #{(Time.new - start_time).round}sec.")
1391
1329
  end
1392
1330
 
1393
1331
  sql_path = OpenStudio::Path.new("#{run_dir}/run/eplusout.sql")
@@ -1396,18 +1334,18 @@ class OpenStudio::Model::Model
1396
1334
 
1397
1335
  # Load the sql file created by the sizing run
1398
1336
  sql_path = OpenStudio::Path.new("#{run_dir}/Energyplus/eplusout.sql")
1399
- if OpenStudio::exists(sql_path)
1337
+ if OpenStudio.exists(sql_path)
1400
1338
  sql = OpenStudio::SqlFile.new(sql_path)
1401
1339
  # Check to make sure the sql file is readable,
1402
1340
  # which won't be true if EnergyPlus crashed during simulation.
1403
- if !sql.connectionOpen
1404
- OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', "The run failed. Look at the eplusout.err file in #{File.dirname(sql_path.to_s)} to see the cause.")
1341
+ unless sql.connectionOpen
1342
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "The run failed. Look at the eplusout.err file in #{File.dirname(sql_path.to_s)} to see the cause.")
1405
1343
  return false
1406
1344
  end
1407
1345
  # Attach the sql file from the run to the sizing model
1408
- self.setSqlFile(sql)
1346
+ setSqlFile(sql)
1409
1347
  else
1410
- OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', "Results for the sizing run couldn't be found here: #{sql_path}.")
1348
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "Results for the sizing run couldn't be found here: #{sql_path}.")
1411
1349
  return false
1412
1350
  end
1413
1351
 
@@ -1416,24 +1354,22 @@ class OpenStudio::Model::Model
1416
1354
  FROM Errors
1417
1355
  WHERE ErrorType='1'"
1418
1356
 
1419
- errs = self.sqlFile.get.execAndReturnVectorOfString(error_query)
1357
+ errs = sqlFile.get.execAndReturnVectorOfString(error_query)
1420
1358
  if errs.is_initialized
1421
1359
  errs = errs.get
1422
- if errs.size > 0
1360
+ unless errs.empty?
1423
1361
  errs = errs.get
1424
- OpenStudio::logFree(OpenStudio::Error, 'openstudio.model.Model', "The run failed with the following severe errors: #{errs.join('\n')}.")
1362
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.model.Model', "The run failed with the following severe errors: #{errs.join('\n')}.")
1425
1363
  return false
1426
1364
  end
1427
1365
  end
1428
1366
 
1429
- OpenStudio::logFree(OpenStudio::Info, 'openstudio.model.Model', "Finished simulation in '#{run_dir}'")
1367
+ OpenStudio.logFree(OpenStudio::Info, 'openstudio.model.Model', "Finished simulation in '#{run_dir}'")
1430
1368
 
1431
1369
  return true
1432
-
1433
1370
  end
1434
1371
 
1435
1372
  def request_timeseries_outputs
1436
-
1437
1373
  # "detailed"
1438
1374
  # "timestep"
1439
1375
  # "hourly"
@@ -1478,14 +1414,14 @@ class OpenStudio::Model::Model
1478
1414
  # vars << ['Air System Mixed Air Mass Flow Rate','timestep']
1479
1415
 
1480
1416
  # vars << ['Heating Coil Gas Rate','timestep']
1481
- vars << ['Boiler Part Load Ratio','timestep']
1482
- vars << ['Boiler Gas Rate','timestep']
1417
+ vars << ['Boiler Part Load Ratio', 'timestep']
1418
+ vars << ['Boiler Gas Rate', 'timestep']
1483
1419
  # vars << ['Boiler Gas Rate','timestep']
1484
1420
  # vars << ['Fan Electric Power','timestep']
1485
1421
 
1486
- vars << ['Pump Electric Power','timestep']
1487
- vars << ['Pump Outlet Temperature','timestep']
1488
- vars << ['Pump Mass Flow Rate','timestep']
1422
+ vars << ['Pump Electric Power', 'timestep']
1423
+ vars << ['Pump Outlet Temperature', 'timestep']
1424
+ vars << ['Pump Mass Flow Rate', 'timestep']
1489
1425
 
1490
1426
  # vars << ['Zone Air Terminal VAV Damper Position','timestep']
1491
1427
  # vars << ['Zone Air Terminal Minimum Air Flow Fraction','timestep']
@@ -1495,10 +1431,129 @@ class OpenStudio::Model::Model
1495
1431
  # vars << ['Schedule Value','hourly']
1496
1432
 
1497
1433
  vars.each do |var, freq|
1498
- outputVariable = OpenStudio::Model::OutputVariable.new(var, self)
1499
- outputVariable.setReportingFrequency(freq)
1434
+ output_var = OpenStudio::Model::OutputVariable.new(var, self)
1435
+ output_var.setReportingFrequency(freq)
1500
1436
  end
1437
+ end
1501
1438
 
1439
+ def clear_and_set_example_constructions
1440
+ # Define Materials
1441
+ name = 'opaque material'
1442
+ thickness = 0.012700
1443
+ conductivity = 0.160000
1444
+ opaque_mat = BTAP::Resources::Envelope::Materials::Opaque.create_opaque_material(self, name, thickness, conductivity)
1445
+
1446
+ name = 'insulation material'
1447
+ thickness = 0.050000
1448
+ conductivity = 0.043000
1449
+ insulation_mat = BTAP::Resources::Envelope::Materials::Opaque.create_opaque_material(self, name, thickness, conductivity)
1450
+
1451
+ name = 'simple glazing test'
1452
+ shgc = 0.250000
1453
+ ufactor = 3.236460
1454
+ thickness = 0.003000
1455
+ visible_transmittance = 0.160000
1456
+ simple_glazing_mat = BTAP::Resources::Envelope::Materials::Fenestration.create_simple_glazing(self, name, shgc, ufactor, thickness, visible_transmittance)
1457
+
1458
+ name = 'Standard Glazing Test'
1459
+ thickness = 0.003
1460
+ conductivity = 0.9
1461
+ solar_trans_normal = 0.84
1462
+ front_solar_ref_normal = 0.075
1463
+ back_solar_ref_normal = 0.075
1464
+ vlt = 0.9
1465
+ front_vis_ref_normal = 0.081
1466
+ back_vis_ref_normal = 0.081
1467
+ ir_trans_normal = 0.0
1468
+ front_ir_emis = 0.84
1469
+ back_ir_emis = 0.84
1470
+ optical_data_type = 'SpectralAverage'
1471
+ dirt_correction_factor = 1.0
1472
+ is_solar_diffusing = false
1473
+
1474
+ standard_glazing_mat = BTAP::Resources::Envelope::Materials::Fenestration.create_standard_glazing(self,
1475
+ name,
1476
+ thickness,
1477
+ conductivity,
1478
+ solar_trans_normal,
1479
+ front_solar_ref_normal,
1480
+ back_solar_ref_normal, vlt,
1481
+ front_vis_ref_normal,
1482
+ back_vis_ref_normal,
1483
+ ir_trans_normal,
1484
+ front_ir_emis,
1485
+ back_ir_emis,
1486
+ optical_data_type,
1487
+ dirt_correction_factor,
1488
+ is_solar_diffusing)
1489
+
1490
+ # Define Constructions
1491
+ # # Surfaces
1492
+ ext_wall = BTAP::Resources::Envelope::Constructions.create_construction(self, 'OpaqueConstructionExtWall', [opaque_mat, insulation_mat], insulation_mat)
1493
+ ext_roof = BTAP::Resources::Envelope::Constructions.create_construction(self, 'OpaqueConstructionExtRoof', [opaque_mat, insulation_mat], insulation_mat)
1494
+ ext_floor = BTAP::Resources::Envelope::Constructions.create_construction(self, 'OpaqueConstructionExtFloor', [opaque_mat, insulation_mat], insulation_mat)
1495
+ grnd_wall = BTAP::Resources::Envelope::Constructions.create_construction(self, 'OpaqueConstructionGrndWall', [opaque_mat, insulation_mat], insulation_mat)
1496
+ grnd_roof = BTAP::Resources::Envelope::Constructions.create_construction(self, 'OpaqueConstructionGrndRoof', [opaque_mat, insulation_mat], insulation_mat)
1497
+ grnd_floor = BTAP::Resources::Envelope::Constructions.create_construction(self, 'OpaqueConstructionGrndFloor', [opaque_mat, insulation_mat], insulation_mat)
1498
+ int_wall = BTAP::Resources::Envelope::Constructions.create_construction(self, 'OpaqueConstructionIntWall', [opaque_mat, insulation_mat], insulation_mat)
1499
+ int_roof = BTAP::Resources::Envelope::Constructions.create_construction(self, 'OpaqueConstructionIntRoof', [opaque_mat, insulation_mat], insulation_mat)
1500
+ int_floor = BTAP::Resources::Envelope::Constructions.create_construction(self, 'OpaqueConstructionIntFloor', [opaque_mat, insulation_mat], insulation_mat)
1501
+ # # Subsurfaces
1502
+ fixed_window = BTAP::Resources::Envelope::Constructions.create_construction(self, 'FenestrationConstructionFixed', [simple_glazing_mat])
1503
+ operable_window = BTAP::Resources::Envelope::Constructions.create_construction(self, 'FenestrationConstructionOperable', [simple_glazing_mat])
1504
+ glass_door = BTAP::Resources::Envelope::Constructions.create_construction(self, 'FenestrationConstructionDoor', [standard_glazing_mat])
1505
+ door = BTAP::Resources::Envelope::Constructions.create_construction(self, 'OpaqueConstructionDoor', [opaque_mat, insulation_mat], insulation_mat)
1506
+ overhead_door = BTAP::Resources::Envelope::Constructions.create_construction(self, 'OpaqueConstructionOverheadDoor', [opaque_mat, insulation_mat], insulation_mat)
1507
+ skylt = BTAP::Resources::Envelope::Constructions.create_construction(self, 'FenestrationConstructionSkylight', [standard_glazing_mat])
1508
+ daylt_dome = BTAP::Resources::Envelope::Constructions.create_construction(self, 'FenestrationConstructionDomeConstruction', [standard_glazing_mat])
1509
+ daylt_diffuser = BTAP::Resources::Envelope::Constructions.create_construction(self, 'FenestrationConstructionDiffuserConstruction', [standard_glazing_mat])
1510
+
1511
+ # Define Construction Sets
1512
+ # # Surface
1513
+ exterior_construction_set = BTAP::Resources::Envelope::ConstructionSets.create_default_surface_constructions(self, 'ExteriorSet', ext_wall, ext_roof, ext_floor)
1514
+ interior_construction_set = BTAP::Resources::Envelope::ConstructionSets.create_default_surface_constructions(self, 'InteriorSet', int_wall, int_roof, int_floor)
1515
+ ground_construction_set = BTAP::Resources::Envelope::ConstructionSets.create_default_surface_constructions(self, 'GroundSet', grnd_wall, grnd_roof, grnd_floor)
1516
+
1517
+ # # Subsurface
1518
+ subsurface_exterior_construction_set = BTAP::Resources::Envelope::ConstructionSets.create_subsurface_construction_set(self, fixed_window, operable_window, door, glass_door, overhead_door, skylt, daylt_dome, daylt_diffuser)
1519
+ subsurface_interior_construction_set = BTAP::Resources::Envelope::ConstructionSets.create_subsurface_construction_set(self, fixed_window, operable_window, door, glass_door, overhead_door, skylt, daylt_dome, daylt_diffuser)
1520
+
1521
+ # Define default construction sets.
1522
+ name = 'Construction Set 1'
1523
+ default_construction_set = BTAP::Resources::Envelope::ConstructionSets.create_default_construction_set(self, name, exterior_construction_set, interior_construction_set, ground_construction_set, subsurface_exterior_construction_set, subsurface_interior_construction_set)
1524
+
1525
+ # Assign default to the model.
1526
+ getBuilding.setDefaultConstructionSet(default_construction_set)
1527
+
1528
+ return default_construction_set
1502
1529
  end
1503
1530
 
1531
+ private
1532
+
1533
+ # Method to multiply the values in a day schedule by a specified value
1534
+ # but only when the existing value is higher than a specified lower limit.
1535
+ # This limit prevents occupancy sensors from affecting unoccupied hours.
1536
+ def multiply_schedule(day_sch, multiplier, limit)
1537
+ # Record the original times and values
1538
+ times = day_sch.times
1539
+ values = day_sch.values
1540
+
1541
+ # Remove the original times and values
1542
+ day_sch.clearValues
1543
+
1544
+ # Create new values by using the multiplier on the original values
1545
+ new_values = []
1546
+ values.each do |value|
1547
+ new_values << if value > limit
1548
+ value * multiplier
1549
+ else
1550
+ value
1551
+ end
1552
+ end
1553
+
1554
+ # Add the revised time/value pairs to the schedule
1555
+ new_values.each_with_index do |new_value, i|
1556
+ day_sch.addValue(times[i], new_value)
1557
+ end
1558
+ end # end reduce schedule
1504
1559
  end