LCOV - code coverage report
Current view: top level - EnergyPlus - NodeInputManager.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 458 570 80.4 %
Date: 2024-08-23 23:50:59 Functions: 12 12 100.0 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // C++ Headers
      49             : #include <string>
      50             : 
      51             : // ObjexxFCL Headers
      52             : #include <ObjexxFCL/Array.functions.hh>
      53             : #include <ObjexxFCL/string.functions.hh>
      54             : 
      55             : // EnergyPlus Headers
      56             : #include <EnergyPlus/BranchNodeConnections.hh>
      57             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      58             : #include <EnergyPlus/DataContaminantBalance.hh>
      59             : #include <EnergyPlus/DataEnvironment.hh>
      60             : #include <EnergyPlus/DataErrorTracking.hh>
      61             : #include <EnergyPlus/EMSManager.hh>
      62             : #include <EnergyPlus/FluidProperties.hh>
      63             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      64             : #include <EnergyPlus/NodeInputManager.hh>
      65             : #include <EnergyPlus/OutputProcessor.hh>
      66             : #include <EnergyPlus/Psychrometrics.hh>
      67             : #include <EnergyPlus/ScheduleManager.hh>
      68             : #include <EnergyPlus/UtilityRoutines.hh>
      69             : 
      70             : namespace EnergyPlus::NodeInputManager {
      71             : 
      72             : // MODULE INFORMATION:
      73             : //       AUTHOR         Linda K. Lawrie
      74             : //       DATE WRITTEN   September 1999
      75             : 
      76             : // PURPOSE OF THIS MODULE:
      77             : // To provide utilities for reading and assigning indices for the
      78             : // nodes in the HVAC loops.
      79             : 
      80             : using namespace DataLoopNode;
      81             : using namespace BranchNodeConnections;
      82             : 
      83             : constexpr const char *fluidNameSteam("STEAM");
      84             : 
      85      284079 : void GetNodeNums(EnergyPlusData &state,
      86             :                  std::string const &Name,                                 // Name for which to obtain information
      87             :                  int &NumNodes,                                           // Number of nodes accompanying this Name
      88             :                  Array1D_int &NodeNumbers,                                // Node Numbers accompanying this Name
      89             :                  bool &ErrorsFound,                                       // True when errors are found...
      90             :                  DataLoopNode::NodeFluidType nodeFluidType,               // Fluidtype for checking/setting node FluidType
      91             :                  DataLoopNode::ConnectionObjectType const NodeObjectType, // Node Object Type (i.e. "Chiller:Electric")
      92             :                  std::string const &NodeObjectName,                       // Node Object Name (i.e. "MyChiller")
      93             :                  DataLoopNode::ConnectionType const nodeConnectionType,   // Node Connection Type (see DataLoopNode)
      94             :                  CompFluidStream const NodeFluidStream,                   // Which Fluid Stream (1,2,3,...)
      95             :                  bool const ObjectIsParent,                               // True/False
      96             :                  bool const IncrementFluidStream,                         // True/False
      97             :                  std::string_view const InputFieldName                    // Input Field Name
      98             : )
      99             : {
     100             : 
     101             :     // SUBROUTINE INFORMATION:
     102             :     //       AUTHOR         Linda K. Lawrie
     103             :     //       DATE WRITTEN   September 1999
     104             :     //       MODIFIED       February 2004, Fluid Type checking/setting
     105             : 
     106             :     // PURPOSE OF THIS SUBROUTINE:
     107             :     // This subroutine calls the Node Manager to determine if the
     108             :     // entered name has already been assigned and if it is a list
     109             :     // or if it is a single node.  If it has not been assigned, then
     110             :     // it is a single node and will need to be entered in the Node
     111             :     // data structure.
     112             : 
     113             :     // SUBROUTINE PARAMETER DEFINITIONS:
     114             :     static constexpr std::string_view RoutineName("GetNodeNums: ");
     115             : 
     116      284079 :     std::string_view const objTypeStr = BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(NodeObjectType)];
     117             : 
     118      284079 :     if (state.dataNodeInputMgr->GetNodeInputFlag) {
     119         633 :         GetNodeListsInput(state, ErrorsFound);
     120         633 :         state.dataNodeInputMgr->GetNodeInputFlag = false;
     121             :     }
     122             : 
     123      284079 :     if (nodeFluidType != DataLoopNode::NodeFluidType::Air && nodeFluidType != DataLoopNode::NodeFluidType::Water &&
     124       41276 :         nodeFluidType != DataLoopNode::NodeFluidType::Electric && nodeFluidType != DataLoopNode::NodeFluidType::Steam &&
     125       41058 :         nodeFluidType != DataLoopNode::NodeFluidType::Blank) {
     126           0 :         ShowSevereError(state, format("{}{}=\"{}=\", invalid fluid type.", RoutineName, objTypeStr, NodeObjectName));
     127           0 :         ShowContinueError(state, format("..Invalid FluidType={}", nodeFluidType));
     128           0 :         ErrorsFound = true;
     129           0 :         ShowFatalError(state, "Preceding issue causes termination.");
     130             :     }
     131             : 
     132      284079 :     if (!Name.empty()) {
     133      274695 :         int ThisOne = Util::FindItemInList(Name, state.dataNodeInputMgr->NodeLists);
     134      274695 :         if (ThisOne != 0) {
     135        6138 :             NumNodes = state.dataNodeInputMgr->NodeLists(ThisOne).NumOfNodesInList;
     136        6138 :             NodeNumbers({1, NumNodes}) = state.dataNodeInputMgr->NodeLists(ThisOne).NodeNumbers({1, NumNodes});
     137       13119 :             for (int Loop = 1; Loop <= NumNodes; ++Loop) {
     138       12556 :                 if (nodeFluidType != DataLoopNode::NodeFluidType::Blank &&
     139        5575 :                     state.dataLoopNodes->Node(NodeNumbers(Loop)).FluidType != DataLoopNode::NodeFluidType::Blank) {
     140         578 :                     if (state.dataLoopNodes->Node(NodeNumbers(Loop)).FluidType != nodeFluidType) {
     141           0 :                         ShowSevereError(state, format("{}{}=\"{}=\", invalid data.", RoutineName, objTypeStr, NodeObjectName));
     142           0 :                         if (!InputFieldName.empty()) {
     143           0 :                             ShowContinueError(state, fmt::format("...Ref field={}", InputFieldName));
     144             :                         }
     145           0 :                         ShowContinueError(
     146             :                             state,
     147           0 :                             format("Existing Fluid type for node, incorrect for request. Node={}", state.dataLoopNodes->NodeID(NodeNumbers(Loop))));
     148           0 :                         ShowContinueError(
     149             :                             state,
     150           0 :                             format("Existing Fluid type={}, Requested Fluid Type={}",
     151           0 :                                    format("{}",
     152           0 :                                           DataLoopNode::NodeFluidTypeNames[static_cast<int>(state.dataLoopNodes->Node(NodeNumbers(Loop)).FluidType)]),
     153           0 :                                    format("{}", DataLoopNode::NodeFluidTypeNames[static_cast<int>(nodeFluidType)])));
     154           0 :                         ErrorsFound = true;
     155             :                     }
     156             :                 }
     157        6981 :                 if (state.dataLoopNodes->Node(NodeNumbers(Loop)).FluidType == DataLoopNode::NodeFluidType::Blank) {
     158        6230 :                     state.dataLoopNodes->Node(NodeNumbers(Loop)).FluidType = nodeFluidType;
     159             :                 }
     160        6981 :                 ++state.dataNodeInputMgr->NodeRef(NodeNumbers(Loop));
     161             :             }
     162             :         } else {
     163      268557 :             ThisOne = AssignNodeNumber(state, Name, nodeFluidType, ErrorsFound);
     164      268557 :             NumNodes = 1;
     165      268557 :             NodeNumbers(1) = ThisOne;
     166             :         }
     167             :     } else {
     168        9384 :         NumNodes = 0;
     169        9384 :         NodeNumbers(1) = 0;
     170             :     }
     171             : 
     172             :     // Most calls to this routine use a fixed fluid stream number for all nodes, this is the default
     173      284079 :     NodeInputManager::CompFluidStream FluidStreamNum = NodeFluidStream;
     174      559617 :     for (int Loop = 1; Loop <= NumNodes; ++Loop) {
     175             :         // If requested, assign NodeFluidStream to the first node and increment the fluid stream number
     176             :         // for each remaining node in the list
     177      275538 :         if (IncrementFluidStream) {
     178        2398 :             FluidStreamNum = static_cast<NodeInputManager::CompFluidStream>(static_cast<int>(NodeFluidStream) + (Loop - 1));
     179             :         }
     180             : 
     181      275538 :         RegisterNodeConnection(state,
     182      275538 :                                NodeNumbers(Loop),
     183      275538 :                                state.dataLoopNodes->NodeID(NodeNumbers(Loop)),
     184             :                                NodeObjectType,
     185             :                                NodeObjectName,
     186             :                                nodeConnectionType,
     187             :                                FluidStreamNum,
     188             :                                ObjectIsParent,
     189             :                                ErrorsFound,
     190             :                                InputFieldName);
     191             :     }
     192      284079 : }
     193             : 
     194         795 : void SetupNodeVarsForReporting(EnergyPlusData &state)
     195             : {
     196             : 
     197             :     // SUBROUTINE INFORMATION:
     198             :     //       AUTHOR         Linda K. Lawrie
     199             :     //       DATE WRITTEN   September
     200             : 
     201             :     // PURPOSE OF THIS SUBROUTINE:
     202             :     // This subroutine is called when the indicated number of
     203             :     // Nodes have been found (TOTAL NODE NUMBER) or when HVAC warmup is
     204             :     // complete, whichever condition is reached first.
     205             : 
     206         795 :     if (!state.dataNodeInputMgr->NodeVarsSetup) {
     207         795 :         if (!state.dataErrTracking->AbortProcessing) {
     208         795 :             state.dataLoopNodes->MoreNodeInfo.allocate(state.dataNodeInputMgr->NumOfUniqueNodeNames);
     209       63030 :             for (int NumNode = 1; NumNode <= state.dataNodeInputMgr->NumOfUniqueNodeNames; ++NumNode) {
     210       62235 :                 auto &Node = state.dataLoopNodes->Node(NumNode);
     211       62235 :                 auto &NodeID = state.dataLoopNodes->NodeID(NumNode);
     212             : 
     213             :                 // Setup Report variables for the Nodes for HVAC Reporting, CurrentModuleObject='Node Name'
     214      124470 :                 SetupOutputVariable(state,
     215             :                                     "System Node Temperature",
     216             :                                     Constant::Units::C,
     217       62235 :                                     Node.Temp,
     218             :                                     OutputProcessor::TimeStepType::System,
     219             :                                     OutputProcessor::StoreType::Average,
     220             :                                     NodeID);
     221      124470 :                 SetupOutputVariable(state,
     222             :                                     "System Node Mass Flow Rate",
     223             :                                     Constant::Units::kg_s,
     224       62235 :                                     Node.MassFlowRate,
     225             :                                     OutputProcessor::TimeStepType::System,
     226             :                                     OutputProcessor::StoreType::Average,
     227             :                                     NodeID);
     228      124470 :                 SetupOutputVariable(state,
     229             :                                     "System Node Humidity Ratio",
     230             :                                     Constant::Units::kgWater_kgDryAir,
     231       62235 :                                     Node.HumRat,
     232             :                                     OutputProcessor::TimeStepType::System,
     233             :                                     OutputProcessor::StoreType::Average,
     234             :                                     NodeID);
     235      124470 :                 SetupOutputVariable(state,
     236             :                                     "System Node Setpoint Temperature",
     237             :                                     Constant::Units::C,
     238       62235 :                                     Node.TempSetPoint,
     239             :                                     OutputProcessor::TimeStepType::System,
     240             :                                     OutputProcessor::StoreType::Average,
     241             :                                     NodeID);
     242      124470 :                 SetupOutputVariable(state,
     243             :                                     "System Node Setpoint High Temperature",
     244             :                                     Constant::Units::C,
     245       62235 :                                     Node.TempSetPointHi,
     246             :                                     OutputProcessor::TimeStepType::System,
     247             :                                     OutputProcessor::StoreType::Average,
     248             :                                     NodeID);
     249      124470 :                 SetupOutputVariable(state,
     250             :                                     "System Node Setpoint Low Temperature",
     251             :                                     Constant::Units::C,
     252       62235 :                                     Node.TempSetPointLo,
     253             :                                     OutputProcessor::TimeStepType::System,
     254             :                                     OutputProcessor::StoreType::Average,
     255             :                                     NodeID);
     256      124470 :                 SetupOutputVariable(state,
     257             :                                     "System Node Setpoint Humidity Ratio",
     258             :                                     Constant::Units::kgWater_kgDryAir,
     259       62235 :                                     Node.HumRatSetPoint,
     260             :                                     OutputProcessor::TimeStepType::System,
     261             :                                     OutputProcessor::StoreType::Average,
     262             :                                     NodeID);
     263      124470 :                 SetupOutputVariable(state,
     264             :                                     "System Node Setpoint Minimum Humidity Ratio",
     265             :                                     Constant::Units::kgWater_kgDryAir,
     266       62235 :                                     Node.HumRatMin,
     267             :                                     OutputProcessor::TimeStepType::System,
     268             :                                     OutputProcessor::StoreType::Average,
     269             :                                     NodeID);
     270      124470 :                 SetupOutputVariable(state,
     271             :                                     "System Node Setpoint Maximum Humidity Ratio",
     272             :                                     Constant::Units::kgWater_kgDryAir,
     273       62235 :                                     Node.HumRatMax,
     274             :                                     OutputProcessor::TimeStepType::System,
     275             :                                     OutputProcessor::StoreType::Average,
     276             :                                     NodeID);
     277      124470 :                 SetupOutputVariable(state,
     278             :                                     "System Node Relative Humidity",
     279             :                                     Constant::Units::Perc,
     280       62235 :                                     state.dataLoopNodes->MoreNodeInfo(NumNode).RelHumidity,
     281             :                                     OutputProcessor::TimeStepType::System,
     282             :                                     OutputProcessor::StoreType::Average,
     283             :                                     NodeID);
     284      124470 :                 SetupOutputVariable(state,
     285             :                                     "System Node Pressure",
     286             :                                     Constant::Units::Pa,
     287       62235 :                                     Node.Press,
     288             :                                     OutputProcessor::TimeStepType::System,
     289             :                                     OutputProcessor::StoreType::Average,
     290             :                                     NodeID);
     291      124470 :                 SetupOutputVariable(state,
     292             :                                     "System Node Standard Density Volume Flow Rate",
     293             :                                     Constant::Units::m3_s,
     294       62235 :                                     state.dataLoopNodes->MoreNodeInfo(NumNode).VolFlowRateStdRho,
     295             :                                     OutputProcessor::TimeStepType::System,
     296             :                                     OutputProcessor::StoreType::Average,
     297             :                                     NodeID);
     298       62235 :                 if (Node.FluidType == DataLoopNode::NodeFluidType::Air ||
     299       27051 :                     Node.FluidType == DataLoopNode::NodeFluidType::Water) { // setup volume flow rate report for actual/current density
     300      124084 :                     SetupOutputVariable(state,
     301             :                                         "System Node Current Density Volume Flow Rate",
     302             :                                         Constant::Units::m3_s,
     303       62042 :                                         state.dataLoopNodes->MoreNodeInfo(NumNode).VolFlowRateCrntRho,
     304             :                                         OutputProcessor::TimeStepType::System,
     305             :                                         OutputProcessor::StoreType::Average,
     306             :                                         NodeID);
     307      124084 :                     SetupOutputVariable(state,
     308             :                                         "System Node Current Density",
     309             :                                         Constant::Units::kg_m3,
     310       62042 :                                         state.dataLoopNodes->MoreNodeInfo(NumNode).Density,
     311             :                                         OutputProcessor::TimeStepType::System,
     312             :                                         OutputProcessor::StoreType::Average,
     313             :                                         NodeID);
     314      124084 :                     SetupOutputVariable(state,
     315             :                                         "System Node Specific Heat",
     316             :                                         Constant::Units::J_kgK,
     317       62042 :                                         state.dataLoopNodes->MoreNodeInfo(NumNode).SpecificHeat,
     318             :                                         OutputProcessor::TimeStepType::System,
     319             :                                         OutputProcessor::StoreType::Average,
     320             :                                         NodeID);
     321             :                 }
     322             : 
     323      124470 :                 SetupOutputVariable(state,
     324             :                                     "System Node Enthalpy",
     325             :                                     Constant::Units::J_kg,
     326       62235 :                                     state.dataLoopNodes->MoreNodeInfo(NumNode).ReportEnthalpy,
     327             :                                     OutputProcessor::TimeStepType::System,
     328             :                                     OutputProcessor::StoreType::Average,
     329             :                                     NodeID);
     330      124470 :                 SetupOutputVariable(state,
     331             :                                     "System Node Wetbulb Temperature",
     332             :                                     Constant::Units::C,
     333       62235 :                                     state.dataLoopNodes->MoreNodeInfo(NumNode).WetBulbTemp,
     334             :                                     OutputProcessor::TimeStepType::System,
     335             :                                     OutputProcessor::StoreType::Average,
     336             :                                     NodeID);
     337      124470 :                 SetupOutputVariable(state,
     338             :                                     "System Node Dewpoint Temperature",
     339             :                                     Constant::Units::C,
     340       62235 :                                     state.dataLoopNodes->MoreNodeInfo(NumNode).AirDewPointTemp,
     341             :                                     OutputProcessor::TimeStepType::System,
     342             :                                     OutputProcessor::StoreType::Average,
     343             :                                     NodeID);
     344      124470 :                 SetupOutputVariable(state,
     345             :                                     "System Node Wind Speed",
     346             :                                     Constant::Units::m_s,
     347       62235 :                                     Node.OutAirWindSpeed,
     348             :                                     OutputProcessor::TimeStepType::System,
     349             :                                     OutputProcessor::StoreType::Average,
     350             :                                     NodeID);
     351      124470 :                 SetupOutputVariable(state,
     352             :                                     "System Node Wind Direction",
     353             :                                     Constant::Units::deg,
     354       62235 :                                     Node.OutAirWindDir,
     355             :                                     OutputProcessor::TimeStepType::System,
     356             :                                     OutputProcessor::StoreType::Average,
     357             :                                     NodeID);
     358      124470 :                 SetupOutputVariable(state,
     359             :                                     "System Node Quality",
     360             :                                     Constant::Units::None,
     361       62235 :                                     Node.Quality,
     362             :                                     OutputProcessor::TimeStepType::System,
     363             :                                     OutputProcessor::StoreType::Average,
     364             :                                     NodeID);
     365      124470 :                 SetupOutputVariable(state,
     366             :                                     "System Node Height",
     367             :                                     Constant::Units::m,
     368       62235 :                                     Node.Height,
     369             :                                     OutputProcessor::TimeStepType::System,
     370             :                                     OutputProcessor::StoreType::Average,
     371             :                                     NodeID);
     372       62235 :                 if (state.dataGlobal->DisplayAdvancedReportVariables) {
     373         928 :                     SetupOutputVariable(state,
     374             :                                         "System Node Minimum Temperature",
     375             :                                         Constant::Units::C,
     376         464 :                                         Node.TempMin,
     377             :                                         OutputProcessor::TimeStepType::System,
     378             :                                         OutputProcessor::StoreType::Average,
     379             :                                         NodeID);
     380         928 :                     SetupOutputVariable(state,
     381             :                                         "System Node Maximum Temperature",
     382             :                                         Constant::Units::C,
     383         464 :                                         Node.TempMax,
     384             :                                         OutputProcessor::TimeStepType::System,
     385             :                                         OutputProcessor::StoreType::Average,
     386             :                                         NodeID);
     387         928 :                     SetupOutputVariable(state,
     388             :                                         "System Node Minimum Limit Mass Flow Rate",
     389             :                                         Constant::Units::kg_s,
     390         464 :                                         Node.MassFlowRateMin,
     391             :                                         OutputProcessor::TimeStepType::System,
     392             :                                         OutputProcessor::StoreType::Average,
     393             :                                         NodeID);
     394         928 :                     SetupOutputVariable(state,
     395             :                                         "System Node Maximum Limit Mass Flow Rate",
     396             :                                         Constant::Units::kg_s,
     397         464 :                                         Node.MassFlowRateMax,
     398             :                                         OutputProcessor::TimeStepType::System,
     399             :                                         OutputProcessor::StoreType::Average,
     400             :                                         NodeID);
     401         928 :                     SetupOutputVariable(state,
     402             :                                         "System Node Minimum Available Mass Flow Rate",
     403             :                                         Constant::Units::kg_s,
     404         464 :                                         Node.MassFlowRateMinAvail,
     405             :                                         OutputProcessor::TimeStepType::System,
     406             :                                         OutputProcessor::StoreType::Average,
     407             :                                         NodeID);
     408         928 :                     SetupOutputVariable(state,
     409             :                                         "System Node Maximum Available Mass Flow Rate",
     410             :                                         Constant::Units::kg_s,
     411         464 :                                         Node.MassFlowRateMaxAvail,
     412             :                                         OutputProcessor::TimeStepType::System,
     413             :                                         OutputProcessor::StoreType::Average,
     414             :                                         NodeID);
     415         928 :                     SetupOutputVariable(state,
     416             :                                         "System Node Setpoint Mass Flow Rate",
     417             :                                         Constant::Units::kg_s,
     418         464 :                                         Node.MassFlowRateSetPoint,
     419             :                                         OutputProcessor::TimeStepType::System,
     420             :                                         OutputProcessor::StoreType::Average,
     421             :                                         NodeID);
     422         928 :                     SetupOutputVariable(state,
     423             :                                         "System Node Requested Mass Flow Rate",
     424             :                                         Constant::Units::kg_s,
     425         464 :                                         Node.MassFlowRateRequest,
     426             :                                         OutputProcessor::TimeStepType::System,
     427             :                                         OutputProcessor::StoreType::Average,
     428             :                                         NodeID);
     429         928 :                     SetupOutputVariable(state,
     430             :                                         "System Node Last Timestep Temperature",
     431             :                                         Constant::Units::C,
     432         464 :                                         Node.TempLastTimestep,
     433             :                                         OutputProcessor::TimeStepType::System,
     434             :                                         OutputProcessor::StoreType::Average,
     435             :                                         NodeID);
     436         928 :                     SetupOutputVariable(state,
     437             :                                         "System Node Last Timestep Enthalpy",
     438             :                                         Constant::Units::J_kg,
     439         464 :                                         Node.EnthalpyLastTimestep,
     440             :                                         OutputProcessor::TimeStepType::System,
     441             :                                         OutputProcessor::StoreType::Average,
     442             :                                         NodeID);
     443             :                 }
     444       62235 :                 if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
     445         610 :                     SetupOutputVariable(state,
     446             :                                         "System Node CO2 Concentration",
     447             :                                         Constant::Units::ppm,
     448         305 :                                         Node.CO2,
     449             :                                         OutputProcessor::TimeStepType::System,
     450             :                                         OutputProcessor::StoreType::Average,
     451             :                                         NodeID);
     452             :                 }
     453       62235 :                 if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
     454         180 :                     SetupOutputVariable(state,
     455             :                                         "System Node Generic Air Contaminant Concentration",
     456             :                                         Constant::Units::ppm,
     457          90 :                                         Node.GenContam,
     458             :                                         OutputProcessor::TimeStepType::System,
     459             :                                         OutputProcessor::StoreType::Average,
     460             :                                         NodeID);
     461             :                 }
     462             :             }
     463             :         }
     464         795 :         state.dataNodeInputMgr->NodeVarsSetup = true;
     465             : 
     466         795 :         print(state.files.bnd, "{}\n", "! This file shows details about the branches, nodes, and other");
     467         795 :         print(state.files.bnd, "{}\n", "! elements of the flow connections.");
     468         795 :         print(state.files.bnd, "{}\n", "! This file is intended for use in \"debugging\" potential problems");
     469         795 :         print(state.files.bnd, "{}\n", "! that may also be detected by the program, but may be more easily");
     470         795 :         print(state.files.bnd, "{}\n", "! identified by \"eye\".");
     471         795 :         print(state.files.bnd, "{}\n", "! This file is also intended to support software which draws a");
     472         795 :         print(state.files.bnd, "{}\n", "! schematic diagram of the HVAC system.");
     473         795 :         print(state.files.bnd, "{}\n", "! ===============================================================");
     474             :         // Show the node names on the Branch-Node Details file
     475             :         static constexpr std::string_view Format_700("! #Nodes,<Number of Unique Nodes>");
     476         795 :         print(state.files.bnd, "{}\n", Format_700);
     477         795 :         print(state.files.bnd, " #Nodes,{}\n", state.dataNodeInputMgr->NumOfUniqueNodeNames);
     478         795 :         if (state.dataNodeInputMgr->NumOfUniqueNodeNames > 0) {
     479             :             static constexpr std::string_view Format_702(
     480             :                 "! <Node>,<NodeNumber>,<Node Name>,<Node Fluid Type>,<# Times Node Referenced After Definition>");
     481         727 :             print(state.files.bnd, "{}\n", Format_702);
     482             :         }
     483         795 :         int Count0 = 0;
     484       63030 :         for (int NumNode = 1; NumNode <= state.dataNodeInputMgr->NumOfUniqueNodeNames; ++NumNode) {
     485       62235 :             auto &Node = state.dataLoopNodes->Node(NumNode);
     486       62235 :             auto &NodeID = state.dataLoopNodes->NodeID(NumNode);
     487      124470 :             print(state.files.bnd,
     488             :                   " Node,{},{},{},{}\n",
     489             :                   NumNode,
     490             :                   NodeID,
     491       62235 :                   DataLoopNode::NodeFluidTypeNames[static_cast<int>(Node.FluidType)],
     492       62235 :                   state.dataNodeInputMgr->NodeRef(NumNode));
     493       62235 :             if (state.dataNodeInputMgr->NodeRef(NumNode) == 0) ++Count0;
     494             :         }
     495             :         // Show suspicious node names on the Branch-Node Details file
     496         795 :         if (Count0 > 0) {
     497         646 :             print(state.files.bnd, "{}\n", "! ===============================================================");
     498         646 :             print(state.files.bnd, "{}\n", "! Suspicious nodes have 0 references.  It is normal for some nodes, however.");
     499         646 :             print(state.files.bnd, "{}\n", "! Listing nodes with 0 references (culled from previous list):");
     500             :             static constexpr std::string_view Format_703(
     501             :                 "! <Suspicious Node>,<NodeNumber>,<Node Name>,<Node Fluid Type>,<# Times Node Referenced After Definition>");
     502         646 :             print(state.files.bnd, "{}\n", Format_703);
     503       59087 :             for (int NumNode = 1; NumNode <= state.dataNodeInputMgr->NumOfUniqueNodeNames; ++NumNode) {
     504       58441 :                 auto &Node = state.dataLoopNodes->Node(NumNode);
     505       58441 :                 auto &NodeID = state.dataLoopNodes->NodeID(NumNode);
     506       58441 :                 if (state.dataNodeInputMgr->NodeRef(NumNode) > 0) continue;
     507       11420 :                 print(state.files.bnd,
     508             :                       " Suspicious Node,{},{},{},{}\n",
     509             :                       NumNode,
     510             :                       NodeID,
     511        5710 :                       DataLoopNode::NodeFluidTypeNames[static_cast<int>(Node.FluidType)],
     512        5710 :                       state.dataNodeInputMgr->NodeRef(NumNode));
     513             :             }
     514             :         }
     515             :     }
     516         795 : }
     517             : 
     518         796 : void GetNodeListsInput(EnergyPlusData &state, bool &ErrorsFound) // Set to true when requested Node List not found, unchanged otherwise
     519             : {
     520             : 
     521             :     // SUBROUTINE INFORMATION:
     522             :     //       AUTHOR         Linda K. Lawrie
     523             :     //       DATE WRITTEN   September 1999
     524             :     //       MODIFIED       na
     525             :     //       RE-ENGINEERED  na
     526             : 
     527             :     // PURPOSE OF THIS SUBROUTINE:
     528             :     // This subroutine gets the Node Lists from the IDF and fills the
     529             :     // Node List Data Structure.
     530             : 
     531             :     // SUBROUTINE PARAMETER DEFINITIONS:
     532             :     static constexpr std::string_view RoutineName("GetNodeListsInput: ");
     533         796 :     static std::string const CurrentModuleObject("NodeList");
     534             : 
     535             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     536             :     int NumAlphas;  // Number of alphas in IDF item
     537             :     int NumNumbers; // Number of numerics in IDF item
     538             :     int IOStatus;   // IOStatus for IDF item (not checked)
     539             :     int NCount;     // Actual number of node lists
     540             :     bool flagError; // true when error node list name should be output
     541         796 :     Array1D_string cAlphas;
     542         796 :     Array1D<Real64> rNumbers;
     543             : 
     544         796 :     bool localErrorsFound(false);
     545         796 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NCount, NumAlphas, NumNumbers);
     546         796 :     cAlphas.allocate(NumAlphas);
     547         796 :     rNumbers.allocate(NumNumbers);
     548         796 :     state.dataNodeInputMgr->NumOfNodeLists = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     549         796 :     state.dataNodeInputMgr->NodeLists.allocate(state.dataNodeInputMgr->NumOfNodeLists);
     550        6989 :     for (int i = 1; i <= state.dataNodeInputMgr->NumOfNodeLists; ++i) {
     551        6193 :         state.dataNodeInputMgr->NodeLists(i).Name.clear();
     552        6193 :         state.dataNodeInputMgr->NodeLists(i).NumOfNodesInList = 0;
     553             :     }
     554             : 
     555         796 :     NCount = 0;
     556        6989 :     for (int Loop = 1; Loop <= state.dataNodeInputMgr->NumOfNodeLists; ++Loop) {
     557        6193 :         state.dataInputProcessing->inputProcessor->getObjectItem(
     558             :             state, CurrentModuleObject, Loop, cAlphas, NumAlphas, rNumbers, NumNumbers, IOStatus);
     559        6193 :         if (Util::IsNameEmpty(state, cAlphas(1), CurrentModuleObject, localErrorsFound)) continue;
     560             : 
     561        6193 :         ++NCount;
     562        6193 :         state.dataNodeInputMgr->NodeLists(NCount).Name = cAlphas(1);
     563        6193 :         state.dataNodeInputMgr->NodeLists(NCount).NodeNames.allocate(NumAlphas - 1);
     564        6193 :         state.dataNodeInputMgr->NodeLists(NCount).NodeNames = "";
     565        6193 :         state.dataNodeInputMgr->NodeLists(NCount).NodeNumbers.allocate(NumAlphas - 1);
     566        6193 :         state.dataNodeInputMgr->NodeLists(NCount).NodeNumbers = 0;
     567        6193 :         state.dataNodeInputMgr->NodeLists(NCount).NumOfNodesInList = NumAlphas - 1;
     568        6193 :         if (NumAlphas <= 1) {
     569           0 :             if (NumAlphas == 1) {
     570           0 :                 ShowSevereError(state, format("{}{}=\"{}\" does not have any nodes.", RoutineName, CurrentModuleObject, cAlphas(1)));
     571             :             } else {
     572           0 :                 ShowSevereError(state, format("{}{}=<blank> does not have any nodes or nodelist name.", RoutineName, CurrentModuleObject));
     573             :             }
     574           0 :             localErrorsFound = true;
     575           0 :             continue;
     576             :         }
     577             :         //  Put all in, then determine unique
     578       13247 :         for (int Loop1 = 1; Loop1 <= NumAlphas - 1; ++Loop1) {
     579        7054 :             state.dataNodeInputMgr->NodeLists(NCount).NodeNames(Loop1) = cAlphas(Loop1 + 1);
     580        7054 :             if (cAlphas(Loop1 + 1).empty()) {
     581           0 :                 ShowWarningError(state, format("{}{}=\"{}\", blank node name in list.", RoutineName, CurrentModuleObject, cAlphas(1)));
     582           0 :                 --state.dataNodeInputMgr->NodeLists(NCount).NumOfNodesInList;
     583           0 :                 if (state.dataNodeInputMgr->NodeLists(NCount).NumOfNodesInList <= 0) {
     584           0 :                     ShowSevereError(state, format("{}{}=\"{}\" does not have any nodes.", RoutineName, CurrentModuleObject, cAlphas(1)));
     585           0 :                     localErrorsFound = true;
     586           0 :                     break;
     587             :                 }
     588           0 :                 continue;
     589             :             }
     590        7054 :             state.dataNodeInputMgr->NodeLists(NCount).NodeNumbers(Loop1) = AssignNodeNumber(
     591        7054 :                 state, state.dataNodeInputMgr->NodeLists(NCount).NodeNames(Loop1), DataLoopNode::NodeFluidType::Blank, localErrorsFound);
     592        7054 :             if (Util::SameString(state.dataNodeInputMgr->NodeLists(NCount).NodeNames(Loop1), state.dataNodeInputMgr->NodeLists(NCount).Name)) {
     593           0 :                 ShowSevereError(state, format("{}{}=\"{}\", invalid node name in list.", RoutineName, CurrentModuleObject, cAlphas(1)));
     594           0 :                 ShowContinueError(state, format("... Node {} Name=\"{}\", duplicates NodeList Name.", Loop1, cAlphas(Loop1 + 1)));
     595           0 :                 localErrorsFound = true;
     596             :             }
     597             :         }
     598             :         // Error on any duplicates
     599        6193 :         flagError = true;
     600       13247 :         for (int Loop1 = 1; Loop1 <= state.dataNodeInputMgr->NodeLists(NCount).NumOfNodesInList; ++Loop1) {
     601        8261 :             for (int Loop2 = Loop1 + 1; Loop2 <= state.dataNodeInputMgr->NodeLists(NCount).NumOfNodesInList; ++Loop2) {
     602        1207 :                 if (state.dataNodeInputMgr->NodeLists(NCount).NodeNumbers(Loop1) != state.dataNodeInputMgr->NodeLists(NCount).NodeNumbers(Loop2))
     603        1207 :                     continue;
     604           0 :                 if (flagError) { // only list nodelist name once
     605           0 :                     ShowSevereError(state, format("{}{}=\"{}\" has duplicate nodes:", RoutineName, CurrentModuleObject, cAlphas(1)));
     606           0 :                     flagError = false;
     607             :                 }
     608           0 :                 ShowContinueError(state,
     609           0 :                                   format("...list item={}, \"{}\", duplicate list item={}, \"{}\".",
     610             :                                          Loop1,
     611           0 :                                          state.dataLoopNodes->NodeID(state.dataNodeInputMgr->NodeLists(NCount).NodeNumbers(Loop1)),
     612             :                                          Loop2,
     613           0 :                                          state.dataLoopNodes->NodeID(state.dataNodeInputMgr->NodeLists(NCount).NodeNumbers(Loop2))));
     614           0 :                 localErrorsFound = true;
     615             :             }
     616             :         }
     617             :     }
     618             : 
     619        6989 :     for (int Loop = 1; Loop <= state.dataNodeInputMgr->NumOfNodeLists; ++Loop) {
     620       13247 :         for (int Loop2 = 1; Loop2 <= state.dataNodeInputMgr->NodeLists(Loop).NumOfNodesInList; ++Loop2) {
     621      236594 :             for (int Loop1 = 1; Loop1 <= state.dataNodeInputMgr->NumOfNodeLists; ++Loop1) {
     622      229540 :                 if (Loop == Loop1) continue; // within a nodelist have already checked to see if node name duplicates nodelist name
     623      222486 :                 if (!Util::SameString(state.dataNodeInputMgr->NodeLists(Loop).NodeNames(Loop2), state.dataNodeInputMgr->NodeLists(Loop1).Name))
     624      222486 :                     continue;
     625           0 :                 ShowSevereError(
     626             :                     state,
     627           0 :                     format(
     628           0 :                         "{}{}=\"{}\", invalid node name in list.", RoutineName, CurrentModuleObject, state.dataNodeInputMgr->NodeLists(Loop1).Name));
     629           0 :                 ShowContinueError(
     630             :                     state,
     631           0 :                     format("... Node {} Name=\"{}\", duplicates NodeList Name.", Loop2, state.dataNodeInputMgr->NodeLists(Loop).NodeNames(Loop2)));
     632           0 :                 ShowContinueError(state, format("... NodeList=\"{}\", is duplicated.", state.dataNodeInputMgr->NodeLists(Loop1).Name));
     633           0 :                 ShowContinueError(state, "... Items in NodeLists must not be the name of another NodeList.");
     634           0 :                 localErrorsFound = true;
     635             :             }
     636             :         }
     637             :     }
     638             : 
     639         796 :     cAlphas.deallocate();
     640         796 :     rNumbers.deallocate();
     641             : 
     642         796 :     if (localErrorsFound) {
     643           0 :         ShowFatalError(state, format("{}{}: Error getting input - causes termination.", RoutineName, CurrentModuleObject));
     644           0 :         ErrorsFound = true;
     645             :     }
     646         796 : }
     647             : 
     648      275611 : int AssignNodeNumber(EnergyPlusData &state,
     649             :                      std::string const &Name,                         // Name for assignment
     650             :                      DataLoopNode::NodeFluidType const nodeFluidType, // must be valid
     651             :                      bool &ErrorsFound)
     652             : {
     653             : 
     654             :     // FUNCTION INFORMATION:
     655             :     //       AUTHOR         Linda K. Lawrie
     656             :     //       DATE WRITTEN   September 1999
     657             :     //       MODIFIED       na
     658             :     //       RE-ENGINEERED  na
     659             : 
     660             :     // PURPOSE OF THIS FUNCTION:
     661             :     // This function assigns a node number to this name.
     662             : 
     663             :     // METHODOLOGY EMPLOYED:
     664             :     // Look to see if a name has already been entered.  Use the index of
     665             :     // the array as the node number, if there.
     666             : 
     667             :     // Return value
     668             :     int AssignNodeNumber;
     669             : 
     670      275611 :     if (nodeFluidType != DataLoopNode::NodeFluidType::Air && nodeFluidType != DataLoopNode::NodeFluidType::Water &&
     671       47321 :         nodeFluidType != DataLoopNode::NodeFluidType::Electric && nodeFluidType != DataLoopNode::NodeFluidType::Steam &&
     672       47104 :         nodeFluidType != DataLoopNode::NodeFluidType::Blank) {
     673           0 :         ShowSevereError(state, format("AssignNodeNumber: Invalid FluidType={}", nodeFluidType));
     674           0 :         ErrorsFound = true;
     675           0 :         ShowFatalError(state, "AssignNodeNumber: Preceding issue causes termination.");
     676             :     }
     677             : 
     678      275611 :     if (state.dataNodeInputMgr->NumOfUniqueNodeNames > 0) {
     679      274883 :         int NumNode = Util::FindItemInList(
     680      549766 :             Name, state.dataLoopNodes->NodeID({1, state.dataNodeInputMgr->NumOfUniqueNodeNames}), state.dataNodeInputMgr->NumOfUniqueNodeNames);
     681      274883 :         if (NumNode > 0) {
     682      213290 :             AssignNodeNumber = NumNode;
     683      213290 :             ++state.dataNodeInputMgr->NodeRef(NumNode);
     684      213290 :             if (nodeFluidType != DataLoopNode::NodeFluidType::Blank) {
     685      235560 :                 if (state.dataLoopNodes->Node(NumNode).FluidType != nodeFluidType &&
     686       31618 :                     state.dataLoopNodes->Node(NumNode).FluidType != DataLoopNode::NodeFluidType::Blank) {
     687           0 :                     ShowSevereError(state,
     688           0 :                                     format("Existing Fluid type for node, incorrect for request. Node={}", state.dataLoopNodes->NodeID(NumNode)));
     689           0 :                     ShowContinueError(
     690             :                         state,
     691           0 :                         format("Existing Fluid type={}, Requested Fluid Type={}",
     692           0 :                                format("{}", DataLoopNode::NodeFluidTypeNames[static_cast<int>(state.dataLoopNodes->Node(NumNode).FluidType)]),
     693           0 :                                format("{}", DataLoopNode::NodeFluidTypeNames[static_cast<int>(nodeFluidType)])));
     694           0 :                     ErrorsFound = true;
     695             :                 }
     696             :             }
     697      213290 :             if (state.dataLoopNodes->Node(NumNode).FluidType == DataLoopNode::NodeFluidType::Blank) {
     698       38445 :                 state.dataLoopNodes->Node(NumNode).FluidType = nodeFluidType;
     699             :             }
     700             :         } else {
     701       61593 :             ++state.dataNodeInputMgr->NumOfUniqueNodeNames;
     702       61593 :             state.dataLoopNodes->NumOfNodes = state.dataNodeInputMgr->NumOfUniqueNodeNames;
     703             : 
     704       61593 :             state.dataLoopNodes->Node.redimension(state.dataLoopNodes->NumOfNodes);
     705       61593 :             state.dataLoopNodes->NodeID.redimension({0, state.dataLoopNodes->NumOfNodes});
     706       61593 :             state.dataNodeInputMgr->NodeRef.redimension(state.dataLoopNodes->NumOfNodes);
     707       61593 :             state.dataLoopNodes->MarkedNode.redimension(state.dataLoopNodes->NumOfNodes);
     708       61593 :             state.dataLoopNodes->NodeSetpointCheck.redimension(state.dataLoopNodes->NumOfNodes);
     709             :             // Set new item in Node
     710       61593 :             state.dataLoopNodes->Node(state.dataLoopNodes->NumOfNodes).FluidType = nodeFluidType;
     711       61593 :             state.dataNodeInputMgr->NodeRef(state.dataLoopNodes->NumOfNodes) = 0;
     712       61593 :             state.dataLoopNodes->NodeID(state.dataNodeInputMgr->NumOfUniqueNodeNames) = Name;
     713             : 
     714       61593 :             AssignNodeNumber = state.dataNodeInputMgr->NumOfUniqueNodeNames;
     715             :         }
     716             :     } else {
     717         728 :         state.dataLoopNodes->Node.allocate(1);
     718         728 :         state.dataLoopNodes->Node(1).FluidType = nodeFluidType;
     719             :         // Allocate takes care of defining
     720         728 :         state.dataLoopNodes->NumOfNodes = 1;
     721         728 :         state.dataLoopNodes->NodeID.allocate({0, 1});
     722         728 :         state.dataNodeInputMgr->NodeRef.allocate(1);
     723         728 :         state.dataLoopNodes->MarkedNode.allocate(1);
     724         728 :         state.dataLoopNodes->NodeSetpointCheck.allocate(1);
     725             : 
     726         728 :         state.dataNodeInputMgr->NumOfUniqueNodeNames = 1;
     727         728 :         state.dataLoopNodes->NodeID(0) = "Undefined";
     728         728 :         state.dataLoopNodes->NodeID(state.dataNodeInputMgr->NumOfUniqueNodeNames) = Name;
     729         728 :         AssignNodeNumber = 1;
     730         728 :         state.dataNodeInputMgr->NodeRef(1) = 0;
     731             :     }
     732             : 
     733      275611 :     return AssignNodeNumber;
     734             : }
     735             : 
     736      222512 : int GetOnlySingleNode(EnergyPlusData &state,
     737             :                       std::string const &NodeName,
     738             :                       bool &errFlag,
     739             :                       DataLoopNode::ConnectionObjectType const NodeObjectType, // Node Object Type (i.e. "Chiller:Electric")
     740             :                       std::string const &NodeObjectName,                       // Node Object Name (i.e. "MyChiller")
     741             :                       DataLoopNode::NodeFluidType const nodeFluidType,         // Fluidtype for checking/setting node FluidType
     742             :                       DataLoopNode::ConnectionType const nodeConnectionType,   // Node Connection Type (see DataLoopNode)
     743             :                       CompFluidStream const NodeFluidStream,                   // Which Fluid Stream
     744             :                       bool const ObjectIsParent,                               // True/False
     745             :                       std::string_view const InputFieldName                    // Input Field Name
     746             : )
     747             : {
     748             : 
     749             :     // FUNCTION INFORMATION:
     750             :     //       AUTHOR         Linda K. Lawrie; adapted from GasAbsorptionChiller;Jason Glazer
     751             :     //       DATE WRITTEN   December 2001
     752             : 
     753             :     // PURPOSE OF THIS FUNCTION:
     754             :     // This function gets a single node (or error message results) using the
     755             :     // node id from the input file.
     756             : 
     757             :     static constexpr std::string_view RoutineName("GetOnlySingleNode: ");
     758             : 
     759             :     int NumNodes;
     760             : 
     761      222512 :     std::string_view const objTypeStr = BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(NodeObjectType)];
     762             : 
     763      222512 :     if (state.dataNodeInputMgr->GetOnlySingleNodeFirstTime) {
     764             :         int NumParams;
     765             :         int NumAlphas;
     766             :         int NumNums;
     767         728 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "NodeList", NumParams, NumAlphas, NumNums);
     768         728 :         state.dataNodeInputMgr->GetOnlySingleNodeNodeNums.dimension(NumParams, 0);
     769         728 :         state.dataNodeInputMgr->GetOnlySingleNodeFirstTime = false;
     770             :     }
     771             : 
     772      445024 :     GetNodeNums(state,
     773             :                 NodeName,
     774             :                 NumNodes,
     775      222512 :                 state.dataNodeInputMgr->GetOnlySingleNodeNodeNums,
     776             :                 errFlag,
     777             :                 nodeFluidType,
     778             :                 NodeObjectType,
     779             :                 NodeObjectName,
     780             :                 nodeConnectionType,
     781             :                 NodeFluidStream,
     782             :                 ObjectIsParent,
     783             :                 false,
     784             :                 InputFieldName);
     785             : 
     786      222512 :     if (NumNodes > 1) {
     787           0 :         ShowSevereError(state, format("{}{}=\"{}=\", invalid data.", RoutineName, objTypeStr, NodeObjectName));
     788           0 :         if (!InputFieldName.empty()) {
     789           0 :             ShowContinueError(state, fmt::format("...Ref field={}", InputFieldName));
     790             :         }
     791           0 :         ShowContinueError(state, format("Only 1st Node used from NodeList=\"{}\".", NodeName));
     792           0 :         ShowContinueError(state, "...a Nodelist may not be valid in this context.");
     793           0 :         errFlag = true;
     794      222512 :     } else if (NumNodes == 0) {
     795        1203 :         state.dataNodeInputMgr->GetOnlySingleNodeNodeNums(1) = 0;
     796             :     }
     797             : 
     798      222512 :     return state.dataNodeInputMgr->GetOnlySingleNodeNodeNums(1);
     799             : }
     800             : 
     801        1072 : void InitUniqueNodeCheck(EnergyPlusData &state, std::string const &ContextName)
     802             : {
     803             : 
     804             :     // SUBROUTINE INFORMATION:
     805             :     //       AUTHOR         Linda Lawrie
     806             :     //       DATE WRITTEN   November 2002
     807             :     //       MODIFIED       na
     808             :     //       RE-ENGINEERED  na
     809             : 
     810             :     // PURPOSE OF THIS SUBROUTINE:
     811             :     // This subroutine begins a process of checking for unique node names
     812             :     // in a sequence of nodes.
     813             : 
     814             :     // Begin set up of Uniqueness context
     815             : 
     816        1072 :     if (state.dataNodeInputMgr->GetNodeInputFlag) {
     817         163 :         bool errFlag(false);
     818         163 :         GetNodeListsInput(state, errFlag);
     819         163 :         state.dataNodeInputMgr->GetNodeInputFlag = false;
     820             :     }
     821             : 
     822        1072 :     if (!state.dataNodeInputMgr->CurCheckContextName.empty()) {
     823           0 :         ShowFatalError(state,
     824           0 :                        format("Init Uniqueness called for \"{}, but checks for \"{}\" was already in progress.",
     825             :                               ContextName,
     826           0 :                               state.dataNodeInputMgr->CurCheckContextName));
     827             :     }
     828        1072 :     if (ContextName.empty()) {
     829           0 :         ShowFatalError(state, "Init Uniqueness called with Blank Context Name");
     830             :     }
     831        1072 :     if (allocated(state.dataNodeInputMgr->UniqueNodeNames)) {
     832           0 :         state.dataNodeInputMgr->UniqueNodeNames.deallocate();
     833             :     }
     834             : 
     835        1072 :     state.dataNodeInputMgr->NumCheckNodes = 0;
     836        1072 :     state.dataNodeInputMgr->MaxCheckNodes = 100;
     837        1072 :     state.dataNodeInputMgr->UniqueNodeNames.allocate(state.dataNodeInputMgr->MaxCheckNodes);
     838        1072 :     state.dataNodeInputMgr->CurCheckContextName = ContextName;
     839        1072 : }
     840             : 
     841        4551 : void CheckUniqueNodeNames(
     842             :     EnergyPlusData &state, std::string const &NodeTypes, bool &ErrorsFound, std::string const &CheckName, std::string const &ObjectName)
     843             : {
     844             : 
     845             :     // SUBROUTINE INFORMATION:
     846             :     //       AUTHOR         Linda Lawrie
     847             :     //       DATE WRITTEN   November 2002
     848             :     //       MODIFIED       na
     849             :     //       RE-ENGINEERED  na
     850             : 
     851             :     // PURPOSE OF THIS SUBROUTINE:
     852             :     // This subroutine checks the appropriate input argument for uniqueness.
     853             :     // Call CheckUniqueNodes(NodeTypes,CheckType,ErrorsFound,CheckName,CheckNumber)
     854             :     // NodeTypes - used in error message (if any produced)
     855             :     // ErrorsFound - true if error found by routine
     856             :     // CheckName - NodeName entered
     857             :     // ObjectName - "Name" field of object (i.e., CurCheckContextName)
     858             : 
     859             :     // METHODOLOGY EMPLOYED:
     860             :     // checks the current list of items for this (again)
     861             : 
     862        4551 :     if (!CheckName.empty()) {
     863        4551 :         int Found = Util::FindItemInList(CheckName, state.dataNodeInputMgr->UniqueNodeNames, state.dataNodeInputMgr->NumCheckNodes);
     864        4551 :         if (Found != 0) {
     865           0 :             ShowSevereError(state, format("{}=\"{}\", duplicate node names found.", state.dataNodeInputMgr->CurCheckContextName, ObjectName));
     866           0 :             ShowContinueError(state, format("...for Node Type(s)={}, duplicate node name=\"{}\".", NodeTypes, CheckName));
     867           0 :             ShowContinueError(state, "...Nodes must be unique across instances of this object.");
     868             :             //          CALL ShowSevereError(state, 'Node Types='//TRIM(NodeTypes)//', Non Unique Name found='//TRIM(CheckName))
     869             :             //          CALL ShowContinueError(state, 'Context='//TRIM(CurCheckContextName))
     870           0 :             ErrorsFound = true;
     871             :         } else {
     872        4551 :             ++state.dataNodeInputMgr->NumCheckNodes;
     873        4551 :             if (state.dataNodeInputMgr->NumCheckNodes > state.dataNodeInputMgr->MaxCheckNodes) {
     874           7 :                 state.dataNodeInputMgr->UniqueNodeNames.redimension(state.dataNodeInputMgr->MaxCheckNodes += 100);
     875             :             }
     876        4551 :             state.dataNodeInputMgr->UniqueNodeNames(state.dataNodeInputMgr->NumCheckNodes) = CheckName;
     877             :         }
     878             :     }
     879        4551 : }
     880             : 
     881        9676 : void CheckUniqueNodeNumbers(
     882             :     EnergyPlusData &state, std::string const &NodeTypes, bool &ErrorsFound, int const CheckNumber, std::string const &ObjectName)
     883             : {
     884             : 
     885             :     // SUBROUTINE INFORMATION:
     886             :     //       AUTHOR         Linda Lawrie
     887             :     //       DATE WRITTEN   November 2002
     888             :     //       MODIFIED       na
     889             :     //       RE-ENGINEERED  na
     890             : 
     891             :     // PURPOSE OF THIS SUBROUTINE:
     892             :     // This subroutine checks the appropriate input argument for uniqueness.
     893             :     // Call CheckUniqueNodes(NodeTypes,CheckType,ErrorsFound,CheckName,CheckNumber)
     894             :     // NodeTypes - used in error message (if any produced)
     895             :     // ErrorsFound - true if error found by routine
     896             :     // CheckNumber - Node Number entered
     897             :     // ObjectName - "Name" field of object (i.e., CurCheckContextName)
     898             : 
     899             :     // METHODOLOGY EMPLOYED:
     900             :     // checks the current list of items for this (again)
     901             : 
     902        9676 :     if (CheckNumber != 0) {
     903        9676 :         int Found = Util::FindItemInList(
     904        9676 :             state.dataLoopNodes->NodeID(CheckNumber), state.dataNodeInputMgr->UniqueNodeNames, state.dataNodeInputMgr->NumCheckNodes);
     905        9676 :         if (Found != 0) {
     906           0 :             ShowSevereError(state, format("{}=\"{}\", duplicate node names found.", state.dataNodeInputMgr->CurCheckContextName, ObjectName));
     907           0 :             ShowContinueError(state,
     908           0 :                               format("...for Node Type(s)={}, duplicate node name=\"{}\".", NodeTypes, state.dataLoopNodes->NodeID(CheckNumber)));
     909           0 :             ShowContinueError(state, "...Nodes must be unique across instances of this object.");
     910           0 :             ErrorsFound = true;
     911             :         } else {
     912        9676 :             ++state.dataNodeInputMgr->NumCheckNodes;
     913        9676 :             if (state.dataNodeInputMgr->NumCheckNodes > state.dataNodeInputMgr->MaxCheckNodes) {
     914          23 :                 state.dataNodeInputMgr->UniqueNodeNames.redimension(state.dataNodeInputMgr->MaxCheckNodes += 100);
     915             :             }
     916        9676 :             state.dataNodeInputMgr->UniqueNodeNames(state.dataNodeInputMgr->NumCheckNodes) = state.dataLoopNodes->NodeID(CheckNumber);
     917             :         }
     918             :     }
     919        9676 : }
     920             : 
     921        1072 : void EndUniqueNodeCheck(EnergyPlusData &state, std::string const &ContextName)
     922             : {
     923             : 
     924             :     // SUBROUTINE INFORMATION:
     925             :     //       AUTHOR         Linda Lawrie
     926             :     //       DATE WRITTEN   November 2002
     927             :     //       MODIFIED       na
     928             :     //       RE-ENGINEERED  na
     929             : 
     930             :     // PURPOSE OF THIS SUBROUTINE:
     931             :     // This subroutine marks the end of a unique node check.
     932             : 
     933        1072 :     if (state.dataNodeInputMgr->CurCheckContextName != ContextName) {
     934           0 :         ShowFatalError(state,
     935           0 :                        format("End Uniqueness called for \"{}, but checks for \"{}\" was in progress.",
     936             :                               ContextName,
     937           0 :                               state.dataNodeInputMgr->CurCheckContextName));
     938             :     }
     939        1072 :     if (ContextName.empty()) {
     940           0 :         ShowFatalError(state, "End Uniqueness called with Blank Context Name");
     941             :     }
     942        1072 :     state.dataNodeInputMgr->CurCheckContextName = std::string();
     943        1072 :     if (allocated(state.dataNodeInputMgr->UniqueNodeNames)) {
     944        1072 :         state.dataNodeInputMgr->UniqueNodeNames.deallocate();
     945             :     }
     946        1072 : }
     947             : 
     948     1097533 : void CalcMoreNodeInfo(EnergyPlusData &state)
     949             : {
     950             : 
     951             :     // SUBROUTINE INFORMATION:
     952             :     //       AUTHOR         Fred Buhl
     953             :     //       DATE WRITTEN   January 2004
     954             :     //       MODIFIED       na
     955             :     //       RE-ENGINEERED  na
     956             : 
     957             :     // PURPOSE OF THIS SUBROUTINE:
     958             :     // Calculate additional node information for reporting
     959             : 
     960             :     // METHODOLOGY EMPLOYED:
     961             :     // Input is the existing node data plus environment variables. Output is
     962             :     // stored in MoreNodeInfo.
     963             : 
     964             :     // Using/Aliasing
     965             :     using FluidProperties::GetDensityGlycol;
     966             :     using FluidProperties::GetSatDensityRefrig;
     967             :     using FluidProperties::GetSatEnthalpyRefrig;
     968             :     using FluidProperties::GetSpecificHeatGlycol;
     969             :     using Psychrometrics::CPCW;
     970             :     using Psychrometrics::PsyCpAirFnW;
     971             :     using Psychrometrics::PsyHFnTdbW;
     972             :     using Psychrometrics::PsyRhFnTdbWPb;
     973             :     using Psychrometrics::PsyRhoAirFnPbTdbW;
     974             :     using Psychrometrics::PsyTdpFnWPb;
     975             :     using Psychrometrics::PsyTwbFnTdbWPb;
     976             :     using Psychrometrics::RhoH2O;
     977             :     using ScheduleManager::GetCurrentScheduleValue;
     978             : 
     979             :     // SUBROUTINE PARAMETER DEFINITIONS:
     980             :     static constexpr std::string_view RoutineName("CalcMoreNodeInfo");
     981     1097533 :     static std::string const NodeReportingCalc("NodeReportingCalc:");
     982             : 
     983     1097533 :     auto &RhoAirStdInit = state.dataNodeInputMgr->RhoAirStdInit;
     984     1097533 :     auto &RhoWaterStdInit = state.dataNodeInputMgr->RhoWaterStdInit;
     985     1097533 :     auto &NodeWetBulbSchedPtr = state.dataNodeInputMgr->NodeWetBulbSchedPtr;
     986     1097533 :     auto &NodeRelHumidityRepReq = state.dataNodeInputMgr->NodeRelHumidityRepReq;
     987     1097533 :     auto &NodeRelHumiditySchedPtr = state.dataNodeInputMgr->NodeRelHumiditySchedPtr;
     988     1097533 :     auto &NodeDewPointRepReq = state.dataNodeInputMgr->NodeDewPointRepReq;
     989     1097533 :     auto &NodeDewPointSchedPtr = state.dataNodeInputMgr->NodeDewPointSchedPtr;
     990     1097533 :     auto &NodeSpecificHeatRepReq = state.dataNodeInputMgr->NodeSpecificHeatRepReq;
     991     1097533 :     auto &NodeSpecificHeatSchedPtr = state.dataNodeInputMgr->NodeSpecificHeatSchedPtr;
     992     1097533 :     auto &nodeReportingStrings = state.dataNodeInputMgr->nodeReportingStrings;
     993     1097533 :     auto &nodeFluidNames = state.dataNodeInputMgr->nodeFluidNames;
     994             :     Real64 SteamDensity;
     995             :     Real64 EnthSteamInDry;
     996             :     Real64 RhoAirCurrent; // temporary value for current air density f(baro, db , W)
     997             :     Real64 rho;
     998             :     Real64 Cp;
     999             :     Real64 rhoStd;
    1000             : 
    1001     1097533 :     if (state.dataNodeInputMgr->CalcMoreNodeInfoMyOneTimeFlag) {
    1002         794 :         RhoAirStdInit = state.dataEnvrn->StdRhoAir;
    1003         794 :         RhoWaterStdInit = RhoH2O(Constant::InitConvTemp);
    1004         794 :         state.dataNodeInputMgr->NodeWetBulbRepReq.allocate(state.dataLoopNodes->NumOfNodes);
    1005         794 :         NodeWetBulbSchedPtr.allocate(state.dataLoopNodes->NumOfNodes);
    1006         794 :         NodeRelHumidityRepReq.allocate(state.dataLoopNodes->NumOfNodes);
    1007         794 :         NodeRelHumiditySchedPtr.allocate(state.dataLoopNodes->NumOfNodes);
    1008         794 :         NodeDewPointRepReq.allocate(state.dataLoopNodes->NumOfNodes);
    1009         794 :         NodeDewPointSchedPtr.allocate(state.dataLoopNodes->NumOfNodes);
    1010         794 :         NodeSpecificHeatRepReq.allocate(state.dataLoopNodes->NumOfNodes);
    1011         794 :         NodeSpecificHeatSchedPtr.allocate(state.dataLoopNodes->NumOfNodes);
    1012         794 :         nodeReportingStrings.reserve(state.dataLoopNodes->NumOfNodes);
    1013         794 :         nodeFluidNames.reserve(state.dataLoopNodes->NumOfNodes);
    1014         794 :         state.dataNodeInputMgr->NodeWetBulbRepReq = false;
    1015         794 :         NodeWetBulbSchedPtr = 0;
    1016         794 :         NodeRelHumidityRepReq = false;
    1017         794 :         NodeRelHumiditySchedPtr = 0;
    1018         794 :         NodeDewPointRepReq = false;
    1019         794 :         NodeDewPointSchedPtr = 0;
    1020         794 :         NodeSpecificHeatRepReq = false;
    1021         794 :         NodeSpecificHeatSchedPtr = 0;
    1022             : 
    1023       62943 :         for (int iNode = 1; iNode <= state.dataLoopNodes->NumOfNodes; ++iNode) {
    1024       62149 :             nodeReportingStrings.push_back(std::string(NodeReportingCalc + state.dataLoopNodes->NodeID(iNode)));
    1025       62149 :             nodeFluidNames.push_back(FluidProperties::GetGlycolNameByIndex(state, state.dataLoopNodes->Node(iNode).FluidIndex));
    1026             : 
    1027     2036901 :             for (auto const *reqVar : state.dataOutputProcessor->reqVars) {
    1028     1974752 :                 if (Util::SameString(reqVar->key, state.dataLoopNodes->NodeID(iNode)) || reqVar->key.empty()) {
    1029     1132803 :                     if (Util::SameString(reqVar->name, "System Node Wetbulb Temperature")) {
    1030         157 :                         state.dataNodeInputMgr->NodeWetBulbRepReq(iNode) = true;
    1031         157 :                         NodeWetBulbSchedPtr(iNode) = reqVar->SchedPtr;
    1032     1132646 :                     } else if (Util::SameString(reqVar->name, "System Node Relative Humidity")) {
    1033          22 :                         NodeRelHumidityRepReq(iNode) = true;
    1034          22 :                         NodeRelHumiditySchedPtr(iNode) = reqVar->SchedPtr;
    1035     1132624 :                     } else if (Util::SameString(reqVar->name, "System Node Dewpoint Temperature")) {
    1036          22 :                         NodeDewPointRepReq(iNode) = true;
    1037          22 :                         NodeDewPointSchedPtr(iNode) = reqVar->SchedPtr;
    1038     1132602 :                     } else if (Util::SameString(reqVar->name, "System Node Specific Heat")) {
    1039           0 :                         NodeSpecificHeatRepReq(iNode) = true;
    1040           0 :                         NodeSpecificHeatSchedPtr(iNode) = reqVar->SchedPtr;
    1041             :                     }
    1042             :                 }
    1043       62149 :             }
    1044       62149 :             if (EMSManager::CheckIfNodeMoreInfoSensedByEMS(state, iNode, "System Node Wetbulb Temperature")) {
    1045           0 :                 state.dataNodeInputMgr->NodeWetBulbRepReq(iNode) = true;
    1046           0 :                 NodeWetBulbSchedPtr(iNode) = 0;
    1047             :             }
    1048       62149 :             if (EMSManager::CheckIfNodeMoreInfoSensedByEMS(state, iNode, "System Node Relative Humidity")) {
    1049           1 :                 NodeRelHumidityRepReq(iNode) = true;
    1050           1 :                 NodeRelHumiditySchedPtr(iNode) = 0;
    1051             :             }
    1052       62149 :             if (EMSManager::CheckIfNodeMoreInfoSensedByEMS(state, iNode, "System Node Dewpoint Temperature")) {
    1053           0 :                 NodeDewPointRepReq(iNode) = true;
    1054           0 :                 NodeDewPointSchedPtr(iNode) = 0;
    1055             :             }
    1056       62149 :             if (EMSManager::CheckIfNodeMoreInfoSensedByEMS(state, iNode, "System Node Specific Heat")) {
    1057           0 :                 NodeSpecificHeatRepReq(iNode) = true;
    1058           0 :                 NodeSpecificHeatSchedPtr(iNode) = 0;
    1059             :             }
    1060             :         }
    1061         794 :         state.dataNodeInputMgr->CalcMoreNodeInfoMyOneTimeFlag = false;
    1062             :     }
    1063             : 
    1064    66713253 :     for (int iNode = 1; iNode <= state.dataLoopNodes->NumOfNodes; ++iNode) {
    1065    65615720 :         bool ReportWetBulb = false;
    1066    65615720 :         bool ReportRelHumidity = false;
    1067    65615720 :         bool ReportDewPoint = false;
    1068    65615720 :         bool ReportSpecificHeat = false;
    1069    65615720 :         if (state.dataNodeInputMgr->NodeWetBulbRepReq(iNode) && NodeWetBulbSchedPtr(iNode) > 0) {
    1070           0 :             ReportWetBulb = (GetCurrentScheduleValue(state, NodeWetBulbSchedPtr(iNode)) > 0.0);
    1071    65615720 :         } else if (state.dataNodeInputMgr->NodeWetBulbRepReq(iNode) && NodeWetBulbSchedPtr(iNode) == 0) {
    1072       82194 :             ReportWetBulb = true;
    1073    65533526 :         } else if (state.dataLoopNodes->Node(iNode).SPMNodeWetBulbRepReq) {
    1074         674 :             ReportWetBulb = true;
    1075             :         }
    1076    65615720 :         if (NodeRelHumidityRepReq(iNode) && NodeRelHumiditySchedPtr(iNode) > 0) {
    1077           0 :             ReportRelHumidity = (GetCurrentScheduleValue(state, NodeRelHumiditySchedPtr(iNode)) > 0.0);
    1078    65615720 :         } else if (NodeRelHumidityRepReq(iNode) && NodeRelHumiditySchedPtr(iNode) == 0) {
    1079       12978 :             ReportRelHumidity = true;
    1080             :         }
    1081    65615720 :         if (NodeDewPointRepReq(iNode) && NodeDewPointSchedPtr(iNode) > 0) {
    1082           0 :             ReportDewPoint = (GetCurrentScheduleValue(state, NodeDewPointSchedPtr(iNode)) > 0.0);
    1083    65615720 :         } else if (NodeDewPointRepReq(iNode) && NodeDewPointSchedPtr(iNode) == 0) {
    1084      172250 :             ReportDewPoint = true;
    1085             :         }
    1086    65615720 :         if (NodeSpecificHeatRepReq(iNode) && NodeSpecificHeatSchedPtr(iNode) > 0) {
    1087           0 :             ReportSpecificHeat = (GetCurrentScheduleValue(state, NodeSpecificHeatSchedPtr(iNode)) > 0.0);
    1088    65615720 :         } else if (NodeSpecificHeatRepReq(iNode) && NodeSpecificHeatSchedPtr(iNode) == 0) {
    1089           0 :             ReportSpecificHeat = true;
    1090             :         }
    1091             :         // calculate the volume flow rate
    1092    65615720 :         if (state.dataLoopNodes->Node(iNode).FluidType == DataLoopNode::NodeFluidType::Air) {
    1093    39109161 :             state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateStdRho = state.dataLoopNodes->Node(iNode).MassFlowRate / RhoAirStdInit;
    1094             :             // if Node%Press was reliable could be used here.
    1095    78218322 :             RhoAirCurrent = PsyRhoAirFnPbTdbW(
    1096    39109161 :                 state, state.dataEnvrn->OutBaroPress, state.dataLoopNodes->Node(iNode).Temp, state.dataLoopNodes->Node(iNode).HumRat);
    1097    39109161 :             state.dataLoopNodes->MoreNodeInfo(iNode).Density = RhoAirCurrent;
    1098    39109161 :             if (RhoAirCurrent != 0.0)
    1099    39109161 :                 state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateCrntRho = state.dataLoopNodes->Node(iNode).MassFlowRate / RhoAirCurrent;
    1100    39109161 :             state.dataLoopNodes->MoreNodeInfo(iNode).ReportEnthalpy =
    1101    39109161 :                 PsyHFnTdbW(state.dataLoopNodes->Node(iNode).Temp, state.dataLoopNodes->Node(iNode).HumRat);
    1102    39109161 :             if (ReportWetBulb) {
    1103             :                 // if Node%Press was reliable could be used here.
    1104      165736 :                 state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = PsyTwbFnTdbWPb(state,
    1105       82868 :                                                                                       state.dataLoopNodes->Node(iNode).Temp,
    1106       82868 :                                                                                       state.dataLoopNodes->Node(iNode).HumRat,
    1107       82868 :                                                                                       state.dataEnvrn->OutBaroPress,
    1108       82868 :                                                                                       nodeReportingStrings[iNode - 1]);
    1109             :             } else {
    1110    39026293 :                 state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = 0.0;
    1111             :             }
    1112    39109161 :             if (ReportDewPoint) {
    1113      172250 :                 state.dataLoopNodes->MoreNodeInfo(iNode).AirDewPointTemp =
    1114      344500 :                     PsyTdpFnWPb(state, state.dataLoopNodes->Node(iNode).HumRat, state.dataEnvrn->OutBaroPress);
    1115             :             } else {
    1116    38936911 :                 state.dataLoopNodes->MoreNodeInfo(iNode).AirDewPointTemp = 0.0;
    1117             :             }
    1118    39109161 :             if (ReportRelHumidity) {
    1119             :                 // if Node%Press was reliable could be used here.
    1120             :                 // following routines don't issue psych errors and may be more reliable.
    1121       25956 :                 state.dataLoopNodes->MoreNodeInfo(iNode).RelHumidity = 100.0 * PsyRhFnTdbWPb(state,
    1122       12978 :                                                                                              state.dataLoopNodes->Node(iNode).Temp,
    1123       12978 :                                                                                              state.dataLoopNodes->Node(iNode).HumRat,
    1124       12978 :                                                                                              state.dataEnvrn->OutBaroPress,
    1125       12978 :                                                                                              nodeReportingStrings[iNode - 1]);
    1126             :             } else {
    1127    39096183 :                 state.dataLoopNodes->MoreNodeInfo(iNode).RelHumidity = 0.0;
    1128             :             }
    1129    39109161 :             if (ReportSpecificHeat) { // only call psych routine if needed.
    1130           0 :                 state.dataLoopNodes->MoreNodeInfo(iNode).SpecificHeat = PsyCpAirFnW(state.dataLoopNodes->Node(iNode).HumRat);
    1131             :             } else {
    1132    39109161 :                 state.dataLoopNodes->MoreNodeInfo(iNode).SpecificHeat = 0.0;
    1133             :             }
    1134    26506559 :         } else if (state.dataLoopNodes->Node(iNode).FluidType == DataLoopNode::NodeFluidType::Water) {
    1135             : 
    1136    52782174 :             if (!((state.dataLoopNodes->Node(iNode).FluidIndex > 0) &&
    1137    26369836 :                   (state.dataLoopNodes->Node(iNode).FluidIndex <= state.dataFluidProps->glycols.isize()))) {
    1138       42502 :                 rho = RhoWaterStdInit;
    1139       42502 :                 rhoStd = RhoWaterStdInit;
    1140       42502 :                 Cp = CPCW(state.dataLoopNodes->Node(iNode).Temp);
    1141             :             } else {
    1142    52739672 :                 Cp = GetSpecificHeatGlycol(state,
    1143    26369836 :                                            nodeFluidNames[iNode - 1],
    1144    26369836 :                                            state.dataLoopNodes->Node(iNode).Temp,
    1145    26369836 :                                            state.dataLoopNodes->Node(iNode).FluidIndex,
    1146    26369836 :                                            nodeReportingStrings[iNode - 1]);
    1147    52739672 :                 rhoStd = GetDensityGlycol(state,
    1148    26369836 :                                           nodeFluidNames[iNode - 1],
    1149             :                                           Constant::InitConvTemp,
    1150    26369836 :                                           state.dataLoopNodes->Node(iNode).FluidIndex,
    1151    26369836 :                                           nodeReportingStrings[iNode - 1]);
    1152    52739672 :                 rho = GetDensityGlycol(state,
    1153    26369836 :                                        nodeFluidNames[iNode - 1],
    1154    26369836 :                                        state.dataLoopNodes->Node(iNode).Temp,
    1155    26369836 :                                        state.dataLoopNodes->Node(iNode).FluidIndex,
    1156    26369836 :                                        nodeReportingStrings[iNode - 1]);
    1157             :             }
    1158             : 
    1159    26412338 :             state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateStdRho = state.dataLoopNodes->Node(iNode).MassFlowRate / rhoStd;
    1160    26412338 :             state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateCrntRho = state.dataLoopNodes->Node(iNode).MassFlowRate / rho;
    1161    26412338 :             state.dataLoopNodes->MoreNodeInfo(iNode).Density = rho;
    1162    26412338 :             state.dataLoopNodes->MoreNodeInfo(iNode).ReportEnthalpy = Cp * state.dataLoopNodes->Node(iNode).Temp;
    1163    26412338 :             state.dataLoopNodes->MoreNodeInfo(iNode).SpecificHeat = Cp; // always fill since cp already always being calculated anyway
    1164    26412338 :             state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = 0.0;
    1165    26412338 :             state.dataLoopNodes->MoreNodeInfo(iNode).RelHumidity = 100.0;
    1166       94221 :         } else if (state.dataLoopNodes->Node(iNode).FluidType == DataLoopNode::NodeFluidType::Steam) {
    1167       72608 :             if (state.dataLoopNodes->Node(iNode).Quality == 1.0) {
    1168       49613 :                 SteamDensity = GetSatDensityRefrig(state,
    1169             :                                                    fluidNameSteam,
    1170       49613 :                                                    state.dataLoopNodes->Node(iNode).Temp,
    1171       49613 :                                                    state.dataLoopNodes->Node(iNode).Quality,
    1172       49613 :                                                    state.dataLoopNodes->Node(iNode).FluidIndex,
    1173             :                                                    RoutineName);
    1174       49613 :                 EnthSteamInDry = GetSatEnthalpyRefrig(state,
    1175             :                                                       fluidNameSteam,
    1176       49613 :                                                       state.dataLoopNodes->Node(iNode).Temp,
    1177       49613 :                                                       state.dataLoopNodes->Node(iNode).Quality,
    1178       49613 :                                                       state.dataLoopNodes->Node(iNode).FluidIndex,
    1179             :                                                       RoutineName);
    1180       49613 :                 state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateStdRho = state.dataLoopNodes->Node(iNode).MassFlowRate / SteamDensity;
    1181       49613 :                 state.dataLoopNodes->MoreNodeInfo(iNode).ReportEnthalpy = EnthSteamInDry;
    1182       49613 :                 state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = 0.0;
    1183       49613 :                 state.dataLoopNodes->MoreNodeInfo(iNode).RelHumidity = 0.0;
    1184       22995 :             } else if (state.dataLoopNodes->Node(iNode).Quality == 0.0) { // The node has condensate water through it
    1185       22035 :                 state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateStdRho = state.dataLoopNodes->Node(iNode).MassFlowRate / RhoWaterStdInit;
    1186       22035 :                 state.dataLoopNodes->MoreNodeInfo(iNode).ReportEnthalpy =
    1187       22035 :                     CPCW(state.dataLoopNodes->Node(iNode).Temp) * state.dataLoopNodes->Node(iNode).Temp;
    1188       22035 :                 state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = 0.0;
    1189       22035 :                 state.dataLoopNodes->MoreNodeInfo(iNode).RelHumidity = 0.0;
    1190             :             }
    1191       21613 :         } else if (state.dataLoopNodes->Node(iNode).FluidType == DataLoopNode::NodeFluidType::Electric) {
    1192        6544 :             state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateStdRho = 0.0;
    1193        6544 :             state.dataLoopNodes->MoreNodeInfo(iNode).ReportEnthalpy = 0.0;
    1194        6544 :             state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = 0.0;
    1195        6544 :             state.dataLoopNodes->MoreNodeInfo(iNode).RelHumidity = 0.0;
    1196        6544 :             state.dataLoopNodes->MoreNodeInfo(iNode).SpecificHeat = 0.0;
    1197             :         } else {
    1198       15069 :             state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateStdRho = state.dataLoopNodes->Node(iNode).MassFlowRate / RhoAirStdInit;
    1199       15069 :             if (state.dataLoopNodes->Node(iNode).HumRat > 0.0) {
    1200           0 :                 state.dataLoopNodes->MoreNodeInfo(iNode).ReportEnthalpy =
    1201           0 :                     PsyHFnTdbW(state.dataLoopNodes->Node(iNode).Temp, state.dataLoopNodes->Node(iNode).HumRat);
    1202           0 :                 if (ReportWetBulb) {
    1203           0 :                     state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = PsyTwbFnTdbWPb(
    1204           0 :                         state, state.dataLoopNodes->Node(iNode).Temp, state.dataLoopNodes->Node(iNode).HumRat, state.dataEnvrn->StdBaroPress);
    1205             :                 } else {
    1206           0 :                     state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = 0.0;
    1207             :                 }
    1208           0 :                 if (ReportSpecificHeat) {
    1209           0 :                     state.dataLoopNodes->MoreNodeInfo(iNode).SpecificHeat = PsyCpAirFnW(state.dataLoopNodes->Node(iNode).HumRat);
    1210             :                 } else {
    1211           0 :                     state.dataLoopNodes->MoreNodeInfo(iNode).SpecificHeat = 0.0;
    1212             :                 }
    1213             :             } else {
    1214       15069 :                 state.dataLoopNodes->MoreNodeInfo(iNode).ReportEnthalpy =
    1215       15069 :                     CPCW(state.dataLoopNodes->Node(iNode).Temp) * state.dataLoopNodes->Node(iNode).Temp;
    1216       15069 :                 state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = 0.0;
    1217       15069 :                 state.dataLoopNodes->MoreNodeInfo(iNode).SpecificHeat = 0.0;
    1218             :             }
    1219             :         }
    1220             :     }
    1221     1097533 : }
    1222             : 
    1223          66 : void MarkNode(EnergyPlusData &state,
    1224             :               int const NodeNumber, // Node Number to be marked
    1225             :               DataLoopNode::ConnectionObjectType const ObjectType,
    1226             :               std::string const &ObjectName,
    1227             :               std::string const &FieldName)
    1228             : {
    1229             : 
    1230             :     // SUBROUTINE INFORMATION:
    1231             :     //       AUTHOR         Linda Lawrie
    1232             :     //       DATE WRITTEN   March 2004
    1233             :     //       MODIFIED       na
    1234             :     //       RE-ENGINEERED  na
    1235             : 
    1236             :     // PURPOSE OF THIS SUBROUTINE:
    1237             :     // This subroutine marks a node -- this node needs to exist in more than one object.
    1238             : 
    1239          66 :     state.dataLoopNodes->MarkedNode(NodeNumber).IsMarked = true;
    1240          66 :     state.dataLoopNodes->MarkedNode(NodeNumber).ObjectType = ObjectType;
    1241          66 :     state.dataLoopNodes->MarkedNode(NodeNumber).ObjectName = ObjectName;
    1242          66 :     state.dataLoopNodes->MarkedNode(NodeNumber).FieldName = FieldName;
    1243          66 : }
    1244             : 
    1245         795 : void CheckMarkedNodes(EnergyPlusData &state, bool &ErrorsFound)
    1246             : {
    1247             : 
    1248             :     // SUBROUTINE INFORMATION:
    1249             :     //       AUTHOR         Linda Lawrie
    1250             :     //       DATE WRITTEN   March 2004
    1251             :     //       MODIFIED       na
    1252             :     //       RE-ENGINEERED  na
    1253             : 
    1254             :     // PURPOSE OF THIS SUBROUTINE:
    1255             :     // This subroutine checks "marked" nodes.
    1256             : 
    1257       63030 :     for (int NodeNum = 1; NodeNum <= state.dataLoopNodes->NumOfNodes; ++NodeNum) {
    1258       62235 :         if (state.dataLoopNodes->MarkedNode(NodeNum).IsMarked) {
    1259          57 :             if (state.dataNodeInputMgr->NodeRef(NodeNum) == 0) {
    1260             :                 std::string_view objType =
    1261           0 :                     BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(state.dataLoopNodes->MarkedNode(NodeNum).ObjectType)];
    1262           0 :                 ShowSevereError(state, format("Node=\"{}\" did not find reference by another object.", state.dataLoopNodes->NodeID(NodeNum)));
    1263           0 :                 ShowContinueError(state,
    1264           0 :                                   format(R"(Object="{}", Name="{}", Field=[{}])",
    1265             :                                          objType,
    1266           0 :                                          state.dataLoopNodes->MarkedNode(NodeNum).ObjectName,
    1267           0 :                                          state.dataLoopNodes->MarkedNode(NodeNum).FieldName));
    1268           0 :                 ErrorsFound = true;
    1269             :             }
    1270             :         }
    1271             :     }
    1272         795 : }
    1273             : 
    1274             : } // namespace EnergyPlus::NodeInputManager

Generated by: LCOV version 1.14