LCOV - code coverage report
Current view: top level - EnergyPlus - MixerComponent.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 193 220 87.7 %
Date: 2024-08-24 18:31:18 Functions: 8 8 100.0 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // ObjexxFCL Headers
      49             : #include <ObjexxFCL/Fmath.hh>
      50             : 
      51             : // EnergyPlus Headers
      52             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      53             : #include <EnergyPlus/DataContaminantBalance.hh>
      54             : #include <EnergyPlus/DataEnvironment.hh>
      55             : #include <EnergyPlus/DataLoopNode.hh>
      56             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      57             : #include <EnergyPlus/MixerComponent.hh>
      58             : #include <EnergyPlus/NodeInputManager.hh>
      59             : #include <EnergyPlus/Psychrometrics.hh>
      60             : #include <EnergyPlus/UtilityRoutines.hh>
      61             : 
      62             : namespace EnergyPlus::MixerComponent {
      63             : 
      64             : // MODULE INFORMATION:
      65             : //       AUTHOR         Richard J. Liesen
      66             : //       DATE WRITTEN   March 2000
      67             : //       MODIFIED       na
      68             : //       RE-ENGINEERED  na
      69             : 
      70             : // PURPOSE OF THIS MODULE:
      71             : // To encapsulate the data and algorithms required to
      72             : // manage Air Path Mixer Components
      73             : 
      74             : // METHODOLOGY EMPLOYED:
      75             : // This Mixer is very simple.  It just takes the inlets and sums them
      76             : // and sets that to the outlet conditions.  For the State Properties
      77             : // it just takes the flow weighted averages of them.
      78             : 
      79             : // Using/Aliasing
      80             : using namespace DataLoopNode;
      81             : 
      82    10921234 : void SimAirMixer(EnergyPlusData &state, std::string_view CompName, int &CompIndex)
      83             : {
      84             : 
      85             :     // SUBROUTINE INFORMATION:
      86             :     //       AUTHOR         Richard Liesen
      87             :     //       DATE WRITTEN   February 1998
      88             :     //       MODIFIED       na
      89             :     //       RE-ENGINEERED  na
      90             : 
      91             :     // PURPOSE OF THIS SUBROUTINE:
      92             :     // This subroutine manages Mixer component simulation.
      93             :     // It is called from the SimAirLoopComponent
      94             :     // at the system time step.
      95             : 
      96             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
      97             :     int MixerNum; // The Mixer that you are currently loading input into
      98             : 
      99             :     // Obtains and Allocates Mixer related parameters from input file
     100    10921234 :     if (state.dataMixerComponent->SimAirMixerInputFlag) { // First time subroutine has been entered
     101         407 :         GetMixerInput(state);
     102         407 :         state.dataMixerComponent->SimAirMixerInputFlag = false;
     103             :     }
     104             : 
     105             :     // Find the correct MixerNumber
     106    10921234 :     if (CompIndex == 0) {
     107        1088 :         MixerNum = Util::FindItemInList(CompName, state.dataMixerComponent->MixerCond, &MixerConditions::MixerName);
     108        1088 :         if (MixerNum == 0) {
     109           0 :             ShowFatalError(state, format("SimAirLoopMixer: Mixer not found={}", CompName));
     110             :         }
     111        1088 :         CompIndex = MixerNum;
     112             :     } else {
     113    10920146 :         MixerNum = CompIndex;
     114    10920146 :         if (MixerNum > state.dataMixerComponent->NumMixers || MixerNum < 1) {
     115           0 :             ShowFatalError(state,
     116           0 :                            format("SimAirLoopMixer: Invalid CompIndex passed={}, Number of Mixers={}, Mixer name={}",
     117             :                                   MixerNum,
     118           0 :                                   state.dataMixerComponent->NumMixers,
     119             :                                   CompName));
     120             :         }
     121    10920146 :         if (state.dataMixerComponent->CheckEquipName(MixerNum)) {
     122        1093 :             if (CompName != state.dataMixerComponent->MixerCond(MixerNum).MixerName) {
     123           0 :                 ShowFatalError(state,
     124           0 :                                format("SimAirLoopMixer: Invalid CompIndex passed={}, Mixer name={}, stored Mixer Name for that index={}",
     125             :                                       MixerNum,
     126             :                                       CompName,
     127           0 :                                       state.dataMixerComponent->MixerCond(MixerNum).MixerName));
     128             :             }
     129        1093 :             state.dataMixerComponent->CheckEquipName(MixerNum) = false;
     130             :         }
     131             :     }
     132             : 
     133             :     // With the correct MixerNum Initialize
     134    10921234 :     InitAirMixer(state, MixerNum); // Initialize all Mixer related parameters
     135             : 
     136    10921234 :     CalcAirMixer(state, MixerNum);
     137             : 
     138             :     // Update the current Mixer to the outlet nodes
     139    10921234 :     UpdateAirMixer(state, MixerNum);
     140             : 
     141             :     // Report the current Mixer
     142    10921234 :     ReportMixer(MixerNum);
     143    10921234 : }
     144             : 
     145             : // Get Input Section of the Module
     146             : //******************************************************************************
     147             : 
     148         413 : void GetMixerInput(EnergyPlusData &state)
     149             : {
     150             : 
     151             :     // SUBROUTINE INFORMATION:
     152             :     //       AUTHOR         Richard J. Liesen
     153             :     //       DATE WRITTEN   March 2000
     154             :     //       MODIFIED       na
     155             :     //       RE-ENGINEERED  na
     156             : 
     157             :     // PURPOSE OF THIS SUBROUTINE:
     158             :     // This subroutine is the main routine to call other input routines and Get routines
     159             : 
     160             :     // METHODOLOGY EMPLOYED:
     161             :     // Uses the status flags to trigger events.
     162             : 
     163             :     // Using/Aliasing
     164             :     using NodeInputManager::GetOnlySingleNode;
     165             : 
     166             :     // SUBROUTINE PARAMETER DEFINITIONS:
     167             :     static constexpr std::string_view RoutineName("GetMixerInput: "); // include trailing blank space
     168             : 
     169             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     170             :     int MixerNum; // The Mixer that you are currently loading input into
     171             :     int NumAlphas;
     172             :     int NumNums;
     173             :     int NodeNum;
     174             :     int IOStat;
     175         413 :     bool ErrorsFound(false);
     176             :     int NumParams;
     177             :     int InNodeNum1;
     178             :     int InNodeNum2;
     179         413 :     std::string CurrentModuleObject; // for ease in getting objects
     180         413 :     Array1D_string AlphArray;        // Alpha input items for object
     181         413 :     Array1D_string cAlphaFields;     // Alpha field names
     182         413 :     Array1D_string cNumericFields;   // Numeric field names
     183         413 :     Array1D<Real64> NumArray;        // Numeric input items for object
     184         413 :     Array1D_bool lAlphaBlanks;       // Logical array, alpha field input BLANK = .TRUE.
     185         413 :     Array1D_bool lNumericBlanks;     // Logical array, numeric field input BLANK = .TRUE.
     186             : 
     187         413 :     CurrentModuleObject = "AirLoopHVAC:ZoneMixer";
     188         413 :     state.dataMixerComponent->NumMixers = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     189             : 
     190         413 :     if (state.dataMixerComponent->NumMixers > 0) state.dataMixerComponent->MixerCond.allocate(state.dataMixerComponent->NumMixers);
     191         413 :     state.dataMixerComponent->CheckEquipName.dimension(state.dataMixerComponent->NumMixers, true);
     192             : 
     193         413 :     state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumParams, NumAlphas, NumNums);
     194         413 :     AlphArray.allocate(NumAlphas);
     195         413 :     cAlphaFields.allocate(NumAlphas);
     196         413 :     lAlphaBlanks.dimension(NumAlphas, true);
     197         413 :     cNumericFields.allocate(NumNums);
     198         413 :     lNumericBlanks.dimension(NumNums, true);
     199         413 :     NumArray.dimension(NumNums, 0.0);
     200             : 
     201        1517 :     for (MixerNum = 1; MixerNum <= state.dataMixerComponent->NumMixers; ++MixerNum) {
     202        1104 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     203             :                                                                  CurrentModuleObject,
     204             :                                                                  MixerNum,
     205             :                                                                  AlphArray,
     206             :                                                                  NumAlphas,
     207             :                                                                  NumArray,
     208             :                                                                  NumNums,
     209             :                                                                  IOStat,
     210             :                                                                  lNumericBlanks,
     211             :                                                                  lAlphaBlanks,
     212             :                                                                  cAlphaFields,
     213             :                                                                  cNumericFields);
     214        1104 :         Util::IsNameEmpty(state, AlphArray(1), CurrentModuleObject, ErrorsFound);
     215             : 
     216        1104 :         state.dataMixerComponent->MixerCond(MixerNum).MixerName = AlphArray(1);
     217             : 
     218        2208 :         state.dataMixerComponent->MixerCond(MixerNum).OutletNode = GetOnlySingleNode(state,
     219        1104 :                                                                                      AlphArray(2),
     220             :                                                                                      ErrorsFound,
     221             :                                                                                      DataLoopNode::ConnectionObjectType::AirLoopHVACZoneMixer,
     222        1104 :                                                                                      AlphArray(1),
     223             :                                                                                      DataLoopNode::NodeFluidType::Air,
     224             :                                                                                      DataLoopNode::ConnectionType::Outlet,
     225             :                                                                                      NodeInputManager::CompFluidStream::Primary,
     226             :                                                                                      ObjectIsNotParent);
     227        1104 :         state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes = NumAlphas - 2;
     228             : 
     229       13112 :         for (auto &e : state.dataMixerComponent->MixerCond)
     230       13112 :             e.InitFlag = true;
     231             : 
     232        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletNode.allocate(state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes);
     233        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRate.allocate(state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes);
     234        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRateMaxAvail.allocate(state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes);
     235        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRateMinAvail.allocate(state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes);
     236        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletTemp.allocate(state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes);
     237        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletHumRat.allocate(state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes);
     238        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletEnthalpy.allocate(state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes);
     239        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletPressure.allocate(state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes);
     240             : 
     241        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletNode = 0;
     242        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRate = 0.0;
     243        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRateMaxAvail = 0.0;
     244        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRateMinAvail = 0.0;
     245        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletTemp = 0.0;
     246        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletHumRat = 0.0;
     247        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletEnthalpy = 0.0;
     248        1104 :         state.dataMixerComponent->MixerCond(MixerNum).InletPressure = 0.0;
     249        1104 :         state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRate = 0.0;
     250        1104 :         state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRateMaxAvail = 0.0;
     251        1104 :         state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRateMinAvail = 0.0;
     252        1104 :         state.dataMixerComponent->MixerCond(MixerNum).OutletTemp = 0.0;
     253        1104 :         state.dataMixerComponent->MixerCond(MixerNum).OutletHumRat = 0.0;
     254        1104 :         state.dataMixerComponent->MixerCond(MixerNum).OutletEnthalpy = 0.0;
     255        1104 :         state.dataMixerComponent->MixerCond(MixerNum).OutletPressure = 0.0;
     256             : 
     257        3696 :         for (NodeNum = 1; NodeNum <= state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes; ++NodeNum) {
     258             : 
     259        2592 :             state.dataMixerComponent->MixerCond(MixerNum).InletNode(NodeNum) =
     260        5184 :                 GetOnlySingleNode(state,
     261        2592 :                                   AlphArray(2 + NodeNum),
     262             :                                   ErrorsFound,
     263             :                                   DataLoopNode::ConnectionObjectType::AirLoopHVACZoneMixer,
     264        2592 :                                   AlphArray(1),
     265             :                                   DataLoopNode::NodeFluidType::Air,
     266             :                                   DataLoopNode::ConnectionType::Inlet,
     267             :                                   NodeInputManager::CompFluidStream::Primary,
     268             :                                   ObjectIsNotParent);
     269        2592 :             if (lAlphaBlanks(2 + NodeNum)) {
     270           0 :                 ShowSevereError(state, format("{} is Blank, {} = {}", cAlphaFields(2 + NodeNum), CurrentModuleObject, AlphArray(1)));
     271           0 :                 ErrorsFound = true;
     272             :             }
     273             :         }
     274             : 
     275             :     } // end Number of Mixer Loop
     276             : 
     277             :     // Check for duplicate names specified in Zone Mixer
     278        1517 :     for (MixerNum = 1; MixerNum <= state.dataMixerComponent->NumMixers; ++MixerNum) {
     279        1104 :         NodeNum = state.dataMixerComponent->MixerCond(MixerNum).OutletNode;
     280        3696 :         for (InNodeNum1 = 1; InNodeNum1 <= state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes; ++InNodeNum1) {
     281        2592 :             if (NodeNum != state.dataMixerComponent->MixerCond(MixerNum).InletNode(InNodeNum1)) continue;
     282           0 :             ShowSevereError(state,
     283           0 :                             format("{} = {} specifies an inlet node name the same as the outlet node.",
     284             :                                    CurrentModuleObject,
     285           0 :                                    state.dataMixerComponent->MixerCond(MixerNum).MixerName));
     286           0 :             ShowContinueError(state, format("..{} = {}", cAlphaFields(2), state.dataLoopNodes->NodeID(NodeNum)));
     287           0 :             ShowContinueError(state, format("..Inlet Node #{} is duplicate.", InNodeNum1));
     288           0 :             ErrorsFound = true;
     289             :         }
     290        3696 :         for (InNodeNum1 = 1; InNodeNum1 <= state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes; ++InNodeNum1) {
     291       16205 :             for (InNodeNum2 = InNodeNum1 + 1; InNodeNum2 <= state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes; ++InNodeNum2) {
     292       13613 :                 if (state.dataMixerComponent->MixerCond(MixerNum).InletNode(InNodeNum1) !=
     293       13613 :                     state.dataMixerComponent->MixerCond(MixerNum).InletNode(InNodeNum2))
     294       13613 :                     continue;
     295           0 :                 ShowSevereError(state,
     296           0 :                                 format("{} = {} specifies duplicate inlet nodes in its inlet node list.",
     297             :                                        CurrentModuleObject,
     298           0 :                                        state.dataMixerComponent->MixerCond(MixerNum).MixerName));
     299           0 :                 ShowContinueError(state, format("..Inlet Node #{} Name={}", InNodeNum1, state.dataLoopNodes->NodeID(InNodeNum1)));
     300           0 :                 ShowContinueError(state, format("..Inlet Node #{} is duplicate.", InNodeNum2));
     301           0 :                 ErrorsFound = true;
     302             :             }
     303             :         }
     304             :     }
     305             : 
     306         413 :     AlphArray.deallocate();
     307         413 :     NumArray.deallocate();
     308         413 :     cAlphaFields.deallocate();
     309         413 :     lAlphaBlanks.deallocate();
     310         413 :     cNumericFields.deallocate();
     311         413 :     lNumericBlanks.deallocate();
     312             : 
     313         413 :     if (ErrorsFound) {
     314           0 :         ShowFatalError(state, format("{}Errors found in getting input.", RoutineName));
     315             :     }
     316         413 : }
     317             : 
     318             : // End of Get Input subroutines for the HB Module
     319             : //******************************************************************************
     320             : 
     321             : // Beginning Initialization Section of the Module
     322             : //******************************************************************************
     323             : 
     324    10921236 : void InitAirMixer(EnergyPlusData &state, int const MixerNum)
     325             : {
     326             : 
     327             :     // SUBROUTINE INFORMATION:
     328             :     //       AUTHOR         Richard J. Liesen
     329             :     //       DATE WRITTEN   March 2000
     330             :     //       MODIFIED       na
     331             :     //       RE-ENGINEERED  na
     332             : 
     333             :     // PURPOSE OF THIS SUBROUTINE:
     334             :     // This subroutine is for  initializations of the Mixer Components.
     335             : 
     336             :     // METHODOLOGY EMPLOYED:
     337             :     // Uses the status flags to trigger events.
     338             : 
     339             :     // REFERENCES:
     340             :     // na
     341             : 
     342             :     // USE STATEMENTS:
     343             :     // na
     344             : 
     345             :     // Locals
     346             :     // SUBROUTINE ARGUMENT DEFINITIONS:
     347             : 
     348             :     // SUBROUTINE PARAMETER DEFINITIONS:
     349             :     // na
     350             : 
     351             :     // INTERFACE BLOCK SPECIFICATIONS
     352             :     // na
     353             : 
     354             :     // DERIVED TYPE DEFINITIONS
     355             :     // na
     356             : 
     357             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     358             :     int InletNode;
     359             :     int NodeNum;
     360             : 
     361             :     // Do the following initializations (every time step): This should be the info from
     362             :     // the previous components outlets or the node data in this section.
     363             : 
     364             :     // Transfer the node data to MixerCond data structure
     365    36157845 :     for (NodeNum = 1; NodeNum <= state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes; ++NodeNum) {
     366             : 
     367    25236609 :         InletNode = state.dataMixerComponent->MixerCond(MixerNum).InletNode(NodeNum);
     368             :         // Set all of the inlet mass flow variables from the nodes
     369    25236609 :         state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRate(NodeNum) = state.dataLoopNodes->Node(InletNode).MassFlowRate;
     370    25236609 :         state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRateMaxAvail(NodeNum) = state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail;
     371    25236609 :         state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRateMinAvail(NodeNum) = state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail;
     372             :         // Set all of the inlet state variables from the inlet nodes
     373    25236609 :         state.dataMixerComponent->MixerCond(MixerNum).InletTemp(NodeNum) = state.dataLoopNodes->Node(InletNode).Temp;
     374    25236609 :         state.dataMixerComponent->MixerCond(MixerNum).InletHumRat(NodeNum) = state.dataLoopNodes->Node(InletNode).HumRat;
     375    25236609 :         state.dataMixerComponent->MixerCond(MixerNum).InletEnthalpy(NodeNum) = state.dataLoopNodes->Node(InletNode).Enthalpy;
     376    25236609 :         state.dataMixerComponent->MixerCond(MixerNum).InletPressure(NodeNum) = state.dataLoopNodes->Node(InletNode).Press;
     377             :     }
     378    10921236 : }
     379             : 
     380             : // End Initialization Section of the Module
     381             : //******************************************************************************
     382             : 
     383             : // Begin Algorithm Section of the Module
     384             : //******************************************************************************
     385             : 
     386    10921234 : void CalcAirMixer(EnergyPlusData &state, int &MixerNum)
     387             : {
     388             : 
     389             :     // SUBROUTINE INFORMATION:
     390             :     //       AUTHOR         Richard J. Liesen
     391             :     //       DATE WRITTEN   March 2000
     392             :     //       MODIFIED       na
     393             :     //       RE-ENGINEERED  na
     394             : 
     395             :     // PURPOSE OF THIS SUBROUTINE:
     396             :     // This subroutine needs a description.
     397             : 
     398             :     // METHODOLOGY EMPLOYED:
     399             :     // Needs description, as appropriate.
     400             : 
     401             :     // REFERENCES:
     402             :     // na
     403             : 
     404             :     // Using/Aliasing
     405             :     using Psychrometrics::PsyTdbFnHW;
     406             : 
     407             :     // Locals
     408             :     // SUBROUTINE ARGUMENT DEFINITIONS:
     409             : 
     410             :     // SUBROUTINE PARAMETER DEFINITIONS:
     411             :     // na
     412             : 
     413             :     // INTERFACE BLOCK SPECIFICATIONS
     414             :     // na
     415             : 
     416             :     // DERIVED TYPE DEFINITIONS
     417             :     // na
     418             : 
     419             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     420             :     int InletNodeNum;
     421             : 
     422             :     // Reset the totals to zero before they are summed.
     423    10921234 :     state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRate = 0.0;
     424    10921234 :     state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRateMaxAvail = 0.0;
     425    10921234 :     state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRateMinAvail = 0.0;
     426    10921234 :     state.dataMixerComponent->MixerCond(MixerNum).OutletTemp = 0.0;
     427    10921234 :     state.dataMixerComponent->MixerCond(MixerNum).OutletHumRat = 0.0;
     428    10921234 :     state.dataMixerComponent->MixerCond(MixerNum).OutletPressure = 0.0;
     429    10921234 :     state.dataMixerComponent->MixerCond(MixerNum).OutletEnthalpy = 0.0;
     430             : 
     431    36157838 :     for (InletNodeNum = 1; InletNodeNum <= state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes; ++InletNodeNum) {
     432    25236604 :         state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRate +=
     433    25236604 :             state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRate(InletNodeNum);
     434    25236604 :         state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRateMaxAvail +=
     435    25236604 :             state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRateMaxAvail(InletNodeNum);
     436    25236604 :         state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRateMinAvail +=
     437    25236604 :             state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRateMinAvail(InletNodeNum);
     438             :     }
     439             : 
     440    10921234 :     if (state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRate > 0.0) {
     441             : 
     442             :         // Mass balance on moisture to get outlet air humidity ratio
     443             : 
     444    29839956 :         for (InletNodeNum = 1; InletNodeNum <= state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes; ++InletNodeNum) {
     445    21162103 :             state.dataMixerComponent->MixerCond(MixerNum).OutletHumRat +=
     446    21162103 :                 state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRate(InletNodeNum) *
     447    21162103 :                 state.dataMixerComponent->MixerCond(MixerNum).InletHumRat(InletNodeNum) /
     448    21162103 :                 state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRate;
     449             :         }
     450             : 
     451             :         // "Momentum balance" to get outlet air pressure
     452             : 
     453    29839956 :         for (InletNodeNum = 1; InletNodeNum <= state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes; ++InletNodeNum) {
     454    21162103 :             state.dataMixerComponent->MixerCond(MixerNum).OutletPressure +=
     455    21162103 :                 state.dataMixerComponent->MixerCond(MixerNum).InletPressure(InletNodeNum) *
     456    21162103 :                 state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRate(InletNodeNum) /
     457    21162103 :                 state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRate;
     458             :         }
     459             : 
     460             :         // Energy balance to get outlet air enthalpy
     461             : 
     462    29839956 :         for (InletNodeNum = 1; InletNodeNum <= state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes; ++InletNodeNum) {
     463    21162103 :             state.dataMixerComponent->MixerCond(MixerNum).OutletEnthalpy +=
     464    21162103 :                 state.dataMixerComponent->MixerCond(MixerNum).InletEnthalpy(InletNodeNum) *
     465    21162103 :                 state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRate(InletNodeNum) /
     466    21162103 :                 state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRate;
     467             :         }
     468             : 
     469             :         // Use Enthalpy and humidity ratio to get outlet temperature from psych chart
     470             : 
     471     8677853 :         state.dataMixerComponent->MixerCond(MixerNum).OutletTemp =
     472     8677853 :             PsyTdbFnHW(state.dataMixerComponent->MixerCond(MixerNum).OutletEnthalpy, state.dataMixerComponent->MixerCond(MixerNum).OutletHumRat);
     473             : 
     474             :     } else {
     475             :         // Mass Flow in air loop is zero and loop is not operating.
     476             :         // Arbitrarily set the output to the first inlet leg
     477     2243381 :         state.dataMixerComponent->MixerCond(MixerNum).OutletHumRat = state.dataMixerComponent->MixerCond(MixerNum).InletHumRat(1);
     478     2243381 :         state.dataMixerComponent->MixerCond(MixerNum).OutletPressure = state.dataMixerComponent->MixerCond(MixerNum).InletPressure(1);
     479     2243381 :         state.dataMixerComponent->MixerCond(MixerNum).OutletEnthalpy = state.dataMixerComponent->MixerCond(MixerNum).InletEnthalpy(1);
     480     2243381 :         state.dataMixerComponent->MixerCond(MixerNum).OutletTemp = state.dataMixerComponent->MixerCond(MixerNum).InletTemp(1);
     481             :     }
     482             : 
     483             :     // make sure MassFlowRateMaxAvail is >= MassFlowRate
     484    10921234 :     state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRateMaxAvail = max(
     485    10921234 :         state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRateMaxAvail, state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRate);
     486    10921234 : }
     487             : 
     488             : // End Algorithm Section of the Module
     489             : // *****************************************************************************
     490             : 
     491             : // Beginning of Update subroutines for the Mixer Module
     492             : // *****************************************************************************
     493             : 
     494    10921234 : void UpdateAirMixer(EnergyPlusData &state, int const MixerNum)
     495             : {
     496             : 
     497             :     // SUBROUTINE INFORMATION:
     498             :     //       AUTHOR         Richard J. Liesen
     499             :     //       DATE WRITTEN   March 2000
     500             :     //       MODIFIED       na
     501             :     //       RE-ENGINEERED  na
     502             : 
     503             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     504             :     int OutletNode;
     505             :     int InletNode;
     506             :     int InletNodeNum;
     507             : 
     508    10921234 :     OutletNode = state.dataMixerComponent->MixerCond(MixerNum).OutletNode;
     509    10921234 :     InletNode = state.dataMixerComponent->MixerCond(MixerNum).InletNode(1); // For now use first inlet node
     510             : 
     511             :     // Set the outlet air nodes of the Mixer
     512    10921234 :     state.dataLoopNodes->Node(OutletNode).MassFlowRate = state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRate;
     513    10921234 :     state.dataLoopNodes->Node(OutletNode).MassFlowRateMaxAvail = state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRateMaxAvail;
     514    10921234 :     state.dataLoopNodes->Node(OutletNode).MassFlowRateMinAvail = state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRateMinAvail;
     515    10921234 :     state.dataLoopNodes->Node(OutletNode).Temp = state.dataMixerComponent->MixerCond(MixerNum).OutletTemp;
     516    10921234 :     state.dataLoopNodes->Node(OutletNode).HumRat = state.dataMixerComponent->MixerCond(MixerNum).OutletHumRat;
     517    10921234 :     state.dataLoopNodes->Node(OutletNode).Enthalpy = state.dataMixerComponent->MixerCond(MixerNum).OutletEnthalpy;
     518    10921234 :     state.dataLoopNodes->Node(OutletNode).Press = state.dataMixerComponent->MixerCond(MixerNum).OutletPressure;
     519             :     // Set the outlet nodes for properties that just pass through & not used
     520    10921234 :     state.dataLoopNodes->Node(OutletNode).Quality = state.dataLoopNodes->Node(InletNode).Quality;
     521             : 
     522    10921234 :     if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
     523       38385 :         if (state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRate > 0.0) {
     524             :             // CO2 balance to get outlet air CO2
     525       32834 :             state.dataLoopNodes->Node(OutletNode).CO2 = 0.0;
     526      142182 :             for (InletNodeNum = 1; InletNodeNum <= state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes; ++InletNodeNum) {
     527      109348 :                 state.dataLoopNodes->Node(OutletNode).CO2 +=
     528      109348 :                     state.dataLoopNodes->Node(state.dataMixerComponent->MixerCond(MixerNum).InletNode(InletNodeNum)).CO2 *
     529      109348 :                     state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRate(InletNodeNum) /
     530      109348 :                     state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRate;
     531             :             }
     532             :         } else {
     533        5551 :             state.dataLoopNodes->Node(OutletNode).CO2 = state.dataLoopNodes->Node(InletNode).CO2;
     534             :         }
     535             :     }
     536             : 
     537    10921234 :     if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
     538        9571 :         if (state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRate > 0.0) {
     539             :             // Generic contaminant balance to get outlet air CO2
     540        7609 :             state.dataLoopNodes->Node(OutletNode).GenContam = 0.0;
     541       30436 :             for (InletNodeNum = 1; InletNodeNum <= state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes; ++InletNodeNum) {
     542       22827 :                 state.dataLoopNodes->Node(OutletNode).GenContam +=
     543       22827 :                     state.dataLoopNodes->Node(state.dataMixerComponent->MixerCond(MixerNum).InletNode(InletNodeNum)).GenContam *
     544       22827 :                     state.dataMixerComponent->MixerCond(MixerNum).InletMassFlowRate(InletNodeNum) /
     545       22827 :                     state.dataMixerComponent->MixerCond(MixerNum).OutletMassFlowRate;
     546             :             }
     547             :         } else {
     548        1962 :             state.dataLoopNodes->Node(OutletNode).GenContam = state.dataLoopNodes->Node(InletNode).GenContam;
     549             :         }
     550             :     }
     551    10921234 : }
     552             : 
     553             : //        End of Update subroutines for the Mixer Module
     554             : // *****************************************************************************
     555             : 
     556             : // Beginning of Reporting subroutines for the Mixer Module
     557             : // *****************************************************************************
     558             : 
     559    10921234 : void ReportMixer([[maybe_unused]] int const MixerNum)
     560             : {
     561             : 
     562             :     // SUBROUTINE INFORMATION:
     563             :     //       AUTHOR         Richard J. Liesen
     564             :     //       DATE WRITTEN   March 2000
     565             :     //       MODIFIED       na
     566             :     //       RE-ENGINEERED  na
     567             : 
     568             :     // PURPOSE OF THIS SUBROUTINE:
     569             :     // This subroutine needs a description.
     570             : 
     571             :     // METHODOLOGY EMPLOYED:
     572             :     // Needs description, as appropriate.
     573             : 
     574             :     // REFERENCES:
     575             :     // na
     576             : 
     577             :     // USE STATEMENTS:
     578             :     // na
     579             : 
     580             :     // Locals
     581             :     // SUBROUTINE ARGUMENT DEFINITIONS:
     582             : 
     583             :     // SUBROUTINE PARAMETER DEFINITIONS:
     584             :     // na
     585             : 
     586             :     // INTERFACE BLOCK SPECIFICATIONS
     587             :     // na
     588             : 
     589             :     // DERIVED TYPE DEFINITIONS
     590             :     // na
     591             : 
     592             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     593             :     // na
     594             : 
     595             :     // Write(*,*)=MixerCond(MixerNum)%MixerPower    Still needs to report the Mixer power from this component
     596    10921234 : }
     597             : 
     598             : //        End of Reporting subroutines for the Mixer Module
     599             : 
     600             : // Beginning of Utility subroutines for the Mixer Component
     601             : // *****************************************************************************
     602             : 
     603           6 : void GetZoneMixerIndex(EnergyPlusData &state, std::string const &MixerName, int &MixerIndex, bool &ErrorsFound, std::string const &ThisObjectType)
     604             : {
     605             : 
     606             :     // SUBROUTINE INFORMATION:
     607             :     //       AUTHOR         Fred Buhl
     608             :     //       DATE WRITTEN   March 2015
     609             :     //       MODIFIED       na
     610             :     //       RE-ENGINEERED  na
     611             : 
     612             :     // PURPOSE OF THIS SUBROUTINE:
     613             :     // This subroutine sets an index for a given zone mixer -- issues error message if that mixer
     614             :     // is not legal mixer.
     615             : 
     616           6 :     if (state.dataMixerComponent->GetZoneMixerIndexInputFlag) { // First time subroutine has been entered
     617           2 :         GetMixerInput(state);
     618           2 :         state.dataMixerComponent->GetZoneMixerIndexInputFlag = false;
     619             :     }
     620             : 
     621           6 :     MixerIndex = Util::FindItemInList(MixerName, state.dataMixerComponent->MixerCond, &MixerConditions::MixerName);
     622           6 :     if (MixerIndex == 0) {
     623           0 :         if (!ThisObjectType.empty()) {
     624           0 :             ShowSevereError(state, format("{}, GetZoneMixerIndex: Zone Mixer not found={}", ThisObjectType, MixerName));
     625             :         } else {
     626           0 :             ShowSevereError(state, format("GetZoneMixerIndex: Zone Mixer not found={}", MixerName));
     627             :         }
     628           0 :         ErrorsFound = true;
     629             :     }
     630           6 : }
     631             : 
     632           4 : int getZoneMixerIndexFromInletNode(EnergyPlusData &state, int const InNodeNum)
     633             : {
     634             : 
     635           4 :     if (state.dataMixerComponent->GetZoneMixerIndexInputFlag) { // First time subroutine has been entered
     636           4 :         GetMixerInput(state);
     637           4 :         state.dataMixerComponent->GetZoneMixerIndexInputFlag = false;
     638             :     }
     639             : 
     640           4 :     if (state.dataMixerComponent->NumMixers > 0) {
     641           8 :         for (int MixerNum = 1; MixerNum <= state.dataMixerComponent->NumMixers; ++MixerNum) {
     642          16 :             for (int InNodeCtr = 1; InNodeCtr <= state.dataMixerComponent->MixerCond(MixerNum).NumInletNodes; ++InNodeCtr) {
     643          12 :                 if (InNodeNum == state.dataMixerComponent->MixerCond(MixerNum).InletNode(InNodeCtr)) {
     644           0 :                     return MixerNum;
     645             :                 }
     646             :             }
     647             :         }
     648             :     }
     649             : 
     650           4 :     return 0;
     651             : }
     652             : 
     653             : // End of Utility subroutines for the Mixer Component
     654             : // *****************************************************************************
     655             : 
     656             : } // namespace EnergyPlus::MixerComponent

Generated by: LCOV version 1.14