LCOV - code coverage report
Current view: top level - EnergyPlus - MixerComponent.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 196 222 88.3 %
Date: 2023-01-17 19:17:23 Functions: 10 10 100.0 %

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

Generated by: LCOV version 1.13