LCOV - code coverage report
Current view: top level - EnergyPlus - AirLoopHVACDOAS.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 368 608 60.5 %
Date: 2024-08-24 18:31:18 Functions: 16 16 100.0 %

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

Generated by: LCOV version 1.14