Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Addresses #5227, updates to Controller:OutdoorAir #208

Draft
wants to merge 2 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions model/simulationtests/controller_outdoorair.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# frozen_string_literal: true

require 'openstudio'
require_relative 'lib/baseline_model'

model = BaselineModel.new

# make a 1 story, 100m X 50m, 1 zone core/perimeter building
model.add_geometry({ 'length' => 100,
'width' => 50,
'num_floors' => 1,
'floor_to_floor_height' => 3,
'plenum_height' => 1,
'perimeter_zone_depth' => 0 })

# add windows at a 40% window-to-wall ratio
model.add_windows({ 'wwr' => 0.4,
'offset' => 1,
'application_type' => 'Above Floor' })

# Make a Dual Duct AirLoopHVAC
air_loop = OpenStudio::Model::AirLoopHVAC.new(model, true)

fan = OpenStudio::Model::FanVariableVolume.new(model)
fan.addToNode(air_loop.supplyInletNode)

oa_controller = OpenStudio::Model::ControllerOutdoorAir.new(model)
oa_controller.setEconomizerControlType('ElectronicEnthalpy')
enthalpy_limit_curve = OpenStudio::Model::CurveCubic.new(model)
enthalpy_limit_curve.setName('ElectronicEnthalpyCurveA')
enthalpy_limit_curve.setCoefficient1Constant(0.01342704)
enthalpy_limit_curve.setCoefficient2x(-0.00047892)
enthalpy_limit_curve.setCoefficient3xPOW2(0.000053352)
enthalpy_limit_curve.setCoefficient4xPOW3(-0.0000018103)
enthalpy_limit_curve.setMinimumValueofx(16.6)
enthalpy_limit_curve.setMaximumValueofx(29.13)
# oa_controller.setElectronicEnthalpyLimitCurve(enthalpy_limit_curve)
min_outdoorair_sch = OpenStudio::Model::ScheduleRuleset.new(model)
min_outdoorair_sch.setName('OAFractionSched')
min_outdoorair_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 7, 0, 0), 0.05)
min_outdoorair_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 18, 0, 0), 1.0)
min_outdoorair_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 0.05)
oa_controller.setMinimumOutdoorAirSchedule(min_outdoorair_sch)
economizer_control_sch = OpenStudio::Model::ScheduleRuleset.new(model)
economizer_control_sch.setName('TimeOfDayEconomizerSch')
economizer_control_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 7, 0, 0), 0.0)
economizer_control_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 7, 30, 0), 1.0)
economizer_control_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 0.0)
oa_controller.setTimeofDayEconomizerControlSchedule(economizer_control_sch)

# Add a humidistat at 50% RH to the zone
dehumidify_sch = OpenStudio::Model::ScheduleConstant.new(model)
dehumidify_sch.setValue(50)
humidistat = OpenStudio::Model::ZoneControlHumidistat.new(model)
humidistat.setHumidifyingRelativeHumiditySetpointSchedule(dehumidify_sch)

oa_system = OpenStudio::Model::AirLoopHVACOutdoorAirSystem.new(model, oa_controller)
oa_system.addToNode(air_loop.supplyInletNode)

# After the splitter, we will now have two supply outlet nodes
supply_outlet_nodes = air_loop.supplyOutletNodes

heating_coil = OpenStudio::Model::CoilHeatingGas.new(model)
heating_coil.addToNode(supply_outlet_nodes[0])

heating_sch = OpenStudio::Model::ScheduleRuleset.new(model)
heating_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 45.0)
heating_spm = OpenStudio::Model::SetpointManagerScheduled.new(model, heating_sch)
heating_spm.addToNode(supply_outlet_nodes[0])

cooling_coil = OpenStudio::Model::CoilCoolingDXTwoSpeed.new(model)
cooling_coil.addToNode(supply_outlet_nodes[1])

cooling_sch = OpenStudio::Model::ScheduleRuleset.new(model)
cooling_sch.defaultDaySchedule.addValue(OpenStudio::Time.new(0, 24, 0, 0), 12.8)
cooling_spm = OpenStudio::Model::SetpointManagerScheduled.new(model, cooling_sch)
cooling_spm.addToNode(supply_outlet_nodes[1])

# In order to produce more consistent results between different runs,
# we sort the zones by names (doesn't matter here, just in case)
zones = model.getThermalZones.sort_by { |z| z.name.to_s }
zones.each do |zone|
terminal = OpenStudio::Model::AirTerminalDualDuctVAV.new(model)
air_loop.addBranchForZone(zone, terminal)
end

zone = zones[0]
zone.setZoneControlHumidistat(humidistat)
# oa_controller.setHumidistatControlZone(zone)

# add thermostats
model.add_thermostats({ 'heating_setpoint' => 24,
'cooling_setpoint' => 28 })

# assign constructions from a local library to the walls/windows/etc. in the model
model.set_constructions

# set whole building space type; simplified 90.1-2004 Large Office Whole Building
model.set_space_type

# add design days to the model (Chicago)
model.add_design_days

# save the OpenStudio model (.osm)
model.save_openstudio_osm({ 'osm_save_directory' => Dir.pwd,
'osm_name' => 'in.osm' })
9 changes: 9 additions & 0 deletions model_tests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,15 @@ def test_coilsystem_integrated_heatpump_osm
result = sim_test('coilsystem_integrated_heatpump.osm')
end

# TODO: To be added in the next official release after: 3.8.0
# def test_controller_outdoorair_osm
# result = sim_test('controller_outdoorair.osm')
# end

def test_controller_outdoorair_rb
result = sim_test('controller_outdoorair.rb')
end

def test_coolingtowers_osm
result = sim_test('coolingtowers.osm')
end
Expand Down