LCOV - code coverage report
Current view: top level - EnergyPlus - NodeInputManager.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 79.8 % 559 446
Test Date: 2025-06-02 07:23:51 Functions: 100.0 % 12 12

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

Generated by: LCOV version 2.0-1