LCOV - code coverage report
Current view: top level - EnergyPlus - OutAirNodeManager.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 187 228 82.0 %
Date: 2023-01-17 19:17:23 Functions: 8 8 100.0 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // ObjexxFCL Headers
      49             : #include <ObjexxFCL/Fmath.hh>
      50             : 
      51             : // EnergyPlus Headers
      52             : #include <EnergyPlus/CurveManager.hh>
      53             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      54             : #include <EnergyPlus/DataContaminantBalance.hh>
      55             : #include <EnergyPlus/DataEnvironment.hh>
      56             : #include <EnergyPlus/DataLoopNode.hh>
      57             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      58             : #include <EnergyPlus/NodeInputManager.hh>
      59             : #include <EnergyPlus/OutAirNodeManager.hh>
      60             : #include <EnergyPlus/Psychrometrics.hh>
      61             : #include <EnergyPlus/ScheduleManager.hh>
      62             : #include <EnergyPlus/UtilityRoutines.hh>
      63             : 
      64             : namespace EnergyPlus {
      65             : 
      66             : namespace OutAirNodeManager {
      67             :     // Module containing the routines that deal with the outside air nodes
      68             : 
      69             :     // MODULE INFORMATION:
      70             :     //       AUTHOR         Fred Buhl
      71             :     //       DATE WRITTEN   September 1998
      72             :     //       MODIFIED       na
      73             :     //       RE-ENGINEERED  na
      74             : 
      75             :     // PURPOSE OF THIS MODULE:
      76             :     // To encapsulate the data and update the conditions for all the outside
      77             :     // air nodes in the problem.
      78             : 
      79             :     // METHODOLOGY EMPLOYED:
      80             :     // Outside air nodes provide the connection to outside conditions for the
      81             :     // EnergyPlus HVAC simulation. The  list of air nodes specified in the input
      82             :     // file will be read in. Each air node will be updated to the outside environmental
      83             :     // conditions at the start of each EnergyPlus main time step.
      84             : 
      85             :     // REFERENCES:
      86             : 
      87             :     // OTHER NOTES:
      88             : 
      89             :     // USE STATEMENTS:
      90             :     // Use statements for data only modules
      91             :     // Using/Aliasing
      92             :     using namespace DataLoopNode;
      93             :     using namespace DataEnvironment;
      94             : 
      95     2575824 :     void SetOutAirNodes(EnergyPlusData &state)
      96             :     {
      97             : 
      98             :         // SUBROUTINE INFORMATION:
      99             :         //       AUTHOR         Fred Buhl
     100             :         //       DATE WRITTEN   September 1998
     101             :         //       MODIFIED       na
     102             :         //       RE-ENGINEERED  na
     103             : 
     104             :         // PURPOSE OF THIS SUBROUTINE:
     105             :         // Make sure the outside air nodes are prepared for the HVAC simulation
     106             : 
     107             :         // METHODOLOGY EMPLOYED:
     108             :         // Use appropriate flag to check for needed action
     109             : 
     110     2575824 :         if (state.dataOutAirNodeMgr->GetOutAirNodesInputFlag) { // First time subroutine has been entered
     111         730 :             GetOutAirNodesInput(state);                         // Get OutAir Nodes data
     112         730 :             state.dataOutAirNodeMgr->GetOutAirNodesInputFlag = false;
     113             :         }
     114     2575824 :         InitOutAirNodes(state);
     115     2575824 :     }
     116             : 
     117         771 :     void GetOutAirNodesInput(EnergyPlusData &state)
     118             :     {
     119             : 
     120             :         // SUBROUTINE INFORMATION:
     121             :         //       AUTHOR         Fred Buhl
     122             :         //       DATE WRITTEN   September 1998
     123             :         //       MODIFIED       na
     124             :         //       RE-ENGINEERED  na
     125             : 
     126             :         // PURPOSE OF THIS SUBROUTINE
     127             :         // Read in the list of outside air nodes & store in array OutAirInletNodeList
     128             : 
     129             :         // METHODOLOGY EMPLOYED:
     130             :         // Use the Get routines from the InputProcessor module.
     131             : 
     132             :         // Using/Aliasing
     133             :         using namespace NodeInputManager;
     134             :         using ScheduleManager::GetScheduleIndex;
     135             : 
     136             :         // Locals
     137             :         // SUBROUTINE PARAMETER DEFINITIONS:
     138             :         static constexpr std::string_view RoutineName("GetOutAirNodesInput: "); // include trailing blank space
     139             : 
     140             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     141             :         int NumOutAirInletNodeLists;
     142             :         int NumOutsideAirNodeSingles;
     143             :         int NumNums;   // Number of REAL(r64) numbers returned by GetObjectItem
     144             :         int NumAlphas; // Number of alphanumerics returned by GetObjectItem
     145             :         int NumParams;
     146        1542 :         Array1D_int NodeNums;
     147             :         int NumNodes;
     148             :         int IOStat;  // Status flag from GetObjectItem
     149             :         int NodeNum; // index into NodeNums
     150             :         //  INTEGER :: OutAirNodeNum ! index into OutAirInletNodeList
     151             :         int OutAirInletNodeListNum;  // OUTSIDE AIR INLET NODE LIST index
     152             :         int OutsideAirNodeSingleNum; // OUTSIDE AIR NODE index
     153             :         int AlphaNum;                // index into Alphas
     154             :         std::size_t ListSize;        // size of OutAirInletNodeList
     155             :         //  LOGICAL :: AlreadyInList ! flag used for checking for duplicate input
     156             :         bool ErrorsFound;
     157             :         bool ErrInList;
     158             :         std::size_t CurSize;
     159             :         int NextFluidStreamNum; // Fluid stream index (all outside air inlet nodes need a unique fluid stream number)
     160        1542 :         Array1D_int TmpNums;
     161        1542 :         std::string CurrentModuleObject; // Object type for getting and error messages
     162        1542 :         Array1D_string Alphas;           // Alpha input items for object
     163        1542 :         Array1D_string cAlphaFields;     // Alpha field names
     164        1542 :         Array1D_string cNumericFields;   // Numeric field names
     165        1542 :         Array1D<Real64> Numbers;         // Numeric input items for object
     166        1542 :         Array1D_bool lAlphaBlanks;       // Logical array, alpha field input BLANK = .TRUE.
     167        1542 :         Array1D_bool lNumericBlanks;     // Logical array, numeric field input BLANK = .TRUE.
     168         771 :         int MaxNums(0);                  // Maximum number of numeric input fields
     169         771 :         int MaxAlphas(0);                // Maximum number of alpha input fields
     170         771 :         int TotalArgs(0);                // Total number of alpha and numeric arguments (max) for a
     171             : 
     172         771 :         NumOutAirInletNodeLists = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "OutdoorAir:NodeList");
     173         771 :         NumOutsideAirNodeSingles = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "OutdoorAir:Node");
     174         771 :         state.dataOutAirNodeMgr->NumOutsideAirNodes = 0;
     175         771 :         ErrorsFound = false;
     176         771 :         NextFluidStreamNum = 1;
     177             : 
     178         771 :         ListSize = 0;
     179         771 :         CurSize = 100;
     180         771 :         TmpNums.dimension(CurSize, 0);
     181             : 
     182         771 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "NodeList", NumParams, NumAlphas, NumNums);
     183         771 :         NodeNums.dimension(NumParams, 0);
     184             : 
     185         771 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "OutdoorAir:NodeList", TotalArgs, NumAlphas, NumNums);
     186         771 :         MaxNums = max(MaxNums, NumNums);
     187         771 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     188         771 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "OutdoorAir:Node", TotalArgs, NumAlphas, NumNums);
     189         771 :         MaxNums = max(MaxNums, NumNums);
     190         771 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     191             : 
     192         771 :         Alphas.allocate(MaxAlphas);
     193         771 :         cAlphaFields.allocate(MaxAlphas);
     194         771 :         cNumericFields.allocate(MaxNums);
     195         771 :         Numbers.dimension(MaxNums, 0.0);
     196         771 :         lAlphaBlanks.dimension(MaxAlphas, true);
     197         771 :         lNumericBlanks.dimension(MaxNums, true);
     198             : 
     199         771 :         if (NumOutAirInletNodeLists > 0) {
     200             :             // Loop over all outside air inlet nodes in the input and count them
     201         428 :             CurrentModuleObject = "OutdoorAir:NodeList";
     202        1431 :             for (OutAirInletNodeListNum = 1; OutAirInletNodeListNum <= NumOutAirInletNodeLists; ++OutAirInletNodeListNum) {
     203        1003 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
     204             :                                                                          CurrentModuleObject,
     205             :                                                                          OutAirInletNodeListNum,
     206             :                                                                          Alphas,
     207             :                                                                          NumAlphas,
     208             :                                                                          Numbers,
     209             :                                                                          NumNums,
     210             :                                                                          IOStat,
     211             :                                                                          lNumericBlanks,
     212             :                                                                          lAlphaBlanks,
     213             :                                                                          cAlphaFields,
     214             :                                                                          cNumericFields);
     215             : 
     216        2008 :                 for (AlphaNum = 1; AlphaNum <= NumAlphas; ++AlphaNum) {
     217        1005 :                     ErrInList = false;
     218             :                     //  To support HVAC diagram, every outside inlet node must have a unique fluid stream number
     219             :                     //  GetNodeNums will increment the value across a node list, the starting value must be incremented
     220             :                     //  here across lists and across objects
     221        2010 :                     GetNodeNums(state,
     222        1005 :                                 Alphas(AlphaNum),
     223             :                                 NumNodes,
     224             :                                 NodeNums,
     225             :                                 ErrInList,
     226             :                                 DataLoopNode::NodeFluidType::Air,
     227             :                                 DataLoopNode::ConnectionObjectType::OutdoorAirNodeList,
     228             :                                 CurrentModuleObject,
     229             :                                 DataLoopNode::ConnectionType::OutsideAir,
     230             :                                 static_cast<NodeInputManager::CompFluidStream>(NextFluidStreamNum),
     231             :                                 ObjectIsNotParent,
     232             :                                 IncrementFluidStreamYes,
     233        1005 :                                 cAlphaFields(AlphaNum));
     234        1005 :                     NextFluidStreamNum += NumNodes;
     235        1005 :                     if (ErrInList) {
     236           0 :                         ShowContinueError(state, "Occurred in " + CurrentModuleObject + ", " + cAlphaFields(AlphaNum) + " = " + Alphas(AlphaNum));
     237           0 :                         ErrorsFound = true;
     238             :                     }
     239        2158 :                     for (NodeNum = 1; NodeNum <= NumNodes; ++NodeNum) {
     240             :                         // Duplicates here are not a problem, just ignore
     241        1153 :                         if (!any_eq(TmpNums, NodeNums(NodeNum))) {
     242        1152 :                             ++ListSize;
     243        1152 :                             if (ListSize > CurSize) {
     244           0 :                                 TmpNums.redimension(CurSize += 100, 0);
     245             :                             }
     246        1152 :                             TmpNums(ListSize) = NodeNums(NodeNum);
     247             :                         }
     248             :                     }
     249             :                 }
     250             :             }
     251             : 
     252         428 :             if (ErrorsFound) {
     253           0 :                 ShowFatalError(state, std::string{RoutineName} + "Errors found in getting " + CurrentModuleObject + " input.");
     254             :             }
     255             :         }
     256             : 
     257         771 :         if (NumOutsideAirNodeSingles > 0) {
     258             :             // Loop over all single outside air nodes in the input
     259         287 :             CurrentModuleObject = "OutdoorAir:Node";
     260        1453 :             for (OutsideAirNodeSingleNum = 1; OutsideAirNodeSingleNum <= NumOutsideAirNodeSingles; ++OutsideAirNodeSingleNum) {
     261        1166 :                 state.dataInputProcessing->inputProcessor->getObjectItem(state,
     262             :                                                                          CurrentModuleObject,
     263             :                                                                          OutsideAirNodeSingleNum,
     264             :                                                                          Alphas,
     265             :                                                                          NumAlphas,
     266             :                                                                          Numbers,
     267             :                                                                          NumNums,
     268             :                                                                          IOStat,
     269             :                                                                          lNumericBlanks,
     270             :                                                                          lAlphaBlanks,
     271             :                                                                          cAlphaFields,
     272             :                                                                          cNumericFields);
     273             : 
     274        1166 :                 ErrInList = false;
     275             :                 //  To support HVAC diagram, every outside inlet node must have a unique fluid stream number
     276             :                 //  GetNodeNums will increment the value across a node list, the starting value must be incremented
     277             :                 //  here across lists and across objects
     278        2332 :                 GetNodeNums(state,
     279        1166 :                             Alphas(1),
     280             :                             NumNodes,
     281             :                             NodeNums,
     282             :                             ErrInList,
     283             :                             DataLoopNode::NodeFluidType::Air,
     284             :                             DataLoopNode::ConnectionObjectType::OutdoorAirNode,
     285             :                             CurrentModuleObject,
     286             :                             DataLoopNode::ConnectionType::OutsideAir,
     287             :                             static_cast<NodeInputManager::CompFluidStream>(NextFluidStreamNum),
     288             :                             ObjectIsNotParent,
     289             :                             IncrementFluidStreamYes,
     290        1166 :                             cAlphaFields(1));
     291        1166 :                 NextFluidStreamNum += NumNodes;
     292        1166 :                 if (ErrInList) {
     293           0 :                     ShowContinueError(state, "Occurred in " + CurrentModuleObject + ", " + cAlphaFields(1) + " = " + Alphas(1));
     294           0 :                     ErrorsFound = true;
     295             :                 }
     296             : 
     297        1166 :                 if (NumNodes > 1) {
     298           0 :                     ShowSevereError(state, CurrentModuleObject + ", " + cAlphaFields(1) + " = " + Alphas(1));
     299           0 :                     ShowContinueError(state, "...appears to point to a node list, not a single node.");
     300           0 :                     ErrorsFound = true;
     301           0 :                     continue;
     302             :                 }
     303             : 
     304        1166 :                 if (!any_eq(TmpNums, NodeNums(1))) {
     305        1166 :                     ++ListSize;
     306        1166 :                     if (ListSize > CurSize) {
     307           1 :                         TmpNums.redimension(CurSize += 100, 0);
     308             :                     }
     309        1166 :                     TmpNums(ListSize) = NodeNums(1);
     310             :                 } else { // Duplicates are a problem
     311           0 :                     ShowSevereError(state, CurrentModuleObject + ", duplicate " + cAlphaFields(1) + " = " + Alphas(1));
     312           0 :                     ShowContinueError(state, "Duplicate " + cAlphaFields(1) + " might be found in an OutdoorAir:NodeList.");
     313           0 :                     ErrorsFound = true;
     314           0 :                     continue;
     315             :                 }
     316             : 
     317             :                 // Set additional node properties
     318        1166 :                 if (NumNums > 0) state.dataLoopNodes->Node(NodeNums(1)).Height = Numbers(1);
     319             : 
     320        1166 :                 if (NumAlphas > 1) {
     321           2 :                     state.dataGlobal->AnyLocalEnvironmentsInModel = true;
     322             :                 }
     323             : 
     324        1166 :                 if (NumAlphas > 1 && !lAlphaBlanks(2)) {
     325           2 :                     state.dataLoopNodes->Node(NodeNums(1)).OutAirDryBulbSchedNum = GetScheduleIndex(state, Alphas(2));
     326           2 :                     if (state.dataLoopNodes->Node(NodeNums(1)).OutAirDryBulbSchedNum == 0) {
     327           0 :                         ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + cAlphaFields(2) + "\", invalid schedule.");
     328           0 :                         ShowContinueError(state, "Dry Bulb Temperature Schedule not found=\"" + Alphas(2) + "\".");
     329           0 :                         ErrorsFound = true;
     330             :                     }
     331             :                 }
     332             : 
     333        1166 :                 if (NumAlphas > 2 && !lAlphaBlanks(3)) {
     334           1 :                     state.dataLoopNodes->Node(NodeNums(1)).OutAirWetBulbSchedNum = GetScheduleIndex(state, Alphas(3));
     335           1 :                     if (state.dataLoopNodes->Node(NodeNums(1)).OutAirWetBulbSchedNum == 0) {
     336           0 :                         ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + cAlphaFields(3) + "\", invalid schedule.");
     337           0 :                         ShowContinueError(state, "Wet Bulb Temperature Schedule not found=\"" + Alphas(3) + "\".");
     338           0 :                         ErrorsFound = true;
     339             :                     }
     340             :                 }
     341             : 
     342        1166 :                 if (NumAlphas > 3 && !lAlphaBlanks(4)) {
     343           1 :                     state.dataLoopNodes->Node(NodeNums(1)).OutAirWindSpeedSchedNum = GetScheduleIndex(state, Alphas(4));
     344           1 :                     if (state.dataLoopNodes->Node(NodeNums(1)).OutAirWindSpeedSchedNum == 0) {
     345           0 :                         ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + cAlphaFields(4) + "\", invalid schedule.");
     346           0 :                         ShowContinueError(state, "Wind Speed Schedule not found=\"" + Alphas(4) + "\".");
     347           0 :                         ErrorsFound = true;
     348             :                     }
     349             :                 }
     350             : 
     351        1166 :                 if (NumAlphas > 4 && !lAlphaBlanks(5)) {
     352           1 :                     state.dataLoopNodes->Node(NodeNums(1)).OutAirWindDirSchedNum = GetScheduleIndex(state, Alphas(5));
     353           1 :                     if (state.dataLoopNodes->Node(NodeNums(1)).OutAirWindDirSchedNum == 0) {
     354           0 :                         ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + "=\"" + cAlphaFields(5) + "\", invalid schedule.");
     355           0 :                         ShowContinueError(state, "Wind Direction Schedule not found=\"" + Alphas(5) + "\".");
     356           0 :                         ErrorsFound = true;
     357             :                     }
     358             :                 }
     359             : 
     360        1166 :                 if (NumAlphas > 8) {
     361           0 :                     ShowSevereError(state, CurrentModuleObject + ", " + cAlphaFields(1) + " = " + Alphas(1));
     362           0 :                     ShowContinueError(state, "Object Definition indicates more than 7 Alpha Objects.");
     363           0 :                     ErrorsFound = true;
     364           0 :                     continue;
     365             :                 }
     366        2330 :                 if (state.dataLoopNodes->Node(NodeNums(1)).OutAirDryBulbSchedNum > 0 ||
     367        1164 :                     state.dataLoopNodes->Node(NodeNums(1)).OutAirWetBulbSchedNum > 0) {
     368           2 :                     state.dataLoopNodes->Node(NodeNums(1)).IsLocalNode = true;
     369             :                 }
     370             :             }
     371         287 :             if (ErrorsFound) {
     372           0 :                 ShowFatalError(state, std::string{RoutineName} + "Errors found in getting " + CurrentModuleObject + " input.");
     373             :             }
     374             :         }
     375             : 
     376         771 :         if (ListSize > 0) {
     377         491 :             state.dataOutAirNodeMgr->NumOutsideAirNodes = ListSize;
     378         491 :             state.dataOutAirNodeMgr->OutsideAirNodeList = TmpNums({1, static_cast<int>(ListSize)});
     379             :         }
     380         771 :     }
     381             : 
     382     2575824 :     void InitOutAirNodes(EnergyPlusData &state)
     383             :     {
     384             :         // SUBROUTINE INFORMATION:
     385             :         //       AUTHOR         Fred Buhl
     386             :         //       DATE WRITTEN   Sept 1998
     387             :         //       MODIFIED       B. Griffith, added EMS override
     388             :         //       RE-ENGINEERED  na
     389             : 
     390             :         // PURPOSE OF THIS SUBROUTINE:
     391             :         // Initialize the outside air node data data.  In Particular,
     392             :         // set the outside air nodes to the outside conditions at the
     393             :         // start of every heat balance time step.
     394             : 
     395             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     396             :         int OutsideAirNodeNum;
     397             :         int NodeNum;
     398             : 
     399             :         // Do the begin time step initialization
     400    10699562 :         for (OutsideAirNodeNum = 1; OutsideAirNodeNum <= state.dataOutAirNodeMgr->NumOutsideAirNodes; ++OutsideAirNodeNum) {
     401     8123738 :             NodeNum = state.dataOutAirNodeMgr->OutsideAirNodeList(OutsideAirNodeNum);
     402     8123738 :             SetOANodeValues(state, NodeNum, true);
     403             :         }
     404     2575824 :     }
     405             : 
     406        2790 :     bool CheckOutAirNodeNumber(EnergyPlusData &state, int const NodeNumber) // Number of node to check to see if in Outside Air list
     407             :     {
     408             : 
     409             :         // FUNCTION INFORMATION:
     410             :         //       AUTHOR         Linda Lawrie
     411             :         //       DATE WRITTEN   Feb 2007
     412             :         //       MODIFIED       na
     413             :         //       RE-ENGINEERED  na
     414             : 
     415             :         // PURPOSE OF THIS FUNCTION:
     416             :         // Provide an entry into the OutAirNode List for checking from other routines.
     417             : 
     418             :         // METHODOLOGY EMPLOYED:
     419             :         // na
     420             : 
     421             :         // REFERENCES:
     422             :         // na
     423             : 
     424             :         // USE STATEMENTS:
     425             :         // na
     426             : 
     427             :         // Return value
     428             :         bool Okay; // True if found, false if not
     429             : 
     430             :         // Locals
     431             :         // FUNCTION ARGUMENT DEFINITIONS:
     432             : 
     433             :         // FUNCTION PARAMETER DEFINITIONS:
     434             :         // na
     435             : 
     436             :         // INTERFACE BLOCK SPECIFICATIONS:
     437             :         // na
     438             : 
     439             :         // DERIVED TYPE DEFINITIONS:
     440             :         // na
     441             : 
     442             :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
     443             :         // na
     444             : 
     445        2790 :         if (state.dataOutAirNodeMgr->GetOutAirNodesInputFlag) { // First time subroutine has been entered
     446          41 :             GetOutAirNodesInput(state);                         // Get Out Air Nodes data
     447          41 :             state.dataOutAirNodeMgr->GetOutAirNodesInputFlag = false;
     448          41 :             SetOutAirNodes(state);
     449             :         }
     450             : 
     451        2790 :         if (any_eq(state.dataOutAirNodeMgr->OutsideAirNodeList, NodeNumber)) {
     452        1571 :             Okay = true;
     453             :         } else {
     454        1219 :             Okay = false;
     455             :         }
     456             : 
     457        2790 :         return Okay;
     458             :     }
     459             : 
     460         117 :     void CheckAndAddAirNodeNumber(EnergyPlusData &state,
     461             :                                   int const NodeNumber, // Number of node to check to see if in Outside Air list
     462             :                                   bool &Okay            // True if found, false if not
     463             :     )
     464             :     {
     465             : 
     466             :         // SUBROUTINE INFORMATION:
     467             :         //       AUTHOR         Linda Lawrie
     468             :         //       DATE WRITTEN   March 2007
     469             :         //       MODIFIED       na
     470             :         //       RE-ENGINEERED  na
     471             : 
     472             :         // PURPOSE OF THIS SUBROUTINE:
     473             :         // At the time of writing, some items (namely Chillers) have "made up" node
     474             :         // names for nodes that are "outside air nodes".  Rather than fatal out, add
     475             :         // this subroutine which will check and then add a outside air node, if necessary.
     476             : 
     477             :         // METHODOLOGY EMPLOYED:
     478             :         // na
     479             : 
     480             :         // REFERENCES:
     481             :         // na
     482             : 
     483             :         // Using/Aliasing
     484             :         using namespace NodeInputManager;
     485             : 
     486             :         // Locals
     487             :         // SUBROUTINE ARGUMENT DEFINITIONS:
     488             : 
     489             :         // SUBROUTINE PARAMETER DEFINITIONS:
     490             :         // na
     491             : 
     492             :         // INTERFACE BLOCK SPECIFICATIONS:
     493             :         // na
     494             : 
     495             :         // DERIVED TYPE DEFINITIONS:
     496             :         // na
     497             : 
     498             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     499         234 :         Array1D_int TmpNums;
     500             :         int DummyNumber;
     501             : 
     502         117 :         if (state.dataOutAirNodeMgr->GetOutAirNodesInputFlag) { // First time subroutine has been entered
     503           0 :             GetOutAirNodesInput(state);                         // Get Out Air Nodes data
     504           0 :             state.dataOutAirNodeMgr->GetOutAirNodesInputFlag = false;
     505           0 :             SetOutAirNodes(state);
     506             :         }
     507             : 
     508         117 :         Okay = false;
     509             : 
     510         117 :         if (state.dataOutAirNodeMgr->NumOutsideAirNodes > 0) {
     511         116 :             if (any_eq(state.dataOutAirNodeMgr->OutsideAirNodeList, NodeNumber)) {
     512         113 :                 Okay = true;
     513             :             } else {
     514           3 :                 Okay = false;
     515             :             }
     516             :         } else {
     517           1 :             Okay = false;
     518             :         }
     519             : 
     520         117 :         if (NodeNumber > 0) {
     521         117 :             if (!Okay) { // Add new outside air node to list
     522           4 :                 state.dataOutAirNodeMgr->OutsideAirNodeList.redimension(++state.dataOutAirNodeMgr->NumOutsideAirNodes);
     523           4 :                 state.dataOutAirNodeMgr->OutsideAirNodeList(state.dataOutAirNodeMgr->NumOutsideAirNodes) = NodeNumber;
     524           4 :                 TmpNums = state.dataOutAirNodeMgr->OutsideAirNodeList;
     525           4 :                 bool errFlag(false);
     526             :                 // register new node..
     527           8 :                 GetNodeNums(state,
     528           4 :                             state.dataLoopNodes->NodeID(NodeNumber),
     529             :                             DummyNumber,
     530             :                             TmpNums,
     531             :                             errFlag,
     532             :                             DataLoopNode::NodeFluidType::Air,
     533             :                             DataLoopNode::ConnectionObjectType::OutdoorAirNode,
     534             :                             "OutdoorAir:Node",
     535             :                             DataLoopNode::ConnectionType::OutsideAir,
     536           4 :                             static_cast<NodeInputManager::CompFluidStream>(state.dataOutAirNodeMgr->NumOutsideAirNodes),
     537             :                             ObjectIsNotParent,
     538           4 :                             IncrementFluidStreamYes);
     539           4 :                 SetOANodeValues(state, NodeNumber, false);
     540             :             }
     541             :         }
     542         117 :     }
     543             : 
     544     8123742 :     void SetOANodeValues(EnergyPlusData &state,
     545             :                          int const NodeNum, // Number of node to check to see if in Outside Air list
     546             :                          bool InitCall      // True if Init calls, false if CheckAndAddAirNodeNumber calls
     547             :     )
     548             :     {
     549             :         // SUBROUTINE INFORMATION:
     550             :         //       AUTHOR         L. Gu
     551             :         //       DATE WRITTEN   July 2018
     552             : 
     553             :         // PURPOSE OF THIS SUBROUTINE:
     554             :         // Consolidate a block from both CheckAndAddAirNodeNumber and InitOutAirNodes to set
     555             :         // up outdoor node values
     556             : 
     557             :         using Psychrometrics::PsyHFnTdbW;
     558             :         using Psychrometrics::PsyTwbFnTdbWPb;
     559             :         using Psychrometrics::PsyWFnTdbTwbPb;
     560             :         using ScheduleManager::GetCurrentScheduleValue;
     561             : 
     562             :         // Set node data to global values
     563     8123742 :         if (state.dataLoopNodes->Node(NodeNum).Height < 0.0) {
     564             :             // Note -- this setting is different than the DataEnvironment "AT" settings.
     565     7855645 :             state.dataLoopNodes->Node(NodeNum).OutAirDryBulb = state.dataEnvrn->OutDryBulbTemp;
     566     7855645 :             state.dataLoopNodes->Node(NodeNum).OutAirWetBulb = state.dataEnvrn->OutWetBulbTemp;
     567     7855645 :             if (InitCall) state.dataLoopNodes->Node(NodeNum).OutAirWindSpeed = state.dataEnvrn->WindSpeed;
     568             :         } else {
     569      268097 :             state.dataLoopNodes->Node(NodeNum).OutAirDryBulb = OutDryBulbTempAt(state, state.dataLoopNodes->Node(NodeNum).Height);
     570      268097 :             state.dataLoopNodes->Node(NodeNum).OutAirWetBulb = OutWetBulbTempAt(state, state.dataLoopNodes->Node(NodeNum).Height);
     571      268097 :             if (InitCall)
     572      268097 :                 state.dataLoopNodes->Node(NodeNum).OutAirWindSpeed = DataEnvironment::WindSpeedAt(state, state.dataLoopNodes->Node(NodeNum).Height);
     573             :         }
     574     8123742 :         if (!InitCall) state.dataLoopNodes->Node(NodeNum).OutAirWindSpeed = state.dataEnvrn->WindSpeed;
     575     8123742 :         state.dataLoopNodes->Node(NodeNum).OutAirWindDir = state.dataEnvrn->WindDir;
     576             : 
     577     8123742 :         if (InitCall) {
     578             :             // Set node data to local air node values if defined
     579     8123738 :             if (state.dataLoopNodes->Node(NodeNum).OutAirDryBulbSchedNum != 0) {
     580        6756 :                 state.dataLoopNodes->Node(NodeNum).OutAirDryBulb =
     581        6756 :                     GetCurrentScheduleValue(state, state.dataLoopNodes->Node(NodeNum).OutAirDryBulbSchedNum);
     582             :             }
     583     8123738 :             if (state.dataLoopNodes->Node(NodeNum).OutAirWetBulbSchedNum != 0) {
     584        2706 :                 state.dataLoopNodes->Node(NodeNum).OutAirWetBulb =
     585        2706 :                     GetCurrentScheduleValue(state, state.dataLoopNodes->Node(NodeNum).OutAirWetBulbSchedNum);
     586             :             }
     587     8123738 :             if (state.dataLoopNodes->Node(NodeNum).OutAirWindSpeedSchedNum != 0) {
     588        2706 :                 state.dataLoopNodes->Node(NodeNum).OutAirWindSpeed =
     589        2706 :                     GetCurrentScheduleValue(state, state.dataLoopNodes->Node(NodeNum).OutAirWindSpeedSchedNum);
     590             :             }
     591     8123738 :             if (state.dataLoopNodes->Node(NodeNum).OutAirWindDirSchedNum != 0) {
     592        2706 :                 state.dataLoopNodes->Node(NodeNum).OutAirWindDir =
     593        2706 :                     GetCurrentScheduleValue(state, state.dataLoopNodes->Node(NodeNum).OutAirWindDirSchedNum);
     594             :             }
     595             : 
     596             :             // Set node data to EMS overwritten values if defined
     597     8123738 :             if (state.dataLoopNodes->Node(NodeNum).EMSOverrideOutAirDryBulb)
     598       16128 :                 state.dataLoopNodes->Node(NodeNum).OutAirDryBulb = state.dataLoopNodes->Node(NodeNum).EMSValueForOutAirDryBulb;
     599     8123738 :             if (state.dataLoopNodes->Node(NodeNum).EMSOverrideOutAirWetBulb)
     600       16128 :                 state.dataLoopNodes->Node(NodeNum).OutAirWetBulb = state.dataLoopNodes->Node(NodeNum).EMSValueForOutAirWetBulb;
     601     8123738 :             if (state.dataLoopNodes->Node(NodeNum).EMSOverrideOutAirWindSpeed)
     602           0 :                 state.dataLoopNodes->Node(NodeNum).OutAirWindSpeed = state.dataLoopNodes->Node(NodeNum).EMSValueForOutAirWindSpeed;
     603     8123738 :             if (state.dataLoopNodes->Node(NodeNum).EMSOverrideOutAirWindDir)
     604           0 :                 state.dataLoopNodes->Node(NodeNum).OutAirWindDir = state.dataLoopNodes->Node(NodeNum).EMSValueForOutAirWindDir;
     605             :         }
     606             : 
     607     8123742 :         state.dataLoopNodes->Node(NodeNum).Temp = state.dataLoopNodes->Node(NodeNum).OutAirDryBulb;
     608     8123742 :         if (state.dataLoopNodes->Node(NodeNum).IsLocalNode) {
     609       22884 :             if (InitCall) {
     610       22884 :                 if (state.dataLoopNodes->Node(NodeNum).OutAirWetBulb > state.dataLoopNodes->Node(NodeNum).OutAirDryBulb) {
     611           0 :                     state.dataLoopNodes->Node(NodeNum).OutAirWetBulb = state.dataLoopNodes->Node(NodeNum).OutAirDryBulb;
     612             :                 }
     613       30984 :                 if (state.dataLoopNodes->Node(NodeNum).OutAirWetBulbSchedNum == 0 && !state.dataLoopNodes->Node(NodeNum).EMSOverrideOutAirWetBulb &&
     614        8100 :                     (state.dataLoopNodes->Node(NodeNum).EMSOverrideOutAirDryBulb || state.dataLoopNodes->Node(NodeNum).OutAirDryBulbSchedNum != 0)) {
     615        4050 :                     state.dataLoopNodes->Node(NodeNum).HumRat = state.dataEnvrn->OutHumRat;
     616       12150 :                     state.dataLoopNodes->Node(NodeNum).OutAirWetBulb = PsyTwbFnTdbWPb(
     617       12150 :                         state, state.dataLoopNodes->Node(NodeNum).OutAirDryBulb, state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
     618             :                 } else {
     619       56502 :                     state.dataLoopNodes->Node(NodeNum).HumRat = PsyWFnTdbTwbPb(state,
     620       18834 :                                                                                state.dataLoopNodes->Node(NodeNum).OutAirDryBulb,
     621       18834 :                                                                                state.dataLoopNodes->Node(NodeNum).OutAirWetBulb,
     622       18834 :                                                                                state.dataEnvrn->OutBaroPress);
     623             :                 }
     624             :             } else {
     625           0 :                 state.dataLoopNodes->Node(NodeNum).HumRat = PsyWFnTdbTwbPb(state,
     626           0 :                                                                            state.dataLoopNodes->Node(NodeNum).OutAirDryBulb,
     627           0 :                                                                            state.dataLoopNodes->Node(NodeNum).OutAirWetBulb,
     628           0 :                                                                            state.dataEnvrn->OutBaroPress);
     629             :             }
     630             :         } else {
     631     8100858 :             state.dataLoopNodes->Node(NodeNum).HumRat = state.dataEnvrn->OutHumRat;
     632             :         }
     633     8123742 :         state.dataLoopNodes->Node(NodeNum).Enthalpy =
     634     8123742 :             PsyHFnTdbW(state.dataLoopNodes->Node(NodeNum).OutAirDryBulb, state.dataLoopNodes->Node(NodeNum).HumRat);
     635     8123742 :         state.dataLoopNodes->Node(NodeNum).Press = state.dataEnvrn->OutBaroPress;
     636     8123742 :         state.dataLoopNodes->Node(NodeNum).Quality = 0.0;
     637             :         // Add contaminants
     638     8123742 :         if (state.dataContaminantBalance->Contaminant.CO2Simulation)
     639       18578 :             state.dataLoopNodes->Node(NodeNum).CO2 = state.dataContaminantBalance->OutdoorCO2;
     640     8123742 :         if (state.dataContaminantBalance->Contaminant.GenericContamSimulation)
     641        7091 :             state.dataLoopNodes->Node(NodeNum).GenContam = state.dataContaminantBalance->OutdoorGC;
     642     8123742 :     }
     643             : 
     644             : } // namespace OutAirNodeManager
     645             : 
     646        2313 : } // namespace EnergyPlus

Generated by: LCOV version 1.13