Class: ZEDGK12EnvelopeInfiltration

Inherits:
OpenStudio::Measure::ModelMeasure
  • Object
show all
Includes:
OsLib_AedgMeasures, OsLib_HelperMethods, OsLib_OutdoorAirAndInfiltration, OsLib_Schedules
Defined in:
lib/measures/zedgk_12_envelope_infiltration/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



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/measures/zedgk_12_envelope_infiltration/measure.rb', line 41

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

  # make an argument for material and installation cost
  costTotalEnvelopeInfiltration = OpenStudio::Measure::OSArgument.makeDoubleArgument('costTotalEnvelopeInfiltration', true)
  costTotalEnvelopeInfiltration.setDisplayName('Total cost for all Envelope Improvements ($).')
  costTotalEnvelopeInfiltration.setDefaultValue(0.0)
  args << costTotalEnvelopeInfiltration

  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



36
37
38
# File 'lib/measures/zedgk_12_envelope_infiltration/measure.rb', line 36

def name
  return 'ZEDG K12 Envelope Infiltration'
end

#run(model, runner, user_arguments) ⇒ Object

define what happens when the measure is run



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
113
114
115
116
117
118
119
120
121
122
123
# File 'lib/measures/zedgk_12_envelope_infiltration/measure.rb', line 54

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
  costTotalEnvelopeInfiltration = runner.getDoubleArgumentValue('costTotalEnvelopeInfiltration', user_arguments)

  # global variables for costs
  expected_life = 25
  years_until_costs_start = 0

  # reporting initial condition of model
  space_infiltration_objects = model.getSpaceInfiltrationDesignFlowRates
  if !space_infiltration_objects.empty?
    runner.registerInitialCondition("The initial model contained #{space_infiltration_objects.size} space infiltration objects.")
  else
    runner.registerInitialCondition('The initial model did not contain any space infiltration objects.')
  end

  # erase existing infiltration objects used in the model, but save most commonly used schedule
  # todo - would be nice to preserve attic space infiltration. There are a number of possible solutions for this
  removedInfiltration = OsLib_OutdoorAirAndInfiltration.eraseInfiltrationUsedInModel(model, runner)

  # find most common hard assigned from removed infiltration objects
  if !removedInfiltration.empty?
    defaultSchedule = removedInfiltration[0][0] # not sure why this is array vs. hash. I wanted to use removedInfiltration.keys[0]
  else
    defaultSchedule = nil
  end

  # get desired envelope infiltration area
  targetFlowPerExteriorArea = 0.0001905 # 0.0375 cfm/ft^2

  # hash to pass into infiltration method
  options_OsLib_OutdoorAirAndInfiltration_envelope = {
    'nameSuffix' => ' - envelope infiltration', # add this to object name for infiltration
    'defaultBuildingSchedule' => defaultSchedule, # this will set schedule set for selected object
    'setCalculationMethod' => 'setFlowperExteriorWallArea', # for net zero changing to setFlowperExteriorWallArea instead of setFlowperExteriorSurfaceArea
    'valueForSelectedCalcMethod' => targetFlowPerExteriorArea
  }
  # add in new envelope infiltration to all spaces in the model
  newInfiltrationPerExteriorSurfaceArea = OsLib_OutdoorAirAndInfiltration.addSpaceInfiltrationDesignFlowRate(model, runner, model.getBuilding, options_OsLib_OutdoorAirAndInfiltration_envelope)
  targetFlowPerExteriorArea_ip = OpenStudio.convert(targetFlowPerExteriorArea, 'm/s', 'ft/min').get
  runner.registerInfo("Adding infiltration object to all spaces in model with value of #{OpenStudio.toNeatString(targetFlowPerExteriorArea_ip, 4, true)} (cfm/ft^2) of exterior surface area.")

  # create lifecycle costs for floors
  envelopeImprovementTotalCost = 0
  totalArea = model.building.get.exteriorSurfaceArea
  newInfiltrationPerExteriorSurfaceArea.each do |infiltrationObject|
    spaceType = infiltrationObject.spaceType.get
    areaForEnvelopeInfiltration_si = OsLib_HelperMethods.getAreaOfSpacesInArray(model, spaceType.spaces, 'exteriorArea')['totalArea']
    fractionOfTotal = areaForEnvelopeInfiltration_si / totalArea
    lcc_mat = OpenStudio::Model::LifeCycleCost.createLifeCycleCost("#{spaceType.name} - Entry Infiltration Cost", model.getBuilding, fractionOfTotal * costTotalEnvelopeInfiltration, 'CostPerEach', 'Construction', expected_life, years_until_costs_start)
    envelopeImprovementTotalCost += lcc_mat.get.totalCost
  end

  # reporting final condition of model
  space_infiltration_objects = model.getSpaceInfiltrationDesignFlowRates
  if !space_infiltration_objects.empty?
    runner.registerFinalCondition("The final model contains #{space_infiltration_objects.size} space infiltration objects. Cost was increased by $#{OpenStudio.toNeatString(envelopeImprovementTotalCost, 2, true)} for envelope infiltration.")
  else
    runner.registerFinalCondition("The final model does not contain any space infiltration objects. Cost was increased by $#{OpenStudio.toNeatString(envelopeImprovementTotalCost, 2, true)} for envelope infiltration.")
  end

  return true
end