Module: OpenstudioStandards::Infiltration
- Defined in:
- lib/openstudio-standards/infiltration/infiltration.rb,
lib/openstudio-standards/infiltration/nist_infiltration.rb
Overview
The Infiltration module provides methods create, modify, and get information about model infiltration
Calculations collapse
-
.adjust_infiltration_to_new_pressure(infiltration_rate, initial_pressure: 75.0, final_pressure: 4.0, infiltration_coefficient: 0.65) ⇒ Double
Convert an infiltration rate at a given pressure to another pressure (typically lower) Method from Gowri, Krishnan, Winiarski, David W, and Jarnagin, Ronald E.
-
.adjust_infiltration_to_prototype_building_conditions(infiltration_rate, initial_pressure: 75.0) ⇒ Double
Convert the infiltration rate to the pressures and conditions assumed in the PNNL prototype buildings Details described in Gowri, Krishnan, Winiarski, David W, and Jarnagin, Ronald E.
Surface collapse
-
.surface_component_infiltration_rate(surface, type: 'baseline') ⇒ Double
Determine the component infiltration rate for a surface Details described in Table 5.7 of Thornton, Brian A, Rosenberg, Michael I, Richman, Eric E, Wang, Weimin, Xie, YuLong, Zhang, Jian, Cho, Heejin, Mendon, Vrushali V, Athalye, Rahul A, and Liu, Bing.
SubSurface collapse
-
.sub_surface_component_infiltration_rate(sub_surface, type: 'baseline') ⇒ Double
Determine the component infiltration rate for a sub surface Details described in Table 5.7 of Thornton, Brian A, Rosenberg, Michael I, Richman, Eric E, Wang, Weimin, Xie, YuLong, Zhang, Jian, Cho, Heejin, Mendon, Vrushali V, Athalye, Rahul A, and Liu, Bing.
NIST Infiltration collapse
-
.model_infer_nist_building_type(model) ⇒ OpenStudio::Model::Schedule
Infer the building type to use for NIST correlations, as only a subset of building types are available.
-
.model_set_nist_infiltration(model, airtightness_value: 13.8, airtightness_pressure: 75.0, airtightness_area_covered: '5-sided', air_barrier: false, hvac_schedule_name: nil, nist_building_type: nil) ⇒ Boolean
This method applies infiltration to a model that varies with weather and HVAC operation, and takes into account building geometry (height, above-ground exterior surface area, and volume).
-
.model_set_nist_infiltration_schedules(model, hvac_schedule: nil) ⇒ Boolean
Loops through SpaceInfiltrationDesignFlowRate objects and adjusts the infiltration schedules to account building HVAC operation.
-
.nist_building_types ⇒ OpenStudio::StringVector
DOE prototype buildings for which there are NIST infiltration coefficients.
Class Method Details
.adjust_infiltration_to_new_pressure(infiltration_rate, initial_pressure: 75.0, final_pressure: 4.0, infiltration_coefficient: 0.65) ⇒ Double
Convert an infiltration rate at a given pressure to another pressure (typically lower) Method from Gowri, Krishnan, Winiarski, David W, and Jarnagin, Ronald E. Infiltration modeling guidelines for commercial building energy analysis. United States: N. p., 2009. Web. doi:10.2172/968203.
14 15 16 17 18 19 20 21 |
# File 'lib/openstudio-standards/infiltration/infiltration.rb', line 14 def self.adjust_infiltration_to_new_pressure(infiltration_rate, initial_pressure: 75.0, final_pressure: 4.0, infiltration_coefficient: 0.65) adjusted_infiltration_rate = infiltration_rate * ((final_pressure / initial_pressure)**infiltration_coefficient) return adjusted_infiltration_rate end |
.adjust_infiltration_to_prototype_building_conditions(infiltration_rate, initial_pressure: 75.0) ⇒ Double
Convert the infiltration rate to the pressures and conditions assumed in the PNNL prototype buildings Details described in Gowri, Krishnan, Winiarski, David W, and Jarnagin, Ronald E. Infiltration modeling guidelines for commercial building energy analysis. United States: N. p., 2009. Web. doi:10.2172/968203.
29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/openstudio-standards/infiltration/infiltration.rb', line 29 def self.adjust_infiltration_to_prototype_building_conditions(infiltration_rate, initial_pressure: 75.0) alpha = 0.22 # terrain adjustment factor for an urban environment, unitless uh = 4.47 # wind speed, m/s rho = 1.18 # air density, kg/m^3 cs = 0.1617 # positive surface pressure coefficient, unitless n = 0.65 # infiltration coefficient, unitless # Calculate the typical pressure - same for all building types final_pressure_pa = 0.5 * cs * rho * (uh**2) adjusted_infiltration_rate = (1.0 + alpha) * infiltration_rate * ((final_pressure_pa / initial_pressure)**n) return adjusted_infiltration_rate end |
.model_infer_nist_building_type(model) ⇒ OpenStudio::Model::Schedule
Infer the building type to use for NIST correlations, as only a subset of building types are available.
30 31 32 33 34 35 36 37 38 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 67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/openstudio-standards/infiltration/nist_infiltration.rb', line 30 def self.model_infer_nist_building_type(model) if model.getBuilding.standardsBuildingType.is_initialized model_building_type = model.getBuilding.standardsBuildingType.get else model_building_type = '' end case model_building_type when 'Office' # map office building type to small medium or large floor_area = model.getBuilding.floorArea if floor_area < 2750.0 nist_building_type = 'SmallOffice' else nist_building_type = 'MediumOffice' end when 'LargeOffice', 'Outpatient', 'OfL' nist_building_type = 'MediumOffice' when 'Retail' # map retal building type to RetailStripmall or RetailStandalone based on building name building_name = model.getBuilding.name.get if building_name.include? 'RetailStandalone' nist_building_type = 'RetailStandalone' else nist_building_type = 'RetailStripmall' end when 'StripMall', 'Warehouse', 'QuickServiceRestaurant', 'FullServiceRestaurant', 'RtS', 'RSD', 'RFF', 'SCn', 'SUn', 'WRf' nist_building_type = 'RetailStripmall' when 'SuperMarket', 'RtL' nist_building_type = 'RetailStandalone' when 'EPr' nist_building_type = 'PrimarySchool' when 'ESe' nist_building_type = 'SecondarySchool' when 'Mtl' nist_building_type = 'SmallHotel' when 'Htl' nist_building_type = 'LargeHotel' when 'Hsp' nist_building_type = 'Hospital' when 'OfS' nist_building_type = 'SmallOffice' else nist_building_type = model_building_type end OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "Using building type #{nist_building_type} for model building type #{model_building_type}.") return nist_building_type end |
.model_set_nist_infiltration(model, airtightness_value: 13.8, airtightness_pressure: 75.0, airtightness_area_covered: '5-sided', air_barrier: false, hvac_schedule_name: nil, nist_building_type: nil) ⇒ Boolean
This method applies infiltration to a model that varies with weather and HVAC operation, and takes into account building geometry (height, above-ground exterior surface area, and volume). It is based on work published by Ng et al. (2018) <a href=‘doi.org/10.1016/j.buildenv.2017.10.029’>‘Weather correlations to calculate infiltration rates for U.S. commercial building energy models’</a> and Ng et al. (2021) <a href=‘doi.org/10.1016/j.buildenv.2021.107783’>‘Evaluating potential benefits of air barriers in commercial buildings using NIST infiltration correlations in EnergyPlus’</a>. This method of calculating infiltration was developed using eleven of the DOE commercial prototype building models (<a href=‘www.energycodes.gov/development/commercial/prototype_models’>Goel et al. 2014</a>) and TMY3 weather files for eight climate zones (CZ). Guidance on implementing the infiltration correlations are explained in the NIST technical report <a href=‘doi.org/10.6028/NIST.TN.2221’>‘Implementing NIST Infiltration Correlations’</a>. Ng et al. (2018) shows that when analyzing the benefits of building envelope airtightening, greater HVAC energy savings were predicted using the infiltration inputs included in this method compared with using the default inputs that are included in the prototype building models. This method will remove any existing infiltration objects (OS:SpaceInfiltration:DesignFlowRate and OS:SpaceInfiltration:EffectiveLeakageArea). Every zone will then get two OS:SpaceInfiltration:DesignFlowRate objects that add infiltration using the ‘Flow per Exterior Surface Area’ input option, one infiltration object when the HVAC system is on and one object when the HVAC system is off. The method assumes that HVAC operation is set by a schedule, though it may not reflect actual simulation/operation when fan operation may depend on internal loads and temperature setpoints. By default, interior zones will receive no infiltration. The user may enter a design building envelope airtightness at a specific design pressure, and whether the design value represents a 4-sided, 5-sided, or 6-sided normalization. By default, the method assumes an airtightness design value of 13.8 (m^3/h-m^2) at 75 Pa. The method assumes that infiltration is evenly distributed across the entire building envelope, including the roof. The user may select the HVAC system operating schedule in the model, or infer it based on the availability schedule of the air loop that serves the largest amount of floor area. The method will make a copy of the HVAC operating schedule, ‘Infiltration HVAC On Schedule’, which is used with the HVAC on infiltration correlations. The method will also make an ‘Infiltration HVAC Off Schedule’ with inverse operation, used with the HVAC off infiltration correlations. OS:SpaceInfiltration:DesignFlowRate object coefficients (A, B, C, and D) come from Ng et al. (2018). The user may select the Building Type and Climate Zone, or the method will infer them from the model.
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 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 |
# File 'lib/openstudio-standards/infiltration/nist_infiltration.rb', line 97 def self.model_set_nist_infiltration(model, airtightness_value: 13.8, airtightness_pressure: 75.0, airtightness_area_covered: '5-sided', air_barrier: false, hvac_schedule_name: nil, nist_building_type: nil) # validate airtightness value and pressure if airtightness_value < 0.0 OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', 'Airtightness value must be postive.') return false end if airtightness_pressure < 0.0 OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', 'Airtightness pressure must be postive.') return false end # calculate infiltration design value at 4 Pa airtightness_value_4pa_per_hr = airtightness_value * ((4.0 / airtightness_pressure)**0.65) OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "User-inputed airtightness design value #{airtightness_value} (m^3/h-m^2) at #{airtightness_pressure} Pa converts to #{airtightness_value_4pa_per_hr.round(7)} (m^3/h-m^2) at 4 Pa") # convert to m^3/s-m^2 airtightness_value_4pa_per_s = airtightness_value_4pa_per_hr / 3600.0 # get 4-sided, 5-sided, and 6-sided areas exterior_wall_area = 0.0 exterior_roof_area = 0.0 exterior_floor_area = 0.0 ground_wall_area = 0.0 ground_roof_area = 0.0 ground_floor_area = 0.0 model.getSurfaces.each do |surface| bc = surface.outsideBoundaryCondition type = surface.surfaceType area = surface.grossArea exterior_wall_area += area if bc == 'Outdoors' && type == 'Wall' exterior_roof_area += area if bc == 'Outdoors' && type == 'RoofCeiling' exterior_floor_area += area if bc == 'Outdoors' && type == 'Floor' ground_wall_area += area if bc == 'Ground' && type == 'Wall' ground_roof_area += area if bc == 'Ground' && type == 'RoofCeiling' ground_floor_area += area if bc == 'Ground' && type == 'Floor' end four_sided_area = exterior_wall_area + ground_wall_area five_sided_area = exterior_wall_area + ground_wall_area + exterior_roof_area + ground_roof_area six_sided_area = exterior_wall_area + ground_wall_area + exterior_roof_area + ground_roof_area + exterior_floor_area + ground_floor_area energy_plus_area = exterior_wall_area + exterior_roof_area OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "4-sided area = #{four_sided_area.round(2)} m^2, 5-sided area = #{five_sided_area.round(2)} m^2, 6-sided area = #{six_sided_area.round(2)} m^2.") # The SpaceInfiltrationDesignFlowRate object FlowperExteriorSurfaceArea method only counts surfaces with the 'Outdoors' boundary conditions towards exterior surface area, not surfaces with the 'Ground' boundary conditions. That means all values need to be normalized to exterior wall and roof area. case airtightness_area_covered when '4-sided' design_infiltration_4pa = airtightness_value_4pa_per_s * (four_sided_area / energy_plus_area) OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "#{airtightness_area_covered} infiltration design value #{airtightness_value_4pa_per_s.round(7)} (m^3/s-m^2) converted to #{design_infiltration_4pa.round(7)} (m^3/s-m^2) based on 4-sided area #{four_sided_area.round(2)} m^2 and 5-sided area #{energy_plus_area.round(2)} m^2 excluding ground boundary surfaces for energyplus.") when '5-sided' design_infiltration_4pa = airtightness_value_4pa_per_s * (five_sided_area / energy_plus_area) OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "#{airtightness_area_covered} infiltration design value #{airtightness_value_4pa_per_s.round(7)} (m^3/s-m^2) converted to #{design_infiltration_4pa.round(7)} (m^3/s-m^2) based on 5-sided area #{five_sided_area.round(2)} m^2 and 5-sided area #{energy_plus_area.round(2)} m^2 excluding ground boundary surfaces for energyplus.") when '6-sided' design_infiltration_4pa = airtightness_value_4pa_per_s * (six_sided_area / energy_plus_area) OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "#{airtightness_area_covered} infiltration design value #{airtightness_value_4pa_per_s.round(7)} (m^3/s-m^2) converted to #{design_infiltration_4pa.round(7)} (m^3/s-m^2) based on 6-sided area #{six_sided_area.round(2)} m^2 and 5-sided area #{energy_plus_area.round(2)} m^2 excluding ground boundary surfaces for energyplus.") end # validate hvac schedule if hvac_schedule_name.nil? hvac_schedule = OpenstudioStandards::Schedules.model_get_hvac_schedule(model) else hvac_schedule = model.getScheduleByName(hvac_schedule_name) unless hvac_schedule.is_initialized OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', "HVAC schedule argument #{hvac_schedule} not found in the model. It may have been removed by another measure.") return false end hvac_schedule = hvac_schedule.get if hvac_schedule.to_ScheduleRuleset.is_initialized hvac_schedule = hvac_schedule.to_ScheduleRuleset.get elsif hvac_schedule.to_ScheduleConstant.is_initialized hvac_schedule = hvac_schedule.to_ScheduleConstant.get else OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', "HVAC schedule argument #{hvac_schedule} is not a Schedule Constant or Schedule Ruleset object.") return false end OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "Using HVAC schedule #{hvac_schedule.name} from user arguments to determine infiltration on/off schedule.") end # creating infiltration schedules based on hvac schedule if hvac_schedule.nil? OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration', 'Unable to determine the building HVAC schedule. Treating the building as if there is no HVAC system with outdoor air. This may be appropriate for design sizing, particularly heating design sizing. If this is not the case, input a schedule argument, or assign one to an air loop in the model.') on_schedule = OpenStudio::Model::ScheduleConstant.new(model) on_schedule.setName('Infiltration HVAC On Schedule') on_schedule.setValue(0.0) off_schedule = OpenStudio::Model::ScheduleConstant.new(model) off_schedule.setName('Infiltration HVAC Off Schedule') off_schedule.setValue(1.0) elsif hvac_schedule.to_ScheduleConstant.is_initialized hvac_schedule = hvac_schedule.to_ScheduleConstant.get on_schedule = OpenStudio::Model::ScheduleConstant.new(model) on_schedule.setName('Infiltration HVAC On Schedule') on_schedule.setValue(hvac_schedule.value) off_schedule = OpenStudio::Model::ScheduleConstant.new(model) off_schedule.setName('Infiltration HVAC Off Schedule') if hvac_schedule.value > 0 off_schedule.setValue(0.0) else off_schedule.setValue(1.0) end elsif hvac_schedule.to_ScheduleRuleset.is_initialized hvac_schedule = hvac_schedule.to_ScheduleRuleset.get on_schedule = hvac_schedule.clone.to_ScheduleRuleset.get on_schedule.setName('Infiltration HVAC On Schedule') off_schedule = OpenstudioStandards::Schedules.create_inverted_schedule_ruleset(hvac_schedule, schedule_name: 'Infiltration HVAC Off Schedule') end # get climate zone number climate_zone_number = OpenstudioStandards::Weather.model_get_ashrae_climate_zone_number(model) # get nist building type if nist_building_type.nil? nist_building_type = model_infer_nist_building_type(model) end # check that model building type is supported unless nist_building_types.include? nist_building_type OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', "NIST coefficients are not available for model building type #{nist_building_type}.") return false end # remove existing infiltration objects OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "The modeled started with #{model.getSpaceInfiltrationDesignFlowRates.size} infiltration objects and #{model.getSpaceInfiltrationEffectiveLeakageAreas.size} effective leakage area objects.") model.getSpaceInfiltrationDesignFlowRates.each(&:remove) model.getSpaceInfiltrationEffectiveLeakageAreas.each(&:remove) # load NIST infiltration correlations file and convert to hash table nist_infiltration_correlations_csv = "#{__dir__}/data/NISTInfiltrationCorrelations.csv" unless File.exist?(nist_infiltration_correlations_csv) OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', "Unable to find file: #{nist_infiltration_correlations_csv}") return false end coefficients_tbl = CSV.table(nist_infiltration_correlations_csv, encoding: "ISO8859-1:utf-8" ) coefficients_hsh = coefficients_tbl.map(&:to_hash) # select down to building type and climate zone coefficients = coefficients_hsh.select { |r| (r[:building_type] == nist_building_type) && (r[:climate_zone] == climate_zone_number) } # filter by air barrier if coefficients = coefficients.select { |r| r[:air_barrier] == 'yes' } else coefficients = coefficients.select { |r| r[:air_barrier] == 'no' } end # determine coefficients # if no off coefficients are defined, use 0 for a and the on coefficients for b and d on_coefficients = coefficients.select { |r| r[:hvac_status] == 'on' } off_coefficients = coefficients.select { |r| r[:hvac_status] == 'off' } a_on = on_coefficients[0][:a] b_on = on_coefficients[0][:b] d_on = on_coefficients[0][:d] a_off = off_coefficients[0][:a].nil? ? on_coefficients[0][:a] : off_coefficients[0][:a] b_off = off_coefficients[0][:b].nil? ? on_coefficients[0][:b] : off_coefficients[0][:b] d_off = off_coefficients[0][:d].nil? ? on_coefficients[0][:d] : off_coefficients[0][:d] # add new infiltration objects # define infiltration as flow per exterior area model.getSpaces.each do |space| next unless space.exteriorArea > 0.0 hvac_on_infiltration = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(model) hvac_on_infiltration.setName("#{space.name.get} HVAC On Infiltration") hvac_on_infiltration.setFlowperExteriorSurfaceArea(design_infiltration_4pa) hvac_on_infiltration.setConstantTermCoefficient(a_on) hvac_on_infiltration.setTemperatureTermCoefficient(b_on) hvac_on_infiltration.setVelocityTermCoefficient(0.0) hvac_on_infiltration.setVelocitySquaredTermCoefficient(d_on) hvac_on_infiltration.setSpace(space) hvac_on_infiltration.setSchedule(on_schedule) hvac_off_infiltration = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(model) hvac_off_infiltration.setName("#{space.name.get} HVAC Off Infiltration") hvac_off_infiltration.setFlowperExteriorSurfaceArea(design_infiltration_4pa) hvac_off_infiltration.setConstantTermCoefficient(a_off) hvac_off_infiltration.setTemperatureTermCoefficient(b_off) hvac_off_infiltration.setVelocityTermCoefficient(0.0) hvac_off_infiltration.setVelocitySquaredTermCoefficient(d_off) hvac_off_infiltration.setSpace(space) hvac_off_infiltration.setSchedule(off_schedule) end OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "The modeled finished with #{model.getSpaceInfiltrationDesignFlowRates.size} infiltration objects.") return true end |
.model_set_nist_infiltration_schedules(model, hvac_schedule: nil) ⇒ Boolean
Loops through SpaceInfiltrationDesignFlowRate objects and adjusts the infiltration schedules to account building HVAC operation
294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'lib/openstudio-standards/infiltration/nist_infiltration.rb', line 294 def self.model_set_nist_infiltration_schedules(model, hvac_schedule: nil) # delete existing schedules if present on_schedule = model.getScheduleByName('Infiltration HVAC On Schedule') on_schedule.get.remove if on_schedule.is_initialized off_schedule = model.getScheduleByName('Infiltration HVAC Off Schedule') off_schedule.get.remove if off_schedule.is_initialized # validate hvac schedule if hvac_schedule.nil? hvac_schedule = OpenstudioStandards::Schedules.model_get_hvac_schedule(model) else unless hvac_schedule.to_Schedule.is_initialized OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', "HVAC schedule argument #{hvac_schedule} not found in the model or is not a Schedule object. It may have been removed by another measure.") return false end hvac_schedule = hvac_schedule.to_Schedule.get if hvac_schedule.to_ScheduleRuleset.is_initialized hvac_schedule = hvac_schedule.to_ScheduleRuleset.get elsif hvac_schedule.to_ScheduleConstant.is_initialized hvac_schedule = hvac_schedule.to_ScheduleConstant.get else OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Infiltration', "HVAC schedule argument #{hvac_schedule} is not a Schedule Constant or Schedule Ruleset object.") return false end OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "Using HVAC schedule #{hvac_schedule.name} from user arguments to determine infiltration on/off schedule.") end # creating infiltration schedules based on hvac schedule if hvac_schedule.nil? OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration', 'Unable to determine the HVAC schedule. Treating the building as if there is no HVAC system with outdoor air. If this is not the case, input a schedule argument, or assign one to an air loop in the model.') on_schedule = OpenStudio::Model::ScheduleConstant.new(model) on_schedule.setName('Infiltration HVAC On Schedule') on_schedule.setValue(0.0) off_schedule = OpenStudio::Model::ScheduleConstant.new(model) off_schedule.setName('Infiltration HVAC Off Schedule') off_schedule.setValue(1.0) elsif hvac_schedule.to_ScheduleConstant.is_initialized hvac_schedule = hvac_schedule.to_ScheduleConstant.get on_schedule = OpenStudio::Model::ScheduleConstant.new(model) on_schedule.setName('Infiltration HVAC On Schedule') on_schedule.setValue(hvac_schedule.value) off_schedule = OpenStudio::Model::ScheduleConstant.new(model) off_schedule.setName('Infiltration HVAC Off Schedule') if hvac_schedule.value > 0 off_schedule.setValue(0.0) else off_schedule.setValue(1.0) end elsif hvac_schedule.to_ScheduleRuleset.is_initialized hvac_schedule = hvac_schedule.to_ScheduleRuleset.get on_schedule = hvac_schedule.clone.to_ScheduleRuleset.get on_schedule.setName('Infiltration HVAC On Schedule') off_schedule = OpenstudioStandards::Schedules.create_inverted_schedule_ruleset(hvac_schedule, schedule_name: 'Infiltration HVAC Off Schedule') end model.getSpaceInfiltrationDesignFlowRates.each do |infil| if infil.name.get.include?('HVAC On Infiltration') infil.setSchedule(on_schedule) end if infil.name.get.include?('HVAC Off Infiltration') infil.setSchedule(off_schedule) end end return true end |
.nist_building_types ⇒ OpenStudio::StringVector
DOE prototype buildings for which there are NIST infiltration coefficients.
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/openstudio-standards/infiltration/nist_infiltration.rb', line 9 def self.nist_building_types building_types = OpenStudio::StringVector.new building_types << 'SecondarySchool' building_types << 'PrimarySchool' building_types << 'SmallOffice' building_types << 'MediumOffice' building_types << 'SmallHotel' building_types << 'LargeHotel' building_types << 'RetailStandalone' building_types << 'RetailStripmall' building_types << 'Hospital' building_types << 'MidriseApartment' building_types << 'HighriseApartment' return building_types end |
.sub_surface_component_infiltration_rate(sub_surface, type: 'baseline') ⇒ Double
Determine the component infiltration rate for a sub surface Details described in Table 5.7 of Thornton, Brian A, Rosenberg, Michael I, Richman, Eric E, Wang, Weimin, Xie, YuLong, Zhang, Jian, Cho, Heejin, Mendon, Vrushali V, Athalye, Rahul A, and Liu, Bing. Achieving the 30% Goal: Energy and Cost Savings Analysis of ASHRAE Standard 90.1-2010. United States: N. p., 2011. Web. doi:10.2172/1015277.
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 |
# File 'lib/openstudio-standards/infiltration/infiltration.rb', line 124 def self.sub_surface_component_infiltration_rate(sub_surface, type: 'baseline') # Define the envelope component infiltration rates component_infil_rates_cfm_per_ft2 = { 'baseline' => { 'opaque_door' => 0.40, 'loading_dock_door' => 0.40, 'swinging_or_revolving_glass_door' => 1.0, 'vestibule' => 1.0, 'sliding_glass_door' => 0.40, 'window' => 0.40, 'skylight' => 0.40 }, 'advanced' => { 'opaque_door' => 0.20, 'loading_dock_door' => 0.20, 'swinging_or_revolving_glass_door' => 1.0, 'vestibule' => 1.0, 'sliding_glass_door' => 0.20, 'window' => 0.20, 'skylight' => 0.20 } } # Skip non-outdoor surfaces unless sub_surface.outsideBoundaryCondition == 'Outdoors' return 0.0 end # Per area infiltration rate for this sub surface case sub_surface.subSurfaceType when 'Door' infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['opaque_door'] when 'OverheadDoor' infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['loading_dock_door'] when 'GlassDoor' OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.Infiltration', "Assuming swinging_or_revolving_glass_door for #{sub_surface.name} for component infiltration rate.") infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['swinging_or_revolving_glass_door'] when 'FixedWindow', 'OperableWindow' infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['window'] when 'Skylight', 'TubularDaylightDome', 'TubularDaylightDiffuser' infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['skylight'] else OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration', "Could not determine infiltration sub surface type for #{sub_surface.name}, defaulting to 0 component infiltration rate.") return 0.0 end # Area of the sub surface area_m2 = sub_surface.netArea area_ft2 = OpenStudio.convert(area_m2, 'm^2', 'ft^2').get # Rate for this sub surface comp_infil_rate_cfm = area_ft2 * infil_rate_cfm_per_ft2 comp_infil_rate_m3_per_s = OpenStudio.convert(comp_infil_rate_cfm, 'cfm', 'm^3/s').get return comp_infil_rate_m3_per_s end |
.surface_component_infiltration_rate(surface, type: 'baseline') ⇒ Double
Determine the component infiltration rate for a surface Details described in Table 5.7 of Thornton, Brian A, Rosenberg, Michael I, Richman, Eric E, Wang, Weimin, Xie, YuLong, Zhang, Jian, Cho, Heejin, Mendon, Vrushali V, Athalye, Rahul A, and Liu, Bing. Achieving the 30% Goal: Energy and Cost Savings Analysis of ASHRAE Standard 90.1-2010. United States: N. p., 2011. Web. doi:10.2172/1015277.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 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 |
# File 'lib/openstudio-standards/infiltration/infiltration.rb', line 53 def self.surface_component_infiltration_rate(surface, type: 'baseline') # Define the envelope component infiltration rates component_infil_rates_cfm_per_ft2 = { 'baseline' => { 'roof' => 0.12, 'exterior_wall' => 0.12, 'below_grade_wall' => 0.12, 'floor_over_unconditioned' => 0.12, 'slab_on_grade' => 0.12 }, 'advanced' => { 'roof' => 0.04, 'exterior_wall' => 0.04, 'below_grade_wall' => 0.04, 'floor_over_unconditioned' => 0.04, 'slab_on_grade' => 0.04 } } # Skip non-outdoor surfaces boundary_condition = surface.outsideBoundaryCondition unless boundary_condition == 'Outdoors' || boundary_condition == 'Ground' return 0.0 end # Per area infiltration rate for this surface surface_type = surface.surfaceType infil_rate_cfm_per_ft2 = nil case boundary_condition when 'Outdoors' case surface_type when 'RoofCeiling' infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['roof'] when 'Wall' infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['exterior_wall'] when 'Floor' infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['floor_over_unconditioned'] end when 'Ground' case surface_type when 'Wall' infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['below_grade_wall'] when 'Floor' infil_rate_cfm_per_ft2 = component_infil_rates_cfm_per_ft2[type]['slab_on_grade'] end else OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.Infiltration', "Could not determine infiltration surface type for #{surface.name}, defaulting to 0 component infiltration rate.") return 0.0 end # Area of the surface area_m2 = surface.netArea area_ft2 = OpenStudio.convert(area_m2, 'm^2', 'ft^2').get # Rate for this surface comp_infil_rate_cfm = area_ft2 * infil_rate_cfm_per_ft2 comp_infil_rate_m3_per_s = OpenStudio.convert(comp_infil_rate_cfm, 'cfm', 'm^3/s').get return comp_infil_rate_m3_per_s end |