openstudio-extension 0.7.1 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +14 -0
  4. data/LICENSE.md +1 -1
  5. data/README.md +2 -0
  6. data/lib/openstudio/extension/runner.rb +12 -8
  7. data/lib/openstudio/extension/runner_config.rb +33 -6
  8. data/lib/openstudio/extension/version.rb +1 -1
  9. data/openstudio-extension.gemspec +6 -6
  10. metadata +15 -66
  11. data/lib/openstudio/extension/core/CreateResults.rb +0 -1033
  12. data/lib/openstudio/extension/core/check_air_sys_temps.rb +0 -160
  13. data/lib/openstudio/extension/core/check_calibration.rb +0 -125
  14. data/lib/openstudio/extension/core/check_cond_zns.rb +0 -54
  15. data/lib/openstudio/extension/core/check_domestic_hot_water.rb +0 -304
  16. data/lib/openstudio/extension/core/check_envelope_conductance.rb +0 -423
  17. data/lib/openstudio/extension/core/check_eui_by_end_use.rb +0 -132
  18. data/lib/openstudio/extension/core/check_eui_reasonableness.rb +0 -105
  19. data/lib/openstudio/extension/core/check_fan_pwr.rb +0 -68
  20. data/lib/openstudio/extension/core/check_internal_loads.rb +0 -363
  21. data/lib/openstudio/extension/core/check_mech_sys_capacity.rb +0 -196
  22. data/lib/openstudio/extension/core/check_mech_sys_efficiency.rb +0 -296
  23. data/lib/openstudio/extension/core/check_mech_sys_part_load_eff.rb +0 -434
  24. data/lib/openstudio/extension/core/check_mech_sys_type.rb +0 -109
  25. data/lib/openstudio/extension/core/check_part_loads.rb +0 -421
  26. data/lib/openstudio/extension/core/check_placeholder.rb +0 -45
  27. data/lib/openstudio/extension/core/check_plant_cap.rb +0 -93
  28. data/lib/openstudio/extension/core/check_plant_temps.rb +0 -129
  29. data/lib/openstudio/extension/core/check_plenum_loads.rb +0 -57
  30. data/lib/openstudio/extension/core/check_pump_pwr.rb +0 -78
  31. data/lib/openstudio/extension/core/check_sch_coord.rb +0 -211
  32. data/lib/openstudio/extension/core/check_schedules.rb +0 -281
  33. data/lib/openstudio/extension/core/check_simultaneous_heating_and_cooling.rb +0 -128
  34. data/lib/openstudio/extension/core/check_supply_air_and_thermostat_temp_difference.rb +0 -118
  35. data/lib/openstudio/extension/core/check_weather_files.rb +0 -102
  36. data/lib/openstudio/extension/core/deer_vintages.rb +0 -281
  37. data/lib/openstudio/extension/core/os_lib_aedg_measures.rb +0 -461
  38. data/lib/openstudio/extension/core/os_lib_constructions.rb +0 -353
  39. data/lib/openstudio/extension/core/os_lib_geometry.rb +0 -1169
  40. data/lib/openstudio/extension/core/os_lib_helper_methods.rb +0 -383
  41. data/lib/openstudio/extension/core/os_lib_hvac.rb +0 -2163
  42. data/lib/openstudio/extension/core/os_lib_lighting_and_equipment.rb +0 -184
  43. data/lib/openstudio/extension/core/os_lib_model_generation.rb +0 -3584
  44. data/lib/openstudio/extension/core/os_lib_model_simplification.rb +0 -1019
  45. data/lib/openstudio/extension/core/os_lib_outdoorair_and_infiltration.rb +0 -135
  46. data/lib/openstudio/extension/core/os_lib_reporting_qaqc.rb +0 -170
  47. data/lib/openstudio/extension/core/os_lib_schedules.rb +0 -933
@@ -1,353 +0,0 @@
1
- # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
- # See also https://openstudio.net/license
4
- # *******************************************************************************
5
-
6
- module OsLib_Constructions
7
- # infer insulation layer from a construction
8
- def self.inferInsulationLayer(construction, minThermalResistance)
9
- construction_layers = construction.layers
10
- counter = 0
11
- max_resistance = 0
12
- thermal_resistance_array = []
13
-
14
- # loop through construction layers and infer insulation layer/material
15
- construction_layers.each do |construction_layer|
16
- construction_thermal_resistance = construction_layer.to_OpaqueMaterial.get.thermalResistance
17
- if !thermal_resistance_array.empty?
18
- if construction_thermal_resistance > max_resistance
19
- thermal_resistance_array = [construction_layer, counter, construction_thermal_resistance]
20
- max_resistance = construction_thermal_resistance
21
- end
22
- else
23
- thermal_resistance_array = [construction_layer, counter, construction_thermal_resistance]
24
- end
25
- counter += 1
26
- end
27
-
28
- # test against minimum
29
- if max_resistance > minThermalResistance
30
- minTestPass = true
31
- else
32
- minTestPass = false
33
- end
34
-
35
- result = {
36
- 'construction' => construction,
37
- 'construction_layer' => thermal_resistance_array[0],
38
- 'layer_index' => thermal_resistance_array[1],
39
- 'construction_thermal_resistance' => thermal_resistance_array[2],
40
- 'insulationFound' => minTestPass
41
- }
42
-
43
- return result
44
- end
45
-
46
- # change thermal resistance of opaque materials
47
- def self.setMaterialThermalResistance(material, thermalResistance, options = {})
48
- # set defaults to use if user inputs not passed in
49
- defaults = {
50
- 'cloneMaterial' => true, # in future give user option to clone or change live material
51
- 'name' => "#{material.name} - adj"
52
- }
53
-
54
- # merge user inputs with defaults
55
- options = defaults.merge(options)
56
-
57
- # clone input material
58
- new_material = material.clone(material.model)
59
- new_material = new_material.to_OpaqueMaterial.get
60
- new_material.setName(options['name'])
61
-
62
- # edit insulation material
63
- new_material_matt = new_material.to_Material
64
- if !new_material_matt.empty?
65
- starting_thickness = new_material_matt.get.thickness
66
- target_thickness = starting_thickness * thermalResistance / material.to_OpaqueMaterial.get.thermalResistance
67
- final_thickness = new_material_matt.get.setThickness(target_thickness)
68
- end
69
- new_material_massless = new_material.to_MasslessOpaqueMaterial
70
- if !new_material_massless.empty?
71
- final_thermal_resistance = new_material_massless.get.setThermalResistance(thermalResistance)
72
- end
73
- new_material_airgap = new_material.to_AirGap
74
- if !new_material_airgap.empty?
75
- final_thermal_resistance = new_material_airgap.get.setThermalResistance(thermalResistance)
76
- end
77
-
78
- result = new_material
79
- return result
80
- end
81
-
82
- # add new material to outside of a construction
83
- def self.addNewLayerToConstruction(construction, options = {})
84
- # set defaults to use if user inputs not passed in
85
- defaults = {
86
- 'cloneConstruction' => false, # in future give user option to clone or change live construction
87
- 'layerIndex' => 0, # 0 will be outside. Measure writer should validate any non 0 layerIndex passed in.
88
- 'name' => "#{construction.name} - new material",
89
- 'roughness' => nil,
90
- 'thickness' => nil,
91
- 'conductivity' => nil,
92
- 'density' => nil,
93
- 'specificHeat' => nil,
94
- 'thermalAbsorptance' => nil,
95
- 'solarAbsorptance' => nil,
96
- 'visibleAbsorptance' => nil
97
- }
98
-
99
- # merge user inputs with defaults
100
- options = defaults.merge(options)
101
-
102
- # TODO: - would be nice to grab surface properties from previous exposed material
103
-
104
- # make new material
105
- exposedMaterialNew = OpenStudio::Model::StandardOpaqueMaterial.new(construction.model)
106
- exposedMaterialNew.setName(options['name'])
107
-
108
- # set requested material properties
109
- if !options['roughness'].nil? then exposedMaterialNew.setRoughness(options['roughness']) end
110
- if !options['thickness'].nil? then exposedMaterialNew.setThickness(options['thickness']) end
111
- if !options['conductivity'].nil? then exposedMaterialNew.setConductivity(options['conductivity']) end
112
- if !options['density'].nil? then exposedMaterialNew.setDensity(options['density']) end
113
- if !options['specificHeat'].nil? then exposedMaterialNew.setSpecificHeat(options['specificHeat']) end
114
- if !options['thermalAbsorptance'].nil? then exposedMaterialNew.setThermalAbsorptance(options['thermalAbsorptance']) end
115
- if !options['solarAbsorptance'].nil? then exposedMaterialNew.setSolarAbsorptance(options['solarAbsorptance']) end
116
- if !options['visibleAbsorptance'].nil? then exposedMaterialNew.setVisibleAbsorptance(options['visibleAbsorptance']) end
117
-
118
- # add material to construction
119
- construction.insertLayer(options['layerIndex'], exposedMaterialNew)
120
-
121
- result = exposedMaterialNew
122
- return result
123
- end
124
-
125
- # set material surface properties for specific layer in construction. this should work on OS:Material and OS:MasslessOpaqueMaterial
126
- def self.setConstructionSurfaceProperties(construction, options = {})
127
- # set defaults to use if user inputs not passed in
128
- defaults = {
129
- 'cloneConstruction' => false, # in future give user option to clone or change live construction
130
- 'nameConstruction' => "#{construction.name} - adj", # not currently used
131
- 'cloneMaterial' => true,
132
- 'roughness' => nil,
133
- 'thermalAbsorptance' => nil,
134
- 'solarAbsorptance' => nil,
135
- 'visibleAbsorptance' => nil
136
- }
137
-
138
- # merge user inputs with defaults
139
- options = defaults.merge(options)
140
-
141
- exposedMaterial = construction.to_LayeredConstruction.get.getLayer(0)
142
- if options['cloneMaterial']
143
-
144
- # clone material
145
- exposedMaterialNew = exposedMaterial.clone(construction.model).to_StandardOpaqueMaterial.get # to_StandardOpaqueMaterial is needed to access roughness, otherwise to_OpaqueMaterial would have been fine.
146
- exposedMaterialNew.setName("#{exposedMaterial.name} - adj")
147
-
148
- # connect new material to original construction
149
- construction.eraseLayer(0)
150
- construction.insertLayer(0, exposedMaterialNew)
151
-
152
- else
153
- exposedMaterialNew = exposedMaterial.to_StandardOpaqueMaterial.get # not being cloned but still want to rename
154
- exposedMaterialNew.setName("#{exposedMaterial.name} - adj")
155
- end
156
-
157
- # TODO: - need to test with MasslessOpaqueMaterial. Add test if doesn't return anything when use to_StandardOpaqueMaterial.get
158
-
159
- # set requested material properties
160
- if !options['roughness'].nil? then exposedMaterialNew.setRoughness(options['roughness']) end
161
- if !options['thermalAbsorptance'].nil? then exposedMaterialNew.setThermalAbsorptance(options['thermalAbsorptance']) end
162
- if !options['solarAbsorptance'].nil? then exposedMaterialNew.setSolarAbsorptance(options['solarAbsorptance']) end
163
- if !options['visibleAbsorptance'].nil? then exposedMaterialNew.setVisibleAbsorptance(options['visibleAbsorptance']) end
164
-
165
- result = { 'exposedMaterial' => exposedMaterial, 'exposedMaterialNew' => exposedMaterialNew }
166
- return result
167
- end
168
-
169
- # similar to setMaterialSurfaceProperties but I just pass a material in. Needed this to set material properties for interior walls and both sides of interior partitions.
170
- def self.setMaterialSurfaceProperties(material, options = {})
171
- # set defaults to use if user inputs not passed in
172
- defaults = {
173
- 'cloneMaterial' => true,
174
- 'roughness' => nil,
175
- 'thermalAbsorptance' => nil,
176
- 'solarAbsorptance' => nil,
177
- 'visibleAbsorptance' => nil
178
- }
179
-
180
- # merge user inputs with defaults
181
- options = defaults.merge(options)
182
-
183
- if options['cloneMaterial']
184
- # clone material
185
- materialNew = exposedMaterial.clone(construction.model).get
186
- materialNew.setName("#{materialNew.name} - adj")
187
- else
188
- materialNew = material # not being cloned
189
- materialNew.setName("#{materialNew.name} - adj")
190
- end
191
-
192
- # to_StandardOpaqueMaterial is needed to access roughness, otherwise to_OpaqueMaterial would have been fine.
193
- if !materialNew.to_StandardOpaqueMaterial.empty?
194
- materialNew = materialNew.to_StandardOpaqueMaterial.get
195
- elsif !materialNew.to_MasslessOpaqueMaterial.empty?
196
- materialNew = materialNew.to_MasslessOpaqueMaterial.get
197
- end
198
-
199
- # set requested material properties
200
- if !options['roughness'].nil? then materialNew.setRoughness(options['roughness']) end
201
- if !options['thermalAbsorptance'].nil? then materialNew.setThermalAbsorptance(options['thermalAbsorptance']) end
202
- if !options['solarAbsorptance'].nil? then materialNew.setSolarAbsorptance(options['solarAbsorptance']) end
203
- if !options['visibleAbsorptance'].nil? then materialNew.setVisibleAbsorptance(options['visibleAbsorptance']) end
204
-
205
- result = { 'material' => material, 'materialNew' => materialNew }
206
- return result
207
- end
208
-
209
- # sri of exposed surface of a construction (calculation from K-12 AEDG, derived from ASTM E1980 assuming medium wind speed)
210
- def self.getConstructionSRI(construction)
211
- exposedMaterial = construction.to_LayeredConstruction.get.getLayer(0)
212
- solarAbsorptance = exposedMaterial.to_OpaqueMaterial.get.solarAbsorptance
213
- thermalEmissivity = exposedMaterial.to_OpaqueMaterial.get.thermalAbsorptance
214
- # lines below just for testing
215
- # solarAbsorptance = 1 - 0.65
216
- # thermalEmissivity = 0.86
217
-
218
- x = (20.797 * solarAbsorptance - 0.603 * thermalEmissivity) / (9.5205 * thermalEmissivity + 12.0)
219
- sri = 123.97 - 141.35 * x + 9.6555 * x * x
220
-
221
- result = sri
222
- return result
223
- end
224
-
225
- # create simple glazing material
226
- def self.createConstructionWithSimpleGlazing(model, runner = nil, options = {})
227
- # set defaults to use if user inputs not passed in
228
- defaults = {
229
- 'constructionName' => nil,
230
- 'materialName' => nil,
231
- 'uFactor' => nil,
232
- 'solarHeatGainCoef' => nil,
233
- 'visibleTransmittance' => nil
234
- }
235
-
236
- # merge user inputs with defaults
237
- options = defaults.merge(options)
238
-
239
- # create construction and material and link them together
240
- construction = OpenStudio::Model::Construction.new(model)
241
- if !options['constructionName'].nil? then construction.setName(options['constructionName'].to_s) end
242
- material = OpenStudio::Model::SimpleGlazing.new(model)
243
- if !options['materialName'].nil? then material.setName(options['materialName'].to_s) end
244
-
245
- # add material to construction
246
- construction.insertLayer(0, material)
247
-
248
- # set material properties
249
- if !options['uFactor'].nil? then material.setUFactor(options['uFactor']) end
250
- if !options['solarHeatGainCoef'].nil? then material.setSolarHeatGainCoefficient(options['solarHeatGainCoef']) end
251
- if !options['visibleTransmittance'].nil? then material.setVisibleTransmittance(options['visibleTransmittance']) end
252
-
253
- # create info message
254
- if !runner.nil? # todo - need to look for bad visible transmittance here
255
- uFactorSiToIpConversion = OpenStudio.convert(material.uFactor, 'W/m^2*K', 'Btu/ft^2*h*R').get
256
- # version check to support 2.x and 3.x
257
- if Gem::Version.new(OpenStudio::openStudioVersion) > Gem::Version.new("2.9.1")
258
- runner.registerInfo("Created #{construction.name} construction. U-factor: #{OpenStudio.toNeatString(uFactorSiToIpConversion, 2, true)}(Btu/ft^2*h*R), SHGC: #{material.solarHeatGainCoefficient}, VT: #{material.getVisibleTransmittance.get}.")
259
- else
260
- runner.registerInfo("Created #{construction.name} construction. U-factor: #{OpenStudio.toNeatString(uFactorSiToIpConversion, 2, true)}(Btu/ft^2*h*R), SHGC: #{material.getSolarHeatGainCoefficient}, VT: #{material.getVisibleTransmittance.get}.")
261
- end
262
- end
263
-
264
- result = construction
265
- return result
266
- end
267
-
268
- # get cost of selected constructions
269
- def self.getTotalCostOfSelectedConstructions(constructionArray)
270
- envelope_cost = 0
271
-
272
- # loop through selected constructions
273
- constructionArray.each do |construction|
274
- next if construction.getNetArea == 0
275
- const_llcs = construction.lifeCycleCosts
276
- const_llcs.each do |const_llc|
277
- if const_llc.category == 'Construction'
278
- envelope_cost += const_llc.totalCost
279
- end
280
- end
281
- end
282
-
283
- result = envelope_cost
284
- return result
285
- end
286
-
287
- # report names of constructions in a construction set
288
- def self.reportConstructionSetConstructions(constructionSet)
289
- constructionArray = []
290
-
291
- # populate exterior surfaces
292
- if constructionSet.defaultExteriorSurfaceConstructions.is_initialized
293
- surfaceSet = constructionSet.defaultExteriorSurfaceConstructions.get
294
- if surfaceSet.floorConstruction.is_initialized then constructionArray << surfaceSet.floorConstruction.get end
295
- if surfaceSet.wallConstruction.is_initialized then constructionArray << surfaceSet.wallConstruction.get end
296
- if surfaceSet.roofCeilingConstruction.is_initialized then constructionArray << surfaceSet.roofCeilingConstruction.get end
297
- end
298
- # populate interior surfaces
299
- if constructionSet.defaultInteriorSurfaceConstructions.is_initialized
300
- surfaceSet = constructionSet.defaultInteriorSurfaceConstructions.get
301
- if surfaceSet.floorConstruction.is_initialized then constructionArray << surfaceSet.floorConstruction.get end
302
- if surfaceSet.wallConstruction.is_initialized then constructionArray << surfaceSet.wallConstruction.get end
303
- if surfaceSet.roofCeilingConstruction.is_initialized then constructionArray << surfaceSet.roofCeilingConstruction.get end
304
- end
305
- # populate ground surfaces
306
- if constructionSet.defaultGroundContactSurfaceConstructions.is_initialized
307
- surfaceSet = constructionSet.defaultGroundContactSurfaceConstructions.get
308
- if surfaceSet.floorConstruction.is_initialized then constructionArray << surfaceSet.floorConstruction.get end
309
- if surfaceSet.wallConstruction.is_initialized then constructionArray << surfaceSet.wallConstruction.get end
310
- if surfaceSet.roofCeilingConstruction.is_initialized then constructionArray << surfaceSet.roofCeilingConstruction.get end
311
- end
312
- # populate exterior sub-surfaces
313
- if constructionSet.defaultExteriorSubSurfaceConstructions.is_initialized
314
- subSurfaceSet = constructionSet.defaultExteriorSubSurfaceConstructions.get
315
- if subSurfaceSet.fixedWindowConstruction.is_initialized then constructionArray << subSurfaceSet.fixedWindowConstruction.get end
316
- if subSurfaceSet.operableWindowConstruction.is_initialized then constructionArray << subSurfaceSet.operableWindowConstruction.get end
317
- if subSurfaceSet.doorConstruction.is_initialized then constructionArray << subSurfaceSet.doorConstruction.get end
318
- if subSurfaceSet.glassDoorConstruction.is_initialized then constructionArray << subSurfaceSet.glassDoorConstruction.get end
319
- if subSurfaceSet.overheadDoorConstruction.is_initialized then constructionArray << subSurfaceSet.overheadDoorConstruction.get end
320
- if subSurfaceSet.skylightConstruction.is_initialized then constructionArray << subSurfaceSet.skylightConstruction.get end
321
- if subSurfaceSet.tubularDaylightDomeConstruction.is_initialized then constructionArray << subSurfaceSet.tubularDaylightDomeConstruction.get end
322
- if subSurfaceSet.tubularDaylightDiffuserConstruction.is_initialized then constructionArray << subSurfaceSet.tubularDaylightDiffuserConstruction.get end
323
- end
324
- # populate interior sub-surfaces
325
- if constructionSet.defaultInteriorSubSurfaceConstructions.is_initialized
326
- subSurfaceSet = constructionSet.defaultInteriorSubSurfaceConstructions.get
327
- if subSurfaceSet.fixedWindowConstruction.is_initialized then constructionArray << subSurfaceSet.fixedWindowConstruction.get end
328
- if subSurfaceSet.operableWindowConstruction.is_initialized then constructionArray << subSurfaceSet.operableWindowConstruction.get end
329
- if subSurfaceSet.doorConstruction.is_initialized then constructionArray << subSurfaceSet.doorConstruction.get end
330
- if subSurfaceSet.glassDoorConstruction.is_initialized then constructionArray << subSurfaceSet.glassDoorConstruction.get end
331
- if subSurfaceSet.overheadDoorConstruction.is_initialized then constructionArray << subSurfaceSet.overheadDoorConstruction.get end
332
- if subSurfaceSet.skylightConstruction.is_initialized then constructionArray << subSurfaceSet.skylightConstruction.get end
333
- if subSurfaceSet.tubularDaylightDomeConstruction.is_initialized then constructionArray << subSurfaceSet.tubularDaylightDomeConstruction.get end
334
- if subSurfaceSet.tubularDaylightDiffuserConstruction.is_initialized then constructionArray << subSurfaceSet.tubularDaylightDiffuserConstruction.get end
335
- end
336
- # populate misc surfaces
337
- if constructionSet.interiorPartitionConstruction.is_initialized
338
- constructionArray << constructionSet.interiorPartitionConstruction.get
339
- end
340
- if constructionSet.spaceShadingConstruction.is_initialized
341
- constructionArray << constructionSet.spaceShadingConstruction.get
342
- end
343
- if constructionSet.buildingShadingConstruction.is_initialized
344
- constructionArray << constructionSet.buildingShadingConstruction.get
345
- end
346
- if constructionSet.siteShadingConstruction.is_initialized
347
- constructionArray << constructionSet.siteShadingConstruction.get
348
- end
349
-
350
- result = constructionArray
351
- return result
352
- end
353
- end