NREL / OpenStudio

OpenStudio is a cross-platform collection of software tools to support whole building energy modeling using EnergyPlus and advanced daylight analysis using Radiance.
https://www.openstudio.net/
Other
492 stars 187 forks source link

Controller:MechanicalVentilation is always translated and adds all thermalZones even those voluntarily without DSOA #4219

Open jmarrec opened 3 years ago

jmarrec commented 3 years ago

Issue overview

Whenever you add an AirLoopHVAC:OutdoorAirSystem, aController:MechanicalVentilation is always translated and adds all thermalZones even those voluntarily without DesignSpecification:OutdoorAir (DSOA)

Current Behavior

As reported in https://unmethours.com/question/51739/design-specification-outdoor-air-object-name-blank/?comment=51798#post-id-51798, the user is trying to hardsize everything and explicitly not rely on any DesignSpecification:OutdoorAir (DSOA). I reviewed his AirLoopHVAC with does have hardsized terminals for all zones served.

The resulting Controller:MechanicalVentilation in IDF is as follows:

Controller:MechanicalVentilation,
  Controller Mechanical Ventilation 1,    !- Name
  Always On Discrete hvac_library,        !- Availability Schedule Name
  Yes,                                    !- Demand Controlled Ventilation
  ZoneSum,                                !- System Outdoor Air Method
  ,                                       !- Zone Maximum Outdoor Air Fraction {dimensionless}
  Thermal Zone 10,                        !- Zone or ZoneList Name 1
  ,                                       !- Design Specification Outdoor Air Object Name 1
  Thermal Zone 10 Design Spec Zone Air Dist, !- Design Specification Zone Air Distribution Object Name 1
  Thermal Zone 2,                         !- Zone or ZoneList Name 2
  ,                                       !- Design Specification Outdoor Air Object Name 2
  ,                                       !- Design Specification Zone Air Distribution Object Name 2
  Thermal Zone 3,                         !- Zone or ZoneList Name 3
  ,                                       !- Design Specification Outdoor Air Object Name 3
  ,                                       !- Design Specification Zone Air Distribution Object Name 3
  Thermal Zone 6,                         !- Zone or ZoneList Name 4
  ,                                       !- Design Specification Outdoor Air Object Name 4
  ,                                       !- Design Specification Zone Air Distribution Object Name 4
  Thermal Zone 7,                         !- Zone or ZoneList Name 5
  ,                                       !- Design Specification Outdoor Air Object Name 5
  ,                                       !- Design Specification Zone Air Distribution Object Name 5
  Thermal Zone 9,                         !- Zone or ZoneList Name 6
  slaapkamer met dressing 2,              !- Design Specification Outdoor Air Object Name 6
  ;                                       !- Design Specification Zone Air Distribution Object Name 6

As a result, the eplusout.err reports:

   ** Warning ** GetOAControllerInputs: Controller:MechanicalVentilation="CONTROLLER MECHANICAL VENTILATION 1
   **   ~~~   ** Cannot locate a matching DesignSpecification:OutdoorAir object for Zone="THERMAL ZONE 10".
   **   ~~~   ** Using default OA of 0.00944 m3/s-person and 0.0 m3/s-m2.

Expected Behavior

Steps to Reproduce

1.Check out model https://wetransfer.com/downloads/54ebbd3f8e0c4cd37359167956ca147c20210218125926/415498

Possible Solution

https://github.com/NREL/OpenStudio/blob/988dd3fcb92a7eea4a879e9543d4e2132c8ffe43/src/energyplus/ForwardTranslator/ForwardTranslateSizingZone.cpp#L267-L295

We should not push an extensible group if it's going to be empty, should we? Well not really, empty, as it's valid per IDD, but when there is no DSOA attached to the zone at all?

https://bigladdersoftware.com/epx/docs/9-4/input-output-reference/group-controllers.html#field-design-specification-outdoor-air-object-name-x

The name of the DesignSpecification:OutdoorAir object, defining the amount of outdoor air, that applies to the zone or zone list. If this field is blank, the corresponding DesignSpecification:OutdoorAir object for the zone will come from the DesignSpecification:OutdoorAir object referenced by the Sizing:Zone object for the same zone. If no such zone match is found, default values from the IDD will be used for the DesignSpecification:OutdoorAir object which is 0.0094 m3/s-person.

Details

Environment

Some additional details about your environment for this issue (if relevant):

Context

jmarrec commented 3 years ago

here is a ruby MCVE

m = Model.new
a = AirLoopHVAC.new(m)

controller = ControllerOutdoorAir.new(m)
oa = AirLoopHVACOutdoorAirSystem.new(m, controller)
oa.addToNode(a.supplyInletNode)

fan = FanVariableVolume.new(m)
fan.addToNode(a.supplyInletNode)

z = ThermalZone.new(m)
atu = AirTerminalSingleDuctConstantVolumeNoReheat.new(m, m.alwaysOnDiscreteSchedule)
a.addBranchForZone(z, atu)

# We need a ThermalZone, with at least one equipment (or useIdealAirLoads) AND a DesignDay, for the Sizing:Zone to be translated
# And it is the Sizing:Zone translation that is populating the
# Controller:MechanicalVentilation
dd = DesignDay.new(m)

pts = OpenStudio::Point3dVector.new;  pts << OpenStudio::Point3d.new(0, 0, 0); pts << OpenStudio::Point3d.new(0, 1, 0); pts << OpenStudio::Point3d.new(1, 1, 0); pts << OpenStudio::Point3d.new(1, 0, 0);
space = Space::fromFloorPrint(pts, 3, m).get()
space.setThermalZone(z)

w = ft.translateModel(m)
puts w.getObjectsByType('Controller:MechanicalVentilation')
Controller:MechanicalVentilation,
  Controller Mechanical Ventilation 1,    !- Name
  Always On Discrete,                     !- Availability Schedule Name
  No,                                     !- Demand Controlled Ventilation
  ZoneSum,                                !- System Outdoor Air Method
  ,                                       !- Zone Maximum Outdoor Air Fraction {dimensionless}
  Thermal Zone 1,                         !- Zone or ZoneList Name 1
  ,                                       !- Design Specification Outdoor Air Object Name 1
  ;                                       !- Design Specification Zone Air Distribution Object Name 1