LCOV - code coverage report
Current view: top level - EnergyPlus - MixerComponent.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 87.9 % 223 196
Test Date: 2025-06-02 07:23:51 Functions: 100.0 % 8 8

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

Generated by: LCOV version 2.0-1