LCOV - code coverage report
Current view: top level - EnergyPlus - DesiccantDehumidifiers.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 53.8 % 1634 879
Test Date: 2025-06-02 07:23:51 Functions: 75.0 % 12 9

            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 <cmath>
      50              : 
      51              : // ObjexxFCL Headers
      52              : #include <ObjexxFCL/Array.functions.hh>
      53              : #include <ObjexxFCL/Fmath.hh>
      54              : 
      55              : // EnergyPlus Headers
      56              : #include <EnergyPlus/BranchNodeConnections.hh>
      57              : #include <EnergyPlus/CurveManager.hh>
      58              : #include <EnergyPlus/DXCoils.hh>
      59              : #include <EnergyPlus/Data/EnergyPlusData.hh>
      60              : #include <EnergyPlus/DataHVACGlobals.hh>
      61              : #include <EnergyPlus/DataLoopNode.hh>
      62              : #include <EnergyPlus/DataSizing.hh>
      63              : #include <EnergyPlus/DesiccantDehumidifiers.hh>
      64              : #include <EnergyPlus/EMSManager.hh>
      65              : #include <EnergyPlus/Fans.hh>
      66              : #include <EnergyPlus/FluidProperties.hh>
      67              : #include <EnergyPlus/General.hh>
      68              : #include <EnergyPlus/GeneralRoutines.hh>
      69              : #include <EnergyPlus/GlobalNames.hh>
      70              : #include <EnergyPlus/HeatRecovery.hh>
      71              : #include <EnergyPlus/HeatingCoils.hh>
      72              : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      73              : #include <EnergyPlus/NodeInputManager.hh>
      74              : #include <EnergyPlus/OutAirNodeManager.hh>
      75              : #include <EnergyPlus/OutputProcessor.hh>
      76              : #include <EnergyPlus/PlantUtilities.hh>
      77              : #include <EnergyPlus/Psychrometrics.hh>
      78              : #include <EnergyPlus/ScheduleManager.hh>
      79              : #include <EnergyPlus/SteamCoils.hh>
      80              : #include <EnergyPlus/UtilityRoutines.hh>
      81              : #include <EnergyPlus/VariableSpeedCoils.hh>
      82              : #include <EnergyPlus/WaterCoils.hh>
      83              : 
      84              : namespace EnergyPlus {
      85              : 
      86              : namespace DesiccantDehumidifiers {
      87              : 
      88              :     // Module containing the routines dealing with dehumidifiers
      89              : 
      90              :     // MODULE INFORMATION:
      91              :     //       AUTHOR         Michael J. Witte, GARD Analytics, Inc.
      92              :     //                      for Gas Research Institute
      93              :     //       DATE WRITTEN   March 2001
      94              :     //       MODIFIED       Jan 2005 M. J. Witte, GARD Analytics, Inc.
      95              :     //                        Add new control type option:
      96              :     //                          NODE LEAVING HUMRAT SETPOINT:BYPASS
      97              :     //                        Change existing control type to:
      98              :     //                          FIXED LEAVING HUMRAT SETPOINT:BYPASS
      99              :     //                        Work supported by ASHRAE research project 1254-RP
     100              :     //                      June 2007 R. Raustad, FSEC
     101              :     //                        Added new dehumidifier type -- DESICCANT DEHUMIDIFIER
     102              :     //                      Jan 2012  B. Nigusse, FSEC
     103              :     //                        Added steam and hot water heating coils
     104              : 
     105              :     //       RE-ENGINEERED  na
     106              : 
     107              :     // PURPOSE OF THIS MODULE:
     108              :     // To encapsulate the data and routines required to model desiccant dehumidifier
     109              :     // components in the EnergyPlus HVAC simulation
     110              : 
     111              :     // METHODOLOGY EMPLOYED:
     112              :     // The desiccant dehumidifier emcompasses not just the component but also its
     113              :     // control. The desiccant dehumidifier removes moisture from its air inlet to meet
     114              :     // the HumRatMax setpoint at its exit node. The HumRatMax is set by
     115              :     // an external setpoint manager or is a fixed user input.
     116              : 
     117              :     // REFERENCES: na
     118              : 
     119              :     // OTHER NOTES: This module is based substantially on the Humidifiers module.
     120              :     //              authored by Fred Buhl.
     121              :     //              Development of portions of this module was funded by the Gas Research Institute.
     122              :     //              (Please see copyright and disclaimer information at end of module)
     123              : 
     124              :     Real64 constexpr TempSteamIn = 100.0;
     125              : 
     126       283978 :     void SimDesiccantDehumidifier(EnergyPlusData &state,
     127              :                                   std::string const &CompName,   // name of the dehumidifier unit
     128              :                                   bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
     129              :                                   int &CompIndex)
     130              :     {
     131              : 
     132              :         // SUBROUTINE INFORMATION:
     133              :         //       AUTHOR         Michael J. Witte, GARD Analytics, Inc.
     134              :         //                      for Gas Research Institute
     135              :         //       DATE WRITTEN   March 2001
     136              :         //       MODIFIED       June 2007, R. Raustad, Added new dehumidifier type -- DESICCANT DEHUMIDIFIER
     137              : 
     138              :         // PURPOSE OF THIS SUBROUTINE:
     139              :         // Manage the simulation of an air dehumidifier
     140              : 
     141              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     142              :         int DesicDehumNum;   // index of solid desiccant unit being simulated
     143              :         Real64 HumRatNeeded; // process air leaving humidity ratio set by controller [kg water/kg air]
     144              : 
     145       283978 :         if (state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier) {
     146            7 :             GetDesiccantDehumidifierInput(state);
     147            7 :             state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier = false;
     148              :         }
     149              : 
     150              :         // Get the desiccant dehumidifier unit index
     151       283978 :         if (CompIndex == 0) {
     152            9 :             DesicDehumNum = Util::FindItemInList(CompName, state.dataDesiccantDehumidifiers->DesicDehum);
     153            9 :             if (DesicDehumNum == 0) {
     154            0 :                 ShowFatalError(state, format("SimDesiccantDehumidifier: Unit not found={}", CompName));
     155              :             }
     156            9 :             CompIndex = DesicDehumNum;
     157              :         } else {
     158       283969 :             DesicDehumNum = CompIndex;
     159       283969 :             if (DesicDehumNum > state.dataDesiccantDehumidifiers->NumDesicDehums || DesicDehumNum < 1) {
     160            0 :                 ShowFatalError(state,
     161            0 :                                format("SimDesiccantDehumidifier:  Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
     162              :                                       DesicDehumNum,
     163            0 :                                       state.dataDesiccantDehumidifiers->NumDesicDehums,
     164              :                                       CompName));
     165              :             }
     166       283969 :             if (CompName != state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).Name) {
     167            0 :                 ShowFatalError(state,
     168            0 :                                format("SimDesiccantDehumidifier: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
     169              :                                       DesicDehumNum,
     170              :                                       CompName,
     171            0 :                                       state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).Name));
     172              :             }
     173              :         }
     174              : 
     175       283978 :         InitDesiccantDehumidifier(state, DesicDehumNum, FirstHVACIteration);
     176              : 
     177       283978 :         ControlDesiccantDehumidifier(state, DesicDehumNum, HumRatNeeded, FirstHVACIteration);
     178              : 
     179              :         // call the correct dehumidifier calculation routine
     180       283978 :         switch (state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).DehumTypeCode) {
     181        92320 :         case DesicDehumType::Solid: {
     182        92320 :             CalcSolidDesiccantDehumidifier(state, DesicDehumNum, HumRatNeeded, FirstHVACIteration);
     183        92320 :         } break;
     184       191658 :         case DesicDehumType::Generic: {
     185       191658 :             CalcGenericDesiccantDehumidifier(state, DesicDehumNum, HumRatNeeded, FirstHVACIteration);
     186       191658 :         } break;
     187            0 :         default: {
     188            0 :             ShowFatalError(state,
     189            0 :                            format("Invalid type, Desiccant Dehumidifer={}", state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).DehumType));
     190            0 :         } break;
     191              :         }
     192              : 
     193       283978 :         UpdateDesiccantDehumidifier(state, DesicDehumNum);
     194              : 
     195       283978 :         ReportDesiccantDehumidifier(state, DesicDehumNum);
     196       283978 :     }
     197              : 
     198            7 :     void GetDesiccantDehumidifierInput(EnergyPlusData &state)
     199              :     {
     200              : 
     201              :         // SUBROUTINE INFORMATION:
     202              :         //       AUTHOR         Michael J. Witte, GARD Analytics, Inc.
     203              :         //                      for Gas Research Institute
     204              :         //       DATE WRITTEN   March 2001
     205              :         //       MODIFIED       Jan 2005 M. J. Witte, GARD Analytics, Inc.
     206              :         //                        Add new control type option:
     207              :         //                          NODE LEAVING HUMRAT SETPOINT:BYPASS
     208              :         //                        Change existing control type to:
     209              :         //                          FIXED LEAVING HUMRAT SETPOINT:BYPASS
     210              :         //                        Work supported by ASHRAE research project 1254-RP
     211              :         //                      June 2007 R. Raustad, FSEC
     212              :         //                        Added new dehumidifier type -- DESICCANT DEHUMIDIFIER
     213              : 
     214              :         // PURPOSE OF THIS SUBROUTINE:
     215              :         // Obtains input data for humidifiers and stores it in dehumidifier data structures.
     216              : 
     217              :         // METHODOLOGY EMPLOYED:
     218              :         // Uses InputProcessor "Get" routines to obtain data.
     219              : 
     220              :         // SUBROUTINE PARAMETER DEFINITIONS:
     221              :         static constexpr std::string_view RoutineName("GetDesiccantDehumidifierInput: "); // include trailing blank space
     222              :         static constexpr std::string_view routineName = "GetDesiccantDehumidifierInput";
     223           21 :         static std::string const dehumidifierDesiccantNoFans("Dehumidifier:Desiccant:NoFans");
     224              : 
     225              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     226              :         int NumAlphas;                  // Number of Alphas for each GetObjectItem call
     227              :         int NumNumbers;                 // Number of Numbers for each GetObjectItem call
     228              :         int IOStatus;                   // Used in GetObjectItem
     229            7 :         bool ErrorsFound(false);        // Set to true if errors in input, fatal at end of routine
     230            7 :         bool ErrorsFound2(false);       // Set to true if errors in input, fatal at end of routine
     231            7 :         bool ErrorsFoundGeneric(false); // Set to true if errors in input, fatal at end of routine
     232              :         bool IsNotOK;                   // Flag to verify name
     233              :         bool OANodeError;               // Flag for check on outside air node
     234            7 :         std::string RegenCoilInlet;     // Desiccant system regeneration air heater inlet node
     235            7 :         std::string RegenCoilOutlet;    // Desiccant system regeneration air heater outlet node
     236              :         int DesuperHeaterIndex;         // Index of desuperheater heating coil
     237              :         int RegenCoilControlNodeNum;    // Control node number of regen heating coil
     238              :         Real64 CoilBypassedFlowFrac;    // Bypass air fraction for multimode DX coils
     239            7 :         Array1D_string Alphas;          // Alpha input items for object
     240            7 :         Array1D_string cAlphaFields;    // Alpha field names
     241            7 :         Array1D_string cNumericFields;  // Numeric field names
     242            7 :         Array1D<Real64> Numbers;        // Numeric input items for object
     243            7 :         Array1D_bool lAlphaBlanks;      // Logical array, alpha field input BLANK = .TRUE.
     244            7 :         Array1D_bool lNumericBlanks;    // Logical array, numeric field input BLANK = .TRUE.
     245              :         bool errFlag;                   // local error flag
     246            7 :         std::string RegenCoilType;      // Regen heating coil type
     247            7 :         std::string RegenCoilName;      // Regen heating coil name
     248              :         bool RegairHeatingCoilFlag;     // local error flag
     249              : 
     250            7 :         int TotalArgs = 0;
     251              : 
     252           14 :         state.dataDesiccantDehumidifiers->NumSolidDesicDehums =
     253            7 :             state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, dehumidifierDesiccantNoFans);
     254           14 :         state.dataDesiccantDehumidifiers->NumGenericDesicDehums =
     255            7 :             state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Dehumidifier:Desiccant:System");
     256           14 :         state.dataDesiccantDehumidifiers->NumDesicDehums =
     257            7 :             state.dataDesiccantDehumidifiers->NumSolidDesicDehums + state.dataDesiccantDehumidifiers->NumGenericDesicDehums;
     258              :         // allocate the data array
     259            7 :         state.dataDesiccantDehumidifiers->DesicDehum.allocate(state.dataDesiccantDehumidifiers->NumDesicDehums);
     260            7 :         state.dataDesiccantDehumidifiers->UniqueDesicDehumNames.reserve(state.dataDesiccantDehumidifiers->NumDesicDehums);
     261            7 :         state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier = false;
     262              : 
     263            7 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, dehumidifierDesiccantNoFans, TotalArgs, NumAlphas, NumNumbers);
     264            7 :         int MaxNums = NumNumbers;
     265            7 :         int MaxAlphas = NumAlphas;
     266            7 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Dehumidifier:Desiccant:System", TotalArgs, NumAlphas, NumNumbers);
     267            7 :         MaxNums = max(MaxNums, NumNumbers);
     268            7 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     269              : 
     270            7 :         Alphas.allocate(MaxAlphas);
     271            7 :         cAlphaFields.allocate(MaxAlphas);
     272            7 :         cNumericFields.allocate(MaxNums);
     273            7 :         Numbers.dimension(MaxNums, 0.0);
     274            7 :         lAlphaBlanks.dimension(MaxAlphas, true);
     275            7 :         lNumericBlanks.dimension(MaxNums, true);
     276              : 
     277              :         // loop over solid desiccant dehumidifiers and load the input data
     278            7 :         std::string CurrentModuleObject = dehumidifierDesiccantNoFans;
     279           12 :         for (int DesicDehumIndex = 1; DesicDehumIndex <= state.dataDesiccantDehumidifiers->NumSolidDesicDehums; ++DesicDehumIndex) {
     280            5 :             auto &desicDehum = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumIndex);
     281              : 
     282            5 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     283              :                                                                      CurrentModuleObject,
     284              :                                                                      DesicDehumIndex,
     285              :                                                                      Alphas,
     286              :                                                                      NumAlphas,
     287              :                                                                      Numbers,
     288              :                                                                      NumNumbers,
     289              :                                                                      IOStatus,
     290              :                                                                      lNumericBlanks,
     291              :                                                                      lAlphaBlanks,
     292              :                                                                      cAlphaFields,
     293              :                                                                      cNumericFields);
     294              : 
     295            5 :             ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
     296              : 
     297            5 :             GlobalNames::VerifyUniqueInterObjectName(
     298           10 :                 state, state.dataDesiccantDehumidifiers->UniqueDesicDehumNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
     299            5 :             desicDehum.Name = Alphas(1);
     300            5 :             desicDehum.DehumType = CurrentModuleObject;
     301            5 :             desicDehum.DehumTypeCode = DesicDehumType::Solid;
     302            5 :             desicDehum.Sched = Alphas(2);
     303              : 
     304            5 :             if (lAlphaBlanks(2)) {
     305            0 :                 desicDehum.availSched = Sched::GetScheduleAlwaysOn(state);
     306            5 :             } else if ((desicDehum.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
     307            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
     308            0 :                 ErrorsFound = true;
     309              :             }
     310              :             // For node connections, this object is both a parent and a non-parent, because the
     311              :             // Desiccant wheel is not called out as a separate component, its nodes must be connected
     312              :             // as ObjectIsNotParent.  But for the Regen fan, the nodes are connected as ObjectIsParent
     313            5 :             desicDehum.ProcAirInNode = NodeInputManager::GetOnlySingleNode(state,
     314            5 :                                                                            Alphas(3),
     315              :                                                                            ErrorsFound,
     316              :                                                                            DataLoopNode::ConnectionObjectType::DehumidifierDesiccantNoFans,
     317            5 :                                                                            Alphas(1),
     318              :                                                                            DataLoopNode::NodeFluidType::Air,
     319              :                                                                            DataLoopNode::ConnectionType::Inlet,
     320              :                                                                            NodeInputManager::CompFluidStream::Primary,
     321              :                                                                            DataLoopNode::ObjectIsNotParent);
     322              : 
     323            5 :             desicDehum.ProcAirOutNode = NodeInputManager::GetOnlySingleNode(state,
     324            5 :                                                                             Alphas(4),
     325              :                                                                             ErrorsFound,
     326              :                                                                             DataLoopNode::ConnectionObjectType::DehumidifierDesiccantNoFans,
     327            5 :                                                                             Alphas(1),
     328              :                                                                             DataLoopNode::NodeFluidType::Air,
     329              :                                                                             DataLoopNode::ConnectionType::Outlet,
     330              :                                                                             NodeInputManager::CompFluidStream::Primary,
     331              :                                                                             DataLoopNode::ObjectIsNotParent);
     332              : 
     333            5 :             desicDehum.RegenAirInNode = NodeInputManager::GetOnlySingleNode(state,
     334            5 :                                                                             Alphas(5),
     335              :                                                                             ErrorsFound,
     336              :                                                                             DataLoopNode::ConnectionObjectType::DehumidifierDesiccantNoFans,
     337            5 :                                                                             Alphas(1),
     338              :                                                                             DataLoopNode::NodeFluidType::Air,
     339              :                                                                             DataLoopNode::ConnectionType::Inlet,
     340              :                                                                             NodeInputManager::CompFluidStream::Secondary,
     341              :                                                                             DataLoopNode::ObjectIsNotParent);
     342              : 
     343            5 :             desicDehum.RegenFanInNode = NodeInputManager::GetOnlySingleNode(state,
     344            5 :                                                                             Alphas(6),
     345              :                                                                             ErrorsFound,
     346              :                                                                             DataLoopNode::ConnectionObjectType::DehumidifierDesiccantNoFans,
     347            5 :                                                                             Alphas(1),
     348              :                                                                             DataLoopNode::NodeFluidType::Air,
     349              :                                                                             DataLoopNode::ConnectionType::Internal,
     350              :                                                                             NodeInputManager::CompFluidStream::Secondary,
     351              :                                                                             DataLoopNode::ObjectIsParent);
     352              : 
     353            5 :             if (Util::SameString(Alphas(7), "LEAVING HUMRAT:BYPASS")) {
     354            0 :                 ShowWarningError(state, format("{}{} = {}", RoutineName, CurrentModuleObject, desicDehum.Name));
     355            0 :                 ShowContinueError(state, format("Obsolete {} = {}", cAlphaFields(7), Alphas(7)));
     356            0 :                 ShowContinueError(state, "setting to LeavingMaximumHumidityRatioSetpoint");
     357            0 :                 desicDehum.controlType = DesicDehumCtrlType::FixedHumratBypass;
     358              :             }
     359            5 :             if (Util::SameString(Alphas(7), "LeavingMaximumHumidityRatioSetpoint")) {
     360            3 :                 desicDehum.controlType = DesicDehumCtrlType::FixedHumratBypass;
     361              :             }
     362            5 :             if (Util::SameString(Alphas(7), "SystemNodeMaximumHumidityRatioSetpoint")) {
     363            2 :                 desicDehum.controlType = DesicDehumCtrlType::NodeHumratBypass;
     364              :             }
     365            5 :             if (desicDehum.controlType == DesicDehumCtrlType::Invalid) {
     366            0 :                 ShowWarningError(state, format("{}{} = {}", RoutineName, CurrentModuleObject, desicDehum.Name));
     367            0 :                 ShowContinueError(state, format("Invalid {} = {}", cAlphaFields(7), Alphas(7)));
     368            0 :                 ShowContinueError(state, "setting to LeavingMaximumHumidityRatioSetpoint");
     369            0 :                 desicDehum.controlType = DesicDehumCtrlType::FixedHumratBypass;
     370              :             }
     371            5 :             desicDehum.HumRatSet = Numbers(1);
     372            5 :             desicDehum.NomProcAirVolFlow = Numbers(2);
     373            5 :             desicDehum.NomProcAirVel = Numbers(3);
     374              : 
     375            5 :             desicDehum.RegenCoilType = Alphas(8);
     376            5 :             desicDehum.RegenCoilName = Alphas(9);
     377              : 
     378            5 :             desicDehum.regenFanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, Alphas(10)));
     379            5 :             assert(desicDehum.regenFanType != HVAC::FanType::Invalid);
     380              : 
     381            5 :             RegenCoilType = Alphas(8);
     382            5 :             RegenCoilName = Alphas(9);
     383              : 
     384           10 :             if (Util::SameString(desicDehum.RegenCoilType, "Coil:Heating:Electric") ||
     385           10 :                 Util::SameString(desicDehum.RegenCoilType, "Coil:Heating:Fuel")) {
     386            5 :                 if (Util::SameString(desicDehum.RegenCoilType, "Coil:Heating:Electric")) {
     387            0 :                     desicDehum.RegenCoilType_Num = HVAC::Coil_HeatingElectric;
     388              :                 }
     389            5 :                 if (Util::SameString(desicDehum.RegenCoilType, "Coil:Heating:Fuel")) {
     390            5 :                     desicDehum.RegenCoilType_Num = HVAC::Coil_HeatingGasOrOtherFuel;
     391              :                 }
     392            5 :                 ValidateComponent(state, desicDehum.RegenCoilType, desicDehum.RegenCoilName, ErrorsFound2, CurrentModuleObject + '=' + Alphas(1));
     393            5 :                 if (ErrorsFound2) {
     394            0 :                     ErrorsFound = true;
     395              :                 }
     396            5 :                 HeatingCoils::GetCoilIndex(state, desicDehum.RegenCoilName, desicDehum.RegenCoilIndex, ErrorsFound2);
     397            5 :                 if (ErrorsFound2) {
     398            0 :                     ErrorsFound = true;
     399              :                 }
     400              : 
     401            0 :             } else if (Util::SameString(desicDehum.RegenCoilType, "Coil:Heating:Water")) {
     402            0 :                 desicDehum.RegenCoilType_Num = HVAC::Coil_HeatingWater;
     403            0 :                 ValidateComponent(state, RegenCoilType, RegenCoilName, IsNotOK, CurrentModuleObject);
     404            0 :                 if (IsNotOK) {
     405            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
     406            0 :                     ErrorsFound = true;
     407              :                 } else { // mine data from heating coil object
     408            0 :                     errFlag = false;
     409            0 :                     desicDehum.RegenCoilIndex = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", RegenCoilName, errFlag);
     410            0 :                     if (desicDehum.RegenCoilIndex == 0) {
     411            0 :                         ShowSevereError(state, format("{}{} illegal {} = {}", RoutineName, CurrentModuleObject, cAlphaFields(9), RegenCoilName));
     412            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     413            0 :                         ErrorsFound = true;
     414              :                     }
     415              : 
     416              :                     // Get the Heating Coil Hot water Inlet or control Node number
     417            0 :                     errFlag = false;
     418            0 :                     desicDehum.CoilControlNode = WaterCoils::GetCoilWaterInletNode(state, "Coil:Heating:Water", RegenCoilName, errFlag);
     419            0 :                     if (errFlag) {
     420            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     421            0 :                         ErrorsFound = true;
     422              :                     }
     423              : 
     424              :                     // Get the Regeneration Heating Coil hot water max volume flow rate
     425            0 :                     errFlag = false;
     426            0 :                     desicDehum.MaxCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", RegenCoilName, errFlag);
     427            0 :                     if (errFlag) {
     428            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     429            0 :                         ErrorsFound = true;
     430              :                     }
     431              : 
     432              :                     // Get the Regeneration Heating Coil Inlet Node
     433            0 :                     errFlag = false;
     434            0 :                     int RegenCoilAirInletNode = WaterCoils::GetCoilInletNode(state, "Coil:Heating:Water", RegenCoilName, errFlag);
     435            0 :                     desicDehum.RegenCoilInletNode = RegenCoilAirInletNode;
     436            0 :                     if (errFlag) {
     437            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     438            0 :                         ErrorsFound = true;
     439              :                     }
     440              : 
     441              :                     // Get the Regeneration Heating Coil Outlet Node
     442            0 :                     errFlag = false;
     443            0 :                     int RegenCoilAirOutletNode = WaterCoils::GetCoilOutletNode(state, "Coil:Heating:Water", RegenCoilName, errFlag);
     444            0 :                     desicDehum.RegenCoilOutletNode = RegenCoilAirOutletNode;
     445            0 :                     if (errFlag) {
     446            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     447            0 :                         ErrorsFound = true;
     448              :                     }
     449              :                 }
     450            0 :             } else if (Util::SameString(desicDehum.RegenCoilType, "Coil:Heating:Steam")) {
     451            0 :                 desicDehum.RegenCoilType_Num = HVAC::Coil_HeatingSteam;
     452            0 :                 ValidateComponent(state, Alphas(8), RegenCoilName, IsNotOK, CurrentModuleObject);
     453            0 :                 if (IsNotOK) {
     454            0 :                     ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
     455            0 :                     ErrorsFound = true;
     456              :                 } else { // mine data from the regeneration heating coil object
     457              : 
     458            0 :                     errFlag = false;
     459            0 :                     desicDehum.RegenCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", RegenCoilName, errFlag);
     460            0 :                     if (desicDehum.RegenCoilIndex == 0) {
     461            0 :                         ShowSevereError(state, format("{}{} illegal {} = {}", RoutineName, CurrentModuleObject, cAlphaFields(9), RegenCoilName));
     462            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     463            0 :                         ErrorsFound = true;
     464              :                     }
     465              : 
     466              :                     // Get the regeneration Heating Coil steam inlet node number
     467            0 :                     errFlag = false;
     468            0 :                     desicDehum.CoilControlNode = SteamCoils::GetCoilSteamInletNode(state, "Coil:Heating:Steam", RegenCoilName, errFlag);
     469            0 :                     if (errFlag) {
     470            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     471            0 :                         ErrorsFound = true;
     472              :                     }
     473              : 
     474              :                     // Get the regeneration heating Coil steam max volume flow rate
     475            0 :                     desicDehum.MaxCoilFluidFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, desicDehum.RegenCoilIndex, errFlag);
     476            0 :                     if (desicDehum.MaxCoilFluidFlow > 0.0) {
     477            0 :                         Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, dehumidifierDesiccantNoFans);
     478            0 :                         desicDehum.MaxCoilFluidFlow *= SteamDensity;
     479              :                     }
     480              : 
     481              :                     // Get the regeneration heating Coil Inlet Node
     482            0 :                     errFlag = false;
     483            0 :                     int RegenCoilAirInletNode = SteamCoils::GetCoilAirInletNode(state, desicDehum.RegenCoilIndex, RegenCoilName, errFlag);
     484            0 :                     desicDehum.RegenCoilInletNode = RegenCoilAirInletNode;
     485            0 :                     if (errFlag) {
     486            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     487            0 :                         ErrorsFound = true;
     488              :                     }
     489              : 
     490              :                     // Get the regeneration heating Coil Outlet Node
     491            0 :                     errFlag = false;
     492            0 :                     int RegenCoilAirOutletNode = SteamCoils::GetCoilAirOutletNode(state, desicDehum.RegenCoilIndex, RegenCoilName, errFlag);
     493            0 :                     desicDehum.RegenCoilOutletNode = RegenCoilAirOutletNode;
     494            0 :                     if (errFlag) {
     495            0 :                         ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     496            0 :                         ErrorsFound = true;
     497              :                     }
     498              :                 }
     499              :             } else {
     500            0 :                 ShowSevereError(state, format("{}{} = {}", RoutineName, CurrentModuleObject, Alphas(1)));
     501            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(8), desicDehum.RegenCoilType));
     502            0 :                 ErrorsFound = true;
     503              :             }
     504              : 
     505            5 :             desicDehum.NomRotorPower = Numbers(4);
     506            5 :             desicDehum.RegenFanName = Alphas(11);
     507              : 
     508            5 :             BranchNodeConnections::TestCompSet(state, desicDehum.DehumType, desicDehum.Name, Alphas(3), Alphas(4), "Process Air Nodes");
     509              : 
     510              :             // Set up component set for regen coil
     511            5 :             BranchNodeConnections::SetUpCompSets(state, desicDehum.DehumType, desicDehum.Name, Alphas(8), Alphas(9), "UNDEFINED", "UNDEFINED");
     512              : 
     513              :             // Set up component set for regen fan
     514            5 :             BranchNodeConnections::SetUpCompSets(state, desicDehum.DehumType, desicDehum.Name, Alphas(10), Alphas(11), Alphas(6), "UNDEFINED");
     515              : 
     516            5 :             if ((!Util::SameString(Alphas(12), "Default")) && (Util::SameString(Alphas(12), "UserCurves"))) {
     517            0 :                 ShowWarningError(state, format("{}{}: Invalid{} = {}", RoutineName, CurrentModuleObject, cAlphaFields(12), Alphas(12)));
     518            0 :                 ShowContinueError(state, "resetting to Default");
     519            0 :                 desicDehum.PerformanceModel_Num = PerformanceModel::Default;
     520              :             }
     521              : 
     522            5 :             if (Util::SameString(Alphas(12), "UserCurves")) {
     523            0 :                 desicDehum.PerformanceModel_Num = PerformanceModel::UserCurves;
     524            0 :                 desicDehum.ProcDryBulbCurvefTW = Curve::GetCurveIndex(state, Alphas(13));
     525            0 :                 if (desicDehum.ProcDryBulbCurvefTW == 0) {
     526            0 :                     ShowSevereError(state, format("{}Curve object={} not found.", RoutineName, Alphas(13)));
     527            0 :                     ErrorsFound2 = true;
     528              :                 }
     529            0 :                 desicDehum.ProcDryBulbCurvefV = Curve::GetCurveIndex(state, Alphas(14));
     530            0 :                 if (desicDehum.ProcDryBulbCurvefV == 0) {
     531            0 :                     ShowSevereError(state, format("{}Curve object={} not found.", RoutineName, Alphas(14)));
     532            0 :                     ErrorsFound2 = true;
     533              :                 }
     534            0 :                 desicDehum.ProcHumRatCurvefTW = Curve::GetCurveIndex(state, Alphas(15));
     535            0 :                 if (desicDehum.ProcHumRatCurvefTW == 0) {
     536            0 :                     ShowSevereError(state, format("{}Curve object={} not found.", RoutineName, Alphas(15)));
     537            0 :                     ErrorsFound2 = true;
     538              :                 }
     539            0 :                 desicDehum.ProcHumRatCurvefV = Curve::GetCurveIndex(state, Alphas(16));
     540            0 :                 if (desicDehum.ProcHumRatCurvefV == 0) {
     541            0 :                     ShowSevereError(state, format("{}Curve object={} not found.", RoutineName, Alphas(16)));
     542            0 :                     ErrorsFound2 = true;
     543              :                 }
     544            0 :                 desicDehum.RegenEnergyCurvefTW = Curve::GetCurveIndex(state, Alphas(17));
     545            0 :                 if (desicDehum.RegenEnergyCurvefTW == 0) {
     546            0 :                     ShowSevereError(state, format("{}Curve object={} not found.", RoutineName, Alphas(17)));
     547            0 :                     ErrorsFound2 = true;
     548              :                 }
     549            0 :                 desicDehum.RegenEnergyCurvefV = Curve::GetCurveIndex(state, Alphas(18));
     550            0 :                 if (desicDehum.RegenEnergyCurvefV == 0) {
     551            0 :                     ShowSevereError(state, format("{}Curve object={} not found.", RoutineName, Alphas(18)));
     552            0 :                     ErrorsFound2 = true;
     553              :                 }
     554            0 :                 desicDehum.RegenVelCurvefTW = Curve::GetCurveIndex(state, Alphas(19));
     555            0 :                 if (desicDehum.RegenVelCurvefTW == 0) {
     556            0 :                     ShowSevereError(state, format("{}Curve object={} not found.", RoutineName, Alphas(19)));
     557            0 :                     ErrorsFound2 = true;
     558              :                 }
     559            0 :                 desicDehum.RegenVelCurvefV = Curve::GetCurveIndex(state, Alphas(20));
     560            0 :                 if (desicDehum.RegenVelCurvefV == 0) {
     561            0 :                     ShowSevereError(state, format("{}Curve object={} not found.", RoutineName, Alphas(20)));
     562            0 :                     ErrorsFound2 = true;
     563              :                 }
     564            0 :                 if (ErrorsFound2) {
     565            0 :                     ShowSevereError(state, format("{}{} = {}", RoutineName, CurrentModuleObject, Alphas(1)));
     566            0 :                     ShowContinueError(state, "Errors found in getting performance curves.");
     567            0 :                     ErrorsFound = true;
     568              :                 }
     569            0 :                 desicDehum.NomRegenTemp = Numbers(5);
     570              : 
     571              :                 // Validate regen fan type, for user defined curves, can be constant or variable volume
     572            0 :                 if (desicDehum.regenFanType == HVAC::FanType::Constant || desicDehum.regenFanType == HVAC::FanType::VAV ||
     573            0 :                     desicDehum.regenFanType == HVAC::FanType::SystemModel) {
     574            0 :                     ValidateComponent(state,
     575            0 :                                       HVAC::fanTypeNamesUC[(int)desicDehum.regenFanType],
     576            0 :                                       desicDehum.RegenFanName,
     577              :                                       ErrorsFound2,
     578            0 :                                       CurrentModuleObject + " = " + Alphas(1));
     579            0 :                     if (ErrorsFound2) {
     580            0 :                         ErrorsFound = true;
     581              :                     }
     582              :                 } else {
     583            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
     584            0 :                     ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(10), Alphas(10)));
     585            0 :                     ErrorsFound = true;
     586              :                 }
     587              :             } else {
     588              :                 // If DEFAULT performance model, set operating limits curves.  Unit is off outside this range
     589            5 :                 desicDehum.PerformanceModel_Num = PerformanceModel::Default;
     590              :                 // this is wrong to initialize all dehumidifiers, it should be just this specific dehumidifier
     591              :                 // this was likely tested with only 1 desiccant dehumidifier so this was never discovered
     592              :                 // or maybe if there were more than 1 these data would not be used when Alphas(12) == "UserCurves" ???
     593           10 :                 for (auto &e : state.dataDesiccantDehumidifiers->DesicDehum) {
     594            5 :                     e.MinProcAirInTemp = 1.67;       //  35 F
     595            5 :                     e.MaxProcAirInTemp = 48.89;      // 120 F
     596            5 :                     e.MinProcAirInHumRat = 0.002857; //  20 gr/lb
     597            5 :                     e.MaxProcAirInHumRat = 0.02857;  // 200 gr/lb
     598              :                 }
     599              :                 //  If DEFAULT performance model, warn if curve names and nominal regen temp have values
     600           10 :                 if ((!lAlphaBlanks(13)) || (!lAlphaBlanks(14)) || (!lAlphaBlanks(15)) || (!lAlphaBlanks(16)) || (!lAlphaBlanks(17)) ||
     601           10 :                     (!lAlphaBlanks(18)) || (!lAlphaBlanks(19)) || (!lAlphaBlanks(20))) {
     602            0 :                     ShowWarningError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
     603            0 :                     ShowContinueError(state, "DEFAULT performance selected, curve names and nominal regen temp will be ignored.");
     604              :                 }
     605            5 :                 if (desicDehum.NomProcAirVel > 4.064) {
     606            0 :                     ShowWarningError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
     607            0 :                     ShowContinueError(state, format("{} > 4.064 m/s.; Value in input={:.3R}", cNumericFields(3), desicDehum.NomProcAirVel));
     608            0 :                     ShowContinueError(state, "DEFAULT performance curves not valid outside 2.032 to 4.064 m/s (400 to 800 fpm).");
     609              :                 }
     610            5 :                 if (desicDehum.NomProcAirVel < 2.032) {
     611            0 :                     ShowWarningError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
     612            0 :                     ShowContinueError(state, format("{} < 2.032 m/s.; Value in input={:.3R}", cNumericFields(3), desicDehum.NomProcAirVel));
     613            0 :                     ShowContinueError(state, "DEFAULT performance curves not valid outside 2.032 to 4.064 m/s (400 to 800 fpm).");
     614              :                 }
     615              :                 // Validate regen fan type, for default curves, can only variable volume
     616            5 :                 if (desicDehum.regenFanType == HVAC::FanType::VAV || desicDehum.regenFanType == HVAC::FanType::SystemModel) {
     617           10 :                     ValidateComponent(state,
     618            5 :                                       HVAC::fanTypeNamesUC[(int)desicDehum.regenFanType],
     619            5 :                                       desicDehum.RegenFanName,
     620              :                                       ErrorsFound2,
     621           10 :                                       CurrentModuleObject + " = " + Alphas(1));
     622            5 :                     if (ErrorsFound2) {
     623            0 :                         ErrorsFound = true;
     624              :                     }
     625              :                 } else {
     626            0 :                     ShowSevereError(state, format("{} = {}", CurrentModuleObject, Alphas(1)));
     627            0 :                     ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(10), Alphas(10)));
     628            0 :                     ShowContinueError(state, "For DEFAULT performance model, the regen fan type must be Fan:VariableVolume");
     629            0 :                     ErrorsFound = true;
     630              :                 }
     631              :             }
     632              :             // process regen fan
     633            5 :             ErrorsFound2 = false;
     634              : 
     635            5 :             desicDehum.RegenFanIndex = Fans::GetFanIndex(state, desicDehum.RegenFanName);
     636            5 :             if (desicDehum.RegenFanIndex == 0) {
     637            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(11), desicDehum.RegenFanName);
     638            0 :                 ErrorsFoundGeneric = true;
     639              :             } else {
     640            5 :                 auto *fan = state.dataFans->fans(desicDehum.RegenFanIndex);
     641            5 :                 assert(desicDehum.regenFanType == fan->type);
     642            5 :                 desicDehum.RegenFanInNode = fan->inletNodeNum;
     643            5 :                 desicDehum.RegenFanOutNode = fan->outletNodeNum;
     644              :             }
     645              :         }
     646              : 
     647           11 :         for (int DesicDehumIndex = 1; DesicDehumIndex <= state.dataDesiccantDehumidifiers->NumGenericDesicDehums; ++DesicDehumIndex) {
     648              : 
     649            4 :             CurrentModuleObject = "Dehumidifier:Desiccant:System";
     650              : 
     651            4 :             int DesicDehumNum = DesicDehumIndex + state.dataDesiccantDehumidifiers->NumSolidDesicDehums;
     652            4 :             auto &desicDehum = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum);
     653              : 
     654            4 :             desicDehum.DehumType = CurrentModuleObject;
     655            4 :             desicDehum.DehumTypeCode = DesicDehumType::Generic;
     656            4 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     657              :                                                                      desicDehum.DehumType,
     658              :                                                                      DesicDehumIndex,
     659              :                                                                      Alphas,
     660              :                                                                      NumAlphas,
     661              :                                                                      Numbers,
     662              :                                                                      NumNumbers,
     663              :                                                                      IOStatus,
     664              :                                                                      lNumericBlanks,
     665              :                                                                      lAlphaBlanks,
     666              :                                                                      cAlphaFields,
     667              :                                                                      cNumericFields);
     668              : 
     669            4 :             ErrorObjectHeader eoh{routineName, desicDehum.DehumType, Alphas(1)};
     670              : 
     671            4 :             GlobalNames::VerifyUniqueInterObjectName(
     672            8 :                 state, state.dataDesiccantDehumidifiers->UniqueDesicDehumNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFoundGeneric);
     673            4 :             desicDehum.Name = Alphas(1);
     674              : 
     675            4 :             ErrorsFound2 = false;
     676            4 :             ValidateComponent(state, desicDehum.DehumType, desicDehum.Name, ErrorsFound2, desicDehum.DehumType + " = \"" + desicDehum.Name + "\"");
     677            4 :             if (ErrorsFound2) {
     678            0 :                 ShowSevereError(state, format("{} \"{}\" is not unique", desicDehum.DehumType, desicDehum.Name));
     679            0 :                 ErrorsFoundGeneric = true;
     680              :             }
     681              : 
     682            4 :             desicDehum.Sched = Alphas(2);
     683            4 :             if (lAlphaBlanks(2)) {
     684            0 :                 desicDehum.availSched = Sched::GetScheduleAlwaysOn(state);
     685            4 :             } else if ((desicDehum.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
     686            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
     687            0 :                 ErrorsFound = true;
     688              :             }
     689              : 
     690            4 :             desicDehum.HXType = Alphas(3);
     691            4 :             desicDehum.HXName = Alphas(4);
     692              : 
     693            4 :             if (!Util::SameString(desicDehum.HXType, "HeatExchanger:Desiccant:BalancedFlow")) {
     694            0 :                 ShowWarningError(state, format("{} = \"{}\"", desicDehum.DehumType, desicDehum.Name));
     695            0 :                 ShowContinueError(state, format("Invalid {} = {}", cAlphaFields(3), desicDehum.HXType));
     696            0 :                 ErrorsFoundGeneric = true;
     697              :             } else {
     698            4 :                 desicDehum.HXTypeNum = BalancedHX;
     699              :             }
     700              : 
     701            4 :             ErrorsFound2 = false;
     702            4 :             ValidateComponent(state, desicDehum.HXType, desicDehum.HXName, ErrorsFound2, desicDehum.DehumType + " = \"" + desicDehum.Name + "\"");
     703            4 :             if (ErrorsFound2) {
     704            0 :                 ErrorsFoundGeneric = true;
     705              :             }
     706              : 
     707            4 :             ErrorsFound2 = false;
     708            4 :             desicDehum.HXProcInNode = HeatRecovery::GetSecondaryInletNode(state, desicDehum.HXName, ErrorsFound2);
     709            4 :             if (ErrorsFound2) {
     710            0 :                 ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.Name));
     711            0 :                 ErrorsFoundGeneric = true;
     712              :             }
     713              : 
     714            4 :             std::string ProcAirInlet = state.dataLoopNodes->NodeID(desicDehum.HXProcInNode);
     715              : 
     716            4 :             desicDehum.ProcAirInNode = NodeInputManager::GetOnlySingleNode(state,
     717              :                                                                            ProcAirInlet,
     718              :                                                                            ErrorsFound,
     719              :                                                                            DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
     720            4 :                                                                            desicDehum.Name,
     721              :                                                                            DataLoopNode::NodeFluidType::Air,
     722              :                                                                            DataLoopNode::ConnectionType::Inlet,
     723              :                                                                            NodeInputManager::CompFluidStream::Primary,
     724              :                                                                            DataLoopNode::ObjectIsParent);
     725              : 
     726            4 :             ErrorsFound2 = false;
     727            4 :             desicDehum.HXProcOutNode = HeatRecovery::GetSecondaryOutletNode(state, desicDehum.HXName, ErrorsFound2);
     728            4 :             if (ErrorsFound2) {
     729            0 :                 ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.Name));
     730            0 :                 ErrorsFoundGeneric = true;
     731              :             }
     732              : 
     733            4 :             std::string ProcAirOutlet = state.dataLoopNodes->NodeID(desicDehum.HXProcOutNode);
     734              : 
     735            8 :             desicDehum.ProcAirOutNode = NodeInputManager::GetOnlySingleNode(state,
     736              :                                                                             ProcAirOutlet,
     737              :                                                                             ErrorsFound,
     738              :                                                                             DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
     739            4 :                                                                             desicDehum.Name,
     740              :                                                                             DataLoopNode::NodeFluidType::Air,
     741              :                                                                             DataLoopNode::ConnectionType::Outlet,
     742              :                                                                             NodeInputManager::CompFluidStream::Primary,
     743              :                                                                             DataLoopNode::ObjectIsParent);
     744              : 
     745            4 :             BranchNodeConnections::TestCompSet(state, desicDehum.DehumType, desicDehum.Name, ProcAirInlet, ProcAirOutlet, "Process Air Nodes");
     746              : 
     747            4 :             ErrorsFound2 = false;
     748            4 :             desicDehum.HXRegenInNode = HeatRecovery::GetSupplyInletNode(state, desicDehum.HXName, ErrorsFound2);
     749            4 :             if (ErrorsFound2) {
     750            0 :                 ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.Name));
     751            0 :                 ErrorsFoundGeneric = true;
     752              :             }
     753              : 
     754            4 :             ErrorsFound2 = false;
     755            4 :             desicDehum.HXRegenOutNode = HeatRecovery::GetSupplyOutletNode(state, desicDehum.HXName, ErrorsFound2);
     756            4 :             if (ErrorsFound2) {
     757            0 :                 ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.Name));
     758            0 :                 ErrorsFoundGeneric = true;
     759              :             }
     760              : 
     761            4 :             desicDehum.ControlNodeNum = NodeInputManager::GetOnlySingleNode(state,
     762            4 :                                                                             Alphas(5),
     763              :                                                                             ErrorsFound,
     764              :                                                                             DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
     765            4 :                                                                             desicDehum.Name,
     766              :                                                                             DataLoopNode::NodeFluidType::Air,
     767              :                                                                             DataLoopNode::ConnectionType::Sensor,
     768              :                                                                             NodeInputManager::CompFluidStream::Primary,
     769              :                                                                             DataLoopNode::ObjectIsNotParent);
     770              : 
     771            4 :             if (desicDehum.ControlNodeNum == 0) {
     772            0 :                 ShowSevereError(state, format("{} = \"{}\"", desicDehum.DehumType, desicDehum.Name));
     773            0 :                 ShowContinueError(state, format("{} must be specified.", cAlphaFields(5)));
     774            0 :                 ErrorsFoundGeneric = true;
     775              :             }
     776              : 
     777            4 :             desicDehum.regenFanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, Alphas(6)));
     778            4 :             assert(desicDehum.regenFanType != HVAC::FanType::Invalid);
     779              : 
     780            4 :             desicDehum.RegenFanName = Alphas(7);
     781              : 
     782            4 :             if (desicDehum.regenFanType == HVAC::FanType::OnOff || desicDehum.regenFanType == HVAC::FanType::Constant ||
     783            2 :                 desicDehum.regenFanType == HVAC::FanType::SystemModel) {
     784            4 :                 ErrorsFound2 = false;
     785            8 :                 ValidateComponent(state,
     786            4 :                                   HVAC::fanTypeNamesUC[(int)desicDehum.regenFanType],
     787            4 :                                   desicDehum.RegenFanName,
     788              :                                   ErrorsFound2,
     789            8 :                                   desicDehum.DehumType + " \"" + desicDehum.Name + "\"");
     790            4 :                 if (ErrorsFound2) {
     791            0 :                     ErrorsFoundGeneric = true;
     792              :                 }
     793              :             } else {
     794            0 :                 ShowSevereError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
     795            0 :                 ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(6), HVAC::fanTypeNamesUC[(int)desicDehum.regenFanType]));
     796            0 :                 ErrorsFoundGeneric = true;
     797              :             }
     798              : 
     799            4 :             desicDehum.regenFanPlace = static_cast<HVAC::FanPlace>(getEnumValue(HVAC::fanPlaceNamesUC, Alphas(8)));
     800            4 :             if (desicDehum.regenFanPlace == HVAC::FanPlace::Invalid) {
     801            0 :                 ShowWarningInvalidKey(state, eoh, cAlphaFields(8), Alphas(8), "DrawThrough");
     802            0 :                 desicDehum.regenFanPlace = HVAC::FanPlace::DrawThru;
     803              :             }
     804              : 
     805            4 :             ErrorsFound2 = false;
     806            4 :             desicDehum.RegenFanIndex = Fans::GetFanIndex(state, desicDehum.RegenFanName);
     807            4 :             if (desicDehum.RegenFanIndex == 0) {
     808            0 :                 ShowSevereItemNotFound(state, eoh, cAlphaFields(7), desicDehum.RegenFanName);
     809            0 :                 ErrorsFoundGeneric = true;
     810              :             } else {
     811            4 :                 auto *fan = state.dataFans->fans(desicDehum.RegenFanIndex);
     812            4 :                 assert(desicDehum.regenFanType == fan->type);
     813            4 :                 desicDehum.RegenFanInNode = fan->inletNodeNum;
     814            4 :                 desicDehum.RegenFanOutNode = fan->outletNodeNum;
     815              :             }
     816              : 
     817            4 :             desicDehum.RegenCoilType = Alphas(9);
     818            4 :             desicDehum.RegenCoilName = Alphas(10);
     819            4 :             RegenCoilType = Alphas(9);
     820            4 :             RegenCoilName = Alphas(10);
     821            4 :             desicDehum.RegenSetPointTemp = Numbers(1);
     822              : 
     823            4 :             if (!lAlphaBlanks(10)) {
     824            8 :                 if (Util::SameString(desicDehum.RegenCoilType, "Coil:Heating:Electric") ||
     825            8 :                     Util::SameString(desicDehum.RegenCoilType, "Coil:Heating:Fuel")) {
     826            4 :                     if (Util::SameString(desicDehum.RegenCoilType, "Coil:Heating:Electric")) {
     827            0 :                         desicDehum.RegenCoilType_Num = HVAC::Coil_HeatingElectric;
     828              :                     }
     829            4 :                     if (Util::SameString(desicDehum.RegenCoilType, "Coil:Heating:Fuel")) {
     830            4 :                         desicDehum.RegenCoilType_Num = HVAC::Coil_HeatingGasOrOtherFuel;
     831              :                     }
     832            4 :                     ErrorsFound2 = false;
     833            4 :                     ValidateComponent(state, RegenCoilType, RegenCoilName, ErrorsFound2, desicDehum.DehumType + " \"" + desicDehum.Name + "\"");
     834            4 :                     if (ErrorsFound2) {
     835            0 :                         ErrorsFoundGeneric = true;
     836              :                     }
     837              : 
     838            4 :                     if (desicDehum.RegenSetPointTemp <= 0.0) {
     839            0 :                         ShowSevereError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
     840            0 :                         ShowContinueError(state, format("{} must be greater than 0.", cNumericFields(1)));
     841            0 :                         ErrorsFoundGeneric = true;
     842              :                     }
     843              : 
     844            4 :                     ErrorsFound2 = false;
     845            4 :                     desicDehum.RegenCoilInletNode = HeatingCoils::GetCoilInletNode(state, RegenCoilType, RegenCoilName, ErrorsFound2);
     846            4 :                     if (ErrorsFound2) {
     847            0 :                         ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.Name));
     848            0 :                         ErrorsFoundGeneric = true;
     849              :                     }
     850              : 
     851            4 :                     ErrorsFound2 = false;
     852            4 :                     desicDehum.RegenCoilOutletNode = HeatingCoils::GetCoilOutletNode(state, RegenCoilType, RegenCoilName, ErrorsFound2);
     853            4 :                     if (ErrorsFound2) {
     854            0 :                         ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.Name));
     855            0 :                         ErrorsFoundGeneric = true;
     856              :                     }
     857              : 
     858            4 :                     ErrorsFound2 = false;
     859            4 :                     HeatingCoils::GetCoilIndex(state, RegenCoilName, desicDehum.RegenCoilIndex, ErrorsFound2);
     860            4 :                     if (ErrorsFound2) {
     861            0 :                         ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.Name));
     862            0 :                         ErrorsFoundGeneric = true;
     863              :                     }
     864              : 
     865            4 :                     ErrorsFound2 = false;
     866            4 :                     RegenCoilControlNodeNum = HeatingCoils::GetCoilControlNodeNum(state, RegenCoilType, RegenCoilName, ErrorsFound2);
     867            4 :                     if (ErrorsFound2) {
     868            0 :                         ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.Name));
     869            0 :                         ErrorsFoundGeneric = true;
     870              :                     }
     871              : 
     872            4 :                     if (RegenCoilControlNodeNum > 0) {
     873            0 :                         ShowSevereError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
     874            0 :                         ShowContinueError(state,
     875            0 :                                           format("{} is specified as {:.3R} C in this object.", cNumericFields(1), desicDehum.RegenSetPointTemp));
     876            0 :                         ShowContinueError(state, " Do not specify a coil temperature setpoint node name in the regeneration air heater object.");
     877            0 :                         ShowContinueError(state, format("...{} = {}", cAlphaFields(9), desicDehum.RegenCoilType));
     878            0 :                         ShowContinueError(state, format("...{} = {}", cAlphaFields(10), desicDehum.RegenCoilName));
     879            0 :                         ShowContinueError(
     880            0 :                             state, format("...heating coil temperature setpoint node = {}", state.dataLoopNodes->NodeID(RegenCoilControlNodeNum)));
     881            0 :                         ShowContinueError(state, "...leave the heating coil temperature setpoint node name blank in the regen heater object.");
     882            0 :                         ErrorsFoundGeneric = true;
     883              :                     }
     884              : 
     885            4 :                     RegairHeatingCoilFlag = true;
     886            4 :                     HeatingCoils::SetHeatingCoilData(state, desicDehum.RegenCoilIndex, ErrorsFound2, RegairHeatingCoilFlag, DesicDehumNum);
     887            4 :                     if (ErrorsFound2) {
     888            0 :                         ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.Name));
     889            0 :                         ErrorsFoundGeneric = true;
     890              :                     }
     891              : 
     892            0 :                 } else if (Util::SameString(desicDehum.RegenCoilType, "Coil:Heating:Water")) {
     893            0 :                     desicDehum.RegenCoilType_Num = HVAC::Coil_HeatingWater;
     894            0 :                     ValidateComponent(state, RegenCoilType, RegenCoilName, IsNotOK, CurrentModuleObject);
     895            0 :                     if (IsNotOK) {
     896            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
     897            0 :                         ErrorsFound = true;
     898              :                     } else { // mine data from heating coil object
     899            0 :                         errFlag = false;
     900            0 :                         desicDehum.RegenCoilIndex = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", RegenCoilName, errFlag);
     901            0 :                         if (desicDehum.RegenCoilIndex == 0) {
     902            0 :                             ShowSevereError(state, format("{} illegal {} = {}", CurrentModuleObject, cAlphaFields(9), RegenCoilName));
     903            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     904            0 :                             ErrorsFound = true;
     905              :                         }
     906              : 
     907            0 :                         if (desicDehum.RegenSetPointTemp <= 0.0) {
     908            0 :                             ShowSevereError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
     909            0 :                             ShowContinueError(state, format("{} must be greater than 0.", cNumericFields(1)));
     910            0 :                             ErrorsFoundGeneric = true;
     911              :                         }
     912              : 
     913              :                         // Get the Heating Coil Hot water Inlet or control Node number
     914            0 :                         errFlag = false;
     915            0 :                         desicDehum.CoilControlNode = WaterCoils::GetCoilWaterInletNode(state, "Coil:Heating:Water", RegenCoilName, errFlag);
     916            0 :                         if (errFlag) {
     917            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     918            0 :                             ErrorsFound = true;
     919              :                         }
     920              : 
     921              :                         // Get the Regeneration Heating Coil hot water max volume flow rate
     922            0 :                         errFlag = false;
     923            0 :                         desicDehum.MaxCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", RegenCoilName, errFlag);
     924            0 :                         if (errFlag) {
     925            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     926            0 :                             ErrorsFound = true;
     927              :                         }
     928              : 
     929              :                         // Get the Regeneration Heating Coil Inlet Node
     930            0 :                         errFlag = false;
     931            0 :                         int RegenCoilAirInletNode = WaterCoils::GetCoilInletNode(state, "Coil:Heating:Water", RegenCoilName, errFlag);
     932            0 :                         desicDehum.RegenCoilInletNode = RegenCoilAirInletNode;
     933            0 :                         if (errFlag) {
     934            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     935            0 :                             ErrorsFound = true;
     936              :                         }
     937              : 
     938              :                         // Get the Regeneration Heating Coil Outlet Node
     939            0 :                         errFlag = false;
     940            0 :                         int RegenCoilAirOutletNode = WaterCoils::GetCoilOutletNode(state, "Coil:Heating:Water", RegenCoilName, errFlag);
     941            0 :                         desicDehum.RegenCoilOutletNode = RegenCoilAirOutletNode;
     942            0 :                         if (errFlag) {
     943            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     944            0 :                             ErrorsFound = true;
     945              :                         }
     946              : 
     947            0 :                         RegairHeatingCoilFlag = true;
     948            0 :                         WaterCoils::SetWaterCoilData(state, desicDehum.RegenCoilIndex, ErrorsFound2, RegairHeatingCoilFlag, DesicDehumNum);
     949            0 :                         if (ErrorsFound2) {
     950            0 :                             ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.Name));
     951            0 :                             ErrorsFoundGeneric = true;
     952              :                         }
     953              :                     }
     954            0 :                 } else if (Util::SameString(desicDehum.RegenCoilType, "Coil:Heating:Steam")) {
     955            0 :                     desicDehum.RegenCoilType_Num = HVAC::Coil_HeatingSteam;
     956            0 :                     ValidateComponent(state, RegenCoilType, RegenCoilName, IsNotOK, CurrentModuleObject);
     957            0 :                     if (IsNotOK) {
     958            0 :                         ShowContinueError(state, format("...occurs in {} = {}", CurrentModuleObject, Alphas(1)));
     959            0 :                         ErrorsFound = true;
     960              :                     } else { // mine data from the regeneration heating coil object
     961            0 :                         if (desicDehum.RegenSetPointTemp <= 0.0) {
     962            0 :                             ShowSevereError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
     963            0 :                             ShowContinueError(state, format("{} must be greater than 0.", cNumericFields(1)));
     964            0 :                             ErrorsFoundGeneric = true;
     965              :                         }
     966              : 
     967            0 :                         errFlag = false;
     968            0 :                         desicDehum.RegenCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", RegenCoilName, errFlag);
     969            0 :                         if (desicDehum.RegenCoilIndex == 0) {
     970            0 :                             ShowSevereError(state, format("{} illegal {} = {}", CurrentModuleObject, cAlphaFields(9), RegenCoilName));
     971            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     972            0 :                             ErrorsFound = true;
     973              :                         }
     974              : 
     975              :                         // Get the regeneration Heating Coil steam inlet node number
     976            0 :                         errFlag = false;
     977            0 :                         desicDehum.CoilControlNode = SteamCoils::GetCoilSteamInletNode(state, "Coil:Heating:Steam", RegenCoilName, errFlag);
     978            0 :                         if (errFlag) {
     979            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     980            0 :                             ErrorsFound = true;
     981              :                         }
     982              : 
     983              :                         // Get the regeneration heating Coil steam max volume flow rate
     984            0 :                         desicDehum.MaxCoilFluidFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, desicDehum.RegenCoilIndex, errFlag);
     985            0 :                         if (desicDehum.MaxCoilFluidFlow > 0.0) {
     986            0 :                             Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, dehumidifierDesiccantNoFans);
     987            0 :                             desicDehum.MaxCoilFluidFlow *= SteamDensity;
     988              :                         }
     989              : 
     990              :                         // Get the regeneration heating Coil Inlet Node
     991            0 :                         errFlag = false;
     992            0 :                         int RegenCoilAirInletNode = SteamCoils::GetCoilAirInletNode(state, desicDehum.RegenCoilIndex, RegenCoilName, errFlag);
     993            0 :                         desicDehum.RegenCoilInletNode = RegenCoilAirInletNode;
     994            0 :                         if (errFlag) {
     995            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
     996            0 :                             ErrorsFound = true;
     997              :                         }
     998              : 
     999              :                         // Get the regeneration heating Coil Outlet Node
    1000            0 :                         errFlag = false;
    1001            0 :                         int RegenCoilAirOutletNode = SteamCoils::GetCoilAirOutletNode(state, desicDehum.RegenCoilIndex, RegenCoilName, errFlag);
    1002            0 :                         desicDehum.RegenCoilOutletNode = RegenCoilAirOutletNode;
    1003            0 :                         if (errFlag) {
    1004            0 :                             ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, desicDehum.Name));
    1005            0 :                             ErrorsFound = true;
    1006              :                         }
    1007              :                     }
    1008              : 
    1009            0 :                     ErrorsFound2 = false;
    1010            0 :                     RegenCoilControlNodeNum = SteamCoils::GetSteamCoilControlNodeNum(state, RegenCoilType, RegenCoilName, ErrorsFound2);
    1011              : 
    1012            0 :                     if (ErrorsFound2) {
    1013            0 :                         ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1014            0 :                         ErrorsFoundGeneric = true;
    1015              :                     }
    1016              : 
    1017            0 :                     if (RegenCoilControlNodeNum > 0) {
    1018            0 :                         ShowSevereError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1019            0 :                         ShowContinueError(state,
    1020            0 :                                           format("{} is specified as {:.3R} C in this object.", cNumericFields(1), desicDehum.RegenSetPointTemp));
    1021            0 :                         ShowContinueError(state, " Do not specify a coil temperature setpoint node name in the regeneration air heater object.");
    1022            0 :                         ShowContinueError(state, format("...{} = {}", cAlphaFields(9), desicDehum.RegenCoilType));
    1023            0 :                         ShowContinueError(state, format("...{} = {}", cAlphaFields(10), desicDehum.RegenCoilName));
    1024            0 :                         ShowContinueError(
    1025            0 :                             state, format("...heating coil temperature setpoint node = {}", state.dataLoopNodes->NodeID(RegenCoilControlNodeNum)));
    1026            0 :                         ShowContinueError(state, "...leave the heating coil temperature setpoint node name blank in the regen heater object.");
    1027            0 :                         ErrorsFoundGeneric = true;
    1028              :                     }
    1029              : 
    1030            0 :                     RegairHeatingCoilFlag = true;
    1031            0 :                     SteamCoils::SetSteamCoilData(state, desicDehum.RegenCoilIndex, ErrorsFound2, RegairHeatingCoilFlag, DesicDehumNum);
    1032            0 :                     if (ErrorsFound2) {
    1033            0 :                         ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1034            0 :                         ErrorsFoundGeneric = true;
    1035              :                     }
    1036              : 
    1037              :                 } else {
    1038            0 :                     ShowSevereError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1039            0 :                     ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(9), desicDehum.RegenCoilType));
    1040            0 :                     ErrorsFoundGeneric = true;
    1041              :                 }
    1042              :             }
    1043              : 
    1044            4 :             std::string RegenAirInlet = state.dataLoopNodes->NodeID(desicDehum.HXRegenInNode);
    1045              : 
    1046            4 :             std::string RegenAirOutlet = state.dataLoopNodes->NodeID(desicDehum.HXRegenOutNode);
    1047              : 
    1048            4 :             std::string RegenFanInlet = state.dataLoopNodes->NodeID(desicDehum.RegenFanInNode);
    1049              : 
    1050            4 :             std::string RegenFanOutlet = state.dataLoopNodes->NodeID(desicDehum.RegenFanOutNode);
    1051              : 
    1052            4 :             if (!lAlphaBlanks(10)) {
    1053            4 :                 RegenCoilInlet = state.dataLoopNodes->NodeID(desicDehum.RegenCoilInletNode);
    1054              : 
    1055            4 :                 RegenCoilOutlet = state.dataLoopNodes->NodeID(desicDehum.RegenCoilOutletNode);
    1056              :             }
    1057              : 
    1058            4 :             BranchNodeConnections::SetUpCompSets(
    1059              :                 state, desicDehum.DehumType, desicDehum.Name, desicDehum.HXType, desicDehum.HXName, ProcAirInlet, ProcAirOutlet);
    1060              : 
    1061            8 :             BranchNodeConnections::SetUpCompSets(state,
    1062              :                                                  desicDehum.DehumType,
    1063              :                                                  desicDehum.Name,
    1064            4 :                                                  HVAC::fanTypeNamesUC[(int)desicDehum.regenFanType],
    1065              :                                                  desicDehum.RegenFanName,
    1066              :                                                  RegenFanInlet,
    1067              :                                                  RegenFanOutlet);
    1068              : 
    1069            4 :             if (!lAlphaBlanks(10)) {
    1070            4 :                 BranchNodeConnections::SetUpCompSets(state,
    1071              :                                                      desicDehum.DehumType,
    1072              :                                                      desicDehum.Name,
    1073              :                                                      desicDehum.RegenCoilType,
    1074              :                                                      desicDehum.RegenCoilName,
    1075              :                                                      RegenCoilInlet,
    1076              :                                                      RegenCoilOutlet);
    1077              :             }
    1078              : 
    1079            4 :             if (desicDehum.regenFanPlace == HVAC::FanPlace::BlowThru) {
    1080            0 :                 desicDehum.RegenAirInNode = NodeInputManager::GetOnlySingleNode(state,
    1081              :                                                                                 RegenFanInlet,
    1082              :                                                                                 ErrorsFound,
    1083              :                                                                                 DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
    1084            0 :                                                                                 desicDehum.Name,
    1085              :                                                                                 DataLoopNode::NodeFluidType::Air,
    1086              :                                                                                 DataLoopNode::ConnectionType::Inlet,
    1087              :                                                                                 NodeInputManager::CompFluidStream::Primary,
    1088              :                                                                                 DataLoopNode::ObjectIsParent);
    1089            0 :                 desicDehum.RegenAirOutNode = NodeInputManager::GetOnlySingleNode(state,
    1090              :                                                                                  RegenAirOutlet,
    1091              :                                                                                  ErrorsFound,
    1092              :                                                                                  DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
    1093            0 :                                                                                  desicDehum.Name,
    1094              :                                                                                  DataLoopNode::NodeFluidType::Air,
    1095              :                                                                                  DataLoopNode::ConnectionType::Outlet,
    1096              :                                                                                  NodeInputManager::CompFluidStream::Primary,
    1097              :                                                                                  DataLoopNode::ObjectIsParent);
    1098            0 :                 if (!lAlphaBlanks(10)) {
    1099            0 :                     if (desicDehum.RegenFanOutNode != desicDehum.RegenCoilInletNode) {
    1100            0 :                         ShowSevereError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1101            0 :                         ShowContinueError(state,
    1102              :                                           "Regen fan outlet node name and regen heater inlet node name do not match for fan placement: Blow Through");
    1103            0 :                         ShowContinueError(state, format("...Regen fan outlet node   = {}", state.dataLoopNodes->NodeID(desicDehum.RegenFanOutNode)));
    1104            0 :                         ShowContinueError(state,
    1105            0 :                                           format("...Regen heater inlet node = {}", state.dataLoopNodes->NodeID(desicDehum.RegenCoilInletNode)));
    1106            0 :                         ErrorsFoundGeneric = true;
    1107              :                     }
    1108            0 :                     if (desicDehum.RegenCoilOutletNode != desicDehum.HXRegenInNode) {
    1109            0 :                         ShowSevereError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1110            0 :                         ShowContinueError(state,
    1111              :                                           "Regen heater outlet node name and desiccant heat exchanger regen inlet node name do not match for fan "
    1112              :                                           "placement: Blow Through");
    1113            0 :                         ShowContinueError(state,
    1114            0 :                                           format("...Regen heater outlet node = {}", state.dataLoopNodes->NodeID(desicDehum.RegenCoilOutletNode)));
    1115            0 :                         ShowContinueError(state, format("...HX regen inlet node      = {}", state.dataLoopNodes->NodeID(desicDehum.HXRegenInNode)));
    1116            0 :                         ErrorsFoundGeneric = true;
    1117              :                     }
    1118              :                 } else {
    1119            0 :                     if (desicDehum.RegenFanOutNode != desicDehum.HXRegenInNode) {
    1120            0 :                         ShowSevereError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1121            0 :                         ShowContinueError(
    1122              :                             state,
    1123              :                             "Regen fan outlet node name and desiccant heat exchanger inlet node name do not match for fan placement: Blow Through");
    1124            0 :                         ShowContinueError(state, format("...Regen fan outlet node   = {}", state.dataLoopNodes->NodeID(desicDehum.RegenFanOutNode)));
    1125            0 :                         ShowContinueError(state, format("...Desiccant HX inlet node = {}", state.dataLoopNodes->NodeID(desicDehum.HXRegenInNode)));
    1126            0 :                         ErrorsFoundGeneric = true;
    1127              :                     }
    1128              :                 }
    1129              :             } else { // ELSE for IF (desicDehum%RegenFanPlacement == HVAC::BlowThru)THEN
    1130            4 :                 desicDehum.RegenAirOutNode = NodeInputManager::GetOnlySingleNode(state,
    1131              :                                                                                  RegenFanOutlet,
    1132              :                                                                                  ErrorsFound,
    1133              :                                                                                  DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
    1134            4 :                                                                                  desicDehum.Name,
    1135              :                                                                                  DataLoopNode::NodeFluidType::Air,
    1136              :                                                                                  DataLoopNode::ConnectionType::Outlet,
    1137              :                                                                                  NodeInputManager::CompFluidStream::Primary,
    1138              :                                                                                  DataLoopNode::ObjectIsParent);
    1139            4 :                 if (!lAlphaBlanks(10)) {
    1140            4 :                     desicDehum.RegenAirInNode = NodeInputManager::GetOnlySingleNode(state,
    1141              :                                                                                     RegenCoilInlet,
    1142              :                                                                                     ErrorsFound,
    1143              :                                                                                     DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
    1144            4 :                                                                                     desicDehum.Name,
    1145              :                                                                                     DataLoopNode::NodeFluidType::Air,
    1146              :                                                                                     DataLoopNode::ConnectionType::Inlet,
    1147              :                                                                                     NodeInputManager::CompFluidStream::Primary,
    1148              :                                                                                     DataLoopNode::ObjectIsParent);
    1149            4 :                     if (desicDehum.RegenCoilOutletNode != desicDehum.HXRegenInNode) {
    1150            0 :                         ShowSevereError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1151            0 :                         ShowContinueError(state,
    1152              :                                           "Regen heater outlet node name and desiccant heat exchanger regen inlet node name do not match for fan "
    1153              :                                           "placement: Draw Through");
    1154            0 :                         ShowContinueError(state,
    1155            0 :                                           format("...Regen heater outlet node = {}", state.dataLoopNodes->NodeID(desicDehum.RegenCoilOutletNode)));
    1156            0 :                         ShowContinueError(state, format("...HX regen inlet node      = {}", state.dataLoopNodes->NodeID(desicDehum.HXRegenInNode)));
    1157            0 :                         ErrorsFoundGeneric = true;
    1158              :                     }
    1159              :                 } else {
    1160            0 :                     desicDehum.RegenAirInNode = NodeInputManager::GetOnlySingleNode(state,
    1161              :                                                                                     RegenAirInlet,
    1162              :                                                                                     ErrorsFound,
    1163              :                                                                                     DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
    1164            0 :                                                                                     desicDehum.Name,
    1165              :                                                                                     DataLoopNode::NodeFluidType::Air,
    1166              :                                                                                     DataLoopNode::ConnectionType::Inlet,
    1167              :                                                                                     NodeInputManager::CompFluidStream::Primary,
    1168              :                                                                                     DataLoopNode::ObjectIsParent);
    1169              :                 }
    1170            4 :                 if (desicDehum.RegenFanInNode != desicDehum.HXRegenOutNode) {
    1171            0 :                     ShowSevereError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1172            0 :                     ShowContinueError(
    1173              :                         state,
    1174              :                         "Regen fan inlet node name and desiccant heat exchanger regen outlet node name do not match for fan placement: Draw Through");
    1175            0 :                     ShowContinueError(state, format("...Regen fan inlet node = {}", state.dataLoopNodes->NodeID(desicDehum.RegenFanInNode)));
    1176            0 :                     ShowContinueError(state, format("...HX regen outlet node = {}", state.dataLoopNodes->NodeID(desicDehum.HXRegenOutNode)));
    1177            0 :                     ErrorsFoundGeneric = true;
    1178              :                 }
    1179              :             }
    1180              : 
    1181            4 :             desicDehum.CoolingCoilType = Alphas(11);
    1182            4 :             desicDehum.CoolingCoilName = Alphas(12);
    1183              : 
    1184            4 :             if (!lAlphaBlanks(12)) {
    1185            3 :                 if ((Util::SameString(desicDehum.CoolingCoilType, "COIL:COOLING:DX:SINGLESPEED")) ||
    1186            3 :                     (Util::SameString(desicDehum.CoolingCoilType, "COIL:COOLING:DX:TWOSTAGEWITHHUMIDITYCONTROLMODE")) ||
    1187            3 :                     (Util::SameString(desicDehum.CoolingCoilType, "COIL:COOLING:DX:VARIABLESPEED"))) {
    1188            2 :                     ErrorsFound2 = false;
    1189            4 :                     ValidateComponent(state,
    1190              :                                       desicDehum.CoolingCoilType,
    1191            2 :                                       desicDehum.CoolingCoilName,
    1192              :                                       ErrorsFound2,
    1193            4 :                                       desicDehum.DehumType + " \"" + desicDehum.Name + "\"");
    1194            2 :                     if (ErrorsFound2) {
    1195            0 :                         ErrorsFoundGeneric = true;
    1196              :                     }
    1197              : 
    1198            2 :                     if ((Util::SameString(desicDehum.CoolingCoilType, "COIL:COOLING:DX:SINGLESPEED"))) {
    1199            1 :                         desicDehum.coolingCoil_TypeNum = HVAC::CoilDX_CoolingSingleSpeed;
    1200            1 :                     } else if ((Util::SameString(desicDehum.CoolingCoilType, "COIL:COOLING:DX:TWOSTAGEWITHHUMIDITYCONTROLMODE"))) {
    1201            0 :                         desicDehum.coolingCoil_TypeNum = HVAC::CoilDX_CoolingTwoStageWHumControl;
    1202            1 :                     } else if ((Util::SameString(desicDehum.CoolingCoilType, "COIL:COOLING:DX:VARIABLESPEED"))) {
    1203            1 :                         desicDehum.coolingCoil_TypeNum = HVAC::Coil_CoolingAirToAirVariableSpeed;
    1204              :                     }
    1205              : 
    1206              :                 } else {
    1207            0 :                     ShowSevereError(state, format("{}={}", desicDehum.DehumType, desicDehum.Name));
    1208            0 :                     ShowContinueError(state, format("Illegal {} = {}", cAlphaFields(11), desicDehum.CoolingCoilType));
    1209            0 :                     ErrorsFoundGeneric = true;
    1210              :                 }
    1211              : 
    1212            2 :                 if ((desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingSingleSpeed) ||
    1213            1 :                     (desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
    1214            1 :                     ErrorsFound2 = false;
    1215            1 :                     desicDehum.CoolingCoilOutletNode =
    1216            1 :                         DXCoils::GetCoilOutletNode(state, desicDehum.CoolingCoilType, desicDehum.CoolingCoilName, ErrorsFound2);
    1217            1 :                     desicDehum.CompanionCoilCapacity =
    1218            1 :                         DXCoils::GetCoilCapacity(state, desicDehum.CoolingCoilType, desicDehum.CoolingCoilName, ErrorsFound2);
    1219            1 :                     if (ErrorsFound2) {
    1220            0 :                         ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.CoolingCoilName));
    1221              :                     }
    1222              : 
    1223            1 :                     ErrorsFound2 = false;
    1224            1 :                     DXCoils::GetDXCoilIndex(state, desicDehum.CoolingCoilName, desicDehum.DXCoilIndex, ErrorsFound2, desicDehum.CoolingCoilType);
    1225            1 :                     if (ErrorsFound2) {
    1226            0 :                         ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.CoolingCoilName));
    1227              :                     }
    1228            1 :                 } else if (desicDehum.coolingCoil_TypeNum == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    1229            1 :                     ErrorsFound2 = false;
    1230            2 :                     desicDehum.CoolingCoilOutletNode = VariableSpeedCoils::GetCoilOutletNodeVariableSpeed(
    1231            1 :                         state, desicDehum.CoolingCoilType, desicDehum.CoolingCoilName, ErrorsFound2);
    1232            1 :                     ErrorsFound2 = false;
    1233            1 :                     desicDehum.CompanionCoilCapacity =
    1234            1 :                         VariableSpeedCoils::GetCoilCapacityVariableSpeed(state, desicDehum.CoolingCoilType, desicDehum.CoolingCoilName, ErrorsFound2);
    1235            1 :                     if (ErrorsFound2) {
    1236            0 :                         ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.CoolingCoilName));
    1237              :                     }
    1238            1 :                     ErrorsFound2 = false;
    1239            1 :                     desicDehum.DXCoilIndex =
    1240            1 :                         VariableSpeedCoils::GetCoilIndexVariableSpeed(state, desicDehum.CoolingCoilType, desicDehum.CoolingCoilName, ErrorsFound2);
    1241            1 :                     if (ErrorsFound2) {
    1242            0 :                         ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.CoolingCoilName));
    1243              :                     }
    1244              :                 }
    1245              : 
    1246              :             } //  (desicDehum%CoolingCoilName /= Blank)THEN
    1247              : 
    1248            4 :             if (Util::SameString(Alphas(13), "Yes")) {
    1249            2 :                 desicDehum.CoilUpstreamOfProcessSide = Selection::Yes;
    1250            2 :             } else if (lAlphaBlanks(13)) {
    1251            2 :                 desicDehum.CoilUpstreamOfProcessSide = Selection::No;
    1252            0 :             } else if (Util::SameString(Alphas(13), "No")) {
    1253            0 :                 desicDehum.CoilUpstreamOfProcessSide = Selection::No;
    1254              :             } else {
    1255            0 :                 ShowWarningError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1256            0 :                 ShowContinueError(state, format("Invalid choice for {} = {}", cAlphaFields(13), Alphas(13)));
    1257            0 :                 ShowContinueError(state, "...resetting to the default value of No");
    1258            0 :                 desicDehum.CoilUpstreamOfProcessSide = Selection::No;
    1259              :             }
    1260              : 
    1261            4 :             if (Util::SameString(Alphas(14), "Yes")) {
    1262            2 :                 desicDehum.Preheat = Selection::Yes;
    1263            2 :             } else if (Util::SameString(Alphas(14), "No")) {
    1264            2 :                 desicDehum.Preheat = Selection::No;
    1265            0 :             } else if (lAlphaBlanks(14)) {
    1266            0 :                 desicDehum.Preheat = Selection::No;
    1267              :             } else {
    1268            0 :                 ShowWarningError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1269            0 :                 ShowContinueError(state, format("Invalid choice for {} = {}", cAlphaFields(14), Alphas(14)));
    1270            0 :                 ShowContinueError(state, "...resetting to the default value of NO");
    1271            0 :                 desicDehum.Preheat = Selection::No;
    1272              :             }
    1273              : 
    1274            4 :             if (desicDehum.DXCoilIndex > 0) {
    1275              : 
    1276            2 :                 if (desicDehum.Preheat == Selection::Yes) { // Companion coil waste heat used for regeneration of desiccant
    1277            2 :                     ErrorsFound2 = false;
    1278              :                     DesuperHeaterIndex =
    1279            2 :                         HeatingCoils::GetHeatReclaimSourceIndex(state, desicDehum.CoolingCoilType, desicDehum.CoolingCoilName, ErrorsFound2);
    1280            2 :                     if (ErrorsFound2) {
    1281            0 :                         ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1282            0 :                         ErrorsFoundGeneric = true;
    1283              :                     }
    1284              : 
    1285            2 :                     if (DesuperHeaterIndex > 0) {
    1286            0 :                         ShowWarningError(state, format("{}={}", desicDehum.DehumType, desicDehum.Name));
    1287            0 :                         ShowContinueError(state,
    1288              :                                           "A Coil:Heating:Desuperheater object should not be used when condenser waste heat is reclaimed for "
    1289              :                                           "desiccant regeneration.");
    1290            0 :                         ShowContinueError(state,
    1291            0 :                                           format("A Coil:Heating:Desuperheater object was found using waste heat from the {} \"{}\" object.",
    1292            0 :                                                  desicDehum.CoolingCoilType,
    1293            0 :                                                  desicDehum.CoolingCoilName));
    1294              :                         //          ErrorsFoundGeneric = .TRUE.
    1295              :                     }
    1296              :                 }
    1297            2 :                 if ((desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingSingleSpeed) ||
    1298            1 :                     (desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
    1299            1 :                     ErrorsFound2 = false;
    1300            1 :                     desicDehum.CondenserInletNode =
    1301            1 :                         DXCoils::GetCoilCondenserInletNode(state, desicDehum.CoolingCoilType, desicDehum.CoolingCoilName, ErrorsFound2);
    1302            1 :                 } else if (desicDehum.coolingCoil_TypeNum == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    1303            1 :                     ErrorsFound2 = false;
    1304            1 :                     desicDehum.CondenserInletNode = VariableSpeedCoils::GetVSCoilCondenserInletNode(state, desicDehum.CoolingCoilName, ErrorsFound2);
    1305              :                 }
    1306            2 :                 if (desicDehum.CondenserInletNode == 0 && desicDehum.Preheat == Selection::Yes) {
    1307            0 :                     desicDehum.CondenserInletNode =
    1308            0 :                         NodeInputManager::GetOnlySingleNode(state,
    1309            0 :                                                             desicDehum.CoolingCoilName + " Condenser Inlet Node",
    1310              :                                                             ErrorsFound,
    1311              :                                                             DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
    1312            0 :                                                             desicDehum.Name,
    1313              :                                                             DataLoopNode::NodeFluidType::Air,
    1314              :                                                             DataLoopNode::ConnectionType::OutsideAirReference,
    1315              :                                                             NodeInputManager::CompFluidStream::Secondary,
    1316              :                                                             DataLoopNode::ObjectIsNotParent);
    1317            0 :                     OutAirNodeManager::CheckAndAddAirNodeNumber(state, desicDehum.CondenserInletNode, OANodeError);
    1318            0 :                     if (!OANodeError) {
    1319            0 :                         ShowWarningError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1320            0 :                         ShowContinueError(state,
    1321            0 :                                           format("The {} input is specified as Yes and a condenser air inlet node name was not specified for the "
    1322              :                                                  "companion cooling coil.",
    1323              :                                                  cAlphaFields(14)));
    1324            0 :                         ShowContinueError(
    1325            0 :                             state, format("Adding condenser inlet air node for {} \"{}\"", desicDehum.CoolingCoilType, desicDehum.CoolingCoilName));
    1326            0 :                         ShowContinueError(
    1327            0 :                             state, format("...condenser inlet air node name = {}", state.dataLoopNodes->NodeID(desicDehum.CondenserInletNode)));
    1328            0 :                         ShowContinueError(state, "...this node name will be specified as an outdoor air node.");
    1329              :                     }
    1330            2 :                 } else if (desicDehum.Preheat == Selection::Yes) {
    1331            2 :                     if (!OutAirNodeManager::CheckOutAirNodeNumber(state, desicDehum.CondenserInletNode)) {
    1332            0 :                         ShowSevereError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1333            0 :                         ShowContinueError(
    1334              :                             state,
    1335            0 :                             format("The regeneration air inlet node must be specified as an outdoor air node when {} is specified as Yes.",
    1336              :                                    cAlphaFields(14)));
    1337            0 :                         ErrorsFoundGeneric = true;
    1338              :                     }
    1339              :                 }
    1340              :             }
    1341              : 
    1342            4 :             if (OutAirNodeManager::CheckOutAirNodeNumber(state, desicDehum.RegenAirInNode)) {
    1343            2 :                 desicDehum.RegenInletIsOutsideAirNode = true;
    1344              :             }
    1345              : 
    1346            4 :             if (desicDehum.DXCoilIndex == 0 && desicDehum.Preheat == Selection::Yes) {
    1347            0 :                 ShowWarningError(state, format("{}={}", desicDehum.DehumType, desicDehum.Name));
    1348            0 :                 ShowContinueError(
    1349            0 :                     state, format("A valid {} must be used when condenser waste heat is reclaimed for desiccant regeneration.", cAlphaFields(12)));
    1350            0 :                 ShowContinueError(state, format("... {} = {}", cAlphaFields(11), desicDehum.CoolingCoilType));
    1351            0 :                 ShowContinueError(state, format("... {} = {}", cAlphaFields(12), desicDehum.CoolingCoilName));
    1352            0 :                 ErrorsFoundGeneric = true;
    1353              :             }
    1354              : 
    1355            4 :             if (desicDehum.DXCoilIndex > 0 && desicDehum.CoilUpstreamOfProcessSide == Selection::Yes) {
    1356            2 :                 if ((desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingSingleSpeed) ||
    1357            1 :                     (desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
    1358            1 :                     ErrorsFound2 = false;
    1359            1 :                     CoilBypassedFlowFrac =
    1360            1 :                         DXCoils::GetDXCoilBypassedFlowFrac(state, desicDehum.CoolingCoilType, desicDehum.CoolingCoilName, ErrorsFound2);
    1361            1 :                 } else if (desicDehum.coolingCoil_TypeNum == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    1362            1 :                     ErrorsFound2 = false;
    1363            1 :                     CoilBypassedFlowFrac = 0.0; // bypass flow fraction not in VS coil model
    1364              :                 }
    1365            2 :                 if (ErrorsFound2) {
    1366            0 :                     ShowContinueError(state, format("...occurs in {} \"{}\"", desicDehum.DehumType, desicDehum.CoolingCoilName));
    1367              :                 }
    1368            2 :                 if (CoilBypassedFlowFrac > 0.0) {
    1369            0 :                     ShowWarningError(state, format("{}={}", desicDehum.DehumType, desicDehum.Name));
    1370            0 :                     ShowContinueError(
    1371              :                         state,
    1372            0 :                         format("A DX coil bypassed air flow fraction greater than 0 may not be used when the input for {} is specified as Yes.",
    1373              :                                cAlphaFields(13)));
    1374            0 :                     ShowContinueError(state,
    1375            0 :                                       format("A DX coil with a bypassed air flow fraction greater than 0 may be upstream of the process inlet "
    1376              :                                              "however the input for {} must be specified as No.",
    1377              :                                              cAlphaFields(13)));
    1378            0 :                     ShowContinueError(state, format("... {} = {}", cAlphaFields(11), desicDehum.CoolingCoilType));
    1379            0 :                     ShowContinueError(state, format("... {} = {}", cAlphaFields(12), desicDehum.CoolingCoilName));
    1380            0 :                     ErrorsFoundGeneric = true;
    1381              :                 }
    1382            2 :             } else if (desicDehum.DXCoilIndex == 0 && desicDehum.CoilUpstreamOfProcessSide == Selection::Yes) {
    1383            0 :                 ShowSevereError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1384            0 :                 ShowContinueError(state, format("A valid companion coil must be specified when {} is specified as Yes.", cAlphaFields(13)));
    1385            0 :                 ErrorsFoundGeneric = true;
    1386              :             }
    1387              : 
    1388            4 :             if (!desicDehum.RegenInletIsOutsideAirNode && desicDehum.Preheat == Selection::Yes) {
    1389            0 :                 ShowWarningError(state, format("{}={}", desicDehum.DehumType, desicDehum.Name));
    1390            0 :                 ShowContinueError(
    1391              :                     state,
    1392            0 :                     format("The desiccant dehumidifier regeneration air inlet must be specified as an outdoor air node when {} is specified as Yes.",
    1393              :                            cAlphaFields(14)));
    1394            0 :                 ShowContinueError(state,
    1395            0 :                                   format("... desiccant dehumidifier regeneration air inlet node name = {}",
    1396            0 :                                          state.dataLoopNodes->NodeID(desicDehum.RegenAirInNode)));
    1397            0 :                 ErrorsFoundGeneric = true;
    1398              :             }
    1399              : 
    1400            4 :             if (desicDehum.CoilUpstreamOfProcessSide == Selection::Yes) {
    1401            2 :                 if (desicDehum.ProcAirInNode != desicDehum.CoolingCoilOutletNode) {
    1402            0 :                     ShowSevereError(state, format("For {} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1403            0 :                     ShowContinueError(state, "Node names are inconsistent in companion cooling coil and desiccant heat exchanger objects.");
    1404            0 :                     ShowContinueError(state,
    1405            0 :                                       format("For companion cooling coil = {} \"{}\"", desicDehum.CoolingCoilType, desicDehum.CoolingCoilName));
    1406            0 :                     ShowContinueError(
    1407            0 :                         state, format("The outlet node name in cooling coil = {}", state.dataLoopNodes->NodeID(desicDehum.CoolingCoilOutletNode)));
    1408            0 :                     ShowContinueError(state, format("For desiccant heat exchanger = {} \"{}\"", desicDehum.HXType, desicDehum.HXName));
    1409            0 :                     ShowContinueError(state, format("The process air inlet node name = {}", state.dataLoopNodes->NodeID(desicDehum.ProcAirInNode)));
    1410            0 :                     ShowFatalError(state, "...previous error causes program termination.");
    1411              :                 }
    1412              :             }
    1413              : 
    1414              :             // Exhaust Fan input
    1415            4 :             desicDehum.ExhaustFanMaxVolFlowRate = Numbers(2);
    1416            4 :             desicDehum.ExhaustFanMaxPower = Numbers(3);
    1417            4 :             desicDehum.ExhaustFanCurveIndex = Curve::GetCurveIndex(state, Alphas(15));
    1418              : 
    1419            4 :             if (desicDehum.ExhaustFanCurveIndex > 0) {
    1420            6 :                 ErrorsFoundGeneric |= EnergyPlus::Curve::CheckCurveDims(state,
    1421              :                                                                         desicDehum.ExhaustFanCurveIndex, // Curve index
    1422              :                                                                         {1},                             // Valid dimensions
    1423              :                                                                         RoutineName,                     // Routine name
    1424              :                                                                         CurrentModuleObject,             // Object Type
    1425              :                                                                         desicDehum.Name,                 // Object Name
    1426            2 :                                                                         cAlphaFields(15));               // Field Name
    1427              :             }
    1428              : 
    1429            4 :             if (desicDehum.Preheat == Selection::Yes) {
    1430            2 :                 ErrorsFound2 = false;
    1431            2 :                 if (desicDehum.ExhaustFanMaxVolFlowRate <= 0) {
    1432            0 :                     ErrorsFound2 = true;
    1433              :                 }
    1434            2 :                 if (desicDehum.ExhaustFanMaxPower <= 0) {
    1435            0 :                     ErrorsFound2 = true;
    1436              :                 }
    1437            2 :                 if (ErrorsFound2) {
    1438            0 :                     ShowSevereError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1439            0 :                     ShowContinueError(
    1440            0 :                         state, format("{} and {} must be defined if {} field is \"Yes\".", cNumericFields(2), cNumericFields(3), cAlphaFields(14)));
    1441              :                 }
    1442            2 :             } else if (desicDehum.Preheat == Selection::No) {
    1443            2 :                 if (desicDehum.ExhaustFanMaxVolFlowRate > 0.0) {
    1444            0 :                     ShowWarningError(state, format("{} \"{}\"", desicDehum.DehumType, desicDehum.Name));
    1445            0 :                     ShowContinueError(state, format("{} should be 0 if {} field is \"No\".", cNumericFields(2), cAlphaFields(14)));
    1446            0 :                     ShowContinueError(state, format("...{} will not be used and is reset to 0.", cNumericFields(2)));
    1447            0 :                     desicDehum.ExhaustFanMaxVolFlowRate = 0.0;
    1448              :                 }
    1449              :             }
    1450            4 :         }
    1451              : 
    1452              :         // SET UP OUTPUTS
    1453           12 :         for (int DesicDehumNum = 1; DesicDehumNum <= state.dataDesiccantDehumidifiers->NumSolidDesicDehums; ++DesicDehumNum) {
    1454            5 :             auto &desicDehum = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum);
    1455              :             // Setup Report variables for the Desiccant Dehumidifiers
    1456           10 :             SetupOutputVariable(state,
    1457              :                                 "Dehumidifier Removed Water Mass",
    1458              :                                 Constant::Units::kg,
    1459            5 :                                 desicDehum.WaterRemove,
    1460              :                                 OutputProcessor::TimeStepType::System,
    1461              :                                 OutputProcessor::StoreType::Sum,
    1462            5 :                                 desicDehum.Name);
    1463           10 :             SetupOutputVariable(state,
    1464              :                                 "Dehumidifier Removed Water Mass Flow Rate",
    1465              :                                 Constant::Units::kg_s,
    1466            5 :                                 desicDehum.WaterRemoveRate,
    1467              :                                 OutputProcessor::TimeStepType::System,
    1468              :                                 OutputProcessor::StoreType::Average,
    1469            5 :                                 desicDehum.Name);
    1470           10 :             SetupOutputVariable(state,
    1471              :                                 "Dehumidifier Part Load Ratio",
    1472              :                                 Constant::Units::None,
    1473            5 :                                 desicDehum.PartLoad,
    1474              :                                 OutputProcessor::TimeStepType::System,
    1475              :                                 OutputProcessor::StoreType::Average,
    1476            5 :                                 desicDehum.Name);
    1477           10 :             SetupOutputVariable(state,
    1478              :                                 "Dehumidifier Electricity Rate",
    1479              :                                 Constant::Units::W,
    1480            5 :                                 desicDehum.ElecUseRate,
    1481              :                                 OutputProcessor::TimeStepType::System,
    1482              :                                 OutputProcessor::StoreType::Average,
    1483            5 :                                 desicDehum.Name);
    1484           10 :             SetupOutputVariable(state,
    1485              :                                 "Dehumidifier Electricity Energy",
    1486              :                                 Constant::Units::J,
    1487            5 :                                 desicDehum.ElecUseEnergy,
    1488              :                                 OutputProcessor::TimeStepType::System,
    1489              :                                 OutputProcessor::StoreType::Sum,
    1490            5 :                                 desicDehum.Name,
    1491              :                                 Constant::eResource::Electricity,
    1492              :                                 OutputProcessor::Group::HVAC,
    1493              :                                 OutputProcessor::EndUseCat::Cooling);
    1494           10 :             SetupOutputVariable(state,
    1495              :                                 "Dehumidifier Regeneration Specific Energy",
    1496              :                                 Constant::Units::J_kgWater,
    1497            5 :                                 desicDehum.SpecRegenEnergy,
    1498              :                                 OutputProcessor::TimeStepType::System,
    1499              :                                 OutputProcessor::StoreType::Average,
    1500            5 :                                 desicDehum.Name);
    1501           10 :             SetupOutputVariable(state,
    1502              :                                 "Dehumidifier Regeneration Rate",
    1503              :                                 Constant::Units::W,
    1504            5 :                                 desicDehum.QRegen,
    1505              :                                 OutputProcessor::TimeStepType::System,
    1506              :                                 OutputProcessor::StoreType::Average,
    1507            5 :                                 desicDehum.Name);
    1508           10 :             SetupOutputVariable(state,
    1509              :                                 "Dehumidifier Regeneration Energy",
    1510              :                                 Constant::Units::J,
    1511            5 :                                 desicDehum.RegenEnergy,
    1512              :                                 OutputProcessor::TimeStepType::System,
    1513              :                                 OutputProcessor::StoreType::Sum,
    1514            5 :                                 desicDehum.Name);
    1515           10 :             SetupOutputVariable(state,
    1516              :                                 "Dehumidifier Regeneration Air Speed",
    1517              :                                 Constant::Units::m_s,
    1518            5 :                                 desicDehum.RegenAirVel,
    1519              :                                 OutputProcessor::TimeStepType::System,
    1520              :                                 OutputProcessor::StoreType::Average,
    1521            5 :                                 desicDehum.Name);
    1522           10 :             SetupOutputVariable(state,
    1523              :                                 "Dehumidifier Regeneration Air Mass Flow Rate",
    1524              :                                 Constant::Units::kg_s,
    1525            5 :                                 desicDehum.RegenAirInMassFlowRate,
    1526              :                                 OutputProcessor::TimeStepType::System,
    1527              :                                 OutputProcessor::StoreType::Average,
    1528            5 :                                 desicDehum.Name);
    1529           10 :             SetupOutputVariable(state,
    1530              :                                 "Dehumidifier Process Air Mass Flow Rate",
    1531              :                                 Constant::Units::kg_s,
    1532            5 :                                 desicDehum.ProcAirInMassFlowRate,
    1533              :                                 OutputProcessor::TimeStepType::System,
    1534              :                                 OutputProcessor::StoreType::Average,
    1535            5 :                                 desicDehum.Name);
    1536              :         }
    1537              : 
    1538           11 :         for (int DesicDehumIndex = 1; DesicDehumIndex <= state.dataDesiccantDehumidifiers->NumGenericDesicDehums; ++DesicDehumIndex) {
    1539              :             // this is wrong, should be a loop from (state.dataDesiccantDehumidifiers->NumSolidDesicDehums + 1) to
    1540              :             // (state.dataDesiccantDehumidifiers->NumDesicDehums = NumSolidDesicDehums + NumGenericDesicDehums)
    1541              :             // DesicDehumNum = DesicDehumIndex + state.dataDesiccantDehumidifiers->NumSolidDesicDehums;
    1542            4 :             auto &desicDehum = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumIndex);
    1543              :             // Setup Report variables for the Desiccant Dehumidifiers
    1544            8 :             SetupOutputVariable(state,
    1545              :                                 "Dehumidifier Removed Water Mass",
    1546              :                                 Constant::Units::kg,
    1547            4 :                                 desicDehum.WaterRemove,
    1548              :                                 OutputProcessor::TimeStepType::System,
    1549              :                                 OutputProcessor::StoreType::Sum,
    1550            4 :                                 desicDehum.Name);
    1551            8 :             SetupOutputVariable(state,
    1552              :                                 "Dehumidifier Removed Water Mass Flow Rate",
    1553              :                                 Constant::Units::kg_s,
    1554            4 :                                 desicDehum.WaterRemoveRate,
    1555              :                                 OutputProcessor::TimeStepType::System,
    1556              :                                 OutputProcessor::StoreType::Average,
    1557            4 :                                 desicDehum.Name);
    1558            8 :             SetupOutputVariable(state,
    1559              :                                 "Dehumidifier Part Load Ratio",
    1560              :                                 Constant::Units::None,
    1561            4 :                                 desicDehum.PartLoad,
    1562              :                                 OutputProcessor::TimeStepType::System,
    1563              :                                 OutputProcessor::StoreType::Average,
    1564            4 :                                 desicDehum.Name);
    1565            4 :             if (desicDehum.ExhaustFanMaxVolFlowRate > 0) {
    1566            4 :                 SetupOutputVariable(state,
    1567              :                                     "Dehumidifier Exhaust Fan Electricity Rate",
    1568              :                                     Constant::Units::W,
    1569            2 :                                     desicDehum.ExhaustFanPower,
    1570              :                                     OutputProcessor::TimeStepType::System,
    1571              :                                     OutputProcessor::StoreType::Average,
    1572            2 :                                     desicDehum.Name);
    1573            4 :                 SetupOutputVariable(state,
    1574              :                                     "Dehumidifier Exhaust Fan Electricity Energy",
    1575              :                                     Constant::Units::J,
    1576            2 :                                     desicDehum.ExhaustFanElecConsumption,
    1577              :                                     OutputProcessor::TimeStepType::System,
    1578              :                                     OutputProcessor::StoreType::Sum,
    1579            2 :                                     desicDehum.Name,
    1580              :                                     Constant::eResource::Electricity,
    1581              :                                     OutputProcessor::Group::HVAC,
    1582              :                                     OutputProcessor::EndUseCat::Cooling);
    1583              :             }
    1584              :         }
    1585              : 
    1586            7 :         if (ErrorsFound) {
    1587            0 :             ShowFatalError(state, "Errors found in getting Dehumidifier:Desiccant:NoFans input");
    1588            7 :         } else if (ErrorsFoundGeneric) {
    1589            0 :             ShowFatalError(state, "Errors found in getting DESICCANT DEHUMIDIFIER input");
    1590              :         }
    1591              : 
    1592            7 :         Alphas.deallocate();
    1593            7 :         cAlphaFields.deallocate();
    1594            7 :         cNumericFields.deallocate();
    1595            7 :         Numbers.deallocate();
    1596            7 :         lAlphaBlanks.deallocate();
    1597            7 :         lNumericBlanks.deallocate();
    1598            7 :     }
    1599              : 
    1600       283978 :     void InitDesiccantDehumidifier(EnergyPlusData &state,
    1601              :                                    int const DesicDehumNum,      // number of the current dehumidifier being simulated
    1602              :                                    bool const FirstHVACIteration // TRUE if 1st HVAC simulation of system timestep
    1603              :     )
    1604              :     {
    1605              : 
    1606              :         // SUBROUTINE INFORMATION:
    1607              :         //       AUTHOR         Michael J. Witte, GARD Analytics, Inc.
    1608              :         //                      for Gas Research Institute
    1609              :         //       DATE WRITTEN   March 2001
    1610              :         //       MODIFIED       Jan 2005 M. J. Witte, GARD Analytics, Inc.
    1611              :         //                        Add setpoint validation for new control type option:
    1612              :         //                          NODE LEAVING HUMRAT SETPOINT:BYPASS
    1613              :         //                        Work supported by ASHRAE research project 1254-RP
    1614              :         //                      June 2007 R. Raustad, FSEC
    1615              :         //                        Added new dehumidifier type -- DESICCANT DEHUMIDIFIER
    1616              :         //                      May 2009, B. Griffith, NREL. added EMS node setpoint checks
    1617              : 
    1618              :         // PURPOSE OF THIS SUBROUTINE:
    1619              :         // This subroutine is for initializations of the dehumidifier Components.
    1620              : 
    1621              :         // METHODOLOGY EMPLOYED:
    1622              :         // Uses the status flags to trigger initializations.
    1623              : 
    1624              :         // SUBROUTINE PARAMETER DEFINITIONS:
    1625              :         static constexpr std::string_view RoutineName("InitDesiccantDehumidifier");
    1626       283992 :         static std::string const initCBVAV("InitCBVAV");
    1627              : 
    1628              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1629              :         // bool ErrorsFound(false);   // Set to true if errors in input, fatal at end of routine
    1630              :         Real64 QCoilActual; // actual CBVAV steam heating coil load met (W)
    1631              :         bool ErrorFlag;     // local error flag returned from data mining
    1632       283978 :         bool DoSetPointTest = state.dataHVACGlobal->DoSetPointTest;
    1633              : 
    1634       283978 :         auto &desicDehum = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum);
    1635              : 
    1636       283978 :         if (state.dataDesiccantDehumidifiers->InitDesiccantDehumidifierOneTimeFlag) {
    1637              : 
    1638              :             // initialize the environment and sizing flags
    1639            7 :             state.dataDesiccantDehumidifiers->MyEnvrnFlag.dimension(state.dataDesiccantDehumidifiers->NumDesicDehums, true);
    1640            7 :             state.dataDesiccantDehumidifiers->MyPlantScanFlag.dimension(state.dataDesiccantDehumidifiers->NumDesicDehums, true);
    1641              : 
    1642            7 :             state.dataDesiccantDehumidifiers->InitDesiccantDehumidifierOneTimeFlag = false;
    1643              :         }
    1644              : 
    1645       283978 :         if (state.dataDesiccantDehumidifiers->MyPlantScanFlag(DesicDehumNum) && allocated(state.dataPlnt->PlantLoop)) {
    1646            9 :             if ((desicDehum.RegenCoilType_Num == HVAC::Coil_HeatingWater) || (desicDehum.RegenCoilType_Num == HVAC::Coil_HeatingSteam)) {
    1647            0 :                 if (desicDehum.RegenCoilType_Num == HVAC::Coil_HeatingWater) {
    1648            0 :                     ErrorFlag = false;
    1649            0 :                     PlantUtilities::ScanPlantLoopsForObject(state,
    1650              :                                                             desicDehum.RegenCoilName,
    1651              :                                                             DataPlant::PlantEquipmentType::CoilWaterSimpleHeating,
    1652            0 :                                                             desicDehum.plantLoc,
    1653              :                                                             ErrorFlag,
    1654              :                                                             _,
    1655              :                                                             _,
    1656              :                                                             _,
    1657              :                                                             _,
    1658              :                                                             _);
    1659            0 :                     if (ErrorFlag) {
    1660            0 :                         ShowFatalError(state, "InitDesiccantDehumidifier: Program terminated for previous conditions.");
    1661              :                     }
    1662              : 
    1663            0 :                     ErrorFlag = false;
    1664            0 :                     desicDehum.MaxCoilFluidFlow =
    1665            0 :                         WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", desicDehum.RegenCoilName, ErrorFlag);
    1666            0 :                     if (desicDehum.MaxCoilFluidFlow > 0.0) {
    1667              :                         Real64 FluidDensity =
    1668            0 :                             state.dataPlnt->PlantLoop(desicDehum.plantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, initCBVAV);
    1669            0 :                         desicDehum.MaxCoilFluidFlow *= FluidDensity;
    1670              :                     }
    1671              : 
    1672            0 :                 } else if (desicDehum.RegenCoilType_Num == HVAC::Coil_HeatingSteam) {
    1673              : 
    1674            0 :                     ErrorFlag = false;
    1675            0 :                     PlantUtilities::ScanPlantLoopsForObject(state,
    1676              :                                                             desicDehum.RegenCoilName,
    1677              :                                                             DataPlant::PlantEquipmentType::CoilSteamAirHeating,
    1678            0 :                                                             desicDehum.plantLoc,
    1679              :                                                             ErrorFlag,
    1680              :                                                             _,
    1681              :                                                             _,
    1682              :                                                             _,
    1683              :                                                             _,
    1684              :                                                             _);
    1685              : 
    1686            0 :                     if (ErrorFlag) {
    1687            0 :                         ShowFatalError(state, "InitDesiccantDehumidifier: Program terminated for previous conditions.");
    1688              :                     }
    1689            0 :                     ErrorFlag = false;
    1690            0 :                     desicDehum.MaxCoilFluidFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, desicDehum.RegenCoilIndex, ErrorFlag);
    1691              : 
    1692            0 :                     if (desicDehum.MaxCoilFluidFlow > 0.0) {
    1693            0 :                         Real64 FluidDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, RoutineName);
    1694            0 :                         desicDehum.MaxCoilFluidFlow *= FluidDensity;
    1695              :                     }
    1696              :                 }
    1697              : 
    1698              :                 // fill outlet node for regenartion hot water or steam heating coil
    1699            0 :                 desicDehum.CoilOutletNode = DataPlant::CompData::getPlantComponent(state, desicDehum.plantLoc).NodeNumOut;
    1700            0 :                 state.dataDesiccantDehumidifiers->MyPlantScanFlag(DesicDehumNum) = false;
    1701              : 
    1702            0 :             } else { // DesicDehum is not connected to plant
    1703            9 :                 state.dataDesiccantDehumidifiers->MyPlantScanFlag(DesicDehumNum) = false;
    1704              :             }
    1705       283969 :         } else if (state.dataDesiccantDehumidifiers->MyPlantScanFlag(DesicDehumNum) && !state.dataGlobal->AnyPlantInModel) {
    1706            0 :             state.dataDesiccantDehumidifiers->MyPlantScanFlag(DesicDehumNum) = false;
    1707              :         }
    1708              : 
    1709       283978 :         switch (desicDehum.DehumTypeCode) {
    1710        92320 :         case DesicDehumType::Solid: {
    1711        92320 :             if (!state.dataGlobal->SysSizingCalc && state.dataDesiccantDehumidifiers->MySetPointCheckFlag && DoSetPointTest) {
    1712            5 :                 if (desicDehum.controlType == DesicDehumCtrlType::NodeHumratBypass) {
    1713            2 :                     int ControlNode = desicDehum.ProcAirOutNode;
    1714            2 :                     if (ControlNode > 0) {
    1715            2 :                         if (state.dataLoopNodes->Node(ControlNode).HumRatMax == DataLoopNode::SensedNodeFlagValue) {
    1716            0 :                             if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1717            0 :                                 ShowSevereError(state, "Missing humidity ratio setpoint (HumRatMax) for ");
    1718            0 :                                 ShowContinueError(state, format("Dehumidifier:Desiccant:NoFans: {}", desicDehum.Name));
    1719            0 :                                 ShowContinueError(state, format("Node Referenced={}", state.dataLoopNodes->NodeID(ControlNode)));
    1720            0 :                                 ShowContinueError(state, "use a Setpoint Manager to establish a setpoint at the process air outlet node.");
    1721            0 :                                 state.dataHVACGlobal->SetPointErrorFlag = true;
    1722              :                             } else {
    1723            0 :                                 EMSManager::CheckIfNodeSetPointManagedByEMS(
    1724            0 :                                     state, ControlNode, HVAC::CtrlVarType::MaxHumRat, state.dataHVACGlobal->SetPointErrorFlag);
    1725            0 :                                 if (state.dataHVACGlobal->SetPointErrorFlag) {
    1726            0 :                                     ShowSevereError(state, "Missing humidity ratio setpoint (HumRatMax) for ");
    1727            0 :                                     ShowContinueError(state, format("Dehumidifier:Desiccant:NoFans: {}", desicDehum.Name));
    1728            0 :                                     ShowContinueError(state, format("Node Referenced={}", state.dataLoopNodes->NodeID(ControlNode)));
    1729            0 :                                     ShowContinueError(state, "use a Setpoint Manager to establish a setpoint at the process air outlet node.");
    1730            0 :                                     ShowContinueError(state, "Or use EMS Actuator to establish a setpoint at the process air outlet node.");
    1731              :                                 }
    1732              :                             }
    1733              :                         }
    1734              :                     }
    1735              :                 }
    1736            5 :                 state.dataDesiccantDehumidifiers->MySetPointCheckFlag = false;
    1737              :             }
    1738              :             // always do these initializations every iteration
    1739        92320 :             int ProcInNode = desicDehum.ProcAirInNode;
    1740        92320 :             desicDehum.ProcAirInTemp = state.dataLoopNodes->Node(ProcInNode).Temp;
    1741        92320 :             desicDehum.ProcAirInHumRat = state.dataLoopNodes->Node(ProcInNode).HumRat;
    1742        92320 :             desicDehum.ProcAirInEnthalpy = state.dataLoopNodes->Node(ProcInNode).Enthalpy;
    1743        92320 :             desicDehum.ProcAirInMassFlowRate = state.dataLoopNodes->Node(ProcInNode).MassFlowRate;
    1744              : 
    1745              :             //  Determine heating coil inlet conditions by calling it with zero load
    1746              :             //  Not sure if this is really a good way to do this, should revisit for next release.
    1747        92320 :             CalcNonDXHeatingCoils(state, DesicDehumNum, FirstHVACIteration, 0.0);
    1748              : 
    1749        92320 :             int RegenInNode = desicDehum.RegenAirInNode;
    1750        92320 :             desicDehum.RegenAirInTemp = state.dataLoopNodes->Node(RegenInNode).Temp;
    1751        92320 :             desicDehum.RegenAirInHumRat = state.dataLoopNodes->Node(RegenInNode).HumRat;
    1752        92320 :             desicDehum.RegenAirInEnthalpy = state.dataLoopNodes->Node(RegenInNode).Enthalpy;
    1753              : 
    1754        92320 :             desicDehum.WaterRemove = 0.0;
    1755        92320 :             desicDehum.ElecUseEnergy = 0.0;
    1756        92320 :             desicDehum.ElecUseRate = 0.0;
    1757              : 
    1758        92320 :         } break;
    1759       191658 :         case DesicDehumType::Generic: {
    1760              :             //      Do the Begin Environment initializations
    1761       191658 :             if (state.dataGlobal->BeginEnvrnFlag && state.dataDesiccantDehumidifiers->MyEnvrnFlag(DesicDehumNum)) {
    1762              :                 // Change the Volume Flow Rates to Mass Flow Rates
    1763            4 :                 desicDehum.ExhaustFanMaxMassFlowRate = desicDehum.ExhaustFanMaxVolFlowRate * state.dataEnvrn->StdRhoAir;
    1764              : 
    1765              :                 //   set fluid-side hardware limits
    1766            4 :                 if (desicDehum.CoilControlNode > 0) {
    1767              :                     //    If water coil max water flow rate is autosized, simulate once in order to mine max water flow rate
    1768            0 :                     if (desicDehum.MaxCoilFluidFlow == DataSizing::AutoSize) {
    1769            0 :                         if (desicDehum.RegenCoilType_Num == HVAC::Coil_HeatingWater) {
    1770            0 :                             WaterCoils::SimulateWaterCoilComponents(state, desicDehum.RegenCoilName, FirstHVACIteration, desicDehum.RegenCoilIndex);
    1771            0 :                             ErrorFlag = false;
    1772              :                             Real64 CoilMaxVolFlowRate =
    1773            0 :                                 WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", desicDehum.RegenCoilName, ErrorFlag);
    1774              :                             // if (ErrorFlag) {
    1775              :                             //    ErrorsFound = true;
    1776              :                             //}
    1777            0 :                             if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
    1778            0 :                                 Real64 FluidDensity = state.dataPlnt->PlantLoop(desicDehum.plantLoc.loopNum)
    1779            0 :                                                           .glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
    1780            0 :                                 desicDehum.MaxCoilFluidFlow = CoilMaxVolFlowRate * FluidDensity;
    1781              :                             }
    1782              :                         }
    1783            0 :                         if (desicDehum.RegenCoilType_Num == HVAC::Coil_HeatingSteam) {
    1784            0 :                             SteamCoils::SimulateSteamCoilComponents(state,
    1785              :                                                                     desicDehum.RegenCoilName,
    1786              :                                                                     FirstHVACIteration,
    1787            0 :                                                                     desicDehum.RegenCoilIndex,
    1788            0 :                                                                     1.0,
    1789              :                                                                     QCoilActual); // simulate any load > 0 to get max capacity of steam coil
    1790            0 :                             ErrorFlag = false;
    1791            0 :                             Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(state, desicDehum.RegenCoilIndex, ErrorFlag);
    1792              :                             // if (ErrorFlag) {
    1793              :                             //    ErrorsFound = true;
    1794              :                             //}
    1795            0 :                             if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
    1796            0 :                                 Real64 FluidDensity = Fluid::GetSteam(state)->getSatDensity(state, TempSteamIn, 1.0, RoutineName);
    1797            0 :                                 desicDehum.MaxCoilFluidFlow = CoilMaxVolFlowRate * FluidDensity;
    1798              :                             }
    1799              :                         }
    1800              :                     }
    1801            0 :                     PlantUtilities::InitComponentNodes(
    1802              :                         state, 0.0, desicDehum.MaxCoilFluidFlow, desicDehum.CoilControlNode, desicDehum.CoilOutletNode);
    1803              :                 }
    1804              : 
    1805            4 :                 state.dataDesiccantDehumidifiers->MyEnvrnFlag(DesicDehumNum) = false;
    1806              :             }
    1807              : 
    1808       191658 :             if (!state.dataGlobal->SysSizingCalc && state.dataDesiccantDehumidifiers->MySetPointCheckFlag && DoSetPointTest) {
    1809            2 :                 int ControlNode = desicDehum.ControlNodeNum;
    1810            2 :                 if (ControlNode > 0) {
    1811            2 :                     if (state.dataLoopNodes->Node(ControlNode).HumRatMax == DataLoopNode::SensedNodeFlagValue) {
    1812            0 :                         if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
    1813            0 :                             ShowSevereError(state, "Missing maximum humidity ratio setpoint (MaxHumRat) for ");
    1814            0 :                             ShowContinueError(state, format("{}: {}", desicDehum.DehumType, desicDehum.Name));
    1815            0 :                             ShowContinueError(state, format("Node Referenced={}", state.dataLoopNodes->NodeID(ControlNode)));
    1816            0 :                             ShowContinueError(state, "use a Setpoint Manager to establish a \"MaxHumRat\" setpoint at the process air control node.");
    1817            0 :                             state.dataHVACGlobal->SetPointErrorFlag = true;
    1818              :                         } else {
    1819            0 :                             EMSManager::CheckIfNodeSetPointManagedByEMS(
    1820            0 :                                 state, ControlNode, HVAC::CtrlVarType::MaxHumRat, state.dataHVACGlobal->SetPointErrorFlag);
    1821            0 :                             if (state.dataHVACGlobal->SetPointErrorFlag) {
    1822            0 :                                 ShowSevereError(state, "Missing maximum humidity ratio setpoint (MaxHumRat) for ");
    1823            0 :                                 ShowContinueError(state, format("{}: {}", desicDehum.DehumType, desicDehum.Name));
    1824            0 :                                 ShowContinueError(state, format("Node Referenced={}", state.dataLoopNodes->NodeID(ControlNode)));
    1825            0 :                                 ShowContinueError(state,
    1826              :                                                   "use a Setpoint Manager to establish a \"MaxHumRat\" setpoint at the process air control node.");
    1827            0 :                                 ShowContinueError(state, "Or use EMS Actuator to establish a setpoint at the process air outlet node.");
    1828              :                             }
    1829              :                         }
    1830              :                     }
    1831              :                 }
    1832            2 :                 state.dataDesiccantDehumidifiers->MySetPointCheckFlag = false;
    1833              :             }
    1834       191658 :             int RegenInNode = desicDehum.RegenAirInNode;
    1835       191658 :             desicDehum.RegenAirInTemp = state.dataLoopNodes->Node(RegenInNode).Temp;
    1836       191658 :             desicDehum.RegenAirInMassFlowRate = state.dataLoopNodes->Node(RegenInNode).MassFlowRate;
    1837              : 
    1838       191658 :             desicDehum.ExhaustFanPower = 0.0;
    1839       191658 :             desicDehum.WaterRemoveRate = 0.0;
    1840       191658 :         } break;
    1841            0 :         default:
    1842            0 :             break;
    1843              :         }
    1844       283978 :     }
    1845              : 
    1846       283978 :     void ControlDesiccantDehumidifier(EnergyPlusData &state,
    1847              :                                       int const DesicDehumNum, // number of the current dehumidifier being simulated
    1848              :                                       Real64 &HumRatNeeded,    // process air leaving humidity ratio set by controller [kg water/kg air]
    1849              :                                       [[maybe_unused]] bool const FirstHVACIteration // TRUE if 1st HVAC simulation of system timestep !unused1208
    1850              :     )
    1851              :     {
    1852              : 
    1853              :         // SUBROUTINE INFORMATION:
    1854              :         //       AUTHOR         Michael J. Witte, GARD Analytics, Inc.
    1855              :         //                      for Gas Research Institute
    1856              :         //       DATE WRITTEN   March 2001
    1857              :         //       MODIFIED       Jan 2005 M. J. Witte, GARD Analytics, Inc.
    1858              :         //                        Add new control type option:
    1859              :         //                          NODE LEAVING HUMRAT SETPOINT:BYPASS
    1860              :         //                        Change existing control type to:
    1861              :         //                          FIXED LEAVING HUMRAT SETPOINT:BYPASS
    1862              :         //                        Work supported by ASHRAE research project 1254-RP
    1863              :         //                      June 2007 R. Raustad, FSEC
    1864              :         //                        Added new dehumidifier type -- DESICCANT DEHUMIDIFIER
    1865              : 
    1866              :         // PURPOSE OF THIS SUBROUTINE:
    1867              :         // This subroutine sets the output required from the dehumidifier
    1868              : 
    1869              :         // METHODOLOGY EMPLOYED:
    1870              :         // Uses a maximum humidity ratio setpoint to calculate required process
    1871              :         // leaving humidity ratio
    1872              : 
    1873              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1874              :         Real64 ProcAirMassFlowRate;  // process air mass flow rate [kg/s]
    1875              :         Real64 RegenAirMassFlowRate; // regen air mass flow rate [kg/s]
    1876              : 
    1877       283978 :         auto &desicDehum = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum);
    1878              : 
    1879       283978 :         ProcAirMassFlowRate = 0.0;
    1880       283978 :         RegenAirMassFlowRate = 0.0;
    1881       283978 :         bool UnitOn = true;
    1882              : 
    1883       283978 :         switch (desicDehum.DehumTypeCode) {
    1884        92320 :         case DesicDehumType::Solid: {
    1885        92320 :             if (desicDehum.HumRatSet <= 0.0) {
    1886            0 :                 UnitOn = false;
    1887              :             }
    1888        92320 :             ProcAirMassFlowRate = desicDehum.ProcAirInMassFlowRate;
    1889        92320 :             if (ProcAirMassFlowRate <= HVAC::SmallMassFlow) {
    1890           54 :                 UnitOn = false;
    1891              :             }
    1892              : 
    1893        92320 :             if (desicDehum.availSched->getCurrentVal() <= 0.0) {
    1894         4446 :                 UnitOn = false;
    1895              :             }
    1896              : 
    1897              :             // If incoming conditions are outside valid range for curve fits, then shut unit off, do not issue warnings
    1898              : 
    1899        92320 :             if (UnitOn) {
    1900        87874 :                 if ((desicDehum.ProcAirInTemp < desicDehum.MinProcAirInTemp) || (desicDehum.ProcAirInTemp > desicDehum.MaxProcAirInTemp)) {
    1901        31524 :                     UnitOn = false;
    1902              :                 }
    1903        87874 :                 if ((desicDehum.ProcAirInHumRat < desicDehum.MinProcAirInHumRat) || (desicDehum.ProcAirInHumRat > desicDehum.MaxProcAirInHumRat)) {
    1904        31524 :                     UnitOn = false;
    1905              :                 }
    1906              :             }
    1907              : 
    1908        92320 :             if (UnitOn) {
    1909              : 
    1910              :                 // perform the correct dehumidifier control strategy
    1911        56350 :                 switch (desicDehum.controlType) {
    1912        23182 :                 case DesicDehumCtrlType::FixedHumratBypass: {
    1913        23182 :                     HumRatNeeded = desicDehum.HumRatSet;
    1914        23182 :                     if (HumRatNeeded <= 0.0) {
    1915            0 :                         ShowSevereError(state, format("Dehumidifier:Desiccant:NoFans: {}", desicDehum.Name));
    1916            0 :                         ShowContinueError(state, format("Invalid Leaving Max Humidity Ratio Setpoint={:.8T}", HumRatNeeded));
    1917            0 :                         ShowFatalError(state, "must be > 0.0");
    1918              :                     }
    1919        23182 :                 } break;
    1920        33168 :                 case DesicDehumCtrlType::NodeHumratBypass: {
    1921        33168 :                     HumRatNeeded = state.dataLoopNodes->Node(desicDehum.ProcAirOutNode).HumRatMax;
    1922        33168 :                 } break;
    1923            0 :                 default: {
    1924            0 :                     ShowFatalError(state, format("Invalid control type in desiccant dehumidifier = {}", desicDehum.Name));
    1925            0 :                 } break;
    1926              :                 }
    1927              : 
    1928              :                 // Setpoint of zero indicates no load from setpoint manager max hum
    1929        56350 :                 if ((HumRatNeeded == 0.0) || (desicDehum.ProcAirInHumRat <= HumRatNeeded)) {
    1930          348 :                     HumRatNeeded = desicDehum.ProcAirInHumRat;
    1931              :                 }
    1932              :             } else {
    1933        35970 :                 HumRatNeeded = desicDehum.ProcAirInHumRat;
    1934              :             }
    1935              : 
    1936        92320 :         } break;
    1937       191658 :         case DesicDehumType::Generic: {
    1938       191658 :             ProcAirMassFlowRate = state.dataLoopNodes->Node(desicDehum.ProcAirInNode).MassFlowRate;
    1939       191658 :             if (ProcAirMassFlowRate <= HVAC::SmallMassFlow) {
    1940           18 :                 UnitOn = false;
    1941              :             }
    1942              : 
    1943       191658 :             if (desicDehum.availSched->getCurrentVal() <= 0.0) {
    1944            0 :                 UnitOn = false;
    1945              :             }
    1946              : 
    1947       191658 :             if (UnitOn) {
    1948       191640 :                 if (desicDehum.ControlNodeNum == desicDehum.ProcAirOutNode) {
    1949       191640 :                     HumRatNeeded = state.dataLoopNodes->Node(desicDehum.ControlNodeNum).HumRatMax;
    1950              :                 } else {
    1951            0 :                     if (state.dataLoopNodes->Node(desicDehum.ControlNodeNum).HumRatMax > 0.0) {
    1952            0 :                         HumRatNeeded = state.dataLoopNodes->Node(desicDehum.ControlNodeNum).HumRatMax -
    1953            0 :                                        (state.dataLoopNodes->Node(desicDehum.ControlNodeNum).HumRat -
    1954            0 :                                         state.dataLoopNodes->Node(desicDehum.ProcAirOutNode).HumRat);
    1955              :                     } else {
    1956            0 :                         HumRatNeeded = 0.0;
    1957              :                     }
    1958              :                 }
    1959              : 
    1960              :                 // Setpoint of zero indicates no load from setpoint manager max hum
    1961       191640 :                 if ((HumRatNeeded == 0.0) || (state.dataLoopNodes->Node(desicDehum.ProcAirInNode).HumRat <= HumRatNeeded)) {
    1962       187437 :                     HumRatNeeded = state.dataLoopNodes->Node(desicDehum.ProcAirInNode).HumRat;
    1963              :                 }
    1964              :             } else {
    1965           18 :                 HumRatNeeded = state.dataLoopNodes->Node(desicDehum.ProcAirInNode).HumRat;
    1966              :             }
    1967              : 
    1968       191658 :         } break;
    1969            0 :         default:
    1970            0 :             break;
    1971              :         }
    1972       283978 :     }
    1973              : 
    1974        92320 :     void CalcSolidDesiccantDehumidifier(EnergyPlusData &state,
    1975              :                                         int const DesicDehumNum,      // number of the current dehumidifier being simulated
    1976              :                                         Real64 const HumRatNeeded,    // process air leaving humidity ratio set by controller [kgWater/kgDryAir]
    1977              :                                         bool const FirstHVACIteration // TRUE if 1st HVAC simulation of system timestep
    1978              :     )
    1979              :     {
    1980              : 
    1981              :         // SUBROUTINE INFORMATION:
    1982              :         //       AUTHOR         Michael J. Witte, GARD Analytics, Inc.
    1983              :         //                      for Gas Research Institute
    1984              :         //       DATE WRITTEN   March 2001
    1985              : 
    1986              :         // PURPOSE OF THIS SUBROUTINE:
    1987              :         // Calculate the electricity consumption, regen heat requirements and the outlet
    1988              :         // conditions for a solid desiccant dehumidifier, given the inlet conditions and
    1989              :         // and the needed process leaving humidity ratio.
    1990              : 
    1991              :         // METHODOLOGY EMPLOYED:
    1992              :         // Given the entering conditions, the full-load outlet conditions are calculated.
    1993              :         // Adjust for part-load if required.
    1994              :         // Caclulate required regen energy and call regen coil and regen fan.
    1995              :         // Desiccant wheel leaving conditions and regen energy requirements are calculated
    1996              :         // from empirical curve fits.  The user can select either default built-in
    1997              :         // performance curves, or use custom user-defined curves.
    1998              : 
    1999              :         // REFERENCES:
    2000              :         // The default performance curves represent a commerical-grade solid desiccant
    2001              :         // wheel typical of HVAC applications in the early 1990's.  These curves were
    2002              :         // developed for Gas Research Institute by William W. Worek, University of Illinois
    2003              :         // at Chicago.
    2004              : 
    2005              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2006              : 
    2007              :         Real64 ProcAirOutHumRat; // process outlet air humidity ratio [kgWater/kgDryAir]
    2008              :         Real64 ProcAirOutTemp;   // process outlet air temperature [C]
    2009              :         Real64 QRegen;           // regen heat input rate requested from regen coil [W]
    2010              :         Real64 QDelivered;       // regen heat actually delivered by regen coil [W]
    2011              :         // REAL(r64) :: RegenAirInHumRat        ! regen inlet air humidity ratio [kgWater/kgDryAir]
    2012              :         Real64 RegenAirVel;          // regen air velocity [m/s]
    2013              :         Real64 RegenAirMassFlowRate; // regen air mass flow rate [kg/s]
    2014              :         Real64 SpecRegenEnergy;      // specific regen energy [J/kg of water removed]
    2015              :         Real64 ElecUseRate;          // electricity consumption rate [W]
    2016              : 
    2017              :         // Variables for hardwired coefficients for default performance model
    2018              : 
    2019              :         Real64 TC0;
    2020              :         Real64 TC1;
    2021              :         Real64 TC2;
    2022              :         Real64 TC3;
    2023              :         Real64 TC4;
    2024              :         Real64 TC5;
    2025              :         Real64 TC6;
    2026              :         Real64 TC7;
    2027              :         Real64 TC8;
    2028              :         Real64 TC9;
    2029              :         Real64 TC10;
    2030              :         Real64 TC11;
    2031              :         Real64 TC12;
    2032              :         Real64 TC13;
    2033              :         Real64 TC14;
    2034              :         Real64 TC15;
    2035              : 
    2036              :         Real64 WC0;
    2037              :         Real64 WC1;
    2038              :         Real64 WC2;
    2039              :         Real64 WC3;
    2040              :         Real64 WC4;
    2041              :         Real64 WC5;
    2042              :         Real64 WC6;
    2043              :         Real64 WC7;
    2044              :         Real64 WC8;
    2045              :         Real64 WC9;
    2046              :         Real64 WC10;
    2047              :         Real64 WC11;
    2048              :         Real64 WC12;
    2049              :         Real64 WC13;
    2050              :         Real64 WC14;
    2051              :         Real64 WC15;
    2052              : 
    2053              :         Real64 QC0;
    2054              :         Real64 QC1;
    2055              :         Real64 QC2;
    2056              :         Real64 QC3;
    2057              :         Real64 QC4;
    2058              :         Real64 QC5;
    2059              :         Real64 QC6;
    2060              :         Real64 QC7;
    2061              :         Real64 QC8;
    2062              :         Real64 QC9;
    2063              :         Real64 QC10;
    2064              :         Real64 QC11;
    2065              :         Real64 QC12;
    2066              :         Real64 QC13;
    2067              :         Real64 QC14;
    2068              :         Real64 QC15;
    2069              : 
    2070              :         Real64 RC0;
    2071              :         Real64 RC1;
    2072              :         Real64 RC2;
    2073              :         Real64 RC3;
    2074              :         Real64 RC4;
    2075              :         Real64 RC5;
    2076              :         Real64 RC6;
    2077              :         Real64 RC7;
    2078              :         Real64 RC8;
    2079              :         Real64 RC9;
    2080              :         Real64 RC10;
    2081              :         Real64 RC11;
    2082              :         Real64 RC12;
    2083              :         Real64 RC13;
    2084              :         Real64 RC14;
    2085              :         Real64 RC15;
    2086              : 
    2087        92320 :         auto &desicDehum = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum);
    2088              : 
    2089              :         // Setup internal variables for calculations
    2090              : 
    2091        92320 :         Real64 ProcAirInTemp = desicDehum.ProcAirInTemp;
    2092        92320 :         Real64 ProcAirInHumRat = desicDehum.ProcAirInHumRat;
    2093        92320 :         Real64 ProcAirMassFlowRate = desicDehum.ProcAirInMassFlowRate;
    2094        92320 :         Real64 ProcAirVel = desicDehum.NomProcAirVel;
    2095        92320 :         Real64 PartLoad = 0.0;
    2096              : 
    2097        92320 :         Real64 RegenAirInTemp = desicDehum.RegenAirInTemp;
    2098        92320 :         Real64 NomRegenTemp = desicDehum.NomRegenTemp;
    2099              : 
    2100              :         // Calculate min available process out humrat
    2101        92320 :         bool UnitOn = false;
    2102        92320 :         Real64 MinProcAirOutHumRat = 0.0; // MAX(MinProcAirOutHumRat,0.000857)
    2103              : 
    2104        92320 :         if (HumRatNeeded < ProcAirInHumRat) {
    2105              : 
    2106        56002 :             UnitOn = true;
    2107              : 
    2108        56002 :             switch (desicDehum.PerformanceModel_Num) { // Performance Model Part A
    2109        56002 :             case PerformanceModel::Default: {
    2110        56002 :                 WC0 = 0.0148880824323806;
    2111        56002 :                 WC1 = -0.000283393198398211;
    2112        56002 :                 WC2 = -0.87802168940547;
    2113        56002 :                 WC3 = -0.000713615831236411;
    2114        56002 :                 WC4 = 0.0311261188874622;
    2115        56002 :                 WC5 = 1.51738892142485e-06;
    2116        56002 :                 WC6 = 0.0287250198281021;
    2117        56002 :                 WC7 = 4.94796903231558e-06;
    2118        56002 :                 WC8 = 24.0771139652826;
    2119        56002 :                 WC9 = 0.000122270283927978;
    2120        56002 :                 WC10 = -0.0151657189566474;
    2121        56002 :                 WC11 = 3.91641393230322e-08;
    2122        56002 :                 WC12 = 0.126032651553348;
    2123        56002 :                 WC13 = 0.000391653854431574;
    2124        56002 :                 WC14 = 0.002160537360507;
    2125        56002 :                 WC15 = 0.00132732844211593;
    2126              : 
    2127        56002 :                 MinProcAirOutHumRat = WC0 + WC1 * ProcAirInTemp + WC2 * ProcAirInHumRat + WC3 * ProcAirVel + WC4 * ProcAirInTemp * ProcAirInHumRat +
    2128        56002 :                                       WC5 * ProcAirInTemp * ProcAirVel + WC6 * ProcAirInHumRat * ProcAirVel + WC7 * ProcAirInTemp * ProcAirInTemp +
    2129        56002 :                                       WC8 * ProcAirInHumRat * ProcAirInHumRat + WC9 * ProcAirVel * ProcAirVel +
    2130        56002 :                                       WC10 * ProcAirInTemp * ProcAirInTemp * ProcAirInHumRat * ProcAirInHumRat +
    2131        56002 :                                       WC11 * ProcAirInTemp * ProcAirInTemp * ProcAirVel * ProcAirVel +
    2132        56002 :                                       WC12 * ProcAirInHumRat * ProcAirInHumRat * ProcAirVel * ProcAirVel + WC13 * std::log(ProcAirInTemp) +
    2133        56002 :                                       WC14 * std::log(ProcAirInHumRat) + WC15 * std::log(ProcAirVel);
    2134              : 
    2135              :                 // limit to 6 grains/lb (0.000857 kg/kg)
    2136              : 
    2137        56002 :             } break;
    2138            0 :             case PerformanceModel::UserCurves: {
    2139            0 :                 MinProcAirOutHumRat = Curve::CurveValue(state, desicDehum.ProcHumRatCurvefTW, ProcAirInTemp, ProcAirInHumRat) *
    2140            0 :                                       Curve::CurveValue(state, desicDehum.ProcHumRatCurvefV, ProcAirVel);
    2141            0 :             } break;
    2142              : 
    2143            0 :             default: {
    2144              : 
    2145            0 :                 ShowFatalError(state, format("Invalid performance model in desiccant dehumidifier = {}", desicDehum.PerformanceModel_Num));
    2146            0 :             } break;
    2147              :             } // Performance Model Part A
    2148              : 
    2149        56002 :             MinProcAirOutHumRat = max(MinProcAirOutHumRat, 0.000857);
    2150              :         }
    2151              : 
    2152        92320 :         if (MinProcAirOutHumRat >= ProcAirInHumRat) {
    2153            0 :             UnitOn = false;
    2154              :         }
    2155              : 
    2156        92320 :         if (UnitOn) {
    2157              : 
    2158              :             // Calculate partload fraction of dehumidification capacity required to meet setpoint
    2159        56002 :             PartLoad = 1.0;
    2160        56002 :             if (MinProcAirOutHumRat < HumRatNeeded) {
    2161        37938 :                 PartLoad = (ProcAirInHumRat - HumRatNeeded) / (ProcAirInHumRat - MinProcAirOutHumRat);
    2162              :             }
    2163        56002 :             PartLoad = max(0.0, PartLoad);
    2164        56002 :             PartLoad = min(1.0, PartLoad);
    2165              : 
    2166        56002 :             switch (desicDehum.PerformanceModel_Num) { // Performance Model Part B
    2167        56002 :             case PerformanceModel::Default: {
    2168              :                 // Calculate leaving conditions
    2169        56002 :                 TC0 = -38.7782841989449;
    2170        56002 :                 TC1 = 2.0127655837628;
    2171        56002 :                 TC2 = 5212.49360216097;
    2172        56002 :                 TC3 = 15.2362536782665;
    2173        56002 :                 TC4 = -80.4910419759181;
    2174        56002 :                 TC5 = -0.105014122001509;
    2175        56002 :                 TC6 = -229.668673645144;
    2176        56002 :                 TC7 = -0.015424703743461;
    2177        56002 :                 TC8 = -69440.0689831847;
    2178        56002 :                 TC9 = -1.6686064694322;
    2179        56002 :                 TC10 = 38.5855718977592;
    2180        56002 :                 TC11 = 0.000196395381206009;
    2181        56002 :                 TC12 = 386.179386548324;
    2182        56002 :                 TC13 = -0.801959614172614;
    2183        56002 :                 TC14 = -3.33080986818745;
    2184        56002 :                 TC15 = -15.2034386065714;
    2185              : 
    2186        56002 :                 ProcAirOutTemp = TC0 + TC1 * ProcAirInTemp + TC2 * ProcAirInHumRat + TC3 * ProcAirVel + TC4 * ProcAirInTemp * ProcAirInHumRat +
    2187        56002 :                                  TC5 * ProcAirInTemp * ProcAirVel + TC6 * ProcAirInHumRat * ProcAirVel + TC7 * ProcAirInTemp * ProcAirInTemp +
    2188        56002 :                                  TC8 * ProcAirInHumRat * ProcAirInHumRat + TC9 * ProcAirVel * ProcAirVel +
    2189        56002 :                                  TC10 * ProcAirInTemp * ProcAirInTemp * ProcAirInHumRat * ProcAirInHumRat +
    2190        56002 :                                  TC11 * ProcAirInTemp * ProcAirInTemp * ProcAirVel * ProcAirVel +
    2191        56002 :                                  TC12 * ProcAirInHumRat * ProcAirInHumRat * ProcAirVel * ProcAirVel + TC13 * std::log(ProcAirInTemp) +
    2192        56002 :                                  TC14 * std::log(ProcAirInHumRat) + TC15 * std::log(ProcAirVel);
    2193              : 
    2194              :                 // Regen energy
    2195        56002 :                 QC0 = -27794046.6291107;
    2196        56002 :                 QC1 = -235725.171759615;
    2197        56002 :                 QC2 = 975461343.331328;
    2198        56002 :                 QC3 = -686069.373946731;
    2199        56002 :                 QC4 = -17717307.3766266;
    2200        56002 :                 QC5 = 31482.2539662489;
    2201        56002 :                 QC6 = 55296552.8260743;
    2202        56002 :                 QC7 = 6195.36070023868;
    2203        56002 :                 QC8 = -8304781359.40435;
    2204        56002 :                 QC9 = -188987.543809419;
    2205        56002 :                 QC10 = 3933449.40965846;
    2206        56002 :                 QC11 = -6.66122876558634;
    2207        56002 :                 QC12 = -349102295.417547;
    2208        56002 :                 QC13 = 83672.179730172;
    2209        56002 :                 QC14 = -6059524.33170538;
    2210        56002 :                 QC15 = 1220523.39525162;
    2211              : 
    2212        56002 :                 SpecRegenEnergy = QC0 + QC1 * ProcAirInTemp + QC2 * ProcAirInHumRat + QC3 * ProcAirVel + QC4 * ProcAirInTemp * ProcAirInHumRat +
    2213        56002 :                                   QC5 * ProcAirInTemp * ProcAirVel + QC6 * ProcAirInHumRat * ProcAirVel + QC7 * ProcAirInTemp * ProcAirInTemp +
    2214        56002 :                                   QC8 * ProcAirInHumRat * ProcAirInHumRat + QC9 * ProcAirVel * ProcAirVel +
    2215        56002 :                                   QC10 * ProcAirInTemp * ProcAirInTemp * ProcAirInHumRat * ProcAirInHumRat +
    2216        56002 :                                   QC11 * ProcAirInTemp * ProcAirInTemp * ProcAirVel * ProcAirVel +
    2217        56002 :                                   QC12 * ProcAirInHumRat * ProcAirInHumRat * ProcAirVel * ProcAirVel + QC13 * std::log(ProcAirInTemp) +
    2218        56002 :                                   QC14 * std::log(ProcAirInHumRat) + QC15 * std::log(ProcAirVel);
    2219              : 
    2220              :                 // Regen face velocity
    2221        56002 :                 RC0 = -4.67358908091488;
    2222        56002 :                 RC1 = 0.0654323095468338;
    2223        56002 :                 RC2 = 396.950518702316;
    2224        56002 :                 RC3 = 1.52610165426736;
    2225        56002 :                 RC4 = -11.3955868430328;
    2226        56002 :                 RC5 = 0.00520693906104437;
    2227        56002 :                 RC6 = 57.783645385621;
    2228        56002 :                 RC7 = -0.000464800668311693;
    2229        56002 :                 RC8 = -5958.78613212602;
    2230        56002 :                 RC9 = -0.205375818291012;
    2231        56002 :                 RC10 = 5.26762675442845;
    2232        56002 :                 RC11 = -8.88452553055039e-05;
    2233        56002 :                 RC12 = -182.382479369311;
    2234        56002 :                 RC13 = -0.100289774002047;
    2235        56002 :                 RC14 = -0.486980507964251;
    2236        56002 :                 RC15 = -0.972715425435447;
    2237              : 
    2238        56002 :                 RegenAirVel = RC0 + RC1 * ProcAirInTemp + RC2 * ProcAirInHumRat + RC3 * ProcAirVel + RC4 * ProcAirInTemp * ProcAirInHumRat +
    2239        56002 :                               RC5 * ProcAirInTemp * ProcAirVel + RC6 * ProcAirInHumRat * ProcAirVel + RC7 * ProcAirInTemp * ProcAirInTemp +
    2240        56002 :                               RC8 * ProcAirInHumRat * ProcAirInHumRat + RC9 * ProcAirVel * ProcAirVel +
    2241        56002 :                               RC10 * ProcAirInTemp * ProcAirInTemp * ProcAirInHumRat * ProcAirInHumRat +
    2242        56002 :                               RC11 * ProcAirInTemp * ProcAirInTemp * ProcAirVel * ProcAirVel +
    2243        56002 :                               RC12 * ProcAirInHumRat * ProcAirInHumRat * ProcAirVel * ProcAirVel + RC13 * std::log(ProcAirInTemp) +
    2244        56002 :                               RC14 * std::log(ProcAirInHumRat) + RC15 * std::log(ProcAirVel);
    2245              : 
    2246        56002 :             } break;
    2247            0 :             case PerformanceModel::UserCurves: {
    2248              : 
    2249            0 :                 ProcAirOutTemp = Curve::CurveValue(state, desicDehum.ProcDryBulbCurvefTW, ProcAirInTemp, ProcAirInHumRat) *
    2250            0 :                                  Curve::CurveValue(state, desicDehum.ProcDryBulbCurvefV, ProcAirVel);
    2251              : 
    2252            0 :                 SpecRegenEnergy = Curve::CurveValue(state, desicDehum.RegenEnergyCurvefTW, ProcAirInTemp, ProcAirInHumRat) *
    2253            0 :                                   Curve::CurveValue(state, desicDehum.RegenEnergyCurvefV, ProcAirVel);
    2254              : 
    2255            0 :                 RegenAirVel = Curve::CurveValue(state, desicDehum.RegenVelCurvefTW, ProcAirInTemp, ProcAirInHumRat) *
    2256            0 :                               Curve::CurveValue(state, desicDehum.RegenVelCurvefV, ProcAirVel);
    2257              : 
    2258            0 :             } break;
    2259            0 :             default: {
    2260              : 
    2261            0 :                 ShowFatalError(state, format("Invalid performance model in desiccant dehumidifier = {}", desicDehum.PerformanceModel_Num));
    2262              : 
    2263              :                 // Suppress uninitialized warnings
    2264            0 :                 ProcAirOutTemp = 0.0;
    2265            0 :                 SpecRegenEnergy = 0.0;
    2266            0 :                 RegenAirVel = 0.0;
    2267            0 :             } break;
    2268              :             } // Performance Model Part B
    2269              : 
    2270        56002 :             ProcAirOutTemp = (1 - PartLoad) * ProcAirInTemp + (PartLoad)*ProcAirOutTemp;
    2271              : 
    2272        56002 :             ProcAirOutHumRat = (1 - PartLoad) * ProcAirInHumRat + (PartLoad)*MinProcAirOutHumRat;
    2273              : 
    2274              :             // Calculate water removal
    2275        56002 :             desicDehum.WaterRemoveRate = ProcAirMassFlowRate * (ProcAirInHumRat - ProcAirOutHumRat);
    2276              : 
    2277              :             // Adjust for regen inlet temperature
    2278        56002 :             SpecRegenEnergy *= (NomRegenTemp - RegenAirInTemp) / (NomRegenTemp - ProcAirInTemp);
    2279        56002 :             SpecRegenEnergy = max(SpecRegenEnergy, 0.0);
    2280        56002 :             QRegen = SpecRegenEnergy * desicDehum.WaterRemoveRate;
    2281              : 
    2282              :             // Above curves are based on a 90deg regen angle and 245deg process air angle
    2283        56002 :             RegenAirMassFlowRate = ProcAirMassFlowRate * 90.0 / 245.0 * RegenAirVel / ProcAirVel;
    2284              : 
    2285        56002 :             ElecUseRate = desicDehum.NomRotorPower;
    2286              : 
    2287              :         } else { // Unit is off
    2288              : 
    2289        36318 :             ProcAirOutTemp = ProcAirInTemp;
    2290        36318 :             ProcAirOutHumRat = ProcAirInHumRat;
    2291        36318 :             SpecRegenEnergy = 0.0;
    2292        36318 :             QRegen = 0.0;
    2293        36318 :             ElecUseRate = 0.0;
    2294        36318 :             RegenAirVel = 0.0;
    2295        36318 :             RegenAirMassFlowRate = 0.0;
    2296        36318 :             desicDehum.WaterRemoveRate = 0.0;
    2297        36318 :             PartLoad = 0.0;
    2298              : 
    2299              :         } // UnitOn/Off
    2300              : 
    2301              :         // Set regen mass flow
    2302        92320 :         state.dataLoopNodes->Node(desicDehum.RegenFanInNode).MassFlowRate = RegenAirMassFlowRate;
    2303        92320 :         state.dataLoopNodes->Node(desicDehum.RegenFanInNode).MassFlowRateMaxAvail = RegenAirMassFlowRate;
    2304              :         // Call regen fan
    2305        92320 :         state.dataFans->fans(desicDehum.RegenFanIndex)->simulate(state, FirstHVACIteration, _, _);
    2306              : 
    2307              :         // Call regen heating coil
    2308        92320 :         CalcNonDXHeatingCoils(state, DesicDehumNum, FirstHVACIteration, QRegen, QDelivered);
    2309              : 
    2310              :         // Verify is requestd flow was delivered (must do after heating coil has executed to pass flow to RegenAirInNode)
    2311        92320 :         if (state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate != RegenAirMassFlowRate) {
    2312              :             // Initialize standard air density
    2313            0 :             ShowRecurringSevereErrorAtEnd(state,
    2314              :                                           "Improper flow delivered by desiccant regen fan - RESULTS INVALID! Check regen fan capacity and schedule.",
    2315            0 :                                           desicDehum.RegenFanErrorIndex1);
    2316            0 :             ShowRecurringContinueErrorAtEnd(state, desicDehum.DehumType + '=' + desicDehum.Name, desicDehum.RegenFanErrorIndex2);
    2317            0 :             ShowRecurringContinueErrorAtEnd(
    2318              :                 state,
    2319            0 :                 format("Flow requested [m3/s] from {} = {}", HVAC::fanTypeNames[(int)desicDehum.regenFanType], desicDehum.RegenFanName),
    2320            0 :                 desicDehum.RegenFanErrorIndex3,
    2321            0 :                 (RegenAirMassFlowRate / state.dataEnvrn->StdRhoAir));
    2322            0 :             ShowRecurringContinueErrorAtEnd(
    2323              :                 state,
    2324              :                 "Flow request varied from delivered by [m3/s]",
    2325            0 :                 desicDehum.RegenFanErrorIndex4,
    2326            0 :                 ((RegenAirMassFlowRate - state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate) / state.dataEnvrn->StdRhoAir),
    2327            0 :                 ((RegenAirMassFlowRate - state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate) / state.dataEnvrn->StdRhoAir));
    2328              :         }
    2329              : 
    2330              :         // Verify is requestd heating was delivered
    2331        92320 :         if (QDelivered < QRegen) {
    2332            0 :             ShowRecurringSevereErrorAtEnd(
    2333              :                 state,
    2334              :                 "Inadequate heat delivered by desiccant regen coil - RESULTS INVALID! Check regen coil capacity and schedule.",
    2335            0 :                 desicDehum.RegenCapErrorIndex1);
    2336            0 :             ShowRecurringContinueErrorAtEnd(state, desicDehum.DehumType + '=' + desicDehum.Name, desicDehum.RegenCapErrorIndex2);
    2337            0 :             ShowRecurringContinueErrorAtEnd(state,
    2338            0 :                                             format("Load requested [W] from {} = {}", desicDehum.RegenCoilType, desicDehum.RegenCoilName),
    2339            0 :                                             desicDehum.RegenCapErrorIndex3,
    2340              :                                             QRegen);
    2341            0 :             ShowRecurringContinueErrorAtEnd(state, "Load request exceeded delivered by [W]", desicDehum.RegenCapErrorIndex4, (QRegen - QDelivered));
    2342              :         }
    2343              : 
    2344        92320 :         desicDehum.SpecRegenEnergy = SpecRegenEnergy;
    2345        92320 :         desicDehum.QRegen = QRegen;
    2346        92320 :         desicDehum.ElecUseRate = ElecUseRate;
    2347        92320 :         desicDehum.PartLoad = PartLoad;
    2348              : 
    2349        92320 :         desicDehum.ProcAirOutMassFlowRate = ProcAirMassFlowRate;
    2350        92320 :         desicDehum.ProcAirOutTemp = ProcAirOutTemp;
    2351        92320 :         desicDehum.ProcAirOutHumRat = ProcAirOutHumRat;
    2352        92320 :         desicDehum.ProcAirOutEnthalpy = Psychrometrics::PsyHFnTdbW(ProcAirOutTemp, ProcAirOutHumRat);
    2353        92320 :         desicDehum.RegenAirInMassFlowRate = RegenAirMassFlowRate;
    2354        92320 :         desicDehum.RegenAirVel = RegenAirVel;
    2355        92320 :     }
    2356              : 
    2357       191658 :     void CalcGenericDesiccantDehumidifier(EnergyPlusData &state,
    2358              :                                           int const DesicDehumNum,      // number of the current dehumidifier being simulated
    2359              :                                           Real64 const HumRatNeeded,    // process air leaving humidity ratio set by controller [kg water/kg air]
    2360              :                                           bool const FirstHVACIteration // TRUE if 1st HVAC simulation of system timestep
    2361              :     )
    2362              :     {
    2363              : 
    2364              :         // SUBROUTINE INFORMATION:
    2365              :         //       AUTHOR         Mangesh Basarkar, FSEC
    2366              :         //       DATE WRITTEN   May 2007
    2367              : 
    2368              :         // PURPOSE OF THIS SUBROUTINE:
    2369              :         // Calculate the electricity consumption, regen heat requirements and the outlet
    2370              :         // conditions for a desiccant dehumidifier, given the inlet conditions,
    2371              :         // DX coil part-load ratio, and/or the needed process leaving humidity ratio.
    2372              : 
    2373              :         // METHODOLOGY EMPLOYED:
    2374              :         // Given the entering conditions, the full-load outlet conditions are calculated.
    2375              :         // Adjust for part-load if required.
    2376              :         // Calculate the required regen energy and call the regen coil and the regen fan.
    2377              : 
    2378              :         // REFERENCES:
    2379              :         // Kosar, D. 2006. Dehumidification Enhancements, ASHRAE Journal, Vol. 48, No. 2, February 2006.
    2380              :         // Kosar, D. et al. 2006. Dehumidification Enhancement of Direct Expansion Systems Through Component
    2381              :         //   Augmentation of the Cooling Coil. 15th Symposium on Improving Building Systems in Hot and Humid
    2382              :         //   Climates, July 24-26, 2006.
    2383              : 
    2384              :         // SUBROUTINE PARAMETER DEFINITIONS:
    2385       191658 :         Real64 constexpr MinVolFlowPerRatedTotQ(0.00002684); // m3/s per W = 200 cfm/ton,
    2386              :         // min vol flow per rated evaporator capacity
    2387              : 
    2388              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2389              :         Real64 DDPartLoadRatio;        // fraction of dehumidification capacity required to meet setpoint
    2390              :         Real64 MassFlowRateNew;        // new required mass flow rate calculated to keep regen setpoint temperature (kg/s)
    2391              :         Real64 CondenserWasteHeat;     // Condenser waste heat (W)
    2392              :         Real64 CpAir;                  // Specific heat of air (J/kg-K)
    2393              :         Real64 NewRegenInTemp;         // new temp calculated from condenser waste heat (C)
    2394              :         Real64 ExhaustFanMassFlowRate; // exhaust fan mass flow rate (kg/s)
    2395              :         Real64 ExhaustFanPLR;          // exhaust fan run time fraction calculated from new mass flow rate for regen side
    2396              :         Real64 ExhaustFanPowerMod;     // used to calculate exhaust fan power from flow fraction
    2397              :         Real64 VolFlowPerRatedTotQ;    // flow rate per rated total cooling capacity of the companion coil (m3/s/W)
    2398              :         Real64 FanDeltaT;              // used to account for fan heat when calculating regeneration heater energy (C)
    2399              :         Real64 OnOffFanPLF;            // save air loop fan part load fracton while calculating exhaust fan power
    2400              :         Real64 RegenSetPointTemp;      // regeneration temperature setpoint (C)
    2401              :         int RegenCoilIndex;            // index to regeneration heating coil, 0 when not used
    2402              :         int CompanionCoilIndexNum;     // index for companion DX cooling coil, 0 when DX coil is not used
    2403              :         bool UnitOn;                   // unit on flag
    2404              :         //  LOGICAL       :: SimFlag                    ! used to turn off additional simulation if DX Coil is off
    2405              :         Real64 QRegen_OASysFanAdjust; // temporary variable used to adjust regen heater load during iteration
    2406              : 
    2407       191658 :         auto &desicDehum = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum);
    2408       191658 :         auto &QRegen(state.dataDesiccantDehumidifiers->QRegen);
    2409              : 
    2410       191658 :         UnitOn = false;
    2411       191658 :         DDPartLoadRatio = 0.0;
    2412       191658 :         RegenCoilIndex = desicDehum.RegenCoilIndex;
    2413       191658 :         FanDeltaT = 0.0;
    2414       191658 :         RegenSetPointTemp = desicDehum.RegenSetPointTemp;
    2415       191658 :         ExhaustFanMassFlowRate = 0.0;
    2416              : 
    2417              :         // Save OnOffFanPartLoadFraction while performing exhaust fan calculations
    2418       191658 :         OnOffFanPLF = state.dataHVACGlobal->OnOffFanPartLoadFraction;
    2419       191658 :         state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
    2420              : 
    2421       191658 :         if (desicDehum.CoilUpstreamOfProcessSide == Selection::Yes) {
    2422              :             // Cooling coil directly upstream of desiccant dehumidifier, dehumidifier runs in tandem with DX coil
    2423              : 
    2424        15495 :             CompanionCoilIndexNum = desicDehum.DXCoilIndex;
    2425              :         } else {
    2426              :             // desiccant dehumidifier determines its own PLR
    2427       176163 :             CompanionCoilIndexNum = 0;
    2428              :         }
    2429              : 
    2430       191658 :         if (HumRatNeeded < state.dataLoopNodes->Node(desicDehum.ProcAirInNode).HumRat) {
    2431         4203 :             UnitOn = true;
    2432              :         }
    2433              : 
    2434       191658 :         if (desicDehum.CoilUpstreamOfProcessSide == Selection::Yes) {
    2435        15495 :             if ((desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingSingleSpeed) ||
    2436         6632 :                 (desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
    2437         8863 :                 if (state.dataDXCoils->DXCoilPartLoadRatio(desicDehum.DXCoilIndex) == 0.0) {
    2438         3052 :                     UnitOn = false;
    2439              :                 }
    2440              :             }
    2441              :         }
    2442              : 
    2443       191658 :         if (UnitOn) {
    2444              : 
    2445         3268 :             if (desicDehum.RegenInletIsOutsideAirNode) {
    2446         1846 :                 if (desicDehum.HXTypeNum == BalancedHX) {
    2447         1846 :                     state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate =
    2448         1846 :                         state.dataLoopNodes->Node(desicDehum.ProcAirInNode).MassFlowRate;
    2449         1846 :                     state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRateMaxAvail =
    2450         1846 :                         state.dataLoopNodes->Node(desicDehum.ProcAirInNode).MassFlowRate;
    2451              :                 }
    2452              :             }
    2453              : 
    2454              :             // Get conditions from DX Coil condenser if present (DXCoilIndex verified > 0 in GetInput)
    2455         3268 :             if (desicDehum.Preheat == Selection::Yes) {
    2456              : 
    2457              :                 //     condenser waste heat is proportional to DX coil PLR
    2458         1846 :                 if ((desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingSingleSpeed) ||
    2459          477 :                     (desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
    2460         1369 :                     CondenserWasteHeat = state.dataHeatBal->HeatReclaimDXCoil(desicDehum.DXCoilIndex).AvailCapacity;
    2461         1369 :                     state.dataHeatBal->HeatReclaimDXCoil(desicDehum.DXCoilIndex).AvailCapacity = 0.0;
    2462          477 :                 } else if (desicDehum.coolingCoil_TypeNum == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    2463          477 :                     CondenserWasteHeat = state.dataHeatBal->HeatReclaimVS_Coil(desicDehum.DXCoilIndex).AvailCapacity;
    2464          477 :                     state.dataHeatBal->HeatReclaimVS_Coil(desicDehum.DXCoilIndex).AvailCapacity = 0.0;
    2465              :                 }
    2466              : 
    2467         1846 :                 CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(desicDehum.CondenserInletNode).HumRat);
    2468              : 
    2469         1846 :                 if (desicDehum.regenFanPlace == HVAC::FanPlace::BlowThru) {
    2470            0 :                     state.dataFans->fans(desicDehum.RegenFanIndex)->simulate(state, FirstHVACIteration, _, _);
    2471            0 :                     FanDeltaT =
    2472            0 :                         state.dataLoopNodes->Node(desicDehum.RegenFanOutNode).Temp - state.dataLoopNodes->Node(desicDehum.RegenFanInNode).Temp;
    2473              :                     //       Adjust setpoint to account for fan heat
    2474            0 :                     RegenSetPointTemp -= FanDeltaT;
    2475              :                 }
    2476              : 
    2477              :                 //     CompanionCoilIndexNum .GT. 0 means the same thing as desicDehum%CoilUpstreamOfProcessSide == Yes
    2478         1846 :                 if (CompanionCoilIndexNum > 0) {
    2479              : 
    2480              :                     //     calculate PLR and actual condenser outlet node (regen inlet node) temperature
    2481         1846 :                     if ((desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingSingleSpeed) ||
    2482          477 :                         (desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
    2483         1369 :                         DDPartLoadRatio = state.dataDXCoils->DXCoilPartLoadRatio(desicDehum.DXCoilIndex);
    2484         2738 :                         if (state.dataDXCoils->DXCoilFanOp(desicDehum.DXCoilIndex) == HVAC::FanOp::Continuous) {
    2485         1369 :                             NewRegenInTemp =
    2486         1369 :                                 state.dataLoopNodes->Node(desicDehum.CondenserInletNode).Temp +
    2487         1369 :                                 CondenserWasteHeat / (CpAir * (state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate) * DDPartLoadRatio);
    2488         1369 :                             CondenserWasteHeat /= DDPartLoadRatio;
    2489              :                         } else {
    2490            0 :                             NewRegenInTemp = state.dataLoopNodes->Node(desicDehum.CondenserInletNode).Temp +
    2491            0 :                                              CondenserWasteHeat / (CpAir * (state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate));
    2492              :                         }
    2493          477 :                     } else if (desicDehum.coolingCoil_TypeNum == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    2494          477 :                         DDPartLoadRatio = 1.0; // condenser waste heat already includes modulation down
    2495          477 :                         NewRegenInTemp = state.dataLoopNodes->Node(desicDehum.CondenserInletNode).Temp +
    2496          477 :                                          CondenserWasteHeat / (CpAir * (state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate));
    2497              :                     } else {
    2498            0 :                         NewRegenInTemp = state.dataLoopNodes->Node(desicDehum.CondenserInletNode).Temp +
    2499            0 :                                          CondenserWasteHeat / (CpAir * (state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate));
    2500              :                     }
    2501              :                 } else {
    2502            0 :                     NewRegenInTemp = state.dataLoopNodes->Node(desicDehum.CondenserInletNode).Temp +
    2503            0 :                                      CondenserWasteHeat / (CpAir * (state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate));
    2504              :                 }
    2505              : 
    2506         1846 :                 state.dataLoopNodes->Node(desicDehum.RegenAirInNode).Temp = NewRegenInTemp;
    2507         1846 :                 state.dataLoopNodes->Node(desicDehum.RegenAirInNode).Enthalpy = Psychrometrics::PsyHFnTdbW(
    2508         1846 :                     state.dataLoopNodes->Node(desicDehum.RegenAirInNode).Temp, state.dataLoopNodes->Node(desicDehum.RegenAirInNode).HumRat);
    2509         1846 :                 MassFlowRateNew = 0.0;
    2510              : 
    2511         1846 :                 if (desicDehum.ExhaustFanMaxVolFlowRate > 0) {
    2512              : 
    2513              :                     //       calculate mass flow rate required to maintain regen inlet setpoint temp
    2514         1846 :                     if (NewRegenInTemp > RegenSetPointTemp) {
    2515         1369 :                         if (RegenSetPointTemp - state.dataLoopNodes->Node(desicDehum.CondenserInletNode).Temp != 0.0) {
    2516         1369 :                             MassFlowRateNew = max(0.0,
    2517              :                                                   CondenserWasteHeat /
    2518         1369 :                                                       (CpAir * (RegenSetPointTemp - state.dataLoopNodes->Node(desicDehum.CondenserInletNode).Temp)));
    2519              :                         } else {
    2520            0 :                             MassFlowRateNew = state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate;
    2521              :                         }
    2522              :                     }
    2523              : 
    2524              :                     //       calculate exhaust fan mass flow rate and new regen inlet temperature (may not be at setpoint)
    2525         1846 :                     if (MassFlowRateNew > state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate) {
    2526         1369 :                         ExhaustFanMassFlowRate = MassFlowRateNew - state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate;
    2527         1369 :                         ExhaustFanMassFlowRate = max(0.0, min(ExhaustFanMassFlowRate, desicDehum.ExhaustFanMaxMassFlowRate));
    2528              : 
    2529         1369 :                         state.dataLoopNodes->Node(desicDehum.RegenAirInNode).Temp =
    2530         1369 :                             state.dataLoopNodes->Node(desicDehum.CondenserInletNode).Temp +
    2531         1369 :                             CondenserWasteHeat /
    2532         1369 :                                 (CpAir * (state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate + ExhaustFanMassFlowRate));
    2533         1369 :                         state.dataLoopNodes->Node(desicDehum.RegenAirInNode).HumRat = state.dataLoopNodes->Node(desicDehum.CondenserInletNode).HumRat;
    2534         1369 :                         state.dataLoopNodes->Node(desicDehum.RegenAirInNode).Enthalpy = Psychrometrics::PsyHFnTdbW(
    2535         1369 :                             state.dataLoopNodes->Node(desicDehum.RegenAirInNode).Temp, state.dataLoopNodes->Node(desicDehum.RegenAirInNode).HumRat);
    2536              :                     }
    2537              :                 }
    2538              : 
    2539         1846 :                 if (RegenCoilIndex > 0) {
    2540         1846 :                     if (NewRegenInTemp < RegenSetPointTemp) {
    2541          477 :                         CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(desicDehum.RegenAirInNode).HumRat);
    2542              :                     }
    2543         3692 :                     QRegen = max(0.0,
    2544         1846 :                                  (CpAir * state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate *
    2545         1846 :                                   (RegenSetPointTemp - state.dataLoopNodes->Node(desicDehum.RegenAirInNode).Temp)));
    2546         1846 :                     if (QRegen == 0.0) {
    2547         1303 :                         QRegen = -1.0;
    2548              :                     }
    2549              :                 }
    2550              : 
    2551              :                 //     CompanionCoilIndexNum .EQ. 0 means the same thing as desicDehum%CoilUpstreamOfProcessSide == No
    2552         1846 :                 if (CompanionCoilIndexNum == 0) {
    2553              : 
    2554            0 :                     if (RegenCoilIndex > 0) {
    2555              : 
    2556            0 :                         QRegen_OASysFanAdjust = QRegen;
    2557            0 :                         if (desicDehum.regenFanPlace == HVAC::FanPlace::BlowThru) {
    2558            0 :                             if (state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate > 0.0) {
    2559              :                                 //             For VAV systems, fan may restrict air flow during iteration. Adjust QRegen proportional to Mdot
    2560              :                                 //             reduction through fan
    2561            0 :                                 QRegen_OASysFanAdjust *= state.dataLoopNodes->Node(desicDehum.RegenFanOutNode).MassFlowRate /
    2562            0 :                                                          state.dataLoopNodes->Node(desicDehum.RegenFanInNode).MassFlowRate;
    2563              :                             }
    2564              :                         }
    2565              : 
    2566            0 :                         CalcNonDXHeatingCoils(state, DesicDehumNum, FirstHVACIteration, QRegen_OASysFanAdjust);
    2567              :                     }
    2568              : 
    2569            0 :                     HeatRecovery::SimHeatRecovery(state,
    2570              :                                                   desicDehum.HXName,
    2571              :                                                   FirstHVACIteration,
    2572            0 :                                                   desicDehum.CompIndex,
    2573              :                                                   HVAC::FanOp::Continuous,
    2574            0 :                                                   1.0,
    2575            0 :                                                   true,
    2576              :                                                   CompanionCoilIndexNum,
    2577            0 :                                                   desicDehum.RegenInletIsOutsideAirNode,
    2578              :                                                   _,
    2579              :                                                   _,
    2580            0 :                                                   desicDehum.coolingCoil_TypeNum);
    2581              : 
    2582              :                     //       calculate desiccant part-load ratio
    2583            0 :                     if (state.dataLoopNodes->Node(desicDehum.ProcAirInNode).HumRat != state.dataLoopNodes->Node(desicDehum.ProcAirOutNode).HumRat) {
    2584            0 :                         DDPartLoadRatio = (state.dataLoopNodes->Node(desicDehum.ProcAirInNode).HumRat - HumRatNeeded) /
    2585            0 :                                           (state.dataLoopNodes->Node(desicDehum.ProcAirInNode).HumRat -
    2586            0 :                                            state.dataLoopNodes->Node(desicDehum.ProcAirOutNode).HumRat);
    2587            0 :                         DDPartLoadRatio = max(0.0, min(1.0, DDPartLoadRatio));
    2588              :                     } else {
    2589            0 :                         DDPartLoadRatio = 1.0;
    2590              :                     }
    2591              :                 }
    2592              : 
    2593         1846 :                 if (ExhaustFanMassFlowRate > 0.0) {
    2594              : 
    2595              :                     //       calculate exhaust fan mass flow rate due to desiccant system operation
    2596         1369 :                     ExhaustFanMassFlowRate *= DDPartLoadRatio;
    2597              : 
    2598              :                     //       calculate exhaust fan PLR due to desiccant system operation
    2599         1369 :                     ExhaustFanPLR = ExhaustFanMassFlowRate / desicDehum.ExhaustFanMaxMassFlowRate;
    2600              : 
    2601              :                     //       find exhaust fan power multiplier using exhaust fan part-load ratio
    2602         1369 :                     if (desicDehum.ExhaustFanCurveIndex > 0) {
    2603         1369 :                         ExhaustFanPowerMod = min(1.0, max(0.0, Curve::CurveValue(state, desicDehum.ExhaustFanCurveIndex, ExhaustFanPLR)));
    2604              :                     } else {
    2605            0 :                         ExhaustFanPowerMod = 1.0;
    2606              :                     }
    2607              : 
    2608              :                     //       calculate exhaust fan power due to desiccant operation
    2609         1369 :                     desicDehum.ExhaustFanPower = desicDehum.ExhaustFanMaxPower * ExhaustFanPowerMod;
    2610              :                 }
    2611              : 
    2612              :             } else { // ELSE for IF(desicDehum%Preheat == Yes)THEN
    2613              : 
    2614         1422 :                 if (state.dataLoopNodes->Node(desicDehum.ProcAirInNode).HumRat > HumRatNeeded) {
    2615              : 
    2616              :                     //       Get Full load output of desiccant wheel
    2617         1422 :                     if (desicDehum.regenFanPlace == HVAC::FanPlace::BlowThru) {
    2618            0 :                         state.dataFans->fans(desicDehum.RegenFanIndex)->simulate(state, FirstHVACIteration, _, _);
    2619              : 
    2620            0 :                         FanDeltaT =
    2621            0 :                             state.dataLoopNodes->Node(desicDehum.RegenFanOutNode).Temp - state.dataLoopNodes->Node(desicDehum.RegenFanInNode).Temp;
    2622            0 :                         RegenSetPointTemp -= FanDeltaT;
    2623              :                     }
    2624              : 
    2625         1422 :                     if (RegenCoilIndex > 0) {
    2626         1422 :                         CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(desicDehum.RegenAirInNode).HumRat);
    2627         2844 :                         QRegen = max(0.0,
    2628         1422 :                                      (CpAir * state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate *
    2629         1422 :                                       (RegenSetPointTemp - state.dataLoopNodes->Node(desicDehum.RegenAirInNode).Temp)));
    2630              : 
    2631         1422 :                         QRegen_OASysFanAdjust = QRegen;
    2632         1422 :                         if (desicDehum.regenFanPlace == HVAC::FanPlace::BlowThru) {
    2633            0 :                             if (state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate > 0.0) {
    2634              :                                 //             For VAV systems, fan may restrict air flow during iteration. Adjust QRegen proportional to Mdot
    2635              :                                 //             reduction through fan
    2636            0 :                                 QRegen_OASysFanAdjust *= state.dataLoopNodes->Node(desicDehum.RegenFanOutNode).MassFlowRate /
    2637            0 :                                                          state.dataLoopNodes->Node(desicDehum.RegenFanInNode).MassFlowRate;
    2638              :                             }
    2639              :                         }
    2640              : 
    2641         1422 :                         if (QRegen_OASysFanAdjust == 0.0) {
    2642            0 :                             QRegen_OASysFanAdjust = -1.0;
    2643              :                         }
    2644         1422 :                         CalcNonDXHeatingCoils(state, DesicDehumNum, FirstHVACIteration, QRegen_OASysFanAdjust);
    2645              :                     }
    2646              : 
    2647              :                     //       CompanionCoilIndexNum .EQ. 0 means the same thing as desicDehum%CoilUpstreamOfProcessSide == No
    2648         1422 :                     if (CompanionCoilIndexNum == 0) {
    2649         5688 :                         HeatRecovery::SimHeatRecovery(state,
    2650              :                                                       desicDehum.HXName,
    2651              :                                                       FirstHVACIteration,
    2652         1422 :                                                       desicDehum.CompIndex,
    2653              :                                                       HVAC::FanOp::Continuous,
    2654         2844 :                                                       1.0,
    2655         2844 :                                                       true,
    2656              :                                                       CompanionCoilIndexNum,
    2657         1422 :                                                       desicDehum.RegenInletIsOutsideAirNode,
    2658              :                                                       _,
    2659              :                                                       _,
    2660         1422 :                                                       desicDehum.coolingCoil_TypeNum);
    2661              : 
    2662              :                         //         calculate desiccant part-load ratio
    2663         1422 :                         if (state.dataLoopNodes->Node(desicDehum.ProcAirInNode).HumRat !=
    2664         1422 :                             state.dataLoopNodes->Node(desicDehum.ProcAirOutNode).HumRat) {
    2665         1422 :                             DDPartLoadRatio = (state.dataLoopNodes->Node(desicDehum.ProcAirInNode).HumRat - HumRatNeeded) /
    2666         1422 :                                               (state.dataLoopNodes->Node(desicDehum.ProcAirInNode).HumRat -
    2667         1422 :                                                state.dataLoopNodes->Node(desicDehum.ProcAirOutNode).HumRat);
    2668         1422 :                             DDPartLoadRatio = max(0.0, min(1.0, DDPartLoadRatio));
    2669              :                         } else {
    2670            0 :                             DDPartLoadRatio = 1.0;
    2671              :                         }
    2672              :                     } else {
    2673            0 :                         if ((desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingSingleSpeed) ||
    2674            0 :                             (desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
    2675            0 :                             DDPartLoadRatio = state.dataDXCoils->DXCoilPartLoadRatio(desicDehum.DXCoilIndex);
    2676            0 :                         } else if (desicDehum.coolingCoil_TypeNum == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    2677            0 :                             DDPartLoadRatio = 1.0; // condenser waste heat already includes modulation down
    2678              :                         }
    2679              :                     }
    2680              :                 } else { // ELSE for IF(state.dataLoopNodes->Node(desicDehum%ProcAirInNode)%HumRat .GT. HumRatNeeded)THEN
    2681            0 :                     DDPartLoadRatio = 0.0;
    2682              :                 } // END IF for IF(state.dataLoopNodes->Node(desicDehum%ProcAirInNode)%HumRat .GT. HumRatNeeded)THEN
    2683              : 
    2684              :             } // END IF for IF(desicDehum%Preheat == Yes)THEN
    2685              : 
    2686         3268 :             desicDehum.PartLoad = DDPartLoadRatio;
    2687         3268 :             QRegen_OASysFanAdjust = QRegen;
    2688              : 
    2689              :             // set average regeneration air mass flow rate based on desiccant cycling ratio (DDPartLoadRatio)
    2690         3268 :             if (desicDehum.RegenInletIsOutsideAirNode) {
    2691         1846 :                 state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate *= DDPartLoadRatio;
    2692              : 
    2693              :                 // **RR moved to here, only adjust regen heater load if mass flow rate is changed
    2694              :                 //   adjust regen heating coil capacity based on desiccant cycling ratio (PLR)
    2695         1846 :                 QRegen_OASysFanAdjust *= DDPartLoadRatio;
    2696              :             }
    2697              : 
    2698              :             // Call regen fan, balanced desiccant HX and heating coil
    2699         3268 :             if (desicDehum.regenFanPlace == HVAC::FanPlace::BlowThru) {
    2700            0 :                 state.dataFans->fans(desicDehum.RegenFanIndex)->simulate(state, FirstHVACIteration, _, _);
    2701              :             }
    2702              : 
    2703         3268 :             if (RegenCoilIndex > 0) {
    2704              : 
    2705              :                 //!   adjust regen heating coil capacity based on desiccant cycling ratio (PLR)
    2706              :                 //    QRegen_OASysFanAdjust = QRegen * DDPartLoadRatio
    2707              : 
    2708         3268 :                 if (desicDehum.regenFanPlace == HVAC::FanPlace::BlowThru) {
    2709            0 :                     if (state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate > 0.0) {
    2710              :                         //       For VAV systems, fan may restrict air flow during iteration. Adjust QRegen proportional to Mdot reduction through fan
    2711            0 :                         QRegen_OASysFanAdjust *= state.dataLoopNodes->Node(desicDehum.RegenFanOutNode).MassFlowRate /
    2712            0 :                                                  state.dataLoopNodes->Node(desicDehum.RegenFanInNode).MassFlowRate;
    2713              :                     }
    2714              :                 }
    2715              : 
    2716         3268 :                 if (QRegen_OASysFanAdjust == 0.0) {
    2717            0 :                     QRegen_OASysFanAdjust = -1.0;
    2718              :                 }
    2719         3268 :                 CalcNonDXHeatingCoils(state, DesicDehumNum, FirstHVACIteration, QRegen_OASysFanAdjust);
    2720              :             }
    2721              : 
    2722        16340 :             HeatRecovery::SimHeatRecovery(state,
    2723              :                                           desicDehum.HXName,
    2724              :                                           FirstHVACIteration,
    2725         3268 :                                           desicDehum.CompIndex,
    2726              :                                           HVAC::FanOp::Continuous,
    2727              :                                           DDPartLoadRatio,
    2728         6536 :                                           true,
    2729              :                                           CompanionCoilIndexNum,
    2730         3268 :                                           desicDehum.RegenInletIsOutsideAirNode,
    2731              :                                           _,
    2732              :                                           _,
    2733         3268 :                                           desicDehum.coolingCoil_TypeNum);
    2734              : 
    2735         3268 :             if (desicDehum.regenFanPlace == HVAC::FanPlace::DrawThru) {
    2736         3268 :                 state.dataFans->fans(desicDehum.RegenFanIndex)->simulate(state, FirstHVACIteration, _, _);
    2737              :             }
    2738              : 
    2739              :             // Calculate water removal
    2740         3268 :             desicDehum.WaterRemoveRate =
    2741         3268 :                 state.dataLoopNodes->Node(desicDehum.ProcAirInNode).MassFlowRate *
    2742         3268 :                 (state.dataLoopNodes->Node(desicDehum.ProcAirInNode).HumRat - state.dataLoopNodes->Node(desicDehum.ProcAirOutNode).HumRat);
    2743              : 
    2744              :             // If preheat is Yes, exhaust fan is condenser fan, if CoilUpstreamOfProcessSide is No, DD runs an its own PLR
    2745         3268 :             if (desicDehum.Preheat == Selection::Yes && desicDehum.CoilUpstreamOfProcessSide == Selection::No) {
    2746              :                 //    should actually use DX coil RTF instead of PLR since fan power is being calculated
    2747            0 :                 if ((desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingSingleSpeed) ||
    2748            0 :                     (desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
    2749            0 :                     desicDehum.ExhaustFanPower += max(
    2750            0 :                         0.0, (desicDehum.ExhaustFanMaxPower * (state.dataDXCoils->DXCoilPartLoadRatio(desicDehum.DXCoilIndex) - DDPartLoadRatio)));
    2751            0 :                 } else if (desicDehum.coolingCoil_TypeNum == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    2752            0 :                     desicDehum.ExhaustFanPower += max(0.0, (desicDehum.ExhaustFanMaxPower * (1.0 - DDPartLoadRatio)));
    2753              :                 }
    2754              :             }
    2755              : 
    2756              :         } else { // unit must be off
    2757              : 
    2758       188390 :             desicDehum.PartLoad = 0.0;
    2759              : 
    2760       188390 :             if (desicDehum.RegenInletIsOutsideAirNode) {
    2761        13649 :                 state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate = 0.0;
    2762        13649 :                 state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRateMaxAvail = 0.0;
    2763              :             }
    2764              : 
    2765       188390 :             if (desicDehum.regenFanPlace == HVAC::FanPlace::BlowThru) {
    2766            0 :                 state.dataFans->fans(desicDehum.RegenFanIndex)->simulate(state, FirstHVACIteration, _, _);
    2767              :             }
    2768              : 
    2769       188390 :             if (RegenCoilIndex > 0) {
    2770       188390 :                 CalcNonDXHeatingCoils(state, DesicDehumNum, FirstHVACIteration, -1.0);
    2771              :             }
    2772              : 
    2773       753560 :             HeatRecovery::SimHeatRecovery(state,
    2774              :                                           desicDehum.HXName,
    2775              :                                           FirstHVACIteration,
    2776       188390 :                                           desicDehum.CompIndex,
    2777              :                                           HVAC::FanOp::Continuous,
    2778       376780 :                                           0.0,
    2779       376780 :                                           false,
    2780              :                                           CompanionCoilIndexNum,
    2781       188390 :                                           desicDehum.RegenInletIsOutsideAirNode,
    2782              :                                           _,
    2783              :                                           _,
    2784       188390 :                                           desicDehum.coolingCoil_TypeNum);
    2785              : 
    2786       188390 :             if (desicDehum.regenFanPlace == HVAC::FanPlace::DrawThru) {
    2787       188390 :                 state.dataFans->fans(desicDehum.RegenFanIndex)->simulate(state, FirstHVACIteration, _, _);
    2788              :             }
    2789              : 
    2790              :             // Turn on exhaust fan if DX Coil is operating
    2791       188390 :             if (desicDehum.ExhaustFanMaxVolFlowRate > 0) {
    2792        13649 :                 if (desicDehum.DXCoilIndex > 0) {
    2793        13649 :                     if ((desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingSingleSpeed) ||
    2794         6155 :                         (desicDehum.coolingCoil_TypeNum == HVAC::CoilDX_CoolingTwoStageWHumControl)) {
    2795         7494 :                         DDPartLoadRatio = state.dataDXCoils->DXCoilPartLoadRatio(desicDehum.DXCoilIndex);
    2796         6155 :                     } else if (desicDehum.coolingCoil_TypeNum == HVAC::Coil_CoolingAirToAirVariableSpeed) {
    2797         6155 :                         DDPartLoadRatio = 1.0; // condenser waste heat already includes modulation down
    2798              :                     }
    2799        13649 :                     desicDehum.ExhaustFanPower = desicDehum.ExhaustFanMaxPower * DDPartLoadRatio;
    2800        13649 :                     ExhaustFanMassFlowRate = desicDehum.ExhaustFanMaxMassFlowRate * DDPartLoadRatio;
    2801              :                 }
    2802              :             }
    2803              : 
    2804              :         } // UnitOn/Off
    2805              : 
    2806              :         // check condenser minimum flow per rated total capacity
    2807       191658 :         if (DDPartLoadRatio > 0.0 && desicDehum.ExhaustFanMaxVolFlowRate > 0.0) {
    2808        12443 :             VolFlowPerRatedTotQ = (state.dataLoopNodes->Node(desicDehum.RegenAirInNode).MassFlowRate + ExhaustFanMassFlowRate) /
    2809        12443 :                                   max(0.00001, (desicDehum.CompanionCoilCapacity * DDPartLoadRatio * state.dataEnvrn->StdRhoAir));
    2810        12443 :             if (!state.dataGlobal->WarmupFlag && (VolFlowPerRatedTotQ < MinVolFlowPerRatedTotQ)) {
    2811            0 :                 ++desicDehum.ErrCount;
    2812            0 :                 if (desicDehum.ErrCount < 2) {
    2813            0 :                     ShowWarningError(state,
    2814            0 :                                      format("{} \"{}\" - Air volume flow rate per watt of total condenser waste heat is below the minimum "
    2815              :                                             "recommended at {:N} m3/s/W.",
    2816            0 :                                             desicDehum.DehumType,
    2817            0 :                                             desicDehum.Name,
    2818              :                                             VolFlowPerRatedTotQ));
    2819            0 :                     ShowContinueErrorTimeStamp(state, "");
    2820            0 :                     ShowContinueError(state,
    2821            0 :                                       format("Expected minimum for VolumeFlowperRatedTotalCondenserWasteHeat = [{:N}]", MinVolFlowPerRatedTotQ));
    2822            0 :                     ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components ");
    2823            0 :                     ShowContinueError(state, "on the regeneration side of the desiccant dehumidifier.");
    2824              :                 } else {
    2825            0 :                     ShowRecurringWarningErrorAtEnd(
    2826              :                         state,
    2827            0 :                         desicDehum.DehumType + " \"" + desicDehum.Name +
    2828              :                             "\" - Air volume flow rate per watt of rated total cooling capacity is out of range error continues...",
    2829            0 :                         desicDehum.ErrIndex1,
    2830              :                         VolFlowPerRatedTotQ,
    2831              :                         VolFlowPerRatedTotQ);
    2832              :                 }
    2833              :             } // flow per rated total capacity check ends
    2834              :         }
    2835              : 
    2836              :         // Reset OnOffFanPartLoadFraction for process side fan calculations
    2837       191658 :         state.dataHVACGlobal->OnOffFanPartLoadFraction = OnOffFanPLF;
    2838       191658 :     }
    2839              : 
    2840       283978 :     void UpdateDesiccantDehumidifier(EnergyPlusData &state, int const DesicDehumNum) // number of the current dehumidifier being simulated
    2841              :     {
    2842              : 
    2843              :         // SUBROUTINE INFORMATION:
    2844              :         //       AUTHOR         Michael J. Witte, GARD Analytics, Inc.
    2845              :         //                      for Gas Research Institute
    2846              :         //       DATE WRITTEN   March 2001
    2847              : 
    2848              :         // PURPOSE OF THIS SUBROUTINE:
    2849              :         // Moves dehumidifier output to the outlet nodes.
    2850              : 
    2851       283978 :         switch (state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).DehumTypeCode) {
    2852        92320 :         case DesicDehumType::Solid: {
    2853        92320 :             int ProcInNode = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ProcAirInNode;
    2854        92320 :             int ProcOutNode = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ProcAirOutNode;
    2855              :             // Set the process outlet air node of the dehumidifier
    2856        92320 :             state.dataLoopNodes->Node(ProcOutNode).Temp = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ProcAirOutTemp;
    2857        92320 :             state.dataLoopNodes->Node(ProcOutNode).HumRat = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ProcAirOutHumRat;
    2858        92320 :             state.dataLoopNodes->Node(ProcOutNode).Enthalpy = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ProcAirOutEnthalpy;
    2859              : 
    2860              :             // Set the process outlet nodes for properties that just pass through & not used
    2861        92320 :             state.dataLoopNodes->Node(ProcOutNode).Quality = state.dataLoopNodes->Node(ProcInNode).Quality;
    2862        92320 :             state.dataLoopNodes->Node(ProcOutNode).Press = state.dataLoopNodes->Node(ProcInNode).Press;
    2863        92320 :             state.dataLoopNodes->Node(ProcOutNode).MassFlowRate = state.dataLoopNodes->Node(ProcInNode).MassFlowRate;
    2864        92320 :             state.dataLoopNodes->Node(ProcOutNode).MassFlowRateMin = state.dataLoopNodes->Node(ProcInNode).MassFlowRateMin;
    2865        92320 :             state.dataLoopNodes->Node(ProcOutNode).MassFlowRateMax = state.dataLoopNodes->Node(ProcInNode).MassFlowRateMax;
    2866        92320 :             state.dataLoopNodes->Node(ProcOutNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(ProcInNode).MassFlowRateMinAvail;
    2867        92320 :             state.dataLoopNodes->Node(ProcOutNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(ProcInNode).MassFlowRateMaxAvail;
    2868              : 
    2869              :             //   RegenInNode =DesicDehum(DesicDehumNum)%RegenAirInNode
    2870              :             //   RegenOutNode = DesicDehum(DesicDehumNum)%RegenAirOutNode
    2871              :             // Set the regen outlet air node of the dehumidifier
    2872              :             //   Node(RegenOutNode)%Temp         = DesicDehum(DesicDehumNum)%RegenAirOutTemp
    2873              :             //   Node(RegenOutNode)%HumRat       = DesicDehum(DesicDehumNum)%RegenAirOutHumRat
    2874              :             //   Node(RegenOutNode)%Enthalpy     = DesicDehum(DesicDehumNum)%RegenAirOutEnthalpy
    2875              : 
    2876              :             // Set the regen outlet nodes for properties that just pass through & not used
    2877              :             //   Node(RegenOutNode)%Quality             = Node(RegenInNode)%Quality
    2878              :             //   Node(RegenOutNode)%Press               = Node(RegenInNode)%Press
    2879              :             //   Node(RegenOutNode)%MassFlowRate        = Node(RegenInNode)%MassFlowRate
    2880              :             //   Node(RegenOutNode)%MassFlowRateMin     = Node(RegenInNode)%MassFlowRateMin
    2881              :             //   Node(RegenOutNode)%MassFlowRateMax     = Node(RegenInNode)%MassFlowRateMax
    2882              :             //   Node(RegenOutNode)%MassFlowRateMinAvail= Node(RegenInNode)%MassFlowRateMinAvail
    2883              :             //   Node(RegenOutNode)%MassFlowRateMaxAvail= Node(RegenInNode)%MassFlowRateMaxAvail
    2884              : 
    2885        92320 :         } break;
    2886       191658 :         case DesicDehumType::Generic: {
    2887       191658 :             return;
    2888              :         } break;
    2889            0 :         default:
    2890            0 :             break;
    2891              :         }
    2892              :     }
    2893              : 
    2894       283978 :     void ReportDesiccantDehumidifier(EnergyPlusData &state, int const DesicDehumNum) // number of the current dehumidifier being simulated
    2895              :     {
    2896              : 
    2897              :         // SUBROUTINE INFORMATION:
    2898              :         //       AUTHOR         Michael J. Witte, GARD Analytics, Inc.
    2899              :         //                      for Gas Research Institute
    2900              :         //       DATE WRITTEN   March 2001
    2901              :         //       MODIFIED       June 2007, R. Raustad, Added new dehumidifier type -- DESICCANT DEHUMIDIFIER
    2902              : 
    2903              :         // PURPOSE OF THIS SUBROUTINE:
    2904              :         // Fill remaining report variables
    2905              : 
    2906       283978 :         Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
    2907              : 
    2908       283978 :         switch (state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).DehumTypeCode) {
    2909        92320 :         case DesicDehumType::Solid: {
    2910        92320 :             state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).WaterRemove =
    2911        92320 :                 state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).WaterRemoveRate * TimeStepSysSec;
    2912        92320 :             state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).RegenEnergy =
    2913        92320 :                 state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).QRegen * TimeStepSysSec;
    2914        92320 :             state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ElecUseEnergy =
    2915        92320 :                 state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ElecUseRate * TimeStepSysSec;
    2916        92320 :         } break;
    2917       191658 :         case DesicDehumType::Generic: {
    2918       191658 :             state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).WaterRemove =
    2919       191658 :                 state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).WaterRemoveRate * TimeStepSysSec;
    2920       191658 :             state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ExhaustFanElecConsumption =
    2921       191658 :                 state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ExhaustFanPower * TimeStepSysSec;
    2922       191658 :         } break;
    2923            0 :         default:
    2924            0 :             break;
    2925              :         }
    2926       283978 :     }
    2927              : 
    2928       377720 :     void CalcNonDXHeatingCoils(EnergyPlusData &state,
    2929              :                                int const DesicDehumNum,                     // Desiccant dehumidifier unit index
    2930              :                                bool const FirstHVACIteration,               // flag for first HVAC iteration in the time step
    2931              :                                Real64 const RegenCoilLoad,                  // heating coil load to be met (Watts)
    2932              :                                ObjexxFCL::Optional<Real64> RegenCoilLoadmet // heating load met
    2933              :     )
    2934              :     {
    2935              : 
    2936              :         // SUBROUTINE INFORMATION:
    2937              :         //       AUTHOR         Bereket Nigusse, FSEC/UCF
    2938              :         //       DATE WRITTEN   January 2012
    2939              : 
    2940              :         // PURPOSE OF THIS SUBROUTINE:
    2941              :         // This subroutine simulates the four non dx heating coil types: Gas, Electric, hot water and steam.
    2942              : 
    2943              :         // METHODOLOGY EMPLOYED:
    2944              :         // Simply calls the different heating coil component.  The hot water flow rate matching the coil load
    2945              :         // is calculated iteratively.
    2946              : 
    2947              :         // SUBROUTINE PARAMETER DEFINITIONS:
    2948       377720 :         Real64 constexpr ErrTolerance(0.001); // convergence limit for hotwater coil
    2949       377720 :         int constexpr SolveMaxIter(50);       // Max iteration for SolveRoot
    2950              : 
    2951              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    2952              :         Real64 RegenCoilActual; // actual heating load met
    2953              :         Real64 mdot;            // heating coil steam or hot water mass flow rate
    2954              :         Real64 MinWaterFlow;    // minimum hot water mass flow rate
    2955              :         // unused  REAL(r64)      :: PartLoadFraction  ! heating or cooling part load fraction
    2956              :         Real64 MaxHotWaterFlow; // maximum hot water mass flow rate, kg/s
    2957              :         Real64 HotWaterMdot;    // actual hot water mass flow rate
    2958              : 
    2959       377720 :         auto &desicDehum = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum);
    2960              : 
    2961       377720 :         RegenCoilActual = 0.0;
    2962       377720 :         if (RegenCoilLoad > HVAC::SmallLoad) {
    2963        59323 :             switch (desicDehum.RegenCoilType_Num) {
    2964        59323 :             case HVAC::Coil_HeatingGasOrOtherFuel:
    2965              :             case HVAC::Coil_HeatingElectric: {
    2966       118646 :                 HeatingCoils::SimulateHeatingCoilComponents(
    2967        59323 :                     state, desicDehum.RegenCoilName, FirstHVACIteration, RegenCoilLoad, desicDehum.RegenCoilIndex, RegenCoilActual);
    2968        59323 :             } break;
    2969            0 :             case HVAC::Coil_HeatingWater: {
    2970            0 :                 MaxHotWaterFlow = desicDehum.MaxCoilFluidFlow;
    2971            0 :                 PlantUtilities::SetComponentFlowRate(
    2972            0 :                     state, MaxHotWaterFlow, desicDehum.CoilControlNode, desicDehum.CoilOutletNode, desicDehum.plantLoc);
    2973            0 :                 RegenCoilActual = RegenCoilLoad;
    2974              :                 // simulate the regenerator hot water heating coil
    2975            0 :                 WaterCoils::SimulateWaterCoilComponents(
    2976            0 :                     state, desicDehum.RegenCoilName, FirstHVACIteration, desicDehum.RegenCoilIndex, RegenCoilActual);
    2977              : 
    2978            0 :                 if (RegenCoilActual > (RegenCoilLoad + HVAC::SmallLoad)) {
    2979              :                     // control water flow to obtain output matching RegenCoilLoad
    2980            0 :                     int SolFlag = 0;
    2981            0 :                     MinWaterFlow = 0.0;
    2982            0 :                     auto f = [&state, DesicDehumNum, FirstHVACIteration, RegenCoilLoad](Real64 HWFlow) {
    2983            0 :                         Real64 RegenCoilHeatLoad = RegenCoilLoad;
    2984            0 :                         Real64 RegenCoilActual = RegenCoilHeatLoad;
    2985            0 :                         Real64 mdot = HWFlow;
    2986            0 :                         PlantUtilities::SetComponentFlowRate(state,
    2987              :                                                              mdot,
    2988            0 :                                                              state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).CoilControlNode,
    2989            0 :                                                              state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).CoilOutletNode,
    2990            0 :                                                              state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).plantLoc);
    2991              : 
    2992              :                         // simulate the hot water regenerator heating coil
    2993            0 :                         WaterCoils::SimulateWaterCoilComponents(state,
    2994            0 :                                                                 state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).RegenCoilName,
    2995              :                                                                 FirstHVACIteration,
    2996            0 :                                                                 state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).RegenCoilIndex,
    2997              :                                                                 RegenCoilActual);
    2998            0 :                         if (RegenCoilHeatLoad != 0.0) {
    2999            0 :                             return (RegenCoilActual - RegenCoilHeatLoad) / RegenCoilHeatLoad;
    3000              :                         } else { // Autodesk:Return ELSE added to assure return value is set
    3001            0 :                             return 0.0;
    3002              :                         }
    3003            0 :                     };
    3004            0 :                     General::SolveRoot(state, ErrTolerance, SolveMaxIter, SolFlag, HotWaterMdot, f, MinWaterFlow, MaxHotWaterFlow);
    3005            0 :                     if (SolFlag == -1) {
    3006            0 :                         if (desicDehum.HotWaterCoilMaxIterIndex == 0) {
    3007            0 :                             ShowWarningMessage(
    3008              :                                 state,
    3009            0 :                                 format("CalcNonDXHeatingCoils: Hot water coil control failed for {}=\"{}\"", desicDehum.DehumType, desicDehum.Name));
    3010            0 :                             ShowContinueErrorTimeStamp(state, "");
    3011            0 :                             ShowContinueError(state,
    3012            0 :                                               format("...Iteration limit [{}] exceeded in calculating hot water mass flow rate", SolveMaxIter));
    3013              :                         }
    3014            0 :                         ShowRecurringWarningErrorAtEnd(
    3015              :                             state,
    3016            0 :                             format("CalcNonDXHeatingCoils: Hot water coil control failed (iteration limit [{}]) for {}=\"{}\"",
    3017              :                                    SolveMaxIter,
    3018            0 :                                    desicDehum.DehumType,
    3019            0 :                                    desicDehum.Name),
    3020            0 :                             desicDehum.HotWaterCoilMaxIterIndex);
    3021            0 :                     } else if (SolFlag == -2) {
    3022            0 :                         if (desicDehum.HotWaterCoilMaxIterIndex2 == 0) {
    3023            0 :                             ShowWarningMessage(state,
    3024            0 :                                                format("CalcNonDXHeatingCoils: Hot water coil control failed (maximum flow limits) for {}=\"{}\"",
    3025            0 :                                                       desicDehum.DehumType,
    3026            0 :                                                       desicDehum.Name));
    3027            0 :                             ShowContinueErrorTimeStamp(state, "");
    3028            0 :                             ShowContinueError(state, "...Bad hot water maximum flow rate limits");
    3029            0 :                             ShowContinueError(state, format("...Given minimum water flow rate={:.3R} kg/s", MinWaterFlow));
    3030            0 :                             ShowContinueError(state, format("...Given maximum water flow rate={:.3R} kg/s", MaxHotWaterFlow));
    3031              :                         }
    3032            0 :                         ShowRecurringWarningErrorAtEnd(state,
    3033            0 :                                                        "CalcNonDXHeatingCoils: Hot water coil control failed (flow limits) for " +
    3034            0 :                                                            desicDehum.DehumType + "=\"" + desicDehum.Name + "\"",
    3035            0 :                                                        desicDehum.HotWaterCoilMaxIterIndex2,
    3036              :                                                        MaxHotWaterFlow,
    3037              :                                                        MinWaterFlow,
    3038              :                                                        _,
    3039              :                                                        "[kg/s]",
    3040              :                                                        "[kg/s]");
    3041              :                     }
    3042              : 
    3043            0 :                     RegenCoilActual = RegenCoilLoad;
    3044              :                     // simulate the regenerator hot water heating coil
    3045            0 :                     WaterCoils::SimulateWaterCoilComponents(
    3046            0 :                         state, desicDehum.RegenCoilName, FirstHVACIteration, desicDehum.RegenCoilIndex, RegenCoilActual);
    3047              :                 }
    3048            0 :             } break;
    3049            0 :             case HVAC::Coil_HeatingSteam: {
    3050            0 :                 mdot = desicDehum.MaxCoilFluidFlow;
    3051            0 :                 PlantUtilities::SetComponentFlowRate(state, mdot, desicDehum.CoilControlNode, desicDehum.CoilOutletNode, desicDehum.plantLoc);
    3052              :                 // simulate the regenerator steam heating coil
    3053            0 :                 SteamCoils::SimulateSteamCoilComponents(
    3054            0 :                     state, desicDehum.RegenCoilName, FirstHVACIteration, desicDehum.RegenCoilIndex, RegenCoilLoad, RegenCoilActual);
    3055            0 :             } break;
    3056            0 :             default:
    3057            0 :                 break;
    3058              :             }
    3059              :         } else {
    3060       318397 :             switch (desicDehum.RegenCoilType_Num) {
    3061       318397 :             case HVAC::Coil_HeatingGasOrOtherFuel:
    3062              :             case HVAC::Coil_HeatingElectric: {
    3063       636794 :                 HeatingCoils::SimulateHeatingCoilComponents(
    3064       318397 :                     state, desicDehum.RegenCoilName, FirstHVACIteration, RegenCoilLoad, desicDehum.RegenCoilIndex, RegenCoilActual);
    3065       318397 :             } break;
    3066            0 :             case HVAC::Coil_HeatingWater: {
    3067            0 :                 mdot = 0.0;
    3068            0 :                 PlantUtilities::SetComponentFlowRate(state, mdot, desicDehum.CoilControlNode, desicDehum.CoilOutletNode, desicDehum.plantLoc);
    3069            0 :                 RegenCoilActual = RegenCoilLoad;
    3070              :                 // simulate the regenerator hot water heating coil
    3071            0 :                 WaterCoils::SimulateWaterCoilComponents(
    3072            0 :                     state, desicDehum.RegenCoilName, FirstHVACIteration, desicDehum.RegenCoilIndex, RegenCoilActual);
    3073            0 :             } break;
    3074            0 :             case HVAC::Coil_HeatingSteam: {
    3075            0 :                 mdot = 0.0;
    3076            0 :                 PlantUtilities::SetComponentFlowRate(state, mdot, desicDehum.CoilControlNode, desicDehum.CoilOutletNode, desicDehum.plantLoc);
    3077              :                 // simulate the regenerator steam heating coil
    3078            0 :                 SteamCoils::SimulateSteamCoilComponents(
    3079            0 :                     state, desicDehum.RegenCoilName, FirstHVACIteration, desicDehum.RegenCoilIndex, RegenCoilLoad, RegenCoilActual);
    3080            0 :             } break;
    3081            0 :             default:
    3082            0 :                 break;
    3083              :             }
    3084              :         }
    3085       377720 :         if (present(RegenCoilLoadmet)) {
    3086        92320 :             RegenCoilLoadmet = RegenCoilActual;
    3087              :         }
    3088       377720 :     }
    3089              : 
    3090            0 :     int GetProcAirInletNodeNum(EnergyPlusData &state, std::string const &DesicDehumName, bool &ErrorsFound)
    3091              :     {
    3092              : 
    3093              :         // FUNCTION INFORMATION:
    3094              :         //       AUTHOR         Lixing Gu
    3095              :         //       DATE WRITTEN   May 2019
    3096              : 
    3097              :         // PURPOSE OF THIS FUNCTION:
    3098              :         // This function looks up the given Desiccant Dehumidifier and returns the process air inlet node number.
    3099              :         // If incorrect Desiccant Dehumidifier name is given, ErrorsFound is returned as true and node number as zero.
    3100              : 
    3101              :         // Obtains and Allocates heat exchanger related parameters from input file
    3102            0 :         if (state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier) {
    3103            0 :             GetDesiccantDehumidifierInput(state);
    3104            0 :             state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier = false;
    3105              :         }
    3106              : 
    3107            0 :         int WhichDesicDehum = Util::FindItemInList(DesicDehumName, state.dataDesiccantDehumidifiers->DesicDehum);
    3108            0 :         if (WhichDesicDehum != 0) {
    3109            0 :             return state.dataDesiccantDehumidifiers->DesicDehum(WhichDesicDehum).ProcAirInNode;
    3110              :         } else {
    3111            0 :             ShowSevereError(state, format("GetProcAirInletNodeNum: Could not find Desciccant Dehumidifier = \"{}\"", DesicDehumName));
    3112            0 :             ErrorsFound = true;
    3113            0 :             return 0;
    3114              :         }
    3115              :     }
    3116              : 
    3117            0 :     int GetProcAirOutletNodeNum(EnergyPlusData &state, std::string const &DesicDehumName, bool &ErrorsFound)
    3118              :     {
    3119              :         // FUNCTION INFORMATION:
    3120              :         //       AUTHOR         Lixing Gu
    3121              :         //       DATE WRITTEN   May 2019
    3122              : 
    3123              :         // PURPOSE OF THIS FUNCTION:
    3124              :         // This function looks up the given Desiccant Dehumidifier and returns the process air outlet node number.
    3125              :         // If incorrect Desiccant Dehumidifier name is given, ErrorsFound is returned as true and node number as zero.
    3126              : 
    3127              :         // Obtains and Allocates heat exchanger related parameters from input file
    3128            0 :         if (state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier) {
    3129            0 :             GetDesiccantDehumidifierInput(state);
    3130            0 :             state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier = false;
    3131              :         }
    3132              : 
    3133            0 :         int WhichDesicDehum = Util::FindItemInList(DesicDehumName, state.dataDesiccantDehumidifiers->DesicDehum);
    3134            0 :         if (WhichDesicDehum != 0) {
    3135            0 :             return state.dataDesiccantDehumidifiers->DesicDehum(WhichDesicDehum).ProcAirOutNode;
    3136              :         } else {
    3137            0 :             ShowSevereError(state, format("GetProcAirInletNodeNum: Could not find Desciccant Dehumidifier = \"{}\"", DesicDehumName));
    3138            0 :             ErrorsFound = true;
    3139            0 :             return 0;
    3140              :         }
    3141              :     }
    3142              : 
    3143              :     //        End of Reporting subroutines for the SimAir Module
    3144              :     // *****************************************************************************
    3145              : 
    3146              :     //                                 COPYRIGHT NOTICE
    3147              : 
    3148              :     //     Portions Copyright (c) Gas Research Institute 2001.  All rights reserved.
    3149              : 
    3150              :     //     GRI LEGAL NOTICE
    3151              :     //     Neither GRI, members of GRI nor any person or organization acting on behalf
    3152              :     //     of either:
    3153              : 
    3154              :     //     A. Makes any warranty of representation, express or implied with respect to
    3155              :     //        the accuracy, completness, or usefulness of the information contained in
    3156              :     //        in this program, including any warranty of merchantability or fitness of
    3157              :     //        any purpose with respoect to the program, or that the use of any
    3158              :     //        information disclosed in this program may not infringe privately-owned
    3159              :     //        rights, or
    3160              : 
    3161              :     //     B.  Assumes any liability with respoct to the use of, or for any and all
    3162              :     //         damages resulting from the use of the program or any portion thereof or
    3163              :     //         any information disclosed therein.
    3164              : 
    3165              : } // namespace DesiccantDehumidifiers
    3166              : 
    3167              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1