Class: AedgK12InteriorFinishes

Inherits:
OpenStudio::Measure::ModelMeasure
  • Object
show all
Includes:
OsLib_AedgMeasures, OsLib_Constructions, OsLib_HelperMethods
Defined in:
lib/measures/AedgK12InteriorFinishes/measure.rb

Overview

start the measure

Instance Method Summary collapse

Methods included from OsLib_HelperMethods

checkChoiceArgFromModelObjects, checkDoubleAndIntegerArguments, checkOptionalChoiceArgFromModelObjects, check_upstream_measure_for_arg, createRunVariables, getAreaOfSpacesInArray, getSpaceTypeStandardsInformation, getTotalCostForObjects, log_msgs, neatConvertWithUnitDisplay, populateChoiceArgFromModelObjects, setup_log_msgs

Methods included from OsLib_AedgMeasures

getClimateZoneNumber, getK12Tips, getLongHowToTips, getSmMdOffTips

Instance Method Details

#arguments(model) ⇒ Object

define the arguments that the user will input



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/measures/AedgK12InteriorFinishes/measure.rb', line 39

def arguments(model)
  args = OpenStudio::Measure::OSArgumentVector.new

  # filter constructions before populating choice argument
  construction_args_hash = {}
  interiorPartitionSurfaces = model.getInteriorPartitionSurfaces
  interiorPartitionSurfaces.each do |surface|
    if !surface.construction.empty?
      construction_arg = surface.construction.get
      construction_args_hash[construction_arg.name.to_s] = construction_arg
    end
  end

  # call method to make argument handles and display names from hash of model objects
  constructionChoiceArgument = OsLib_HelperMethods.populateChoiceArgFromModelObjects(model, construction_args_hash, includeBuilding = '*All Interior Partition Surfaces*')

  # make an argument for construction
  object = OpenStudio::Measure::OSArgument.makeChoiceArgument('object', constructionChoiceArgument['modelObject_handles'], constructionChoiceArgument['modelObject_display_names'], true)
  object.setDisplayName('Only Check/Alter Interior Partition Surfaces To Meet Furniture Target When They Use This Construction.')
  object.setDefaultValue('*All Interior Partition Surfaces*')
  args << object

  # TODO: - add bools for each surface type

  # TODO: - add logic to include adiabatic surfaces as well

  return args
end

#nameObject

define the name that a user will see, this method may be deprecated as the display name in PAT comes from the name field in measure.xml



34
35
36
# File 'lib/measures/AedgK12InteriorFinishes/measure.rb', line 34

def name
  return 'AedgK12InteriorFinishes'
end

#run(model, runner, user_arguments) ⇒ Object

define what happens when the measure is run



69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/measures/AedgK12InteriorFinishes/measure.rb', line 69

def run(model, runner, user_arguments)
  super(model, runner, user_arguments)

  # use the built-in error checking
  if !runner.validateUserArguments(arguments(model), user_arguments)
    return false
  end

  # assign the user inputs to variables
  object = runner.getOptionalWorkspaceObjectChoiceValue('object', user_arguments, model) # model is passed in because of argument type

  # check that construction exists in model
  modelObjectCheck = OsLib_HelperMethods.checkChoiceArgFromModelObjects(object, 'object', 'to_Construction', runner, user_arguments)

  if modelObjectCheck == false
    return false
  else
    modelObject = modelObjectCheck['modelObject']
    apply_to_building = modelObjectCheck['apply_to_building']
  end

  # create an hash of hashes for surfaces
  surfacesHashCeilings = {}
  surfacesHashWalls = {}
  surfacesHashFurniture = {}
  surfacesHashFloors = {}

  # arrays for initial condition by surface type
  surfacesCeilings = []
  surfacesWalls = []
  surfacesFurniture = []
  surfacesFloors = []

  # TODO: - allow user to pick spaces or space types or look for daylighting controls, but that creates some issues in run order
  # todo - if this will be applied selectively then will want to clone material and constructions vs. editing in place.

  # loop through surfaces to populate hash
  surfaces = model.getSurfaces
  surfaces.each do |surface|
    surfaceType = surface.surfaceType
    if !surface.construction.empty?
      construction = surface.construction.get
      numLayers = construction.to_LayeredConstruction.get.layers
      insideMaterial = construction.to_LayeredConstruction.get.getLayer(numLayers.size - 1)
      visibleAbsorptance = insideMaterial.to_OpaqueMaterial.get.visibleAbsorptance
      if surfaceType == 'RoofCeiling'
        surfacesCeilings << visibleAbsorptance
        surfacesHashCeilings["#{surface.name} - inside"] = { 'surfaceType' => surfaceType, 'construction' => construction, 'material' => insideMaterial, 'visibleAbsorptance' => visibleAbsorptance }
      elsif surfaceType == 'Wall'
        surfacesWalls << visibleAbsorptance
        surfacesHashWalls["#{surface.name} - inside"] = { 'surfaceType' => surfaceType, 'construction' => construction, 'material' => insideMaterial, 'visibleAbsorptance' => visibleAbsorptance }
      elsif surfaceType == 'Floor'
        surfacesFloors << visibleAbsorptance
        surfacesHashFloors["#{surface.name} - inside"] = { 'surfaceType' => surfaceType, 'construction' => construction, 'material' => insideMaterial, 'visibleAbsorptance' => visibleAbsorptance }
      else
        runner.registerWarning("Can't evaluate #{surface.name}, it has an unexpected surface type.")
      end
    else
      # warning
      runner.registerWarning("Can't evaluate #{surface.name}, it doesn't have a construction.")
    end
  end

  # loop through interior partition surfaces to populate hash
  partitionSurfaces = model.getInteriorPartitionSurfaces
  partitionSurfaces.each do |surface|
    surfaceType = 'Partition'
    if !surface.construction.empty?
      if !apply_to_building
        if surface.construction.get != modelObject
          next
        end
      end
      construction = surface.construction.get
      numLayers = construction.to_LayeredConstruction.get.layers
      insideMaterial = construction.to_LayeredConstruction.get.getLayer(numLayers.size - 1)
      exposedMaterial = construction.to_LayeredConstruction.get.getLayer(0)
      visibleAbsorptanceInside = insideMaterial.to_OpaqueMaterial.get.visibleAbsorptance
      visibleAbsorptance = exposedMaterial.to_OpaqueMaterial.get.visibleAbsorptance
      surfacesFurniture << visibleAbsorptanceInside
      surfacesFurniture << visibleAbsorptance
      surfacesHashFurniture["#{surface.name} - inside"] = { 'surfaceType' => surfaceType, 'construction' => construction, 'material' => insideMaterial, 'visibleAbsorptance' => visibleAbsorptanceInside }
      surfacesHashFurniture["#{surface.name} - outside"] = { 'surfaceType' => surfaceType, 'construction' => construction, 'material' => exposedMaterial, 'visibleAbsorptance' => visibleAbsorptance }
    else
      # warning
      runner.registerWarning("Can't evaluate #{surface.name}, it doesn't have a construction.")
    end
  end

  editMaterialsCeilings = []
  editMaterialsWalls = []
  editMaterialsFurniture = []
  editMaterialsFloors = []

  # loop through Ceilings first (most reflective at min 80%)
  minValue = 0.2
  surfacesHashCeilings.each do |k, hash|
    if (hash['visibleAbsorptance'] > minValue) && (!editMaterialsCeilings.include? hash['material'])
      editMaterialsCeilings << hash['material']
      editedMaterial = OsLib_Constructions.setMaterialSurfaceProperties(hash['material'], 'cloneMaterial' => false, 'visibleAbsorptance' => minValue)
      runner.registerInfo("Increasing reflectance of #{hash['material'].name} to AEDG ceiling target reflectance of 80%.")
    end
  end

  # loop through interior walls (min 70% reflective)
  minValue = 0.3
  surfacesHashWalls.each do |k, hash|
    if (hash['visibleAbsorptance'] > minValue) && (!editMaterialsWalls.include? hash['material'])
      editMaterialsWalls << hash['material']
      if editMaterialsCeilings.include? hash['material']
        runner.registerWarning("#{hash['material'].name} is used on one or more interior wall surfaces. It is using a higher reflectance target from another surface type.")
        next
      end
      editedMaterial = OsLib_Constructions.setMaterialSurfaceProperties(hash['material'], 'cloneMaterial' => false, 'visibleAbsorptance' => minValue)
      runner.registerInfo("Increasing reflectance of #{hash['material'].name} to AEDG wall target reflectance of 70%.")
    end
  end

  # loop through interior partition surfaces (min 50% reflective)
  minValue = 0.5
  surfacesHashFurniture.each do |k, hash|
    if (hash['visibleAbsorptance'] > minValue) && (!editMaterialsFurniture.include? hash['material'])
      editMaterialsFurniture << hash['material']
      if editMaterialsCeilings.include?(hash['material']) || editMaterialsWalls.include?(hash['material'])
        runner.registerWarning("#{hash['material'].name} is used on one or more interior partition surfaces. It is using a higher reflectance target from another surface type.")
        next
      end
      editedMaterial = OsLib_Constructions.setMaterialSurfaceProperties(hash['material'], 'cloneMaterial' => false, 'visibleAbsorptance' => minValue)
      runner.registerInfo("Increasing reflectance of #{hash['material'].name} to AEDG furniture target reflectance of 50%.")
    end
  end

  # loop through floors (min 20% reflective)
  minValue = 0.8
  surfacesHashFloors.each do |k, hash|
    if (hash['visibleAbsorptance'] > minValue) && (!editMaterialsFloors.include? hash['material'])
      editMaterialsFloors << hash['material']
      if editMaterialsCeilings.include?(hash['material']) || editMaterialsWalls.include?(hash['material']) || editMaterialsFurniture.include?(hash['material'])
        runner.registerWarning("#{hash['material'].name} is used on one or more interior floor surfaces. It is using a higher reflectance target from another surface type.")
        next
      end
      editedMaterial = OsLib_Constructions.setMaterialSurfaceProperties(hash['material'], 'cloneMaterial' => false, 'visibleAbsorptance' => minValue)
      runner.registerInfo("Increasing reflectance of #{hash['material'].name} to AEDG floor target reflectance of 20%.")
    end
  end

  # add AEDG tips
  if surfaces.size + partitionSurfaces.size > 0
    aedgTips = ['DL14']
  else
    runner.registerAsNotApplicable("This model doesn't appear to have any surfaces to change.")
    return true
  end

  # populate how to tip messages
  aedgTipsLong = OsLib_AedgMeasures.getLongHowToTips('K12', aedgTips.uniq.sort, runner)
  if !aedgTipsLong
    return false # this should only happen if measure writer passes bad values to getLongHowToTips
  end

  # string for final condition.
  string = []
  if !surfacesCeilings.empty?
    string << "Initial ceiling reflectance values ranged from #{100 * (1.0 - surfacesCeilings.max)} to #{100 * (1.0 - surfacesCeilings.min)} percent. "
  end
  if !surfacesWalls.empty?
    string << "Initial wall reflectance values ranged from #{100 * (1.0 - surfacesWalls.max)} to #{100 * (1.0 - surfacesWalls.min)} percent. "
  end
  if !surfacesFurniture.empty?
    string << "Initial furniture reflectance values ranged from #{100 * (1.0 - surfacesFurniture.max)} to #{100 * (1.0 - surfacesFurniture.min)} percent. "
  end
  if !surfacesFloors.empty?
    string << "Initial floor reflectance values ranged from #{100 * (1.0 - surfacesFloors.max)} to #{100 * (1.0 - surfacesFloors.min)} percent. "
  end

  # reporting initial condition of model
  runner.registerInitialCondition(string.to_s)

  # string for final condition.
  string = []
  if !editMaterialsCeilings.empty?
    string << "Increased reflectance to #{editMaterialsCeilings.size} ceiling materials. "
  end
  if !editMaterialsWalls.empty?
    string << "Increased reflectance to #{editMaterialsWalls.size} wall materials. "
  end
  if !editMaterialsFurniture.empty?
    string << "Increased reflectance to #{editMaterialsFurniture.size} furniture materials. "
  end
  if !editMaterialsFloors.empty?
    string << "Increased reflectance to #{editMaterialsFloors.size} floors materials. "
  end

  # reporting final condition of model
  runner.registerFinalCondition("#{string} #{aedgTipsLong}")

  return true
end