class ASHRAE901PRM < Standard # @!group Space # Set the infiltration rate for this space to include the impact of air leakage requirements in the standard. # # @param space [OpenStudio::Model::Space] space object # @param tot_infil_m3_per_s [Float] total infiltration in m3/s # @param infil_method [String] infiltration method # @param infil_coefficients [Array] Array of 4 items # [Constant Term Coefficient, Temperature Term Coefficient, # Velocity Term Coefficient, Velocity Squared Term Coefficient] # @return [Boolean] returns true if successful, false if not def space_apply_infiltration_rate(space, tot_infil_m3_per_s, infil_method, infil_coefficients) # Calculate infiltration rate case infil_method.to_s when 'Flow/ExteriorWallArea' # Spread the total infiltration rate total_exterior_wall_area = 0 space.model.getSpaces.each do |spc| # Get the space conditioning type space_cond_type = space_conditioning_category(spc) total_exterior_wall_area += spc.exteriorWallArea * spc.multiplier unless space_cond_type == 'Unconditioned' end prm_raise(total_exterior_wall_area > 0, @sizing_run_dir, 'Total exterior wall area in the model is 0. Check your model inputs') adj_infil_flow_ext_wall_area = tot_infil_m3_per_s / total_exterior_wall_area OpenStudio.logFree(OpenStudio::Debug, 'prm.log', "For #{space.name}, adj infil = #{adj_infil_flow_ext_wall_area.round(8)} m^3/s*m^2 of above grade wall area.") when 'Flow/Area' # Spread the total infiltration rate total_floor_area = 0 space.model.getSpaces.each do |spc| # Get the space conditioning type space_cond_type = space_conditioning_category(spc) total_floor_area += spc.floorArea * spc.multipler unless space_cond_type == 'Unconditioned' || space.exteriorArea == 0 end prm_raise(total_floor_area > 0, @sizing_run_dir, 'Sum of the floor area in exterior spaces in the model is 0. Check your model inputs') adj_infil_flow_area = tot_infil_m3_per_s / total_floor_area OpenStudio.logFree(OpenStudio::Debug, 'prm.log', "For #{space.name}, adj infil = #{adj_infil_flow_area.round(8)} m^3/s*m^2 of space floor area.") end # Get any infiltration schedule already assigned to this space or its space type # If not, the always on schedule will be applied. # @todo Infiltration schedules should be based on HVAC operation infil_sch = nil unless space.spaceInfiltrationDesignFlowRates.empty? old_infil = space.spaceInfiltrationDesignFlowRates[0] if old_infil.schedule.is_initialized infil_sch = old_infil.schedule.get end end if infil_sch.nil? && space.spaceType.is_initialized space_type = space.spaceType.get unless space_type.spaceInfiltrationDesignFlowRates.empty? old_infil = space_type.spaceInfiltrationDesignFlowRates[0] if old_infil.schedule.is_initialized infil_sch = old_infil.schedule.get end end end if infil_sch.nil? infil_sch = space.model.alwaysOnDiscreteSchedule else # Add specific schedule type object to insure compatibility with the OpenStudio infiltration object infil_sch_limit_type = OpenstudioStandards::Schedules.create_schedule_type_limits(space.model, name: 'Infiltration Schedule Type Limits', lower_limit_value: 0.0, upper_limit_value: 1.0, numeric_type: 'Continuous', unit_type: 'Dimensionless') infil_sch.setScheduleTypeLimits(infil_sch_limit_type) end # Remove all pre-existing space infiltration objects space.spaceInfiltrationDesignFlowRates.each(&:remove) # Get the space conditioning type space_cond_type = space_conditioning_category(space) if space_cond_type != 'Unconditioned' # Create an infiltration rate object for this space infiltration = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(space.model) infiltration.setName("#{space.name} Infiltration") case infil_method.to_s when 'Flow/ExteriorWallArea' infiltration.setFlowperExteriorWallArea(adj_infil_flow_ext_wall_area.round(13)) if space.exteriorWallArea > 0 when 'Flow/Area' infiltration.setFlowperSpaceFloorArea(adj_infil_flow_area.round(13)) if space.exteriorArea > 0 end infiltration.setSchedule(infil_sch) infiltration.setConstantTermCoefficient(infil_coefficients[0]) infiltration.setTemperatureTermCoefficient(infil_coefficients[1]) infiltration.setVelocityTermCoefficient(infil_coefficients[2]) infiltration.setVelocitySquaredTermCoefficient(infil_coefficients[3]) infiltration.setSpace(space) end return true end # For stable baseline, remove all daylighting controls (sidelighting and toplighting) # @param space [OpenStudio::Model::Space] the space with daylighting # @param remove_existing [Boolean] if true, will remove existing controls then add new ones # @param draw_areas_for_debug [Boolean] If this argument is set to true, # @return [Boolean] returns true if successful, false if not def space_set_baseline_daylighting_controls(space, remove_existing = false, draw_areas_for_debug = false) removed = space_remove_daylighting_controls(space) return removed end # Create and assign PRM computer room electric equipment schedule # # @param space [OpenStudio::Model::Space] OpenStudio Space object # @return [Boolean] returns true if successful, false if not def space_add_prm_computer_room_equipment_schedule(space) # Get proposed or baseline model model = space.model # Get space type associated with the space standard_space_type = prm_get_optional_handler(space, @sizing_run_dir, 'spaceType', 'standardsSpaceType').delete(' ').downcase # Check if the PRM computer room schedule is already in the model schedule_name = 'ASHRAE 90.1 Appendix G - Computer Room Equipment Schedule' schedule_found = model.getScheduleRulesetByName(schedule_name) # Create and assign the the electric equipment schedule if standard_space_type == 'computerroom' space.spaceType.get.electricEquipment.each do |elec_equipment| # Only create the schedule if it could not be found if !schedule_found.is_initialized computer_room_equipment_schedule_ruleset = OpenStudio::Model::ScheduleRuleset.new(model) computer_room_equipment_schedule_ruleset.setName(schedule_name) schedule_fractions = [0.25, 0.5, 0.75, 1.0, 0.25, 0.5, 0.75, 1.0, 0.25, 0.5, 0.75, 1.0] # Weekdays and weekends schedules schedule_fractions.each_with_index do |frac, i| sch_rule = OpenStudio::Model::ScheduleRule.new(computer_room_equipment_schedule_ruleset) sch_rule.setStartDate(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(i.to_i + 1), 1)) # No leap year according to PRM-RM sch_rule.setEndDate(OpenStudio::Date.new(OpenStudio::MonthOfYear.new(i.to_i + 1), Date.new(2006, i.to_i + 1, -1).day)) day_sch = sch_rule.daySchedule day_sch.setName("#{schedule_name} - Month #{i + 1} - Fraction #{frac}") model_add_vals_to_sch(model, day_sch, 'Constant', [frac]) sch_rule.setApplyAllDays(true) end # Special days schedules equipment_on = OpenStudio::Model::ScheduleDay.new(model) model_add_vals_to_sch(model, equipment_on, 'Constant', [1]) equipment_off = OpenStudio::Model::ScheduleDay.new(model) model_add_vals_to_sch(model, equipment_off, 'Constant', [0]) computer_room_equipment_schedule_ruleset.setHolidaySchedule(equipment_on) computer_room_equipment_schedule_ruleset.setCustomDay1Schedule(equipment_on) computer_room_equipment_schedule_ruleset.setCustomDay2Schedule(equipment_on) computer_room_equipment_schedule_ruleset.setSummerDesignDaySchedule(equipment_on) computer_room_equipment_schedule_ruleset.setWinterDesignDaySchedule(equipment_off) else computer_room_equipment_schedule_ruleset = model.getScheduleRulesetByName(schedule_name).get end elec_equipment.setSchedule(computer_room_equipment_schedule_ruleset) end end return true end end