LCOV - code coverage report
Current view: top level - EnergyPlus - OutAirNodeManager.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 83.4 % 217 181
Test Date: 2025-05-22 16:09:37 Functions: 100.0 % 6 6

            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              : // 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       248744 :     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       248744 :         if (state.dataOutAirNodeMgr->GetOutAirNodesInputFlag) { // First time subroutine has been entered
     111          137 :             GetOutAirNodesInput(state);                         // Get OutAir Nodes data
     112          137 :             state.dataOutAirNodeMgr->GetOutAirNodesInputFlag = false;
     113              :         }
     114       248744 :         InitOutAirNodes(state);
     115       248744 :     }
     116              : 
     117          251 :     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              : 
     135              :         // Locals
     136              :         // SUBROUTINE PARAMETER DEFINITIONS:
     137              :         static constexpr std::string_view RoutineName("GetOutAirNodesInput: "); // include trailing blank space
     138              :         static constexpr std::string_view routineName = "GetOutAirNodesInput";
     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          251 :         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          251 :         Array1D_int TmpNums;
     161          251 :         std::string CurrentModuleObject; // Object type for getting and error messages
     162          251 :         Array1D_string Alphas;           // Alpha input items for object
     163          251 :         Array1D_string cAlphaFields;     // Alpha field names
     164          251 :         Array1D_string cNumericFields;   // Numeric field names
     165          251 :         Array1D<Real64> Numbers;         // Numeric input items for object
     166          251 :         Array1D_bool lAlphaBlanks;       // Logical array, alpha field input BLANK = .TRUE.
     167          251 :         Array1D_bool lNumericBlanks;     // Logical array, numeric field input BLANK = .TRUE.
     168          251 :         int MaxNums(0);                  // Maximum number of numeric input fields
     169          251 :         int MaxAlphas(0);                // Maximum number of alpha input fields
     170          251 :         int TotalArgs(0);                // Total number of alpha and numeric arguments (max) for a
     171              : 
     172          251 :         NumOutAirInletNodeLists = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "OutdoorAir:NodeList");
     173          251 :         NumOutsideAirNodeSingles = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "OutdoorAir:Node");
     174          251 :         state.dataOutAirNodeMgr->NumOutsideAirNodes = 0;
     175          251 :         ErrorsFound = false;
     176          251 :         NextFluidStreamNum = 1;
     177              : 
     178          251 :         ListSize = 0;
     179          251 :         CurSize = 100;
     180          251 :         TmpNums.dimension(CurSize, 0);
     181              : 
     182          251 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "NodeList", NumParams, NumAlphas, NumNums);
     183          251 :         NodeNums.dimension(NumParams, 0);
     184              : 
     185          251 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "OutdoorAir:NodeList", TotalArgs, NumAlphas, NumNums);
     186          251 :         MaxNums = max(MaxNums, NumNums);
     187          251 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     188          251 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "OutdoorAir:Node", TotalArgs, NumAlphas, NumNums);
     189          251 :         MaxNums = max(MaxNums, NumNums);
     190          251 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     191              : 
     192          251 :         Alphas.allocate(MaxAlphas);
     193          251 :         cAlphaFields.allocate(MaxAlphas);
     194          251 :         cNumericFields.allocate(MaxNums);
     195          251 :         Numbers.dimension(MaxNums, 0.0);
     196          251 :         lAlphaBlanks.dimension(MaxAlphas, true);
     197          251 :         lNumericBlanks.dimension(MaxNums, true);
     198              : 
     199          251 :         if (NumOutAirInletNodeLists > 0) {
     200              :             // Loop over all outside air inlet nodes in the input and count them
     201           76 :             CurrentModuleObject = "OutdoorAir:NodeList";
     202          197 :             for (OutAirInletNodeListNum = 1; OutAirInletNodeListNum <= NumOutAirInletNodeLists; ++OutAirInletNodeListNum) {
     203          121 :                 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          254 :                 for (AlphaNum = 1; AlphaNum <= NumAlphas; ++AlphaNum) {
     217          133 :                     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          266 :                     GetNodeNums(state,
     222          133 :                                 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          133 :                                 cAlphaFields(AlphaNum));
     234          133 :                     NextFluidStreamNum += NumNodes;
     235          133 :                     if (ErrInList) {
     236            0 :                         ShowContinueError(state, format("Occurred in {}, {} = {}", CurrentModuleObject, cAlphaFields(AlphaNum), Alphas(AlphaNum)));
     237            0 :                         ErrorsFound = true;
     238              :                     }
     239          284 :                     for (NodeNum = 1; NodeNum <= NumNodes; ++NodeNum) {
     240              :                         // Duplicates here are not a problem, just ignore
     241          151 :                         if (!any_eq(TmpNums, NodeNums(NodeNum))) {
     242          151 :                             ++ListSize;
     243          151 :                             if (ListSize > CurSize) {
     244            0 :                                 TmpNums.redimension(CurSize += 100, 0);
     245              :                             }
     246          151 :                             TmpNums(ListSize) = NodeNums(NodeNum);
     247              :                         }
     248              :                     }
     249              :                 }
     250              :             }
     251              : 
     252           76 :             if (ErrorsFound) {
     253            0 :                 ShowFatalError(state, format("{}Errors found in getting {} input.", RoutineName, CurrentModuleObject));
     254              :             }
     255              :         }
     256              : 
     257          251 :         if (NumOutsideAirNodeSingles > 0) {
     258              :             // Loop over all single outside air nodes in the input
     259           79 :             CurrentModuleObject = "OutdoorAir:Node";
     260          187 :             for (OutsideAirNodeSingleNum = 1; OutsideAirNodeSingleNum <= NumOutsideAirNodeSingles; ++OutsideAirNodeSingleNum) {
     261          108 :                 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          108 :                 ErrorObjectHeader eoh{routineName, CurrentModuleObject, Alphas(1)};
     275              : 
     276          108 :                 ErrInList = false;
     277              :                 //  To support HVAC diagram, every outside inlet node must have a unique fluid stream number
     278              :                 //  GetNodeNums will increment the value across a node list, the starting value must be incremented
     279              :                 //  here across lists and across objects
     280          216 :                 GetNodeNums(state,
     281          108 :                             Alphas(1),
     282              :                             NumNodes,
     283              :                             NodeNums,
     284              :                             ErrInList,
     285              :                             DataLoopNode::NodeFluidType::Air,
     286              :                             DataLoopNode::ConnectionObjectType::OutdoorAirNode,
     287              :                             CurrentModuleObject,
     288              :                             DataLoopNode::ConnectionType::OutsideAir,
     289              :                             static_cast<NodeInputManager::CompFluidStream>(NextFluidStreamNum),
     290              :                             ObjectIsNotParent,
     291              :                             IncrementFluidStreamYes,
     292          108 :                             cAlphaFields(1));
     293          108 :                 NextFluidStreamNum += NumNodes;
     294          108 :                 if (ErrInList) {
     295            0 :                     ShowContinueError(state, format("Occurred in {}, {} = {}", CurrentModuleObject, cAlphaFields(1), Alphas(1)));
     296            0 :                     ErrorsFound = true;
     297              :                 }
     298              : 
     299          108 :                 if (NumNodes > 1) {
     300            0 :                     ShowSevereError(state, format("{}, {} = {}", CurrentModuleObject, cAlphaFields(1), Alphas(1)));
     301            0 :                     ShowContinueError(state, "...appears to point to a node list, not a single node.");
     302            0 :                     ErrorsFound = true;
     303            0 :                     continue;
     304              :                 }
     305              : 
     306          108 :                 if (!any_eq(TmpNums, NodeNums(1))) {
     307          108 :                     ++ListSize;
     308          108 :                     if (ListSize > CurSize) {
     309            0 :                         TmpNums.redimension(CurSize += 100, 0);
     310              :                     }
     311          108 :                     TmpNums(ListSize) = NodeNums(1);
     312              :                 } else { // Duplicates are a problem
     313            0 :                     ShowSevereError(state, format("{}, duplicate {} = {}", CurrentModuleObject, cAlphaFields(1), Alphas(1)));
     314            0 :                     ShowContinueError(state, format("Duplicate {} might be found in an OutdoorAir:NodeList.", cAlphaFields(1)));
     315            0 :                     ErrorsFound = true;
     316            0 :                     continue;
     317              :                 }
     318              : 
     319              :                 // Set additional node properties
     320          108 :                 if (NumNums > 0) state.dataLoopNodes->Node(NodeNums(1)).Height = Numbers(1);
     321              : 
     322          108 :                 if (NumAlphas > 1) {
     323            4 :                     state.dataGlobal->AnyLocalEnvironmentsInModel = true;
     324              :                 }
     325              : 
     326          108 :                 if (NumAlphas <= 1 || lAlphaBlanks(2)) {
     327            3 :                 } else if ((state.dataLoopNodes->Node(NodeNums(1)).outAirDryBulbSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
     328            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
     329            0 :                     ErrorsFound = true;
     330              :                 }
     331              : 
     332          108 :                 if (NumAlphas <= 2 || lAlphaBlanks(3)) {
     333            3 :                 } else if ((state.dataLoopNodes->Node(NodeNums(1)).outAirWetBulbSched = Sched::GetSchedule(state, Alphas(3))) == nullptr) {
     334            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFields(3), Alphas(3));
     335            0 :                     ErrorsFound = true;
     336              :                 }
     337              : 
     338          108 :                 if (NumAlphas <= 3 || lAlphaBlanks(4)) {
     339            3 :                 } else if ((state.dataLoopNodes->Node(NodeNums(1)).outAirWindSpeedSched = Sched::GetSchedule(state, Alphas(4))) == nullptr) {
     340            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFields(4), Alphas(4));
     341            0 :                     ErrorsFound = true;
     342              :                 }
     343              : 
     344          108 :                 if (NumAlphas <= 4 || lAlphaBlanks(5)) {
     345            3 :                 } else if ((state.dataLoopNodes->Node(NodeNums(1)).outAirWindDirSched = Sched::GetSchedule(state, Alphas(5))) == nullptr) {
     346            0 :                     ShowSevereItemNotFound(state, eoh, cAlphaFields(5), Alphas(5));
     347            0 :                     ErrorsFound = true;
     348              :                 }
     349              : 
     350          108 :                 if (NumAlphas > 8) {
     351            0 :                     ShowSevereError(state, format("{}, {} = {}", CurrentModuleObject, cAlphaFields(1), Alphas(1)));
     352            0 :                     ShowContinueError(state, "Object Definition indicates more than 7 Alpha Objects.");
     353            0 :                     ErrorsFound = true;
     354            0 :                     continue;
     355              :                 }
     356          213 :                 if (state.dataLoopNodes->Node(NodeNums(1)).outAirDryBulbSched != nullptr ||
     357          105 :                     state.dataLoopNodes->Node(NodeNums(1)).outAirWetBulbSched != nullptr) {
     358            3 :                     state.dataLoopNodes->Node(NodeNums(1)).IsLocalNode = true;
     359              :                 }
     360              :             }
     361           79 :             if (ErrorsFound) {
     362            0 :                 ShowFatalError(state, format("{}Errors found in getting {} input.", RoutineName, CurrentModuleObject));
     363              :             }
     364              :         }
     365              : 
     366          251 :         if (ListSize > 0) {
     367          130 :             state.dataOutAirNodeMgr->NumOutsideAirNodes = ListSize;
     368          130 :             state.dataOutAirNodeMgr->OutsideAirNodeList = TmpNums({1, static_cast<int>(ListSize)});
     369              :         }
     370          251 :     }
     371              : 
     372       248747 :     void InitOutAirNodes(EnergyPlusData &state)
     373              :     {
     374              :         // SUBROUTINE INFORMATION:
     375              :         //       AUTHOR         Fred Buhl
     376              :         //       DATE WRITTEN   Sept 1998
     377              :         //       MODIFIED       B. Griffith, added EMS override
     378              :         //       RE-ENGINEERED  na
     379              : 
     380              :         // PURPOSE OF THIS SUBROUTINE:
     381              :         // Initialize the outside air node data data.  In Particular,
     382              :         // set the outside air nodes to the outside conditions at the
     383              :         // start of every heat balance time step.
     384              : 
     385              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     386              :         int OutsideAirNodeNum;
     387              :         int NodeNum;
     388              : 
     389              :         // Do the begin time step initialization
     390       471895 :         for (OutsideAirNodeNum = 1; OutsideAirNodeNum <= state.dataOutAirNodeMgr->NumOutsideAirNodes; ++OutsideAirNodeNum) {
     391       223148 :             NodeNum = state.dataOutAirNodeMgr->OutsideAirNodeList(OutsideAirNodeNum);
     392       223148 :             SetOANodeValues(state, NodeNum, true);
     393              :         }
     394       248747 :     }
     395              : 
     396          230 :     bool CheckOutAirNodeNumber(EnergyPlusData &state, int const NodeNumber) // Number of node to check to see if in Outside Air list
     397              :     {
     398              : 
     399              :         // FUNCTION INFORMATION:
     400              :         //       AUTHOR         Linda Lawrie
     401              :         //       DATE WRITTEN   Feb 2007
     402              :         //       MODIFIED       na
     403              :         //       RE-ENGINEERED  na
     404              : 
     405              :         // PURPOSE OF THIS FUNCTION:
     406              :         // Provide an entry into the OutAirNode List for checking from other routines.
     407              : 
     408              :         // METHODOLOGY EMPLOYED:
     409              :         // na
     410              : 
     411              :         // REFERENCES:
     412              :         // na
     413              : 
     414              :         // USE STATEMENTS:
     415              :         // na
     416              : 
     417              :         // Return value
     418              :         bool Okay; // True if found, false if not
     419              : 
     420              :         // Locals
     421              :         // FUNCTION ARGUMENT DEFINITIONS:
     422              : 
     423              :         // FUNCTION PARAMETER DEFINITIONS:
     424              :         // na
     425              : 
     426              :         // INTERFACE BLOCK SPECIFICATIONS:
     427              :         // na
     428              : 
     429              :         // DERIVED TYPE DEFINITIONS:
     430              :         // na
     431              : 
     432              :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
     433              :         // na
     434              : 
     435          230 :         if (state.dataOutAirNodeMgr->GetOutAirNodesInputFlag) { // First time subroutine has been entered
     436           98 :             GetOutAirNodesInput(state);                         // Get Out Air Nodes data
     437           98 :             state.dataOutAirNodeMgr->GetOutAirNodesInputFlag = false;
     438           98 :             SetOutAirNodes(state);
     439              :         }
     440              : 
     441          230 :         if (any_eq(state.dataOutAirNodeMgr->OutsideAirNodeList, NodeNumber)) {
     442          117 :             Okay = true;
     443              :         } else {
     444          113 :             Okay = false;
     445              :         }
     446              : 
     447          230 :         return Okay;
     448              :     }
     449              : 
     450           21 :     void CheckAndAddAirNodeNumber(EnergyPlusData &state,
     451              :                                   int const NodeNumber, // Number of node to check to see if in Outside Air list
     452              :                                   bool &Okay            // True if found, false if not
     453              :     )
     454              :     {
     455              : 
     456              :         // SUBROUTINE INFORMATION:
     457              :         //       AUTHOR         Linda Lawrie
     458              :         //       DATE WRITTEN   March 2007
     459              :         //       MODIFIED       na
     460              :         //       RE-ENGINEERED  na
     461              : 
     462              :         // PURPOSE OF THIS SUBROUTINE:
     463              :         // At the time of writing, some items (namely Chillers) have "made up" node
     464              :         // names for nodes that are "outside air nodes".  Rather than fatal out, add
     465              :         // this subroutine which will check and then add a outside air node, if necessary.
     466              : 
     467              :         // METHODOLOGY EMPLOYED:
     468              :         // na
     469              : 
     470              :         // REFERENCES:
     471              :         // na
     472              : 
     473              :         // Using/Aliasing
     474              :         using namespace NodeInputManager;
     475              : 
     476              :         // Locals
     477              :         // SUBROUTINE ARGUMENT DEFINITIONS:
     478              : 
     479              :         // SUBROUTINE PARAMETER DEFINITIONS:
     480              :         // na
     481              : 
     482              :         // INTERFACE BLOCK SPECIFICATIONS:
     483              :         // na
     484              : 
     485              :         // DERIVED TYPE DEFINITIONS:
     486              :         // na
     487              : 
     488              :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     489           21 :         Array1D_int TmpNums;
     490              :         int DummyNumber;
     491              : 
     492           21 :         if (state.dataOutAirNodeMgr->GetOutAirNodesInputFlag) { // First time subroutine has been entered
     493           14 :             GetOutAirNodesInput(state);                         // Get Out Air Nodes data
     494           14 :             state.dataOutAirNodeMgr->GetOutAirNodesInputFlag = false;
     495           14 :             SetOutAirNodes(state);
     496              :         }
     497              : 
     498           21 :         Okay = false;
     499              : 
     500           21 :         if (state.dataOutAirNodeMgr->NumOutsideAirNodes > 0) {
     501           13 :             if (any_eq(state.dataOutAirNodeMgr->OutsideAirNodeList, NodeNumber)) {
     502           12 :                 Okay = true;
     503              :             } else {
     504            1 :                 Okay = false;
     505              :             }
     506              :         } else {
     507            8 :             Okay = false;
     508              :         }
     509              : 
     510           21 :         if (NodeNumber > 0) {
     511           21 :             if (!Okay) { // Add new outside air node to list
     512            9 :                 state.dataOutAirNodeMgr->OutsideAirNodeList.redimension(++state.dataOutAirNodeMgr->NumOutsideAirNodes);
     513            9 :                 state.dataOutAirNodeMgr->OutsideAirNodeList(state.dataOutAirNodeMgr->NumOutsideAirNodes) = NodeNumber;
     514            9 :                 TmpNums = state.dataOutAirNodeMgr->OutsideAirNodeList;
     515            9 :                 bool errFlag(false);
     516              :                 // register new node..
     517           27 :                 GetNodeNums(state,
     518            9 :                             state.dataLoopNodes->NodeID(NodeNumber),
     519              :                             DummyNumber,
     520              :                             TmpNums,
     521              :                             errFlag,
     522              :                             DataLoopNode::NodeFluidType::Air,
     523              :                             DataLoopNode::ConnectionObjectType::OutdoorAirNode,
     524              :                             "OutdoorAir:Node",
     525              :                             DataLoopNode::ConnectionType::OutsideAir,
     526            9 :                             static_cast<NodeInputManager::CompFluidStream>(state.dataOutAirNodeMgr->NumOutsideAirNodes),
     527              :                             ObjectIsNotParent,
     528              :                             IncrementFluidStreamYes);
     529            9 :                 SetOANodeValues(state, NodeNumber, false);
     530              :             }
     531              :         }
     532           21 :     }
     533              : 
     534       223157 :     void SetOANodeValues(EnergyPlusData &state,
     535              :                          int const NodeNum, // Number of node to check to see if in Outside Air list
     536              :                          bool InitCall      // True if Init calls, false if CheckAndAddAirNodeNumber calls
     537              :     )
     538              :     {
     539              :         // SUBROUTINE INFORMATION:
     540              :         //       AUTHOR         L. Gu
     541              :         //       DATE WRITTEN   July 2018
     542              : 
     543              :         // PURPOSE OF THIS SUBROUTINE:
     544              :         // Consolidate a block from both CheckAndAddAirNodeNumber and InitOutAirNodes to set
     545              :         // up outdoor node values
     546              : 
     547              :         using Psychrometrics::PsyHFnTdbW;
     548              :         using Psychrometrics::PsyTwbFnTdbWPb;
     549              :         using Psychrometrics::PsyWFnTdbTwbPb;
     550              : 
     551              :         // Set node data to global values
     552       223157 :         if (state.dataLoopNodes->Node(NodeNum).Height < 0.0) {
     553              :             // Note -- this setting is different than the DataEnvironment "AT" settings.
     554       223151 :             state.dataLoopNodes->Node(NodeNum).OutAirDryBulb = state.dataEnvrn->OutDryBulbTemp;
     555       223151 :             state.dataLoopNodes->Node(NodeNum).OutAirWetBulb = state.dataEnvrn->OutWetBulbTemp;
     556       223151 :             if (InitCall) state.dataLoopNodes->Node(NodeNum).OutAirWindSpeed = state.dataEnvrn->WindSpeed;
     557              :         } else {
     558            6 :             state.dataLoopNodes->Node(NodeNum).OutAirDryBulb = OutDryBulbTempAt(state, state.dataLoopNodes->Node(NodeNum).Height);
     559            6 :             state.dataLoopNodes->Node(NodeNum).OutAirWetBulb = OutWetBulbTempAt(state, state.dataLoopNodes->Node(NodeNum).Height);
     560            6 :             if (InitCall)
     561            6 :                 state.dataLoopNodes->Node(NodeNum).OutAirWindSpeed = DataEnvironment::WindSpeedAt(state, state.dataLoopNodes->Node(NodeNum).Height);
     562              :         }
     563       223157 :         if (!InitCall) state.dataLoopNodes->Node(NodeNum).OutAirWindSpeed = state.dataEnvrn->WindSpeed;
     564       223157 :         state.dataLoopNodes->Node(NodeNum).OutAirWindDir = state.dataEnvrn->WindDir;
     565              : 
     566       223157 :         if (InitCall) {
     567              :             // Set node data to local air node values if defined
     568       223148 :             if (state.dataLoopNodes->Node(NodeNum).outAirDryBulbSched != nullptr) {
     569            4 :                 state.dataLoopNodes->Node(NodeNum).OutAirDryBulb = state.dataLoopNodes->Node(NodeNum).outAirDryBulbSched->getCurrentVal();
     570              :             }
     571       223148 :             if (state.dataLoopNodes->Node(NodeNum).outAirWetBulbSched != nullptr) {
     572            3 :                 state.dataLoopNodes->Node(NodeNum).OutAirWetBulb = state.dataLoopNodes->Node(NodeNum).outAirWetBulbSched->getCurrentVal();
     573              :             }
     574       223148 :             if (state.dataLoopNodes->Node(NodeNum).outAirWindSpeedSched != nullptr) {
     575            3 :                 state.dataLoopNodes->Node(NodeNum).OutAirWindSpeed = state.dataLoopNodes->Node(NodeNum).outAirWindSpeedSched->getCurrentVal();
     576              :             }
     577       223148 :             if (state.dataLoopNodes->Node(NodeNum).outAirWindDirSched != nullptr) {
     578            3 :                 state.dataLoopNodes->Node(NodeNum).OutAirWindDir = state.dataLoopNodes->Node(NodeNum).outAirWindDirSched->getCurrentVal();
     579              :             }
     580              : 
     581              :             // Set node data to EMS overwritten values if defined
     582       223148 :             if (state.dataLoopNodes->Node(NodeNum).EMSOverrideOutAirDryBulb)
     583            1 :                 state.dataLoopNodes->Node(NodeNum).OutAirDryBulb = state.dataLoopNodes->Node(NodeNum).EMSValueForOutAirDryBulb;
     584       223148 :             if (state.dataLoopNodes->Node(NodeNum).EMSOverrideOutAirWetBulb)
     585            1 :                 state.dataLoopNodes->Node(NodeNum).OutAirWetBulb = state.dataLoopNodes->Node(NodeNum).EMSValueForOutAirWetBulb;
     586       223148 :             if (state.dataLoopNodes->Node(NodeNum).EMSOverrideOutAirWindSpeed)
     587            0 :                 state.dataLoopNodes->Node(NodeNum).OutAirWindSpeed = state.dataLoopNodes->Node(NodeNum).EMSValueForOutAirWindSpeed;
     588       223148 :             if (state.dataLoopNodes->Node(NodeNum).EMSOverrideOutAirWindDir)
     589            0 :                 state.dataLoopNodes->Node(NodeNum).OutAirWindDir = state.dataLoopNodes->Node(NodeNum).EMSValueForOutAirWindDir;
     590              :         }
     591              : 
     592       223157 :         state.dataLoopNodes->Node(NodeNum).Temp = state.dataLoopNodes->Node(NodeNum).OutAirDryBulb;
     593       223157 :         if (state.dataLoopNodes->Node(NodeNum).IsLocalNode) {
     594            6 :             if (InitCall) {
     595            6 :                 if (state.dataLoopNodes->Node(NodeNum).OutAirWetBulb > state.dataLoopNodes->Node(NodeNum).OutAirDryBulb) {
     596            0 :                     state.dataLoopNodes->Node(NodeNum).OutAirWetBulb = state.dataLoopNodes->Node(NodeNum).OutAirDryBulb;
     597              :                 }
     598            6 :                 if (state.dataLoopNodes->Node(NodeNum).outAirWetBulbSched == nullptr &&
     599            8 :                     !state.dataLoopNodes->Node(NodeNum).EMSOverrideOutAirWetBulb &&
     600            2 :                     (state.dataLoopNodes->Node(NodeNum).EMSOverrideOutAirDryBulb ||
     601            2 :                      state.dataLoopNodes->Node(NodeNum).outAirDryBulbSched != nullptr)) {
     602            1 :                     state.dataLoopNodes->Node(NodeNum).HumRat = state.dataEnvrn->OutHumRat;
     603            2 :                     state.dataLoopNodes->Node(NodeNum).OutAirWetBulb = PsyTwbFnTdbWPb(
     604            1 :                         state, state.dataLoopNodes->Node(NodeNum).OutAirDryBulb, state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
     605              :                 } else {
     606           10 :                     state.dataLoopNodes->Node(NodeNum).HumRat = PsyWFnTdbTwbPb(state,
     607            5 :                                                                                state.dataLoopNodes->Node(NodeNum).OutAirDryBulb,
     608            5 :                                                                                state.dataLoopNodes->Node(NodeNum).OutAirWetBulb,
     609            5 :                                                                                state.dataEnvrn->OutBaroPress);
     610              :                 }
     611              :             } else {
     612            0 :                 state.dataLoopNodes->Node(NodeNum).HumRat = PsyWFnTdbTwbPb(state,
     613            0 :                                                                            state.dataLoopNodes->Node(NodeNum).OutAirDryBulb,
     614            0 :                                                                            state.dataLoopNodes->Node(NodeNum).OutAirWetBulb,
     615            0 :                                                                            state.dataEnvrn->OutBaroPress);
     616              :             }
     617              :         } else {
     618       223151 :             state.dataLoopNodes->Node(NodeNum).HumRat = state.dataEnvrn->OutHumRat;
     619              :         }
     620       223157 :         state.dataLoopNodes->Node(NodeNum).Enthalpy =
     621       223157 :             PsyHFnTdbW(state.dataLoopNodes->Node(NodeNum).OutAirDryBulb, state.dataLoopNodes->Node(NodeNum).HumRat);
     622       223157 :         state.dataLoopNodes->Node(NodeNum).Press = state.dataEnvrn->OutBaroPress;
     623       223157 :         state.dataLoopNodes->Node(NodeNum).Quality = 0.0;
     624              :         // Add contaminants
     625       223157 :         if (state.dataContaminantBalance->Contaminant.CO2Simulation)
     626            3 :             state.dataLoopNodes->Node(NodeNum).CO2 = state.dataContaminantBalance->OutdoorCO2;
     627       223157 :         if (state.dataContaminantBalance->Contaminant.GenericContamSimulation)
     628            0 :             state.dataLoopNodes->Node(NodeNum).GenContam = state.dataContaminantBalance->OutdoorGC;
     629       223157 :     }
     630              : 
     631              : } // namespace OutAirNodeManager
     632              : 
     633              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1