LCOV - code coverage report
Current view: top level - EnergyPlus - NodeInputManager.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 494 602 82.1 %
Date: 2023-01-17 19:17:23 Functions: 14 14 100.0 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2023, 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      283609 : 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      283609 :     std::string_view const objTypeStr = BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(NodeObjectType)];
     117             : 
     118      283609 :     if (state.dataNodeInputMgr->GetNodeInputFlag) {
     119         615 :         GetNodeListsInput(state, ErrorsFound);
     120         615 :         state.dataNodeInputMgr->GetNodeInputFlag = false;
     121             :     }
     122             : 
     123      321503 :     if (nodeFluidType != DataLoopNode::NodeFluidType::Air && nodeFluidType != DataLoopNode::NodeFluidType::Water &&
     124      113499 :         nodeFluidType != DataLoopNode::NodeFluidType::Electric && nodeFluidType != DataLoopNode::NodeFluidType::Steam &&
     125       37722 :         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      283609 :     if (!Name.empty()) {
     133      274646 :         int ThisOne = UtilityRoutines::FindItemInList(Name, state.dataNodeInputMgr->NodeLists);
     134      274646 :         if (ThisOne != 0) {
     135        5870 :             NumNodes = state.dataNodeInputMgr->NodeLists(ThisOne).NumOfNodesInList;
     136        5870 :             NodeNumbers({1, NumNodes}) = state.dataNodeInputMgr->NodeLists(ThisOne).NodeNumbers({1, NumNodes});
     137       12555 :             for (int Loop = 1; Loop <= NumNodes; ++Loop) {
     138       12470 :                 if (nodeFluidType != DataLoopNode::NodeFluidType::Blank &&
     139        5785 :                     state.dataLoopNodes->Node(NodeNumbers(Loop)).FluidType != DataLoopNode::NodeFluidType::Blank) {
     140         728 :                     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           0 :                             state, "Existing Fluid type for node, incorrect for request. Node=" + state.dataLoopNodes->NodeID(NodeNumbers(Loop)));
     147           0 :                         ShowContinueError(
     148             :                             state,
     149           0 :                             "Existing Fluid type=" +
     150           0 :                                 format("{}",
     151           0 :                                        DataLoopNode::NodeFluidTypeNames[static_cast<int>(state.dataLoopNodes->Node(NodeNumbers(Loop)).FluidType)]) +
     152           0 :                                 ", Requested Fluid Type=" + format("{}", DataLoopNode::NodeFluidTypeNames[static_cast<int>(nodeFluidType)]));
     153           0 :                         ErrorsFound = true;
     154             :                     }
     155             :                 }
     156        6685 :                 if (state.dataLoopNodes->Node(NodeNumbers(Loop)).FluidType == DataLoopNode::NodeFluidType::Blank) {
     157        5944 :                     state.dataLoopNodes->Node(NodeNumbers(Loop)).FluidType = nodeFluidType;
     158             :                 }
     159        6685 :                 ++state.dataNodeInputMgr->NodeRef(NodeNumbers(Loop));
     160             :             }
     161             :         } else {
     162      268776 :             ThisOne = AssignNodeNumber(state, Name, nodeFluidType, ErrorsFound);
     163      268776 :             NumNodes = 1;
     164      268776 :             NodeNumbers(1) = ThisOne;
     165             :         }
     166             :     } else {
     167        8963 :         NumNodes = 0;
     168        8963 :         NodeNumbers(1) = 0;
     169             :     }
     170             : 
     171             :     // Most calls to this routine use a fixed fluid stream number for all nodes, this is the default
     172      283609 :     NodeInputManager::CompFluidStream FluidStreamNum = NodeFluidStream;
     173      559070 :     for (int Loop = 1; Loop <= NumNodes; ++Loop) {
     174             :         // If requested, assign NodeFluidStream to the first node and increment the fluid stream number
     175             :         // for each remaining node in the list
     176      275461 :         if (IncrementFluidStream) {
     177        2323 :             FluidStreamNum = static_cast<NodeInputManager::CompFluidStream>(static_cast<int>(NodeFluidStream) + (Loop - 1));
     178             :         }
     179             : 
     180      826383 :         RegisterNodeConnection(state,
     181      275461 :                                NodeNumbers(Loop),
     182      275461 :                                state.dataLoopNodes->NodeID(NodeNumbers(Loop)),
     183             :                                NodeObjectType,
     184             :                                NodeObjectName,
     185             :                                nodeConnectionType,
     186             :                                FluidStreamNum,
     187             :                                ObjectIsParent,
     188             :                                ErrorsFound,
     189             :                                InputFieldName);
     190             :     }
     191      283609 : }
     192             : 
     193         769 : void SetupNodeVarsForReporting(EnergyPlusData &state)
     194             : {
     195             : 
     196             :     // SUBROUTINE INFORMATION:
     197             :     //       AUTHOR         Linda K. Lawrie
     198             :     //       DATE WRITTEN   September
     199             : 
     200             :     // PURPOSE OF THIS SUBROUTINE:
     201             :     // This subroutine is called when the indicated number of
     202             :     // Nodes have been found (TOTAL NODE NUMBER) or when HVAC warmup is
     203             :     // complete, whichever condition is reached first.
     204             : 
     205         769 :     auto &Node(state.dataLoopNodes->Node);
     206         769 :     auto &NodeID(state.dataLoopNodes->NodeID);
     207             : 
     208         769 :     if (!state.dataNodeInputMgr->NodeVarsSetup) {
     209         769 :         if (!state.dataErrTracking->AbortProcessing) {
     210         769 :             state.dataLoopNodes->MoreNodeInfo.allocate(state.dataNodeInputMgr->NumOfUniqueNodeNames);
     211       60194 :             for (int NumNode = 1; NumNode <= state.dataNodeInputMgr->NumOfUniqueNodeNames; ++NumNode) {
     212             :                 // Setup Report variables for the Nodes for HVAC Reporting, CurrentModuleObject='Node Name'
     213      237700 :                 SetupOutputVariable(state,
     214             :                                     "System Node Temperature",
     215             :                                     OutputProcessor::Unit::C,
     216       59425 :                                     state.dataLoopNodes->Node(NumNode).Temp,
     217             :                                     OutputProcessor::SOVTimeStepType::System,
     218             :                                     OutputProcessor::SOVStoreType::Average,
     219      118850 :                                     NodeID(NumNode));
     220      237700 :                 SetupOutputVariable(state,
     221             :                                     "System Node Mass Flow Rate",
     222             :                                     OutputProcessor::Unit::kg_s,
     223       59425 :                                     Node(NumNode).MassFlowRate,
     224             :                                     OutputProcessor::SOVTimeStepType::System,
     225             :                                     OutputProcessor::SOVStoreType::Average,
     226      118850 :                                     NodeID(NumNode));
     227      237700 :                 SetupOutputVariable(state,
     228             :                                     "System Node Humidity Ratio",
     229             :                                     OutputProcessor::Unit::kgWater_kgDryAir,
     230       59425 :                                     Node(NumNode).HumRat,
     231             :                                     OutputProcessor::SOVTimeStepType::System,
     232             :                                     OutputProcessor::SOVStoreType::Average,
     233      118850 :                                     NodeID(NumNode));
     234      237700 :                 SetupOutputVariable(state,
     235             :                                     "System Node Setpoint Temperature",
     236             :                                     OutputProcessor::Unit::C,
     237       59425 :                                     Node(NumNode).TempSetPoint,
     238             :                                     OutputProcessor::SOVTimeStepType::System,
     239             :                                     OutputProcessor::SOVStoreType::Average,
     240      118850 :                                     NodeID(NumNode));
     241      237700 :                 SetupOutputVariable(state,
     242             :                                     "System Node Setpoint High Temperature",
     243             :                                     OutputProcessor::Unit::C,
     244       59425 :                                     Node(NumNode).TempSetPointHi,
     245             :                                     OutputProcessor::SOVTimeStepType::System,
     246             :                                     OutputProcessor::SOVStoreType::Average,
     247      118850 :                                     NodeID(NumNode));
     248      237700 :                 SetupOutputVariable(state,
     249             :                                     "System Node Setpoint Low Temperature",
     250             :                                     OutputProcessor::Unit::C,
     251       59425 :                                     Node(NumNode).TempSetPointLo,
     252             :                                     OutputProcessor::SOVTimeStepType::System,
     253             :                                     OutputProcessor::SOVStoreType::Average,
     254      118850 :                                     NodeID(NumNode));
     255      237700 :                 SetupOutputVariable(state,
     256             :                                     "System Node Setpoint Humidity Ratio",
     257             :                                     OutputProcessor::Unit::kgWater_kgDryAir,
     258       59425 :                                     Node(NumNode).HumRatSetPoint,
     259             :                                     OutputProcessor::SOVTimeStepType::System,
     260             :                                     OutputProcessor::SOVStoreType::Average,
     261      118850 :                                     NodeID(NumNode));
     262      237700 :                 SetupOutputVariable(state,
     263             :                                     "System Node Setpoint Minimum Humidity Ratio",
     264             :                                     OutputProcessor::Unit::kgWater_kgDryAir,
     265       59425 :                                     Node(NumNode).HumRatMin,
     266             :                                     OutputProcessor::SOVTimeStepType::System,
     267             :                                     OutputProcessor::SOVStoreType::Average,
     268      118850 :                                     NodeID(NumNode));
     269      237700 :                 SetupOutputVariable(state,
     270             :                                     "System Node Setpoint Maximum Humidity Ratio",
     271             :                                     OutputProcessor::Unit::kgWater_kgDryAir,
     272       59425 :                                     Node(NumNode).HumRatMax,
     273             :                                     OutputProcessor::SOVTimeStepType::System,
     274             :                                     OutputProcessor::SOVStoreType::Average,
     275      118850 :                                     NodeID(NumNode));
     276      237700 :                 SetupOutputVariable(state,
     277             :                                     "System Node Relative Humidity",
     278             :                                     OutputProcessor::Unit::Perc,
     279       59425 :                                     state.dataLoopNodes->MoreNodeInfo(NumNode).RelHumidity,
     280             :                                     OutputProcessor::SOVTimeStepType::System,
     281             :                                     OutputProcessor::SOVStoreType::Average,
     282      118850 :                                     NodeID(NumNode));
     283      237700 :                 SetupOutputVariable(state,
     284             :                                     "System Node Pressure",
     285             :                                     OutputProcessor::Unit::Pa,
     286       59425 :                                     Node(NumNode).Press,
     287             :                                     OutputProcessor::SOVTimeStepType::System,
     288             :                                     OutputProcessor::SOVStoreType::Average,
     289      118850 :                                     NodeID(NumNode));
     290      237700 :                 SetupOutputVariable(state,
     291             :                                     "System Node Standard Density Volume Flow Rate",
     292             :                                     OutputProcessor::Unit::m3_s,
     293       59425 :                                     state.dataLoopNodes->MoreNodeInfo(NumNode).VolFlowRateStdRho,
     294             :                                     OutputProcessor::SOVTimeStepType::System,
     295             :                                     OutputProcessor::SOVStoreType::Average,
     296      118850 :                                     NodeID(NumNode));
     297       85304 :                 if (Node(NumNode).FluidType == DataLoopNode::NodeFluidType::Air ||
     298       25879 :                     Node(NumNode).FluidType == DataLoopNode::NodeFluidType::Water) { // setup volume flow rate report for actual/current density
     299      237076 :                     SetupOutputVariable(state,
     300             :                                         "System Node Current Density Volume Flow Rate",
     301             :                                         OutputProcessor::Unit::m3_s,
     302       59269 :                                         state.dataLoopNodes->MoreNodeInfo(NumNode).VolFlowRateCrntRho,
     303             :                                         OutputProcessor::SOVTimeStepType::System,
     304             :                                         OutputProcessor::SOVStoreType::Average,
     305      118538 :                                         NodeID(NumNode));
     306      237076 :                     SetupOutputVariable(state,
     307             :                                         "System Node Current Density",
     308             :                                         OutputProcessor::Unit::kg_m3,
     309       59269 :                                         state.dataLoopNodes->MoreNodeInfo(NumNode).Density,
     310             :                                         OutputProcessor::SOVTimeStepType::System,
     311             :                                         OutputProcessor::SOVStoreType::Average,
     312      118538 :                                         NodeID(NumNode));
     313      237076 :                     SetupOutputVariable(state,
     314             :                                         "System Node Specific Heat",
     315             :                                         OutputProcessor::Unit::J_kgK,
     316       59269 :                                         state.dataLoopNodes->MoreNodeInfo(NumNode).SpecificHeat,
     317             :                                         OutputProcessor::SOVTimeStepType::System,
     318             :                                         OutputProcessor::SOVStoreType::Average,
     319      118538 :                                         NodeID(NumNode));
     320             :                 }
     321             : 
     322      237700 :                 SetupOutputVariable(state,
     323             :                                     "System Node Enthalpy",
     324             :                                     OutputProcessor::Unit::J_kg,
     325       59425 :                                     state.dataLoopNodes->MoreNodeInfo(NumNode).ReportEnthalpy,
     326             :                                     OutputProcessor::SOVTimeStepType::System,
     327             :                                     OutputProcessor::SOVStoreType::Average,
     328      118850 :                                     NodeID(NumNode));
     329      237700 :                 SetupOutputVariable(state,
     330             :                                     "System Node Wetbulb Temperature",
     331             :                                     OutputProcessor::Unit::C,
     332       59425 :                                     state.dataLoopNodes->MoreNodeInfo(NumNode).WetBulbTemp,
     333             :                                     OutputProcessor::SOVTimeStepType::System,
     334             :                                     OutputProcessor::SOVStoreType::Average,
     335      118850 :                                     NodeID(NumNode));
     336      237700 :                 SetupOutputVariable(state,
     337             :                                     "System Node Dewpoint Temperature",
     338             :                                     OutputProcessor::Unit::C,
     339       59425 :                                     state.dataLoopNodes->MoreNodeInfo(NumNode).AirDewPointTemp,
     340             :                                     OutputProcessor::SOVTimeStepType::System,
     341             :                                     OutputProcessor::SOVStoreType::Average,
     342      118850 :                                     NodeID(NumNode));
     343      237700 :                 SetupOutputVariable(state,
     344             :                                     "System Node Wind Speed",
     345             :                                     OutputProcessor::Unit::m_s,
     346       59425 :                                     Node(NumNode).OutAirWindSpeed,
     347             :                                     OutputProcessor::SOVTimeStepType::System,
     348             :                                     OutputProcessor::SOVStoreType::Average,
     349      118850 :                                     NodeID(NumNode));
     350      237700 :                 SetupOutputVariable(state,
     351             :                                     "System Node Wind Direction",
     352             :                                     OutputProcessor::Unit::deg,
     353       59425 :                                     Node(NumNode).OutAirWindDir,
     354             :                                     OutputProcessor::SOVTimeStepType::System,
     355             :                                     OutputProcessor::SOVStoreType::Average,
     356      118850 :                                     NodeID(NumNode));
     357      237700 :                 SetupOutputVariable(state,
     358             :                                     "System Node Quality",
     359             :                                     OutputProcessor::Unit::None,
     360       59425 :                                     Node(NumNode).Quality,
     361             :                                     OutputProcessor::SOVTimeStepType::System,
     362             :                                     OutputProcessor::SOVStoreType::Average,
     363      118850 :                                     NodeID(NumNode));
     364      237700 :                 SetupOutputVariable(state,
     365             :                                     "System Node Height",
     366             :                                     OutputProcessor::Unit::m,
     367       59425 :                                     Node(NumNode).Height,
     368             :                                     OutputProcessor::SOVTimeStepType::System,
     369             :                                     OutputProcessor::SOVStoreType::Average,
     370      118850 :                                     NodeID(NumNode));
     371       59425 :                 if (state.dataGlobal->DisplayAdvancedReportVariables) {
     372        1708 :                     SetupOutputVariable(state,
     373             :                                         "System Node Minimum Temperature",
     374             :                                         OutputProcessor::Unit::C,
     375         427 :                                         Node(NumNode).TempMin,
     376             :                                         OutputProcessor::SOVTimeStepType::System,
     377             :                                         OutputProcessor::SOVStoreType::Average,
     378         854 :                                         NodeID(NumNode));
     379        1708 :                     SetupOutputVariable(state,
     380             :                                         "System Node Maximum Temperature",
     381             :                                         OutputProcessor::Unit::C,
     382         427 :                                         Node(NumNode).TempMax,
     383             :                                         OutputProcessor::SOVTimeStepType::System,
     384             :                                         OutputProcessor::SOVStoreType::Average,
     385         854 :                                         NodeID(NumNode));
     386        1708 :                     SetupOutputVariable(state,
     387             :                                         "System Node Minimum Limit Mass Flow Rate",
     388             :                                         OutputProcessor::Unit::kg_s,
     389         427 :                                         Node(NumNode).MassFlowRateMin,
     390             :                                         OutputProcessor::SOVTimeStepType::System,
     391             :                                         OutputProcessor::SOVStoreType::Average,
     392         854 :                                         NodeID(NumNode));
     393        1708 :                     SetupOutputVariable(state,
     394             :                                         "System Node Maximum Limit Mass Flow Rate",
     395             :                                         OutputProcessor::Unit::kg_s,
     396         427 :                                         Node(NumNode).MassFlowRateMax,
     397             :                                         OutputProcessor::SOVTimeStepType::System,
     398             :                                         OutputProcessor::SOVStoreType::Average,
     399         854 :                                         NodeID(NumNode));
     400        1708 :                     SetupOutputVariable(state,
     401             :                                         "System Node Minimum Available Mass Flow Rate",
     402             :                                         OutputProcessor::Unit::kg_s,
     403         427 :                                         Node(NumNode).MassFlowRateMinAvail,
     404             :                                         OutputProcessor::SOVTimeStepType::System,
     405             :                                         OutputProcessor::SOVStoreType::Average,
     406         854 :                                         NodeID(NumNode));
     407        1708 :                     SetupOutputVariable(state,
     408             :                                         "System Node Maximum Available Mass Flow Rate",
     409             :                                         OutputProcessor::Unit::kg_s,
     410         427 :                                         Node(NumNode).MassFlowRateMaxAvail,
     411             :                                         OutputProcessor::SOVTimeStepType::System,
     412             :                                         OutputProcessor::SOVStoreType::Average,
     413         854 :                                         NodeID(NumNode));
     414        1708 :                     SetupOutputVariable(state,
     415             :                                         "System Node Setpoint Mass Flow Rate",
     416             :                                         OutputProcessor::Unit::kg_s,
     417         427 :                                         Node(NumNode).MassFlowRateSetPoint,
     418             :                                         OutputProcessor::SOVTimeStepType::System,
     419             :                                         OutputProcessor::SOVStoreType::Average,
     420         854 :                                         NodeID(NumNode));
     421        1708 :                     SetupOutputVariable(state,
     422             :                                         "System Node Requested Mass Flow Rate",
     423             :                                         OutputProcessor::Unit::kg_s,
     424         427 :                                         Node(NumNode).MassFlowRateRequest,
     425             :                                         OutputProcessor::SOVTimeStepType::System,
     426             :                                         OutputProcessor::SOVStoreType::Average,
     427         854 :                                         NodeID(NumNode));
     428        1708 :                     SetupOutputVariable(state,
     429             :                                         "System Node Last Timestep Temperature",
     430             :                                         OutputProcessor::Unit::C,
     431         427 :                                         Node(NumNode).TempLastTimestep,
     432             :                                         OutputProcessor::SOVTimeStepType::System,
     433             :                                         OutputProcessor::SOVStoreType::Average,
     434         854 :                                         NodeID(NumNode));
     435        1708 :                     SetupOutputVariable(state,
     436             :                                         "System Node Last Timestep Enthalpy",
     437             :                                         OutputProcessor::Unit::J_kg,
     438         427 :                                         Node(NumNode).EnthalpyLastTimestep,
     439             :                                         OutputProcessor::SOVTimeStepType::System,
     440             :                                         OutputProcessor::SOVStoreType::Average,
     441         854 :                                         NodeID(NumNode));
     442             :                 }
     443       59425 :                 if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
     444        1132 :                     SetupOutputVariable(state,
     445             :                                         "System Node CO2 Concentration",
     446             :                                         OutputProcessor::Unit::ppm,
     447         283 :                                         Node(NumNode).CO2,
     448             :                                         OutputProcessor::SOVTimeStepType::System,
     449             :                                         OutputProcessor::SOVStoreType::Average,
     450         566 :                                         NodeID(NumNode));
     451             :                 }
     452       59425 :                 if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
     453         360 :                     SetupOutputVariable(state,
     454             :                                         "System Node Generic Air Contaminant Concentration",
     455             :                                         OutputProcessor::Unit::ppm,
     456          90 :                                         Node(NumNode).GenContam,
     457             :                                         OutputProcessor::SOVTimeStepType::System,
     458             :                                         OutputProcessor::SOVStoreType::Average,
     459         180 :                                         NodeID(NumNode));
     460             :                 }
     461             :             }
     462             :         }
     463         769 :         state.dataNodeInputMgr->NodeVarsSetup = true;
     464             : 
     465         769 :         print(state.files.bnd, "{}\n", "! This file shows details about the branches, nodes, and other");
     466         769 :         print(state.files.bnd, "{}\n", "! elements of the flow connections.");
     467         769 :         print(state.files.bnd, "{}\n", "! This file is intended for use in \"debugging\" potential problems");
     468         769 :         print(state.files.bnd, "{}\n", "! that may also be detected by the program, but may be more easily");
     469         769 :         print(state.files.bnd, "{}\n", "! identified by \"eye\".");
     470         769 :         print(state.files.bnd, "{}\n", "! This file is also intended to support software which draws a");
     471         769 :         print(state.files.bnd, "{}\n", "! schematic diagram of the HVAC system.");
     472         769 :         print(state.files.bnd, "{}\n", "! ===============================================================");
     473             :         // Show the node names on the Branch-Node Details file
     474             :         static constexpr std::string_view Format_700("! #Nodes,<Number of Unique Nodes>");
     475         769 :         print(state.files.bnd, "{}\n", Format_700);
     476         769 :         print(state.files.bnd, " #Nodes,{}\n", state.dataNodeInputMgr->NumOfUniqueNodeNames);
     477         769 :         if (state.dataNodeInputMgr->NumOfUniqueNodeNames > 0) {
     478             :             static constexpr std::string_view Format_702(
     479             :                 "! <Node>,<NodeNumber>,<Node Name>,<Node Fluid Type>,<# Times Node Referenced After Definition>");
     480         704 :             print(state.files.bnd, "{}\n", Format_702);
     481             :         }
     482         769 :         int Count0 = 0;
     483       60194 :         for (int NumNode = 1; NumNode <= state.dataNodeInputMgr->NumOfUniqueNodeNames; ++NumNode) {
     484      178275 :             print(state.files.bnd,
     485             :                   " Node,{},{},{},{}\n",
     486             :                   NumNode,
     487             :                   NodeID(NumNode),
     488       59425 :                   DataLoopNode::NodeFluidTypeNames[static_cast<int>(Node(NumNode).FluidType)],
     489      118850 :                   state.dataNodeInputMgr->NodeRef(NumNode));
     490       59425 :             if (state.dataNodeInputMgr->NodeRef(NumNode) == 0) ++Count0;
     491             :         }
     492             :         // Show suspicious node names on the Branch-Node Details file
     493         769 :         if (Count0 > 0) {
     494         627 :             print(state.files.bnd, "{}\n", "! ===============================================================");
     495         627 :             print(state.files.bnd, "{}\n", "! Suspicious nodes have 0 references.  It is normal for some nodes, however.");
     496         627 :             print(state.files.bnd, "{}\n", "! Listing nodes with 0 references (culled from previous list):");
     497             :             static constexpr std::string_view Format_703(
     498             :                 "! <Suspicious Node>,<NodeNumber>,<Node Name>,<Node Fluid Type>,<# Times Node Referenced After Definition>");
     499         627 :             print(state.files.bnd, "{}\n", Format_703);
     500       56336 :             for (int NumNode = 1; NumNode <= state.dataNodeInputMgr->NumOfUniqueNodeNames; ++NumNode) {
     501       55709 :                 if (state.dataNodeInputMgr->NodeRef(NumNode) > 0) continue;
     502       16281 :                 print(state.files.bnd,
     503             :                       " Suspicious Node,{},{},{},{}\n",
     504             :                       NumNode,
     505             :                       NodeID(NumNode),
     506        5427 :                       DataLoopNode::NodeFluidTypeNames[static_cast<int>(Node(NumNode).FluidType)],
     507       10854 :                       state.dataNodeInputMgr->NodeRef(NumNode));
     508             :             }
     509             :         }
     510             :     }
     511         769 : }
     512             : 
     513         771 : void GetNodeListsInput(EnergyPlusData &state, bool &ErrorsFound) // Set to true when requested Node List not found, unchanged otherwise
     514             : {
     515             : 
     516             :     // SUBROUTINE INFORMATION:
     517             :     //       AUTHOR         Linda K. Lawrie
     518             :     //       DATE WRITTEN   September 1999
     519             :     //       MODIFIED       na
     520             :     //       RE-ENGINEERED  na
     521             : 
     522             :     // PURPOSE OF THIS SUBROUTINE:
     523             :     // This subroutine gets the Node Lists from the IDF and fills the
     524             :     // Node List Data Structure.
     525             : 
     526             :     // SUBROUTINE PARAMETER DEFINITIONS:
     527             :     static constexpr std::string_view RoutineName("GetNodeListsInput: ");
     528         771 :     static std::string const CurrentModuleObject("NodeList");
     529             : 
     530             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     531             :     int NumAlphas;  // Number of alphas in IDF item
     532             :     int NumNumbers; // Number of numerics in IDF item
     533             :     int IOStatus;   // IOStatus for IDF item (not checked)
     534             :     int NCount;     // Actual number of node lists
     535             :     bool flagError; // true when error node list name should be output
     536        1542 :     Array1D_string cAlphas;
     537        1542 :     Array1D<Real64> rNumbers;
     538             : 
     539         771 :     bool localErrorsFound(false);
     540         771 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NCount, NumAlphas, NumNumbers);
     541         771 :     cAlphas.allocate(NumAlphas);
     542         771 :     rNumbers.allocate(NumNumbers);
     543         771 :     state.dataNodeInputMgr->NumOfNodeLists = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     544         771 :     state.dataNodeInputMgr->NodeLists.allocate(state.dataNodeInputMgr->NumOfNodeLists);
     545        6678 :     for (int i = 1; i <= state.dataNodeInputMgr->NumOfNodeLists; ++i) {
     546        5907 :         state.dataNodeInputMgr->NodeLists(i).Name.clear();
     547        5907 :         state.dataNodeInputMgr->NodeLists(i).NumOfNodesInList = 0;
     548             :     }
     549             : 
     550         771 :     NCount = 0;
     551        6678 :     for (int Loop = 1; Loop <= state.dataNodeInputMgr->NumOfNodeLists; ++Loop) {
     552        5907 :         state.dataInputProcessing->inputProcessor->getObjectItem(
     553             :             state, CurrentModuleObject, Loop, cAlphas, NumAlphas, rNumbers, NumNumbers, IOStatus);
     554        5907 :         if (UtilityRoutines::IsNameEmpty(state, cAlphas(1), CurrentModuleObject, localErrorsFound)) continue;
     555             : 
     556        5907 :         ++NCount;
     557        5907 :         state.dataNodeInputMgr->NodeLists(NCount).Name = cAlphas(1);
     558        5907 :         state.dataNodeInputMgr->NodeLists(NCount).NodeNames.allocate(NumAlphas - 1);
     559        5907 :         state.dataNodeInputMgr->NodeLists(NCount).NodeNames = "";
     560        5907 :         state.dataNodeInputMgr->NodeLists(NCount).NodeNumbers.allocate(NumAlphas - 1);
     561        5907 :         state.dataNodeInputMgr->NodeLists(NCount).NodeNumbers = 0;
     562        5907 :         state.dataNodeInputMgr->NodeLists(NCount).NumOfNodesInList = NumAlphas - 1;
     563        5907 :         if (NumAlphas <= 1) {
     564           0 :             if (NumAlphas == 1) {
     565           0 :                 ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + cAlphas(1) + "\" does not have any nodes.");
     566             :             } else {
     567           0 :                 ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=<blank> does not have any nodes or nodelist name.");
     568             :             }
     569           0 :             localErrorsFound = true;
     570           0 :             continue;
     571             :         }
     572             :         //  Put all in, then determine unique
     573       12634 :         for (int Loop1 = 1; Loop1 <= NumAlphas - 1; ++Loop1) {
     574        6727 :             state.dataNodeInputMgr->NodeLists(NCount).NodeNames(Loop1) = cAlphas(Loop1 + 1);
     575        6727 :             if (cAlphas(Loop1 + 1).empty()) {
     576           0 :                 ShowWarningError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + cAlphas(1) + "\", blank node name in list.");
     577           0 :                 --state.dataNodeInputMgr->NodeLists(NCount).NumOfNodesInList;
     578           0 :                 if (state.dataNodeInputMgr->NodeLists(NCount).NumOfNodesInList <= 0) {
     579           0 :                     ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + cAlphas(1) + "\" does not have any nodes.");
     580           0 :                     localErrorsFound = true;
     581           0 :                     break;
     582             :                 }
     583           0 :                 continue;
     584             :             }
     585       13454 :             state.dataNodeInputMgr->NodeLists(NCount).NodeNumbers(Loop1) = AssignNodeNumber(
     586       13454 :                 state, state.dataNodeInputMgr->NodeLists(NCount).NodeNames(Loop1), DataLoopNode::NodeFluidType::Blank, localErrorsFound);
     587        6727 :             if (UtilityRoutines::SameString(state.dataNodeInputMgr->NodeLists(NCount).NodeNames(Loop1),
     588        6727 :                                             state.dataNodeInputMgr->NodeLists(NCount).Name)) {
     589           0 :                 ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + cAlphas(1) + "\", invalid node name in list.");
     590           0 :                 ShowContinueError(state, format("... Node {} Name=\"{}\", duplicates NodeList Name.", Loop1, cAlphas(Loop1 + 1)));
     591           0 :                 localErrorsFound = true;
     592             :             }
     593             :         }
     594             :         // Error on any duplicates
     595        5907 :         flagError = true;
     596       12634 :         for (int Loop1 = 1; Loop1 <= state.dataNodeInputMgr->NodeLists(NCount).NumOfNodesInList; ++Loop1) {
     597        7871 :             for (int Loop2 = Loop1 + 1; Loop2 <= state.dataNodeInputMgr->NodeLists(NCount).NumOfNodesInList; ++Loop2) {
     598        1144 :                 if (state.dataNodeInputMgr->NodeLists(NCount).NodeNumbers(Loop1) != state.dataNodeInputMgr->NodeLists(NCount).NodeNumbers(Loop2))
     599        1144 :                     continue;
     600           0 :                 if (flagError) { // only list nodelist name once
     601           0 :                     ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + cAlphas(1) + "\" has duplicate nodes:");
     602           0 :                     flagError = false;
     603             :                 }
     604           0 :                 ShowContinueError(state,
     605           0 :                                   format("...list item={}, \"{}\", duplicate list item={}, \"{}\".",
     606             :                                          Loop1,
     607           0 :                                          state.dataLoopNodes->NodeID(state.dataNodeInputMgr->NodeLists(NCount).NodeNumbers(Loop1)),
     608             :                                          Loop2,
     609           0 :                                          state.dataLoopNodes->NodeID(state.dataNodeInputMgr->NodeLists(NCount).NodeNumbers(Loop2))));
     610           0 :                 localErrorsFound = true;
     611             :             }
     612             :         }
     613             :     }
     614             : 
     615        6678 :     for (int Loop = 1; Loop <= state.dataNodeInputMgr->NumOfNodeLists; ++Loop) {
     616       12634 :         for (int Loop2 = 1; Loop2 <= state.dataNodeInputMgr->NodeLists(Loop).NumOfNodesInList; ++Loop2) {
     617      217225 :             for (int Loop1 = 1; Loop1 <= state.dataNodeInputMgr->NumOfNodeLists; ++Loop1) {
     618      210498 :                 if (Loop == Loop1) continue; // within a nodelist have already checked to see if node name duplicates nodelist name
     619      203771 :                 if (!UtilityRoutines::SameString(state.dataNodeInputMgr->NodeLists(Loop).NodeNames(Loop2),
     620      203771 :                                                  state.dataNodeInputMgr->NodeLists(Loop1).Name))
     621      203771 :                     continue;
     622           0 :                 ShowSevereError(state,
     623           0 :                                 std::string{RoutineName} + CurrentModuleObject + "=\"" + state.dataNodeInputMgr->NodeLists(Loop1).Name +
     624             :                                     "\", invalid node name in list.");
     625           0 :                 ShowContinueError(
     626             :                     state,
     627           0 :                     format("... Node {} Name=\"{}\", duplicates NodeList Name.", Loop2, state.dataNodeInputMgr->NodeLists(Loop).NodeNames(Loop2)));
     628           0 :                 ShowContinueError(state, "... NodeList=\"" + state.dataNodeInputMgr->NodeLists(Loop1).Name + "\", is duplicated.");
     629           0 :                 ShowContinueError(state, "... Items in NodeLists must not be the name of another NodeList.");
     630           0 :                 localErrorsFound = true;
     631             :             }
     632             :         }
     633             :     }
     634             : 
     635         771 :     cAlphas.deallocate();
     636         771 :     rNumbers.deallocate();
     637             : 
     638         771 :     if (localErrorsFound) {
     639           0 :         ShowFatalError(state, std::string{RoutineName} + CurrentModuleObject + ": Error getting input - causes termination.");
     640           0 :         ErrorsFound = true;
     641             :     }
     642         771 : }
     643             : 
     644      275503 : int AssignNodeNumber(EnergyPlusData &state,
     645             :                      std::string const &Name,                         // Name for assignment
     646             :                      DataLoopNode::NodeFluidType const nodeFluidType, // must be valid
     647             :                      bool &ErrorsFound)
     648             : {
     649             : 
     650             :     // FUNCTION INFORMATION:
     651             :     //       AUTHOR         Linda K. Lawrie
     652             :     //       DATE WRITTEN   September 1999
     653             :     //       MODIFIED       na
     654             :     //       RE-ENGINEERED  na
     655             : 
     656             :     // PURPOSE OF THIS FUNCTION:
     657             :     // This function assigns a node number to this name.
     658             : 
     659             :     // METHODOLOGY EMPLOYED:
     660             :     // Look to see if a name has already been entered.  Use the index of
     661             :     // the array as the node number, if there.
     662             : 
     663             :     // Return value
     664             :     int AssignNodeNumber;
     665             : 
     666      319348 :     if (nodeFluidType != DataLoopNode::NodeFluidType::Air && nodeFluidType != DataLoopNode::NodeFluidType::Water &&
     667      131354 :         nodeFluidType != DataLoopNode::NodeFluidType::Electric && nodeFluidType != DataLoopNode::NodeFluidType::Steam &&
     668       43674 :         nodeFluidType != DataLoopNode::NodeFluidType::Blank) {
     669           0 :         ShowSevereError(state, format("AssignNodeNumber: Invalid FluidType={}", nodeFluidType));
     670           0 :         ErrorsFound = true;
     671           0 :         ShowFatalError(state, "AssignNodeNumber: Preceding issue causes termination.");
     672             :     }
     673             : 
     674      275503 :     int NumNode = 0;
     675      275503 :     if (state.dataNodeInputMgr->NumOfUniqueNodeNames > 0) {
     676      549594 :         NumNode = UtilityRoutines::FindItemInList(
     677      824391 :             Name, state.dataLoopNodes->NodeID({1, state.dataNodeInputMgr->NumOfUniqueNodeNames}), state.dataNodeInputMgr->NumOfUniqueNodeNames);
     678      274797 :         if (NumNode > 0) {
     679      215916 :             AssignNodeNumber = NumNode;
     680      215916 :             ++state.dataNodeInputMgr->NodeRef(NumNode);
     681      215916 :             if (nodeFluidType != DataLoopNode::NodeFluidType::Blank) {
     682      238357 :                 if (state.dataLoopNodes->Node(NumNode).FluidType != nodeFluidType &&
     683       29978 :                     state.dataLoopNodes->Node(NumNode).FluidType != DataLoopNode::NodeFluidType::Blank) {
     684           0 :                     ShowSevereError(state, "Existing Fluid type for node, incorrect for request. Node=" + state.dataLoopNodes->NodeID(NumNode));
     685           0 :                     ShowContinueError(
     686             :                         state,
     687           0 :                         "Existing Fluid type=" +
     688           0 :                             format("{}", DataLoopNode::NodeFluidTypeNames[static_cast<int>(state.dataLoopNodes->Node(NumNode).FluidType)]) +
     689           0 :                             ", Requested Fluid Type=" + format("{}", DataLoopNode::NodeFluidTypeNames[static_cast<int>(nodeFluidType)]));
     690           0 :                     ErrorsFound = true;
     691             :                 }
     692             :             }
     693      215916 :             if (state.dataLoopNodes->Node(NumNode).FluidType == DataLoopNode::NodeFluidType::Blank) {
     694       35778 :                 state.dataLoopNodes->Node(NumNode).FluidType = nodeFluidType;
     695             :             }
     696             :         } else {
     697       58881 :             ++state.dataNodeInputMgr->NumOfUniqueNodeNames;
     698       58881 :             state.dataLoopNodes->NumOfNodes = state.dataNodeInputMgr->NumOfUniqueNodeNames;
     699             : 
     700       58881 :             state.dataLoopNodes->Node.redimension(state.dataLoopNodes->NumOfNodes);
     701       58881 :             state.dataLoopNodes->NodeID.redimension({0, state.dataLoopNodes->NumOfNodes});
     702       58881 :             state.dataNodeInputMgr->NodeRef.redimension(state.dataLoopNodes->NumOfNodes);
     703       58881 :             state.dataLoopNodes->MarkedNode.redimension(state.dataLoopNodes->NumOfNodes);
     704       58881 :             state.dataLoopNodes->NodeSetpointCheck.redimension(state.dataLoopNodes->NumOfNodes);
     705             :             // Set new item in Node
     706       58881 :             state.dataLoopNodes->Node(state.dataLoopNodes->NumOfNodes).FluidType = nodeFluidType;
     707       58881 :             state.dataNodeInputMgr->NodeRef(state.dataLoopNodes->NumOfNodes) = 0;
     708       58881 :             state.dataLoopNodes->NodeID(state.dataNodeInputMgr->NumOfUniqueNodeNames) = Name;
     709             : 
     710       58881 :             AssignNodeNumber = state.dataNodeInputMgr->NumOfUniqueNodeNames;
     711             :         }
     712             :     } else {
     713         706 :         state.dataLoopNodes->Node.allocate(1);
     714         706 :         state.dataLoopNodes->Node(1).FluidType = nodeFluidType;
     715             :         // Allocate takes care of defining
     716         706 :         state.dataLoopNodes->NumOfNodes = 1;
     717         706 :         state.dataLoopNodes->NodeID.allocate({0, 1});
     718         706 :         state.dataNodeInputMgr->NodeRef.allocate(1);
     719         706 :         state.dataLoopNodes->MarkedNode.allocate(1);
     720         706 :         state.dataLoopNodes->NodeSetpointCheck.allocate(1);
     721             : 
     722         706 :         state.dataNodeInputMgr->NumOfUniqueNodeNames = 1;
     723         706 :         state.dataLoopNodes->NodeID(0) = "Undefined";
     724         706 :         state.dataLoopNodes->NodeID(state.dataNodeInputMgr->NumOfUniqueNodeNames) = Name;
     725         706 :         AssignNodeNumber = 1;
     726         706 :         state.dataNodeInputMgr->NodeRef(1) = 0;
     727             :     }
     728             : 
     729      275503 :     return AssignNodeNumber;
     730             : }
     731             : 
     732      224576 : int GetOnlySingleNode(EnergyPlusData &state,
     733             :                       std::string const &NodeName,
     734             :                       bool &errFlag,
     735             :                       DataLoopNode::ConnectionObjectType const NodeObjectType, // Node Object Type (i.e. "Chiller:Electric")
     736             :                       std::string const &NodeObjectName,                       // Node Object Name (i.e. "MyChiller")
     737             :                       DataLoopNode::NodeFluidType const nodeFluidType,         // Fluidtype for checking/setting node FluidType
     738             :                       DataLoopNode::ConnectionType const nodeConnectionType,   // Node Connection Type (see DataLoopNode)
     739             :                       CompFluidStream const NodeFluidStream,                   // Which Fluid Stream
     740             :                       bool const ObjectIsParent,                               // True/False
     741             :                       std::string_view const InputFieldName                    // Input Field Name
     742             : )
     743             : {
     744             : 
     745             :     // FUNCTION INFORMATION:
     746             :     //       AUTHOR         Linda K. Lawrie; adapted from GasAbsorptionChiller;Jason Glazer
     747             :     //       DATE WRITTEN   December 2001
     748             : 
     749             :     // PURPOSE OF THIS FUNCTION:
     750             :     // This function gets a single node (or error message results) using the
     751             :     // node id from the input file.
     752             : 
     753             :     static constexpr std::string_view RoutineName("GetOnlySingleNode: ");
     754             : 
     755             :     int NumNodes;
     756             :     int NumParams;
     757             :     int NumAlphas;
     758             :     int NumNums;
     759             : 
     760      224576 :     std::string_view const objTypeStr = BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(NodeObjectType)];
     761             : 
     762      224576 :     if (state.dataNodeInputMgr->GetOnlySingleNodeFirstTime) {
     763         706 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "NodeList", NumParams, NumAlphas, NumNums);
     764         706 :         state.dataNodeInputMgr->GetOnlySingleNodeNodeNums.dimension(NumParams, 0);
     765         706 :         state.dataNodeInputMgr->GetOnlySingleNodeFirstTime = false;
     766             :     }
     767             : 
     768      449152 :     GetNodeNums(state,
     769             :                 NodeName,
     770             :                 NumNodes,
     771      224576 :                 state.dataNodeInputMgr->GetOnlySingleNodeNodeNums,
     772             :                 errFlag,
     773             :                 nodeFluidType,
     774             :                 NodeObjectType,
     775             :                 NodeObjectName,
     776             :                 nodeConnectionType,
     777             :                 NodeFluidStream,
     778             :                 ObjectIsParent,
     779             :                 false,
     780             :                 InputFieldName);
     781             : 
     782      224576 :     if (NumNodes > 1) {
     783           0 :         ShowSevereError(state, format("{}{}=\"{}=\", invalid data.", RoutineName, objTypeStr, NodeObjectName));
     784           0 :         if (!InputFieldName.empty()) {
     785           0 :             ShowContinueError(state, fmt::format("...Ref field={}", InputFieldName));
     786             :         }
     787           0 :         ShowContinueError(state, "Only 1st Node used from NodeList=\"" + NodeName + "\".");
     788           0 :         ShowContinueError(state, "...a Nodelist may not be valid in this context.");
     789           0 :         errFlag = true;
     790      224576 :     } else if (NumNodes == 0) {
     791        1180 :         state.dataNodeInputMgr->GetOnlySingleNodeNodeNums(1) = 0;
     792             :     }
     793             : 
     794      224576 :     return state.dataNodeInputMgr->GetOnlySingleNodeNodeNums(1);
     795             : }
     796             : 
     797        1038 : void InitUniqueNodeCheck(EnergyPlusData &state, std::string const &ContextName)
     798             : {
     799             : 
     800             :     // SUBROUTINE INFORMATION:
     801             :     //       AUTHOR         Linda Lawrie
     802             :     //       DATE WRITTEN   November 2002
     803             :     //       MODIFIED       na
     804             :     //       RE-ENGINEERED  na
     805             : 
     806             :     // PURPOSE OF THIS SUBROUTINE:
     807             :     // This subroutine begins a process of checking for unique node names
     808             :     // in a sequence of nodes.
     809             : 
     810             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     811        1038 :     bool errFlag(false);
     812             : 
     813             :     // Begin set up of Uniqueness context
     814             : 
     815        1038 :     if (state.dataNodeInputMgr->GetNodeInputFlag) {
     816         156 :         GetNodeListsInput(state, errFlag);
     817         156 :         state.dataNodeInputMgr->GetNodeInputFlag = false;
     818             :     }
     819             : 
     820        1038 :     if (!state.dataNodeInputMgr->CurCheckContextName.empty()) {
     821           0 :         ShowFatalError(state,
     822           0 :                        "Init Uniqueness called for \"" + ContextName + ", but checks for \"" + state.dataNodeInputMgr->CurCheckContextName +
     823             :                            "\" was already in progress.");
     824             :     }
     825        1038 :     if (ContextName.empty()) {
     826           0 :         ShowFatalError(state, "Init Uniqueness called with Blank Context Name");
     827             :     }
     828        1038 :     if (allocated(state.dataNodeInputMgr->UniqueNodeNames)) {
     829           0 :         state.dataNodeInputMgr->UniqueNodeNames.deallocate();
     830             :     }
     831             : 
     832        1038 :     state.dataNodeInputMgr->NumCheckNodes = 0;
     833        1038 :     state.dataNodeInputMgr->MaxCheckNodes = 100;
     834        1038 :     state.dataNodeInputMgr->UniqueNodeNames.allocate(state.dataNodeInputMgr->MaxCheckNodes);
     835        1038 :     state.dataNodeInputMgr->CurCheckContextName = ContextName;
     836        1038 : }
     837             : 
     838        4328 : void CheckUniqueNodeNames(
     839             :     EnergyPlusData &state, std::string const &NodeTypes, bool &ErrorsFound, std::string const &CheckName, std::string const &ObjectName)
     840             : {
     841             : 
     842             :     // SUBROUTINE INFORMATION:
     843             :     //       AUTHOR         Linda Lawrie
     844             :     //       DATE WRITTEN   November 2002
     845             :     //       MODIFIED       na
     846             :     //       RE-ENGINEERED  na
     847             : 
     848             :     // PURPOSE OF THIS SUBROUTINE:
     849             :     // This subroutine checks the appropriate input argument for uniqueness.
     850             :     // Call CheckUniqueNodes(NodeTypes,CheckType,ErrorsFound,CheckName,CheckNumber)
     851             :     // NodeTypes - used in error message (if any produced)
     852             :     // ErrorsFound - true if error found by routine
     853             :     // CheckName - NodeName entered
     854             :     // ObjectName - "Name" field of object (i.e., CurCheckContextName)
     855             : 
     856             :     // METHODOLOGY EMPLOYED:
     857             :     // checks the current list of items for this (again)
     858             : 
     859             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     860             :     int Found;
     861             : 
     862        4328 :     if (!CheckName.empty()) {
     863        4328 :         Found = UtilityRoutines::FindItemInList(CheckName, state.dataNodeInputMgr->UniqueNodeNames, state.dataNodeInputMgr->NumCheckNodes);
     864        4328 :         if (Found != 0) {
     865           0 :             ShowSevereError(state, state.dataNodeInputMgr->CurCheckContextName + "=\"" + ObjectName + "\", duplicate node names found.");
     866           0 :             ShowContinueError(state, "...for Node Type(s)=" + NodeTypes + ", duplicate node name=\"" + 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        4328 :             ++state.dataNodeInputMgr->NumCheckNodes;
     873        4328 :             if (state.dataNodeInputMgr->NumCheckNodes > state.dataNodeInputMgr->MaxCheckNodes) {
     874           7 :                 state.dataNodeInputMgr->UniqueNodeNames.redimension(state.dataNodeInputMgr->MaxCheckNodes += 100);
     875             :             }
     876        4328 :             state.dataNodeInputMgr->UniqueNodeNames(state.dataNodeInputMgr->NumCheckNodes) = CheckName;
     877             :         }
     878             :     }
     879        4328 : }
     880             : 
     881        9162 : 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             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     903             :     int Found;
     904             : 
     905        9162 :     if (CheckNumber != 0) {
     906       27486 :         Found = UtilityRoutines::FindItemInList(
     907       27486 :             state.dataLoopNodes->NodeID(CheckNumber), state.dataNodeInputMgr->UniqueNodeNames, state.dataNodeInputMgr->NumCheckNodes);
     908        9162 :         if (Found != 0) {
     909           0 :             ShowSevereError(state, state.dataNodeInputMgr->CurCheckContextName + "=\"" + ObjectName + "\", duplicate node names found.");
     910           0 :             ShowContinueError(state,
     911           0 :                               "...for Node Type(s)=" + NodeTypes + ", duplicate node name=\"" + state.dataLoopNodes->NodeID(CheckNumber) + "\".");
     912           0 :             ShowContinueError(state, "...Nodes must be unique across instances of this object.");
     913           0 :             ErrorsFound = true;
     914             :         } else {
     915        9162 :             ++state.dataNodeInputMgr->NumCheckNodes;
     916        9162 :             if (state.dataNodeInputMgr->NumCheckNodes > state.dataNodeInputMgr->MaxCheckNodes) {
     917          21 :                 state.dataNodeInputMgr->UniqueNodeNames.redimension(state.dataNodeInputMgr->MaxCheckNodes += 100);
     918             :             }
     919        9162 :             state.dataNodeInputMgr->UniqueNodeNames(state.dataNodeInputMgr->NumCheckNodes) = state.dataLoopNodes->NodeID(CheckNumber);
     920             :         }
     921             :     }
     922        9162 : }
     923             : 
     924        1038 : void EndUniqueNodeCheck(EnergyPlusData &state, std::string const &ContextName)
     925             : {
     926             : 
     927             :     // SUBROUTINE INFORMATION:
     928             :     //       AUTHOR         Linda Lawrie
     929             :     //       DATE WRITTEN   November 2002
     930             :     //       MODIFIED       na
     931             :     //       RE-ENGINEERED  na
     932             : 
     933             :     // PURPOSE OF THIS SUBROUTINE:
     934             :     // This subroutine marks the end of a unique node check.
     935             : 
     936        1038 :     if (state.dataNodeInputMgr->CurCheckContextName != ContextName) {
     937           0 :         ShowFatalError(state,
     938           0 :                        "End Uniqueness called for \"" + ContextName + ", but checks for \"" + state.dataNodeInputMgr->CurCheckContextName +
     939             :                            "\" was in progress.");
     940             :     }
     941        1038 :     if (ContextName.empty()) {
     942           0 :         ShowFatalError(state, "End Uniqueness called with Blank Context Name");
     943             :     }
     944        1038 :     state.dataNodeInputMgr->CurCheckContextName = std::string();
     945        1038 :     if (allocated(state.dataNodeInputMgr->UniqueNodeNames)) {
     946        1038 :         state.dataNodeInputMgr->UniqueNodeNames.deallocate();
     947             :     }
     948        1038 : }
     949             : 
     950      690474 : void CalcMoreNodeInfo(EnergyPlusData &state)
     951             : {
     952             : 
     953             :     // SUBROUTINE INFORMATION:
     954             :     //       AUTHOR         Fred Buhl
     955             :     //       DATE WRITTEN   January 2004
     956             :     //       MODIFIED       na
     957             :     //       RE-ENGINEERED  na
     958             : 
     959             :     // PURPOSE OF THIS SUBROUTINE:
     960             :     // Calculate additional node information for reporting
     961             : 
     962             :     // METHODOLOGY EMPLOYED:
     963             :     // Input is the existing node data plus environment variables. Output is
     964             :     // stored in MoreNodeInfo.
     965             : 
     966             :     // Using/Aliasing
     967             :     using FluidProperties::GetDensityGlycol;
     968             :     using FluidProperties::GetSatDensityRefrig;
     969             :     using FluidProperties::GetSatEnthalpyRefrig;
     970             :     using FluidProperties::GetSpecificHeatGlycol;
     971             :     using OutputProcessor::ReqReportVariables;
     972             :     using Psychrometrics::CPCW;
     973             :     using Psychrometrics::PsyCpAirFnW;
     974             :     using Psychrometrics::PsyHFnTdbW;
     975             :     using Psychrometrics::PsyRhFnTdbWPb;
     976             :     using Psychrometrics::PsyRhoAirFnPbTdbW;
     977             :     using Psychrometrics::PsyTdpFnWPb;
     978             :     using Psychrometrics::PsyTwbFnTdbWPb;
     979             :     using Psychrometrics::RhoH2O;
     980             :     using ScheduleManager::GetCurrentScheduleValue;
     981             : 
     982             :     // SUBROUTINE PARAMETER DEFINITIONS:
     983             :     static constexpr std::string_view RoutineName("CalcMoreNodeInfo");
     984      690474 :     static std::string const NodeReportingCalc("NodeReportingCalc:");
     985             : 
     986      690474 :     auto &RhoAirStdInit = state.dataNodeInputMgr->RhoAirStdInit;
     987      690474 :     auto &RhoWaterStdInit = state.dataNodeInputMgr->RhoWaterStdInit;
     988      690474 :     auto &NodeWetBulbSchedPtr = state.dataNodeInputMgr->NodeWetBulbSchedPtr;
     989      690474 :     auto &NodeRelHumidityRepReq = state.dataNodeInputMgr->NodeRelHumidityRepReq;
     990      690474 :     auto &NodeRelHumiditySchedPtr = state.dataNodeInputMgr->NodeRelHumiditySchedPtr;
     991      690474 :     auto &NodeDewPointRepReq = state.dataNodeInputMgr->NodeDewPointRepReq;
     992      690474 :     auto &NodeDewPointSchedPtr = state.dataNodeInputMgr->NodeDewPointSchedPtr;
     993      690474 :     auto &NodeSpecificHeatRepReq = state.dataNodeInputMgr->NodeSpecificHeatRepReq;
     994      690474 :     auto &NodeSpecificHeatSchedPtr = state.dataNodeInputMgr->NodeSpecificHeatSchedPtr;
     995      690474 :     auto &nodeReportingStrings = state.dataNodeInputMgr->nodeReportingStrings;
     996      690474 :     auto &nodeFluidNames = state.dataNodeInputMgr->nodeFluidNames;
     997             :     bool ReportWetBulb;
     998             :     bool ReportRelHumidity;
     999             :     bool ReportDewPoint;
    1000             :     bool ReportSpecificHeat;
    1001             :     Real64 SteamDensity;
    1002             :     Real64 EnthSteamInDry;
    1003             :     Real64 RhoAirCurrent; // temporary value for current air density f(baro, db , W)
    1004             :     Real64 rho;
    1005             :     Real64 Cp;
    1006             :     Real64 rhoStd;
    1007             : 
    1008      690474 :     if (state.dataNodeInputMgr->CalcMoreNodeInfoMyOneTimeFlag) {
    1009         769 :         RhoAirStdInit = state.dataEnvrn->StdRhoAir;
    1010         769 :         RhoWaterStdInit = RhoH2O(DataGlobalConstants::InitConvTemp);
    1011         769 :         state.dataNodeInputMgr->NodeWetBulbRepReq.allocate(state.dataLoopNodes->NumOfNodes);
    1012         769 :         NodeWetBulbSchedPtr.allocate(state.dataLoopNodes->NumOfNodes);
    1013         769 :         NodeRelHumidityRepReq.allocate(state.dataLoopNodes->NumOfNodes);
    1014         769 :         NodeRelHumiditySchedPtr.allocate(state.dataLoopNodes->NumOfNodes);
    1015         769 :         NodeDewPointRepReq.allocate(state.dataLoopNodes->NumOfNodes);
    1016         769 :         NodeDewPointSchedPtr.allocate(state.dataLoopNodes->NumOfNodes);
    1017         769 :         NodeSpecificHeatRepReq.allocate(state.dataLoopNodes->NumOfNodes);
    1018         769 :         NodeSpecificHeatSchedPtr.allocate(state.dataLoopNodes->NumOfNodes);
    1019         769 :         nodeReportingStrings.reserve(state.dataLoopNodes->NumOfNodes);
    1020         769 :         nodeFluidNames.reserve(state.dataLoopNodes->NumOfNodes);
    1021         769 :         state.dataNodeInputMgr->NodeWetBulbRepReq = false;
    1022         769 :         NodeWetBulbSchedPtr = 0;
    1023         769 :         NodeRelHumidityRepReq = false;
    1024         769 :         NodeRelHumiditySchedPtr = 0;
    1025         769 :         NodeDewPointRepReq = false;
    1026         769 :         NodeDewPointSchedPtr = 0;
    1027         769 :         NodeSpecificHeatRepReq = false;
    1028         769 :         NodeSpecificHeatSchedPtr = 0;
    1029             : 
    1030       60194 :         for (int iNode = 1; iNode <= state.dataLoopNodes->NumOfNodes; ++iNode) {
    1031       59425 :             nodeReportingStrings.push_back(std::string(NodeReportingCalc + state.dataLoopNodes->NodeID(iNode)));
    1032       59425 :             nodeFluidNames.push_back(FluidProperties::GetGlycolNameByIndex(state, state.dataLoopNodes->Node(iNode).FluidIndex));
    1033     1842161 :             for (int iReq = 1; iReq <= state.dataOutputProcessor->NumOfReqVariables; ++iReq) {
    1034     3561415 :                 if (UtilityRoutines::SameString(state.dataOutputProcessor->ReqRepVars(iReq).Key, state.dataLoopNodes->NodeID(iNode)) ||
    1035     1778679 :                     state.dataOutputProcessor->ReqRepVars(iReq).Key.empty()) {
    1036     1033350 :                     if (UtilityRoutines::SameString(state.dataOutputProcessor->ReqRepVars(iReq).VarName, "System Node Wetbulb Temperature")) {
    1037         155 :                         state.dataNodeInputMgr->NodeWetBulbRepReq(iNode) = true;
    1038         155 :                         NodeWetBulbSchedPtr(iNode) = state.dataOutputProcessor->ReqRepVars(iReq).SchedPtr;
    1039     1033195 :                     } else if (UtilityRoutines::SameString(state.dataOutputProcessor->ReqRepVars(iReq).VarName, "System Node Relative Humidity")) {
    1040          22 :                         NodeRelHumidityRepReq(iNode) = true;
    1041          22 :                         NodeRelHumiditySchedPtr(iNode) = state.dataOutputProcessor->ReqRepVars(iReq).SchedPtr;
    1042     1033173 :                     } else if (UtilityRoutines::SameString(state.dataOutputProcessor->ReqRepVars(iReq).VarName, "System Node Dewpoint Temperature")) {
    1043          19 :                         NodeDewPointRepReq(iNode) = true;
    1044          19 :                         NodeDewPointSchedPtr(iNode) = state.dataOutputProcessor->ReqRepVars(iReq).SchedPtr;
    1045     1033154 :                     } else if (UtilityRoutines::SameString(state.dataOutputProcessor->ReqRepVars(iReq).VarName, "System Node Specific Heat")) {
    1046           0 :                         NodeSpecificHeatRepReq(iNode) = true;
    1047           0 :                         NodeSpecificHeatSchedPtr(iNode) = state.dataOutputProcessor->ReqRepVars(iReq).SchedPtr;
    1048             :                     }
    1049             :                 }
    1050             :             }
    1051       59425 :             if (EMSManager::CheckIfNodeMoreInfoSensedByEMS(state, iNode, "System Node Wetbulb Temperature")) {
    1052           0 :                 state.dataNodeInputMgr->NodeWetBulbRepReq(iNode) = true;
    1053           0 :                 NodeWetBulbSchedPtr(iNode) = 0;
    1054             :             }
    1055       59425 :             if (EMSManager::CheckIfNodeMoreInfoSensedByEMS(state, iNode, "System Node Relative Humidity")) {
    1056           1 :                 NodeRelHumidityRepReq(iNode) = true;
    1057           1 :                 NodeRelHumiditySchedPtr(iNode) = 0;
    1058             :             }
    1059       59425 :             if (EMSManager::CheckIfNodeMoreInfoSensedByEMS(state, iNode, "System Node Dewpoint Temperature")) {
    1060           0 :                 NodeDewPointRepReq(iNode) = true;
    1061           0 :                 NodeDewPointSchedPtr(iNode) = 0;
    1062             :             }
    1063       59425 :             if (EMSManager::CheckIfNodeMoreInfoSensedByEMS(state, iNode, "System Node Specific Heat")) {
    1064           0 :                 NodeSpecificHeatRepReq(iNode) = true;
    1065           0 :                 NodeSpecificHeatSchedPtr(iNode) = 0;
    1066             :             }
    1067             :         }
    1068         769 :         state.dataNodeInputMgr->CalcMoreNodeInfoMyOneTimeFlag = false;
    1069             :     }
    1070             : 
    1071    55927977 :     for (int iNode = 1; iNode <= state.dataLoopNodes->NumOfNodes; ++iNode) {
    1072    55237503 :         ReportWetBulb = false;
    1073    55237503 :         ReportRelHumidity = false;
    1074    55237503 :         ReportDewPoint = false;
    1075    55237503 :         ReportSpecificHeat = false;
    1076    55237503 :         if (state.dataNodeInputMgr->NodeWetBulbRepReq(iNode) && NodeWetBulbSchedPtr(iNode) > 0) {
    1077           0 :             ReportWetBulb = (GetCurrentScheduleValue(state, NodeWetBulbSchedPtr(iNode)) > 0.0);
    1078    55237503 :         } else if (state.dataNodeInputMgr->NodeWetBulbRepReq(iNode) && NodeWetBulbSchedPtr(iNode) == 0) {
    1079       80713 :             ReportWetBulb = true;
    1080    55156790 :         } else if (state.dataLoopNodes->Node(iNode).SPMNodeWetBulbRepReq) {
    1081         680 :             ReportWetBulb = true;
    1082             :         }
    1083    55237503 :         if (NodeRelHumidityRepReq(iNode) && NodeRelHumiditySchedPtr(iNode) > 0) {
    1084           0 :             ReportRelHumidity = (GetCurrentScheduleValue(state, NodeRelHumiditySchedPtr(iNode)) > 0.0);
    1085    55237503 :         } else if (NodeRelHumidityRepReq(iNode) && NodeRelHumiditySchedPtr(iNode) == 0) {
    1086       13002 :             ReportRelHumidity = true;
    1087             :         }
    1088    55237503 :         if (NodeDewPointRepReq(iNode) && NodeDewPointSchedPtr(iNode) > 0) {
    1089           0 :             ReportDewPoint = (GetCurrentScheduleValue(state, NodeDewPointSchedPtr(iNode)) > 0.0);
    1090    55237503 :         } else if (NodeDewPointRepReq(iNode) && NodeDewPointSchedPtr(iNode) == 0) {
    1091      170774 :             ReportDewPoint = true;
    1092             :         }
    1093    55237503 :         if (NodeSpecificHeatRepReq(iNode) && NodeSpecificHeatSchedPtr(iNode) > 0) {
    1094           0 :             ReportSpecificHeat = (GetCurrentScheduleValue(state, NodeSpecificHeatSchedPtr(iNode)) > 0.0);
    1095    55237503 :         } else if (NodeSpecificHeatRepReq(iNode) && NodeSpecificHeatSchedPtr(iNode) == 0) {
    1096           0 :             ReportSpecificHeat = true;
    1097             :         }
    1098             :         // calculate the volume flow rate
    1099    55237503 :         if (state.dataLoopNodes->Node(iNode).FluidType == DataLoopNode::NodeFluidType::Air) {
    1100    29404069 :             state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateStdRho = state.dataLoopNodes->Node(iNode).MassFlowRate / RhoAirStdInit;
    1101             :             // if Node%Press was reliable could be used here.
    1102    88212207 :             RhoAirCurrent = PsyRhoAirFnPbTdbW(
    1103    88212207 :                 state, state.dataEnvrn->OutBaroPress, state.dataLoopNodes->Node(iNode).Temp, state.dataLoopNodes->Node(iNode).HumRat);
    1104    29404069 :             state.dataLoopNodes->MoreNodeInfo(iNode).Density = RhoAirCurrent;
    1105    29404069 :             if (RhoAirCurrent != 0.0)
    1106    29404069 :                 state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateCrntRho = state.dataLoopNodes->Node(iNode).MassFlowRate / RhoAirCurrent;
    1107    29404069 :             state.dataLoopNodes->MoreNodeInfo(iNode).ReportEnthalpy =
    1108    29404069 :                 PsyHFnTdbW(state.dataLoopNodes->Node(iNode).Temp, state.dataLoopNodes->Node(iNode).HumRat);
    1109    29404069 :             if (ReportWetBulb) {
    1110             :                 // if Node%Press was reliable could be used here.
    1111      325572 :                 state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = PsyTwbFnTdbWPb(state,
    1112       81393 :                                                                                       state.dataLoopNodes->Node(iNode).Temp,
    1113       81393 :                                                                                       state.dataLoopNodes->Node(iNode).HumRat,
    1114       81393 :                                                                                       state.dataEnvrn->OutBaroPress,
    1115       81393 :                                                                                       nodeReportingStrings[iNode - 1]);
    1116             :             } else {
    1117    29322676 :                 state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = 0.0;
    1118             :             }
    1119    29404069 :             if (ReportDewPoint) {
    1120      170774 :                 state.dataLoopNodes->MoreNodeInfo(iNode).AirDewPointTemp =
    1121      341548 :                     PsyTdpFnWPb(state, state.dataLoopNodes->Node(iNode).HumRat, state.dataEnvrn->OutBaroPress);
    1122             :             } else {
    1123    29233295 :                 state.dataLoopNodes->MoreNodeInfo(iNode).AirDewPointTemp = 0.0;
    1124             :             }
    1125    29404069 :             if (ReportRelHumidity) {
    1126             :                 // if Node%Press was reliable could be used here.
    1127             :                 // following routines don't issue psych errors and may be more reliable.
    1128       52008 :                 state.dataLoopNodes->MoreNodeInfo(iNode).RelHumidity = 100.0 * PsyRhFnTdbWPb(state,
    1129       13002 :                                                                                              state.dataLoopNodes->Node(iNode).Temp,
    1130       13002 :                                                                                              state.dataLoopNodes->Node(iNode).HumRat,
    1131       13002 :                                                                                              state.dataEnvrn->OutBaroPress,
    1132       13002 :                                                                                              nodeReportingStrings[iNode - 1]);
    1133             :             } else {
    1134    29391067 :                 state.dataLoopNodes->MoreNodeInfo(iNode).RelHumidity = 0.0;
    1135             :             }
    1136    29404069 :             if (ReportSpecificHeat) { // only call psych routine if needed.
    1137           0 :                 state.dataLoopNodes->MoreNodeInfo(iNode).SpecificHeat = PsyCpAirFnW(state.dataLoopNodes->Node(iNode).HumRat);
    1138             :             } else {
    1139    29404069 :                 state.dataLoopNodes->MoreNodeInfo(iNode).SpecificHeat = 0.0;
    1140             :             }
    1141    25833434 :         } else if (state.dataLoopNodes->Node(iNode).FluidType == DataLoopNode::NodeFluidType::Water) {
    1142             : 
    1143    51470646 :             if (!((state.dataLoopNodes->Node(iNode).FluidIndex > 0) &&
    1144    25714011 :                   (state.dataLoopNodes->Node(iNode).FluidIndex <= state.dataFluidProps->NumOfGlycols))) {
    1145       42624 :                 rho = RhoWaterStdInit;
    1146       42624 :                 rhoStd = RhoWaterStdInit;
    1147       42624 :                 Cp = CPCW(state.dataLoopNodes->Node(iNode).Temp);
    1148             :             } else {
    1149   102856044 :                 Cp = GetSpecificHeatGlycol(state,
    1150    25714011 :                                            nodeFluidNames[iNode - 1],
    1151    25714011 :                                            state.dataLoopNodes->Node(iNode).Temp,
    1152    25714011 :                                            state.dataLoopNodes->Node(iNode).FluidIndex,
    1153    25714011 :                                            nodeReportingStrings[iNode - 1]);
    1154    77142033 :                 rhoStd = GetDensityGlycol(state,
    1155    25714011 :                                           nodeFluidNames[iNode - 1],
    1156             :                                           DataGlobalConstants::InitConvTemp,
    1157    25714011 :                                           state.dataLoopNodes->Node(iNode).FluidIndex,
    1158    25714011 :                                           nodeReportingStrings[iNode - 1]);
    1159   102856044 :                 rho = GetDensityGlycol(state,
    1160    25714011 :                                        nodeFluidNames[iNode - 1],
    1161    25714011 :                                        state.dataLoopNodes->Node(iNode).Temp,
    1162    25714011 :                                        state.dataLoopNodes->Node(iNode).FluidIndex,
    1163    25714011 :                                        nodeReportingStrings[iNode - 1]);
    1164             :             }
    1165             : 
    1166    25756635 :             state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateStdRho = state.dataLoopNodes->Node(iNode).MassFlowRate / rhoStd;
    1167    25756635 :             state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateCrntRho = state.dataLoopNodes->Node(iNode).MassFlowRate / rho;
    1168    25756635 :             state.dataLoopNodes->MoreNodeInfo(iNode).Density = rho;
    1169    25756635 :             state.dataLoopNodes->MoreNodeInfo(iNode).ReportEnthalpy = Cp * state.dataLoopNodes->Node(iNode).Temp;
    1170    25756635 :             state.dataLoopNodes->MoreNodeInfo(iNode).SpecificHeat = Cp; // always fill since cp already always being calculated anyway
    1171    25756635 :             state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = 0.0;
    1172    25756635 :             state.dataLoopNodes->MoreNodeInfo(iNode).RelHumidity = 100.0;
    1173       76799 :         } else if (state.dataLoopNodes->Node(iNode).FluidType == DataLoopNode::NodeFluidType::Steam) {
    1174       55702 :             if (state.dataLoopNodes->Node(iNode).Quality == 1.0) {
    1175      158476 :                 SteamDensity = GetSatDensityRefrig(state,
    1176             :                                                    fluidNameSteam,
    1177       39619 :                                                    state.dataLoopNodes->Node(iNode).Temp,
    1178       39619 :                                                    state.dataLoopNodes->Node(iNode).Quality,
    1179       39619 :                                                    state.dataLoopNodes->Node(iNode).FluidIndex,
    1180       39619 :                                                    RoutineName);
    1181      158476 :                 EnthSteamInDry = GetSatEnthalpyRefrig(state,
    1182             :                                                       fluidNameSteam,
    1183       39619 :                                                       state.dataLoopNodes->Node(iNode).Temp,
    1184       39619 :                                                       state.dataLoopNodes->Node(iNode).Quality,
    1185       39619 :                                                       state.dataLoopNodes->Node(iNode).FluidIndex,
    1186       39619 :                                                       RoutineName);
    1187       39619 :                 state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateStdRho = state.dataLoopNodes->Node(iNode).MassFlowRate / SteamDensity;
    1188       39619 :                 state.dataLoopNodes->MoreNodeInfo(iNode).ReportEnthalpy = EnthSteamInDry;
    1189       39619 :                 state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = 0.0;
    1190       39619 :                 state.dataLoopNodes->MoreNodeInfo(iNode).RelHumidity = 0.0;
    1191       16083 :             } else if (state.dataLoopNodes->Node(iNode).Quality == 0.0) { // The node has condensate water through it
    1192       15123 :                 state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateStdRho = state.dataLoopNodes->Node(iNode).MassFlowRate / RhoWaterStdInit;
    1193       15123 :                 state.dataLoopNodes->MoreNodeInfo(iNode).ReportEnthalpy =
    1194       15123 :                     CPCW(state.dataLoopNodes->Node(iNode).Temp) * state.dataLoopNodes->Node(iNode).Temp;
    1195       15123 :                 state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = 0.0;
    1196       15123 :                 state.dataLoopNodes->MoreNodeInfo(iNode).RelHumidity = 0.0;
    1197             :             }
    1198       21097 :         } else if (state.dataLoopNodes->Node(iNode).FluidType == DataLoopNode::NodeFluidType::Electric) {
    1199        6590 :             state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateStdRho = 0.0;
    1200        6590 :             state.dataLoopNodes->MoreNodeInfo(iNode).ReportEnthalpy = 0.0;
    1201        6590 :             state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = 0.0;
    1202        6590 :             state.dataLoopNodes->MoreNodeInfo(iNode).RelHumidity = 0.0;
    1203        6590 :             state.dataLoopNodes->MoreNodeInfo(iNode).SpecificHeat = 0.0;
    1204             :         } else {
    1205       14507 :             state.dataLoopNodes->MoreNodeInfo(iNode).VolFlowRateStdRho = state.dataLoopNodes->Node(iNode).MassFlowRate / RhoAirStdInit;
    1206       14507 :             if (state.dataLoopNodes->Node(iNode).HumRat > 0.0) {
    1207           0 :                 state.dataLoopNodes->MoreNodeInfo(iNode).ReportEnthalpy =
    1208           0 :                     PsyHFnTdbW(state.dataLoopNodes->Node(iNode).Temp, state.dataLoopNodes->Node(iNode).HumRat);
    1209           0 :                 if (ReportWetBulb) {
    1210           0 :                     state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = PsyTwbFnTdbWPb(
    1211           0 :                         state, state.dataLoopNodes->Node(iNode).Temp, state.dataLoopNodes->Node(iNode).HumRat, state.dataEnvrn->StdBaroPress);
    1212             :                 } else {
    1213           0 :                     state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = 0.0;
    1214             :                 }
    1215           0 :                 if (ReportSpecificHeat) {
    1216           0 :                     state.dataLoopNodes->MoreNodeInfo(iNode).SpecificHeat = PsyCpAirFnW(state.dataLoopNodes->Node(iNode).HumRat);
    1217             :                 } else {
    1218           0 :                     state.dataLoopNodes->MoreNodeInfo(iNode).SpecificHeat = 0.0;
    1219             :                 }
    1220             :             } else {
    1221       14507 :                 state.dataLoopNodes->MoreNodeInfo(iNode).ReportEnthalpy =
    1222       14507 :                     CPCW(state.dataLoopNodes->Node(iNode).Temp) * state.dataLoopNodes->Node(iNode).Temp;
    1223       14507 :                 state.dataLoopNodes->MoreNodeInfo(iNode).WetBulbTemp = 0.0;
    1224       14507 :                 state.dataLoopNodes->MoreNodeInfo(iNode).SpecificHeat = 0.0;
    1225             :             }
    1226             :         }
    1227             :     }
    1228      690474 : }
    1229             : 
    1230          63 : void MarkNode(EnergyPlusData &state,
    1231             :               int const NodeNumber, // Node Number to be marked
    1232             :               DataLoopNode::ConnectionObjectType const ObjectType,
    1233             :               std::string const &ObjectName,
    1234             :               std::string const &FieldName)
    1235             : {
    1236             : 
    1237             :     // SUBROUTINE INFORMATION:
    1238             :     //       AUTHOR         Linda Lawrie
    1239             :     //       DATE WRITTEN   March 2004
    1240             :     //       MODIFIED       na
    1241             :     //       RE-ENGINEERED  na
    1242             : 
    1243             :     // PURPOSE OF THIS SUBROUTINE:
    1244             :     // This subroutine marks a node -- this node needs to exist in more than one object.
    1245             : 
    1246          63 :     state.dataLoopNodes->MarkedNode(NodeNumber).IsMarked = true;
    1247          63 :     state.dataLoopNodes->MarkedNode(NodeNumber).ObjectType = ObjectType;
    1248          63 :     state.dataLoopNodes->MarkedNode(NodeNumber).ObjectName = ObjectName;
    1249          63 :     state.dataLoopNodes->MarkedNode(NodeNumber).FieldName = FieldName;
    1250          63 : }
    1251             : 
    1252         769 : void CheckMarkedNodes(EnergyPlusData &state, bool &ErrorsFound)
    1253             : {
    1254             : 
    1255             :     // SUBROUTINE INFORMATION:
    1256             :     //       AUTHOR         Linda Lawrie
    1257             :     //       DATE WRITTEN   March 2004
    1258             :     //       MODIFIED       na
    1259             :     //       RE-ENGINEERED  na
    1260             : 
    1261             :     // PURPOSE OF THIS SUBROUTINE:
    1262             :     // This subroutine checks "marked" nodes.
    1263             : 
    1264       60194 :     for (int NodeNum = 1; NodeNum <= state.dataLoopNodes->NumOfNodes; ++NodeNum) {
    1265       59425 :         if (state.dataLoopNodes->MarkedNode(NodeNum).IsMarked) {
    1266          54 :             if (state.dataNodeInputMgr->NodeRef(NodeNum) == 0) {
    1267             :                 auto objType =
    1268           0 :                     BranchNodeConnections::ConnectionObjectTypeNames[static_cast<int>(state.dataLoopNodes->MarkedNode(NodeNum).ObjectType)];
    1269           0 :                 ShowSevereError(state, "Node=\"" + state.dataLoopNodes->NodeID(NodeNum) + "\" did not find reference by another object.");
    1270           0 :                 ShowContinueError(state,
    1271           0 :                                   format(R"(Object="{}", Name="{}", Field=[{}])",
    1272             :                                          objType,
    1273           0 :                                          state.dataLoopNodes->MarkedNode(NodeNum).ObjectName,
    1274           0 :                                          state.dataLoopNodes->MarkedNode(NodeNum).FieldName));
    1275           0 :                 ErrorsFound = true;
    1276             :             }
    1277             :         }
    1278             :     }
    1279         769 : }
    1280             : 
    1281        2313 : } // namespace EnergyPlus::NodeInputManager

Generated by: LCOV version 1.13