LCOV - code coverage report
Current view: top level - EnergyPlus - DesiccantDehumidifiers.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 872 1618 53.9 %
Date: 2024-08-23 23:50:59 Functions: 9 12 75.0 %

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

Generated by: LCOV version 1.14