LCOV - code coverage report
Current view: top level - EnergyPlus - AirLoopHVACDOAS.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 60.7 % 613 372
Test Date: 2025-07-17 05:04:31 Functions: 100.0 % 16 16

            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              : // C++ Headers
      49              : #include <string>
      50              : 
      51              : // EnergyPlus Headers
      52              : #include <EnergyPlus/AirLoopHVACDOAS.hh>
      53              : #include <EnergyPlus/Autosizing/Base.hh>
      54              : #include <EnergyPlus/BranchNodeConnections.hh>
      55              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      56              : #include <EnergyPlus/DataAirLoop.hh>
      57              : #include <EnergyPlus/DataAirSystems.hh>
      58              : #include <EnergyPlus/DataEnvironment.hh>
      59              : #include <EnergyPlus/DataLoopNode.hh>
      60              : #include <EnergyPlus/DataSizing.hh>
      61              : #include <EnergyPlus/DesiccantDehumidifiers.hh>
      62              : #include <EnergyPlus/EvaporativeCoolers.hh>
      63              : #include <EnergyPlus/Fans.hh>
      64              : #include <EnergyPlus/FluidProperties.hh>
      65              : #include <EnergyPlus/HVACDXHeatPumpSystem.hh>
      66              : #include <EnergyPlus/HVACHXAssistedCoolingCoil.hh>
      67              : #include <EnergyPlus/HVACVariableRefrigerantFlow.hh>
      68              : #include <EnergyPlus/HeatRecovery.hh>
      69              : #include <EnergyPlus/HeatingCoils.hh>
      70              : #include <EnergyPlus/Humidifiers.hh>
      71              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      72              : #include <EnergyPlus/MixedAir.hh>
      73              : #include <EnergyPlus/NodeInputManager.hh>
      74              : #include <EnergyPlus/OutAirNodeManager.hh>
      75              : #include <EnergyPlus/PhotovoltaicThermalCollectors.hh>
      76              : #include <EnergyPlus/PlantUtilities.hh>
      77              : #include <EnergyPlus/Psychrometrics.hh>
      78              : #include <EnergyPlus/ScheduleManager.hh>
      79              : #include <EnergyPlus/SimAirServingZones.hh>
      80              : #include <EnergyPlus/SteamCoils.hh>
      81              : #include <EnergyPlus/TranspiredCollector.hh>
      82              : #include <EnergyPlus/UnitarySystem.hh>
      83              : #include <EnergyPlus/UtilityRoutines.hh>
      84              : #include <EnergyPlus/WaterCoils.hh>
      85              : #include <EnergyPlus/WeatherManager.hh>
      86              : 
      87              : namespace EnergyPlus {
      88              : 
      89              : namespace AirLoopHVACDOAS {
      90              : 
      91              :     // the equipment list object has its own subset of E+ components that are valid, this covers that list
      92              :     enum class ValidEquipListType
      93              :     {
      94              :         Invalid = -1,
      95              :         OutdoorAirMixer,
      96              :         FanConstantVolume,
      97              :         FanVariableVolume,
      98              :         FanSystemModel,
      99              :         FanComponentModel,
     100              :         CoilCoolingWater,
     101              :         CoilHeatingWater,
     102              :         CoilHeatingSteam,
     103              :         CoilCoolingWaterDetailedGeometry,
     104              :         CoilHeatingElectric,
     105              :         CoilHeatingFuel,
     106              :         CoilSystemCoolingWaterHeatExchangerAssisted,
     107              :         CoilSystemCoolingDX,
     108              :         CoilSystemHeatingDX,
     109              :         AirLoopHVACUnitarySystem,
     110              :         CoilUserDefined,
     111              :         HeatExchangerAirToAirFlatPlate,
     112              :         HeatExchangerAirToAirSensibleAndLatent,
     113              :         HeatExchangerDesiccantBalancedFlow,
     114              :         DehumidifierDesiccantNoFans,
     115              :         DehumidifierDesiccantSystem,
     116              :         HumidifierSteamElectric,
     117              :         HumidifierSteamGas,
     118              :         SolarCollectorUnglazedTranspired,
     119              :         SolarCollectorFlatPlatePhotovoltaicThermal,
     120              :         EvaporativeCoolerDirectCeldekPad,
     121              :         EvaporativeCoolerIndirectCeldekPad,
     122              :         EvaporativeCoolerIndirectWetCoil,
     123              :         EvaporativeCoolerIndirectResearchSpecial,
     124              :         EvaporativeCoolerDirectResearchSpecial,
     125              :         ZoneHVACTerminalUnitVariableRefrigerantFlow,
     126              :         Num
     127              :     };
     128              :     constexpr std::array<std::string_view, static_cast<int>(ValidEquipListType::Num)> validEquipNamesUC = {
     129              :         "OUTDOORAIR:MIXER",
     130              :         "FAN:CONSTANTVOLUME",
     131              :         "FAN:VARIABLEVOLUME",
     132              :         "FAN:SYSTEMMODEL",
     133              :         "FAN:COMPONENTMODEL",
     134              :         "COIL:COOLING:WATER",
     135              :         "COIL:HEATING:WATER",
     136              :         "COIL:HEATING:STEAM",
     137              :         "COIL:COOLING:WATER:DETAILEDGEOMETRY",
     138              :         "COIL:HEATING:ELECTRIC",
     139              :         "COIL:HEATING:FUEL",
     140              :         "COILSYSTEM:COOLING:WATER:HEATEXCHANGERASSISTED",
     141              :         "COILSYSTEM:COOLING:DX",
     142              :         "COILSYSTEM:HEATING:DX",
     143              :         "AIRLOOPHVAC:UNITARYSYSTEM",
     144              :         "COIL:USERDEFINED",
     145              :         "HEATEXCHANGER:AIRTOAIR:FLATPLATE",
     146              :         "HEATEXCHANGER:AIRTOAIR:SENSIBLEANDLATENT",
     147              :         "HEATEXCHANGER:DESICCANT:BALANCEDFLOW",
     148              :         "DEHUMIDIFIER:DESICCANT:NOFANS",
     149              :         "DEHUMIDIFIER:DESICCANT:SYSTEM",
     150              :         "HUMIDIFIER:STEAM:ELECTRIC",
     151              :         "HUMIDIFIER:STEAM:GAS",
     152              :         "SOLARCOLLECTOR:UNGLAZEDTRANSPIRED",
     153              :         "SOLARCOLLECTOR:FLATPLATE:PHOTOVOLTAICTHERMAL",
     154              :         "EVAPORATIVECOOLER:DIRECT:CELDEKPAD",
     155              :         "EVAPORATIVECOOLER:INDIRECT:CELDEKPAD",
     156              :         "EVAPORATIVECOOLER:INDIRECT:WETCOIL",
     157              :         "EVAPORATIVECOOLER:INDIRECT:RESEARCHSPECIAL",
     158              :         "EVAPORATIVECOOLER:DIRECT:RESEARCHSPECIAL",
     159              :         "ZONEHVAC:TERMINALUNIT:VARIABLEREFRIGERANTFLOW",
     160              :     };
     161              : 
     162        10882 :     void AirLoopDOAS::SimAirLoopHVACDOAS(EnergyPlusData &state, bool const FirstHVACIteration, int &CompIndex)
     163              :     {
     164              : 
     165              :         // Obtains and Allocates unitary system related parameters from input file
     166        10882 :         if (state.dataAirLoopHVACDOAS->GetInputOnceFlag) {
     167              :             // Get the AirLoopHVACDOAS input
     168            0 :             getAirLoopDOASInput(state);
     169            0 :             state.dataAirLoopHVACDOAS->GetInputOnceFlag = false;
     170              :         }
     171              : 
     172        10882 :         if (CompIndex == -1) {
     173            0 :             CompIndex = this->m_AirLoopDOASNum;
     174              :         }
     175              : 
     176        10882 :         if (this->SizingOnceFlag) {
     177            1 :             this->SizingAirLoopDOAS(state);
     178            1 :             this->SizingOnceFlag = false;
     179              :         }
     180              : 
     181        10882 :         this->initAirLoopDOAS(state, FirstHVACIteration);
     182              : 
     183        10882 :         if (this->SumMassFlowRate == 0.0 && !state.dataGlobal->BeginEnvrnFlag) {
     184         5474 :             state.dataLoopNodes->Node(this->m_CompPointerAirLoopMixer->OutletNodeNum).MassFlowRate = 0.0;
     185              :         }
     186              : 
     187        10882 :         this->CalcAirLoopDOAS(state, FirstHVACIteration);
     188        10882 :     }
     189              : 
     190            1 :     AirLoopMixer *AirLoopMixer::factory(EnergyPlusData &state, int object_num, std::string const &objectName)
     191              :     {
     192              : 
     193            1 :         if (state.dataAirLoopHVACDOAS->getAirLoopMixerInputOnceFlag) {
     194            0 :             AirLoopMixer::getAirLoopMixer(state);
     195            0 :             state.dataAirLoopHVACDOAS->getAirLoopMixerInputOnceFlag = false;
     196              :         }
     197              : 
     198            1 :         int MixerNum = -1;
     199            1 :         for (auto &dSpec : state.dataAirLoopHVACDOAS->airloopMixer) {
     200            1 :             ++MixerNum;
     201            1 :             if (Util::SameString(dSpec.name, objectName) && dSpec.m_AirLoopMixer_Num == object_num) {
     202            1 :                 return &dSpec;
     203              :             }
     204            2 :         }
     205              : 
     206            0 :         ShowSevereError(state, format("AirLoopMixer factory: Error getting inputs for system named: {}", objectName));
     207            0 :         return nullptr;
     208              :     }
     209              : 
     210            1 :     void AirLoopMixer::getAirLoopMixer(EnergyPlusData &state)
     211              :     {
     212              : 
     213            1 :         std::string const cCurrentModuleObject = "AirLoopHVAC:Mixer";
     214              : 
     215            1 :         auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
     216            1 :         if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
     217            1 :             bool errorsFound(false);
     218            1 :             std::string cFieldName;
     219            1 :             int AirLoopMixerNum = 0;
     220            1 :             auto &instancesValue = instances.value();
     221            2 :             for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
     222              : 
     223            1 :                 auto const &fields = instance.value();
     224            1 :                 std::string const &thisObjectName = instance.key();
     225            1 :                 state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjectName);
     226            1 :                 ++AirLoopMixerNum;
     227            1 :                 AirLoopMixer thisMixer;
     228              : 
     229            1 :                 thisMixer.name = Util::makeUPPER(thisObjectName);
     230            1 :                 thisMixer.OutletNodeName = Util::makeUPPER(fields.at("outlet_node_name").get<std::string>());
     231            1 :                 thisMixer.m_AirLoopMixer_Num = AirLoopMixerNum - 1;
     232            1 :                 thisMixer.OutletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     233              :                                                                               thisMixer.OutletNodeName,
     234              :                                                                               errorsFound,
     235              :                                                                               DataLoopNode::ConnectionObjectType::AirLoopHVACMixer,
     236              :                                                                               thisObjectName,
     237              :                                                                               DataLoopNode::NodeFluidType::Air,
     238              :                                                                               DataLoopNode::ConnectionType::Outlet,
     239              :                                                                               NodeInputManager::CompFluidStream::Primary,
     240              :                                                                               DataLoopNode::ObjectIsParent);
     241              : 
     242            1 :                 auto NodeNames = fields.find("nodes");
     243            1 :                 if (NodeNames != fields.end()) {
     244            1 :                     auto const &NodeArray = NodeNames.value();
     245            1 :                     thisMixer.numOfInletNodes = NodeArray.size();
     246            1 :                     int num = 0;
     247            6 :                     for (auto const &NodeDOASName : NodeArray) {
     248            5 :                         num += 1;
     249            5 :                         std::string name = Util::makeUPPER(NodeDOASName.at("inlet_node_name").get<std::string>());
     250            5 :                         int NodeNum = NodeInputManager::GetOnlySingleNode(state,
     251              :                                                                           name,
     252              :                                                                           errorsFound,
     253              :                                                                           DataLoopNode::ConnectionObjectType::AirLoopHVACMixer,
     254              :                                                                           thisObjectName,
     255              :                                                                           DataLoopNode::NodeFluidType::Air,
     256              :                                                                           DataLoopNode::ConnectionType::Inlet,
     257              :                                                                           NodeInputManager::CompFluidStream::Primary,
     258            5 :                                                                           DataLoopNode::ObjectIsParent);
     259            5 :                         if (NodeNum > 0 && num <= thisMixer.numOfInletNodes) {
     260            5 :                             thisMixer.InletNodeName.push_back(name);
     261            5 :                             thisMixer.InletNodeNum.push_back(NodeNum);
     262              :                         } else {
     263            0 :                             cFieldName = "Inlet Node Name";
     264            0 :                             ShowSevereError(state, format("{}, \"{}\" {} not found: {}", cCurrentModuleObject, thisMixer.name, name, cFieldName));
     265            0 :                             errorsFound = true;
     266              :                         }
     267            6 :                     }
     268              :                 }
     269              : 
     270            1 :                 state.dataAirLoopHVACDOAS->airloopMixer.push_back(thisMixer);
     271              : 
     272            1 :                 if (thisMixer.numOfInletNodes < 1) { // No inlet nodes specified--this is not possible
     273            0 :                     ShowSevereError(state, format("{}, \"{}\" does not have any inlet nodes.", cCurrentModuleObject, thisMixer.name));
     274            0 :                     ShowContinueError(state, "All mixers must have at least one inlet node.");
     275            0 :                     errorsFound = true;
     276              :                 }
     277            2 :             }
     278            1 :             if (errorsFound) {
     279            0 :                 ShowFatalError(state, "getAirLoopMixer: Previous errors cause termination.");
     280              :             }
     281            1 :         }
     282            1 :     } // namespace AirLoopMixer
     283              : 
     284        10882 :     void AirLoopMixer::CalcAirLoopMixer(EnergyPlusData &state)
     285              :     {
     286        10882 :         Real64 outletTemp = 0.0;
     287        10882 :         Real64 outletHumRat = 0.0;
     288        10882 :         Real64 massSum = 0.0;
     289              : 
     290        65292 :         for (int i = 1; i <= this->numOfInletNodes; i++) {
     291        54410 :             int InletNum = this->InletNodeNum[i - 1];
     292        54410 :             massSum += state.dataLoopNodes->Node(InletNum).MassFlowRate;
     293        54410 :             outletTemp += state.dataLoopNodes->Node(InletNum).MassFlowRate * state.dataLoopNodes->Node(InletNum).Temp;
     294        54410 :             outletHumRat += state.dataLoopNodes->Node(InletNum).MassFlowRate * state.dataLoopNodes->Node(InletNum).HumRat;
     295              :         }
     296        10882 :         if (massSum > 0.0) {
     297         5358 :             state.dataLoopNodes->Node(this->OutletNodeNum).Temp = outletTemp / massSum;
     298         5358 :             state.dataLoopNodes->Node(this->OutletNodeNum).HumRat = outletHumRat / massSum;
     299         5358 :             state.dataLoopNodes->Node(this->OutletNodeNum).MassFlowRate = massSum;
     300         5358 :             state.dataLoopNodes->Node(this->OutletNodeNum).Enthalpy = Psychrometrics::PsyHFnTdbW(outletTemp / massSum, outletHumRat / massSum);
     301         5358 :             this->OutletTemp = state.dataLoopNodes->Node(this->OutletNodeNum).Temp;
     302              :         } else {
     303         5524 :             state.dataLoopNodes->Node(this->OutletNodeNum).Temp = state.dataLoopNodes->Node(this->InletNodeNum[0]).Temp;
     304         5524 :             state.dataLoopNodes->Node(this->OutletNodeNum).HumRat = state.dataLoopNodes->Node(this->InletNodeNum[0]).HumRat;
     305         5524 :             state.dataLoopNodes->Node(this->OutletNodeNum).MassFlowRate = 0.0;
     306         5524 :             state.dataLoopNodes->Node(this->OutletNodeNum).Enthalpy = state.dataLoopNodes->Node(this->InletNodeNum[0]).Enthalpy;
     307         5524 :             this->OutletTemp = state.dataLoopNodes->Node(this->InletNodeNum[0]).Temp;
     308              :         }
     309        10882 :     }
     310              : 
     311            1 :     int getAirLoopMixerIndex(EnergyPlusData &state, std::string const &objectName)
     312              :     {
     313            1 :         if (state.dataAirLoopHVACDOAS->getAirLoopMixerInputOnceFlag) {
     314            1 :             AirLoopMixer::getAirLoopMixer(state);
     315            1 :             state.dataAirLoopHVACDOAS->getAirLoopMixerInputOnceFlag = false;
     316              :         }
     317              : 
     318            1 :         int index = -1;
     319            1 :         for (std::size_t loop = 0; loop < state.dataAirLoopHVACDOAS->airloopMixer.size(); ++loop) {
     320            1 :             AirLoopMixer *thisAirLoopMixerObjec = &state.dataAirLoopHVACDOAS->airloopMixer[loop];
     321            1 :             if (Util::SameString(objectName, thisAirLoopMixerObjec->name)) {
     322            1 :                 index = loop;
     323            1 :                 return index;
     324              :             }
     325              :         }
     326            0 :         ShowSevereError(state, format("getAirLoopMixer: did not find AirLoopHVAC:Mixer name ={}. Check inputs", objectName));
     327            0 :         return index;
     328              :     }
     329              : 
     330            1 :     AirLoopSplitter *AirLoopSplitter::factory(EnergyPlusData &state, int object_num, std::string const &objectName)
     331              :     {
     332              : 
     333            1 :         if (state.dataAirLoopHVACDOAS->getAirLoopSplitterInputOnceFlag) {
     334            0 :             AirLoopSplitter::getAirLoopSplitter(state);
     335            0 :             state.dataAirLoopHVACDOAS->getAirLoopSplitterInputOnceFlag = false;
     336              :         }
     337              : 
     338            1 :         int SplitterNum = -1;
     339            1 :         for (auto &dSpec : state.dataAirLoopHVACDOAS->airloopSplitter) {
     340            1 :             SplitterNum++;
     341            1 :             if (Util::SameString(dSpec.name, objectName) && dSpec.m_AirLoopSplitter_Num == object_num) {
     342            1 :                 return &dSpec;
     343              :             }
     344            2 :         }
     345            0 :         ShowSevereError(state, format("AirLoopSplitter factory: Error getting inputs for system named: {}", objectName));
     346            0 :         return nullptr;
     347              :     }
     348              : 
     349        10882 :     void AirLoopSplitter::CalcAirLoopSplitter(EnergyPlusData &state, Real64 Temp, Real64 HumRat)
     350              :     {
     351        65292 :         for (int i = 0; i < this->numOfOutletNodes; i++) {
     352        54410 :             state.dataLoopNodes->Node(this->OutletNodeNum[i]).Temp = Temp;
     353        54410 :             state.dataLoopNodes->Node(this->OutletNodeNum[i]).HumRat = HumRat;
     354        54410 :             state.dataLoopNodes->Node(this->OutletNodeNum[i]).Enthalpy = Psychrometrics::PsyHFnTdbW(Temp, HumRat);
     355              :         }
     356        10882 :         this->InletTemp = Temp;
     357        10882 :     }
     358              : 
     359            1 :     int getAirLoopSplitterIndex(EnergyPlusData &state, std::string const &objectName)
     360              :     {
     361            1 :         if (state.dataAirLoopHVACDOAS->getAirLoopSplitterInputOnceFlag) {
     362            1 :             AirLoopSplitter::getAirLoopSplitter(state);
     363            1 :             state.dataAirLoopHVACDOAS->getAirLoopSplitterInputOnceFlag = false;
     364              :         }
     365              : 
     366            1 :         int index = -1;
     367            1 :         for (std::size_t loop = 0; loop < state.dataAirLoopHVACDOAS->airloopSplitter.size(); ++loop) {
     368            1 :             AirLoopSplitter *thisAirLoopSplitterObjec = &state.dataAirLoopHVACDOAS->airloopSplitter[loop];
     369            1 :             if (Util::SameString(objectName, thisAirLoopSplitterObjec->name)) {
     370            1 :                 index = loop;
     371            1 :                 return index;
     372              :             }
     373              :         }
     374            0 :         ShowSevereError(state, format("getAirLoopSplitter: did not find AirLoopSplitter name ={}. Check inputs", objectName));
     375            0 :         return index;
     376              :     }
     377              : 
     378            1 :     void AirLoopSplitter::getAirLoopSplitter(EnergyPlusData &state)
     379              :     {
     380              : 
     381            1 :         std::string const cCurrentModuleObject = "AirLoopHVAC:Splitter";
     382              : 
     383            1 :         auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
     384            1 :         if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
     385            1 :             bool errorsFound(false);
     386            1 :             std::string cFieldName;
     387            1 :             int AirLoopSplitterNum = 0;
     388            1 :             auto &instancesValue = instances.value();
     389            2 :             for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
     390              : 
     391            1 :                 auto const &fields = instance.value();
     392            1 :                 std::string const &thisObjectName = instance.key();
     393            1 :                 state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjectName);
     394              : 
     395            1 :                 ++AirLoopSplitterNum;
     396            1 :                 AirLoopSplitter thisSplitter;
     397              : 
     398            1 :                 thisSplitter.name = Util::makeUPPER(thisObjectName);
     399            1 :                 thisSplitter.InletNodeName = Util::makeUPPER(fields.at("inlet_node_name").get<std::string>());
     400            1 :                 thisSplitter.InletNodeNum = NodeInputManager::GetOnlySingleNode(state,
     401              :                                                                                 thisSplitter.InletNodeName,
     402              :                                                                                 errorsFound,
     403              :                                                                                 DataLoopNode::ConnectionObjectType::AirLoopHVACSplitter,
     404              :                                                                                 thisObjectName,
     405              :                                                                                 DataLoopNode::NodeFluidType::Air,
     406              :                                                                                 DataLoopNode::ConnectionType::Inlet,
     407              :                                                                                 NodeInputManager::CompFluidStream::Primary,
     408              :                                                                                 DataLoopNode::ObjectIsParent);
     409            1 :                 thisSplitter.m_AirLoopSplitter_Num = AirLoopSplitterNum - 1;
     410              : 
     411            1 :                 auto NodeNames = fields.find("nodes");
     412            1 :                 if (NodeNames != fields.end()) {
     413            1 :                     auto const &NodeArray = NodeNames.value();
     414            1 :                     thisSplitter.numOfOutletNodes = NodeArray.size();
     415            1 :                     int num = 0;
     416            6 :                     for (auto const &NodeDOASName : NodeArray) {
     417            5 :                         num += 1;
     418              : 
     419            5 :                         std::string name = Util::makeUPPER(NodeDOASName.at("outlet_node_name").get<std::string>());
     420            5 :                         int NodeNum = NodeInputManager::GetOnlySingleNode(state,
     421              :                                                                           name,
     422              :                                                                           errorsFound,
     423              :                                                                           DataLoopNode::ConnectionObjectType::AirLoopHVACSplitter,
     424              :                                                                           thisObjectName,
     425              :                                                                           DataLoopNode::NodeFluidType::Air,
     426              :                                                                           DataLoopNode::ConnectionType::Inlet,
     427              :                                                                           NodeInputManager::CompFluidStream::Primary,
     428            5 :                                                                           DataLoopNode::ObjectIsParent);
     429            5 :                         if (NodeNum > 0 && num <= thisSplitter.numOfOutletNodes) {
     430            5 :                             thisSplitter.OutletNodeName.push_back(name);
     431            5 :                             thisSplitter.OutletNodeNum.push_back(NodeNum);
     432              :                         } else {
     433            0 :                             cFieldName = "Outlet Node Name";
     434            0 :                             ShowSevereError(state, format("{}, \"{}\"{} not found: {}", cCurrentModuleObject, thisSplitter.name, cFieldName, name));
     435            0 :                             errorsFound = true;
     436              :                         }
     437            6 :                     }
     438              :                 }
     439              : 
     440            1 :                 state.dataAirLoopHVACDOAS->airloopSplitter.push_back(thisSplitter);
     441              : 
     442            1 :                 if (thisSplitter.numOfOutletNodes < 1) { // No outlet nodes specified--this is not possible
     443            0 :                     ShowSevereError(state, format("{}, \"{}\" does not have any outlet nodes.", cCurrentModuleObject, thisSplitter.name));
     444            0 :                     ShowContinueError(state, "All splitters must have at least one outlet node.");
     445            0 :                     errorsFound = true;
     446              :                 }
     447            2 :             }
     448            1 :             if (errorsFound) {
     449            0 :                 ShowFatalError(state, "getAirLoopSplitter: Previous errors cause termination.");
     450              :             }
     451            1 :         }
     452            1 :     } // namespace AirLoopSplitter
     453              : 
     454            1 :     void AirLoopDOAS::getAirLoopDOASInput(EnergyPlusData &state)
     455              :     {
     456            1 :         constexpr std::string_view routineName = "AirLoopDOAS::getAirLoopDOASInput";
     457            1 :         std::string const cCurrentModuleObject = "AirLoopHVAC:DedicatedOutdoorAirSystem";
     458              : 
     459            1 :         auto const instances = state.dataInputProcessing->inputProcessor->epJSON.find(cCurrentModuleObject);
     460            1 :         if (instances != state.dataInputProcessing->inputProcessor->epJSON.end()) {
     461            1 :             bool errorsFound(false);
     462            1 :             std::string cFieldName;
     463            1 :             int AirLoopDOASNum = 0;
     464            1 :             auto &instancesValue = instances.value();
     465            2 :             for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
     466              : 
     467            1 :                 auto const &fields = instance.value();
     468            1 :                 std::string const &thisObjectName = instance.key();
     469            1 :                 state.dataInputProcessing->inputProcessor->markObjectAsUsed(cCurrentModuleObject, thisObjectName);
     470            1 :                 ++AirLoopDOASNum;
     471            1 :                 AirLoopDOAS thisDOAS;
     472              : 
     473            1 :                 ErrorObjectHeader eoh{routineName, cCurrentModuleObject, thisObjectName};
     474              : 
     475            1 :                 thisDOAS.Name = Util::makeUPPER(thisObjectName);
     476              :                 // get OA and avail num
     477            1 :                 thisDOAS.OASystemName = Util::makeUPPER(fields.at("airloophvac_outdoorairsystem_name").get<std::string>());
     478            1 :                 thisDOAS.m_OASystemNum = Util::FindItemInList(thisDOAS.OASystemName, state.dataAirLoop->OutsideAirSys);
     479              : 
     480            1 :                 if (thisDOAS.m_OASystemNum == 0) {
     481            0 :                     cFieldName = "AirLoopHVAC:OutdoorAirSystem Name";
     482            0 :                     ShowSevereError(state,
     483            0 :                                     format("{}, \"{}\", {} not found: {}\n", cCurrentModuleObject, thisDOAS.Name, cFieldName, thisDOAS.OASystemName));
     484            0 :                     errorsFound = true;
     485              :                 }
     486              :                 // Check controller type
     487            1 :                 std::string_view CurrentModuleObject = "AirLoopHVAC:OutdoorAirSystem";
     488            1 :                 auto &thisOutsideAirSys = state.dataAirLoop->OutsideAirSys(thisDOAS.m_OASystemNum);
     489            3 :                 for (int InListNum = 1; InListNum <= thisOutsideAirSys.NumControllers; ++InListNum) {
     490            2 :                     if (Util::SameString(thisOutsideAirSys.ControllerType(InListNum), "Controller:OutdoorAir")) {
     491            0 :                         ShowSevereError(state,
     492            0 :                                         format("When {} = {} is used in AirLoopHVAC:DedicatedOutdoorAirSystem,",
     493              :                                                CurrentModuleObject,
     494              :                                                thisOutsideAirSys.ControllerName(InListNum)));
     495            0 :                         ShowContinueError(state, "The Controller:OutdoorAir can not be used as a controller. Please remove it");
     496            0 :                         errorsFound = true;
     497              :                     }
     498              :                 }
     499              : 
     500              :                 // get inlet and outlet node number from equipment list
     501            1 :                 CurrentModuleObject = "AirLoopHVAC:OutdoorAirSystem:EquipmentList";
     502            1 :                 int CoolingCoilOrder = 0;
     503            1 :                 int FanOrder = 0;
     504            4 :                 for (int CompNum = 1; CompNum <= thisOutsideAirSys.NumComponents; ++CompNum) {
     505            3 :                     std::string &CompType = thisOutsideAirSys.ComponentType(CompNum);
     506            3 :                     std::string &CompName = thisOutsideAirSys.ComponentName(CompNum);
     507              : 
     508            3 :                     bool InletNodeErrFlag = false;
     509            3 :                     bool OutletNodeErrFlag = false;
     510              : 
     511            3 :                     const std::string typeNameUC = Util::makeUPPER(thisOutsideAirSys.ComponentType(CompNum));
     512            3 :                     ValidEquipListType foundType = static_cast<ValidEquipListType>(getEnumValue(validEquipNamesUC, typeNameUC));
     513              : 
     514            3 :                     switch (foundType) {
     515            0 :                     case ValidEquipListType::OutdoorAirMixer:
     516            0 :                         ShowSevereError(state,
     517            0 :                                         format("When {} = {} is used in AirLoopHVAC:DedicatedOutdoorAirSystem,", CurrentModuleObject, CompName));
     518            0 :                         ShowContinueError(state, " the OUTDOORAIR:MIXER can not be used as a component. Please remove it");
     519            0 :                         errorsFound = true;
     520            0 :                         break;
     521              : 
     522            0 :                     case ValidEquipListType::FanConstantVolume:
     523            0 :                         ShowSevereError(state,
     524            0 :                                         format("When {} = {} is used in AirLoopHVAC:DedicatedOutdoorAirSystem,", CurrentModuleObject, CompName));
     525            0 :                         ShowContinueError(state,
     526              :                                           " the FAN:CONSTANTVOLUME can not be used as a component. The allowed fan types are FAN:SYSTEMMODEL and "
     527              :                                           "FAN:COMPONENTMODEL. Please change it");
     528            0 :                         errorsFound = true;
     529            0 :                         break;
     530              : 
     531            0 :                     case ValidEquipListType::FanVariableVolume:
     532            0 :                         ShowSevereError(state,
     533            0 :                                         format("When {} = {} is used in AirLoopHVAC:DedicatedOutdoorAirSystem,", CurrentModuleObject, CompName));
     534            0 :                         ShowContinueError(state,
     535              :                                           " the FAN:VARIABLEVOLUME can not be used as a component. The allowed fan types are FAN:SYSTEMMODEL and "
     536              :                                           "FAN:COMPONENTMODEL. Please change it");
     537            0 :                         errorsFound = true;
     538            0 :                         break;
     539              : 
     540            1 :                     case ValidEquipListType::FanSystemModel:
     541            1 :                         thisDOAS.FanName = CompName;
     542            1 :                         thisDOAS.m_FanTypeNum = SimAirServingZones::CompType::Fan_System_Object;
     543            1 :                         thisDOAS.m_FanIndex = Fans::GetFanIndex(state, CompName);
     544            1 :                         thisOutsideAirSys.InletNodeNum(CompNum) = state.dataFans->fans(thisDOAS.m_FanIndex)->inletNodeNum;
     545            1 :                         if (thisOutsideAirSys.InletNodeNum(CompNum) == 0) {
     546            0 :                             InletNodeErrFlag = true;
     547              :                         }
     548            1 :                         thisOutsideAirSys.OutletNodeNum(CompNum) = state.dataFans->fans(thisDOAS.m_FanIndex)->outletNodeNum;
     549            1 :                         if (thisOutsideAirSys.OutletNodeNum(CompNum) == 0) {
     550            0 :                             OutletNodeErrFlag = true;
     551              :                         }
     552            1 :                         thisDOAS.m_FanInletNodeNum = thisOutsideAirSys.InletNodeNum(CompNum);
     553            1 :                         thisDOAS.m_FanOutletNodeNum = thisOutsideAirSys.OutletNodeNum(CompNum);
     554            1 :                         if (CompNum == 1) {
     555            1 :                             thisDOAS.FanBeforeCoolingCoilFlag = true;
     556              :                         }
     557            1 :                         FanOrder = CompNum;
     558            1 :                         break;
     559              : 
     560            0 :                     case ValidEquipListType::FanComponentModel:
     561            0 :                         thisDOAS.m_FanTypeNum = SimAirServingZones::CompType::Fan_ComponentModel;
     562            0 :                         thisDOAS.m_FanIndex = Fans::GetFanIndex(state, CompName);
     563            0 :                         thisDOAS.FanName = CompName;
     564            0 :                         if (CompNum == 1) {
     565            0 :                             thisDOAS.FanBeforeCoolingCoilFlag = true;
     566              :                         }
     567            0 :                         thisOutsideAirSys.InletNodeNum(CompNum) = state.dataFans->fans(thisDOAS.m_FanIndex)->inletNodeNum;
     568            0 :                         thisOutsideAirSys.OutletNodeNum(CompNum) = state.dataFans->fans(thisDOAS.m_FanIndex)->outletNodeNum;
     569            0 :                         thisDOAS.m_FanInletNodeNum = thisOutsideAirSys.InletNodeNum(CompNum);
     570            0 :                         thisDOAS.m_FanOutletNodeNum = thisOutsideAirSys.OutletNodeNum(CompNum);
     571            0 :                         FanOrder = CompNum;
     572            0 :                         break;
     573              : 
     574            1 :                     case ValidEquipListType::CoilCoolingWater:
     575            1 :                         thisOutsideAirSys.InletNodeNum(CompNum) = WaterCoils::GetCoilInletNode(state, typeNameUC, CompName, InletNodeErrFlag);
     576            1 :                         thisOutsideAirSys.OutletNodeNum(CompNum) = WaterCoils::GetCoilOutletNode(state, typeNameUC, CompName, OutletNodeErrFlag);
     577            1 :                         thisDOAS.CWCtrlNodeNum = WaterCoils::GetCoilWaterInletNode(state, "COIL:COOLING:WATER", CompName, errorsFound);
     578            1 :                         if (errorsFound) {
     579            0 :                             ShowContinueError(state, format("The control node number is not found in {} = {}", CurrentModuleObject, CompName));
     580              :                         }
     581            1 :                         PlantUtilities::ScanPlantLoopsForObject(
     582              :                             state, CompName, DataPlant::PlantEquipmentType::CoilWaterCooling, thisDOAS.CWPlantLoc, errorsFound, _, _, _, _, _);
     583            1 :                         if (errorsFound) { // is this really needed here, program fatals out later on when errorsFound = true
     584            0 :                             ShowFatalError(state, "GetAirLoopDOASInput: Program terminated for previous conditions.");
     585              :                         }
     586            1 :                         CoolingCoilOrder = CompNum;
     587            1 :                         break;
     588              : 
     589            1 :                     case ValidEquipListType::CoilHeatingWater:
     590            1 :                         thisOutsideAirSys.InletNodeNum(CompNum) = WaterCoils::GetCoilInletNode(state, typeNameUC, CompName, InletNodeErrFlag);
     591            1 :                         thisOutsideAirSys.OutletNodeNum(CompNum) = WaterCoils::GetCoilOutletNode(state, typeNameUC, CompName, OutletNodeErrFlag);
     592            1 :                         thisDOAS.HWCtrlNodeNum = WaterCoils::GetCoilWaterInletNode(state, "Coil:Heating:Water", CompName, errorsFound);
     593            1 :                         if (errorsFound) {
     594            0 :                             ShowContinueError(state, format("The control node number is not found in {} = {}", CurrentModuleObject, CompName));
     595              :                         }
     596            1 :                         PlantUtilities::ScanPlantLoopsForObject(
     597              :                             state, CompName, DataPlant::PlantEquipmentType::CoilWaterSimpleHeating, thisDOAS.HWPlantLoc, errorsFound, _, _, _, _, _);
     598            1 :                         if (errorsFound) { // is this really needed here, program fatals out later on when errorsFound = true
     599            0 :                             ShowFatalError(state, "GetAirLoopDOASInput: Program terminated for previous conditions.");
     600              :                         }
     601            1 :                         break;
     602              : 
     603            0 :                     case ValidEquipListType::CoilHeatingSteam:
     604            0 :                         thisOutsideAirSys.InletNodeNum(CompNum) = SteamCoils::GetCoilSteamInletNode(state, CompType, CompName, InletNodeErrFlag);
     605            0 :                         thisOutsideAirSys.OutletNodeNum(CompNum) = SteamCoils::GetCoilSteamOutletNode(state, CompType, CompName, OutletNodeErrFlag);
     606            0 :                         break;
     607              : 
     608            0 :                     case ValidEquipListType::CoilCoolingWaterDetailedGeometry:
     609            0 :                         thisOutsideAirSys.InletNodeNum(CompNum) = WaterCoils::GetCoilInletNode(state, typeNameUC, CompName, InletNodeErrFlag);
     610            0 :                         thisOutsideAirSys.OutletNodeNum(CompNum) = WaterCoils::GetCoilOutletNode(state, typeNameUC, CompName, OutletNodeErrFlag);
     611            0 :                         thisDOAS.CWCtrlNodeNum =
     612            0 :                             WaterCoils::GetCoilWaterInletNode(state, "Coil:Cooling:Water:DetailedGeometry", CompName, errorsFound);
     613            0 :                         if (errorsFound) {
     614            0 :                             ShowContinueError(state, format("The control node number is not found in {} = {}", CurrentModuleObject, CompName));
     615              :                         }
     616            0 :                         PlantUtilities::ScanPlantLoopsForObject(state,
     617              :                                                                 CompName,
     618              :                                                                 DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling,
     619              :                                                                 thisDOAS.CWPlantLoc,
     620              :                                                                 errorsFound,
     621              :                                                                 _,
     622              :                                                                 _,
     623              :                                                                 _,
     624              :                                                                 _,
     625              :                                                                 _);
     626            0 :                         if (errorsFound) { // is this really needed here, program fatals out later on when errorsFound = true
     627            0 :                             ShowFatalError(state, "GetAirLoopDOASInput: Program terminated for previous conditions.");
     628              :                         }
     629            0 :                         CoolingCoilOrder = CompNum;
     630            0 :                         break;
     631              : 
     632            0 :                     case ValidEquipListType::CoilHeatingElectric:
     633              :                     case ValidEquipListType::CoilHeatingFuel:
     634            0 :                         thisOutsideAirSys.InletNodeNum(CompNum) = HeatingCoils::GetCoilInletNode(state, typeNameUC, CompName, InletNodeErrFlag);
     635            0 :                         thisOutsideAirSys.OutletNodeNum(CompNum) = HeatingCoils::GetCoilOutletNode(state, typeNameUC, CompName, OutletNodeErrFlag);
     636            0 :                         break;
     637              : 
     638            0 :                     case ValidEquipListType::CoilSystemCoolingWaterHeatExchangerAssisted:
     639            0 :                         thisOutsideAirSys.InletNodeNum(CompNum) =
     640            0 :                             HVACHXAssistedCoolingCoil::GetCoilInletNode(state, CompType, CompName, InletNodeErrFlag);
     641            0 :                         thisOutsideAirSys.OutletNodeNum(CompNum) =
     642            0 :                             HVACHXAssistedCoolingCoil::GetCoilOutletNode(state, CompType, CompName, OutletNodeErrFlag);
     643            0 :                         break;
     644              : 
     645            0 :                     case ValidEquipListType::CoilSystemCoolingDX:
     646              :                     case ValidEquipListType::AirLoopHVACUnitarySystem:
     647            0 :                         if (thisOutsideAirSys.compPointer[CompNum] == nullptr) {
     648            0 :                             UnitarySystems::UnitarySys thisSys;
     649            0 :                             thisOutsideAirSys.compPointer[CompNum] =
     650            0 :                                 UnitarySystems::UnitarySys::factory(state, HVAC::UnitarySysType::Unitary_AnyCoilType, CompName, false, 0);
     651            0 :                         }
     652            0 :                         thisOutsideAirSys.InletNodeNum(CompNum) =
     653            0 :                             thisOutsideAirSys.compPointer[CompNum]->getAirInNode(state, CompName, 0, InletNodeErrFlag);
     654            0 :                         thisOutsideAirSys.OutletNodeNum(CompNum) =
     655            0 :                             thisOutsideAirSys.compPointer[CompNum]->getAirOutNode(state, CompName, 0, OutletNodeErrFlag);
     656            0 :                         CoolingCoilOrder = CompNum;
     657            0 :                         break;
     658              : 
     659            0 :                     case ValidEquipListType::CoilSystemHeatingDX:
     660            0 :                         thisOutsideAirSys.InletNodeNum(CompNum) = HVACDXHeatPumpSystem::GetHeatingCoilInletNodeNum(state, CompName, InletNodeErrFlag);
     661            0 :                         thisOutsideAirSys.OutletNodeNum(CompNum) =
     662            0 :                             HVACDXHeatPumpSystem::GetHeatingCoilOutletNodeNum(state, CompName, OutletNodeErrFlag);
     663            0 :                         break;
     664              : 
     665            0 :                     case ValidEquipListType::CoilUserDefined:
     666            0 :                         ShowSevereError(state,
     667            0 :                                         format("When {} = {} is used in AirLoopHVAC:DedicatedOutdoorAirSystem,", CurrentModuleObject, CompName));
     668            0 :                         ShowContinueError(state, " the COIL:USERDEFINED can not be used as a component.");
     669            0 :                         errorsFound = true;
     670            0 :                         break;
     671              : 
     672            0 :                     case ValidEquipListType::HeatExchangerAirToAirFlatPlate:
     673              :                     case ValidEquipListType::HeatExchangerAirToAirSensibleAndLatent:
     674              :                     case ValidEquipListType::HeatExchangerDesiccantBalancedFlow:
     675            0 :                         thisOutsideAirSys.HeatExchangerFlag = true;
     676            0 :                         thisOutsideAirSys.InletNodeNum(CompNum) = HeatRecovery::GetSupplyInletNode(state, CompName, InletNodeErrFlag);
     677            0 :                         thisOutsideAirSys.OutletNodeNum(CompNum) = HeatRecovery::GetSupplyOutletNode(state, CompName, OutletNodeErrFlag);
     678            0 :                         break;
     679              : 
     680            0 :                     case ValidEquipListType::DehumidifierDesiccantNoFans:
     681              :                     case ValidEquipListType::DehumidifierDesiccantSystem:
     682            0 :                         thisOutsideAirSys.InletNodeNum(CompNum) = DesiccantDehumidifiers::GetProcAirInletNodeNum(state, CompName, InletNodeErrFlag);
     683            0 :                         thisOutsideAirSys.OutletNodeNum(CompNum) =
     684            0 :                             DesiccantDehumidifiers::GetProcAirOutletNodeNum(state, CompName, OutletNodeErrFlag);
     685            0 :                         break;
     686              : 
     687            0 :                     case ValidEquipListType::HumidifierSteamElectric:
     688              :                     case ValidEquipListType::HumidifierSteamGas:
     689            0 :                         thisOutsideAirSys.InletNodeNum(CompNum) = Humidifiers::GetAirInletNodeNum(state, CompName, InletNodeErrFlag);
     690            0 :                         thisOutsideAirSys.OutletNodeNum(CompNum) = Humidifiers::GetAirOutletNodeNum(state, CompName, OutletNodeErrFlag);
     691            0 :                         break;
     692              : 
     693            0 :                     case ValidEquipListType::SolarCollectorUnglazedTranspired:
     694            0 :                         thisOutsideAirSys.InletNodeNum(CompNum) = TranspiredCollector::GetAirInletNodeNum(state, CompName, InletNodeErrFlag);
     695            0 :                         thisOutsideAirSys.OutletNodeNum(CompNum) = TranspiredCollector::GetAirOutletNodeNum(state, CompName, OutletNodeErrFlag);
     696            0 :                         break;
     697              : 
     698            0 :                     case ValidEquipListType::SolarCollectorFlatPlatePhotovoltaicThermal:
     699            0 :                         thisOutsideAirSys.InletNodeNum(CompNum) =
     700            0 :                             PhotovoltaicThermalCollectors::GetAirInletNodeNum(state, CompName, InletNodeErrFlag);
     701            0 :                         thisOutsideAirSys.OutletNodeNum(CompNum) =
     702            0 :                             PhotovoltaicThermalCollectors::GetAirOutletNodeNum(state, CompName, OutletNodeErrFlag);
     703            0 :                         break;
     704              : 
     705            0 :                     case ValidEquipListType::EvaporativeCoolerDirectCeldekPad:
     706              :                     case ValidEquipListType::EvaporativeCoolerIndirectCeldekPad:
     707              :                     case ValidEquipListType::EvaporativeCoolerIndirectWetCoil:
     708              :                     case ValidEquipListType::EvaporativeCoolerIndirectResearchSpecial:
     709              :                     case ValidEquipListType::EvaporativeCoolerDirectResearchSpecial:
     710            0 :                         thisOutsideAirSys.InletNodeNum(CompNum) = EvaporativeCoolers::GetInletNodeNum(state, CompName, InletNodeErrFlag);
     711            0 :                         thisOutsideAirSys.OutletNodeNum(CompNum) = EvaporativeCoolers::GetOutletNodeNum(state, CompName, OutletNodeErrFlag);
     712            0 :                         break;
     713              : 
     714            0 :                     case ValidEquipListType::ZoneHVACTerminalUnitVariableRefrigerantFlow:
     715            0 :                         thisOutsideAirSys.InletNodeNum(CompNum) =
     716            0 :                             HVACVariableRefrigerantFlow::GetVRFTUInAirNodeFromName(state, CompName, InletNodeErrFlag);
     717            0 :                         thisOutsideAirSys.OutletNodeNum(CompNum) =
     718            0 :                             HVACVariableRefrigerantFlow::GetVRFTUOutAirNodeFromName(state, CompName, OutletNodeErrFlag);
     719            0 :                         break;
     720              : 
     721            0 :                     default:
     722            0 :                         ShowSevereError(state,
     723            0 :                                         format(R"({} = "{}" invalid Outside Air Component="{}".)",
     724              :                                                CurrentModuleObject,
     725              :                                                CompName,
     726              :                                                thisOutsideAirSys.ComponentType(CompNum)));
     727            0 :                         errorsFound = true;
     728              :                     }
     729            3 :                     if (CoolingCoilOrder > FanOrder && !thisDOAS.FanBeforeCoolingCoilFlag) {
     730            0 :                         thisDOAS.FanBeforeCoolingCoilFlag = true;
     731              :                     }
     732            3 :                     if (InletNodeErrFlag) {
     733            0 :                         ShowSevereError(state, format("Inlet node number is not found in {} = {}", CurrentModuleObject, CompName));
     734            0 :                         errorsFound = true;
     735              :                     }
     736            3 :                     if (OutletNodeErrFlag) {
     737            0 :                         ShowSevereError(state, format("Outlet node number is not found in {} = {}", CurrentModuleObject, CompName));
     738            0 :                         errorsFound = true;
     739              :                     }
     740              :                     // Check node connection to ensure that the outlet node of the previous component is the inlet node of the current component
     741            3 :                     if (CompNum > 1) {
     742            2 :                         if (thisOutsideAirSys.InletNodeNum(CompNum) != thisOutsideAirSys.OutletNodeNum(CompNum - 1)) {
     743            0 :                             ShowSevereError(state,
     744            0 :                                             format("getAirLoopMixer: Node Connection Error in AirLoopHVAC:DedicatedOutdoorAirSystem = {}. Inlet node "
     745              :                                                    "of {} as current component is not same as the outlet node of "
     746              :                                                    "{} as previous component",
     747              :                                                    thisDOAS.Name,
     748              :                                                    thisOutsideAirSys.ComponentName(CompNum),
     749              :                                                    thisOutsideAirSys.ComponentName(CompNum - 1)));
     750            0 :                             ShowContinueError(state,
     751            0 :                                               format("The inlet node name = {}, and the outlet node name = {}.",
     752            0 :                                                      state.dataLoopNodes->NodeID(thisOutsideAirSys.InletNodeNum(CompNum)),
     753            0 :                                                      state.dataLoopNodes->NodeID(thisOutsideAirSys.OutletNodeNum(CompNum - 1))));
     754            0 :                             errorsFound = true;
     755              :                         }
     756              :                     }
     757            3 :                 }
     758              : 
     759            1 :                 thisDOAS.m_InletNodeNum = thisOutsideAirSys.InletNodeNum(1);
     760            1 :                 thisDOAS.m_OutletNodeNum = thisOutsideAirSys.OutletNodeNum(thisOutsideAirSys.NumComponents);
     761            1 :                 thisOutsideAirSys.AirLoopDOASNum = AirLoopDOASNum - 1;
     762              :                 // Set up parent-child connection
     763            2 :                 BranchNodeConnections::SetUpCompSets(state,
     764              :                                                      cCurrentModuleObject,
     765              :                                                      thisDOAS.Name,
     766              :                                                      "AIRLOOPHVAC:OUTDOORAIRSYSTEM",
     767              :                                                      thisDOAS.OASystemName,
     768            1 :                                                      state.dataLoopNodes->NodeID(thisDOAS.m_InletNodeNum),
     769            1 :                                                      state.dataLoopNodes->NodeID(thisDOAS.m_OutletNodeNum));
     770              : 
     771            1 :                 if (thisOutsideAirSys.HeatExchangerFlag) {
     772            0 :                     thisDOAS.m_HeatExchangerFlag = true;
     773              :                 }
     774              : 
     775            1 :                 thisDOAS.AvailManagerSchedName = Util::makeUPPER(fields.at("availability_schedule_name").get<std::string>());
     776              : 
     777            1 :                 if ((thisDOAS.m_AvailManagerSched = Sched::GetSchedule(state, thisDOAS.AvailManagerSchedName)) == nullptr) {
     778            0 :                     ShowSevereItemNotFound(state, eoh, "Availability Schedule Name", thisDOAS.AvailManagerSchedName);
     779            0 :                     errorsFound = true;
     780              :                 }
     781              : 
     782            1 :                 thisDOAS.AirLoopMixerName = Util::makeUPPER(fields.at("airloophvac_mixer_name").get<std::string>()); //
     783            1 :                 thisDOAS.m_AirLoopMixerIndex = getAirLoopMixerIndex(state, thisDOAS.AirLoopMixerName);
     784            1 :                 if (thisDOAS.m_AirLoopMixerIndex < 0) {
     785            0 :                     cFieldName = "AirLoopHVAC:Mixer Name";
     786            0 :                     ShowSevereError(
     787            0 :                         state, format("{}, \"{}\" {} not found: {}", cCurrentModuleObject, thisDOAS.Name, cFieldName, thisDOAS.AirLoopMixerName));
     788            0 :                     errorsFound = true;
     789              :                 }
     790            2 :                 AirLoopMixer thisAirLoopMixer;
     791            1 :                 thisDOAS.m_CompPointerAirLoopMixer = thisAirLoopMixer.factory(state, thisDOAS.m_AirLoopMixerIndex, thisDOAS.AirLoopMixerName);
     792            1 :                 thisDOAS.AirLoopSplitterName = Util::makeUPPER(fields.at("airloophvac_splitter_name").get<std::string>()); //
     793            1 :                 thisDOAS.m_AirLoopSplitterIndex = getAirLoopSplitterIndex(state, thisDOAS.AirLoopSplitterName);
     794            1 :                 if (thisDOAS.m_AirLoopSplitterIndex < 0) {
     795            0 :                     cFieldName = "AirLoopHVAC:Splitter Name";
     796            0 :                     ShowSevereError(
     797            0 :                         state, format("{}, \"{}\" {} not found: {}", cCurrentModuleObject, thisDOAS.Name, cFieldName, thisDOAS.AirLoopSplitterName));
     798            0 :                     errorsFound = true;
     799              :                 }
     800            2 :                 AirLoopSplitter thisAirLoopSplitter;
     801            1 :                 thisDOAS.m_CompPointerAirLoopSplitter =
     802            1 :                     thisAirLoopSplitter.factory(state, thisDOAS.m_AirLoopSplitterIndex, thisDOAS.AirLoopSplitterName);
     803              : 
     804              :                 // get pretreated design conditions
     805            2 :                 thisDOAS.PreheatTemp = fields.at("preheat_design_temperature").get<Real64>();
     806            2 :                 thisDOAS.PreheatHumRat = fields.at("preheat_design_humidity_ratio").get<Real64>();
     807            2 :                 thisDOAS.PrecoolTemp = fields.at("precool_design_temperature").get<Real64>();
     808            2 :                 thisDOAS.PrecoolHumRat = fields.at("precool_design_humidity_ratio").get<Real64>();
     809              : 
     810              :                 // get info on AirLoops
     811            1 :                 thisDOAS.NumOfAirLoops = fields.at("number_of_airloophvac").get<int>(); //
     812            1 :                 if (thisDOAS.NumOfAirLoops < 1) {
     813            0 :                     cFieldName = "Number of AirLoopHVAC";
     814            0 :                     ShowSevereError(state,
     815            0 :                                     fmt::format("{}, \"{}\" {} = {}", cCurrentModuleObject, thisDOAS.Name, cFieldName, thisDOAS.NumOfAirLoops));
     816            0 :                     ShowContinueError(state, " The minimum value should be 1.");
     817            0 :                     errorsFound = true;
     818              :                 }
     819              : 
     820            2 :                 auto AirLoopNames = fields.find("airloophvacs");
     821            1 :                 if (AirLoopNames != fields.end()) {
     822            1 :                     auto const &AirLoopArray = AirLoopNames.value();
     823            1 :                     int num = 0;
     824            6 :                     for (auto const &AirLoopHVACName : AirLoopArray) {
     825            5 :                         std::string name = Util::makeUPPER(AirLoopHVACName.at("airloophvac_name").get<std::string>());
     826            5 :                         int LoopNum = Util::FindItemInList(name, state.dataAirSystemsData->PrimaryAirSystems);
     827              : 
     828            5 :                         num += 1;
     829            5 :                         if (LoopNum > 0 && num <= thisDOAS.NumOfAirLoops) {
     830            5 :                             thisDOAS.AirLoopName.push_back(name);
     831            5 :                             thisDOAS.m_AirLoopNum.push_back(LoopNum);
     832              :                         } else {
     833            0 :                             cFieldName = "AirLoopHVAC Name";
     834            0 :                             ShowSevereError(state, format("{}, \"{}\" {} not found: {}", cCurrentModuleObject, thisDOAS.Name, cFieldName, name));
     835            0 :                             errorsFound = true;
     836              :                         }
     837            6 :                     }
     838              :                 }
     839              : 
     840            1 :                 thisDOAS.m_AirLoopDOASNum = AirLoopDOASNum - 1;
     841            1 :                 state.dataAirLoopHVACDOAS->airloopDOAS.push_back(thisDOAS);
     842              : 
     843            1 :                 if (!OutAirNodeManager::CheckOutAirNodeNumber(state, thisDOAS.m_InletNodeNum)) {
     844            0 :                     ShowSevereError(state,
     845            0 :                                     format("Inlet node ({}) is not one of OutdoorAir:Node in {} = {}",
     846            0 :                                            state.dataLoopNodes->NodeID(thisDOAS.m_InletNodeNum),
     847              :                                            CurrentModuleObject,
     848              :                                            thisDOAS.Name));
     849            0 :                     errorsFound = true;
     850              :                 }
     851              : 
     852              :                 // Ensure the outlet node is the splitter inlet node, otherwise issue a severe error
     853            1 :                 if (thisDOAS.m_OutletNodeNum != thisDOAS.m_CompPointerAirLoopSplitter->InletNodeNum) {
     854            0 :                     ShowSevereError(
     855              :                         state,
     856            0 :                         format("The outlet node is not the inlet node of AirLoopHVAC:Splitter in {} = {}", CurrentModuleObject, thisDOAS.Name));
     857            0 :                     ShowContinueError(state,
     858            0 :                                       format("The outlet node name is {}, and the inlet node name of AirLoopHVAC:Splitter is {}",
     859            0 :                                              state.dataLoopNodes->NodeID(thisDOAS.m_OutletNodeNum),
     860            0 :                                              state.dataLoopNodes->NodeID(thisDOAS.m_CompPointerAirLoopSplitter->InletNodeNum)));
     861            0 :                     errorsFound = true;
     862              :                 }
     863            2 :             }
     864              : 
     865              :             // Check valid OA controller
     866            7 :             for (int OASysNum = 1; OASysNum <= state.dataAirLoop->NumOASystems; OASysNum++) {
     867            6 :                 if (Util::SameString(state.dataAirLoop->OutsideAirSys(OASysNum).ControllerListName, "")) {
     868            0 :                     if (state.dataAirLoop->OutsideAirSys(OASysNum).AirLoopDOASNum == -1) {
     869            0 :                         ShowSevereError(state,
     870            0 :                                         format("AirLoopHVAC:OutdoorAirSystem = \"{}\" invalid Controller List Name = \" not found.",
     871            0 :                                                state.dataAirLoop->OutsideAirSys(OASysNum).Name));
     872            0 :                         errorsFound = true;
     873              :                     }
     874              :                 }
     875              :             }
     876            1 :             if (errorsFound) {
     877            0 :                 ShowFatalError(state, "getAirLoopHVACDOAS: Previous errors cause termination.");
     878              :             }
     879            1 :         }
     880            1 :     }
     881              : 
     882        10882 :     void AirLoopDOAS::initAirLoopDOAS(EnergyPlusData &state, bool const FirstHVACIteration)
     883              :     {
     884              :         int LoopOA;
     885              :         Real64 SchAvailValue;
     886              :         static constexpr std::string_view RoutineName = "AirLoopDOAS::initAirLoopDOAS";
     887              : 
     888        10882 :         if (state.dataGlobal->BeginEnvrnFlag && this->MyEnvrnFlag) {
     889            5 :             bool ErrorsFound = false;
     890              :             Real64 rho;
     891           20 :             for (int CompNum = 1; CompNum <= state.dataAirLoop->OutsideAirSys(this->m_OASystemNum).NumComponents; ++CompNum) {
     892           15 :                 std::string const &CompType = state.dataAirLoop->OutsideAirSys(this->m_OASystemNum).ComponentType(CompNum);
     893           15 :                 std::string const &CompName = state.dataAirLoop->OutsideAirSys(this->m_OASystemNum).ComponentName(CompNum);
     894           15 :                 if (Util::SameString(CompType, "FAN:SYSTEMMODEL")) {
     895            5 :                     state.dataFans->fans(this->m_FanIndex)->simulate(state, FirstHVACIteration);
     896              :                 }
     897           15 :                 if (Util::SameString(CompType, "FAN:COMPONENTMODEL")) {
     898            0 :                     state.dataFans->fans(this->m_FanIndex)->simulate(state, FirstHVACIteration);
     899              :                 }
     900              : 
     901           15 :                 if (Util::SameString(CompType, "COIL:HEATING:WATER")) {
     902            5 :                     WaterCoils::SimulateWaterCoilComponents(state, CompName, FirstHVACIteration, this->m_HeatCoilNum);
     903            5 :                     Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", CompName, ErrorsFound);
     904            5 :                     rho = state.dataPlnt->PlantLoop(this->HWPlantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
     905            5 :                     PlantUtilities::InitComponentNodes(state,
     906              :                                                        0.0,
     907              :                                                        CoilMaxVolFlowRate * rho,
     908              :                                                        this->HWCtrlNodeNum,
     909            5 :                                                        state.dataAirLoop->OutsideAirSys(this->m_OASystemNum).OutletNodeNum(CompNum));
     910              :                 }
     911           15 :                 if (Util::SameString(CompType, "COIL:COOLING:WATER")) {
     912            5 :                     WaterCoils::SimulateWaterCoilComponents(state, CompName, FirstHVACIteration, this->m_CoolCoilNum);
     913            5 :                     Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Cooling:Water", CompName, ErrorsFound);
     914            5 :                     rho = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
     915            5 :                     PlantUtilities::InitComponentNodes(state,
     916              :                                                        0.0,
     917              :                                                        CoilMaxVolFlowRate * rho,
     918              :                                                        this->CWCtrlNodeNum,
     919            5 :                                                        state.dataAirLoop->OutsideAirSys(this->m_OASystemNum).OutletNodeNum(CompNum));
     920              :                 }
     921           15 :                 if (Util::SameString(CompType, "COIL:COOLING:WATER:DETAILEDGEOMETRY")) {
     922            0 :                     WaterCoils::SimulateWaterCoilComponents(state, CompName, FirstHVACIteration, this->m_CoolCoilNum);
     923              :                     Real64 CoilMaxVolFlowRate =
     924            0 :                         WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Cooling:Water:DetailedGeometry", CompName, ErrorsFound);
     925            0 :                     rho = state.dataPlnt->PlantLoop(this->CWPlantLoc.loopNum).glycol->getDensity(state, Constant::CWInitConvTemp, RoutineName);
     926            0 :                     PlantUtilities::InitComponentNodes(state,
     927              :                                                        0.0,
     928              :                                                        CoilMaxVolFlowRate * rho,
     929              :                                                        this->CWCtrlNodeNum,
     930            0 :                                                        state.dataAirLoop->OutsideAirSys(this->m_OASystemNum).OutletNodeNum(CompNum));
     931              :                 }
     932              :             }
     933              : 
     934            5 :             this->MyEnvrnFlag = false;
     935            5 :             if (ErrorsFound) {
     936            0 :                 ShowFatalError(state, "initAirLoopDOAS: Previous errors cause termination.");
     937              :             }
     938              :         }
     939              : 
     940        10882 :         if (!state.dataGlobal->BeginEnvrnFlag) {
     941        10832 :             this->MyEnvrnFlag = true;
     942              :         }
     943              : 
     944        10882 :         this->SumMassFlowRate = 0.0;
     945              : 
     946        65292 :         for (LoopOA = 0; LoopOA < this->m_CompPointerAirLoopSplitter->numOfOutletNodes; LoopOA++) {
     947        54410 :             int NodeNum = this->m_CompPointerAirLoopSplitter->OutletNodeNum[LoopOA];
     948        54410 :             this->SumMassFlowRate += state.dataLoopNodes->Node(NodeNum).MassFlowRate;
     949              :         }
     950              : 
     951        10882 :         SchAvailValue = this->m_AvailManagerSched->getCurrentVal();
     952        10882 :         if (SchAvailValue < 1.0) {
     953            0 :             this->SumMassFlowRate = 0.0;
     954              :         }
     955        10882 :         state.dataLoopNodes->Node(this->m_InletNodeNum).MassFlowRate = this->SumMassFlowRate;
     956        10882 :     }
     957              : 
     958        10882 :     void AirLoopDOAS::CalcAirLoopDOAS(EnergyPlusData &state, bool const FirstHVACIteration)
     959              :     {
     960              :         using MixedAir::ManageOutsideAirSystem;
     961              : 
     962        10882 :         this->m_CompPointerAirLoopMixer->CalcAirLoopMixer(state);
     963        10882 :         if (this->m_FanIndex > 0) {
     964        10882 :             if (this->m_FanInletNodeNum == this->m_InletNodeNum) {
     965        10882 :                 state.dataLoopNodes->Node(this->m_FanInletNodeNum).MassFlowRateMaxAvail = this->SumMassFlowRate;
     966        10882 :                 state.dataLoopNodes->Node(this->m_FanOutletNodeNum).MassFlowRateMaxAvail = this->SumMassFlowRate;
     967        10882 :                 state.dataLoopNodes->Node(this->m_FanOutletNodeNum).MassFlowRateMax = this->SumMassFlowRate;
     968              :             } else {
     969            0 :                 state.dataLoopNodes->Node(this->m_InletNodeNum).MassFlowRateMax = this->SumMassFlowRate;
     970            0 :                 state.dataLoopNodes->Node(this->m_InletNodeNum).MassFlowRateMaxAvail = this->SumMassFlowRate;
     971              :             }
     972              :         }
     973        10882 :         ManageOutsideAirSystem(state, this->OASystemName, FirstHVACIteration, 0, this->m_OASystemNum);
     974        10882 :         Real64 Temp = state.dataLoopNodes->Node(this->m_OutletNodeNum).Temp;
     975        10882 :         Real64 HumRat = state.dataLoopNodes->Node(this->m_OutletNodeNum).HumRat;
     976        10882 :         state.dataLoopNodes->Node(this->m_OutletNodeNum).Enthalpy = Psychrometrics::PsyHFnTdbW(Temp, HumRat);
     977              : 
     978        10882 :         this->m_CompPointerAirLoopSplitter->CalcAirLoopSplitter(state, Temp, HumRat);
     979        10882 :     }
     980              : 
     981            1 :     void AirLoopDOAS::SizingAirLoopDOAS(EnergyPlusData &state)
     982              :     {
     983            1 :         Real64 sizingVolumeFlow = 0;
     984              : 
     985            6 :         for (int AirLoop = 1; AirLoop <= this->NumOfAirLoops; AirLoop++) {
     986            5 :             int AirLoopNum = this->m_AirLoopNum[AirLoop - 1];
     987            5 :             this->m_OACtrlNum.push_back(state.dataAirLoop->AirLoopControlInfo(AirLoopNum).OACtrlNum);
     988              : 
     989            5 :             if (this->m_OACtrlNum[AirLoop - 1] > 0) {
     990            5 :                 sizingVolumeFlow +=
     991            5 :                     state.dataMixedAir->OAController(this->m_OACtrlNum[AirLoop - 1]).MaxOA; // this is a volume flow rate not a mass flow rate
     992              :             }
     993              :         }
     994            1 :         this->SizingMassFlow = sizingVolumeFlow * state.dataEnvrn->StdRhoAir;
     995              : 
     996            1 :         BaseSizer::reportSizerOutput(state, "AirLoopHVAC:DedicatedOutdoorAirSystem", this->Name, "Design Volume Flow Rate [m3/s]", sizingVolumeFlow);
     997            1 :         this->GetDesignDayConditions(state);
     998              : 
     999            1 :         if (this->m_FanIndex > 0 && this->m_FanTypeNum == SimAirServingZones::CompType::Fan_System_Object) {
    1000            1 :             state.dataFans->fans(this->m_FanIndex)->maxAirFlowRate = sizingVolumeFlow;
    1001            1 :             state.dataLoopNodes->Node(this->m_FanInletNodeNum).MassFlowRateMaxAvail = this->SizingMassFlow;
    1002            1 :             state.dataLoopNodes->Node(this->m_FanOutletNodeNum).MassFlowRateMaxAvail = this->SizingMassFlow;
    1003            1 :             state.dataLoopNodes->Node(this->m_FanOutletNodeNum).MassFlowRateMax = this->SizingMassFlow;
    1004              :         }
    1005            1 :         if (this->m_FanIndex > 0 && this->m_FanTypeNum == SimAirServingZones::CompType::Fan_ComponentModel) {
    1006            0 :             state.dataFans->fans(this->m_FanIndex)->maxAirFlowRate = sizingVolumeFlow;
    1007            0 :             state.dataFans->fans(this->m_FanIndex)->minAirFlowRate = 0.0;
    1008            0 :             state.dataFans->fans(this->m_FanIndex)->maxAirMassFlowRate = this->SizingMassFlow;
    1009            0 :             state.dataLoopNodes->Node(this->m_FanInletNodeNum).MassFlowRateMaxAvail = this->SizingMassFlow;
    1010            0 :             state.dataLoopNodes->Node(this->m_FanOutletNodeNum).MassFlowRateMaxAvail = this->SizingMassFlow;
    1011            0 :             state.dataLoopNodes->Node(this->m_FanOutletNodeNum).MassFlowRateMax = this->SizingMassFlow;
    1012              :         }
    1013              : 
    1014            1 :         state.dataSize->CurSysNum = state.dataHVACGlobal->NumPrimaryAirSys + this->m_AirLoopDOASNum + 1;
    1015            1 :         state.dataSize->CurOASysNum = this->m_OASystemNum;
    1016            1 :     }
    1017              : 
    1018            1 :     void getAirLoopHVACDOASInput(EnergyPlusData &state)
    1019              :     {
    1020            1 :         if (state.dataAirLoopHVACDOAS->GetInputOnceFlag) {
    1021            1 :             AirLoopDOAS::getAirLoopDOASInput(state);
    1022            1 :             state.dataAirLoopHVACDOAS->GetInputOnceFlag = false;
    1023              :         }
    1024            1 :     }
    1025              : 
    1026            1 :     void AirLoopDOAS::GetDesignDayConditions(EnergyPlusData &state)
    1027              :     {
    1028            4 :         for (auto &env : state.dataWeather->Environment) {
    1029            3 :             if (env.KindOfEnvrn != Constant::KindOfSim::DesignDay && env.KindOfEnvrn != Constant::KindOfSim::RunPeriodDesign) {
    1030            1 :                 continue;
    1031              :             }
    1032            2 :             if (env.maxCoolingOATSizing > this->SizingCoolOATemp) {
    1033            2 :                 this->SizingCoolOATemp = env.maxCoolingOATSizing;
    1034              :                 // DesignDayNum = 0 for KindOfSim == RunPeriodDesign
    1035            2 :                 if (env.KindOfEnvrn == Constant::KindOfSim::DesignDay && state.dataWeather->DesDayInput(env.DesignDayNum).PressureEntered) {
    1036            2 :                     this->SizingCoolOAHumRat =
    1037            2 :                         Psychrometrics::PsyWFnTdpPb(state, env.maxCoolingOADPSizing, state.dataWeather->DesDayInput(env.DesignDayNum).PressBarom);
    1038              :                 } else {
    1039            0 :                     this->SizingCoolOAHumRat = Psychrometrics::PsyWFnTdpPb(state, env.maxCoolingOADPSizing, state.dataEnvrn->StdBaroPress);
    1040              :                 }
    1041              :             }
    1042            2 :             if (env.minHeatingOATSizing < this->HeatOutTemp) {
    1043            1 :                 this->HeatOutTemp = env.minHeatingOATSizing;
    1044            1 :                 if (env.KindOfEnvrn == Constant::KindOfSim::DesignDay && state.dataWeather->DesDayInput(env.DesignDayNum).PressureEntered) {
    1045            1 :                     this->HeatOutHumRat =
    1046            1 :                         Psychrometrics::PsyWFnTdpPb(state, env.minHeatingOADPSizing, state.dataWeather->DesDayInput(env.DesignDayNum).PressBarom);
    1047              :                 } else {
    1048            0 :                     this->HeatOutHumRat = Psychrometrics::PsyWFnTdpPb(state, env.minHeatingOADPSizing, state.dataEnvrn->StdBaroPress);
    1049              :                 }
    1050              :             }
    1051              :         }
    1052              : 
    1053            1 :         BaseSizer::reportSizerOutput(
    1054              :             state, "AirLoopHVAC:DedicatedOutdoorAirSystem", this->Name, "Design Cooling Outdoor Air Temperature [C]", this->SizingCoolOATemp);
    1055            1 :         BaseSizer::reportSizerOutput(state,
    1056              :                                      "AirLoopHVAC:DedicatedOutdoorAirSystem",
    1057              :                                      this->Name,
    1058              :                                      "Design Cooling Outdoor Air Humidity Ratio [kgWater/kgDryAir]",
    1059              :                                      this->SizingCoolOAHumRat);
    1060            1 :         BaseSizer::reportSizerOutput(
    1061              :             state, "AirLoopHVAC:DedicatedOutdoorAirSystem", this->Name, "Design Heating Outdoor Air Temperature [C]", this->HeatOutTemp);
    1062            1 :         BaseSizer::reportSizerOutput(state,
    1063              :                                      "AirLoopHVAC:DedicatedOutdoorAirSystem",
    1064              :                                      this->Name,
    1065              :                                      "Design Heating Outdoor Air Humidity Ratio [kgWater/kgDryAir]",
    1066              :                                      this->HeatOutHumRat);
    1067            1 :     }
    1068              : 
    1069         5358 :     void CheckConvergence(EnergyPlusData &state)
    1070              :     {
    1071              : 
    1072              :         Real64 maxDiff;
    1073              :         Real64 Diff;
    1074              :         Real64 OldTemp;
    1075        10716 :         for (auto &loop : state.dataAirLoopHVACDOAS->airloopDOAS) {
    1076         5358 :             maxDiff = 0.0;
    1077        10716 :             Diff = std::abs(loop.m_CompPointerAirLoopSplitter->InletTemp -
    1078         5358 :                             state.dataLoopNodes->Node(loop.m_CompPointerAirLoopSplitter->OutletNodeNum[0]).Temp);
    1079         5358 :             if (Diff > maxDiff) {
    1080            0 :                 maxDiff = Diff;
    1081              :             }
    1082         5358 :             if (loop.m_HeatExchangerFlag) {
    1083            0 :                 OldTemp = loop.m_CompPointerAirLoopMixer->OutletTemp;
    1084            0 :                 loop.m_CompPointerAirLoopMixer->CalcAirLoopMixer(state);
    1085            0 :                 Diff = std::abs(OldTemp - loop.m_CompPointerAirLoopMixer->OutletTemp);
    1086            0 :                 if (Diff > maxDiff) {
    1087            0 :                     maxDiff = Diff;
    1088              :                 }
    1089              :             }
    1090         5358 :             if (maxDiff > 1.0e-6) {
    1091            0 :                 if (loop.ConveCount == 0) {
    1092            0 :                     ++loop.ConveCount;
    1093            0 :                     ShowWarningError(state, format("Convergence limit is above 1.0e-6 for unit={}", loop.Name));
    1094            0 :                     ShowContinueErrorTimeStamp(
    1095            0 :                         state, format("The max difference of node temperatures between AirLoopDOAS outlet and OA mixer inlet ={:.6R}", maxDiff));
    1096              :                 } else {
    1097            0 :                     ++loop.ConveCount;
    1098            0 :                     ShowRecurringWarningErrorAtEnd(state,
    1099            0 :                                                    loop.Name + "\": The max difference of node temperatures exceeding 1.0e-6  continues...",
    1100            0 :                                                    loop.ConveIndex,
    1101              :                                                    maxDiff,
    1102              :                                                    maxDiff);
    1103              :                 }
    1104              :             }
    1105         5358 :         }
    1106         5358 :     }
    1107              : 
    1108              : } // namespace AirLoopHVACDOAS
    1109              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1