LCOV - code coverage report
Current view: top level - EnergyPlus - ThermalChimney.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 328 492 66.7 %
Date: 2023-01-17 19:17:23 Functions: 7 7 100.0 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
       2             : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3             : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4             : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5             : // contributors. All rights reserved.
       6             : //
       7             : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8             : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9             : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10             : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11             : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12             : //
      13             : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14             : // provided that the following conditions are met:
      15             : //
      16             : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17             : //     conditions and the following disclaimer.
      18             : //
      19             : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20             : //     conditions and the following disclaimer in the documentation and/or other materials
      21             : //     provided with the distribution.
      22             : //
      23             : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24             : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25             : //     used to endorse or promote products derived from this software without specific prior
      26             : //     written permission.
      27             : //
      28             : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29             : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30             : //     reference solely to the software portion of its product, Licensee must refer to the
      31             : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32             : //     obtained under this License and may not use a different name for the software. Except as
      33             : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34             : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35             : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36             : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37             : //
      38             : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39             : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40             : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41             : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42             : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43             : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44             : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45             : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46             : // POSSIBILITY OF SUCH DAMAGE.
      47             : 
      48             : // C++ Headers
      49             : #include <cmath>
      50             : 
      51             : // ObjexxFCL Headers
      52             : #include <ObjexxFCL/Fmath.hh>
      53             : 
      54             : // EnergyPlus Headers
      55             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      56             : #include <EnergyPlus/DataEnvironment.hh>
      57             : #include <EnergyPlus/DataHVACGlobals.hh>
      58             : #include <EnergyPlus/DataHeatBalSurface.hh>
      59             : #include <EnergyPlus/DataHeatBalance.hh>
      60             : #include <EnergyPlus/DataIPShortCuts.hh>
      61             : #include <EnergyPlus/DataSurfaces.hh>
      62             : #include <EnergyPlus/EMSManager.hh>
      63             : #include <EnergyPlus/General.hh>
      64             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      65             : #include <EnergyPlus/OutputProcessor.hh>
      66             : #include <EnergyPlus/Psychrometrics.hh>
      67             : #include <EnergyPlus/ScheduleManager.hh>
      68             : #include <EnergyPlus/ThermalChimney.hh>
      69             : #include <EnergyPlus/UtilityRoutines.hh>
      70             : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      71             : 
      72             : namespace EnergyPlus {
      73             : 
      74             : namespace ThermalChimney {
      75             :     // Module containing the data for Thermal Chimney system
      76             : 
      77             :     // MODULE INFORMATION:
      78             :     //       AUTHOR         Kwang Ho Lee
      79             :     //       DATE WRITTEN   April 2008
      80             :     //       MODIFIED       na
      81             :     //       RE-ENGINEERED  na
      82             : 
      83             :     // PURPOSE OF THIS MODULE:
      84             :     // To encapsulate the data and algorithyms required to manage the ThermalChimney System Component
      85             : 
      86             :     // METHODOLOGY EMPLOYED:
      87             :     // na
      88             : 
      89             :     // REFERENCES:
      90             :     // 1. N. K. Bansal, R. Mathur and M. S. Bhandari, "Solar Chimney for Enhanced Stack Ventilation",
      91             :     // Building and Environment, 28, pp. 373-377, 1993
      92             :     // 2. K. S. Ong, "A Mathematical Model of a Solar Chimney", Renewable Energy, 28, pp. 1047-1060, 2003
      93             :     // 3. J. Marti-Herrero and M. R. Heras-Celemin, "Dynamic Physical Model for a Solar Chimney",
      94             :     // Solar Energy, 81, pp. 614-622, 2007
      95             : 
      96             :     // OTHER NOTES: none
      97             : 
      98             :     // Using/Aliasing
      99             :     using namespace DataEnvironment;
     100             :     using namespace DataHeatBalance;
     101             :     using namespace DataSurfaces;
     102             :     using namespace DataHeatBalSurface;
     103             : 
     104             :     // Use statements for access to subroutines in other modules
     105             :     using namespace Psychrometrics;
     106             : 
     107     3479215 :     void ManageThermalChimney(EnergyPlusData &state)
     108             :     {
     109             : 
     110             :         // SUBROUTINE INFORMATION:
     111             :         //       AUTHOR         Kwang Ho Lee
     112             :         //       DATE WRITTEN   April 2008
     113             :         //       MODIFIED       na
     114             :         //       RE-ENGINEERED  na
     115             : 
     116             :         // PURPOSE OF THIS SUBROUTINE:
     117             :         // This subroutine manages the simulation of ThermalChimney unit.
     118             :         // This driver manages the calls to all of
     119             :         // the other drivers and simulation algorithms.
     120             : 
     121             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     122     3479215 :         bool ErrorsFound(false);
     123             : 
     124             :         // Obtains and Allocates heat balance related parameters from input file
     125     3479215 :         if (state.dataThermalChimneys->ThermalChimneyGetInputFlag) {
     126         739 :             GetThermalChimney(state, ErrorsFound);
     127         739 :             state.dataThermalChimneys->ThermalChimneyGetInputFlag = false;
     128             :         }
     129             : 
     130     3479215 :         if (state.dataThermalChimneys->TotThermalChimney == 0) return;
     131             : 
     132        8279 :         CalcThermalChimney(state);
     133             : 
     134        8279 :         ReportThermalChimney(state);
     135             :     }
     136             : 
     137         739 :     void GetThermalChimney(EnergyPlusData &state, bool &ErrorsFound) // If errors found in input
     138             :     {
     139             : 
     140             :         // SUBROUTINE INFORMATION:
     141             :         //       AUTHOR         Kwang Ho Lee
     142             :         //       DATE WRITTEN   April 2008
     143             :         //       MODIFIED       na
     144             :         //       RE-ENGINEERED  na
     145             : 
     146             :         // PURPOSE OF THIS SUBROUTINE:
     147             :         // This subroutine obtains input data for ThermalChimney units and
     148             :         // stores it in the ThermalChimney data structure.
     149             : 
     150             :         // Using/Aliasing
     151             : 
     152             :         using ScheduleManager::GetScheduleIndex;
     153             : 
     154             :         // SUBROUTINE PARAMETER DEFINITIONS:
     155         739 :         Real64 constexpr FlowFractionTolerance(0.0001); // Smallest deviation from unity for the sum of all fractions
     156             : 
     157             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     158             :         int NumAlpha;
     159             :         int NumNumber;
     160             :         Real64 AllRatiosSummed;
     161             :         int TCZoneNum;  // Thermal chimney zone counter
     162             :         int TCZoneNum1; // Thermal chimney zone counter
     163             :         int IOStat;
     164             :         int Loop;
     165             :         int Loop1;
     166         739 :         auto &cCurrentModuleObject = state.dataIPShortCut->cCurrentModuleObject;
     167             : 
     168             :         // Following used for reporting
     169         739 :         state.dataThermalChimneys->ZnRptThermChim.allocate(state.dataGlobal->NumOfZones);
     170             : 
     171         739 :         cCurrentModuleObject = "ZoneThermalChimney";
     172         739 :         state.dataThermalChimneys->TotThermalChimney = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     173             : 
     174         739 :         state.dataThermalChimneys->ThermalChimneySys.allocate(state.dataThermalChimneys->TotThermalChimney);
     175         739 :         state.dataThermalChimneys->ThermalChimneyReport.allocate(state.dataThermalChimneys->TotThermalChimney);
     176             : 
     177         741 :         for (Loop = 1; Loop <= state.dataThermalChimneys->TotThermalChimney; ++Loop) {
     178             : 
     179          14 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     180             :                                                                      cCurrentModuleObject,
     181             :                                                                      Loop,
     182           2 :                                                                      state.dataIPShortCut->cAlphaArgs,
     183             :                                                                      NumAlpha,
     184           2 :                                                                      state.dataIPShortCut->rNumericArgs,
     185             :                                                                      NumNumber,
     186             :                                                                      IOStat,
     187           2 :                                                                      state.dataIPShortCut->lNumericFieldBlanks,
     188           2 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
     189           2 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
     190           2 :                                                                      state.dataIPShortCut->cNumericFieldNames);
     191           2 :             if (UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound)) {
     192           0 :                 continue;
     193             :             }
     194             : 
     195             :             // First Alpha is Thermal Chimney Name
     196           2 :             state.dataThermalChimneys->ThermalChimneySys(Loop).Name = state.dataIPShortCut->cAlphaArgs(1);
     197             : 
     198             :             // Second Alpha is Zone Name
     199           2 :             state.dataThermalChimneys->ThermalChimneySys(Loop).RealZonePtr =
     200           2 :                 UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(2), state.dataHeatBal->Zone);
     201           2 :             if (state.dataThermalChimneys->ThermalChimneySys(Loop).RealZonePtr == 0) {
     202           0 :                 ShowSevereError(state, cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + " invalid Zone");
     203           0 :                 ShowContinueError(
     204           0 :                     state, "invalid - not found " + state.dataIPShortCut->cAlphaFieldNames(2) + "=\"" + state.dataIPShortCut->cAlphaArgs(2) + "\".");
     205           0 :                 ErrorsFound = true;
     206           2 :             } else if (!state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).RealZonePtr).HasWindow) {
     207           0 :                 ShowSevereError(state, cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + " invalid Zone");
     208           0 :                 ShowContinueError(state,
     209           0 :                                   "...invalid - no window(s) in " + state.dataIPShortCut->cAlphaFieldNames(2) + "=\"" +
     210           0 :                                       state.dataIPShortCut->cAlphaArgs(2) + "\".");
     211           0 :                 ShowContinueError(state, "...thermal chimney zones must have window(s).");
     212           0 :                 ErrorsFound = true;
     213             :             }
     214           2 :             state.dataThermalChimneys->ThermalChimneySys(Loop).RealZoneName = state.dataIPShortCut->cAlphaArgs(2);
     215             : 
     216           2 :             state.dataThermalChimneys->ThermalChimneySys(Loop).SchedName = state.dataIPShortCut->cAlphaArgs(3);
     217           2 :             if (state.dataIPShortCut->lAlphaFieldBlanks(3)) {
     218           0 :                 state.dataThermalChimneys->ThermalChimneySys(Loop).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
     219             :             } else {
     220           2 :                 state.dataThermalChimneys->ThermalChimneySys(Loop).SchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(3));
     221           2 :                 if (state.dataThermalChimneys->ThermalChimneySys(Loop).SchedPtr == 0) {
     222           0 :                     ShowSevereError(state, cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + " invalid data");
     223           0 :                     ShowContinueError(state,
     224           0 :                                       "Invalid-not found " + state.dataIPShortCut->cAlphaFieldNames(3) + "=\"" + state.dataIPShortCut->cAlphaArgs(3) +
     225             :                                           "\".");
     226           0 :                     ErrorsFound = true;
     227             :                 }
     228             :             }
     229             : 
     230           2 :             state.dataThermalChimneys->ThermalChimneySys(Loop).AbsorberWallWidth = state.dataIPShortCut->rNumericArgs(1);
     231           2 :             if (state.dataThermalChimneys->ThermalChimneySys(Loop).AbsorberWallWidth < 0.0) {
     232           0 :                 ShowSevereError(state,
     233           0 :                                 format("{}=\"{} invalid {} must be >= 0, entered value=[{:.2R}].",
     234             :                                        cCurrentModuleObject,
     235           0 :                                        state.dataIPShortCut->cAlphaArgs(1),
     236           0 :                                        state.dataIPShortCut->cNumericFieldNames(1),
     237           0 :                                        state.dataIPShortCut->rNumericArgs(1)));
     238           0 :                 ErrorsFound = true;
     239             :             }
     240             : 
     241           2 :             state.dataThermalChimneys->ThermalChimneySys(Loop).AirOutletCrossArea = state.dataIPShortCut->rNumericArgs(2);
     242           2 :             if (state.dataThermalChimneys->ThermalChimneySys(Loop).AirOutletCrossArea < 0.0) {
     243           0 :                 ShowSevereError(state,
     244           0 :                                 format("{}=\"{} invalid {} must be >= 0, entered value=[{:.2R}].",
     245             :                                        cCurrentModuleObject,
     246           0 :                                        state.dataIPShortCut->cAlphaArgs(1),
     247           0 :                                        state.dataIPShortCut->cNumericFieldNames(2),
     248           0 :                                        state.dataIPShortCut->rNumericArgs(2)));
     249           0 :                 ErrorsFound = true;
     250             :             }
     251             : 
     252           2 :             state.dataThermalChimneys->ThermalChimneySys(Loop).DischargeCoeff = state.dataIPShortCut->rNumericArgs(3);
     253           4 :             if ((state.dataThermalChimneys->ThermalChimneySys(Loop).DischargeCoeff <= 0.0) ||
     254           2 :                 (state.dataThermalChimneys->ThermalChimneySys(Loop).DischargeCoeff > 1.0)) {
     255           0 :                 ShowSevereError(state,
     256           0 :                                 format("{}=\"{} invalid {} must be > 0 and <=1.0, entered value=[{:.2R}].",
     257             :                                        cCurrentModuleObject,
     258           0 :                                        state.dataIPShortCut->cAlphaArgs(1),
     259           0 :                                        state.dataIPShortCut->cNumericFieldNames(3),
     260           0 :                                        state.dataIPShortCut->rNumericArgs(3)));
     261           0 :                 ErrorsFound = true;
     262             :             }
     263             : 
     264           2 :             state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib = NumAlpha - 3;
     265           2 :             state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr.allocate(state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib);
     266           2 :             state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName.allocate(state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib);
     267           4 :             state.dataThermalChimneys->ThermalChimneySys(Loop).DistanceThermChimInlet.allocate(
     268           4 :                 state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib);
     269           4 :             state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow.allocate(
     270           4 :                 state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib);
     271           4 :             state.dataThermalChimneys->ThermalChimneySys(Loop).EachAirInletCrossArea.allocate(
     272           4 :                 state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib);
     273             : 
     274           2 :             AllRatiosSummed = 0.0;
     275           4 :             for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
     276           2 :                 state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName(TCZoneNum) = state.dataIPShortCut->cAlphaArgs(TCZoneNum + 3);
     277           2 :                 state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) =
     278           2 :                     UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(TCZoneNum + 3), state.dataHeatBal->Zone);
     279           2 :                 state.dataThermalChimneys->ThermalChimneySys(Loop).DistanceThermChimInlet(TCZoneNum) =
     280           2 :                     state.dataIPShortCut->rNumericArgs(3 * TCZoneNum + 1);
     281           2 :                 state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) =
     282           2 :                     state.dataIPShortCut->rNumericArgs(3 * TCZoneNum + 2);
     283           2 :                 if (state.dataIPShortCut->lNumericFieldBlanks(3 * TCZoneNum + 2))
     284           0 :                     state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) = 1.0;
     285           2 :                 state.dataThermalChimneys->ThermalChimneySys(Loop).EachAirInletCrossArea(TCZoneNum) =
     286           2 :                     state.dataIPShortCut->rNumericArgs(3 * TCZoneNum + 3);
     287             : 
     288             :                 //!! Error trap for zones that do not exist or zones not in the zone the thermal chimney is in
     289           2 :                 if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) == 0) {
     290           0 :                     ShowSevereError(state,
     291           0 :                                     cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + " invalid " +
     292           0 :                                         state.dataIPShortCut->cAlphaFieldNames(TCZoneNum + 3) + "=\"" +
     293           0 :                                         state.dataIPShortCut->cAlphaArgs(TCZoneNum + 3) + "\" not found.");
     294           0 :                     ErrorsFound = true;
     295           4 :                 } else if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) ==
     296           2 :                            state.dataThermalChimneys->ThermalChimneySys(Loop).RealZonePtr) {
     297           0 :                     ShowSevereError(state,
     298           0 :                                     cCurrentModuleObject + "=\"" + state.dataIPShortCut->cAlphaArgs(1) + " invalid reference " +
     299           0 :                                         state.dataIPShortCut->cAlphaFieldNames(2) + "=\"" + state.dataIPShortCut->cAlphaArgs(2));
     300           0 :                     ShowContinueError(state,
     301           0 :                                       "...must not have same zone as reference= " + state.dataIPShortCut->cAlphaFieldNames(TCZoneNum + 3) + "=\"" +
     302           0 :                                           state.dataIPShortCut->cAlphaArgs(TCZoneNum + 3) + "\".");
     303           0 :                     ErrorsFound = true;
     304             :                 }
     305             : 
     306           2 :                 if (state.dataThermalChimneys->ThermalChimneySys(Loop).DistanceThermChimInlet(TCZoneNum) < 0.0) {
     307           0 :                     ShowSevereError(state,
     308           0 :                                     format("{}=\"{} invalid {} must be >= 0, entered value=[{:.2R}].",
     309             :                                            cCurrentModuleObject,
     310           0 :                                            state.dataIPShortCut->cAlphaArgs(1),
     311           0 :                                            state.dataIPShortCut->cNumericFieldNames(3 * TCZoneNum + 1),
     312           0 :                                            state.dataIPShortCut->rNumericArgs(3 * TCZoneNum + 1)));
     313           0 :                     ErrorsFound = true;
     314             :                 }
     315             : 
     316           4 :                 if ((state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) <= 0.0) ||
     317           2 :                     (state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) > 1.0)) {
     318           0 :                     ShowSevereError(state,
     319           0 :                                     format("{}=\"{} invalid {} must be > 0 and <=1.0, entered value=[{:.2R}].",
     320             :                                            cCurrentModuleObject,
     321           0 :                                            state.dataIPShortCut->cAlphaArgs(1),
     322           0 :                                            state.dataIPShortCut->cNumericFieldNames(3 * TCZoneNum + 2),
     323           0 :                                            state.dataIPShortCut->rNumericArgs(3 * TCZoneNum + 2)));
     324           0 :                     ErrorsFound = true;
     325             :                 }
     326             : 
     327           2 :                 if (state.dataThermalChimneys->ThermalChimneySys(Loop).EachAirInletCrossArea(TCZoneNum) < 0.0) {
     328           0 :                     ShowSevereError(state,
     329           0 :                                     format("{}=\"{} invalid {} must be >= 0, entered value=[{:.2R}].",
     330             :                                            cCurrentModuleObject,
     331           0 :                                            state.dataIPShortCut->cAlphaArgs(1),
     332           0 :                                            state.dataIPShortCut->cNumericFieldNames(3 * TCZoneNum + 3),
     333           0 :                                            state.dataIPShortCut->rNumericArgs(3 * TCZoneNum + 3)));
     334           0 :                     ErrorsFound = true;
     335             :                 }
     336             : 
     337           2 :                 AllRatiosSummed += state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum);
     338             : 
     339             :             } // DO TCZoneNum = 1, ThermalChimneySys(Loop)%TotZoneToDistrib
     340             : 
     341             :             // Error trap if the sum of fractions is not equal to 1.0
     342           2 :             if (std::abs(AllRatiosSummed - 1.0) > FlowFractionTolerance) {
     343           0 :                 ShowSevereError(state,
     344           0 :                                 format("{}=\"{} invalid sum of fractions, must be =1.0, entered value (summed from entries)=[{:.4R}].",
     345             :                                        cCurrentModuleObject,
     346           0 :                                        state.dataIPShortCut->cAlphaArgs(1),
     347           0 :                                        AllRatiosSummed));
     348           0 :                 ErrorsFound = true;
     349             :             }
     350             : 
     351             :         } // DO Loop=1, TotThermalChimney
     352             : 
     353             :         // check infiltration output
     354             :         // setup zone-level infiltration reports
     355        1478 :         Array1D_bool RepVarSet;
     356         739 :         RepVarSet.dimension(state.dataGlobal->NumOfZones, true);
     357        4054 :         for (Loop = 1; Loop <= state.dataHeatBal->TotInfiltration; ++Loop) {
     358        3315 :             int zoneNum = state.dataHeatBal->Infiltration(Loop).ZonePtr;
     359        3315 :             if (zoneNum > 0 && !state.dataHeatBal->Zone(zoneNum).zoneOAQuadratureSum) {
     360        3314 :                 RepVarSet(zoneNum) = false;
     361             :             }
     362             :         }
     363             :         // Set up the output variables for thermal chimneys
     364         741 :         for (Loop = 1; Loop <= state.dataThermalChimneys->TotThermalChimney; ++Loop) {
     365           8 :             SetupOutputVariable(state,
     366             :                                 "Zone Thermal Chimney Current Density Air Volume Flow Rate",
     367             :                                 OutputProcessor::Unit::m3_s,
     368           2 :                                 state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlow,
     369             :                                 OutputProcessor::SOVTimeStepType::System,
     370             :                                 OutputProcessor::SOVStoreType::Average,
     371           4 :                                 state.dataThermalChimneys->ThermalChimneySys(Loop).Name);
     372           8 :             SetupOutputVariable(state,
     373             :                                 "Zone Thermal Chimney Standard Density Air Volume Flow Rate",
     374             :                                 OutputProcessor::Unit::m3_s,
     375           2 :                                 state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlowStd,
     376             :                                 OutputProcessor::SOVTimeStepType::System,
     377             :                                 OutputProcessor::SOVStoreType::Average,
     378           4 :                                 state.dataThermalChimneys->ThermalChimneySys(Loop).Name);
     379           8 :             SetupOutputVariable(state,
     380             :                                 "Zone Thermal Chimney Mass Flow Rate",
     381             :                                 OutputProcessor::Unit::kg_s,
     382           2 :                                 state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCMassFlow,
     383             :                                 OutputProcessor::SOVTimeStepType::System,
     384             :                                 OutputProcessor::SOVStoreType::Average,
     385           4 :                                 state.dataThermalChimneys->ThermalChimneySys(Loop).Name);
     386           8 :             SetupOutputVariable(state,
     387             :                                 "Zone Thermal Chimney Outlet Temperature",
     388             :                                 OutputProcessor::Unit::C,
     389           2 :                                 state.dataThermalChimneys->ThermalChimneyReport(Loop).OutletAirTempThermalChim,
     390             :                                 OutputProcessor::SOVTimeStepType::System,
     391             :                                 OutputProcessor::SOVStoreType::Average,
     392           4 :                                 state.dataThermalChimneys->ThermalChimneySys(Loop).Name);
     393             : 
     394           2 :             if (state.dataGlobal->AnyEnergyManagementSystemInModel) {
     395           0 :                 SetupEMSActuator(state,
     396             :                                  "Zone Thermal Chimney",
     397           0 :                                  state.dataThermalChimneys->ThermalChimneySys(Loop).Name,
     398             :                                  "Air Exchange Flow Rate",
     399             :                                  "[m3/s]",
     400           0 :                                  state.dataThermalChimneys->ThermalChimneySys(Loop).EMSOverrideOn,
     401           0 :                                  state.dataThermalChimneys->ThermalChimneySys(Loop).EMSAirFlowRateValue);
     402             :             }
     403             : 
     404           4 :             for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
     405           8 :                 SetupOutputVariable(state,
     406             :                                     "Zone Thermal Chimney Heat Loss Energy",
     407             :                                     OutputProcessor::Unit::J,
     408           2 :                                     state.dataThermalChimneys->ZnRptThermChim(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum))
     409             :                                         .ThermalChimneyHeatLoss,
     410             :                                     OutputProcessor::SOVTimeStepType::System,
     411             :                                     OutputProcessor::SOVStoreType::Summed,
     412           4 :                                     state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     413           8 :                 SetupOutputVariable(state,
     414             :                                     "Zone Thermal Chimney Heat Gain Energy",
     415             :                                     OutputProcessor::Unit::J,
     416           2 :                                     state.dataThermalChimneys->ZnRptThermChim(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum))
     417             :                                         .ThermalChimneyHeatGain,
     418             :                                     OutputProcessor::SOVTimeStepType::System,
     419             :                                     OutputProcessor::SOVStoreType::Summed,
     420           4 :                                     state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     421           8 :                 SetupOutputVariable(state,
     422             :                                     "Zone Thermal Chimney Volume",
     423             :                                     OutputProcessor::Unit::m3,
     424           2 :                                     state.dataThermalChimneys->ZnRptThermChim(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum))
     425             :                                         .ThermalChimneyVolume,
     426             :                                     OutputProcessor::SOVTimeStepType::System,
     427             :                                     OutputProcessor::SOVStoreType::Summed,
     428           4 :                                     state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     429           8 :                 SetupOutputVariable(state,
     430             :                                     "Zone Thermal Chimney Mass",
     431             :                                     OutputProcessor::Unit::kg,
     432           2 :                                     state.dataThermalChimneys->ZnRptThermChim(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum))
     433             :                                         .ThermalChimneyMass,
     434             :                                     OutputProcessor::SOVTimeStepType::System,
     435             :                                     OutputProcessor::SOVStoreType::Summed,
     436           4 :                                     state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     437           2 :                 if (RepVarSet(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum))) {
     438           0 :                     SetupOutputVariable(
     439             :                         state,
     440             :                         "Zone Infiltration Sensible Heat Loss Energy",
     441             :                         OutputProcessor::Unit::J,
     442           0 :                         state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilHeatLoss,
     443             :                         OutputProcessor::SOVTimeStepType::System,
     444             :                         OutputProcessor::SOVStoreType::Summed,
     445           0 :                         state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     446           0 :                     SetupOutputVariable(
     447             :                         state,
     448             :                         "Zone Infiltration Sensible Heat Gain Energy",
     449             :                         OutputProcessor::Unit::J,
     450           0 :                         state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilHeatGain,
     451             :                         OutputProcessor::SOVTimeStepType::System,
     452             :                         OutputProcessor::SOVStoreType::Summed,
     453           0 :                         state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     454           0 :                     SetupOutputVariable(
     455             :                         state,
     456             :                         "Zone Infiltration Latent Heat Loss Energy",
     457             :                         OutputProcessor::Unit::J,
     458           0 :                         state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilLatentLoss,
     459             :                         OutputProcessor::SOVTimeStepType::System,
     460             :                         OutputProcessor::SOVStoreType::Summed,
     461           0 :                         state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     462           0 :                     SetupOutputVariable(
     463             :                         state,
     464             :                         "Zone Infiltration Latent Heat Gain Energy",
     465             :                         OutputProcessor::Unit::J,
     466           0 :                         state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilLatentGain,
     467             :                         OutputProcessor::SOVTimeStepType::System,
     468             :                         OutputProcessor::SOVStoreType::Summed,
     469           0 :                         state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     470           0 :                     SetupOutputVariable(
     471             :                         state,
     472             :                         "Zone Infiltration Total Heat Loss Energy",
     473             :                         OutputProcessor::Unit::J,
     474           0 :                         state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilTotalLoss,
     475             :                         OutputProcessor::SOVTimeStepType::System,
     476             :                         OutputProcessor::SOVStoreType::Summed,
     477           0 :                         state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     478           0 :                     SetupOutputVariable(
     479             :                         state,
     480             :                         "Zone Infiltration Total Heat Gain Energy",
     481             :                         OutputProcessor::Unit::J,
     482           0 :                         state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilTotalGain,
     483             :                         OutputProcessor::SOVTimeStepType::System,
     484             :                         OutputProcessor::SOVStoreType::Summed,
     485           0 :                         state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     486           0 :                     SetupOutputVariable(
     487             :                         state,
     488             :                         "Zone Infiltration Current Density Volume Flow Rate",
     489             :                         OutputProcessor::Unit::m3_s,
     490           0 :                         state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilVdotCurDensity,
     491             :                         OutputProcessor::SOVTimeStepType::System,
     492             :                         OutputProcessor::SOVStoreType::Average,
     493           0 :                         state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     494           0 :                     SetupOutputVariable(
     495             :                         state,
     496             :                         "Zone Infiltration Standard Density Volume Flow Rate",
     497             :                         OutputProcessor::Unit::m3_s,
     498           0 :                         state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilVdotStdDensity,
     499             :                         OutputProcessor::SOVTimeStepType::System,
     500             :                         OutputProcessor::SOVStoreType::Average,
     501           0 :                         state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     502           0 :                     SetupOutputVariable(
     503             :                         state,
     504             :                         "Zone Infiltration Current Density Volume",
     505             :                         OutputProcessor::Unit::m3,
     506           0 :                         state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilVolumeCurDensity,
     507             :                         OutputProcessor::SOVTimeStepType::System,
     508             :                         OutputProcessor::SOVStoreType::Summed,
     509           0 :                         state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     510           0 :                     SetupOutputVariable(
     511             :                         state,
     512             :                         "Zone Infiltration Standard Density Volume",
     513             :                         OutputProcessor::Unit::m3,
     514           0 :                         state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilVolumeStdDensity,
     515             :                         OutputProcessor::SOVTimeStepType::System,
     516             :                         OutputProcessor::SOVStoreType::Summed,
     517           0 :                         state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     518           0 :                     SetupOutputVariable(state,
     519             :                                         "Zone Infiltration Mass",
     520             :                                         OutputProcessor::Unit::kg,
     521           0 :                                         state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilMass,
     522             :                                         OutputProcessor::SOVTimeStepType::System,
     523             :                                         OutputProcessor::SOVStoreType::Summed,
     524           0 :                                         state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     525           0 :                     SetupOutputVariable(state,
     526             :                                         "Zone Infiltration Mass Flow Rate",
     527             :                                         OutputProcessor::Unit::kg_s,
     528           0 :                                         state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilMdot,
     529             :                                         OutputProcessor::SOVTimeStepType::System,
     530             :                                         OutputProcessor::SOVStoreType::Average,
     531           0 :                                         state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     532           0 :                     SetupOutputVariable(
     533             :                         state,
     534             :                         "Zone Infiltration Air Change Rate",
     535             :                         OutputProcessor::Unit::ach,
     536           0 :                         state.dataHeatBal->ZnAirRpt(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).InfilAirChangeRate,
     537             :                         OutputProcessor::SOVTimeStepType::System,
     538             :                         OutputProcessor::SOVStoreType::Average,
     539           0 :                         state.dataHeatBal->Zone(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)).Name);
     540           0 :                     RepVarSet(state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum)) = false;
     541             :                 }
     542             :             } // DO TCZoneNum = 1, ThermalChimneySys(Loop)%TotZoneToDistrib
     543             :         }     // DO Loop=1, TotThermalChimney
     544             : 
     545             :         //! LKL-more renaming effort and code review might be possible here
     546             :         // Check to make sure there is only one thermal chimney statement per zone
     547         741 :         for (Loop = 1; Loop <= state.dataThermalChimneys->TotThermalChimney; ++Loop) {
     548           2 :             if (state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib > 1) {
     549           0 :                 for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
     550             : 
     551           0 :                     if (state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib >= (TCZoneNum + 1)) {
     552           0 :                         for (TCZoneNum1 = TCZoneNum + 1; TCZoneNum1 <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib;
     553             :                              ++TCZoneNum1) {
     554           0 :                             if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) ==
     555           0 :                                 state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum1)) {
     556           0 :                                 ShowSevereError(state,
     557           0 :                                                 "Only one ZoneThermalChimney object allowed per zone but zone " +
     558           0 :                                                     state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName(TCZoneNum) +
     559             :                                                     " has two ZoneThermalChimney objects associated with it");
     560           0 :                                 ErrorsFound = true;
     561             :                             }
     562             :                         }
     563           0 :                         for (TCZoneNum1 = 1; TCZoneNum1 <= TCZoneNum - 1; ++TCZoneNum1) {
     564           0 :                             if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) ==
     565           0 :                                 state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum1)) {
     566           0 :                                 ShowSevereError(state,
     567           0 :                                                 "Only one ZoneThermalChimney object allowed per zone but zone " +
     568           0 :                                                     state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName(TCZoneNum) +
     569             :                                                     " has two ZoneThermalChimney objects associated with it");
     570           0 :                                 ErrorsFound = true;
     571             :                             }
     572             :                         }
     573             :                     } else { // IF ( ThermalChimneySys(Loop)%TotZoneToDistrib >= (TCZoneNum+1) ) THEN
     574           0 :                         for (TCZoneNum1 = 1; TCZoneNum1 <= TCZoneNum - 1; ++TCZoneNum1) {
     575           0 :                             if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) ==
     576           0 :                                 state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum1)) {
     577           0 :                                 ShowSevereError(state,
     578           0 :                                                 "Only one ZoneThermalChimney object allowed per zone but zone " +
     579           0 :                                                     state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName(TCZoneNum) +
     580             :                                                     " has two ZoneThermalChimney objects associated with it");
     581           0 :                                 ErrorsFound = true;
     582             :                             }
     583             :                         }
     584             :                     } // IF ( ThermalChimneySys(Loop)%TotZoneToDistrib >= (TCZoneNum+1) ) THEN
     585             : 
     586             :                 } // DO TCZoneNum = 1, ThermalChimneySys(Loop)%TotZoneToDistrib
     587             :             }     // IF (ThermalChimneySys(Loop)%TotZoneToDistrib > 1) THEN
     588             :         }         // DO Loop = 1, TotThermalChimney
     589             : 
     590             :         // Check to make sure there is only one thermal chimney statement per zone
     591         739 :         if (state.dataThermalChimneys->TotThermalChimney > 1) {
     592           3 :             for (Loop = 1; Loop <= state.dataThermalChimneys->TotThermalChimney; ++Loop) {
     593             : 
     594           2 :                 if (state.dataThermalChimneys->TotThermalChimney >= (Loop + 1)) {
     595           2 :                     for (Loop1 = Loop + 1; Loop1 <= state.dataThermalChimneys->TotThermalChimney; ++Loop1) {
     596           2 :                         for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
     597           2 :                             for (TCZoneNum1 = 1; TCZoneNum1 <= state.dataThermalChimneys->ThermalChimneySys(Loop1).TotZoneToDistrib; ++TCZoneNum1) {
     598           2 :                                 if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) ==
     599           1 :                                     state.dataThermalChimneys->ThermalChimneySys(Loop1).ZonePtr(TCZoneNum1)) {
     600           0 :                                     ShowSevereError(state,
     601           0 :                                                     "Only one ZoneThermalChimney object allowed per zone but zone " +
     602           0 :                                                         state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName(TCZoneNum) +
     603             :                                                         " has two ZoneThermalChimney objects associated with it");
     604           0 :                                     ErrorsFound = true;
     605             :                                 }
     606             :                             }
     607             :                         }
     608             :                     }
     609           1 :                     for (Loop1 = 1; Loop1 <= Loop - 1; ++Loop1) {
     610           0 :                         for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
     611           0 :                             for (TCZoneNum1 = 1; TCZoneNum1 <= state.dataThermalChimneys->ThermalChimneySys(Loop1).TotZoneToDistrib; ++TCZoneNum1) {
     612           0 :                                 if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) ==
     613           0 :                                     state.dataThermalChimneys->ThermalChimneySys(Loop1).ZonePtr(TCZoneNum1)) {
     614           0 :                                     ShowSevereError(state,
     615           0 :                                                     "Only one ZoneThermalChimney object allowed per zone but zone " +
     616           0 :                                                         state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName(TCZoneNum) +
     617             :                                                         " has two ZoneThermalChimney objects associated with it");
     618           0 :                                     ErrorsFound = true;
     619             :                                 }
     620             :                             }
     621             :                         }
     622             :                     }
     623             :                 } else { // IF ( TotThermalChimney >= (Loop+1) ) THEN
     624           2 :                     for (Loop1 = 1; Loop1 <= Loop - 1; ++Loop1) {
     625           2 :                         for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
     626           2 :                             for (TCZoneNum1 = 1; TCZoneNum1 <= state.dataThermalChimneys->ThermalChimneySys(Loop1).TotZoneToDistrib; ++TCZoneNum1) {
     627           2 :                                 if (state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum) ==
     628           1 :                                     state.dataThermalChimneys->ThermalChimneySys(Loop1).ZonePtr(TCZoneNum1)) {
     629           0 :                                     ShowSevereError(state,
     630           0 :                                                     "Only one ZoneThermalChimney object allowed per zone but zone " +
     631           0 :                                                         state.dataThermalChimneys->ThermalChimneySys(Loop).ZoneName(TCZoneNum) +
     632             :                                                         " has two ZoneThermalChimney objects associated with it");
     633           0 :                                     ErrorsFound = true;
     634             :                                 }
     635             :                             }
     636             :                         }
     637             :                     }
     638             :                 } // IF ( TotThermalChimney >= (Loop+1) ) THEN
     639             : 
     640             :             } // DO Loop = 1, TotThermalChimney
     641             :         }     // IF (TotThermalChimney > 1) THEN
     642             : 
     643         739 :         if (ErrorsFound) {
     644           0 :             ShowFatalError(state, cCurrentModuleObject + " Errors found in input.  Preceding condition(s) cause termination.");
     645             :         }
     646         739 :     }
     647             : 
     648        8279 :     void CalcThermalChimney(EnergyPlusData &state)
     649             :     {
     650             : 
     651             :         // SUBROUTINE INFORMATION:
     652             :         //       AUTHOR         Kwang Ho Lee
     653             :         //       DATE WRITTEN   April 2008
     654             :         //       MODIFIED       na
     655             :         //       RE-ENGINEERED  na
     656             : 
     657             :         // PURPOSE OF THIS SUBROUTINE:
     658             :         // This subroutine simulates the components making up the ThermalChimney.
     659             : 
     660             :         using ScheduleManager::GetCurrentScheduleValue;
     661             : 
     662        8279 :         int constexpr NTC(15); // Number of subregions in thermal chimney air channel for FINITE DIFFERENCE
     663             : 
     664             :         // To be obtained from other modules and subroutines
     665             :         Real64 SurfTempAbsorberWall;     // Absorber wall surface temperature (K)
     666             :         Real64 SurfTempGlassCover;       // Glass cover surface temperature (K)
     667             :         Real64 ConvTransCoeffWallFluid;  // Absorber wall convection trasnfer coefficient
     668             :         Real64 ConvTransCoeffGlassFluid; // Glass cover convection trasnfer coefficient
     669             : 
     670             :         // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     671             :         // Real local vaiables
     672             :         int TCZoneNumCounter;
     673             :         int TCZoneNum;
     674             :         Real64 minorW; // width of enclosure (narrow dimension)
     675             :         Real64 majorW; // width of major surface
     676             :         Real64 TempmajorW;
     677             : 
     678             :         Real64 RoomAirTemp;
     679             :         Real64 AirSpecHeatThermalChim; // (J/kg*C) or (J/kg*K)
     680             :         Real64 AbsorberWallWidthTC;
     681             :         Real64 TCVolumeAirFlowRate; // (m^3/s)
     682             :         Real64 TCMassAirFlowRate;   // (kg/s)
     683             :         Real64 DischargeCoeffTC;
     684             :         Real64 AirOutletCrossAreaTC;
     685             :         Real64 AirInletCrossArea;
     686             :         Real64 AirRelativeCrossArea;
     687             :         // REAL(r64)                    :: OutletAirTempThermalChim
     688             :         Real64 OverallThermalChimLength;
     689             :         Real64 ThermChimTolerance;
     690       16558 :         Array1D<Real64> TempTCMassAirFlowRate(10);   // Temporary Value of Thermal Chimney Mass Flow Rate ()
     691       16558 :         Array1D<Real64> TempTCVolumeAirFlowRate(10); // Temporary Value of Thermal Chimney Volume Flow Rate ()
     692             :         int IterationLoop;
     693             :         Real64 Process1; // Temporary Variable Used in the Middle of the Calculation
     694             :         Real64 Process2; // Temporary Variable Used in the Middle of the Calculation
     695             :         Real64 Process3; // Temporary Variable Used in the Middle of the Calculation
     696             :         // unused1208  REAL(r64)   :: Process4                            ! Temporary Variable Used in the Middle of the Calculation
     697             :         Real64 AirDensityThermalChim; // (kg/m^3)
     698             :         Real64 AirDensity;            // (kg/m^3)
     699             :         Real64 CpAir;
     700             :         Real64 TemporaryWallSurfTemp;
     701             : 
     702             :         Real64 DeltaL; // OverallThermalChimLength / NTC
     703             :         int ThermChimLoop1;
     704             :         int ThermChimLoop2;
     705       16558 :         Array2D<Real64> EquaCoef(NTC, NTC);    // Coefficients in Linear Algebraic Euqation for FINITE DIFFERENCE
     706       16558 :         Array1D<Real64> EquaConst(NTC);        // Constants in Linear Algebraic Equation for FINITE DIFFERENCE
     707       16558 :         Array1D<Real64> ThermChimSubTemp(NTC); // Air temperature of each thermal chimney air channel subregion
     708             : 
     709       24837 :         for (int Loop = 1; Loop <= state.dataThermalChimneys->TotThermalChimney; ++Loop) {
     710             : 
     711       16558 :             int ZoneNum = state.dataThermalChimneys->ThermalChimneySys(Loop).RealZonePtr;
     712       16558 :             auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
     713             :             // start off with first surface in zone widths
     714       16558 :             int firstSpaceHTSurfaceFirst = state.dataHeatBal->space(state.dataHeatBal->Zone(ZoneNum).spaceIndexes(1)).HTSurfaceFirst;
     715       16558 :             majorW = state.dataSurface->Surface(firstSpaceHTSurfaceFirst).Width;
     716       16558 :             minorW = majorW;
     717       16558 :             TempmajorW = 0.0;
     718       16558 :             TemporaryWallSurfTemp = -10000.0;
     719             : 
     720             :             // determine major width and minor width
     721       33116 :             for (int spaceNum : state.dataHeatBal->Zone(ZoneNum).spaceIndexes) {
     722       16558 :                 auto &thisSpace = state.dataHeatBal->space(spaceNum);
     723      149022 :                 for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
     724      132464 :                     if (state.dataSurface->Surface(SurfNum).Class != SurfaceClass::Wall) continue;
     725             : 
     726       82790 :                     if (state.dataSurface->Surface(SurfNum).Width > majorW) {
     727           0 :                         majorW = state.dataSurface->Surface(SurfNum).Width;
     728             :                     }
     729             : 
     730       82790 :                     if (state.dataSurface->Surface(SurfNum).Width < minorW) {
     731       16558 :                         minorW = state.dataSurface->Surface(SurfNum).Width;
     732             :                     }
     733             :                 }
     734             : 
     735      149022 :                 for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
     736      132464 :                     if (state.dataSurface->Surface(SurfNum).Width == majorW) {
     737       66232 :                         if (state.dataHeatBalSurf->SurfTempIn(SurfNum) > TemporaryWallSurfTemp) {
     738       33217 :                             TemporaryWallSurfTemp = state.dataHeatBalSurf->SurfTempIn(SurfNum);
     739       33217 :                             ConvTransCoeffWallFluid = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
     740       33217 :                             SurfTempAbsorberWall = state.dataHeatBalSurf->SurfTempIn(SurfNum) + DataGlobalConstants::KelvinConv;
     741             :                         }
     742             :                     }
     743             :                 }
     744             : 
     745      149022 :                 for (int SurfNum = thisSpace.HTSurfaceFirst; SurfNum <= thisSpace.HTSurfaceLast; ++SurfNum) {
     746      132464 :                     if (state.dataSurface->Surface(SurfNum).Class == SurfaceClass::Window) {
     747       16558 :                         if (state.dataSurface->Surface(SurfNum).Width > TempmajorW) {
     748       16558 :                             TempmajorW = state.dataSurface->Surface(SurfNum).Width;
     749       16558 :                             ConvTransCoeffGlassFluid = state.dataHeatBalSurf->SurfHConvInt(SurfNum);
     750       16558 :                             SurfTempGlassCover = state.dataHeatBalSurf->SurfTempIn(SurfNum) + DataGlobalConstants::KelvinConv;
     751             :                         }
     752             :                     }
     753             :                 }
     754             :             }
     755             : 
     756       16558 :             AbsorberWallWidthTC = majorW;
     757       16558 :             if (state.dataThermalChimneys->ThermalChimneySys(Loop).AbsorberWallWidth != majorW) {
     758       16558 :                 AbsorberWallWidthTC = state.dataThermalChimneys->ThermalChimneySys(Loop).AbsorberWallWidth;
     759             :             }
     760             : 
     761       16558 :             AirDensityThermalChim = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat);
     762       16558 :             AirSpecHeatThermalChim = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat);
     763       16558 :             AirOutletCrossAreaTC = state.dataThermalChimneys->ThermalChimneySys(Loop).AirOutletCrossArea;
     764       16558 :             DischargeCoeffTC = state.dataThermalChimneys->ThermalChimneySys(Loop).DischargeCoeff;
     765             : 
     766       16558 :             AirInletCrossArea = 0.0;
     767       33116 :             for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
     768       16558 :                 AirInletCrossArea += state.dataThermalChimneys->ThermalChimneySys(Loop).EachAirInletCrossArea(TCZoneNum);
     769             :             }
     770             : 
     771       16558 :             RoomAirTemp = 0.0;
     772       33116 :             for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
     773       16558 :                 TCZoneNumCounter = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum);
     774       33116 :                 RoomAirTemp += state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) *
     775       16558 :                                state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter).MAT;
     776             :             }
     777       16558 :             RoomAirTemp += DataGlobalConstants::KelvinConv;
     778             : 
     779       16558 :             Process1 = 0.0;
     780       16558 :             Process2 = 0.0;
     781       33116 :             for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
     782       16558 :                 TCZoneNumCounter = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum);
     783       16558 :                 auto &thisTCZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter);
     784       49674 :                 Process1 += PsyHFnTdbW(thisTCZoneHB.MAT, thisTCZoneHB.ZoneAirHumRat) *
     785       33116 :                             state.dataThermalChimneys->ThermalChimneySys(Loop).DistanceThermChimInlet(TCZoneNum) *
     786       16558 :                             state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum);
     787       33116 :                 Process2 += state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum) *
     788       16558 :                             PsyHFnTdbW(state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter).MAT, thisTCZoneHB.ZoneAirHumRat);
     789             :             }
     790       16558 :             OverallThermalChimLength = Process1 / Process2;
     791             : 
     792       16558 :             DeltaL = OverallThermalChimLength / NTC;
     793             : 
     794             :             // Starting the iteration for mass and volumetric flow rate calculation
     795       16558 :             ThermChimTolerance = 10000000.0; // An impossibly big tolerance
     796      182138 :             for (IterationLoop = 1; IterationLoop <= 10; ++IterationLoop) {
     797             : 
     798      165580 :                 if (IterationLoop == 1) {
     799       16558 :                     TempTCMassAirFlowRate(IterationLoop) = 0.05; // Inital Guess
     800             : 
     801             :                 } else {
     802      149022 :                     TempTCMassAirFlowRate(IterationLoop) = TempTCVolumeAirFlowRate(IterationLoop - 1) * AirDensityThermalChim;
     803             : 
     804      149022 :                     if (std::abs(TempTCMassAirFlowRate(IterationLoop) - TempTCMassAirFlowRate(IterationLoop - 1)) < ThermChimTolerance) {
     805       99712 :                         ThermChimTolerance = std::abs(TempTCMassAirFlowRate(IterationLoop) - TempTCMassAirFlowRate(IterationLoop - 1));
     806       99712 :                         TCMassAirFlowRate = TempTCMassAirFlowRate(IterationLoop);
     807       99712 :                         TCVolumeAirFlowRate = TempTCVolumeAirFlowRate(IterationLoop);
     808             :                     }
     809             : 
     810             :                 } // IF (IterationLoop == 1) THEN
     811             : 
     812             :                 // Calculation of Thermal Chimney Discharge Air Temperature
     813      331160 :                 Process1 = AbsorberWallWidthTC * DeltaL * ConvTransCoeffGlassFluid + AbsorberWallWidthTC * DeltaL * ConvTransCoeffWallFluid -
     814      165580 :                            2.0 * TempTCMassAirFlowRate(IterationLoop) * AirSpecHeatThermalChim;
     815      331160 :                 Process2 = AbsorberWallWidthTC * DeltaL * ConvTransCoeffGlassFluid + AbsorberWallWidthTC * DeltaL * ConvTransCoeffWallFluid +
     816      165580 :                            2.0 * TempTCMassAirFlowRate(IterationLoop) * AirSpecHeatThermalChim;
     817      331160 :                 Process3 = 2.0 * AbsorberWallWidthTC * DeltaL * ConvTransCoeffGlassFluid * SurfTempGlassCover +
     818      165580 :                            2.0 * AbsorberWallWidthTC * DeltaL * ConvTransCoeffWallFluid * SurfTempAbsorberWall;
     819             : 
     820     2649280 :                 for (ThermChimLoop1 = 1; ThermChimLoop1 <= NTC; ++ThermChimLoop1) {
     821    39739200 :                     for (ThermChimLoop2 = 1; ThermChimLoop2 <= NTC; ++ThermChimLoop2) {
     822    37255500 :                         EquaCoef(ThermChimLoop2, ThermChimLoop1) = 0.0;
     823             :                     }
     824             :                 }
     825             : 
     826      165580 :                 EquaCoef(1, 1) = Process2;
     827      165580 :                 EquaConst(1) = Process3 - Process1 * RoomAirTemp;
     828     2483700 :                 for (ThermChimLoop1 = 2; ThermChimLoop1 <= NTC; ++ThermChimLoop1) {
     829     2318120 :                     EquaCoef((ThermChimLoop1 - 1), ThermChimLoop1) = Process1;
     830     2318120 :                     EquaCoef(ThermChimLoop1, ThermChimLoop1) = Process2;
     831     2318120 :                     EquaConst(ThermChimLoop1) = Process3;
     832             :                 }
     833             : 
     834      165580 :                 GaussElimination(EquaCoef, EquaConst, ThermChimSubTemp, NTC);
     835             : 
     836      165580 :                 AirRelativeCrossArea = AirOutletCrossAreaTC / AirInletCrossArea;
     837      165580 :                 if (ThermChimSubTemp(NTC) <= RoomAirTemp) {
     838       49510 :                     TempTCVolumeAirFlowRate(IterationLoop) = 0.0;
     839             :                 } else {
     840      232140 :                     TempTCVolumeAirFlowRate(IterationLoop) = DischargeCoeffTC * AirOutletCrossAreaTC *
     841      232140 :                                                              std::sqrt(2.0 * ((ThermChimSubTemp(NTC) - RoomAirTemp) / RoomAirTemp) * 9.8 *
     842      116070 :                                                                        OverallThermalChimLength / pow_2(1.0 + AirRelativeCrossArea));
     843             :                 }
     844             : 
     845             :             } // DO IterationLoop = 1,10
     846             : 
     847             :             // Calculation of Thermal Chimney Discharge Temperature
     848       33116 :             Process1 = AbsorberWallWidthTC * DeltaL * ConvTransCoeffGlassFluid + AbsorberWallWidthTC * DeltaL * ConvTransCoeffWallFluid -
     849       16558 :                        2.0 * TCMassAirFlowRate * AirSpecHeatThermalChim;
     850       33116 :             Process2 = AbsorberWallWidthTC * DeltaL * ConvTransCoeffGlassFluid + AbsorberWallWidthTC * DeltaL * ConvTransCoeffWallFluid +
     851       16558 :                        2.0 * TCMassAirFlowRate * AirSpecHeatThermalChim;
     852       33116 :             Process3 = 2.0 * AbsorberWallWidthTC * DeltaL * ConvTransCoeffGlassFluid * SurfTempGlassCover +
     853       16558 :                        2.0 * AbsorberWallWidthTC * DeltaL * ConvTransCoeffWallFluid * SurfTempAbsorberWall;
     854             : 
     855      264928 :             for (ThermChimLoop1 = 1; ThermChimLoop1 <= NTC; ++ThermChimLoop1) {
     856     3973920 :                 for (ThermChimLoop2 = 1; ThermChimLoop2 <= NTC; ++ThermChimLoop2) {
     857     3725550 :                     EquaCoef(ThermChimLoop2, ThermChimLoop1) = 0.0;
     858             :                 }
     859             :             }
     860             : 
     861       16558 :             EquaCoef(1, 1) = Process2;
     862       16558 :             EquaConst(1) = Process3 - Process1 * RoomAirTemp;
     863      248370 :             for (ThermChimLoop1 = 2; ThermChimLoop1 <= NTC; ++ThermChimLoop1) {
     864      231812 :                 EquaCoef((ThermChimLoop1 - 1), ThermChimLoop1) = Process1;
     865      231812 :                 EquaCoef(ThermChimLoop1, ThermChimLoop1) = Process2;
     866      231812 :                 EquaConst(ThermChimLoop1) = Process3;
     867             :             }
     868             : 
     869       16558 :             GaussElimination(EquaCoef, EquaConst, ThermChimSubTemp, NTC);
     870             : 
     871       16558 :             AirRelativeCrossArea = AirOutletCrossAreaTC / AirInletCrossArea;
     872       16558 :             if (ThermChimSubTemp(NTC) <= RoomAirTemp) {
     873        4951 :                 TCVolumeAirFlowRate = 0.0;
     874             :             } else {
     875       23214 :                 TCVolumeAirFlowRate = DischargeCoeffTC * AirOutletCrossAreaTC *
     876       23214 :                                       std::sqrt(2.0 * ((ThermChimSubTemp(NTC) - RoomAirTemp) / RoomAirTemp) * 9.8 * OverallThermalChimLength /
     877       11607 :                                                 pow_2(1.0 + AirRelativeCrossArea));
     878       11607 :                 if (state.dataThermalChimneys->ThermalChimneySys(Loop).EMSOverrideOn) {
     879           0 :                     TCVolumeAirFlowRate = state.dataThermalChimneys->ThermalChimneySys(Loop).EMSAirFlowRateValue;
     880             :                 }
     881             :             }
     882             : 
     883             :             // Now assignment of the overall mass flow rate into each zone
     884       33116 :             for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
     885       16558 :                 TCZoneNumCounter = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum);
     886       16558 :                 auto &thisTCZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter);
     887       49674 :                 AirDensity = PsyRhoAirFnPbTdbW(state,
     888       16558 :                                                state.dataEnvrn->OutBaroPress,
     889       16558 :                                                state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter).MAT,
     890       16558 :                                                thisTCZoneHB.ZoneAirHumRat);
     891       16558 :                 CpAir = PsyCpAirFnW(thisTCZoneHB.ZoneAirHumRat);
     892       16558 :                 thisTCZoneHB.MCPThermChim =
     893       16558 :                     TCVolumeAirFlowRate * AirDensity * CpAir * state.dataThermalChimneys->ThermalChimneySys(Loop).RatioThermChimAirFlow(TCZoneNum);
     894       16558 :                 if (thisTCZoneHB.MCPThermChim <= 0.0) {
     895        4951 :                     thisTCZoneHB.MCPThermChim = 0.0;
     896             :                 }
     897       16558 :                 thisTCZoneHB.ThermChimAMFL = thisTCZoneHB.MCPThermChim / CpAir;
     898       16558 :                 thisTCZoneHB.MCPTThermChim = thisTCZoneHB.MCPThermChim * state.dataHeatBal->Zone(TCZoneNumCounter).OutDryBulbTemp;
     899             :             }
     900             : 
     901       16558 :             thisZoneHB.MCPThermChim = TCVolumeAirFlowRate * AirDensity * CpAir;
     902       16558 :             if (thisZoneHB.MCPThermChim <= 0.0) {
     903        4951 :                 thisZoneHB.MCPThermChim = 0.0;
     904             :             }
     905       16558 :             thisZoneHB.ThermChimAMFL = thisZoneHB.MCPThermChim / CpAir;
     906       16558 :             thisZoneHB.MCPTThermChim = thisZoneHB.MCPThermChim * state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp;
     907             : 
     908       16558 :             state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlow = TCVolumeAirFlowRate;
     909       16558 :             state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCMassFlow = TCMassAirFlowRate;
     910       16558 :             state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlowStd = TCMassAirFlowRate / state.dataEnvrn->StdRhoAir;
     911       16558 :             if (state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCMassFlow != (TCVolumeAirFlowRate * AirDensityThermalChim)) {
     912        5335 :                 state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCMassFlow =
     913        5335 :                     state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlow * AirDensityThermalChim;
     914             :             }
     915       16558 :             state.dataThermalChimneys->ThermalChimneyReport(Loop).OutletAirTempThermalChim = ThermChimSubTemp(NTC) - DataGlobalConstants::KelvinConv;
     916             : 
     917       16558 :             if (GetCurrentScheduleValue(state, state.dataThermalChimneys->ThermalChimneySys(Loop).SchedPtr) <= 0.0) {
     918       16558 :                 for (TCZoneNum = 1; TCZoneNum <= state.dataThermalChimneys->ThermalChimneySys(Loop).TotZoneToDistrib; ++TCZoneNum) {
     919        8279 :                     TCZoneNumCounter = state.dataThermalChimneys->ThermalChimneySys(Loop).ZonePtr(TCZoneNum);
     920        8279 :                     auto &thisTCZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(TCZoneNumCounter);
     921        8279 :                     thisTCZoneHB.MCPThermChim = 0.0;
     922        8279 :                     thisTCZoneHB.ThermChimAMFL = 0.0;
     923        8279 :                     thisTCZoneHB.MCPTThermChim = 0.0;
     924             :                 }
     925        8279 :                 thisZoneHB.MCPThermChim = 0.0;
     926        8279 :                 thisZoneHB.ThermChimAMFL = 0.0;
     927        8279 :                 thisZoneHB.MCPTThermChim = 0.0;
     928        8279 :                 state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlow = 0.0;
     929        8279 :                 state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCVolumeFlowStd = 0.0;
     930        8279 :                 state.dataThermalChimneys->ThermalChimneyReport(Loop).OverallTCMassFlow = 0.0;
     931        8279 :                 state.dataThermalChimneys->ThermalChimneyReport(Loop).OutletAirTempThermalChim =
     932        8279 :                     state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
     933             :             }
     934             : 
     935             :         } // DO Loop=1, TotThermalChimney
     936        8279 :     }
     937             : 
     938        8279 :     void ReportThermalChimney(EnergyPlusData &state)
     939             :     {
     940             : 
     941             :         // SUBROUTINE INFORMATION:
     942             :         //       AUTHOR         Kwang Ho Lee
     943             :         //       DATE WRITTEN   April 2008
     944             :         //       MODIFIED       na
     945             :         //       RE-ENGINEERED  na
     946             : 
     947             :         // PURPOSE OF THIS SUBROUTINE:
     948             :         // This subroutine fills remaining report variables.
     949             : 
     950        8279 :         auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys;
     951             : 
     952             :         int ZoneLoop; // Counter for the # of zones (nz)
     953             :         Real64 AirDensity;
     954             :         Real64 CpAir;
     955             :         Real64 TSMult;
     956             : 
     957        8279 :         TSMult = TimeStepSys * DataGlobalConstants::SecInHour;
     958             : 
     959       41395 :         for (ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { // Start of zone loads report variable update loop ...
     960       33116 :             auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop);
     961             : 
     962             :             // Break the infiltration load into heat gain and loss components.
     963       99348 :             AirDensity = PsyRhoAirFnPbTdbW(
     964       99348 :                 state, state.dataEnvrn->OutBaroPress, state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop).MAT, thisZoneHB.ZoneAirHumRat);
     965       33116 :             CpAir = PsyCpAirFnW(thisZoneHB.ZoneAirHumRat);
     966       33116 :             state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyVolume = (thisZoneHB.MCPThermChim / CpAir / AirDensity) * TSMult;
     967       33116 :             state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyMass = (thisZoneHB.MCPThermChim / CpAir) * TSMult;
     968             : 
     969       33116 :             state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatLoss = 0.0;
     970       33116 :             state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatGain = 0.0;
     971             : 
     972       33116 :             if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop).ZT > state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp) {
     973             : 
     974       26167 :                 state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatLoss =
     975       52334 :                     thisZoneHB.MCPThermChim *
     976       52334 :                     (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop).ZT - state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp) * TSMult;
     977       26167 :                 state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatGain = 0.0;
     978             : 
     979        6949 :             } else if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop).ZT <= state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp) {
     980             : 
     981        6949 :                 state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatGain =
     982       13898 :                     thisZoneHB.MCPThermChim *
     983       13898 :                     (state.dataHeatBal->Zone(ZoneLoop).OutDryBulbTemp - state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop).ZT) * TSMult;
     984        6949 :                 state.dataThermalChimneys->ZnRptThermChim(ZoneLoop).ThermalChimneyHeatLoss = 0.0;
     985             :             }
     986             : 
     987             :         } // ... end of zone loads report variable update loop.
     988        8279 :     }
     989             : 
     990      182138 :     void GaussElimination(Array2A<Real64> EquaCoef, Array1D<Real64> &EquaConst, Array1D<Real64> &ThermChimSubTemp, int const NTC)
     991             :     {
     992             :         // PURPOSE OF THIS SUBROUTINE:
     993             :         // This subroutine sovles linear algebraic equations using Gauss Elimination Method.
     994             : 
     995      182138 :         EquaCoef.dim(NTC, NTC);
     996      182138 :         EP_SIZE_CHECK(EquaConst, NTC);
     997      182138 :         EP_SIZE_CHECK(ThermChimSubTemp, NTC);
     998             : 
     999      364276 :         Array1D<Real64> tempor(NTC);
    1000             :         Real64 tempb;
    1001             :         Real64 TCvalue;
    1002             :         Real64 TCcoefficient;
    1003             :         int pivot;
    1004             :         Real64 ThermalChimSum;
    1005             :         int ThermChimLoop1;
    1006             :         int ThermChimLoop2;
    1007             :         int ThermChimLoop3;
    1008             : 
    1009     2914208 :         for (ThermChimLoop1 = 1; ThermChimLoop1 <= NTC; ++ThermChimLoop1) {
    1010             : 
    1011     2732070 :             TCvalue = std::abs(EquaCoef(ThermChimLoop1, ThermChimLoop1));
    1012     2732070 :             pivot = ThermChimLoop1;
    1013    21856560 :             for (ThermChimLoop2 = ThermChimLoop1 + 1; ThermChimLoop2 <= NTC; ++ThermChimLoop2) {
    1014    19124490 :                 if (std::abs(EquaCoef(ThermChimLoop1, ThermChimLoop2)) > TCvalue) {
    1015           0 :                     TCvalue = std::abs(EquaCoef(ThermChimLoop1, ThermChimLoop2));
    1016           0 :                     pivot = ThermChimLoop2;
    1017             :                 }
    1018             :             }
    1019             : 
    1020     2732070 :             if (pivot != ThermChimLoop1) {
    1021           0 :                 tempor({ThermChimLoop1, NTC}) = EquaCoef({ThermChimLoop1, NTC}, ThermChimLoop1);
    1022           0 :                 tempb = EquaConst(ThermChimLoop1);
    1023           0 :                 EquaCoef({ThermChimLoop1, NTC}, ThermChimLoop1) = EquaCoef({ThermChimLoop1, NTC}, pivot);
    1024           0 :                 EquaConst(ThermChimLoop1) = EquaConst(pivot);
    1025           0 :                 EquaCoef({ThermChimLoop1, NTC}, pivot) = tempor({ThermChimLoop1, NTC});
    1026           0 :                 EquaConst(pivot) = tempb;
    1027             :             }
    1028             : 
    1029    21856560 :             for (ThermChimLoop2 = ThermChimLoop1 + 1; ThermChimLoop2 <= NTC; ++ThermChimLoop2) {
    1030    19124490 :                 TCcoefficient = -EquaCoef(ThermChimLoop1, ThermChimLoop2) / EquaCoef(ThermChimLoop1, ThermChimLoop1);
    1031    19124490 :                 EquaCoef({ThermChimLoop1, NTC}, ThermChimLoop2) += TCcoefficient * EquaCoef({ThermChimLoop1, NTC}, ThermChimLoop1);
    1032    19124490 :                 EquaConst(ThermChimLoop2) += TCcoefficient * EquaConst(ThermChimLoop1);
    1033             :             }
    1034             :         }
    1035             : 
    1036      182138 :         ThermChimSubTemp(NTC) = EquaConst(NTC) / EquaCoef(NTC, NTC);
    1037     2732070 :         for (ThermChimLoop2 = NTC - 1; ThermChimLoop2 >= 1; --ThermChimLoop2) {
    1038     2549932 :             ThermalChimSum = 0.0;
    1039    21674422 :             for (ThermChimLoop3 = ThermChimLoop2 + 1; ThermChimLoop3 <= NTC; ++ThermChimLoop3) {
    1040    19124490 :                 ThermalChimSum += EquaCoef(ThermChimLoop3, ThermChimLoop2) * ThermChimSubTemp(ThermChimLoop3);
    1041             :             }
    1042     2549932 :             ThermChimSubTemp(ThermChimLoop2) = (EquaConst(ThermChimLoop2) - ThermalChimSum) / EquaCoef(ThermChimLoop2, ThermChimLoop2);
    1043             :         }
    1044      182138 :     }
    1045             : 
    1046             :     //        End of Module Subroutines for ThermalChimney
    1047             : 
    1048             :     //*****************************************************************************************
    1049             : 
    1050             : } // namespace ThermalChimney
    1051             : 
    1052        2313 : } // namespace EnergyPlus

Generated by: LCOV version 1.13