LCOV - code coverage report
Current view: top level - EnergyPlus - TranspiredCollector.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 562 763 73.7 %
Date: 2023-01-17 19:17:23 Functions: 10 13 76.9 %

          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             : // C++ Headers
      49             : #include <cassert>
      50             : #include <cmath>
      51             : 
      52             : // ObjexxFCL Headers
      53             : #include <ObjexxFCL/Array.functions.hh>
      54             : #include <ObjexxFCL/Fmath.hh>
      55             : #include <ObjexxFCL/member.functions.hh>
      56             : 
      57             : // EnergyPlus Headers
      58             : #include <EnergyPlus/BranchNodeConnections.hh>
      59             : #include <EnergyPlus/Construction.hh>
      60             : #include <EnergyPlus/ConvectionCoefficients.hh>
      61             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      62             : #include <EnergyPlus/DataEnvironment.hh>
      63             : #include <EnergyPlus/DataHVACGlobals.hh>
      64             : #include <EnergyPlus/DataHeatBalSurface.hh>
      65             : #include <EnergyPlus/DataHeatBalance.hh>
      66             : #include <EnergyPlus/DataIPShortCuts.hh>
      67             : #include <EnergyPlus/DataLoopNode.hh>
      68             : #include <EnergyPlus/DataSurfaces.hh>
      69             : #include <EnergyPlus/EMSManager.hh>
      70             : #include <EnergyPlus/General.hh>
      71             : #include <EnergyPlus/GeneralRoutines.hh>
      72             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      73             : #include <EnergyPlus/Material.hh>
      74             : #include <EnergyPlus/NodeInputManager.hh>
      75             : #include <EnergyPlus/OutputProcessor.hh>
      76             : #include <EnergyPlus/Psychrometrics.hh>
      77             : #include <EnergyPlus/ScheduleManager.hh>
      78             : #include <EnergyPlus/TranspiredCollector.hh>
      79             : #include <EnergyPlus/UtilityRoutines.hh>
      80             : 
      81             : namespace EnergyPlus {
      82             : 
      83             : namespace TranspiredCollector {
      84             : 
      85             :     // Module containing routines and data dealing with the Transpired Collectors
      86             : 
      87             :     // MODULE INFORMATION:
      88             :     //       AUTHOR         B.T. Griffith
      89             :     //       DATE WRITTEN   November 2004
      90             :     //       MODIFIED       na
      91             :     //       RE-ENGINEERED  na
      92             : 
      93             :     // PURPOSE OF THIS MODULE:
      94             :     // Ecapsulates data and routines for simulating unglazed transpired solar collectors (UTSC)
      95             :     //   as a component on the HVAC air system.
      96             : 
      97             :     // METHODOLOGY EMPLOYED:
      98             :     // Two modes, passive and active.  Active is when air is purposely drawn through collector.
      99             :     // Passive is when air exchanges are driven by Natural Ventilation rather than outside air system
     100             : 
     101             :     // REFERENCES:
     102             :     // Heat Exchange effectiveness relations:
     103             :     // Kutscher, C.F. 1994. Heat exchange effectiveness and pressure drop for air flow through perforated plates
     104             :     //     with and without crosswind. Journal of Heat Transfer. May 1994, Vol. 116, p. 391.
     105             :     //     American Society of Mechanical Engineers.
     106             :     // Van Decker, G.W.E., K.G.T. Hollands, and A.P. Brunger. 2001. Heat-exchange relations for unglazed transpired
     107             :     //     solar collectors with circular holes on a square of triangular pitch. Solar Energy. Vol. 71, No. 1. pp 33-45, 2001.
     108             :     // .
     109             : 
     110             :     // OTHER NOTES:
     111             :     // EnergyPlus implementation is unique and adds new modeling not described in Literature.
     112             :     //   See EngineeringReference for details
     113             : 
     114             :     // Using/Aliasing
     115             :     using DataVectorTypes::Vector;
     116             : 
     117             :     int constexpr Layout_Square = 1;
     118             :     int constexpr Layout_Triangle = 2;
     119             :     int constexpr Correlation_Kutscher1994 = 1;
     120             :     int constexpr Correlation_VanDeckerHollandsBrunger2001 = 2;
     121             : 
     122       40675 :     void SimTranspiredCollector(EnergyPlusData &state,
     123             :                                 std::string_view CompName, // component name
     124             :                                 int &CompIndex             // component index (to reduce string compares during simulation)
     125             :     )
     126             :     {
     127             : 
     128             :         // SUBROUTINE INFORMATION:
     129             :         //       AUTHOR         B.T. Griffith
     130             :         //       DATE WRITTEN   November 2004
     131             :         //       MODIFIED       na
     132             :         //       RE-ENGINEERED  na
     133             : 
     134             :         // PURPOSE OF THIS SUBROUTINE:
     135             :         // Manage simulation of Transpired Collectors
     136             : 
     137             :         // METHODOLOGY EMPLOYED:
     138             :         // Setup to avoid string comparisons after first call
     139             : 
     140             :         // Using/Aliasing
     141             :         using DataHVACGlobals::TempControlTol;
     142             : 
     143             :         using ScheduleManager::GetCurrentScheduleValue;
     144             : 
     145             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     146             : 
     147       40675 :         int UTSCNum(0); // local number index for UTSC
     148             : 
     149       40675 :         if (state.dataTranspiredCollector->GetInputFlag) {
     150           0 :             GetTranspiredCollectorInput(state);
     151           0 :             state.dataTranspiredCollector->GetInputFlag = false;
     152             :         }
     153             : 
     154             :         // Find the correct transpired collector with the Component name and/or index
     155       40675 :         if (CompIndex == 0) {
     156           9 :             UTSCNum = UtilityRoutines::FindItemInList(CompName, state.dataTranspiredCollector->UTSC);
     157           9 :             if (UTSCNum == 0) {
     158           0 :                 ShowFatalError(state, "Transpired Collector not found=" + std::string{CompName});
     159             :             }
     160           9 :             CompIndex = UTSCNum;
     161             :         } else {
     162       40666 :             UTSCNum = CompIndex;
     163       40666 :             if (UTSCNum > state.dataTranspiredCollector->NumUTSC || UTSCNum < 1) {
     164           0 :                 ShowFatalError(state,
     165           0 :                                format("SimTranspiredCollector: Invalid CompIndex passed={}, Number of Transpired Collectors={}, UTSC name={}",
     166             :                                       UTSCNum,
     167           0 :                                       state.dataTranspiredCollector->NumUTSC,
     168           0 :                                       CompName));
     169             :             }
     170       40666 :             if (state.dataTranspiredCollector->CheckEquipName(UTSCNum)) {
     171           5 :                 if (CompName != state.dataTranspiredCollector->UTSC(UTSCNum).Name) {
     172           0 :                     ShowFatalError(state,
     173           0 :                                    format("SimTranspiredCollector: Invalid CompIndex passed={}, Transpired Collector name={}, stored Transpired "
     174             :                                           "Collector Name for that index={}",
     175             :                                           UTSCNum,
     176             :                                           CompName,
     177           0 :                                           state.dataTranspiredCollector->UTSC(UTSCNum).Name));
     178             :                 }
     179           5 :                 state.dataTranspiredCollector->CheckEquipName(UTSCNum) = false;
     180             :             }
     181             :         }
     182             : 
     183       40675 :         InitTranspiredCollector(state, CompIndex);
     184             : 
     185             :         // Control point of deciding if transpired collector is active or not.
     186       40675 :         auto &UTSC_CI(state.dataTranspiredCollector->UTSC(CompIndex));
     187       40675 :         auto &InletNode(UTSC_CI.InletNode);
     188       40675 :         auto &ControlNode(UTSC_CI.ControlNode);
     189       40675 :         UTSC_CI.IsOn = false;
     190       55447 :         if ((GetCurrentScheduleValue(state, UTSC_CI.SchedPtr) > 0.0) &&
     191       14772 :             (UTSC_CI.InletMDot > 0.0)) { // availability Schedule | OA system is setting mass flow
     192        9700 :             bool ControlLTSet(false);
     193        9700 :             bool ControlLTSchedule(false);
     194        9700 :             bool ZoneLTSchedule(false);
     195        9700 :             assert(equal_dimensions(InletNode, ControlNode));
     196        9700 :             assert(equal_dimensions(InletNode, UTSC_CI.ZoneNode));
     197       31992 :             for (int i = InletNode.l(), e = InletNode.u(); i <= e; ++i) {
     198       22292 :                 if (state.dataLoopNodes->Node(InletNode(i)).Temp + TempControlTol < state.dataLoopNodes->Node(ControlNode(i)).TempSetPoint)
     199       22292 :                     ControlLTSet = true;
     200       22292 :                 if (state.dataLoopNodes->Node(InletNode(i)).Temp + TempControlTol < GetCurrentScheduleValue(state, UTSC_CI.FreeHeatSetPointSchedPtr))
     201       22292 :                     ControlLTSchedule = true;
     202       44584 :                 if (state.dataLoopNodes->Node(UTSC_CI.ZoneNode(i)).Temp + TempControlTol <
     203       22292 :                     GetCurrentScheduleValue(state, UTSC_CI.FreeHeatSetPointSchedPtr))
     204        6510 :                     ZoneLTSchedule = true;
     205             :             }
     206        9700 :             if (ControlLTSet || (ControlLTSchedule && ZoneLTSchedule))
     207        9700 :                 UTSC_CI.IsOn = true; // heating required | free heating helpful | free heating helpful
     208             :         }
     209             : 
     210       40675 :         if (state.dataTranspiredCollector->UTSC(UTSCNum).IsOn) {
     211        9700 :             CalcActiveTranspiredCollector(state, UTSCNum);
     212             :         } else {
     213       30975 :             CalcPassiveTranspiredCollector(state, UTSCNum);
     214             :         }
     215             : 
     216       40675 :         UpdateTranspiredCollector(state, UTSCNum);
     217       40675 :     }
     218             : 
     219           1 :     void GetTranspiredCollectorInput(EnergyPlusData &state)
     220             :     {
     221             : 
     222             :         // SUBROUTINE INFORMATION:
     223             :         //       AUTHOR         B.T. Griffith
     224             :         //       DATE WRITTEN   November 2004
     225             :         //       MODIFIED       na
     226             :         //       RE-ENGINEERED  na
     227             : 
     228             :         // PURPOSE OF THIS SUBROUTINE:
     229             :         //  Retrieve user input and set up data structure
     230             : 
     231             :         // METHODOLOGY EMPLOYED:
     232             :         // usual EnergyPlus input
     233             :         // Extensible UTSC object for underlying heat transfer surfaces and for multisystem
     234             : 
     235             :         // Using/Aliasing
     236             :         using BranchNodeConnections::TestCompSet;
     237             :         using DataLoopNode::ObjectIsNotParent;
     238             :         using DataSurfaces::OtherSideCondModeledExt;
     239             :         using DataSurfaces::SurfaceData;
     240             :         using NodeInputManager::GetOnlySingleNode;
     241             :         using ScheduleManager::GetScheduleIndex;
     242             : 
     243             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     244             : 
     245           2 :         Array1D_string Alphas; // Alpha items for extensible
     246             :         // Solar Collectors:Unglazed Transpired object
     247             :         int Item;                    // Item to be "gotten"
     248           2 :         Array1D<Real64> Numbers(11); // Numeric items for object
     249             :         int NumAlphas;               // Number of Alphas for each GetObjectItem call
     250             :         int NumNumbers;              // Number of Numbers for each GetObjectItem call
     251             :         int MaxNumAlphas;            // argumenet for call to GetObjectDefMaxArgs
     252             :         int MaxNumNumbers;           // argumenet for call to GetObjectDefMaxArgs
     253             :         int Dummy;                   // argumenet for call to GetObjectDefMaxArgs
     254             :         int IOStatus;                // Used in GetObjectItem
     255           1 :         bool ErrorsFound(false);     // Set to true if errors in input, fatal at end of routine
     256             :         int Found;
     257             :         int AlphaOffset; // local temp var
     258           2 :         std::string Roughness;
     259             :         int ThisSurf;         // do loop counter
     260             :         Real64 AvgAzimuth;    // temp for error checking
     261             :         Real64 AvgTilt;       // temp for error checking
     262             :         int SurfID;           // local surface "pointer"
     263             :         Real64 TiltRads;      // average tilt of collector in radians
     264             :         Real64 tempHdeltaNPL; // temporary variable for buoyancy length scale
     265           1 :         int NumUTSCSplitter(0);
     266           2 :         Array1D_string AlphasSplit; // Alpha items for extensible
     267             :         // Solar Collectors:Unglazed Transpired object
     268             :         int ItemSplit;                        // Item to be "gotten"
     269           2 :         Array1D<Real64> NumbersSplit(1);      // Numeric items for object
     270             :         int NumAlphasSplit;                   // Number of Alphas for each GetObjectItem call
     271             :         int NumNumbersSplit;                  // Number of Numbers for each GetObjectItem call
     272             :         int MaxNumAlphasSplit;                // argumenet for call to GetObjectDefMaxArgs
     273             :         int MaxNumNumbersSplit;               // argumenet for call to GetObjectDefMaxArgs
     274             :         int IOStatusSplit;                    // Used in GetObjectItem
     275             :         int NumOASys;                         // do loop counter
     276             :         int ACountBase;                       // counter for alhpasSplit
     277           2 :         Array1D_bool SplitterNameOK;          // check for correct association of
     278           2 :         std::string CurrentModuleObject;      // for ease in renaming.
     279           2 :         std::string CurrentModuleMultiObject; // for ease in renaming.
     280             : 
     281           1 :         CurrentModuleObject = "SolarCollector:UnglazedTranspired";
     282           1 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, Dummy, MaxNumAlphas, MaxNumNumbers);
     283             : 
     284           1 :         if (MaxNumNumbers != 11) {
     285           0 :             ShowSevereError(state,
     286           0 :                             format("GetTranspiredCollectorInput: {} Object Definition indicates not = 11 Number Objects, Number Indicated={}",
     287             :                                    CurrentModuleObject,
     288           0 :                                    MaxNumNumbers));
     289           0 :             ErrorsFound = true;
     290             :         }
     291           1 :         Alphas.allocate(MaxNumAlphas);
     292           1 :         Numbers = 0.0;
     293           1 :         Alphas = "";
     294             : 
     295           1 :         state.dataTranspiredCollector->NumUTSC = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     296           1 :         CurrentModuleMultiObject = "SolarCollector:UnglazedTranspired:Multisystem";
     297           1 :         NumUTSCSplitter = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleMultiObject);
     298             : 
     299           1 :         state.dataTranspiredCollector->UTSC.allocate(state.dataTranspiredCollector->NumUTSC);
     300           1 :         state.dataTranspiredCollector->CheckEquipName.dimension(state.dataTranspiredCollector->NumUTSC, true);
     301           1 :         SplitterNameOK.dimension(NumUTSCSplitter, false);
     302             : 
     303           6 :         for (Item = 1; Item <= state.dataTranspiredCollector->NumUTSC; ++Item) {
     304          25 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     305             :                                                                      CurrentModuleObject,
     306             :                                                                      Item,
     307             :                                                                      Alphas,
     308             :                                                                      NumAlphas,
     309             :                                                                      Numbers,
     310             :                                                                      NumNumbers,
     311             :                                                                      IOStatus,
     312           5 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
     313           5 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
     314           5 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
     315           5 :                                                                      state.dataIPShortCut->cNumericFieldNames);
     316             : 
     317             :             // first handle alphas
     318           5 :             state.dataTranspiredCollector->UTSC(Item).Name = Alphas(1);
     319             : 
     320             :             // now check for multisystem
     321           5 :             if (NumUTSCSplitter > 0) {
     322           5 :                 state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
     323             :                     state, CurrentModuleMultiObject, Dummy, MaxNumAlphasSplit, MaxNumNumbersSplit);
     324             : 
     325           5 :                 if (MaxNumNumbersSplit != 0) {
     326           0 :                     ShowSevereError(state,
     327           0 :                                     format("GetTranspiredCollectorInput: {} Object Definition indicates not = 0 Number Objects, Number Indicated={}",
     328             :                                            CurrentModuleMultiObject,
     329           0 :                                            MaxNumNumbersSplit));
     330           0 :                     ErrorsFound = true;
     331             :                 }
     332           5 :                 if (!allocated(AlphasSplit)) AlphasSplit.allocate(MaxNumAlphasSplit);
     333           5 :                 NumbersSplit = 0.0;
     334           5 :                 AlphasSplit = "";
     335          10 :                 for (ItemSplit = 1; ItemSplit <= NumUTSCSplitter; ++ItemSplit) {
     336           5 :                     state.dataInputProcessing->inputProcessor->getObjectItem(
     337             :                         state, CurrentModuleMultiObject, ItemSplit, AlphasSplit, NumAlphasSplit, NumbersSplit, NumNumbersSplit, IOStatusSplit);
     338           5 :                     if (!(UtilityRoutines::SameString(AlphasSplit(1), Alphas(1)))) continue;
     339           1 :                     SplitterNameOK(ItemSplit) = true;
     340           1 :                     state.dataTranspiredCollector->UTSC(Item).NumOASysAttached = std::floor(NumAlphasSplit / 4.0);
     341           1 :                     if (mod((NumAlphasSplit), 4) != 1) {
     342           0 :                         ShowSevereError(state,
     343           0 :                                         "GetTranspiredCollectorInput: " + CurrentModuleMultiObject +
     344           0 :                                             " Object Definition indicates not uniform quadtuples of nodes for " + AlphasSplit(1));
     345           0 :                         ErrorsFound = true;
     346             :                     }
     347           1 :                     state.dataTranspiredCollector->UTSC(Item).InletNode.allocate(state.dataTranspiredCollector->UTSC(Item).NumOASysAttached);
     348           1 :                     state.dataTranspiredCollector->UTSC(Item).InletNode = 0;
     349           1 :                     state.dataTranspiredCollector->UTSC(Item).OutletNode.allocate(state.dataTranspiredCollector->UTSC(Item).NumOASysAttached);
     350           1 :                     state.dataTranspiredCollector->UTSC(Item).OutletNode = 0;
     351           1 :                     state.dataTranspiredCollector->UTSC(Item).ControlNode.allocate(state.dataTranspiredCollector->UTSC(Item).NumOASysAttached);
     352           1 :                     state.dataTranspiredCollector->UTSC(Item).ControlNode = 0;
     353           1 :                     state.dataTranspiredCollector->UTSC(Item).ZoneNode.allocate(state.dataTranspiredCollector->UTSC(Item).NumOASysAttached);
     354           1 :                     state.dataTranspiredCollector->UTSC(Item).ZoneNode = 0;
     355           6 :                     for (NumOASys = 1; NumOASys <= state.dataTranspiredCollector->UTSC(Item).NumOASysAttached; ++NumOASys) {
     356           5 :                         ACountBase = (NumOASys - 1) * 4 + 2;
     357           5 :                         state.dataTranspiredCollector->UTSC(Item).InletNode(NumOASys) =
     358          10 :                             GetOnlySingleNode(state,
     359           5 :                                               AlphasSplit(ACountBase),
     360             :                                               ErrorsFound,
     361             :                                               DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
     362           5 :                                               AlphasSplit(1),
     363             :                                               DataLoopNode::NodeFluidType::Air,
     364             :                                               DataLoopNode::ConnectionType::Inlet,
     365             :                                               static_cast<NodeInputManager::CompFluidStream>(NumOASys),
     366           5 :                                               ObjectIsNotParent);
     367             : 
     368           5 :                         state.dataTranspiredCollector->UTSC(Item).OutletNode(NumOASys) =
     369          10 :                             GetOnlySingleNode(state,
     370           5 :                                               AlphasSplit(ACountBase + 1),
     371             :                                               ErrorsFound,
     372             :                                               DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
     373           5 :                                               AlphasSplit(1),
     374             :                                               DataLoopNode::NodeFluidType::Air,
     375             :                                               DataLoopNode::ConnectionType::Outlet,
     376             :                                               static_cast<NodeInputManager::CompFluidStream>(NumOASys),
     377           5 :                                               ObjectIsNotParent);
     378          10 :                         TestCompSet(state,
     379             :                                     CurrentModuleObject,
     380           5 :                                     AlphasSplit(1),
     381           5 :                                     AlphasSplit(ACountBase),
     382           5 :                                     AlphasSplit(ACountBase + 1),
     383             :                                     "Transpired Collector Air Nodes"); // appears that test fails by design??
     384           5 :                         state.dataTranspiredCollector->UTSC(Item).ControlNode(NumOASys) =
     385          10 :                             GetOnlySingleNode(state,
     386           5 :                                               AlphasSplit(ACountBase + 2),
     387             :                                               ErrorsFound,
     388             :                                               DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
     389           5 :                                               AlphasSplit(1),
     390             :                                               DataLoopNode::NodeFluidType::Air,
     391             :                                               DataLoopNode::ConnectionType::Sensor,
     392             :                                               NodeInputManager::CompFluidStream::Primary,
     393           5 :                                               ObjectIsNotParent);
     394             : 
     395           5 :                         state.dataTranspiredCollector->UTSC(Item).ZoneNode(NumOASys) =
     396          10 :                             GetOnlySingleNode(state,
     397           5 :                                               AlphasSplit(ACountBase + 3),
     398             :                                               ErrorsFound,
     399             :                                               DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
     400           5 :                                               AlphasSplit(1),
     401             :                                               DataLoopNode::NodeFluidType::Air,
     402             :                                               DataLoopNode::ConnectionType::Sensor,
     403             :                                               NodeInputManager::CompFluidStream::Primary,
     404           5 :                                               ObjectIsNotParent);
     405             : 
     406             :                     } // Each OA System in a Multisystem
     407             :                       // DEALLOCATE(AlphasSplit)
     408             :                 }     // each Multisystem present
     409             :             }         // any UTSC Multisystem present
     410             : 
     411           5 :             state.dataTranspiredCollector->UTSC(Item).OSCMName = Alphas(2);
     412           5 :             Found = UtilityRoutines::FindItemInList(state.dataTranspiredCollector->UTSC(Item).OSCMName, state.dataSurface->OSCM);
     413           5 :             if (Found == 0) {
     414           0 :                 ShowSevereError(state,
     415           0 :                                 state.dataIPShortCut->cAlphaFieldNames(2) + " not found=" + state.dataTranspiredCollector->UTSC(Item).OSCMName +
     416           0 :                                     " in " + CurrentModuleObject + " =" + state.dataTranspiredCollector->UTSC(Item).Name);
     417           0 :                 ErrorsFound = true;
     418             :             }
     419           5 :             state.dataTranspiredCollector->UTSC(Item).OSCMPtr = Found;
     420           5 :             if (state.dataIPShortCut->lAlphaFieldBlanks(3)) {
     421           0 :                 state.dataTranspiredCollector->UTSC(Item).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
     422             :             } else {
     423           5 :                 state.dataTranspiredCollector->UTSC(Item).SchedPtr = GetScheduleIndex(state, Alphas(3));
     424           5 :                 if (state.dataTranspiredCollector->UTSC(Item).SchedPtr == 0) {
     425           0 :                     ShowSevereError(state,
     426           0 :                                     state.dataIPShortCut->cAlphaFieldNames(3) + "not found=" + Alphas(3) + " in " + CurrentModuleObject + " =" +
     427           0 :                                         state.dataTranspiredCollector->UTSC(Item).Name);
     428           0 :                     ErrorsFound = true;
     429           0 :                     continue;
     430             :                 }
     431             :             }
     432             : 
     433             :             // now if UTSC(Item)%NumOASysAttached still not set, assume no multisystem
     434           5 :             if (state.dataTranspiredCollector->UTSC(Item).NumOASysAttached == 0) {
     435           4 :                 state.dataTranspiredCollector->UTSC(Item).NumOASysAttached = 1;
     436           4 :                 state.dataTranspiredCollector->UTSC(Item).InletNode.allocate(1);
     437           4 :                 state.dataTranspiredCollector->UTSC(Item).InletNode(1) = 0;
     438           4 :                 state.dataTranspiredCollector->UTSC(Item).OutletNode.allocate(1);
     439           4 :                 state.dataTranspiredCollector->UTSC(Item).OutletNode(1) = 0;
     440           4 :                 state.dataTranspiredCollector->UTSC(Item).ControlNode.allocate(1);
     441           4 :                 state.dataTranspiredCollector->UTSC(Item).ControlNode(1) = 0;
     442           4 :                 state.dataTranspiredCollector->UTSC(Item).ZoneNode.allocate(1);
     443           4 :                 state.dataTranspiredCollector->UTSC(Item).ZoneNode(1) = 0;
     444             : 
     445           4 :                 state.dataTranspiredCollector->UTSC(Item).InletNode(1) =
     446           8 :                     GetOnlySingleNode(state,
     447           4 :                                       Alphas(4),
     448             :                                       ErrorsFound,
     449             :                                       DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
     450           4 :                                       Alphas(1),
     451             :                                       DataLoopNode::NodeFluidType::Air,
     452             :                                       DataLoopNode::ConnectionType::Inlet,
     453             :                                       NodeInputManager::CompFluidStream::Primary,
     454           4 :                                       ObjectIsNotParent);
     455           4 :                 state.dataTranspiredCollector->UTSC(Item).OutletNode(1) =
     456           8 :                     GetOnlySingleNode(state,
     457           4 :                                       Alphas(5),
     458             :                                       ErrorsFound,
     459             :                                       DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
     460           4 :                                       Alphas(1),
     461             :                                       DataLoopNode::NodeFluidType::Air,
     462             :                                       DataLoopNode::ConnectionType::Outlet,
     463             :                                       NodeInputManager::CompFluidStream::Primary,
     464           4 :                                       ObjectIsNotParent);
     465           4 :                 TestCompSet(state, CurrentModuleObject, Alphas(1), Alphas(4), Alphas(5), "Transpired Collector Air Nodes");
     466             : 
     467           4 :                 state.dataTranspiredCollector->UTSC(Item).ControlNode(1) =
     468           8 :                     GetOnlySingleNode(state,
     469           4 :                                       Alphas(6),
     470             :                                       ErrorsFound,
     471             :                                       DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
     472           4 :                                       Alphas(1),
     473             :                                       DataLoopNode::NodeFluidType::Air,
     474             :                                       DataLoopNode::ConnectionType::Sensor,
     475             :                                       NodeInputManager::CompFluidStream::Primary,
     476           4 :                                       ObjectIsNotParent);
     477           4 :                 state.dataTranspiredCollector->UTSC(Item).ZoneNode(1) =
     478           8 :                     GetOnlySingleNode(state,
     479           4 :                                       Alphas(7),
     480             :                                       ErrorsFound,
     481             :                                       DataLoopNode::ConnectionObjectType::SolarCollectorUnglazedTranspired,
     482           4 :                                       Alphas(1),
     483             :                                       DataLoopNode::NodeFluidType::Air,
     484             :                                       DataLoopNode::ConnectionType::Sensor,
     485             :                                       NodeInputManager::CompFluidStream::Primary,
     486           4 :                                       ObjectIsNotParent);
     487             :             } // no splitter
     488             : 
     489           5 :             state.dataTranspiredCollector->UTSC(Item).FreeHeatSetPointSchedPtr = GetScheduleIndex(state, Alphas(8));
     490           5 :             if (state.dataTranspiredCollector->UTSC(Item).FreeHeatSetPointSchedPtr == 0) {
     491           0 :                 ShowSevereError(state,
     492           0 :                                 state.dataIPShortCut->cAlphaFieldNames(8) + " not found=" + Alphas(8) + " in " + CurrentModuleObject + " =" +
     493           0 :                                     state.dataTranspiredCollector->UTSC(Item).Name);
     494           0 :                 ErrorsFound = true;
     495           0 :                 continue;
     496             :             }
     497             : 
     498           5 :             if (UtilityRoutines::SameString(Alphas(9), "Triangle")) {
     499           5 :                 state.dataTranspiredCollector->UTSC(Item).Layout = Layout_Triangle;
     500           0 :             } else if (UtilityRoutines::SameString(Alphas(9), "Square")) {
     501           0 :                 state.dataTranspiredCollector->UTSC(Item).Layout = Layout_Square;
     502             :             } else {
     503           0 :                 ShowSevereError(state,
     504           0 :                                 state.dataIPShortCut->cAlphaFieldNames(9) + " has incorrect entry of " + Alphas(9) + " in " + CurrentModuleObject +
     505           0 :                                     " =" + state.dataTranspiredCollector->UTSC(Item).Name);
     506           0 :                 ErrorsFound = true;
     507           0 :                 continue;
     508             :             }
     509             : 
     510           5 :             if (UtilityRoutines::SameString(Alphas(10), "Kutscher1994")) {
     511           3 :                 state.dataTranspiredCollector->UTSC(Item).Correlation = Correlation_Kutscher1994;
     512           2 :             } else if (UtilityRoutines::SameString(Alphas(10), "VanDeckerHollandsBrunger2001")) {
     513           2 :                 state.dataTranspiredCollector->UTSC(Item).Correlation = Correlation_VanDeckerHollandsBrunger2001;
     514             :             } else {
     515           0 :                 ShowSevereError(state,
     516           0 :                                 state.dataIPShortCut->cAlphaFieldNames(10) + " has incorrect entry of " + Alphas(9) + " in " + CurrentModuleObject +
     517           0 :                                     " =" + state.dataTranspiredCollector->UTSC(Item).Name);
     518           0 :                 ErrorsFound = true;
     519           0 :                 continue;
     520             :             }
     521             : 
     522           5 :             Roughness = Alphas(11);
     523             :             // Select the correct Number for the associated ascii name for the roughness type
     524           5 :             if (UtilityRoutines::SameString(Roughness, "VeryRough"))
     525           0 :                 state.dataTranspiredCollector->UTSC(Item).CollRoughness = DataSurfaces::SurfaceRoughness::VeryRough;
     526           5 :             if (UtilityRoutines::SameString(Roughness, "Rough"))
     527           0 :                 state.dataTranspiredCollector->UTSC(Item).CollRoughness = DataSurfaces::SurfaceRoughness::Rough;
     528           5 :             if (UtilityRoutines::SameString(Roughness, "MediumRough"))
     529           5 :                 state.dataTranspiredCollector->UTSC(Item).CollRoughness = DataSurfaces::SurfaceRoughness::MediumRough;
     530           5 :             if (UtilityRoutines::SameString(Roughness, "MediumSmooth"))
     531           0 :                 state.dataTranspiredCollector->UTSC(Item).CollRoughness = DataSurfaces::SurfaceRoughness::MediumSmooth;
     532           5 :             if (UtilityRoutines::SameString(Roughness, "Smooth"))
     533           0 :                 state.dataTranspiredCollector->UTSC(Item).CollRoughness = DataSurfaces::SurfaceRoughness::Smooth;
     534           5 :             if (UtilityRoutines::SameString(Roughness, "VerySmooth"))
     535           0 :                 state.dataTranspiredCollector->UTSC(Item).CollRoughness = DataSurfaces::SurfaceRoughness::VerySmooth;
     536             : 
     537             :             // Was it set?
     538           5 :             if (state.dataTranspiredCollector->UTSC(Item).CollRoughness == DataSurfaces::SurfaceRoughness::Invalid) {
     539           0 :                 ShowSevereError(state,
     540           0 :                                 state.dataIPShortCut->cAlphaFieldNames(11) + " has incorrect entry of " + Alphas(11) + " in " + CurrentModuleObject +
     541           0 :                                     " =" + state.dataTranspiredCollector->UTSC(Item).Name);
     542           0 :                 ErrorsFound = true;
     543             :             }
     544             : 
     545           5 :             AlphaOffset = 11;
     546           5 :             state.dataTranspiredCollector->UTSC(Item).NumSurfs = NumAlphas - AlphaOffset;
     547           5 :             if (state.dataTranspiredCollector->UTSC(Item).NumSurfs == 0) {
     548           0 :                 ShowSevereError(state,
     549           0 :                                 "No underlying surfaces specified in " + CurrentModuleObject + " =" + state.dataTranspiredCollector->UTSC(Item).Name);
     550           0 :                 ErrorsFound = true;
     551           0 :                 continue;
     552             :             }
     553           5 :             state.dataTranspiredCollector->UTSC(Item).SurfPtrs.allocate(state.dataTranspiredCollector->UTSC(Item).NumSurfs);
     554           5 :             state.dataTranspiredCollector->UTSC(Item).SurfPtrs = 0;
     555          11 :             for (ThisSurf = 1; ThisSurf <= state.dataTranspiredCollector->UTSC(Item).NumSurfs; ++ThisSurf) {
     556           6 :                 Found = UtilityRoutines::FindItemInList(Alphas(ThisSurf + AlphaOffset), state.dataSurface->Surface);
     557           6 :                 if (Found == 0) {
     558           0 :                     ShowSevereError(state,
     559           0 :                                     "Surface Name not found=" + Alphas(ThisSurf + AlphaOffset) + " in " + CurrentModuleObject + " =" +
     560           0 :                                         state.dataTranspiredCollector->UTSC(Item).Name);
     561           0 :                     ErrorsFound = true;
     562           0 :                     continue;
     563             :                 }
     564             :                 // check that surface is appropriate, Heat transfer, Sun, Wind,
     565           6 :                 if (!state.dataSurface->Surface(Found).HeatTransSurf) {
     566           0 :                     ShowSevereError(state,
     567           0 :                                     "Surface " + Alphas(ThisSurf + AlphaOffset) + " not of Heat Transfer type in " + CurrentModuleObject + " =" +
     568           0 :                                         state.dataTranspiredCollector->UTSC(Item).Name);
     569           0 :                     ErrorsFound = true;
     570           0 :                     continue;
     571             :                 }
     572           6 :                 if (!state.dataSurface->Surface(Found).ExtSolar) {
     573           0 :                     ShowSevereError(state,
     574           0 :                                     "Surface " + Alphas(ThisSurf + AlphaOffset) + " not exposed to sun in " + CurrentModuleObject + " =" +
     575           0 :                                         state.dataTranspiredCollector->UTSC(Item).Name);
     576           0 :                     ErrorsFound = true;
     577           0 :                     continue;
     578             :                 }
     579           6 :                 if (!state.dataSurface->Surface(Found).ExtWind) {
     580           0 :                     ShowSevereError(state,
     581           0 :                                     "Surface " + Alphas(ThisSurf + AlphaOffset) + " not exposed to wind in " + CurrentModuleObject + " =" +
     582           0 :                                         state.dataTranspiredCollector->UTSC(Item).Name);
     583           0 :                     ErrorsFound = true;
     584           0 :                     continue;
     585             :                 }
     586           6 :                 if (state.dataSurface->Surface(Found).ExtBoundCond != OtherSideCondModeledExt) {
     587           0 :                     ShowSevereError(state,
     588           0 :                                     "Surface " + Alphas(ThisSurf + AlphaOffset) +
     589           0 :                                         " does not have OtherSideConditionsModel for exterior boundary conditions in " + CurrentModuleObject + " =" +
     590           0 :                                         state.dataTranspiredCollector->UTSC(Item).Name);
     591           0 :                     ErrorsFound = true;
     592           0 :                     continue;
     593             :                 }
     594             :                 // check surface orientation, warn if upside down
     595           6 :                 if ((state.dataSurface->Surface(Found).Tilt < -95.0) || (state.dataSurface->Surface(Found).Tilt > 95.0)) {
     596           0 :                     ShowWarningError(state, "Suspected input problem with collector surface = " + Alphas(ThisSurf + AlphaOffset));
     597           0 :                     ShowContinueError(
     598           0 :                         state, "Entered in " + state.dataIPShortCut->cCurrentModuleObject + " = " + state.dataTranspiredCollector->UTSC(Item).Name);
     599           0 :                     ShowContinueError(state, "Surface used for solar collector faces down");
     600           0 :                     ShowContinueError(
     601           0 :                         state, format("Surface tilt angle (degrees from ground outward normal) = {:.2R}", state.dataSurface->Surface(Found).Tilt));
     602             :                 }
     603             : 
     604           6 :                 state.dataTranspiredCollector->UTSC(Item).SurfPtrs(ThisSurf) = Found;
     605             :             }
     606             : 
     607           5 :             if (ErrorsFound) continue; // previous inner do loop may have detected problems that need to be cycle'd again to avoid crash
     608             : 
     609             :             // now that we should have all the surfaces, do some preperations and checks.
     610             : 
     611             :             // are they all similar tilt and azimuth? Issue warnings so people can do it if they really want
     612           5 :             Real64 const surfaceArea(sum_sub(state.dataSurface->Surface, &SurfaceData::Area, state.dataTranspiredCollector->UTSC(Item).SurfPtrs));
     613             :             //            AvgAzimuth = sum( Surface( UTSC( Item ).SurfPtrs ).Azimuth * Surface( UTSC( Item ).SurfPtrs ).Area ) / sum( Surface(
     614             :             // UTSC(  Item
     615             :             //).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced by below
     616           5 :             AvgAzimuth =
     617          10 :                 sum_product_sub(
     618          10 :                     state.dataSurface->Surface, &SurfaceData::Azimuth, &SurfaceData::Area, state.dataTranspiredCollector->UTSC(Item).SurfPtrs) /
     619             :                 surfaceArea; // Autodesk:F2C++ Functions handle array subscript usage
     620             :             //            AvgTilt = sum( Surface( UTSC( Item ).SurfPtrs ).Tilt * Surface( UTSC( Item ).SurfPtrs ).Area ) / sum( Surface( UTSC(
     621             :             // Item
     622             :             //).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced by below
     623          10 :             AvgTilt = sum_product_sub(
     624          10 :                           state.dataSurface->Surface, &SurfaceData::Tilt, &SurfaceData::Area, state.dataTranspiredCollector->UTSC(Item).SurfPtrs) /
     625             :                       surfaceArea; // Autodesk:F2C++ Functions handle array subscript usage
     626          11 :             for (ThisSurf = 1; ThisSurf <= state.dataTranspiredCollector->UTSC(Item).NumSurfs; ++ThisSurf) {
     627           6 :                 SurfID = state.dataTranspiredCollector->UTSC(Item).SurfPtrs(ThisSurf);
     628           6 :                 if (std::abs(state.dataSurface->Surface(SurfID).Azimuth - AvgAzimuth) > 15.0) {
     629           0 :                     ShowWarningError(state,
     630           0 :                                      "Surface " + state.dataSurface->Surface(SurfID).Name +
     631           0 :                                          " has Azimuth different from others in the group associated with " + CurrentModuleObject + " =" +
     632           0 :                                          state.dataTranspiredCollector->UTSC(Item).Name);
     633             :                 }
     634           6 :                 if (std::abs(state.dataSurface->Surface(SurfID).Tilt - AvgTilt) > 10.0) {
     635           0 :                     ShowWarningError(state,
     636           0 :                                      "Surface " + state.dataSurface->Surface(SurfID).Name +
     637           0 :                                          " has Tilt different from others in the group associated with " + CurrentModuleObject + " =" +
     638           0 :                                          state.dataTranspiredCollector->UTSC(Item).Name);
     639             :                 }
     640             : 
     641             :                 // test that there are no windows.  Now allow windows
     642             :                 // If (Surface(SurfID)%GrossArea >  Surface(SurfID)%Area) Then
     643             :                 //      Call ShowWarningError(state, 'Surface '//TRIM(Surface(SurfID)%name)//' has a subsurface whose area is not being ' &
     644             :                 //         //'subtracted in the group of surfaces associated with '//TRIM(UTSC(Item)%Name))
     645             :                 // endif
     646             :             }
     647           5 :             state.dataTranspiredCollector->UTSC(Item).Tilt = AvgTilt;
     648           5 :             state.dataTranspiredCollector->UTSC(Item).Azimuth = AvgAzimuth;
     649             : 
     650             :             // find area weighted centroid.
     651             :             //    UTSC(Item)%Centroid%x = SUM(Surface(UTSC(Item)%SurfPtrs)%Centroid%x*Surface(UTSC(Item)%SurfPtrs)%Area) &
     652             :             //                            /SUM(Surface(UTSC(Item)%SurfPtrs)%Area)
     653             :             //    UTSC(Item)%Centroid%y = SUM(Surface(UTSC(Item)%SurfPtrs)%Centroid%y*Surface(UTSC(Item)%SurfPtrs)%Area) &
     654             :             //                            /SUM(Surface(UTSC(Item)%SurfPtrs)%Area)
     655             :             //            UTSC( Item ).Centroid.z = sum( Surface( UTSC( Item ).SurfPtrs ).Centroid.z * Surface( UTSC( Item ).SurfPtrs ).Area ) /
     656             :             // sum(  Surface( UTSC( Item ).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced by below
     657          15 :             state.dataTranspiredCollector->UTSC(Item).Centroid.z = sum_product_sub(state.dataSurface->Surface,
     658             :                                                                                    &SurfaceData::Centroid,
     659             :                                                                                    &Vector::z,
     660           5 :                                                                                    state.dataSurface->Surface,
     661             :                                                                                    &SurfaceData::Area,
     662          10 :                                                                                    state.dataTranspiredCollector->UTSC(Item).SurfPtrs) /
     663             :                                                                    surfaceArea; // Autodesk:F2C++ Functions handle array subscript usage
     664             : 
     665             :             // now handle numbers from input object
     666           5 :             state.dataTranspiredCollector->UTSC(Item).HoleDia = Numbers(1);
     667           5 :             state.dataTranspiredCollector->UTSC(Item).Pitch = Numbers(2);
     668           5 :             state.dataTranspiredCollector->UTSC(Item).LWEmitt = Numbers(3);
     669           5 :             state.dataTranspiredCollector->UTSC(Item).SolAbsorp = Numbers(4);
     670           5 :             state.dataTranspiredCollector->UTSC(Item).Height = Numbers(5);
     671           5 :             state.dataTranspiredCollector->UTSC(Item).PlenGapThick = Numbers(6);
     672           5 :             if (state.dataTranspiredCollector->UTSC(Item).PlenGapThick <= 0.0) {
     673           0 :                 ShowSevereError(
     674           0 :                     state, "Plenum gap must be greater than Zero in " + CurrentModuleObject + " =" + state.dataTranspiredCollector->UTSC(Item).Name);
     675           0 :                 continue;
     676             :             }
     677           5 :             state.dataTranspiredCollector->UTSC(Item).PlenCrossArea = Numbers(7);
     678           5 :             state.dataTranspiredCollector->UTSC(Item).AreaRatio = Numbers(8);
     679           5 :             state.dataTranspiredCollector->UTSC(Item).CollectThick = Numbers(9);
     680           5 :             state.dataTranspiredCollector->UTSC(Item).Cv = Numbers(10);
     681           5 :             state.dataTranspiredCollector->UTSC(Item).Cd = Numbers(11);
     682             : 
     683             :             // Fill out data we now know
     684             :             // sum areas of HT surface areas
     685             :             //            UTSC( Item ).ProjArea = sum( Surface( UTSC( Item ).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced
     686             :             // by  below
     687           5 :             state.dataTranspiredCollector->UTSC(Item).ProjArea = surfaceArea;
     688           5 :             if (state.dataTranspiredCollector->UTSC(Item).ProjArea == 0) {
     689           0 :                 ShowSevereError(state,
     690           0 :                                 "Gross area of underlying surfaces is zero in " + CurrentModuleObject + " =" +
     691           0 :                                     state.dataTranspiredCollector->UTSC(Item).Name);
     692           0 :                 continue;
     693             :             }
     694           5 :             state.dataTranspiredCollector->UTSC(Item).ActualArea =
     695           5 :                 state.dataTranspiredCollector->UTSC(Item).ProjArea * state.dataTranspiredCollector->UTSC(Item).AreaRatio;
     696             :             //  need to update this for slots as well as holes
     697           5 :             switch (state.dataTranspiredCollector->UTSC(Item).Layout) {
     698           5 :             case Layout_Triangle: { // 'TRIANGLE'
     699           5 :                 state.dataTranspiredCollector->UTSC(Item).Porosity =
     700          10 :                     0.907 * pow_2(state.dataTranspiredCollector->UTSC(Item).HoleDia /
     701           5 :                                   state.dataTranspiredCollector->UTSC(Item).Pitch); // Kutscher equation, Triangle layout
     702           5 :             } break;
     703           0 :             case Layout_Square: { // 'SQUARE'
     704           0 :                 state.dataTranspiredCollector->UTSC(Item).Porosity =
     705           0 :                     (DataGlobalConstants::Pi / 4.0) * pow_2(state.dataTranspiredCollector->UTSC(Item).HoleDia) /
     706           0 :                     pow_2(state.dataTranspiredCollector->UTSC(Item).Pitch); // Waterloo equation, square layout
     707           0 :             } break;
     708           0 :             default:
     709           0 :                 break;
     710             :             }
     711           5 :             TiltRads = std::abs(AvgTilt) * DataGlobalConstants::DegToRadians;
     712           5 :             tempHdeltaNPL = std::sin(TiltRads) * state.dataTranspiredCollector->UTSC(Item).Height / 4.0;
     713           5 :             state.dataTranspiredCollector->UTSC(Item).HdeltaNPL = max(tempHdeltaNPL, state.dataTranspiredCollector->UTSC(Item).PlenGapThick);
     714             : 
     715          20 :             SetupOutputVariable(state,
     716             :                                 "Solar Collector Heat Exchanger Effectiveness",
     717             :                                 OutputProcessor::Unit::None,
     718           5 :                                 state.dataTranspiredCollector->UTSC(Item).HXeff,
     719             :                                 OutputProcessor::SOVTimeStepType::System,
     720             :                                 OutputProcessor::SOVStoreType::Average,
     721          10 :                                 state.dataTranspiredCollector->UTSC(Item).Name);
     722          20 :             SetupOutputVariable(state,
     723             :                                 "Solar Collector Leaving Air Temperature",
     724             :                                 OutputProcessor::Unit::C,
     725           5 :                                 state.dataTranspiredCollector->UTSC(Item).TairHX,
     726             :                                 OutputProcessor::SOVTimeStepType::System,
     727             :                                 OutputProcessor::SOVStoreType::Average,
     728          10 :                                 state.dataTranspiredCollector->UTSC(Item).Name);
     729          20 :             SetupOutputVariable(state,
     730             :                                 "Solar Collector Outside Face Suction Velocity",
     731             :                                 OutputProcessor::Unit::m_s,
     732           5 :                                 state.dataTranspiredCollector->UTSC(Item).Vsuction,
     733             :                                 OutputProcessor::SOVTimeStepType::System,
     734             :                                 OutputProcessor::SOVStoreType::Average,
     735          10 :                                 state.dataTranspiredCollector->UTSC(Item).Name);
     736          20 :             SetupOutputVariable(state,
     737             :                                 "Solar Collector Surface Temperature",
     738             :                                 OutputProcessor::Unit::C,
     739           5 :                                 state.dataTranspiredCollector->UTSC(Item).Tcoll,
     740             :                                 OutputProcessor::SOVTimeStepType::System,
     741             :                                 OutputProcessor::SOVStoreType::Average,
     742          10 :                                 state.dataTranspiredCollector->UTSC(Item).Name);
     743          20 :             SetupOutputVariable(state,
     744             :                                 "Solar Collector Plenum Air Temperature",
     745             :                                 OutputProcessor::Unit::C,
     746           5 :                                 state.dataTranspiredCollector->UTSC(Item).Tplen,
     747             :                                 OutputProcessor::SOVTimeStepType::System,
     748             :                                 OutputProcessor::SOVStoreType::Average,
     749          10 :                                 state.dataTranspiredCollector->UTSC(Item).Name);
     750          20 :             SetupOutputVariable(state,
     751             :                                 "Solar Collector Sensible Heating Rate",
     752             :                                 OutputProcessor::Unit::W,
     753           5 :                                 state.dataTranspiredCollector->UTSC(Item).SensHeatingRate,
     754             :                                 OutputProcessor::SOVTimeStepType::System,
     755             :                                 OutputProcessor::SOVStoreType::Average,
     756          10 :                                 state.dataTranspiredCollector->UTSC(Item).Name);
     757          20 :             SetupOutputVariable(state,
     758             :                                 "Solar Collector Sensible Heating Energy",
     759             :                                 OutputProcessor::Unit::J,
     760           5 :                                 state.dataTranspiredCollector->UTSC(Item).SensHeatingEnergy,
     761             :                                 OutputProcessor::SOVTimeStepType::System,
     762             :                                 OutputProcessor::SOVStoreType::Summed,
     763           5 :                                 state.dataTranspiredCollector->UTSC(Item).Name,
     764             :                                 _,
     765             :                                 "SolarAir",
     766             :                                 "HeatProduced",
     767             :                                 _,
     768           5 :                                 "System");
     769             : 
     770          20 :             SetupOutputVariable(state,
     771             :                                 "Solar Collector Natural Ventilation Air Change Rate",
     772             :                                 OutputProcessor::Unit::ach,
     773           5 :                                 state.dataTranspiredCollector->UTSC(Item).PassiveACH,
     774             :                                 OutputProcessor::SOVTimeStepType::System,
     775             :                                 OutputProcessor::SOVStoreType::Average,
     776          10 :                                 state.dataTranspiredCollector->UTSC(Item).Name);
     777          20 :             SetupOutputVariable(state,
     778             :                                 "Solar Collector Natural Ventilation Mass Flow Rate",
     779             :                                 OutputProcessor::Unit::kg_s,
     780           5 :                                 state.dataTranspiredCollector->UTSC(Item).PassiveMdotVent,
     781             :                                 OutputProcessor::SOVTimeStepType::System,
     782             :                                 OutputProcessor::SOVStoreType::Average,
     783          10 :                                 state.dataTranspiredCollector->UTSC(Item).Name);
     784          20 :             SetupOutputVariable(state,
     785             :                                 "Solar Collector Wind Natural Ventilation Mass Flow Rate",
     786             :                                 OutputProcessor::Unit::kg_s,
     787           5 :                                 state.dataTranspiredCollector->UTSC(Item).PassiveMdotWind,
     788             :                                 OutputProcessor::SOVTimeStepType::System,
     789             :                                 OutputProcessor::SOVStoreType::Average,
     790          10 :                                 state.dataTranspiredCollector->UTSC(Item).Name);
     791          20 :             SetupOutputVariable(state,
     792             :                                 "Solar Collector Buoyancy Natural Ventilation Mass Flow Rate",
     793             :                                 OutputProcessor::Unit::kg_s,
     794           5 :                                 state.dataTranspiredCollector->UTSC(Item).PassiveMdotTherm,
     795             :                                 OutputProcessor::SOVTimeStepType::System,
     796             :                                 OutputProcessor::SOVStoreType::Average,
     797          10 :                                 state.dataTranspiredCollector->UTSC(Item).Name);
     798          20 :             SetupOutputVariable(state,
     799             :                                 "Solar Collector Incident Solar Radiation",
     800             :                                 OutputProcessor::Unit::W_m2,
     801           5 :                                 state.dataTranspiredCollector->UTSC(Item).Isc,
     802             :                                 OutputProcessor::SOVTimeStepType::System,
     803             :                                 OutputProcessor::SOVStoreType::Average,
     804          10 :                                 state.dataTranspiredCollector->UTSC(Item).Name);
     805          20 :             SetupOutputVariable(state,
     806             :                                 "Solar Collector System Efficiency",
     807             :                                 OutputProcessor::Unit::None,
     808           5 :                                 state.dataTranspiredCollector->UTSC(Item).UTSCEfficiency,
     809             :                                 OutputProcessor::SOVTimeStepType::System,
     810             :                                 OutputProcessor::SOVStoreType::Average,
     811          10 :                                 state.dataTranspiredCollector->UTSC(Item).Name);
     812          20 :             SetupOutputVariable(state,
     813             :                                 "Solar Collector Surface Efficiency",
     814             :                                 OutputProcessor::Unit::None,
     815           5 :                                 state.dataTranspiredCollector->UTSC(Item).UTSCCollEff,
     816             :                                 OutputProcessor::SOVTimeStepType::System,
     817             :                                 OutputProcessor::SOVStoreType::Average,
     818          10 :                                 state.dataTranspiredCollector->UTSC(Item).Name);
     819             :         }
     820             : 
     821           2 :         for (ItemSplit = 1; ItemSplit <= NumUTSCSplitter; ++ItemSplit) {
     822           1 :             if (!SplitterNameOK(ItemSplit)) {
     823           0 :                 ShowSevereError(state, "Did not find a match, check names for Solar Collectors:Transpired Collector:Multisystem");
     824           0 :                 ErrorsFound = true;
     825             :             }
     826             :         }
     827             : 
     828           1 :         if (ErrorsFound) {
     829           0 :             ShowFatalError(state, "GetTranspiredCollectorInput: Errors found in input");
     830             :         }
     831             : 
     832           1 :         Alphas.deallocate();
     833           1 :     }
     834             : 
     835       40675 :     void InitTranspiredCollector(EnergyPlusData &state, int const UTSCNum) // compindex already checked in calling routine
     836             :     {
     837             : 
     838             :         // SUBROUTINE INFORMATION:
     839             :         //       AUTHOR         B.T. Griffith
     840             :         //       DATE WRITTEN   November 2004
     841             :         //       MODIFIED       B. Griffith, May 2009, added EMS setpoint check
     842             :         //       RE-ENGINEERED  na
     843             : 
     844             :         // Using/Aliasing
     845       40675 :         auto &DoSetPointTest = state.dataHVACGlobal->DoSetPointTest;
     846       40675 :         auto &SetPointErrorFlag = state.dataHVACGlobal->SetPointErrorFlag;
     847             :         using namespace DataLoopNode;
     848             :         using DataSurfaces::SurfaceData;
     849             :         using EMSManager::CheckIfNodeSetPointManagedByEMS;
     850             : 
     851             :         int UTSCUnitNum;
     852             :         int ControlNode;
     853             :         int SplitBranch;
     854             :         int thisUTSC;
     855             :         Real64 Tamb;
     856             : 
     857       40675 :         if (state.dataTranspiredCollector->MyOneTimeFlag) {
     858             :             // do various one time setups and pitch adjustments across all UTSC
     859           6 :             for (thisUTSC = 1; thisUTSC <= state.dataTranspiredCollector->NumUTSC; ++thisUTSC) {
     860           5 :                 if (state.dataTranspiredCollector->UTSC(thisUTSC).Layout == Layout_Triangle) {
     861           5 :                     switch (state.dataTranspiredCollector->UTSC(thisUTSC).Correlation) {
     862           3 :                     case Correlation_Kutscher1994: { // Kutscher1994
     863           3 :                         state.dataTranspiredCollector->UTSC(thisUTSC).Pitch = state.dataTranspiredCollector->UTSC(thisUTSC).Pitch;
     864           3 :                     } break;
     865           2 :                     case Correlation_VanDeckerHollandsBrunger2001: { // VanDeckerHollandsBrunger2001
     866           2 :                         state.dataTranspiredCollector->UTSC(thisUTSC).Pitch /= 1.6;
     867           2 :                     } break;
     868           0 :                     default:
     869           0 :                         break;
     870             :                     }
     871             :                 }
     872           5 :                 if (state.dataTranspiredCollector->UTSC(thisUTSC).Layout == Layout_Square) {
     873           0 :                     switch (state.dataTranspiredCollector->UTSC(thisUTSC).Correlation) {
     874           0 :                     case Correlation_Kutscher1994: { // Kutscher1994
     875           0 :                         state.dataTranspiredCollector->UTSC(thisUTSC).Pitch *= 1.6;
     876           0 :                     } break;
     877           0 :                     case Correlation_VanDeckerHollandsBrunger2001: { // VanDeckerHollandsBrunger2001
     878           0 :                         state.dataTranspiredCollector->UTSC(thisUTSC).Pitch = state.dataTranspiredCollector->UTSC(thisUTSC).Pitch;
     879           0 :                     } break;
     880           0 :                     default:
     881           0 :                         break;
     882             :                     }
     883             :                 }
     884             :             }
     885             : 
     886           1 :             state.dataTranspiredCollector->MyEnvrnFlag.dimension(state.dataTranspiredCollector->NumUTSC, true);
     887           1 :             state.dataTranspiredCollector->MyOneTimeFlag = false;
     888             :         } // first time
     889             : 
     890             :         // Check that setpoint is active (from test by RJL in HVACEvapComponent)
     891       40675 :         if (!state.dataGlobal->SysSizingCalc && state.dataTranspiredCollector->MySetPointCheckFlag && DoSetPointTest) {
     892           6 :             for (UTSCUnitNum = 1; UTSCUnitNum <= state.dataTranspiredCollector->NumUTSC; ++UTSCUnitNum) {
     893          14 :                 for (SplitBranch = 1; SplitBranch <= state.dataTranspiredCollector->UTSC(UTSCUnitNum).NumOASysAttached; ++SplitBranch) {
     894           9 :                     ControlNode = state.dataTranspiredCollector->UTSC(UTSCUnitNum).ControlNode(SplitBranch);
     895           9 :                     if (ControlNode > 0) {
     896           9 :                         if (state.dataLoopNodes->Node(ControlNode).TempSetPoint == SensedNodeFlagValue) {
     897           0 :                             if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
     898           0 :                                 ShowSevereError(state,
     899           0 :                                                 "Missing temperature setpoint for UTSC " + state.dataTranspiredCollector->UTSC(UTSCUnitNum).Name);
     900           0 :                                 ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the unit control node.");
     901           0 :                                 SetPointErrorFlag = true;
     902             :                             } else {
     903             :                                 // need call to EMS to check node
     904           0 :                                 CheckIfNodeSetPointManagedByEMS(
     905             :                                     state, ControlNode, EMSManager::SPControlType::TemperatureSetPoint, SetPointErrorFlag);
     906           0 :                                 if (SetPointErrorFlag) {
     907           0 :                                     ShowSevereError(state,
     908           0 :                                                     "Missing temperature setpoint for UTSC " + state.dataTranspiredCollector->UTSC(UTSCUnitNum).Name);
     909           0 :                                     ShowContinueError(state, " use a Setpoint Manager to establish a setpoint at the unit control node.");
     910           0 :                                     ShowContinueError(state, "Or add EMS Actuator to provide temperature setpoint at this node");
     911             :                                 }
     912             :                             }
     913             :                         }
     914             :                     }
     915             :                 }
     916             :             }
     917           1 :             state.dataTranspiredCollector->MySetPointCheckFlag = false;
     918             :         }
     919             : 
     920       40675 :         if (state.dataGlobal->BeginEnvrnFlag && state.dataTranspiredCollector->MyEnvrnFlag(UTSCNum)) {
     921          30 :             state.dataTranspiredCollector->UTSC(UTSCNum).TplenLast = 22.5;
     922          30 :             state.dataTranspiredCollector->UTSC(UTSCNum).TcollLast = 22.0;
     923             : 
     924          30 :             state.dataTranspiredCollector->MyEnvrnFlag(UTSCNum) = false;
     925             :         }
     926       40675 :         if (!state.dataGlobal->BeginEnvrnFlag) {
     927       40179 :             state.dataTranspiredCollector->MyEnvrnFlag(UTSCNum) = true;
     928             :         }
     929             : 
     930             :         // determine average ambient temperature
     931       40675 :         Real64 sum_area = 0.0;
     932      104697 :         for (int SurfNum : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) {
     933       64022 :             sum_area += state.dataSurface->Surface(SurfNum).Area;
     934             :         }
     935       40675 :         if (!state.dataEnvrn->IsRain) {
     936       40675 :             Real64 sum_produc_area_drybulb = 0.0;
     937      104697 :             for (int SurfNum : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) {
     938       64022 :                 sum_produc_area_drybulb += state.dataSurface->Surface(SurfNum).Area * state.dataSurface->SurfOutDryBulbTemp(SurfNum);
     939             :             }
     940       40675 :             Tamb = sum_produc_area_drybulb / sum_area;
     941             :         } else { // when raining we use wet bulb not drybulb
     942           0 :             Real64 sum_produc_area_wetbulb = 0.0;
     943           0 :             for (int SurfNum : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) {
     944           0 :                 sum_produc_area_wetbulb += state.dataSurface->Surface(SurfNum).Area * state.dataSurface->SurfOutWetBulbTemp(SurfNum);
     945             :             }
     946           0 :             Tamb = sum_produc_area_wetbulb / sum_area;
     947             :         }
     948             : 
     949             :         // inits for each iteration
     950             :         //        UTSC( UTSCNum ).InletMDot = sum( Node( UTSC( UTSCNum ).InletNode ).MassFlowRate ); //Autodesk:F2C++ Array subscript usage:
     951             :         // Replaced by below
     952       40675 :         state.dataTranspiredCollector->UTSC(UTSCNum).InletMDot =
     953       40675 :             sum_sub(state.dataLoopNodes->Node,
     954             :                     &DataLoopNode::NodeData::MassFlowRate,
     955       40675 :                     state.dataTranspiredCollector->UTSC(UTSCNum).InletNode); // Autodesk:F2C++ Functions handle array subscript usage
     956       40675 :         state.dataTranspiredCollector->UTSC(UTSCNum).IsOn = false;           // intialize then turn on if appropriate
     957       40675 :         state.dataTranspiredCollector->UTSC(UTSCNum).Tplen = state.dataTranspiredCollector->UTSC(UTSCNum).TplenLast;
     958       40675 :         state.dataTranspiredCollector->UTSC(UTSCNum).Tcoll = state.dataTranspiredCollector->UTSC(UTSCNum).TcollLast;
     959       40675 :         state.dataTranspiredCollector->UTSC(UTSCNum).TairHX = Tamb;
     960       40675 :         state.dataTranspiredCollector->UTSC(UTSCNum).MdotVent = 0.0;
     961       40675 :         state.dataTranspiredCollector->UTSC(UTSCNum).HXeff = 0.0;
     962       40675 :         state.dataTranspiredCollector->UTSC(UTSCNum).Isc = 0.0;
     963             : 
     964       40675 :         state.dataTranspiredCollector->UTSC(UTSCNum).UTSCEfficiency = 0.0;
     965       40675 :         state.dataTranspiredCollector->UTSC(UTSCNum).UTSCCollEff = 0.0;
     966       40675 :     }
     967             : 
     968        9700 :     void CalcActiveTranspiredCollector(EnergyPlusData &state, int const UTSCNum)
     969             :     {
     970             : 
     971             :         // SUBROUTINE INFORMATION:
     972             :         //       AUTHOR         B.T. Griffith
     973             :         //       DATE WRITTEN   November 2004
     974             :         //       MODIFIED       na
     975             :         //       RE-ENGINEERED  na
     976             : 
     977             :         // Using/Aliasing
     978             :         using ConvectionCoefficients::InitExteriorConvectionCoeff;
     979        9700 :         auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys;
     980             :         using DataSurfaces::SurfaceData;
     981             :         using Psychrometrics::PsyCpAirFnW;
     982             :         using Psychrometrics::PsyHFnTdbW;
     983             :         using Psychrometrics::PsyRhoAirFnPbTdbW;
     984             :         using namespace DataHeatBalance; // , ONLY: SurfQRadSWOutIncident, Construct, Material
     985             : 
     986             :         // SUBROUTINE PARAMETER DEFINITIONS:
     987        9700 :         Real64 constexpr nu(15.66e-6); // kinematic viscosity (m**2/s) for air at 300 K
     988             :         // (Mills 1999 Heat Transfer)
     989        9700 :         Real64 constexpr k(0.0267); // thermal conductivity (W/m K) for air at 300 K
     990             :         // (Mills 1999 Heat Transfer)
     991        9700 :         Real64 constexpr Sigma(5.6697e-08); // Stefan-Boltzmann constant
     992             : 
     993             :         // following arrays are used to temporarily hold results from multiple underlying surfaces
     994       19400 :         Array1D<Real64> HSkyARR;
     995       19400 :         Array1D<Real64> HGroundARR;
     996       19400 :         Array1D<Real64> HAirARR;
     997       19400 :         Array1D<Real64> HPlenARR;
     998       19400 :         Array1D<Real64> LocalWindArr;
     999             : 
    1000             :         // working variables
    1001             :         Real64 RhoAir;                            // density of air
    1002             :         Real64 CpAir;                             // specific heat of air
    1003             :         Real64 holeArea;                          // area of perforations, includes corrugation of surface
    1004             :         Real64 Tamb;                              // outdoor drybulb
    1005             :         Real64 A;                                 // projected area of collector, from sum of underlying surfaces
    1006             :         Real64 Vholes;                            // mean velocity of air as it passes through collector holes
    1007             :         Real64 Vsuction;                          // mean velocity of air as is approaches the collector
    1008             :         Real64 Vplen;                             // mean velocity of air inside plenum
    1009             :         Real64 HcPlen;                            // surface convection heat transfer coefficient for plenum surfaces
    1010             :         Real64 D;                                 // hole diameter
    1011             :         Real64 ReD;                               // Reynolds number for holes
    1012             :         Real64 P;                                 // pitch, distance betweeen holes
    1013             :         Real64 Por;                               // porosity, area fraction of collector that is open because of holes
    1014             :         Real64 Mdot;                              // mass flow rate of suction air
    1015             :         Real64 QdotSource;                        // energy flux for source/sink inside collector surface (for hybrid PV UTSC)
    1016             :         int ThisSurf;                             // do loop counter
    1017             :         int NumSurfs;                             // number of underlying HT surfaces associated with UTSC
    1018             :         DataSurfaces::SurfaceRoughness Roughness; // parameters for surface roughness, defined in DataHeatBalance
    1019             :         Real64 SolAbs;                            // solar absorptivity of collector
    1020             :         Real64 AbsExt;                            // thermal emmittance of collector
    1021             :         Real64 TempExt;                           // collector temperature
    1022             :         int SurfPtr;                              // index of surface in main surface structure
    1023             :         Real64 HMovInsul;                         // dummy for call to InitExteriorConvectionCoeff
    1024             :         Real64 HExt;                              // dummy for call to InitExteriorConvectionCoeff
    1025             :         int ConstrNum;                            // index of construction in main construction structure
    1026             :         Real64 AbsThermSurf;                      // thermal emmittance of underlying wall.
    1027             :         Real64 TsoK;                              // underlying surface temperature in Kelvin
    1028             :         Real64 TscollK;                           // collector temperature in Kelvin  (lagged)
    1029             :         Real64 AreaSum;                           // sum of contributing surfaces for area-weighted averages.
    1030             :         Real64 Vwind;                             // localized, and area-weighted average for wind speed
    1031             :         Real64 HrSky;                             // radiation coeff for sky, area-weighted average
    1032             :         Real64 HrGround;                          // radiation coeff for ground, area-weighted average
    1033             :         Real64 HrAtm;                             // radiation coeff for air (bulk atmosphere), area-weighted average
    1034             :         Real64 Isc;                               // Incoming combined solar radiation, area-weighted average
    1035             :         Real64 HrPlen;                            // radiation coeff for plenum surfaces, area-weighted average
    1036             :         Real64 Tso;                               // temperature of underlying surface, area-weighted average
    1037             :         Real64 HcWind;                            // convection coeff for high speed wind situations
    1038             :         Real64 NuD;                               // nusselt number for Reynolds based on hole
    1039             :         Real64 U;                                 // overall heat exchanger coefficient
    1040             :         Real64 HXeff;                             // effectiveness for heat exchanger
    1041             :         Real64 t;                                 // collector thickness
    1042             :         Real64 ReS;                               // Reynolds number based on suction velocity and pitch
    1043             :         Real64 ReW;                               // Reynolds number based on Wind and pitch
    1044             :         Real64 ReB;                               // Reynolds number based on hole velocity and pitch
    1045             :         Real64 ReH;                               // Reynolds number based on hole velocity and diameter
    1046             :         Real64 Tscoll;                            // temperature of collector
    1047             :         Real64 TaHX;                              // leaving air temperature from heat exchanger (entering plenum)
    1048             :         Real64 Taplen;                            // Air temperature in plen and outlet node.
    1049             :         Real64 SensHeatingRate;                   // Rate at which the system is heating outdoor air
    1050             :         Real64 AlessHoles;                        // Area for Kutscher's relation
    1051             : 
    1052             :         // Active UTSC calculation
    1053             :         // first do common things for both correlations
    1054        9700 :         Real64 sum_area = 0.0;
    1055       22548 :         for (int SurfNum : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) {
    1056       12848 :             sum_area += state.dataSurface->Surface(SurfNum).Area;
    1057             :         }
    1058        9700 :         if (!state.dataEnvrn->IsRain) {
    1059        9700 :             Real64 sum_produc_area_drybulb = 0.0;
    1060       22548 :             for (int SurfNum : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) {
    1061       12848 :                 sum_produc_area_drybulb += state.dataSurface->Surface(SurfNum).Area * state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    1062             :             }
    1063        9700 :             Tamb = sum_produc_area_drybulb / sum_area;
    1064             :         } else { // when raining we use wet bulb not drybulb
    1065           0 :             Real64 sum_produc_area_wetbulb = 0.0;
    1066           0 :             for (int SurfNum : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) {
    1067           0 :                 sum_produc_area_wetbulb += state.dataSurface->Surface(SurfNum).Area * state.dataSurface->SurfOutWetBulbTemp(SurfNum);
    1068             :             }
    1069           0 :             Tamb = sum_produc_area_wetbulb / sum_area;
    1070             :         }
    1071             : 
    1072        9700 :         RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, Tamb, state.dataEnvrn->OutHumRat);
    1073             : 
    1074        9700 :         CpAir = PsyCpAirFnW(state.dataEnvrn->OutHumRat);
    1075             : 
    1076        9700 :         holeArea = state.dataTranspiredCollector->UTSC(UTSCNum).ActualArea * state.dataTranspiredCollector->UTSC(UTSCNum).Porosity;
    1077             : 
    1078        9700 :         A = state.dataTranspiredCollector->UTSC(UTSCNum).ProjArea;
    1079             : 
    1080        9700 :         Vholes = state.dataTranspiredCollector->UTSC(UTSCNum).InletMDot / RhoAir / holeArea;
    1081             : 
    1082        9700 :         Vplen = state.dataTranspiredCollector->UTSC(UTSCNum).InletMDot / RhoAir / state.dataTranspiredCollector->UTSC(UTSCNum).PlenCrossArea;
    1083             : 
    1084        9700 :         Vsuction = state.dataTranspiredCollector->UTSC(UTSCNum).InletMDot / RhoAir / A;
    1085             : 
    1086        9700 :         if ((Vsuction < 0.001) || (Vsuction > 0.08)) { // warn that collector is not sized well
    1087           0 :             if (state.dataTranspiredCollector->UTSC(UTSCNum).VsucErrIndex == 0) {
    1088           0 :                 ShowWarningMessage(state,
    1089           0 :                                    "Solar Collector:Unglazed Transpired=\"" + state.dataTranspiredCollector->UTSC(UTSCNum).Name +
    1090             :                                        "\", Suction velocity is outside of range for a good design");
    1091           0 :                 ShowContinueErrorTimeStamp(state, format("Suction velocity ={:.4R}", Vsuction));
    1092           0 :                 if (Vsuction < 0.003) {
    1093           0 :                     ShowContinueError(state, "Velocity is low -- suggest decreasing area of transpired collector");
    1094             :                 }
    1095           0 :                 if (Vsuction > 0.08) {
    1096           0 :                     ShowContinueError(state, "Velocity is high -- suggest increasing area of transpired collector");
    1097             :                 }
    1098           0 :                 ShowContinueError(state, "Occasional suction velocity messages are not unexpected when simulating actual conditions");
    1099             :             }
    1100           0 :             ShowRecurringWarningErrorAtEnd(state,
    1101           0 :                                            "Solar Collector:Unglazed Transpired=\"" + state.dataTranspiredCollector->UTSC(UTSCNum).Name +
    1102             :                                                "\", Suction velocity is outside of range",
    1103           0 :                                            state.dataTranspiredCollector->UTSC(UTSCNum).VsucErrIndex,
    1104             :                                            Vsuction,
    1105             :                                            Vsuction,
    1106             :                                            _,
    1107             :                                            "[m/s]",
    1108             :                                            "[m/s]");
    1109             :         }
    1110             : 
    1111        9700 :         HcPlen = 5.62 + 3.92 * Vplen;
    1112             : 
    1113        9700 :         D = state.dataTranspiredCollector->UTSC(UTSCNum).HoleDia;
    1114             : 
    1115        9700 :         ReD = Vholes * D / nu;
    1116             : 
    1117        9700 :         P = state.dataTranspiredCollector->UTSC(UTSCNum).Pitch;
    1118             : 
    1119        9700 :         Por = state.dataTranspiredCollector->UTSC(UTSCNum).Porosity;
    1120             : 
    1121        9700 :         Mdot = state.dataTranspiredCollector->UTSC(UTSCNum).InletMDot;
    1122             : 
    1123        9700 :         QdotSource = state.dataTranspiredCollector->UTSC(UTSCNum).QdotSource; // for hybrid PV transpired collectors
    1124             : 
    1125             :         // loop through underlying surfaces and collect needed data
    1126             :         // now collect average values for things associated with the underlying surface(s)
    1127        9700 :         NumSurfs = state.dataTranspiredCollector->UTSC(UTSCNum).NumSurfs;
    1128        9700 :         HSkyARR.dimension(NumSurfs, 0.0);
    1129        9700 :         HGroundARR.dimension(NumSurfs, 0.0);
    1130        9700 :         HAirARR.dimension(NumSurfs, 0.0);
    1131        9700 :         LocalWindArr.dimension(NumSurfs, 0.0);
    1132             :         // ALLOCATE(IscARR(NumSurfs))
    1133             :         // IscARR = 0.0
    1134        9700 :         HPlenARR.dimension(NumSurfs, 0.0);
    1135             :         //  ALLOCATE(TsoARR(NumSurfs))
    1136             :         //  TsoARR = 0.0
    1137             : 
    1138        9700 :         Roughness = state.dataTranspiredCollector->UTSC(UTSCNum).CollRoughness;
    1139        9700 :         SolAbs = state.dataTranspiredCollector->UTSC(UTSCNum).SolAbsorp;
    1140        9700 :         AbsExt = state.dataTranspiredCollector->UTSC(UTSCNum).LWEmitt;
    1141        9700 :         TempExt = state.dataTranspiredCollector->UTSC(UTSCNum).TcollLast;
    1142       22548 :         for (ThisSurf = 1; ThisSurf <= NumSurfs; ++ThisSurf) {
    1143       12848 :             SurfPtr = state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs(ThisSurf);
    1144             :             // Initializations for this surface
    1145       12848 :             HMovInsul = 0.0;
    1146       12848 :             HExt = 0.0;
    1147       12848 :             LocalWindArr(ThisSurf) = state.dataSurface->SurfOutWindSpeed(SurfPtr);
    1148       12848 :             InitExteriorConvectionCoeff(
    1149       12848 :                 state, SurfPtr, HMovInsul, Roughness, AbsExt, TempExt, HExt, HSkyARR(ThisSurf), HGroundARR(ThisSurf), HAirARR(ThisSurf));
    1150       12848 :             ConstrNum = state.dataSurface->Surface(SurfPtr).Construction;
    1151       12848 :             AbsThermSurf = state.dataMaterial->Material(state.dataConstruction->Construct(ConstrNum).LayerPoint(1)).AbsorpThermal;
    1152       12848 :             TsoK = state.dataHeatBalSurf->SurfOutsideTempHist(1)(SurfPtr) + DataGlobalConstants::KelvinConv;
    1153       12848 :             TscollK = state.dataTranspiredCollector->UTSC(UTSCNum).TcollLast + DataGlobalConstants::KelvinConv;
    1154       12848 :             HPlenARR(ThisSurf) = Sigma * AbsExt * AbsThermSurf * (pow_4(TscollK) - pow_4(TsoK)) / (TscollK - TsoK);
    1155             :         }
    1156             :         //        AreaSum = sum( Surface( UTSC( UTSCNum ).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced by below
    1157             :         auto Area(
    1158        9700 :             array_sub(state.dataSurface->Surface,
    1159             :                       &SurfaceData::Area,
    1160        9700 :                       state.dataTranspiredCollector->UTSC(UTSCNum)
    1161       29100 :                           .SurfPtrs)); // Autodesk:F2C++ Copy of subscripted Area array for use below: This makes a copy so review wrt performance
    1162        9700 :         AreaSum = sum(Area);
    1163             :         // now figure area-weighted averages from underlying surfaces.
    1164             :         //        Vwind = sum( LocalWindArr * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / AreaSum; //Autodesk:F2C++ Array subscript usage:
    1165             :         // Replaced by below
    1166        9700 :         Vwind = sum(LocalWindArr * Area) / AreaSum;
    1167        9700 :         LocalWindArr.deallocate();
    1168             :         //        HrSky = sum( HSkyARR * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / AreaSum; //Autodesk:F2C++ Array subscript usage: Replaced
    1169             :         // by  below
    1170        9700 :         HrSky = sum(HSkyARR * Area) / AreaSum;
    1171        9700 :         HSkyARR.deallocate();
    1172             :         //        HrGround = sum( HGroundARR * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / AreaSum; //Autodesk:F2C++ Array subscript usage:
    1173             :         // Replaced by below
    1174        9700 :         HrGround = sum(HGroundARR * Area) / AreaSum;
    1175        9700 :         HGroundARR.deallocate();
    1176             :         //        HrAtm = sum( HAirARR * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / AreaSum; //Autodesk:F2C++ Array subscript usage: Replaced
    1177             :         // by  below
    1178        9700 :         HrAtm = sum(HAirARR * Area) / AreaSum;
    1179        9700 :         HAirARR.deallocate();
    1180             :         //        HrPlen = sum( HPlenARR * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / AreaSum; //Autodesk:F2C++ Array subscript usage:
    1181             :         // Replaced  by below
    1182        9700 :         HrPlen = sum(HPlenARR * Area) / AreaSum;
    1183        9700 :         HPlenARR.deallocate();
    1184             : 
    1185             :         //        Isc = sum( SurfQRadSWOutIncident( UTSC( UTSCNum ).SurfPtrs ) * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / AreaSum;
    1186             :         ////Autodesk:F2C++ Array subscript usage: Replaced by below
    1187       19400 :         Isc = sum_product_sub(state.dataHeatBal->SurfQRadSWOutIncident,
    1188        9700 :                               state.dataSurface->Surface,
    1189             :                               &SurfaceData::Area,
    1190        9700 :                               state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) /
    1191             :               AreaSum; // Autodesk:F2C++ Functions handle array subscript usage
    1192             :         //        Tso = sum( TH( UTSC( UTSCNum ).SurfPtrs, 1, 1 ) * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / AreaSum; //Autodesk:F2C++ Array
    1193             :         // subscript usage: Replaced by below
    1194       19400 :         Tso = sum_product_sub(state.dataHeatBalSurf->SurfOutsideTempHist(1),
    1195        9700 :                               state.dataSurface->Surface,
    1196             :                               &SurfaceData::Area,
    1197        9700 :                               state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) /
    1198             :               AreaSum; // Autodesk:F2C++ Functions handle array subscript usage
    1199             : 
    1200        9700 :         if (Vwind > 5.0) {
    1201           0 :             HcWind = 5.62 + 3.9 * (Vwind - 5.0); // McAdams forced convection correlation
    1202             :         } else {
    1203        9700 :             HcWind = 0.0;
    1204             :         }
    1205             : 
    1206        9700 :         if (state.dataEnvrn->IsRain) HcWind = 1000.0;
    1207             : 
    1208        9700 :         HXeff = 0.0; // init
    1209             : 
    1210        9700 :         switch (state.dataTranspiredCollector->UTSC(UTSCNum).Correlation) {
    1211        6424 :         case Correlation_Kutscher1994: { // Kutscher1994
    1212        6424 :             AlessHoles = A - holeArea;
    1213             : 
    1214        6424 :             NuD = 2.75 * ((std::pow(P / D, -1.2) * std::pow(ReD, 0.43)) + (0.011 * Por * ReD * std::pow(Vwind / Vsuction, 0.48)));
    1215        6424 :             U = k * NuD / D;
    1216        6424 :             HXeff = 1.0 - std::exp(-1.0 * ((U * AlessHoles) / (Mdot * CpAir)));
    1217        6424 :         } break;
    1218        3276 :         case Correlation_VanDeckerHollandsBrunger2001: { // VanDeckerHollandsBrunger2001
    1219        3276 :             t = state.dataTranspiredCollector->UTSC(UTSCNum).CollectThick;
    1220        3276 :             ReS = Vsuction * P / nu;
    1221        3276 :             ReW = Vwind * P / nu;
    1222        3276 :             ReB = Vholes * P / nu;
    1223        3276 :             ReH = (Vsuction * D) / (nu * Por);
    1224        3276 :             if (ReD > 0.0) {
    1225        3276 :                 if (ReW > 0.0) {
    1226        9828 :                     HXeff = (1.0 - std::pow(1.0 + ReS * max(1.733 * std::pow(ReW, -0.5), 0.02136), -1.0)) *
    1227        6552 :                             (1.0 - std::pow(1.0 + 0.2273 * std::sqrt(ReB), -1.0)) * std::exp(-0.01895 * (P / D) - (20.62 / ReH) * (t / D));
    1228             :                 } else {
    1229           0 :                     HXeff = (1.0 - std::pow(1.0 + ReS * 0.02136, -1.0)) * (1.0 - std::pow(1.0 + 0.2273 * std::sqrt(ReB), -1.0)) *
    1230           0 :                             std::exp(-0.01895 * (P / D) - (20.62 / ReH) * (t / D));
    1231             :                 }
    1232             :             } else {
    1233           0 :                 HXeff = 0.0;
    1234             :             }
    1235        3276 :         } break;
    1236           0 :         default:
    1237           0 :             break;
    1238             :         }
    1239             : 
    1240             :         // now calculate collector temperature
    1241             : 
    1242       29100 :         Tscoll = (Isc * SolAbs + HrAtm * Tamb + HrSky * state.dataEnvrn->SkyTemp + HrGround * Tamb + HrPlen * Tso + HcWind * Tamb +
    1243       19400 :                   (Mdot * CpAir / A) * Tamb - (Mdot * CpAir / A) * (1.0 - HXeff) * Tamb + QdotSource) /
    1244        9700 :                  (HrAtm + HrSky + HrGround + HrPlen + HcWind + (Mdot * CpAir / A) * HXeff);
    1245             : 
    1246             :         // Heat exchanger leaving temperature
    1247        9700 :         TaHX = HXeff * Tscoll + (1.0 - HXeff) * Tamb;
    1248             : 
    1249             :         // now calculate plenum air temperature
    1250             : 
    1251        9700 :         Taplen = (Mdot * CpAir * TaHX + HcPlen * A * Tso) / (Mdot * CpAir + HcPlen * A);
    1252             : 
    1253             :         // calculate Sensible Heating Rate
    1254        9700 :         if (Taplen > Tamb) {
    1255        1714 :             SensHeatingRate = Mdot * CpAir * (Taplen - Tamb);
    1256             :         } else {
    1257        7986 :             SensHeatingRate = 0.0;
    1258             :         }
    1259             : 
    1260             :         // now fill results into derived types
    1261        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).Isc = Isc;
    1262        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).HXeff = HXeff;
    1263        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).Tplen = Taplen;
    1264        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).Tcoll = Tscoll;
    1265        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).HrPlen = HrPlen;
    1266        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).HcPlen = HcPlen;
    1267        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).TairHX = TaHX;
    1268        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).InletMDot = Mdot;
    1269        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).InletTempDB = Tamb;
    1270        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).Vsuction = Vsuction;
    1271        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).PlenumVelocity = Vplen;
    1272        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).SupOutTemp = Taplen;
    1273        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).SupOutHumRat = state.dataEnvrn->OutHumRat; // stays the same with sensible heating
    1274        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).SupOutEnth =
    1275        9700 :             PsyHFnTdbW(state.dataTranspiredCollector->UTSC(UTSCNum).SupOutTemp, state.dataTranspiredCollector->UTSC(UTSCNum).SupOutHumRat);
    1276        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).SupOutMassFlow = Mdot;
    1277        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).SensHeatingRate = SensHeatingRate;
    1278        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).SensHeatingEnergy = SensHeatingRate * TimeStepSys * DataGlobalConstants::SecInHour;
    1279        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).PassiveACH = 0.0;
    1280        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).PassiveMdotVent = 0.0;
    1281        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).PassiveMdotWind = 0.0;
    1282        9700 :         state.dataTranspiredCollector->UTSC(UTSCNum).PassiveMdotTherm = 0.0;
    1283        9700 :         if (Isc > 10.0) {
    1284           0 :             state.dataTranspiredCollector->UTSC(UTSCNum).UTSCEfficiency = SensHeatingRate / (Isc * A);
    1285           0 :             if (TaHX > Tamb) {
    1286           0 :                 state.dataTranspiredCollector->UTSC(UTSCNum).UTSCCollEff = Mdot * CpAir * (TaHX - Tamb) / (Isc * A);
    1287             :             } else {
    1288           0 :                 state.dataTranspiredCollector->UTSC(UTSCNum).UTSCCollEff = 0.0;
    1289             :             }
    1290             :         } else {
    1291        9700 :             state.dataTranspiredCollector->UTSC(UTSCNum).UTSCEfficiency = 0.0;
    1292        9700 :             state.dataTranspiredCollector->UTSC(UTSCNum).UTSCCollEff = 0.0;
    1293             :         }
    1294        9700 :     }
    1295             : 
    1296       30975 :     void CalcPassiveTranspiredCollector(EnergyPlusData &state, int const UTSCNum)
    1297             :     {
    1298             : 
    1299             :         // SUBROUTINE INFORMATION:
    1300             :         //       AUTHOR         B.T. Griffith
    1301             :         //       DATE WRITTEN   November 2004
    1302             :         //       MODIFIED       na
    1303             :         //       RE-ENGINEERED  na
    1304             : 
    1305             :         // PURPOSE OF THIS SUBROUTINE:
    1306             :         // model the effect of the a ventilated baffle covering the outside of a heat transfer surface.
    1307             : 
    1308             :         // METHODOLOGY EMPLOYED:
    1309             :         // All the work is done in a subroutine .
    1310             : 
    1311             :         // REFERENCES:
    1312             :         // Nat. Vent. equations from ASHRAE HoF 2001 Chapt. 26
    1313             : 
    1314             :         // Using/Aliasing
    1315             :         using DataSurfaces::SurfaceData;
    1316             :         using Psychrometrics::PsyHFnTdbW;
    1317             :         using Psychrometrics::PsyRhoAirFnPbTdbW;
    1318             :         using Psychrometrics::PsyWFnTdbTwbPb;
    1319             : 
    1320             :         // local working variables
    1321             :         Real64 AspRat; // Aspect Ratio of gap
    1322             :         Real64 TmpTscoll;
    1323             :         Real64 TmpTaPlen;
    1324             :         Real64 RhoAir;
    1325             :         Real64 holeArea;
    1326             :         Real64 Tamb;
    1327             :         Real64 HrPlen;
    1328             :         Real64 HcPlen;
    1329             :         Real64 Isc;
    1330             :         Real64 MdotVent;
    1331             :         Real64 VdotWind;
    1332             :         Real64 VdotThermal;
    1333             :         Real64 Twbamb;
    1334             :         Real64 OutHumRatAmb;
    1335             : 
    1336             :         //        Tamb = sum( Surface( UTSC( UTSCNum ).SurfPtrs ).OutDryBulbTemp * Surface( UTSC( UTSCNum ).SurfPtrs ).Area ) / sum( Surface(
    1337             :         // UTSC( UTSCNum ).SurfPtrs ).Area ); //Autodesk:F2C++ Array subscript usage: Replaced by below
    1338       30975 :         Real64 sum_area = 0.0;
    1339       30975 :         Real64 sum_produc_area_drybulb = 0.0;
    1340       30975 :         Real64 sum_produc_area_wetbulb = 0.0;
    1341       82149 :         for (int SurfNum : state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs) {
    1342       51174 :             sum_area += state.dataSurface->Surface(SurfNum).Area;
    1343       51174 :             sum_produc_area_wetbulb += state.dataSurface->Surface(SurfNum).Area * state.dataSurface->SurfOutWetBulbTemp(SurfNum);
    1344       51174 :             sum_produc_area_drybulb += state.dataSurface->Surface(SurfNum).Area * state.dataSurface->SurfOutDryBulbTemp(SurfNum);
    1345             :         }
    1346       30975 :         Tamb = sum_produc_area_drybulb / sum_area;
    1347       30975 :         Twbamb = sum_produc_area_wetbulb / sum_area;
    1348             : 
    1349       30975 :         OutHumRatAmb = PsyWFnTdbTwbPb(state, Tamb, Twbamb, state.dataEnvrn->OutBaroPress);
    1350             : 
    1351       30975 :         RhoAir = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, Tamb, OutHumRatAmb);
    1352       30975 :         holeArea = state.dataTranspiredCollector->UTSC(UTSCNum).ActualArea * state.dataTranspiredCollector->UTSC(UTSCNum).Porosity;
    1353             : 
    1354       30975 :         AspRat = state.dataTranspiredCollector->UTSC(UTSCNum).Height / state.dataTranspiredCollector->UTSC(UTSCNum).PlenGapThick;
    1355       30975 :         TmpTscoll = state.dataTranspiredCollector->UTSC(UTSCNum).TcollLast;
    1356       30975 :         TmpTaPlen = state.dataTranspiredCollector->UTSC(UTSCNum).TplenLast;
    1357             : 
    1358             :         // all the work is done in this routine located in GeneralRoutines.cc
    1359             : 
    1360      340725 :         CalcPassiveExteriorBaffleGap(state,
    1361       30975 :                                      state.dataTranspiredCollector->UTSC(UTSCNum).SurfPtrs,
    1362             :                                      holeArea,
    1363       30975 :                                      state.dataTranspiredCollector->UTSC(UTSCNum).Cv,
    1364       30975 :                                      state.dataTranspiredCollector->UTSC(UTSCNum).Cd,
    1365       30975 :                                      state.dataTranspiredCollector->UTSC(UTSCNum).HdeltaNPL,
    1366       30975 :                                      state.dataTranspiredCollector->UTSC(UTSCNum).SolAbsorp,
    1367       30975 :                                      state.dataTranspiredCollector->UTSC(UTSCNum).LWEmitt,
    1368       30975 :                                      state.dataTranspiredCollector->UTSC(UTSCNum).Tilt,
    1369             :                                      AspRat,
    1370       30975 :                                      state.dataTranspiredCollector->UTSC(UTSCNum).PlenGapThick,
    1371       30975 :                                      state.dataTranspiredCollector->UTSC(UTSCNum).CollRoughness,
    1372       30975 :                                      state.dataTranspiredCollector->UTSC(UTSCNum).QdotSource,
    1373             :                                      TmpTscoll,
    1374             :                                      TmpTaPlen,
    1375             :                                      HcPlen,
    1376             :                                      HrPlen,
    1377             :                                      Isc,
    1378             :                                      MdotVent,
    1379             :                                      VdotWind,
    1380             :                                      VdotThermal);
    1381             : 
    1382             :         // now fill results into derived types
    1383       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).Isc = Isc;
    1384       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).Tplen = TmpTaPlen;
    1385       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).Tcoll = TmpTscoll;
    1386       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).HrPlen = HrPlen;
    1387       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).HcPlen = HcPlen;
    1388       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).TairHX = Tamb;
    1389       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).InletMDot = 0.0;
    1390       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).InletTempDB = Tamb;
    1391       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).Vsuction = 0.0;
    1392       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).PlenumVelocity = 0.0;
    1393       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).SupOutTemp = TmpTaPlen;
    1394       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).SupOutHumRat = OutHumRatAmb;
    1395       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).SupOutEnth = PsyHFnTdbW(TmpTaPlen, OutHumRatAmb);
    1396       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).SupOutMassFlow = 0.0;
    1397       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).SensHeatingRate = 0.0;
    1398       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).SensHeatingEnergy = 0.0;
    1399       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).PassiveACH =
    1400       61950 :             (MdotVent / RhoAir) *
    1401       61950 :             (1.0 / (state.dataTranspiredCollector->UTSC(UTSCNum).ProjArea * state.dataTranspiredCollector->UTSC(UTSCNum).PlenGapThick)) *
    1402             :             DataGlobalConstants::SecInHour;
    1403       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).PassiveMdotVent = MdotVent;
    1404       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).PassiveMdotWind = VdotWind * RhoAir;
    1405       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).PassiveMdotTherm = VdotThermal * RhoAir;
    1406       30975 :         state.dataTranspiredCollector->UTSC(UTSCNum).UTSCEfficiency = 0.0;
    1407       30975 :     }
    1408             : 
    1409       40675 :     void UpdateTranspiredCollector(EnergyPlusData &state, int const UTSCNum)
    1410             :     {
    1411             : 
    1412             :         // SUBROUTINE INFORMATION:
    1413             :         //       AUTHOR         B.T. Griffith
    1414             :         //       DATE WRITTEN   November 2004
    1415             :         //       MODIFIED       na
    1416             :         //       RE-ENGINEERED  na
    1417             : 
    1418             :         int OutletNode;
    1419             :         int InletNode;
    1420             :         int thisOSCM;
    1421             :         int thisOASys;
    1422             : 
    1423             :         // update "last" values in Derived type
    1424       40675 :         state.dataTranspiredCollector->UTSC(UTSCNum).TplenLast = state.dataTranspiredCollector->UTSC(UTSCNum).Tplen;
    1425       40675 :         state.dataTranspiredCollector->UTSC(UTSCNum).TcollLast = state.dataTranspiredCollector->UTSC(UTSCNum).Tcoll;
    1426             : 
    1427             :         // Set the outlet air nodes of the UTSC
    1428             : 
    1429       40675 :         if (state.dataTranspiredCollector->UTSC(UTSCNum).IsOn) { // Active
    1430        9700 :             if (state.dataTranspiredCollector->UTSC(UTSCNum).NumOASysAttached == 1) {
    1431        6552 :                 OutletNode = state.dataTranspiredCollector->UTSC(UTSCNum).OutletNode(1);
    1432        6552 :                 InletNode = state.dataTranspiredCollector->UTSC(UTSCNum).InletNode(1);
    1433        6552 :                 state.dataLoopNodes->Node(OutletNode).MassFlowRate = state.dataTranspiredCollector->UTSC(UTSCNum).SupOutMassFlow;
    1434        6552 :                 state.dataLoopNodes->Node(OutletNode).Temp = state.dataTranspiredCollector->UTSC(UTSCNum).SupOutTemp;
    1435        6552 :                 state.dataLoopNodes->Node(OutletNode).HumRat = state.dataTranspiredCollector->UTSC(UTSCNum).SupOutHumRat;
    1436        6552 :                 state.dataLoopNodes->Node(OutletNode).Enthalpy = state.dataTranspiredCollector->UTSC(UTSCNum).SupOutEnth;
    1437        3148 :             } else if (state.dataTranspiredCollector->UTSC(UTSCNum).NumOASysAttached > 1) {
    1438       18888 :                 for (thisOASys = 1; thisOASys <= state.dataTranspiredCollector->UTSC(UTSCNum).NumOASysAttached; ++thisOASys) {
    1439       15740 :                     state.dataLoopNodes->Node(state.dataTranspiredCollector->UTSC(UTSCNum).OutletNode(thisOASys)).MassFlowRate =
    1440       15740 :                         state.dataLoopNodes->Node(state.dataTranspiredCollector->UTSC(UTSCNum).InletNode(thisOASys))
    1441       15740 :                             .MassFlowRate; // system gets what it asked for at inlet
    1442       15740 :                     state.dataLoopNodes->Node(state.dataTranspiredCollector->UTSC(UTSCNum).OutletNode(thisOASys)).Temp =
    1443       15740 :                         state.dataTranspiredCollector->UTSC(UTSCNum).SupOutTemp;
    1444       15740 :                     state.dataLoopNodes->Node(state.dataTranspiredCollector->UTSC(UTSCNum).OutletNode(thisOASys)).HumRat =
    1445       15740 :                         state.dataTranspiredCollector->UTSC(UTSCNum).SupOutHumRat;
    1446       15740 :                     state.dataLoopNodes->Node(state.dataTranspiredCollector->UTSC(UTSCNum).OutletNode(thisOASys)).Enthalpy =
    1447       15740 :                         state.dataTranspiredCollector->UTSC(UTSCNum).SupOutEnth;
    1448             :                 }
    1449             :             }
    1450             :         } else { // Passive and/or bypassed           Note Array assignments in following
    1451             :                  // Autodesk:F2C++ Array subscript usage: Replaced by below
    1452             :             //            Node( UTSC( UTSCNum ).OutletNode ).MassFlowRate = Node( UTSC( UTSCNum ).InletNode ).MassFlowRate;
    1453             :             //            Node( UTSC( UTSCNum ).OutletNode ).Temp = Node( UTSC( UTSCNum ).InletNode ).Temp;
    1454             :             //            Node( UTSC( UTSCNum ).OutletNode ).HumRat = Node( UTSC( UTSCNum ).InletNode ).HumRat;
    1455             :             //            Node( UTSC( UTSCNum ).OutletNode ).Enthalpy = Node( UTSC( UTSCNum ).InletNode ).Enthalpy;
    1456       30975 :             auto const &OutletNode(state.dataTranspiredCollector->UTSC(UTSCNum).OutletNode);
    1457       30975 :             auto const &InletNode(state.dataTranspiredCollector->UTSC(UTSCNum).InletNode);
    1458       30975 :             assert(OutletNode.size() == InletNode.size());
    1459      142746 :             for (int io = OutletNode.l(), ii = InletNode.l(), eo = OutletNode.u(); io <= eo; ++io, ++ii) {
    1460      111771 :                 auto &outNode(state.dataLoopNodes->Node(OutletNode(io)));
    1461      111771 :                 auto const &inNode(state.dataLoopNodes->Node(InletNode(ii)));
    1462      111771 :                 outNode.MassFlowRate = inNode.MassFlowRate;
    1463      111771 :                 outNode.Temp = inNode.Temp;
    1464      111771 :                 outNode.HumRat = inNode.HumRat;
    1465      111771 :                 outNode.Enthalpy = inNode.Enthalpy;
    1466             :             }
    1467             :         }
    1468             : 
    1469             :         // update the OtherSideConditionsModel coefficients.
    1470       40675 :         thisOSCM = state.dataTranspiredCollector->UTSC(UTSCNum).OSCMPtr;
    1471             : 
    1472       40675 :         state.dataSurface->OSCM(thisOSCM).TConv = state.dataTranspiredCollector->UTSC(UTSCNum).Tplen;
    1473       40675 :         state.dataSurface->OSCM(thisOSCM).HConv = state.dataTranspiredCollector->UTSC(UTSCNum).HcPlen;
    1474       40675 :         state.dataSurface->OSCM(thisOSCM).TRad = state.dataTranspiredCollector->UTSC(UTSCNum).Tcoll;
    1475       40675 :         state.dataSurface->OSCM(thisOSCM).HRad = state.dataTranspiredCollector->UTSC(UTSCNum).HrPlen;
    1476       40675 :     }
    1477             : 
    1478        8208 :     void SetUTSCQdotSource(EnergyPlusData &state,
    1479             :                            int const UTSCNum,
    1480             :                            Real64 const QSource // source term in Watts
    1481             :     )
    1482             :     {
    1483             : 
    1484             :         // SUBROUTINE INFORMATION:
    1485             :         //       AUTHOR         B. Griffith
    1486             :         //       DATE WRITTEN   November 2004
    1487             :         //       MODIFIED       na
    1488             :         //       RE-ENGINEERED  na
    1489             : 
    1490             :         // PURPOSE OF THIS SUBROUTINE:
    1491             :         // object oriented "Set" routine for updating sink term without exposing variables
    1492             : 
    1493             :         // METHODOLOGY EMPLOYED:
    1494             :         // update derived type with new data , turn power into W/m2
    1495             : 
    1496        8208 :         state.dataTranspiredCollector->UTSC(UTSCNum).QdotSource = QSource / state.dataTranspiredCollector->UTSC(UTSCNum).ProjArea;
    1497        8208 :     }
    1498             : 
    1499           1 :     void GetTranspiredCollectorIndex(EnergyPlusData &state, int const SurfacePtr, int &UTSCIndex)
    1500             :     {
    1501             : 
    1502             :         // SUBROUTINE INFORMATION:
    1503             :         //       AUTHOR         B. Griffith
    1504             :         //       DATE WRITTEN   November 2004
    1505             :         //       MODIFIED       na
    1506             :         //       RE-ENGINEERED  na
    1507             : 
    1508             :         // PURPOSE OF THIS SUBROUTINE:
    1509             :         // object oriented "Get" routine for establishing correct integer index from outside this module
    1510             : 
    1511             :         // METHODOLOGY EMPLOYED:
    1512             :         // mine Surface derived type for correct index/number of surface
    1513             :         // mine UTSC derived type that has the surface.
    1514             : 
    1515             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1516             :         int UTSCNum;  // temporary
    1517             :         int ThisSurf; // temporary
    1518             :         int thisUTSC;
    1519             :         bool Found;
    1520             : 
    1521           1 :         if (state.dataTranspiredCollector->GetInputFlag) {
    1522           1 :             GetTranspiredCollectorInput(state);
    1523           1 :             state.dataTranspiredCollector->GetInputFlag = false;
    1524             :         }
    1525             : 
    1526           1 :         if (SurfacePtr == 0) {
    1527           0 :             ShowFatalError(state,
    1528           0 :                            "Invalid surface passed to GetTranspiredCollectorIndex, Surface name = " + state.dataSurface->Surface(SurfacePtr).Name);
    1529             :         }
    1530             : 
    1531           1 :         UTSCNum = 0;
    1532           1 :         Found = false;
    1533           6 :         for (thisUTSC = 1; thisUTSC <= state.dataTranspiredCollector->NumUTSC; ++thisUTSC) {
    1534          11 :             for (ThisSurf = 1; ThisSurf <= state.dataTranspiredCollector->UTSC(thisUTSC).NumSurfs; ++ThisSurf) {
    1535           6 :                 if (SurfacePtr == state.dataTranspiredCollector->UTSC(thisUTSC).SurfPtrs(ThisSurf)) {
    1536           1 :                     Found = true;
    1537           1 :                     UTSCNum = thisUTSC;
    1538             :                 }
    1539             :             }
    1540             :         }
    1541             : 
    1542           1 :         if (!Found) {
    1543           0 :             ShowFatalError(state,
    1544           0 :                            "Did not find surface in UTSC description in GetTranspiredCollectorIndex, Surface name = " +
    1545           0 :                                state.dataSurface->Surface(SurfacePtr).Name);
    1546             :         } else {
    1547             : 
    1548           1 :             UTSCIndex = UTSCNum;
    1549             :         }
    1550           1 :     }
    1551             : 
    1552           0 :     void GetUTSCTsColl(EnergyPlusData &state, int const UTSCNum, Real64 &TsColl)
    1553             :     {
    1554             : 
    1555             :         // SUBROUTINE INFORMATION:
    1556             :         //       AUTHOR         <author>
    1557             :         //       DATE WRITTEN   <date_written>
    1558             :         //       MODIFIED       na
    1559             :         //       RE-ENGINEERED  na
    1560             : 
    1561             :         // PURPOSE OF THIS SUBROUTINE:
    1562             :         // object oriented "Get" routine for collector surface temperature
    1563             : 
    1564             :         // METHODOLOGY EMPLOYED:
    1565             :         // access derived type
    1566             : 
    1567           0 :         TsColl = state.dataTranspiredCollector->UTSC(UTSCNum).Tcoll;
    1568           0 :     }
    1569             : 
    1570           0 :     int GetAirInletNodeNum(EnergyPlusData &state, std::string const &UTSCName, bool &ErrorsFound)
    1571             :     {
    1572             :         // FUNCTION INFORMATION:
    1573             :         //       AUTHOR         Lixing Gu
    1574             :         //       DATE WRITTEN   May 2019
    1575             :         //       MODIFIED       na
    1576             :         //       RE-ENGINEERED  na
    1577             : 
    1578             :         // PURPOSE OF THIS FUNCTION:
    1579             :         // This function looks up the given UTSC and returns the air inlet node number.
    1580             :         // If incorrect UTSC name is given, ErrorsFound is returned as true and node number as zero.
    1581             : 
    1582             :         // Return value
    1583             :         int NodeNum; // node number returned
    1584             : 
    1585             :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    1586             :         int WhichUTSC;
    1587             : 
    1588           0 :         if (state.dataTranspiredCollector->GetInputFlag) {
    1589           0 :             GetTranspiredCollectorInput(state);
    1590           0 :             state.dataTranspiredCollector->GetInputFlag = false;
    1591             :         }
    1592             : 
    1593           0 :         WhichUTSC = UtilityRoutines::FindItemInList(UTSCName, state.dataTranspiredCollector->UTSC);
    1594           0 :         if (WhichUTSC != 0) {
    1595           0 :             NodeNum = state.dataTranspiredCollector->UTSC(WhichUTSC).InletNode(1);
    1596             :         } else {
    1597           0 :             ShowSevereError(state, "GetAirInletNodeNum: Could not find TranspiredCollector = \"" + UTSCName + "\"");
    1598           0 :             ErrorsFound = true;
    1599           0 :             NodeNum = 0;
    1600             :         }
    1601             : 
    1602           0 :         return NodeNum;
    1603             :     }
    1604             : 
    1605           0 :     int GetAirOutletNodeNum(EnergyPlusData &state, std::string const &UTSCName, bool &ErrorsFound)
    1606             :     {
    1607             :         // FUNCTION INFORMATION:
    1608             :         //       AUTHOR         Lixing Gu
    1609             :         //       DATE WRITTEN   May 2019
    1610             :         //       MODIFIED       na
    1611             :         //       RE-ENGINEERED  na
    1612             : 
    1613             :         // PURPOSE OF THIS FUNCTION:
    1614             :         // This function looks up the given UTSC and returns the air outlet node number.
    1615             :         // If incorrect UTSC name is given, ErrorsFound is returned as true and node number as zero.
    1616             : 
    1617             :         // Return value
    1618             :         int NodeNum; // node number returned
    1619             : 
    1620             :         // FUNCTION LOCAL VARIABLE DECLARATIONS:
    1621             :         int WhichUTSC;
    1622             : 
    1623           0 :         if (state.dataTranspiredCollector->GetInputFlag) {
    1624           0 :             GetTranspiredCollectorInput(state);
    1625           0 :             state.dataTranspiredCollector->GetInputFlag = false;
    1626             :         }
    1627             : 
    1628           0 :         WhichUTSC = UtilityRoutines::FindItemInList(UTSCName, state.dataTranspiredCollector->UTSC);
    1629           0 :         if (WhichUTSC != 0) {
    1630           0 :             NodeNum = state.dataTranspiredCollector->UTSC(WhichUTSC).OutletNode(1);
    1631             :         } else {
    1632           0 :             ShowSevereError(state, "GetAirOutletNodeNum: Could not find TranspiredCollector = \"" + UTSCName + "\"");
    1633           0 :             ErrorsFound = true;
    1634           0 :             NodeNum = 0;
    1635             :         }
    1636             : 
    1637           0 :         return NodeNum;
    1638             :     }
    1639             : 
    1640             : } // namespace TranspiredCollector
    1641             : 
    1642        2313 : } // namespace EnergyPlus

Generated by: LCOV version 1.13