LCOV - code coverage report
Current view: top level - EnergyPlus - DataSizing.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 81.5 % 844 688
Test Date: 2025-05-22 16:09:37 Functions: 100.0 % 24 24

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // EnergyPlus Headers
      49              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      50              : #include <EnergyPlus/DataContaminantBalance.hh>
      51              : #include <EnergyPlus/DataEnvironment.hh>
      52              : #include <EnergyPlus/DataHeatBalance.hh>
      53              : #include <EnergyPlus/DataSizing.hh>
      54              : #include <EnergyPlus/DataZoneEnergyDemands.hh>
      55              : #include <EnergyPlus/DataZoneEquipment.hh>
      56              : #include <EnergyPlus/Psychrometrics.hh>
      57              : #include <EnergyPlus/ScheduleManager.hh>
      58              : #include <EnergyPlus/SizingManager.hh>
      59              : 
      60              : namespace EnergyPlus::DataSizing {
      61              : 
      62              : // MODULE INFORMATION:
      63              : //       AUTHOR         Fred Buhl
      64              : //       DATE WRITTEN   December 2000
      65              : 
      66              : // PURPOSE OF THIS MODULE:
      67              : // This data-only module contains type definitions and variables
      68              : // associated with HVAC system design flow rates, temperatures and
      69              : // capacities. This data is available to the HVAC component modules
      70              : // for their self sizing calculations.
      71              : 
      72              : //  days; includes effects of user multiplier
      73              : //  and user set flows)
      74              : //  of user input multiplier and flows
      75              : //  all design days, calculated only)
      76              : //  using user input system flow rates.
      77              : //  before applying user input sys flow rates.
      78              : 
      79        10220 : Real64 TermUnitSizingData::applyTermUnitSizingCoolFlow(Real64 const coolFlowWithOA, // Cooling flow rate with MinOA limit applied
      80              :                                                        Real64 const coolFlowNoOA    // Cooling flow rate without MinOA limit applied
      81              : )
      82              : {
      83              :     // Apply DesignSpecification:AirTerminal:Sizing to cooling flow (could be vol flow or mass flow)
      84        10220 :     Real64 coolFlowRatio = 1.0;
      85        10220 :     if (this->SpecDesCoolSATRatio > 0.0) {
      86        10220 :         coolFlowRatio = this->SpecDesSensCoolingFrac / this->SpecDesCoolSATRatio;
      87              :     } else {
      88            0 :         coolFlowRatio = this->SpecDesSensCoolingFrac;
      89              :     }
      90        10220 :     Real64 adjustedFlow = coolFlowNoOA * coolFlowRatio + (coolFlowWithOA - coolFlowNoOA) * this->SpecMinOAFrac;
      91        10220 :     return adjustedFlow;
      92              : }
      93              : 
      94        10220 : Real64 TermUnitSizingData::applyTermUnitSizingHeatFlow(Real64 const heatFlowWithOA, // Heating flow rate with MinOA limit applied
      95              :                                                        Real64 const heatFlowNoOA    // Heating flow rate without MinOA limit applied
      96              : )
      97              : {
      98              :     // Apply DesignSpecification:AirTerminal:Sizing to heating flow (could be vol flow or mass flow)
      99        10220 :     Real64 heatFlowRatio = 1.0;
     100        10220 :     if (this->SpecDesHeatSATRatio > 0.0) {
     101        10220 :         heatFlowRatio = this->SpecDesSensHeatingFrac / this->SpecDesHeatSATRatio;
     102              :     } else {
     103            0 :         heatFlowRatio = this->SpecDesSensHeatingFrac;
     104              :     }
     105        10220 :     Real64 adjustedFlow = heatFlowNoOA * heatFlowRatio + (heatFlowWithOA - heatFlowNoOA) * this->SpecMinOAFrac;
     106        10220 :     return adjustedFlow;
     107              : }
     108              : 
     109           25 : void TermUnitZoneSizingData::scaleZoneCooling(Real64 const ratio)
     110              : {
     111              :     // Apply scaling ratio to TermUnitFinalZoneSizing cooling flow and load
     112           25 :     this->DesCoolVolFlow *= ratio;
     113           25 :     this->DesCoolMassFlow *= ratio;
     114           25 :     this->DesCoolLoad *= ratio;
     115         2425 :     for (auto &cfs : this->CoolFlowSeq) {
     116         2400 :         cfs *= ratio;
     117              :     }
     118           25 : }
     119              : 
     120           17 : void TermUnitZoneSizingData::scaleZoneHeating(Real64 const ratio)
     121              : {
     122              :     // Apply scaling ratio to TermUnitFinalZoneSizing heating flow and load
     123           17 :     this->DesHeatVolFlow *= ratio;
     124           17 :     this->DesHeatMassFlow *= ratio;
     125           17 :     this->DesHeatLoad *= ratio;
     126         1649 :     for (auto &cfs : this->HeatFlowSeq) {
     127         1632 :         cfs *= ratio;
     128              :     }
     129           17 : }
     130              : 
     131          214 : void ZoneSizingData::zeroMemberData()
     132              : {
     133          214 :     if (!allocated(this->DOASSupMassFlowSeq)) return;
     134          204 :     std::fill(this->DOASSupMassFlowSeq.begin(), this->DOASSupMassFlowSeq.end(), 0.0);
     135          204 :     std::fill(this->DOASHeatLoadSeq.begin(), this->DOASHeatLoadSeq.end(), 0.0);
     136          204 :     std::fill(this->DOASCoolLoadSeq.begin(), this->DOASCoolLoadSeq.end(), 0.0);
     137          204 :     std::fill(this->DOASHeatAddSeq.begin(), this->DOASHeatAddSeq.end(), 0.0);
     138          204 :     std::fill(this->DOASLatAddSeq.begin(), this->DOASLatAddSeq.end(), 0.0);
     139          204 :     std::fill(this->DOASSupTempSeq.begin(), this->DOASSupTempSeq.end(), 0.0);
     140          204 :     std::fill(this->DOASSupHumRatSeq.begin(), this->DOASSupHumRatSeq.end(), 0.0);
     141          204 :     std::fill(this->DOASTotCoolLoadSeq.begin(), this->DOASTotCoolLoadSeq.end(), 0.0);
     142          204 :     std::fill(this->HeatFlowSeq.begin(), this->HeatFlowSeq.end(), 0.0);
     143          204 :     std::fill(this->HeatFlowSeqNoOA.begin(), this->HeatFlowSeqNoOA.end(), 0.0);
     144          204 :     std::fill(this->HeatLoadSeq.begin(), this->HeatLoadSeq.end(), 0.0);
     145          204 :     std::fill(this->HeatZoneTempSeq.begin(), this->HeatZoneTempSeq.end(), 0.0);
     146          204 :     std::fill(this->DesHeatSetPtSeq.begin(), this->DesHeatSetPtSeq.end(), 0.0);
     147          204 :     std::fill(this->HeatOutTempSeq.begin(), this->HeatOutTempSeq.end(), 0.0);
     148          204 :     std::fill(this->HeatZoneRetTempSeq.begin(), this->HeatZoneRetTempSeq.end(), 0.0);
     149          204 :     std::fill(this->HeatTstatTempSeq.begin(), this->HeatTstatTempSeq.end(), 0.0);
     150          204 :     std::fill(this->HeatZoneHumRatSeq.begin(), this->HeatZoneHumRatSeq.end(), 0.0);
     151          204 :     std::fill(this->HeatOutHumRatSeq.begin(), this->HeatOutHumRatSeq.end(), 0.0);
     152          204 :     std::fill(this->CoolFlowSeq.begin(), this->CoolFlowSeq.end(), 0.0);
     153          204 :     std::fill(this->CoolFlowSeqNoOA.begin(), this->CoolFlowSeqNoOA.end(), 0.0);
     154          204 :     std::fill(this->CoolLoadSeq.begin(), this->CoolLoadSeq.end(), 0.0);
     155          204 :     std::fill(this->CoolZoneTempSeq.begin(), this->CoolZoneTempSeq.end(), 0.0);
     156          204 :     std::fill(this->DesCoolSetPtSeq.begin(), this->DesCoolSetPtSeq.end(), 0.0);
     157          204 :     std::fill(this->CoolOutTempSeq.begin(), this->CoolOutTempSeq.end(), 0.0);
     158          204 :     std::fill(this->CoolZoneRetTempSeq.begin(), this->CoolZoneRetTempSeq.end(), 0.0);
     159          204 :     std::fill(this->CoolTstatTempSeq.begin(), this->CoolTstatTempSeq.end(), 0.0);
     160          204 :     std::fill(this->CoolZoneHumRatSeq.begin(), this->CoolZoneHumRatSeq.end(), 0.0);
     161          204 :     std::fill(this->CoolOutHumRatSeq.begin(), this->CoolOutHumRatSeq.end(), 0.0);
     162          204 :     std::fill(this->HeatLoadNoDOASSeq.begin(), this->HeatLoadNoDOASSeq.end(), 0.0);
     163          204 :     std::fill(this->CoolLoadNoDOASSeq.begin(), this->CoolLoadNoDOASSeq.end(), 0.0);
     164          204 :     std::fill(this->LatentHeatLoadSeq.begin(), this->LatentHeatLoadSeq.end(), 0.0);
     165          204 :     std::fill(this->LatentCoolLoadSeq.begin(), this->LatentCoolLoadSeq.end(), 0.0);
     166          204 :     std::fill(this->HeatLatentLoadNoDOASSeq.begin(), this->HeatLatentLoadNoDOASSeq.end(), 0.0);
     167          204 :     std::fill(this->CoolLatentLoadNoDOASSeq.begin(), this->CoolLatentLoadNoDOASSeq.end(), 0.0);
     168          204 :     std::fill(this->LatentCoolFlowSeq.begin(), this->LatentCoolFlowSeq.end(), 0.0);
     169          204 :     std::fill(this->LatentHeatFlowSeq.begin(), this->LatentHeatFlowSeq.end(), 0.0);
     170              : 
     171          204 :     this->CoolDesDay = "";          // name of a sensible cooling design day
     172          204 :     this->HeatDesDay = "";          // name of a sensible heating design day
     173          204 :     this->CoolNoDOASDesDay = "";    // name of a sensible cooling design day without DOAS
     174          204 :     this->HeatNoDOASDesDay = "";    // name of a sensible heating design day without DOAS
     175          204 :     this->LatCoolDesDay = "";       // name of a latent cooling design day
     176          204 :     this->LatHeatDesDay = "";       // name of a latent heating design day
     177          204 :     this->LatCoolNoDOASDesDay = ""; // name of a latent cooling design day without DOAS
     178          204 :     this->LatHeatNoDOASDesDay = ""; // name of a latent heating design day without DOAS
     179              : 
     180          204 :     this->DesHeatMassFlow = 0.0;                // zone design heating air mass flow rate [kg/s]
     181          204 :     this->DesCoolMassFlow = 0.0;                // zone design cooling air mass flow rate [kg/s]
     182          204 :     this->DesHeatLoad = 0.0;                    // zone design heating load [W]
     183          204 :     this->DesCoolLoad = 0.0;                    // zone design cooling load [W]
     184          204 :     this->DesHeatDens = 0.0;                    // zone design heating air density [kg/m3]
     185          204 :     this->DesCoolDens = 0.0;                    // zone design cooling air density [kg/m3]
     186          204 :     this->DesHeatVolFlow = 0.0;                 // zone design heating air volume flow rate [m3/s]
     187          204 :     this->DesCoolVolFlow = 0.0;                 // zone design cooling air volume flow rate [m3/s]
     188          204 :     this->DesHeatVolFlowMax = 0.0;              // zone design heating maximum air volume flow rate [m3/s]
     189          204 :     this->DesCoolVolFlowMin = 0.0;              // zone design cooling minimum air volume flow rate [m3/s]
     190          204 :     this->DesHeatCoilInTemp = 0.0;              // zone heating coil design air inlet temperature [C]
     191          204 :     this->DesCoolCoilInTemp = 0.0;              // zone cooling coil design air inlet temperature [C]
     192          204 :     this->DesHeatCoilInHumRat = 0.0;            // zone heating coil design air inlet humidity ratio [kg/kg]
     193          204 :     this->DesCoolCoilInHumRat = 0.0;            // zone cooling coil design air inlet humidity ratio [kg/kg]
     194          204 :     this->DesHeatCoilInTempTU = 0.0;            // zone heating coil design air inlet temperature (supply air)([C]
     195          204 :     this->DesCoolCoilInTempTU = 0.0;            // zone cooling coil design air inlet temperature (supply air)[C]
     196          204 :     this->DesHeatCoilInHumRatTU = 0.0;          // zone heating coil design air inlet humidity ratio
     197          204 :     this->DesCoolCoilInHumRatTU = 0.0;          // zone cooling coil design air inlet humidity ratio
     198          204 :     this->HeatMassFlow = 0.0;                   // current zone heating air mass flow rate (HVAC time step)
     199          204 :     this->CoolMassFlow = 0.0;                   // current zone cooling air mass flow rate (HVAC time step)
     200          204 :     this->HeatLoad = 0.0;                       // current zone heating load (HVAC time step)
     201          204 :     this->CoolLoad = 0.0;                       // current zone heating load (HVAC time step)
     202          204 :     this->HeatZoneTemp = 0.0;                   // current zone temperature (heating, time step)
     203          204 :     this->HeatOutTemp = 0.0;                    // current outdoor temperature (heating, time step)
     204          204 :     this->HeatZoneRetTemp = 0.0;                // current zone return temperature (heating, time step)
     205          204 :     this->HeatTstatTemp = 0.0;                  // current zone thermostat temperature (heating, time step)
     206          204 :     this->CoolZoneTemp = 0.0;                   // current zone temperature (cooling, time step)
     207          204 :     this->CoolOutTemp = 0.0;                    // current Outdoor temperature (cooling, time step)
     208          204 :     this->CoolZoneRetTemp = 0.0;                // current zone return temperature (cooling, time step)
     209          204 :     this->CoolTstatTemp = 0.0;                  // current zone thermostat temperature (cooling, time step)
     210          204 :     this->HeatZoneHumRat = 0.0;                 // current zone humidity ratio (heating, time step)
     211          204 :     this->CoolZoneHumRat = 0.0;                 // current zone humidity ratio (cooling, time step)
     212          204 :     this->HeatOutHumRat = 0.0;                  // current outdoor humidity ratio (heating, time step)
     213          204 :     this->CoolOutHumRat = 0.0;                  // current outdoor humidity ratio (cooling, time step)
     214          204 :     this->ZoneTempAtHeatPeak = 0.0;             // zone temp at max heating [C]
     215          204 :     this->ZoneRetTempAtHeatPeak = 0.0;          // zone return temp at max heating [C]
     216          204 :     this->OutTempAtHeatPeak = 0.0;              // outdoor temperature at max heating [C]
     217          204 :     this->ZoneTempAtCoolPeak = 0.0;             // zone temp at max cooling [C]
     218          204 :     this->ZoneRetTempAtCoolPeak = 0.0;          // zone return temp at max cooling [C]
     219          204 :     this->OutTempAtCoolPeak = 0.0;              // outdoor temperature at max cooling [C]
     220          204 :     this->ZoneHumRatAtHeatPeak = 0.0;           // zone humidity ratio at max heating [kg/kg]
     221          204 :     this->ZoneHumRatAtCoolPeak = 0.0;           // zone humidity ratio at max cooling [kg/kg]
     222          204 :     this->OutHumRatAtHeatPeak = 0.0;            // outdoor humidity at max heating [kg/kg]
     223          204 :     this->OutHumRatAtCoolPeak = 0.0;            // outdoor humidity at max cooling [kg/kg]
     224          204 :     this->TimeStepNumAtHeatMax = 0;             // time step number (in day) at Heating peak
     225          204 :     this->TimeStepNumAtCoolMax = 0;             // time step number (in day) at cooling peak
     226          204 :     this->HeatDDNum = 0;                        // design day index of design day causing heating peak
     227          204 :     this->CoolDDNum = 0;                        // design day index of design day causing heating peak
     228          204 :     this->LatentHeatDDNum = 0;                  // design day index of design day causing heating peak
     229          204 :     this->LatentCoolDDNum = 0;                  // design day index of design day causing cooling peak
     230          204 :     this->LatentHeatNoDOASDDNum = 0;            // design day index of design day causing latent heating peak without DOAS
     231          204 :     this->LatentCoolNoDOASDDNum = 0;            // design day index of design day causing latent cooling peak without DOAS
     232          204 :     this->cHeatDDDate = "";                     // date of design day causing heating peak
     233          204 :     this->cCoolDDDate = "";                     // date of design day causing cooling peak
     234          204 :     this->cLatentHeatDDDate = "";               // date of design day causing heating peak
     235          204 :     this->cLatentCoolDDDate = "";               // date of design day causing cooling peak
     236          204 :     this->DOASHeatLoad = 0.0;                   // current heating load from DOAS supply air [W]
     237          204 :     this->DOASCoolLoad = 0.0;                   // current cooling load from DOAS supply air [W]
     238          204 :     this->DOASSupMassFlow = 0.0;                // current mass flow rate of DOAS supply air [kg/s]
     239          204 :     this->DOASSupTemp = 0.0;                    // current DOAS supply air temperature [C]
     240          204 :     this->DOASSupHumRat = 0.0;                  // current DOAS supply air humidity ratio [kgWater/kgDryAir]
     241          204 :     this->DOASTotCoolLoad = 0.0;                // current total cooling load imposed by DOAS supply air [W]
     242          204 :     this->HeatLoadNoDOAS = 0.0;                 // current zone heating load no DOAS (HVAC time step)
     243          204 :     this->CoolLoadNoDOAS = 0.0;                 // current zone heating load no DOAS (HVAC time step)
     244          204 :     this->HeatLatentLoad = 0.0;                 // current zone humidification load (HVAC time step)
     245          204 :     this->CoolLatentLoad = 0.0;                 // current zone dehumidification load (HVAC time step)
     246          204 :     this->HeatLatentLoadNoDOAS = 0.0;           // current zone humidification load without DOAS (HVAC time step)
     247          204 :     this->CoolLatentLoadNoDOAS = 0.0;           // current zone dehumidification load without DOAS (HVAC time step)
     248          204 :     this->ZoneHeatLatentMassFlow = 0.0;         // current mass flow rate required to meet humidification load [kg/s]
     249          204 :     this->ZoneCoolLatentMassFlow = 0.0;         // current mass flow rate required to meet dehumidification load [kg/s]
     250          204 :     this->ZoneHeatLatentVolFlow = 0.0;          // current volume flow rate required to meet humidification load [m3/s]
     251          204 :     this->ZoneCoolLatentVolFlow = 0.0;          // current volume flow rate required to meet dehumidification load [m3/s]
     252          204 :     this->DesHeatLoadNoDOAS = 0.0;              // zone design heating load without DOAS [W]
     253          204 :     this->DesCoolLoadNoDOAS = 0.0;              // zone design cooling load without DOAS [W]
     254          204 :     this->DesLatentHeatLoad = 0.0;              // current zone humidification load (HVAC time step)
     255          204 :     this->DesLatentCoolLoad = 0.0;              // current zone dehumidification load (HVAC time step)
     256          204 :     this->DesLatentHeatLoadNoDOAS = 0.0;        // current zone humidification load no DOAS (HVAC time step)
     257          204 :     this->DesLatentCoolLoadNoDOAS = 0.0;        // current zone dehumidification load no DOAS (HVAC time step)
     258          204 :     this->DesLatentHeatMassFlow = 0.0;          // current mass flow rate required to meet humidification load [kg/s]
     259          204 :     this->DesLatentCoolMassFlow = 0.0;          // current mass flow rate required to meet dehumidification load [kg/s]
     260          204 :     this->DesLatentHeatVolFlow = 0.0;           // current volume flow rate required to meet humidification load [m3/s]
     261          204 :     this->DesLatentCoolVolFlow = 0.0;           // current volume flow rate required to meet dehumidification load [m3/s]
     262          204 :     this->DesLatentHeatCoilInTemp = 0.0;        // zone heating coil design air inlet temperature [C]
     263          204 :     this->DesLatentCoolCoilInTemp = 0.0;        // zone cooling coil design air inlet temperature [C]
     264          204 :     this->DesLatentHeatCoilInHumRat = 0.0;      // zone heating coil design air inlet humidity ratio [kg/kg]
     265          204 :     this->DesLatentCoolCoilInHumRat = 0.0;      // zone cooling coil design air inlet humidity ratio [kg/kg]
     266          204 :     this->TimeStepNumAtLatentHeatMax = 0;       // time step number (in day) at latent heating peak
     267          204 :     this->TimeStepNumAtLatentCoolMax = 0;       // time step number (in day) at latent cooling peak
     268          204 :     this->TimeStepNumAtLatentHeatNoDOASMax = 0; // time step number (in day) at latent heating peak without DOAS
     269          204 :     this->TimeStepNumAtLatentCoolNoDOASMax = 0; // time step number (in day) at latent cooling peak without DOAS
     270          204 :     this->OutTempAtLatentCoolPeak = 0.0;        // outdoor temperature at max latent cooling [C]
     271          204 :     this->OutHumRatAtLatentCoolPeak = 0.0;      // outdoor humrat at max latent cooling [C]
     272          204 :     this->OutTempAtLatentHeatPeak = 0.0;        // outdoor temperature at max latent heating [C]
     273          204 :     this->OutHumRatAtLatentHeatPeak = 0.0;      // outdoor humrat at max latent heating [C]
     274          204 :     this->ZoneRetTempAtLatentCoolPeak = 0.0;    // zone return temp at max cooling [C]
     275          204 :     this->ZoneRetTempAtLatentHeatPeak = 0.0;    // zone return temp at max heating [C]
     276              : }
     277              : 
     278          547 : void ZoneSizingData::allocateMemberArrays(int const numOfTimeStepInDay)
     279              : {
     280          547 :     this->HeatFlowSeq.dimension(numOfTimeStepInDay, 0.0);
     281          547 :     this->CoolFlowSeq.dimension(numOfTimeStepInDay, 0.0);
     282          547 :     this->HeatFlowSeqNoOA.dimension(numOfTimeStepInDay, 0.0);
     283          547 :     this->CoolFlowSeqNoOA.dimension(numOfTimeStepInDay, 0.0);
     284          547 :     this->HeatLoadSeq.dimension(numOfTimeStepInDay, 0.0);
     285          547 :     this->CoolLoadSeq.dimension(numOfTimeStepInDay, 0.0);
     286          547 :     this->HeatZoneTempSeq.dimension(numOfTimeStepInDay, 0.0);
     287          547 :     this->DesHeatSetPtSeq.dimension(numOfTimeStepInDay, 0.0);
     288          547 :     this->CoolZoneTempSeq.dimension(numOfTimeStepInDay, 0.0);
     289          547 :     this->DesCoolSetPtSeq.dimension(numOfTimeStepInDay, 0.0);
     290          547 :     this->HeatOutTempSeq.dimension(numOfTimeStepInDay, 0.0);
     291          547 :     this->CoolOutTempSeq.dimension(numOfTimeStepInDay, 0.0);
     292          547 :     this->HeatZoneRetTempSeq.dimension(numOfTimeStepInDay, 0.0);
     293          547 :     this->HeatTstatTempSeq.dimension(numOfTimeStepInDay, 0.0);
     294          547 :     this->CoolZoneRetTempSeq.dimension(numOfTimeStepInDay, 0.0);
     295          547 :     this->CoolTstatTempSeq.dimension(numOfTimeStepInDay, 0.0);
     296          547 :     this->HeatZoneHumRatSeq.dimension(numOfTimeStepInDay, 0.0);
     297          547 :     this->CoolZoneHumRatSeq.dimension(numOfTimeStepInDay, 0.0);
     298          547 :     this->HeatOutHumRatSeq.dimension(numOfTimeStepInDay, 0.0);
     299          547 :     this->CoolOutHumRatSeq.dimension(numOfTimeStepInDay, 0.0);
     300          547 :     this->DOASHeatLoadSeq.dimension(numOfTimeStepInDay, 0.0);
     301          547 :     this->DOASCoolLoadSeq.dimension(numOfTimeStepInDay, 0.0);
     302          547 :     this->DOASHeatAddSeq.dimension(numOfTimeStepInDay, 0.0);
     303          547 :     this->DOASLatAddSeq.dimension(numOfTimeStepInDay, 0.0);
     304          547 :     this->DOASSupMassFlowSeq.dimension(numOfTimeStepInDay, 0.0);
     305          547 :     this->DOASSupTempSeq.dimension(numOfTimeStepInDay, 0.0);
     306          547 :     this->DOASSupHumRatSeq.dimension(numOfTimeStepInDay, 0.0);
     307          547 :     this->DOASTotCoolLoadSeq.dimension(numOfTimeStepInDay, 0.0);
     308          547 :     this->HeatLoadNoDOASSeq.dimension(numOfTimeStepInDay, 0.0);
     309          547 :     this->CoolLoadNoDOASSeq.dimension(numOfTimeStepInDay, 0.0);
     310          547 :     this->LatentHeatLoadSeq.dimension(numOfTimeStepInDay, 0.0);
     311          547 :     this->LatentCoolLoadSeq.dimension(numOfTimeStepInDay, 0.0);
     312          547 :     this->HeatLatentLoadNoDOASSeq.dimension(numOfTimeStepInDay, 0.0);
     313          547 :     this->CoolLatentLoadNoDOASSeq.dimension(numOfTimeStepInDay, 0.0);
     314          547 :     this->LatentCoolFlowSeq.dimension(numOfTimeStepInDay, 0.0);
     315          547 :     this->LatentHeatFlowSeq.dimension(numOfTimeStepInDay, 0.0);
     316          547 : }
     317              : 
     318           78 : void TermUnitZoneSizingData::allocateMemberArrays(int const numOfTimeStepInDay)
     319              : {
     320           78 :     this->HeatFlowSeq.dimension(numOfTimeStepInDay, 0.0);
     321           78 :     this->CoolFlowSeq.dimension(numOfTimeStepInDay, 0.0);
     322           78 :     this->HeatFlowSeqNoOA.dimension(numOfTimeStepInDay, 0.0);
     323           78 :     this->CoolFlowSeqNoOA.dimension(numOfTimeStepInDay, 0.0);
     324           78 :     this->HeatZoneTempSeq.dimension(numOfTimeStepInDay, 0.0);
     325           78 :     this->HeatZoneRetTempSeq.dimension(numOfTimeStepInDay, 0.0);
     326           78 :     this->CoolZoneTempSeq.dimension(numOfTimeStepInDay, 0.0);
     327           78 :     this->CoolZoneRetTempSeq.dimension(numOfTimeStepInDay, 0.0);
     328           78 : }
     329              : 
     330           82 : void TermUnitZoneSizingData::copyFromZoneSizing(ZoneSizingData const &sourceData)
     331              : {
     332           82 :     this->ZoneName = sourceData.ZoneName;
     333           82 :     this->ADUName = sourceData.ADUName;
     334           82 :     this->CoolDesTemp = sourceData.CoolDesTemp;
     335           82 :     this->HeatDesTemp = sourceData.HeatDesTemp;
     336           82 :     this->CoolDesHumRat = sourceData.CoolDesHumRat;
     337           82 :     this->HeatDesHumRat = sourceData.HeatDesHumRat;
     338           82 :     this->DesOAFlowPPer = sourceData.DesOAFlowPPer;
     339           82 :     this->DesOAFlowPerArea = sourceData.DesOAFlowPerArea;
     340           82 :     this->DesCoolMinAirFlow = sourceData.DesCoolMinAirFlow;
     341           82 :     this->DesCoolMinAirFlowFrac = sourceData.DesCoolMinAirFlowFrac;
     342           82 :     this->DesHeatMaxAirFlow = sourceData.DesHeatMaxAirFlow;
     343           82 :     this->DesHeatMaxAirFlowFrac = sourceData.DesHeatMaxAirFlowFrac;
     344           82 :     this->ZoneNum = sourceData.ZoneNum;
     345           82 :     this->DesHeatMassFlow = sourceData.DesHeatMassFlow;
     346           82 :     this->DesHeatMassFlowNoOA = sourceData.DesHeatMassFlowNoOA;
     347           82 :     this->DesHeatOAFlowFrac = sourceData.DesHeatOAFlowFrac;
     348           82 :     this->DesCoolMassFlow = sourceData.DesCoolMassFlow;
     349           82 :     this->DesCoolMassFlowNoOA = sourceData.DesCoolMassFlowNoOA;
     350           82 :     this->DesCoolOAFlowFrac = sourceData.DesCoolOAFlowFrac;
     351           82 :     this->DesHeatLoad = sourceData.DesHeatLoad;
     352           82 :     this->NonAirSysDesHeatLoad = sourceData.NonAirSysDesHeatLoad;
     353           82 :     this->DesCoolLoad = sourceData.DesCoolLoad;
     354           82 :     this->NonAirSysDesCoolLoad = sourceData.NonAirSysDesCoolLoad;
     355           82 :     this->DesHeatVolFlow = sourceData.DesHeatVolFlow;
     356           82 :     this->DesHeatVolFlowNoOA = sourceData.DesHeatVolFlowNoOA;
     357           82 :     this->NonAirSysDesHeatVolFlow = sourceData.NonAirSysDesHeatVolFlow;
     358           82 :     this->DesCoolVolFlow = sourceData.DesCoolVolFlow;
     359           82 :     this->DesCoolVolFlowNoOA = sourceData.DesCoolVolFlowNoOA;
     360           82 :     this->NonAirSysDesCoolVolFlow = sourceData.NonAirSysDesCoolVolFlow;
     361           82 :     this->DesHeatVolFlowMax = sourceData.DesHeatVolFlowMax;
     362           82 :     this->DesCoolVolFlowMin = sourceData.DesCoolVolFlowMin;
     363           82 :     this->DesHeatCoilInTempTU = sourceData.DesHeatCoilInTempTU;
     364           82 :     this->DesCoolCoilInTempTU = sourceData.DesCoolCoilInTempTU;
     365           82 :     this->DesHeatCoilInHumRatTU = sourceData.DesHeatCoilInHumRatTU;
     366           82 :     this->DesCoolCoilInHumRatTU = sourceData.DesCoolCoilInHumRatTU;
     367           82 :     this->ZoneTempAtHeatPeak = sourceData.ZoneTempAtHeatPeak;
     368           82 :     this->ZoneRetTempAtHeatPeak = sourceData.ZoneRetTempAtHeatPeak;
     369           82 :     this->ZoneTempAtCoolPeak = sourceData.ZoneTempAtCoolPeak;
     370           82 :     this->ZoneRetTempAtCoolPeak = sourceData.ZoneRetTempAtCoolPeak;
     371           82 :     this->ZoneHumRatAtHeatPeak = sourceData.ZoneHumRatAtHeatPeak;
     372           82 :     this->ZoneHumRatAtCoolPeak = sourceData.ZoneHumRatAtCoolPeak;
     373           82 :     this->TimeStepNumAtHeatMax = sourceData.TimeStepNumAtHeatMax;
     374           82 :     this->TimeStepNumAtCoolMax = sourceData.TimeStepNumAtCoolMax;
     375           82 :     this->HeatDDNum = sourceData.HeatDDNum;
     376           82 :     this->CoolDDNum = sourceData.CoolDDNum;
     377           82 :     this->MinOA = sourceData.MinOA;
     378           82 :     this->DesCoolMinAirFlow2 = sourceData.DesCoolMinAirFlow2;
     379           82 :     this->DesHeatMaxAirFlow2 = sourceData.DesHeatMaxAirFlow2;
     380         8698 :     for (size_t t = 1; t <= this->HeatFlowSeq.size(); ++t) {
     381         8616 :         this->HeatFlowSeq(t) = sourceData.HeatFlowSeq(t);
     382         8616 :         this->HeatFlowSeqNoOA(t) = sourceData.HeatFlowSeqNoOA(t);
     383         8616 :         this->CoolFlowSeq(t) = sourceData.CoolFlowSeq(t);
     384         8616 :         this->CoolFlowSeqNoOA(t) = sourceData.CoolFlowSeqNoOA(t);
     385         8616 :         this->HeatZoneTempSeq(t) = sourceData.HeatZoneTempSeq(t);
     386         8616 :         this->HeatZoneRetTempSeq(t) = sourceData.HeatZoneRetTempSeq(t);
     387         8616 :         this->CoolZoneTempSeq(t) = sourceData.CoolZoneTempSeq(t);
     388         8616 :         this->CoolZoneRetTempSeq(t) = sourceData.CoolZoneRetTempSeq(t);
     389              :     }
     390           82 :     this->ZoneADEffCooling = sourceData.ZoneADEffCooling;
     391           82 :     this->ZoneADEffHeating = sourceData.ZoneADEffHeating;
     392           82 :     this->ZoneSecondaryRecirculation = sourceData.ZoneSecondaryRecirculation;
     393           82 :     this->ZoneVentilationEff = sourceData.ZoneVentilationEff;
     394           82 :     this->ZonePrimaryAirFraction = sourceData.ZonePrimaryAirFraction;
     395           82 :     this->ZonePrimaryAirFractionHtg = sourceData.ZonePrimaryAirFractionHtg;
     396           82 :     this->ZoneOAFracCooling = sourceData.ZoneOAFracCooling;
     397           82 :     this->ZoneOAFracHeating = sourceData.ZoneOAFracHeating;
     398           82 :     this->TotalOAFromPeople = sourceData.TotalOAFromPeople;
     399           82 :     this->TotalOAFromArea = sourceData.TotalOAFromArea;
     400           82 :     this->TotPeopleInZone = sourceData.TotPeopleInZone;
     401           82 :     this->TotalZoneFloorArea = sourceData.TotalZoneFloorArea;
     402           82 :     this->SupplyAirAdjustFactor = sourceData.SupplyAirAdjustFactor;
     403           82 :     this->ZpzClgByZone = sourceData.ZpzClgByZone;
     404           82 :     this->ZpzHtgByZone = sourceData.ZpzHtgByZone;
     405           82 :     this->VozClgByZone = sourceData.VozClgByZone;
     406           82 :     this->VozHtgByZone = sourceData.VozHtgByZone;
     407           82 :     this->VpzMinByZoneSPSized = sourceData.VpzMinByZoneSPSized;
     408           82 :     this->ZoneSizThermSetPtHi = sourceData.ZoneSizThermSetPtHi;
     409           82 :     this->ZoneSizThermSetPtLo = sourceData.ZoneSizThermSetPtLo;
     410           82 : }
     411              : 
     412           76 : void resetHVACSizingGlobals(EnergyPlusData &state,
     413              :                             int const curZoneEqNum,
     414              :                             int const curSysNum,
     415              :                             bool &firstPassFlag) // called in zone equipment Report function
     416              : {
     417              :     // reset Data globals so that previously set variables are not used in other equipment models
     418           76 :     state.dataSize->DataTotCapCurveIndex = 0;
     419           76 :     state.dataSize->DataPltSizCoolNum = 0;
     420           76 :     state.dataSize->DataPltSizHeatNum = 0;
     421           76 :     state.dataSize->DataWaterLoopNum = 0;
     422           76 :     state.dataSize->DataCoilNum = 0;
     423           76 :     state.dataSize->DataFanOp = HVAC::FanOp::Invalid;
     424           76 :     state.dataSize->DataCoilIsSuppHeater = false;
     425           76 :     state.dataSize->DataIsDXCoil = false;
     426           76 :     state.dataSize->DataAutosizable = true;
     427           76 :     state.dataSize->DataEMSOverrideON = false;
     428           76 :     state.dataSize->DataScalableSizingON = false;
     429           76 :     state.dataSize->DataScalableCapSizingON = false;
     430           76 :     state.dataSize->DataSysScalableFlowSizingON = false;
     431           76 :     state.dataSize->DataSysScalableCapSizingON = false;
     432           76 :     state.dataSize->DataDesAccountForFanHeat = true;
     433           76 :     state.dataSize->DataDXCoolsLowSpeedsAutozize = false;
     434              : 
     435           76 :     state.dataSize->DataDesInletWaterTemp = 0.0;
     436           76 :     state.dataSize->DataDesInletAirHumRat = 0.0;
     437           76 :     state.dataSize->DataDesInletAirTemp = 0.0;
     438           76 :     state.dataSize->DataDesOutletAirTemp = 0.0;
     439           76 :     state.dataSize->DataDesOutletAirHumRat = 0.0;
     440           76 :     state.dataSize->DataCoolCoilCap = 0.0;
     441           76 :     state.dataSize->DataFlowUsedForSizing = 0.0;
     442           76 :     state.dataSize->DataAirFlowUsedForSizing = 0.0;
     443           76 :     state.dataSize->DataWaterFlowUsedForSizing = 0.0;
     444           76 :     state.dataSize->DataCapacityUsedForSizing = 0.0;
     445           76 :     state.dataSize->DataDesignCoilCapacity = 0.0;
     446           76 :     state.dataSize->DataHeatSizeRatio = 1.0;
     447           76 :     state.dataSize->DataEMSOverride = 0.0;
     448           76 :     state.dataSize->DataBypassFrac = 0.0;
     449           76 :     state.dataSize->DataFracOfAutosizedCoolingAirflow = 1.0;
     450           76 :     state.dataSize->DataFracOfAutosizedHeatingAirflow = 1.0;
     451           76 :     state.dataSize->DataFlowPerCoolingCapacity = 0.0;
     452           76 :     state.dataSize->DataFlowPerHeatingCapacity = 0.0;
     453           76 :     state.dataSize->DataFracOfAutosizedCoolingCapacity = 1.0;
     454           76 :     state.dataSize->DataFracOfAutosizedHeatingCapacity = 1.0;
     455           76 :     state.dataSize->DataAutosizedCoolingCapacity = 0.0;
     456           76 :     state.dataSize->DataAutosizedHeatingCapacity = 0.0;
     457           76 :     state.dataSize->DataConstantUsedForSizing = 0.0;
     458           76 :     state.dataSize->DataFractionUsedForSizing = 0.0;
     459           76 :     state.dataSize->DataNonZoneNonAirloopValue = 0.0;
     460           76 :     state.dataSize->DataZoneNumber = 0;
     461           76 :     state.dataSize->DataFanType = HVAC::FanType::Invalid;
     462           76 :     state.dataSize->DataFanIndex = 0;
     463           76 :     state.dataSize->DataWaterCoilSizCoolDeltaT = 0.0;
     464           76 :     state.dataSize->DataWaterCoilSizHeatDeltaT = 0.0;
     465           76 :     state.dataSize->DataNomCapInpMeth = false;
     466           76 :     state.dataSize->DataFanPlacement = HVAC::FanPlace::Invalid;
     467           76 :     state.dataSize->DataDXSpeedNum = 0;
     468           76 :     state.dataSize->DataCoilSizingAirInTemp = 0.0;
     469           76 :     state.dataSize->DataCoilSizingAirInHumRat = 0.0;
     470           76 :     state.dataSize->DataCoilSizingAirOutTemp = 0.0;
     471           76 :     state.dataSize->DataCoilSizingAirOutHumRat = 0.0;
     472           76 :     state.dataSize->DataCoolCoilType = -1;
     473           76 :     state.dataSize->DataCoolCoilIndex = -1;
     474              : 
     475              :     // These zone specific sizing variables are set in zone equipment to use for sizing.
     476              :     // Reset to avoid chance that second zone equipment will size using these variables set by first zone equipment to be sized
     477           76 :     if (curZoneEqNum > 0) {
     478              : 
     479           58 :         if (state.dataSize->ZoneEqSizing.size() == 0) {
     480            1 :             firstPassFlag = false;
     481            1 :             return;
     482              :         }
     483              : 
     484           57 :         auto &ZoneEqSizing = state.dataSize->ZoneEqSizing(curZoneEqNum);
     485           57 :         ZoneEqSizing.AirFlow = false;
     486           57 :         ZoneEqSizing.CoolingAirFlow = false;
     487           57 :         ZoneEqSizing.HeatingAirFlow = false;
     488           57 :         ZoneEqSizing.SystemAirFlow = false;
     489           57 :         ZoneEqSizing.Capacity = false;
     490           57 :         ZoneEqSizing.CoolingCapacity = false;
     491           57 :         ZoneEqSizing.HeatingCapacity = false;
     492           57 :         ZoneEqSizing.AirVolFlow = 0.0;
     493           57 :         ZoneEqSizing.MaxHWVolFlow = 0.0;
     494           57 :         ZoneEqSizing.MaxCWVolFlow = 0.0;
     495           57 :         ZoneEqSizing.OAVolFlow = 0.0;
     496           57 :         ZoneEqSizing.DesCoolingLoad = 0.0;
     497           57 :         ZoneEqSizing.DesHeatingLoad = 0.0;
     498           57 :         ZoneEqSizing.CoolingAirVolFlow = 0.0;
     499           57 :         ZoneEqSizing.HeatingAirVolFlow = 0.0;
     500           57 :         ZoneEqSizing.SystemAirVolFlow = 0.0;
     501           57 :         ZoneEqSizing.DesignSizeFromParent = false;
     502              :     }
     503              : 
     504           75 :     if (curSysNum > 0) {
     505              : 
     506           16 :         if (state.dataSize->UnitarySysEqSizing.size() == 0) {
     507            0 :             firstPassFlag = false;
     508            0 :             return;
     509              :         }
     510              : 
     511           16 :         auto &UnitarySysEqSizing = state.dataSize->UnitarySysEqSizing(curSysNum);
     512           16 :         UnitarySysEqSizing.AirFlow = false;
     513           16 :         UnitarySysEqSizing.CoolingAirFlow = false;
     514           16 :         UnitarySysEqSizing.HeatingAirFlow = false;
     515           16 :         UnitarySysEqSizing.Capacity = false;
     516           16 :         UnitarySysEqSizing.CoolingCapacity = false;
     517           16 :         UnitarySysEqSizing.HeatingCapacity = false;
     518              :     }
     519              : 
     520           75 :     firstPassFlag = false;
     521              : }
     522              : 
     523           33 : void GetCoilDesFlowT(EnergyPlusData &state,
     524              :                      int SysNum,           // central air system index
     525              :                      Real64 CpAir,         // specific heat to be used in calculations [J/kgC]
     526              :                      Real64 &DesFlow,      // returned design mass flow [kg/s]
     527              :                      Real64 &DesExitTemp,  // returned design coil exit temperature [kg/s]
     528              :                      Real64 &DesExitHumRat // returned design coil exit humidity ratio [kg/kg]
     529              : )
     530              : {
     531              :     // FUNCTION INFORMATION:
     532              :     //       AUTHOR         Fred Buhl
     533              :     //       DATE WRITTEN   September 2014
     534              : 
     535              :     // PURPOSE OF THIS FUNCTION:
     536              :     // This function calculates the coil design air flow rate and exit temperature depending on the
     537              :     // cooling capacity control method
     538              : 
     539              :     // METHODOLOGY EMPLOYED:
     540              :     // energy and mass flow balance
     541              : 
     542              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
     543           33 :     int TimeStepAtPeak = 0;
     544           33 :     Real64 ZoneCoolLoadSum = 0; // sum of zone cooling loads at the peak [W]
     545           33 :     Real64 AvgZoneTemp = 0;     // average zone temperature [C]
     546              : 
     547           33 :     auto &finalSysSizing = state.dataSize->FinalSysSizing(SysNum);
     548           33 :     auto &sysSizPeakDDNum = state.dataSize->SysSizPeakDDNum(SysNum);
     549           33 :     auto &calcSysSizing = state.dataSize->CalcSysSizing(SysNum);
     550              : 
     551           33 :     int sysSizIndex = Util::FindItemInList(finalSysSizing.AirPriLoopName, state.dataSize->SysSizInput, &SystemSizingInputData::AirPriLoopName);
     552           33 :     if (sysSizIndex == 0) sysSizIndex = 1;
     553           33 :     auto &sysSizInput = state.dataSize->SysSizInput(sysSizIndex);
     554              : 
     555           33 :     if (sysSizPeakDDNum.SensCoolPeakDD > 0) {
     556           29 :         if (sysSizInput.coolingPeakLoad == PeakLoad::TotalCooling) {
     557           11 :             TimeStepAtPeak = sysSizPeakDDNum.TimeStepAtTotCoolPk(sysSizPeakDDNum.TotCoolPeakDD);
     558              :         } else {
     559           18 :             TimeStepAtPeak = sysSizPeakDDNum.TimeStepAtSensCoolPk(sysSizPeakDDNum.SensCoolPeakDD);
     560              :         }
     561              :     } else {
     562            4 :         if ((sysSizInput.CoolCapControl == CapacityControl::VT) || (sysSizInput.CoolCapControl == CapacityControl::Bypass)) {
     563            4 :             ShowWarningError(state,
     564            4 :                              format("GetCoilDesFlow: AirLoopHVAC = {} has no time of peak cooling load for sizing.", sysSizInput.AirPriLoopName));
     565            4 :             ShowContinueError(state, "Using Central Cooling Capacity Control Method=VAV instead of Bypass or VT.");
     566            2 :             sysSizInput.CoolCapControl = CapacityControl::VAV;
     567              :         }
     568              :     }
     569              : 
     570           33 :     if (sysSizInput.CoolCapControl == CapacityControl::VAV) {
     571           15 :         DesExitTemp = finalSysSizing.CoolSupTemp;
     572           15 :         DesFlow = finalSysSizing.MassFlowAtCoolPeak / state.dataEnvrn->StdRhoAir;
     573           15 :         DesExitHumRat = finalSysSizing.CoolSupHumRat;
     574           18 :     } else if (sysSizInput.CoolCapControl == CapacityControl::OnOff) {
     575            6 :         DesExitTemp = finalSysSizing.CoolSupTemp;
     576            6 :         DesFlow = state.dataSize->DataAirFlowUsedForSizing;
     577            6 :         DesExitHumRat = finalSysSizing.CoolSupHumRat;
     578           12 :     } else if (sysSizInput.CoolCapControl == CapacityControl::VT) {
     579            6 :         ZoneCoolLoadSum = calcSysSizing.SumZoneCoolLoadSeq(TimeStepAtPeak);
     580            6 :         AvgZoneTemp = calcSysSizing.CoolZoneAvgTempSeq(TimeStepAtPeak);
     581            6 :         DesExitTemp =
     582            6 :             max(finalSysSizing.CoolSupTemp, AvgZoneTemp - ZoneCoolLoadSum / (state.dataEnvrn->StdRhoAir * CpAir * finalSysSizing.DesCoolVolFlow));
     583            6 :         DesFlow = finalSysSizing.DesCoolVolFlow;
     584            6 :         DesExitHumRat = Psychrometrics::PsyWFnTdbRhPb(state, DesExitTemp, 0.9, state.dataEnvrn->StdBaroPress, "GetCoilDesFlowT");
     585            6 :     } else if (sysSizInput.CoolCapControl == CapacityControl::Bypass) {
     586            6 :         ZoneCoolLoadSum = calcSysSizing.SumZoneCoolLoadSeq(TimeStepAtPeak);
     587            6 :         AvgZoneTemp = calcSysSizing.CoolZoneAvgTempSeq(TimeStepAtPeak);
     588            6 :         DesExitTemp = finalSysSizing.CoolSupTemp;
     589            6 :         if (calcSysSizing.MixTempAtCoolPeak > DesExitTemp) {
     590            5 :             Real64 AvgSupTemp = AvgZoneTemp - ZoneCoolLoadSum / (state.dataEnvrn->StdRhoAir * CpAir * finalSysSizing.DesCoolVolFlow);
     591            5 :             DesFlow = finalSysSizing.DesCoolVolFlow *
     592            5 :                       max(0.0, min(1.0, ((calcSysSizing.MixTempAtCoolPeak - AvgSupTemp) / (calcSysSizing.MixTempAtCoolPeak - DesExitTemp))));
     593              :         } else {
     594            1 :             DesFlow = finalSysSizing.DesCoolVolFlow;
     595              :         }
     596            6 :         DesExitHumRat = Psychrometrics::PsyWFnTdbRhPb(state, DesExitTemp, 0.9, state.dataEnvrn->StdBaroPress, "GetCoilDesFlowT");
     597              :     }
     598           33 : }
     599              : 
     600          746 : Real64 ZoneAirDistributionData::calculateEz(EnergyPlusData &state, int const ZoneNum) // Zone index
     601              : {
     602          746 :     Real64 zoneEz = 1.0;
     603              :     // Calc the zone supplied OA flow rate counting the zone air distribution effectiveness
     604              :     //  First check whether the zone air distribution effectiveness schedule exists, if yes uses it;
     605              :     //   otherwise uses the inputs of zone distribution effectiveness in cooling mode or heating mode
     606          746 :     if (this->zoneADEffSched != nullptr) {
     607              :         // Get schedule value for the zone air distribution effectiveness
     608            0 :         zoneEz = this->zoneADEffSched->getCurrentVal();
     609              :     } else {
     610          746 :         Real64 zoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).TotalOutputRequired;
     611              : 
     612              :         // Zone in cooling mode
     613          746 :         if (zoneLoad < 0.0) zoneEz = this->ZoneADEffCooling;
     614              : 
     615              :         // Zone in heating mode
     616          746 :         if (zoneLoad > 0.0) zoneEz = this->ZoneADEffHeating;
     617              :     }
     618          746 :     if (zoneEz <= 0.0) {
     619              :         // Enforce defaults
     620            0 :         zoneEz = 1.0;
     621              :     }
     622          746 :     return zoneEz;
     623              : }
     624              : 
     625              : Real64
     626        86190 : calcDesignSpecificationOutdoorAir(EnergyPlusData &state,
     627              :                                   int const DSOAPtr,           // Pointer to DesignSpecification:OutdoorAir object
     628              :                                   int const ActualZoneNum,     // Zone index
     629              :                                   bool const UseOccSchFlag,    // Zone occupancy schedule will be used instead of using total zone occupancy
     630              :                                   bool const UseMinOASchFlag,  // Use min OA schedule in DesignSpecification:OutdoorAir object
     631              :                                   bool const PerPersonNotSet,  // when calculation should not include occupants (e.g., dual duct)
     632              :                                   bool const MaxOAVolFlowFlag, // TRUE when calculation uses occupancy schedule  (e.g., dual duct)
     633              :                                   int const spaceNum,          // Space index (if applicable)
     634              :                                   bool const calcIAQMethods)   // For IAQProcedure, PCOccSch, and PCDesOcc, calculate if true, return zero if false
     635              : {
     636        86190 :     Real64 totOAFlowRate = 0.0;
     637        86190 :     if (DSOAPtr == 0) return totOAFlowRate;
     638              : 
     639        85848 :     auto &thisDSOA = state.dataSize->OARequirements(DSOAPtr);
     640              : 
     641        85848 :     if (thisDSOA.numDSOA == 0) {
     642              :         // This is a simple DesignSpecification:OutdoorAir
     643        82893 :         return thisDSOA.calcOAFlowRate(
     644        82893 :             state, ActualZoneNum, UseOccSchFlag, UseMinOASchFlag, PerPersonNotSet, MaxOAVolFlowFlag, spaceNum, calcIAQMethods);
     645              :     } else {
     646              :         // This is a DesignSpecification:OutdoorAir:SpaceList
     647         8879 :         for (int dsoaCount = 1; dsoaCount <= thisDSOA.numDSOA; ++dsoaCount) {
     648         5924 :             if ((spaceNum == 0) || ((spaceNum > 0) && (spaceNum == thisDSOA.dsoaSpaceIndexes(dsoaCount)))) {
     649         5924 :                 totOAFlowRate += state.dataSize->OARequirements(thisDSOA.dsoaIndexes(dsoaCount))
     650         5924 :                                      .calcOAFlowRate(state,
     651              :                                                      ActualZoneNum,
     652              :                                                      UseOccSchFlag,
     653              :                                                      UseMinOASchFlag,
     654              :                                                      PerPersonNotSet,
     655              :                                                      MaxOAVolFlowFlag,
     656         5924 :                                                      thisDSOA.dsoaSpaceIndexes(dsoaCount),
     657              :                                                      calcIAQMethods);
     658              :             }
     659              :         }
     660         2955 :         return totOAFlowRate;
     661              :     }
     662              : }
     663              : 
     664            3 : int getDefaultOAReq(EnergyPlusData &state)
     665              : {
     666            3 :     if (state.dataSize->OARequirements_Default == 0) {
     667            2 :         SizingManager::GetOARequirements(state); // get the OA requirements object and set up the default
     668              :     }
     669            3 :     return state.dataSize->OARequirements_Default;
     670              : }
     671              : 
     672           15 : Real64 OARequirementsData::oaFlowArea(EnergyPlusData &state,
     673              :                                       int const zoneNum,
     674              :                                       bool const useMinOASchFlag, // Use min OA schedule in DesignSpecification:OutdoorAir object
     675              :                                       int const spaceNum)         // Space index (if applicable)
     676              : {
     677           15 :     Real64 sumAreaOA = 0.0; // OA Flow Rate based on area [m3/s]
     678           15 :     if (this->numDSOA == 0) {
     679              :         // This is a simple DesignSpecification:OutdoorAir
     680           12 :         if (this->OAFlowMethod != OAFlowCalcMethod::PerPerson && this->OAFlowMethod != OAFlowCalcMethod::PerZone &&
     681           12 :             this->OAFlowMethod != OAFlowCalcMethod::ACH) {
     682           12 :             if (spaceNum == 0) {
     683           12 :                 sumAreaOA = state.dataHeatBal->Zone(zoneNum).FloorArea * this->OAFlowPerArea;
     684              :             } else {
     685            0 :                 sumAreaOA = state.dataHeatBal->space(spaceNum).FloorArea * this->OAFlowPerArea;
     686              :             }
     687           12 :             if (useMinOASchFlag && (this->oaFlowFracSched != nullptr)) {
     688           12 :                 sumAreaOA *= this->oaFlowFracSched->getCurrentVal();
     689              :             }
     690              :         }
     691              :     } else {
     692              :         // This is a DesignSpecification:OutdoorAir:SpaceList
     693           13 :         for (int dsoaCount = 1; dsoaCount <= this->numDSOA; ++dsoaCount) {
     694           10 :             auto const &thisDSOA = state.dataSize->OARequirements(this->dsoaIndexes(dsoaCount));
     695           10 :             int const dsoaSpaceNum = this->dsoaSpaceIndexes(dsoaCount);
     696           10 :             if (thisDSOA.OAFlowMethod != OAFlowCalcMethod::PerPerson && thisDSOA.OAFlowMethod != OAFlowCalcMethod::PerZone &&
     697            8 :                 thisDSOA.OAFlowMethod != OAFlowCalcMethod::ACH) {
     698            7 :                 if ((spaceNum == 0) || (spaceNum == dsoaSpaceNum)) {
     699            7 :                     Real64 spaceArea = state.dataHeatBal->space(this->dsoaSpaceIndexes(dsoaCount)).FloorArea;
     700            7 :                     Real64 spaceOAArea = thisDSOA.OAFlowPerArea * spaceArea;
     701            7 :                     if (useMinOASchFlag && (thisDSOA.oaFlowFracSched != nullptr)) {
     702            0 :                         spaceOAArea *= thisDSOA.oaFlowFracSched->getCurrentVal();
     703              :                     }
     704            7 :                     sumAreaOA += spaceOAArea;
     705              :                 }
     706              :             }
     707              :         }
     708              :     }
     709           15 :     auto &thisZone = state.dataHeatBal->Zone(zoneNum);
     710           15 :     sumAreaOA = sumAreaOA * thisZone.Multiplier * thisZone.ListMultiplier;
     711           15 :     return sumAreaOA;
     712              : }
     713              : 
     714            3 : Real64 OARequirementsData::floorArea(EnergyPlusData &state, int const zoneNum,
     715              :                                      int const spaceNum) // Space index (if applicable)
     716              : {
     717            3 :     Real64 sumArea = 0.0; // Zone or space floor area [m2]
     718            3 :     if (this->numDSOA == 0) {
     719              :         // This is a simple DesignSpecification:OutdoorAir
     720            0 :         if (spaceNum == 0) {
     721            0 :             sumArea = state.dataHeatBal->Zone(zoneNum).FloorArea;
     722              :         } else {
     723            0 :             sumArea = state.dataHeatBal->space(spaceNum).FloorArea;
     724              :         }
     725              :     } else {
     726              :         // This is a DesignSpecification:OutdoorAir:SpaceList
     727           13 :         for (int dsoaCount = 1; dsoaCount <= this->numDSOA; ++dsoaCount) {
     728           10 :             auto const &thisDSOA = state.dataSize->OARequirements(this->dsoaIndexes(dsoaCount));
     729           10 :             int const dsoaSpaceNum = this->dsoaSpaceIndexes(dsoaCount);
     730           10 :             if ((spaceNum == 0) || (spaceNum == dsoaSpaceNum)) {
     731           10 :                 Real64 spaceArea = state.dataHeatBal->space(this->dsoaSpaceIndexes(dsoaCount)).FloorArea;
     732           10 :                 sumArea += spaceArea;
     733              :             }
     734              :         }
     735              :     }
     736            3 :     auto &thisZone = state.dataHeatBal->Zone(zoneNum);
     737            3 :     sumArea = sumArea * thisZone.Multiplier * thisZone.ListMultiplier;
     738            3 :     return sumArea;
     739              : }
     740              : 
     741          131 : Real64 OARequirementsData::desFlowPerZoneArea(EnergyPlusData &state, int const zoneNum, int const spaceNum)
     742              : {
     743          131 :     Real64 desFlowPA = 0.0;
     744          131 :     if (this->numDSOA == 0) {
     745              :         // This is a simple DesignSpecification:OutdoorAir
     746          128 :         if (this->OAFlowMethod != OAFlowCalcMethod::PerPerson && this->OAFlowMethod != OAFlowCalcMethod::PerZone &&
     747           64 :             this->OAFlowMethod != OAFlowCalcMethod::ACH) {
     748           62 :             desFlowPA = this->OAFlowPerArea;
     749              :         }
     750              :     } else {
     751              :         // This is a DesignSpecification:OutdoorAir:SpaceList
     752            3 :         bool useMinOASch = false;
     753            3 :         Real64 sumAreaOA = this->oaFlowArea(state, zoneNum, useMinOASch, spaceNum);
     754            3 :         Real64 sumArea = this->floorArea(state, zoneNum, spaceNum);
     755            3 :         if (sumArea > 0.0) {
     756            3 :             desFlowPA = sumAreaOA / sumArea;
     757              :         }
     758              :     }
     759          131 :     return desFlowPA;
     760              : }
     761              : 
     762           18 : Real64 OARequirementsData::oaFlowPeople(EnergyPlusData &state,
     763              :                                         int const zoneNum,          // Zone index
     764              :                                         bool const useOccSchFlag,   // Use occupancy schedule
     765              :                                         bool const useMinOASchFlag, // Use min OA schedule in DesignSpecification:OutdoorAir object
     766              :                                         int const spaceNum)         // Space index (if applicable)
     767              : {
     768           18 :     Real64 sumPeopleOA = 0.0; // OA Flow Rate based on people [m3/s]
     769           18 :     if (this->numDSOA == 0) {
     770              :         // This is a simple DesignSpecification:OutdoorAir
     771           14 :         if (this->OAFlowMethod != OAFlowCalcMethod::PerArea && this->OAFlowMethod != OAFlowCalcMethod::PerZone &&
     772           14 :             this->OAFlowMethod != OAFlowCalcMethod::ACH) {
     773           14 :             Real64 sumPeople = 0.0; // Zone or space number of people
     774           14 :             if (spaceNum == 0) {
     775           14 :                 if (useOccSchFlag) {
     776            2 :                     sumPeople = state.dataHeatBal->ZoneIntGain(zoneNum).NOFOCC;
     777              :                 } else {
     778           12 :                     sumPeople = state.dataHeatBal->Zone(zoneNum).TotOccupants;
     779              :                 }
     780              :             } else {
     781            0 :                 if (useOccSchFlag) {
     782            0 :                     sumPeople = state.dataHeatBal->space(spaceNum).TotOccupants;
     783              :                 } else {
     784            0 :                     sumPeople = state.dataHeatBal->spaceIntGain(spaceNum).NOFOCC;
     785              :                 }
     786              :             }
     787           14 :             sumPeopleOA = sumPeople * this->OAFlowPerPerson;
     788              :             // Apply schedule as needed. Sizing does not use schedule.
     789           14 :             if (useMinOASchFlag && (this->oaFlowFracSched != nullptr)) {
     790           14 :                 sumPeopleOA *= this->oaFlowFracSched->getCurrentVal();
     791              :             }
     792              :         }
     793              :     } else {
     794              :         // This is a DesignSpecification:OutdoorAir:SpaceList
     795           16 :         for (int dsoaCount = 1; dsoaCount <= this->numDSOA; ++dsoaCount) {
     796           12 :             auto const &thisDSOA = state.dataSize->OARequirements(this->dsoaIndexes(dsoaCount));
     797           12 :             int const dsoaSpaceNum = this->dsoaSpaceIndexes(dsoaCount);
     798           12 :             if (thisDSOA.OAFlowMethod != OAFlowCalcMethod::PerArea && thisDSOA.OAFlowMethod != OAFlowCalcMethod::PerZone &&
     799           10 :                 thisDSOA.OAFlowMethod != OAFlowCalcMethod::ACH) {
     800            9 :                 if ((spaceNum == 0) || (spaceNum == dsoaSpaceNum)) {
     801            9 :                     Real64 spacePeople = 0.0;
     802            9 :                     if (useOccSchFlag) {
     803            0 :                         spacePeople = state.dataHeatBal->spaceIntGain(spaceNum).NOFOCC;
     804              :                     } else {
     805            9 :                         spacePeople = state.dataHeatBal->space(dsoaSpaceNum).TotOccupants;
     806              :                     }
     807            9 :                     sumPeopleOA += thisDSOA.OAFlowPerPerson * spacePeople;
     808            9 :                     if (useMinOASchFlag && (thisDSOA.oaFlowFracSched != nullptr)) {
     809            0 :                         sumPeopleOA *= thisDSOA.oaFlowFracSched->getCurrentVal();
     810              :                     }
     811              :                 }
     812              :             }
     813              :         }
     814              :     }
     815           18 :     auto &thisZone = state.dataHeatBal->Zone(zoneNum);
     816           18 :     sumPeopleOA = sumPeopleOA * thisZone.Multiplier * thisZone.ListMultiplier;
     817           18 :     return sumPeopleOA;
     818              : }
     819              : 
     820            4 : Real64 OARequirementsData::people(EnergyPlusData &state,
     821              :                                   int const zoneNum,        // Zone index
     822              :                                   bool const useOccSchFlag, // Use zone occupancy schedule
     823              :                                   int const spaceNum)       // Space index (if applicable)
     824              : {
     825            4 :     Real64 sumPeople = 0.0; // Zone or space number of people
     826            4 :     if (this->numDSOA == 0) {
     827              :         // This is a simple DesignSpecification:OutdoorAir
     828            0 :         if (spaceNum == 0) {
     829            0 :             if (useOccSchFlag) {
     830            0 :                 sumPeople = state.dataHeatBal->ZoneIntGain(zoneNum).NOFOCC;
     831              :             } else {
     832            0 :                 sumPeople = state.dataHeatBal->Zone(zoneNum).TotOccupants;
     833              :             }
     834              :         } else {
     835            0 :             if (useOccSchFlag) {
     836            0 :                 sumPeople = state.dataHeatBal->space(spaceNum).TotOccupants;
     837              :             } else {
     838            0 :                 sumPeople = state.dataHeatBal->spaceIntGain(spaceNum).NOFOCC;
     839              :             }
     840              :         }
     841              :     } else {
     842              :         // This is a DesignSpecification:OutdoorAir:SpaceList
     843           16 :         for (int dsoaCount = 1; dsoaCount <= this->numDSOA; ++dsoaCount) {
     844           12 :             auto const &thisDSOA = state.dataSize->OARequirements(this->dsoaIndexes(dsoaCount));
     845           12 :             int const dsoaSpaceNum = this->dsoaSpaceIndexes(dsoaCount);
     846           12 :             if ((spaceNum == 0) || (spaceNum == dsoaSpaceNum)) {
     847           12 :                 Real64 spacePeople = 0.0;
     848           12 :                 if (useOccSchFlag) {
     849            0 :                     spacePeople = state.dataHeatBal->spaceIntGain(spaceNum).NOFOCC;
     850              :                 } else {
     851           12 :                     spacePeople = state.dataHeatBal->space(dsoaSpaceNum).TotOccupants;
     852              :                 }
     853           12 :                 sumPeople += spacePeople;
     854              :             }
     855              :         }
     856              :     }
     857            4 :     auto &thisZone = state.dataHeatBal->Zone(zoneNum);
     858            4 :     sumPeople = sumPeople * thisZone.Multiplier * thisZone.ListMultiplier;
     859            4 :     return sumPeople;
     860              : }
     861              : 
     862          148 : Real64 OARequirementsData::desFlowPerZonePerson(EnergyPlusData &state, int const zoneNum, int const spaceNum)
     863              : {
     864          148 :     Real64 desFlowPP = 0.0;
     865          148 :     if (this->numDSOA == 0) {
     866              :         // This is a simple DesignSpecification:OutdoorAir
     867          144 :         if (this->OAFlowMethod != OAFlowCalcMethod::PerArea && this->OAFlowMethod != OAFlowCalcMethod::PerZone &&
     868          137 :             this->OAFlowMethod != OAFlowCalcMethod::ACH) {
     869          135 :             desFlowPP = this->OAFlowPerPerson;
     870              :         }
     871              :     } else {
     872              :         // This is a DesignSpecification:OutdoorAir:SpaceList
     873            4 :         bool useOccSch = false; // Use the design people value
     874            4 :         bool useMinOASch = false;
     875            4 :         Real64 sumPeopleOA = this->oaFlowPeople(state, zoneNum, useOccSch, useMinOASch, spaceNum);
     876            4 :         Real64 sumPeople = this->people(state, zoneNum, useOccSch, spaceNum);
     877            4 :         if (sumPeople > 0.0) {
     878            3 :             desFlowPP = sumPeopleOA / sumPeople;
     879              :         }
     880              :     }
     881          148 :     return desFlowPP;
     882              : }
     883              : 
     884            5 : Real64 OARequirementsData::desFlowPerZone(EnergyPlusData &state, int const zoneNum, int const spaceNum)
     885              : {
     886            5 :     Real64 desFlowPZ = 0.0; // [m3/s]
     887            5 :     if (this->numDSOA == 0) {
     888              :         // This is a simple DesignSpecification:OutdoorAir
     889            5 :         if (this->OAFlowMethod != OAFlowCalcMethod::PerPerson && this->OAFlowMethod != OAFlowCalcMethod::PerArea &&
     890            4 :             this->OAFlowMethod != OAFlowCalcMethod::ACH) {
     891            4 :             desFlowPZ = this->OAFlowPerZone;
     892              :         }
     893              :     } else {
     894              :         // This is a DesignSpecification:OutdoorAir:SpaceList
     895            0 :         for (int dsoaCount = 1; dsoaCount <= this->numDSOA; ++dsoaCount) {
     896            0 :             auto const &thisDSOA = state.dataSize->OARequirements(this->dsoaIndexes(dsoaCount));
     897            0 :             int const dsoaSpaceNum = this->dsoaSpaceIndexes(dsoaCount);
     898            0 :             if (thisDSOA.OAFlowMethod != OAFlowCalcMethod::PerPerson && thisDSOA.OAFlowMethod != OAFlowCalcMethod::PerArea &&
     899            0 :                 thisDSOA.OAFlowMethod != OAFlowCalcMethod::ACH) {
     900            0 :                 if ((spaceNum == 0) || (spaceNum == dsoaSpaceNum)) {
     901            0 :                     desFlowPZ += thisDSOA.OAFlowPerZone;
     902              :                 }
     903              :             }
     904              :         }
     905              :     }
     906            5 :     return desFlowPZ;
     907              : }
     908              : 
     909            5 : Real64 OARequirementsData::desFlowPerACH(EnergyPlusData &state, int const zoneNum, int const spaceNum)
     910              : {
     911            5 :     Real64 desFlowPACH = 0.0; // [1/hr]
     912            5 :     if (this->numDSOA == 0) {
     913              :         // This is a simple DesignSpecification:OutdoorAir
     914            5 :         if (this->OAFlowMethod != OAFlowCalcMethod::PerPerson && this->OAFlowMethod != OAFlowCalcMethod::PerArea &&
     915            4 :             this->OAFlowMethod != OAFlowCalcMethod::PerZone) {
     916            4 :             desFlowPACH = this->OAFlowACH;
     917              :         }
     918              :     } else {
     919              :         // This is a DesignSpecification:OutdoorAir:SpaceList
     920            0 :         Real64 sumVolume = 0.0;
     921            0 :         Real64 sumACHFlow = 0.0;
     922            0 :         for (int dsoaCount = 1; dsoaCount <= this->numDSOA; ++dsoaCount) {
     923            0 :             auto const &thisDSOA = state.dataSize->OARequirements(this->dsoaIndexes(dsoaCount));
     924            0 :             int const dsoaSpaceNum = this->dsoaSpaceIndexes(dsoaCount);
     925            0 :             if (thisDSOA.OAFlowMethod != OAFlowCalcMethod::PerPerson && thisDSOA.OAFlowMethod != OAFlowCalcMethod::PerArea &&
     926            0 :                 thisDSOA.OAFlowMethod != OAFlowCalcMethod::PerZone) {
     927            0 :                 if ((spaceNum == 0) || (spaceNum == dsoaSpaceNum)) {
     928            0 :                     Real64 spaceVol = state.dataHeatBal->space(this->dsoaSpaceIndexes(dsoaCount)).Volume;
     929            0 :                     sumVolume += spaceVol;
     930            0 :                     Real64 spaceOAACH = thisDSOA.OAFlowACH * spaceVol;
     931            0 :                     sumACHFlow += spaceOAACH;
     932              :                 }
     933              :             }
     934              :         }
     935            0 :         if (sumVolume > 0.0) {
     936            0 :             desFlowPACH = Constant::rSecsInHour * sumACHFlow / sumVolume;
     937              :         }
     938              :     }
     939            5 :     return desFlowPACH;
     940              : }
     941              : 
     942              : Real64
     943        88817 : OARequirementsData::calcOAFlowRate(EnergyPlusData &state,
     944              :                                    int const ActualZoneNum,     // Zone index
     945              :                                    bool const UseOccSchFlag,    // Zone occupancy schedule will be used instead of using total zone occupancy
     946              :                                    bool const UseMinOASchFlag,  // Use min OA schedule in DesignSpecification:OutdoorAir object
     947              :                                    bool const PerPersonNotSet,  // when calculation should not include occupants (e.g., dual duct)
     948              :                                    bool const MaxOAVolFlowFlag, // TRUE when calculation uses occupancy schedule  (e.g., dual duct)
     949              :                                    int const spaceNum,          // Space index (if applicable)
     950              :                                    bool const calcIAQMethods    // For IAQProcedure, PCOccSch, and PCDesOcc, calculate if true, return zero if false
     951              : )
     952              : {
     953              : 
     954              :     // FUNCTION INFORMATION:
     955              :     //       AUTHOR         Richard Raustad, FSEC
     956              :     //       DATE WRITTEN   October 2012
     957              : 
     958              :     // PURPOSE OF THIS FUNCTION:
     959              :     // This function returns the air volume flow rate based on DesignSpecification:OutdoorAir object.
     960              : 
     961              :     // METHODOLOGY EMPLOYED:
     962              :     // User inputs and zone index allows calculation of outdoor air quantity.
     963              :     // Sizing does not use occupancy or min OA schedule and will call with flags set to FALSE
     964              :     // Ventilation Rate Procedure uses occupancy schedule based on user input.
     965              : 
     966              :     // Return value
     967              :     Real64 OAVolumeFlowRate; // Return value for calculated outdoor air volume flow rate [m3/s]
     968              : 
     969              :     // FUNCTION LOCAL VARIABLE DECLARATIONS:
     970              :     Real64 DSOAFlowPeople;            // Outdoor air volume flow rate based on occupancy (m3/s)
     971              :     Real64 DSOAFlowPerZone;           // Outdoor air volume flow rate (m3/s)
     972              :     Real64 DSOAFlowPerArea;           // Outdoor air volume flow rate based on zone floor area (m3/s)
     973              :     Real64 DSOAFlowACH;               // Outdoor air volume flow rate based on air changes per hour (m3/s)
     974              :     Real64 ZoneOAPeople;              // Zone OA flow rate based on number of occupants [m3/s]
     975              :     Real64 ZoneOAArea;                // Zone OA flow rate based on space floor area [m3/s]
     976              :     Real64 ZoneOAMin;                 // Minimum Zone OA flow rate when the zone is unoccupied (i.e. ZoneOAPeople = 0)
     977              :                                       // used for "ProportionalControl" System outdoor air method
     978              :     Real64 ZoneOAMax;                 // Maximum Zone OA flow rate (ZoneOAPeople + ZoneOAArea)
     979              :                                       // used for "ProportionalControl" System outdoor air method
     980              :     Real64 ZoneMaxCO2;                // Breathing-zone CO2 concentration
     981              :     Real64 ZoneMinCO2;                // Minimum CO2 concentration in zone
     982              :     Real64 ZoneContamControllerSched; // Schedule value for ZoneControl:ContaminantController
     983              :     Real64 CO2PeopleGeneration;       // CO2 generation from people at design level
     984              : 
     985        88817 :     OAVolumeFlowRate = 0.0;
     986              : 
     987        88817 :     auto &thisZone = state.dataHeatBal->Zone(ActualZoneNum);
     988        88817 :     Real64 floorArea = 0.0;
     989        88817 :     Real64 volume = 0.0;
     990        88817 :     Real64 nomTotOccupants = 0.0;
     991        88817 :     Real64 curNumOccupants = 0.0;
     992        88817 :     Real64 maxOccupants = 0.0;
     993        88817 :     if (spaceNum > 0) {
     994         5945 :         auto const &thisSpace = state.dataHeatBal->space(spaceNum);
     995         5945 :         floorArea = thisSpace.FloorArea;
     996         5945 :         volume = thisSpace.Volume;
     997         5945 :         nomTotOccupants = thisSpace.TotOccupants;
     998         5945 :         curNumOccupants = state.dataHeatBal->spaceIntGain(spaceNum).NOFOCC;
     999         5945 :         maxOccupants = thisSpace.maxOccupants;
    1000              :     } else {
    1001        82872 :         floorArea = thisZone.FloorArea;
    1002        82872 :         volume = thisZone.Volume;
    1003        82872 :         nomTotOccupants = thisZone.TotOccupants;
    1004        82872 :         curNumOccupants = state.dataHeatBal->ZoneIntGain(ActualZoneNum).NOFOCC;
    1005        82872 :         maxOccupants = thisZone.maxOccupants;
    1006              :     }
    1007              : 
    1008        88817 :     if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::IAQProcedure && this->myEnvrnFlag) {
    1009            0 :         if (!state.dataContaminantBalance->Contaminant.CO2Simulation) {
    1010            0 :             ShowSevereError(state,
    1011            0 :                             format("DesignSpecification:OutdoorAir=\"{}{}",
    1012            0 :                                    this->Name,
    1013              :                                    R"(" valid Outdoor Air Method =" IndoorAirQualityProcedure" requires CO2 simulation.)"));
    1014            0 :             ShowContinueError(state, "The choice must be Yes for the field Carbon Dioxide Concentration in ZoneAirContaminantBalance");
    1015            0 :             ShowFatalError(state, "CalcDesignSpecificationOutdoorAir: Errors found in input. Preceding condition(s) cause termination.");
    1016              :         }
    1017            0 :         this->myEnvrnFlag = false;
    1018              :     }
    1019        88817 :     if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCOccSch && this->myEnvrnFlag) {
    1020            1 :         if (!state.dataContaminantBalance->Contaminant.CO2Simulation) {
    1021            0 :             ShowSevereError(state,
    1022            0 :                             format("DesignSpecification:OutdoorAir=\"{}{}",
    1023            0 :                                    this->Name,
    1024              :                                    R"(" valid Outdoor Air Method =" ProportionalControlBasedOnDesignOccupancy" requires CO2 simulation.)"));
    1025            0 :             ShowContinueError(state, "The choice must be Yes for the field Carbon Dioxide Concentration in ZoneAirContaminantBalance");
    1026            0 :             ShowFatalError(state, "CalcDesignSpecificationOutdoorAir: Errors found in input. Preceding condition(s) cause termination.");
    1027              :         }
    1028            1 :         this->myEnvrnFlag = false;
    1029              :     }
    1030        88817 :     if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCDesOcc && this->myEnvrnFlag) {
    1031            2 :         if (!state.dataContaminantBalance->Contaminant.CO2Simulation) {
    1032            0 :             ShowSevereError(state,
    1033            0 :                             format("DesignSpecification:OutdoorAir=\"{}{}",
    1034            0 :                                    this->Name,
    1035              :                                    R"(" valid Outdoor Air Method =" ProportionalControlBasedOnOccupancySchedule" requires CO2 simulation.)"));
    1036            0 :             ShowContinueError(state, "The choice must be Yes for the field Carbon Dioxide Concentration in ZoneAirContaminantBalance");
    1037            0 :             ShowFatalError(state, "CalcDesignSpecificationOutdoorAir: Errors found in input. Preceding condition(s) cause termination.");
    1038              :         }
    1039            2 :         this->myEnvrnFlag = false;
    1040              :     }
    1041              : 
    1042        88817 :     if (!calcIAQMethods &&
    1043        36637 :         (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::IAQProcedure || this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCOccSch ||
    1044        36637 :          this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCDesOcc)) {
    1045           12 :         return OAVolumeFlowRate;
    1046              :     }
    1047              : 
    1048              :     // Calculate people outdoor air flow rate as needed
    1049        88805 :     switch (this->OAFlowMethod) {
    1050        87544 :     case OAFlowCalcMethod::PerPerson:
    1051              :     case OAFlowCalcMethod::Sum:
    1052              :     case OAFlowCalcMethod::Max: {
    1053        87544 :         if (UseOccSchFlag) {
    1054        85338 :             if (MaxOAVolFlowFlag) {
    1055              :                 // OAPerPersonMode == PerPersonDCVByCurrentLevel (UseOccSchFlag = TRUE)
    1056              :                 // for dual duct, get max people according to max schedule value when requesting MaxOAFlow
    1057            0 :                 DSOAFlowPeople = maxOccupants * this->OAFlowPerPerson;
    1058              :             } else {
    1059        85338 :                 DSOAFlowPeople = curNumOccupants * this->OAFlowPerPerson;
    1060              :             }
    1061              :         } else {
    1062         2206 :             if (MaxOAVolFlowFlag) {
    1063              :                 // OAPerPersonMode == PerPersonByDesignLevel (UseOccSchFlag = FALSE)
    1064              :                 // use total people when requesting MaxOAFlow
    1065            0 :                 DSOAFlowPeople = nomTotOccupants * this->OAFlowPerPerson;
    1066              :             } else {
    1067         2206 :                 DSOAFlowPeople = nomTotOccupants * this->OAFlowPerPerson;
    1068              :             }
    1069              :         }
    1070        87544 :         if (PerPersonNotSet) DSOAFlowPeople = 0.0; // for Dual Duct if Per Person Ventilation Rate Mode is not entered
    1071        87544 :     } break;
    1072         1261 :     default: {
    1073         1261 :         DSOAFlowPeople = 0.0;
    1074         1261 :     } break;
    1075              :     }
    1076              : 
    1077              :     // Calculate minimum outdoor air flow rate
    1078        88805 :     switch (this->OAFlowMethod) {
    1079        46729 :     case OAFlowCalcMethod::PerPerson: {
    1080              :         // Multiplied by occupancy
    1081        46729 :         OAVolumeFlowRate = DSOAFlowPeople;
    1082        46729 :     } break;
    1083         1242 :     case OAFlowCalcMethod::PerZone: {
    1084              :         // User input
    1085         1242 :         OAVolumeFlowRate = this->OAFlowPerZone;
    1086         1242 :     } break;
    1087            7 :     case OAFlowCalcMethod::PerArea: {
    1088              :         // Multiplied by zone floor area
    1089            7 :         OAVolumeFlowRate = this->OAFlowPerArea * floorArea;
    1090            7 :     } break;
    1091            8 :     case OAFlowCalcMethod::ACH: {
    1092              :         // Multiplied by zone volume
    1093            8 :         OAVolumeFlowRate = this->OAFlowACH * volume / 3600.0;
    1094            8 :     } break;
    1095        40815 :     case OAFlowCalcMethod::Sum:
    1096              :     case OAFlowCalcMethod::Max: {
    1097              :         // Use sum or max of per person and the following
    1098        40815 :         DSOAFlowPerZone = this->OAFlowPerZone;
    1099        40815 :         DSOAFlowPerArea = this->OAFlowPerArea * floorArea;
    1100        40815 :         DSOAFlowACH = this->OAFlowACH * volume / 3600.0;
    1101        40815 :         if (this->OAFlowMethod == OAFlowCalcMethod::Max) {
    1102           10 :             OAVolumeFlowRate = max(DSOAFlowPeople, DSOAFlowPerZone, DSOAFlowPerArea, DSOAFlowACH);
    1103              :         } else {
    1104        40805 :             OAVolumeFlowRate = DSOAFlowPeople + DSOAFlowPerZone + DSOAFlowPerArea + DSOAFlowACH;
    1105              :         }
    1106        40815 :     } break;
    1107            1 :     case DataSizing::OAFlowCalcMethod::IAQProcedure: {
    1108            1 :         if (state.dataGlobal->DoingSizing) {
    1109            0 :             DSOAFlowPeople = nomTotOccupants * this->OAFlowPerPerson;
    1110            0 :             DSOAFlowPerZone = this->OAFlowPerZone;
    1111            0 :             DSOAFlowPerArea = this->OAFlowPerArea * floorArea;
    1112            0 :             DSOAFlowACH = this->OAFlowACH * volume / 3600.0;
    1113            0 :             OAVolumeFlowRate = DSOAFlowPeople + DSOAFlowPerZone + DSOAFlowPerArea + DSOAFlowACH;
    1114              :         } else {
    1115            1 :             OAVolumeFlowRate = state.dataContaminantBalance->ZoneSysContDemand(ActualZoneNum).OutputRequiredToCO2SP / state.dataEnvrn->StdRhoAir;
    1116              :         }
    1117            1 :     } break;
    1118            3 :     case DataSizing::OAFlowCalcMethod::PCOccSch:
    1119              :     case DataSizing::OAFlowCalcMethod::PCDesOcc: {
    1120            3 :         ZoneOAPeople = 0.0;
    1121            3 :         if (this->OAFlowMethod != DataSizing::OAFlowCalcMethod::PCDesOcc) {
    1122            2 :             ZoneOAPeople = curNumOccupants * thisZone.Multiplier * thisZone.ListMultiplier * this->OAFlowPerPerson;
    1123              :         } else {
    1124            1 :             ZoneOAPeople = nomTotOccupants * thisZone.Multiplier * thisZone.ListMultiplier * this->OAFlowPerPerson;
    1125            1 :             CO2PeopleGeneration = 0.0;
    1126            1 :             if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCDesOcc) {
    1127              :                 // Accumulate CO2 generation from people at design occupancy and current activity level
    1128            2 :                 for (int PeopleNum = 1; PeopleNum <= state.dataHeatBal->TotPeople; ++PeopleNum) {
    1129            1 :                     if (spaceNum > 0) {
    1130            0 :                         if (state.dataHeatBal->People(PeopleNum).spaceIndex != spaceNum) continue;
    1131              :                     } else {
    1132            1 :                         if (state.dataHeatBal->People(PeopleNum).ZonePtr != ActualZoneNum) continue;
    1133              :                     }
    1134            2 :                     CO2PeopleGeneration += state.dataHeatBal->People(PeopleNum).NumberOfPeople * state.dataHeatBal->People(PeopleNum).CO2RateFactor *
    1135            1 :                                            state.dataHeatBal->People(PeopleNum).activityLevelSched->getCurrentVal();
    1136              :                 }
    1137              :             }
    1138              :         }
    1139            3 :         ZoneOAArea = floorArea * thisZone.Multiplier * thisZone.ListMultiplier * this->OAFlowPerArea;
    1140            3 :         ZoneOAMin = ZoneOAArea;
    1141            3 :         ZoneOAMax = (ZoneOAArea + ZoneOAPeople);
    1142            3 :         if (thisZone.zoneContamControllerSched != nullptr) {
    1143              :             // Check the availability schedule value for ZoneControl:ContaminantController
    1144            3 :             ZoneContamControllerSched = thisZone.zoneContamControllerSched->getCurrentVal();
    1145            3 :             if (ZoneContamControllerSched > 0.0) {
    1146            3 :                 if (ZoneOAPeople > 0.0) {
    1147            3 :                     if (state.dataContaminantBalance->ZoneCO2GainFromPeople(ActualZoneNum) > 0.0) {
    1148            3 :                         if (thisZone.zoneMinCO2Sched != nullptr) {
    1149              :                             // Take the schedule value of "Minimum Carbon Dioxide Concentration Schedule Name"
    1150              :                             // in the ZoneControl:ContaminantController
    1151            0 :                             ZoneMinCO2 = thisZone.zoneMinCO2Sched->getCurrentVal();
    1152              :                         } else {
    1153            3 :                             ZoneMinCO2 = state.dataContaminantBalance->OutdoorCO2;
    1154              :                         }
    1155              : 
    1156              :                         // Calculate zone maximum target CO2 concentration in PPM
    1157            3 :                         if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCDesOcc) {
    1158            1 :                             ZoneMaxCO2 = state.dataContaminantBalance->OutdoorCO2 +
    1159            1 :                                          (CO2PeopleGeneration * thisZone.Multiplier * thisZone.ListMultiplier * 1.0e6) / ZoneOAMax;
    1160              :                         } else {
    1161            2 :                             ZoneMaxCO2 =
    1162            2 :                                 state.dataContaminantBalance->OutdoorCO2 + (state.dataContaminantBalance->ZoneCO2GainFromPeople(ActualZoneNum) *
    1163            2 :                                                                             thisZone.Multiplier * thisZone.ListMultiplier * 1.0e6) /
    1164              :                                                                                ZoneOAMax;
    1165              :                         }
    1166              : 
    1167            3 :                         if (ZoneMaxCO2 <= ZoneMinCO2) {
    1168            0 :                             ++this->CO2MaxMinLimitErrorCount;
    1169            0 :                             if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCOccSch) {
    1170            0 :                                 if (this->CO2MaxMinLimitErrorCount < 2) {
    1171            0 :                                     ShowSevereError(state,
    1172            0 :                                                     format("CalcDesignSpecificationOutdoorAir DesignSpecification:OutdoorAir = \"{}\".", this->Name));
    1173            0 :                                     ShowContinueError(
    1174              :                                         state,
    1175            0 :                                         format("For System Outdoor Air Method = ProportionalControlBasedOnOccupancySchedule, maximum target "
    1176              :                                                "CO2 concentration ({:.2R}), is not greater than minimum target CO2 concentration ({:.2R}).",
    1177              :                                                ZoneMaxCO2,
    1178              :                                                ZoneMinCO2));
    1179            0 :                                     ShowContinueError(state,
    1180              :                                                       "\"ProportionalControlBasedOnOccupancySchedule\" will not be modeled. "
    1181              :                                                       "Default \"Flow/Person+Flow/Area\" will be modeled. Simulation continues...");
    1182            0 :                                     ShowContinueErrorTimeStamp(state, "");
    1183              :                                 } else {
    1184            0 :                                     ShowRecurringWarningErrorAtEnd(
    1185              :                                         state,
    1186            0 :                                         format("DesignSpecification:OutdoorAir = \"{}\", For System Outdoor Air Method = "
    1187              :                                                "ProportionalControlBasedOnOccupancySchedule, maximum target CO2 concentration is not greater than "
    1188              :                                                "minimum target CO2 concentration. Error continues...",
    1189            0 :                                                this->Name),
    1190            0 :                                         this->CO2MaxMinLimitErrorIndex);
    1191              :                                 }
    1192              :                             }
    1193            0 :                             if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCDesOcc) {
    1194            0 :                                 if (this->CO2MaxMinLimitErrorCount < 2) {
    1195            0 :                                     ShowSevereError(state,
    1196            0 :                                                     format("CalcDesignSpecificationOutdoorAir DesignSpecification:OutdoorAir = \"{}\".", this->Name));
    1197            0 :                                     ShowContinueError(
    1198              :                                         state,
    1199            0 :                                         format("For System Outdoor Air Method = ProportionalControlBasedOnDesignOccupancy, maximum target "
    1200              :                                                "CO2 concentration ({:.2R}), is not greater than minimum target CO2 concentration ({:.2R}).",
    1201              :                                                ZoneMaxCO2,
    1202              :                                                ZoneMinCO2));
    1203            0 :                                     ShowContinueError(state,
    1204              :                                                       "\"ProportionalControlBasedOnDesignOccupancy\" will not be modeled. "
    1205              :                                                       "Default \"Flow/Person+Flow/Area\" will be modeled. Simulation continues...");
    1206            0 :                                     ShowContinueErrorTimeStamp(state, "");
    1207              :                                 } else {
    1208            0 :                                     ShowRecurringWarningErrorAtEnd(
    1209              :                                         state,
    1210            0 :                                         format("DesignSpecification:OutdoorAir = \"{}\", For System Outdoor Air Method = "
    1211              :                                                "ProportionalControlBasedOnDesignOccupancy, maximum target CO2 concentration is not greater than "
    1212              :                                                "minimum target CO2 concentration. Error continues...",
    1213            0 :                                                this->Name),
    1214            0 :                                         this->CO2MaxMinLimitErrorIndex);
    1215              :                                 }
    1216              :                             }
    1217              : 
    1218            0 :                             OAVolumeFlowRate = ZoneOAMax;
    1219              :                         } else {
    1220              : 
    1221            3 :                             if (state.dataContaminantBalance->ZoneAirCO2(ActualZoneNum) <= ZoneMinCO2) {
    1222              :                                 // Zone air CO2 concentration is less than minimum zone CO2 concentration, set the Zone OA flow rate to
    1223              :                                 // minimum Zone OA flow rate when the zone is unoccupied
    1224            0 :                                 OAVolumeFlowRate = ZoneOAMin;
    1225            3 :                             } else if (state.dataContaminantBalance->ZoneAirCO2(ActualZoneNum) >= ZoneMaxCO2) {
    1226              :                                 // Zone air CO2 concentration is greater than maximum zone CO2 concentration, set the Zone OA flow rate to
    1227              :                                 // maximum Zone OA flow rate (i.e. ZoneOAArea + ZoneOAPeople)
    1228            1 :                                 OAVolumeFlowRate = ZoneOAMax;
    1229              :                             } else {
    1230              :                                 // Zone air CO2 concentration is between maximum and minimum limits of zone CO2 concentration,
    1231              :                                 // set Zone OA flow rate by proportionally adjusting between ZoneOAMin and ZoneOAMax
    1232            2 :                                 OAVolumeFlowRate =
    1233            2 :                                     ZoneOAMin + (ZoneOAMax - ZoneOAMin) * ((state.dataContaminantBalance->ZoneAirCO2(ActualZoneNum) - ZoneMinCO2) /
    1234            2 :                                                                            (ZoneMaxCO2 - ZoneMinCO2));
    1235              :                             }
    1236              :                         }
    1237              :                     } else {
    1238            0 :                         if (state.dataGlobal->DisplayExtraWarnings) {
    1239            0 :                             ++this->CO2GainErrorCount;
    1240            0 :                             if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCOccSch) {
    1241            0 :                                 if (this->CO2GainErrorCount < 2) {
    1242            0 :                                     ShowSevereError(state,
    1243            0 :                                                     format("CalcDesignSpecificationOutdoorAir DesignSpecification:OutdoorAir = \"{}\".", this->Name));
    1244            0 :                                     ShowContinueError(state,
    1245            0 :                                                       format("For System Outdoor Air Method = ProportionalControlBasedOnOccupancySchedule, CO2 "
    1246              :                                                              "generation from people is not greater than zero. Occurs in Zone =\"{}\". ",
    1247            0 :                                                              thisZone.Name));
    1248            0 :                                     ShowContinueError(state,
    1249              :                                                       "\"ProportionalControlBasedOnOccupancySchedule\" will not be modeled. "
    1250              :                                                       "Default \"Flow/Person+Flow/Area\" will be modeled. Simulation continues...");
    1251            0 :                                     ShowContinueErrorTimeStamp(state, "");
    1252              :                                 } else {
    1253            0 :                                     ShowRecurringWarningErrorAtEnd(state,
    1254            0 :                                                                    format("DesignSpecification:OutdoorAir = \"{}\", For System Outdoor Air Method = "
    1255              :                                                                           "ProportionalControlBasedOnOccupancySchedule, CO2 generation from people "
    1256              :                                                                           "is not greater than zero. Error continues...",
    1257            0 :                                                                           this->Name),
    1258            0 :                                                                    this->CO2GainErrorIndex);
    1259              :                                 }
    1260              :                             }
    1261            0 :                             if (this->OAFlowMethod == DataSizing::OAFlowCalcMethod::PCDesOcc) {
    1262            0 :                                 if (this->CO2GainErrorCount < 2) {
    1263            0 :                                     ShowSevereError(state,
    1264            0 :                                                     format("CalcDesignSpecificationOutdoorAir DesignSpecification:OutdoorAir = \"{}\".", this->Name));
    1265            0 :                                     ShowContinueError(state,
    1266            0 :                                                       format("For System Outdoor Air Method = ProportionalControlBasedOnDesignOccupancy, CO2 "
    1267              :                                                              "generation from people is not greater than zero. Occurs in Zone =\"{}\". ",
    1268            0 :                                                              thisZone.Name));
    1269            0 :                                     ShowContinueError(state,
    1270              :                                                       "\"ProportionalControlBasedOnDesignOccupancy\" will not be modeled. "
    1271              :                                                       "Default \"Flow/Person+Flow/Area\" will be modeled. Simulation continues...");
    1272            0 :                                     ShowContinueErrorTimeStamp(state, "");
    1273              :                                 } else {
    1274            0 :                                     ShowRecurringWarningErrorAtEnd(state,
    1275            0 :                                                                    format("DesignSpecification:OutdoorAir = \"{}\", For System Outdoor Air Method = "
    1276              :                                                                           "ProportionalControlBasedOnDesignOccupancy, CO2 generation from people is "
    1277              :                                                                           "not greater than zero. Error continues...",
    1278            0 :                                                                           this->Name),
    1279            0 :                                                                    this->CO2GainErrorIndex);
    1280              :                                 }
    1281              :                             }
    1282              :                         }
    1283            0 :                         OAVolumeFlowRate = ZoneOAMax;
    1284              :                     }
    1285              :                 } else {
    1286              :                     // ZoneOAPeople is less than or equal to zero
    1287            0 :                     OAVolumeFlowRate = ZoneOAMax;
    1288              :                 }
    1289              :             } else {
    1290              :                 // ZoneControl:ContaminantController is scheduled off (not available)
    1291            0 :                 OAVolumeFlowRate = ZoneOAMax;
    1292              :             }
    1293              :         } else {
    1294              :             // "Carbon Dioxide Control Availability Schedule" for ZoneControl:ContaminantController not found
    1295            0 :             OAVolumeFlowRate = ZoneOAMax;
    1296              :         }
    1297            3 :     } break;
    1298            0 :     default: {
    1299              :         // Will never get here
    1300            0 :         OAVolumeFlowRate = 0.0;
    1301            0 :     } break;
    1302              :     }
    1303              : 
    1304              :     // Apply zone multipliers and zone list multipliers
    1305              :     // TODO MJW: this looks like it's double-counting the multipliers - it *is* double counting for methods PCOccSch and PCDesOcc
    1306        88805 :     OAVolumeFlowRate *= thisZone.Multiplier * thisZone.ListMultiplier;
    1307              : 
    1308              :     // Apply schedule as needed. Sizing does not use schedule.
    1309        88805 :     if (this->oaFlowFracSched != nullptr && UseMinOASchFlag) {
    1310        88685 :         if (MaxOAVolFlowFlag) {
    1311            0 :             OAVolumeFlowRate *= this->oaFlowFracSched->getMaxVal(state);
    1312              :         } else {
    1313        88685 :             OAVolumeFlowRate *= this->oaFlowFracSched->getCurrentVal();
    1314              :         }
    1315              :     }
    1316              : 
    1317        88805 :     return OAVolumeFlowRate;
    1318              : }
    1319              : 
    1320            2 : Sched::Schedule *OARequirementsData::getZoneFlowFracSched(EnergyPlusData &state, bool notAllSame)
    1321              : {
    1322            2 :     notAllSame = false;
    1323            2 :     Sched::Schedule *schedPtr = nullptr;
    1324            2 :     if (this->numDSOA == 0) {
    1325              :         // This is a simple DesignSpecification:OutdoorAir
    1326            2 :         schedPtr = this->oaFlowFracSched;
    1327              :     } else {
    1328              :         // This is a DesignSpecification:OutdoorAir:SpaceList
    1329            0 :         for (int dsoaCount = 1; dsoaCount <= this->numDSOA; ++dsoaCount) {
    1330            0 :             auto const &thisDSOA = state.dataSize->OARequirements(this->dsoaIndexes(dsoaCount));
    1331            0 :             if (dsoaCount == 1) {
    1332            0 :                 schedPtr = thisDSOA.oaFlowFracSched;
    1333              :             } else {
    1334            0 :                 if (schedPtr != thisDSOA.oaFlowFracSched) {
    1335            0 :                     notAllSame = true;
    1336            0 :                     ShowWarningError(state,
    1337            0 :                                      format("getZoneFlowFracSched: Outdoor Air Schedules are not the same for all spaces in "
    1338              :                                             "DesignSpecification:OutdoorAir:SpaceList={}.",
    1339            0 :                                             this->Name));
    1340            0 :                     ShowContinueError(state, format("Using the first space schedule={}", schedPtr->Name));
    1341            0 :                     break;
    1342              :                 }
    1343              :             }
    1344              :         }
    1345              :     }
    1346            2 :     return schedPtr;
    1347              : }
    1348              : 
    1349            5 : Sched::Schedule *OARequirementsData::getZonePropCtlMinRateSched(EnergyPlusData &state, bool notAllSame)
    1350              : {
    1351            5 :     notAllSame = false;
    1352            5 :     Sched::Schedule *schedPtr = nullptr;
    1353            5 :     if (this->numDSOA == 0) {
    1354              :         // This is a simple DesignSpecification:OutdoorAir
    1355            5 :         schedPtr = this->oaPropCtlMinRateSched;
    1356              :     } else {
    1357              :         // This is a DesignSpecification:OutdoorAir:SpaceList
    1358            0 :         for (int dsoaCount = 1; dsoaCount <= this->numDSOA; ++dsoaCount) {
    1359            0 :             auto const &thisDSOA = state.dataSize->OARequirements(this->dsoaIndexes(dsoaCount));
    1360            0 :             if (dsoaCount == 1) {
    1361            0 :                 schedPtr = thisDSOA.oaPropCtlMinRateSched;
    1362              :             } else {
    1363            0 :                 if (schedPtr != thisDSOA.oaPropCtlMinRateSched) {
    1364            0 :                     notAllSame = true;
    1365            0 :                     ShowWarningError(
    1366              :                         state,
    1367            0 :                         format(
    1368              :                             "getZoneFlowFracSched: Proportional Control Minimum Outdoor Air Flow Rate Schedules are not the same for all spaces in "
    1369              :                             "DesignSpecification:OutdoorAir:SpaceList={}.",
    1370            0 :                             this->Name));
    1371            0 :                     ShowContinueError(state, format("Using the first space schedule={}", schedPtr->Name));
    1372            0 :                     break;
    1373              :                 }
    1374              :             }
    1375              :         }
    1376              :     }
    1377            5 :     return schedPtr;
    1378              : }
    1379              : 
    1380              : } // namespace EnergyPlus::DataSizing
        

Generated by: LCOV version 2.0-1