LCOV - code coverage report
Current view: top level - EnergyPlus - EarthTube.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 256 368 69.6 %
Date: 2023-01-17 19:17:23 Functions: 8 8 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/Array.functions.hh>
      53             : #include <ObjexxFCL/Fmath.hh>
      54             : 
      55             : // EnergyPlus Headers
      56             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      57             : #include <EnergyPlus/DataEnvironment.hh>
      58             : #include <EnergyPlus/DataHVACGlobals.hh>
      59             : #include <EnergyPlus/DataHeatBalance.hh>
      60             : #include <EnergyPlus/DataIPShortCuts.hh>
      61             : #include <EnergyPlus/EarthTube.hh>
      62             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      63             : #include <EnergyPlus/OutputProcessor.hh>
      64             : #include <EnergyPlus/Psychrometrics.hh>
      65             : #include <EnergyPlus/ScheduleManager.hh>
      66             : #include <EnergyPlus/UtilityRoutines.hh>
      67             : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
      68             : 
      69             : namespace EnergyPlus::EarthTube {
      70             : // Module containing the data for Earth Tube system
      71             : 
      72             : // MODULE INFORMATION:
      73             : //       AUTHOR         Kwang Ho Lee
      74             : //       DATE WRITTEN   November 2005
      75             : 
      76             : // PURPOSE OF THIS MODULE:
      77             : // To encapsulate the data and algorithyms required to manage the EarthTube System Component
      78             : 
      79             : // REFERENCES:
      80             : // 1. M. Krarti, "Analytical Model to Predict Annual Soil Surface Temperature Variation",
      81             : // Journal of Solar Energy Engineering 117, 1995, pp 91-99
      82             : // 2. K. Labs In: J. Cook, editor, "Passive Cooling",
      83             : // Cambridge Massachusetts, MIT Press, 1989, pp 206-212
      84             : 
      85             : // This is an interesting one.  The actual members of the enum are never explicitly used
      86             : // The enum is used in a getEnumerationValue call to determine what was found in GetInput
      87             : // The value is then used as an array index to lookup thermal conductivity and such from some std::arrays
      88             : // So the IDE thinks these are unused, and I'm not sure the best way to hint that they sorta aren't
      89             : enum class SoilType
      90             : {
      91             :     Invalid = -1,
      92             :     HeavyAndSat,
      93             :     HeavyAndDamp,
      94             :     HeavyAndDry,
      95             :     LightAndDry,
      96             :     Num
      97             : };
      98             : 
      99             : constexpr std::array<std::string_view, static_cast<int>(Ventilation::Num)> ventilationNamesUC = {"NATURAL", "INTAKE", "EXHAUST"};
     100             : constexpr std::array<std::string_view, static_cast<int>(SoilType::Num)> soilTypeNamesUC = {
     101             :     "HEAVYANDSATURATED", "HEAVYANDDAMP", "HEAVYANDDRY", "LIGHTANDDRY"};
     102             : 
     103     3479215 : void ManageEarthTube(EnergyPlusData &state)
     104             : {
     105             : 
     106             :     // SUBROUTINE INFORMATION:
     107             :     //       AUTHOR         Kwang Ho Lee
     108             :     //       DATE WRITTEN   November 2005
     109             : 
     110             :     // PURPOSE OF THIS SUBROUTINE:
     111             :     // This subroutine manages the simulation of EarthTube unit.
     112             :     // This driver manages the calls to all of
     113             :     // the other drivers and simulation algorithms.
     114             : 
     115             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     116     3479215 :     bool ErrorsFound(false);
     117             : 
     118             :     // Obtains and Allocates heat balance related parameters from input file
     119     3479215 :     if (state.dataEarthTube->GetInputFlag) {
     120         739 :         GetEarthTube(state, ErrorsFound);
     121         739 :         state.dataEarthTube->GetInputFlag = false;
     122             :     }
     123             : 
     124     3479215 :     if (state.dataEarthTube->EarthTubeSys.empty()) return;
     125             : 
     126        2106 :     CalcEarthTube(state);
     127             : 
     128        2106 :     ReportEarthTube(state);
     129             : }
     130             : 
     131         739 : void GetEarthTube(EnergyPlusData &state, bool &ErrorsFound) // If errors found in input
     132             : {
     133             : 
     134             :     // SUBROUTINE INFORMATION:
     135             :     //       AUTHOR         Kwang Ho Lee
     136             :     //       DATE WRITTEN   November 2005
     137             : 
     138             :     // PURPOSE OF THIS SUBROUTINE:
     139             :     // This subroutine obtains input data for EarthTube units and
     140             :     // stores it in the EarthTube data structure.
     141             : 
     142             :     // SUBROUTINE PARAMETER DEFINITIONS:
     143         739 :     Real64 constexpr EarthTubeTempLimit(100.0); // degrees Celsius
     144             : 
     145             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     146             :     int NumAlpha;
     147             :     int NumNumber;
     148             :     int IOStat;
     149             :     int Loop;
     150        1478 :     Array1D_bool RepVarSet;
     151             : 
     152         739 :     auto &Zone(state.dataHeatBal->Zone);
     153             : 
     154         739 :     RepVarSet.dimension(state.dataGlobal->NumOfZones, true);
     155             : 
     156             :     // Following used for reporting
     157         739 :     state.dataEarthTube->ZnRptET.allocate(state.dataGlobal->NumOfZones);
     158             : 
     159        1478 :     std::string cCurrentModuleObject = "ZoneEarthtube";
     160         739 :     int TotEarthTube = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     161             : 
     162         739 :     state.dataEarthTube->EarthTubeSys.allocate(TotEarthTube);
     163             : 
     164         742 :     for (Loop = 1; Loop <= TotEarthTube; ++Loop) {
     165           3 :         auto &thisEarthTube = state.dataEarthTube->EarthTubeSys(Loop);
     166          21 :         state.dataInputProcessing->inputProcessor->getObjectItem(state,
     167             :                                                                  cCurrentModuleObject,
     168             :                                                                  Loop,
     169           3 :                                                                  state.dataIPShortCut->cAlphaArgs,
     170             :                                                                  NumAlpha,
     171           3 :                                                                  state.dataIPShortCut->rNumericArgs,
     172             :                                                                  NumNumber,
     173             :                                                                  IOStat,
     174           3 :                                                                  state.dataIPShortCut->lNumericFieldBlanks,
     175           3 :                                                                  state.dataIPShortCut->lAlphaFieldBlanks,
     176           3 :                                                                  state.dataIPShortCut->cAlphaFieldNames,
     177           3 :                                                                  state.dataIPShortCut->cNumericFieldNames);
     178             : 
     179             :         // First Alpha is Zone Name
     180           3 :         thisEarthTube.ZonePtr = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(1), Zone);
     181           3 :         if (thisEarthTube.ZonePtr == 0) {
     182           0 :             ShowSevereError(
     183           0 :                 state, cCurrentModuleObject + ": " + state.dataIPShortCut->cAlphaFieldNames(1) + " not found=" + state.dataIPShortCut->cAlphaArgs(1));
     184           0 :             ErrorsFound = true;
     185             :         }
     186             : 
     187             :         // Second Alpha is Schedule Name
     188           3 :         thisEarthTube.SchedPtr = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(2));
     189           3 :         if (thisEarthTube.SchedPtr == 0) {
     190           0 :             if (state.dataIPShortCut->lAlphaFieldBlanks(2)) {
     191           0 :                 ShowSevereError(state,
     192           0 :                                 cCurrentModuleObject + ": " + state.dataIPShortCut->cAlphaFieldNames(2) + " is required, missing for " +
     193           0 :                                     state.dataIPShortCut->cAlphaFieldNames(1) + '=' + state.dataIPShortCut->cAlphaArgs(1));
     194             :             } else {
     195           0 :                 ShowSevereError(state,
     196           0 :                                 cCurrentModuleObject + ": invalid " + state.dataIPShortCut->cAlphaFieldNames(2) +
     197           0 :                                     " entered=" + state.dataIPShortCut->cAlphaArgs(2) + " for " + state.dataIPShortCut->cAlphaFieldNames(1) + '=' +
     198           0 :                                     state.dataIPShortCut->cAlphaArgs(1));
     199             :             }
     200           0 :             ErrorsFound = true;
     201             :         }
     202             : 
     203             :         // Overall parameters and their limits
     204           3 :         thisEarthTube.DesignLevel = state.dataIPShortCut->rNumericArgs(1);
     205             : 
     206           3 :         thisEarthTube.MinTemperature = state.dataIPShortCut->rNumericArgs(2);
     207           3 :         if ((thisEarthTube.MinTemperature < -EarthTubeTempLimit) || (thisEarthTube.MinTemperature > EarthTubeTempLimit)) {
     208           0 :             ShowSevereError(state,
     209           0 :                             format("{}: {}={} must have a minimum temperature between -{:.0R}C and {:.0R}C",
     210             :                                    cCurrentModuleObject,
     211           0 :                                    state.dataIPShortCut->cAlphaFieldNames(1),
     212           0 :                                    state.dataIPShortCut->cAlphaArgs(1),
     213             :                                    EarthTubeTempLimit,
     214           0 :                                    EarthTubeTempLimit));
     215           0 :             ShowContinueError(state, format("Entered value={:.0R}", thisEarthTube.MinTemperature));
     216           0 :             ErrorsFound = true;
     217             :         }
     218             : 
     219           3 :         thisEarthTube.MaxTemperature = state.dataIPShortCut->rNumericArgs(3);
     220           3 :         if ((thisEarthTube.MaxTemperature < -EarthTubeTempLimit) || (thisEarthTube.MaxTemperature > EarthTubeTempLimit)) {
     221           0 :             ShowSevereError(state,
     222           0 :                             format("{}: {}={} must have a maximum temperature between -{:.0R}C and {:.0R}C",
     223             :                                    cCurrentModuleObject,
     224           0 :                                    state.dataIPShortCut->cAlphaFieldNames(1),
     225           0 :                                    state.dataIPShortCut->cAlphaArgs(1),
     226             :                                    EarthTubeTempLimit,
     227           0 :                                    EarthTubeTempLimit));
     228           0 :             ShowContinueError(state, format("Entered value={:.0R}", thisEarthTube.MaxTemperature));
     229           0 :             ErrorsFound = true;
     230             :         }
     231             : 
     232           3 :         thisEarthTube.DelTemperature = state.dataIPShortCut->rNumericArgs(4); //  3/12/03  Negative del temp now allowed COP
     233             : 
     234             :         // if we have a blank, then just set it to the Natural type, otherwise, search on it
     235           3 :         if (state.dataIPShortCut->cAlphaArgs(3).empty()) {
     236           0 :             thisEarthTube.FanType = Ventilation::Natural;
     237             :         } else {
     238           3 :             thisEarthTube.FanType = static_cast<Ventilation>(getEnumerationValue(ventilationNamesUC, state.dataIPShortCut->cAlphaArgs(3)));
     239           3 :             if (thisEarthTube.FanType == Ventilation::Invalid) {
     240           0 :                 ShowSevereError(state,
     241           0 :                                 cCurrentModuleObject + ": " + state.dataIPShortCut->cAlphaFieldNames(1) + '=' + state.dataIPShortCut->cAlphaArgs(1) +
     242           0 :                                     ", " + state.dataIPShortCut->cAlphaFieldNames(3) + " invalid=" + state.dataIPShortCut->cAlphaArgs(3));
     243           0 :                 ErrorsFound = true;
     244             :             }
     245             :         }
     246             : 
     247           3 :         thisEarthTube.FanPressure = state.dataIPShortCut->rNumericArgs(5);
     248           3 :         if (thisEarthTube.FanPressure < 0.0) {
     249           0 :             ShowSevereError(state,
     250           0 :                             format("{}: {}={}, {} must be positive, entered value={:.2R}",
     251             :                                    cCurrentModuleObject,
     252           0 :                                    state.dataIPShortCut->cAlphaFieldNames(1),
     253           0 :                                    state.dataIPShortCut->cAlphaArgs(1),
     254           0 :                                    state.dataIPShortCut->cNumericFieldNames(5),
     255           0 :                                    thisEarthTube.FanPressure));
     256           0 :             ErrorsFound = true;
     257             :         }
     258             : 
     259           3 :         thisEarthTube.FanEfficiency = state.dataIPShortCut->rNumericArgs(6);
     260           3 :         if ((thisEarthTube.FanEfficiency <= 0.0) || (thisEarthTube.FanEfficiency > 1.0)) {
     261           0 :             ShowSevereError(state,
     262           0 :                             format("{}: {}={}, {} must be greater than zero and less than or equal to one, entered value={:.2R}",
     263             :                                    cCurrentModuleObject,
     264           0 :                                    state.dataIPShortCut->cAlphaFieldNames(1),
     265           0 :                                    state.dataIPShortCut->cAlphaArgs(1),
     266           0 :                                    state.dataIPShortCut->cNumericFieldNames(6),
     267           0 :                                    thisEarthTube.FanEfficiency));
     268           0 :             ErrorsFound = true;
     269             :         }
     270             : 
     271           3 :         thisEarthTube.r1 = state.dataIPShortCut->rNumericArgs(7);
     272           3 :         if (thisEarthTube.r1 <= 0.0) {
     273           0 :             ShowSevereError(state,
     274           0 :                             format("{}: {}={}, {} must be positive, entered value={:.2R}",
     275             :                                    cCurrentModuleObject,
     276           0 :                                    state.dataIPShortCut->cAlphaFieldNames(1),
     277           0 :                                    state.dataIPShortCut->cAlphaArgs(1),
     278           0 :                                    state.dataIPShortCut->cNumericFieldNames(7),
     279           0 :                                    thisEarthTube.r1));
     280           0 :             ErrorsFound = true;
     281             :         }
     282             : 
     283           3 :         thisEarthTube.r2 = state.dataIPShortCut->rNumericArgs(8);
     284           3 :         if (thisEarthTube.r2 <= 0.0) {
     285           0 :             ShowSevereError(state,
     286           0 :                             format("{}: {}={}, {} must be positive, entered value={:.2R}",
     287             :                                    cCurrentModuleObject,
     288           0 :                                    state.dataIPShortCut->cAlphaFieldNames(1),
     289           0 :                                    state.dataIPShortCut->cAlphaArgs(1),
     290           0 :                                    state.dataIPShortCut->cNumericFieldNames(8),
     291           0 :                                    thisEarthTube.r2));
     292           0 :             ErrorsFound = true;
     293             :         }
     294             : 
     295           3 :         thisEarthTube.r3 = 2.0 * thisEarthTube.r1;
     296             : 
     297           3 :         thisEarthTube.PipeLength = state.dataIPShortCut->rNumericArgs(9);
     298           3 :         if (thisEarthTube.PipeLength <= 0.0) {
     299           0 :             ShowSevereError(state,
     300           0 :                             format("{}: {}={}, {} must be positive, entered value={:.2R}",
     301             :                                    cCurrentModuleObject,
     302           0 :                                    state.dataIPShortCut->cAlphaFieldNames(1),
     303           0 :                                    state.dataIPShortCut->cAlphaArgs(1),
     304           0 :                                    state.dataIPShortCut->cNumericFieldNames(9),
     305           0 :                                    thisEarthTube.PipeLength));
     306           0 :             ErrorsFound = true;
     307             :         }
     308             : 
     309           3 :         thisEarthTube.PipeThermCond = state.dataIPShortCut->rNumericArgs(10);
     310           3 :         if (thisEarthTube.PipeThermCond <= 0.0) {
     311           0 :             ShowSevereError(state,
     312           0 :                             format("{}: {}={}, {} must be positive, entered value={:.2R}",
     313             :                                    cCurrentModuleObject,
     314           0 :                                    state.dataIPShortCut->cAlphaFieldNames(1),
     315           0 :                                    state.dataIPShortCut->cAlphaArgs(1),
     316           0 :                                    state.dataIPShortCut->cNumericFieldNames(10),
     317           0 :                                    thisEarthTube.PipeThermCond));
     318           0 :             ErrorsFound = true;
     319             :         }
     320             : 
     321           3 :         thisEarthTube.z = state.dataIPShortCut->rNumericArgs(11);
     322           3 :         if (thisEarthTube.z <= 0.0) {
     323           0 :             ShowSevereError(state,
     324           0 :                             format("{}: {}={}, {} must be positive, entered value={:.2R}",
     325             :                                    cCurrentModuleObject,
     326           0 :                                    state.dataIPShortCut->cAlphaFieldNames(1),
     327           0 :                                    state.dataIPShortCut->cAlphaArgs(1),
     328           0 :                                    state.dataIPShortCut->cNumericFieldNames(11),
     329           0 :                                    thisEarthTube.z));
     330           0 :             ErrorsFound = true;
     331             :         }
     332           3 :         if (thisEarthTube.z <= (thisEarthTube.r1 + thisEarthTube.r2 + thisEarthTube.r3)) {
     333           0 :             ShowSevereError(state,
     334           0 :                             format("{}: {}={}, {} must be greater than 3*{} + {} entered value={:.2R} ref sum={:.2R}",
     335             :                                    cCurrentModuleObject,
     336           0 :                                    state.dataIPShortCut->cAlphaFieldNames(1),
     337           0 :                                    state.dataIPShortCut->cAlphaArgs(1),
     338           0 :                                    state.dataIPShortCut->cNumericFieldNames(11),
     339           0 :                                    state.dataIPShortCut->cNumericFieldNames(7),
     340           0 :                                    state.dataIPShortCut->cNumericFieldNames(8),
     341             :                                    thisEarthTube.z,
     342           0 :                                    thisEarthTube.r1 + thisEarthTube.r2 + thisEarthTube.r3));
     343           0 :             ErrorsFound = true;
     344             :         }
     345             : 
     346           3 :         auto soilType = static_cast<SoilType>(getEnumerationValue(soilTypeNamesUC, state.dataIPShortCut->cAlphaArgs(4)));
     347           3 :         constexpr std::array<Real64, static_cast<int>(SoilType::Num)> thermalDiffusivity = {0.0781056, 0.055728, 0.0445824, 0.024192};
     348           3 :         constexpr std::array<Real64, static_cast<int>(SoilType::Num)> thermalConductivity = {2.42, 1.3, 0.865, 0.346};
     349           3 :         if (soilType == SoilType::Invalid) {
     350           0 :             ShowSevereError(state,
     351           0 :                             cCurrentModuleObject + ": " + state.dataIPShortCut->cAlphaFieldNames(1) + '=' + state.dataIPShortCut->cAlphaArgs(1) +
     352           0 :                                 ", " + state.dataIPShortCut->cAlphaFieldNames(4) + " invalid=" + state.dataIPShortCut->cAlphaArgs(4));
     353           0 :             ErrorsFound = true;
     354             :         } else {
     355           3 :             thisEarthTube.SoilThermDiff = thermalDiffusivity[static_cast<int>(soilType)];
     356           3 :             thisEarthTube.SoilThermCond = thermalConductivity[static_cast<int>(soilType)];
     357             :         }
     358             : 
     359           3 :         thisEarthTube.AverSoilSurTemp = state.dataIPShortCut->rNumericArgs(12);
     360           3 :         thisEarthTube.ApmlSoilSurTemp = state.dataIPShortCut->rNumericArgs(13);
     361           3 :         thisEarthTube.SoilSurPhaseConst = int(state.dataIPShortCut->rNumericArgs(14));
     362             : 
     363             :         // Override any user input for cases where natural ventilation is being used
     364           3 :         if (thisEarthTube.FanType == Ventilation::Natural) {
     365           1 :             thisEarthTube.FanPressure = 0.0;
     366           1 :             thisEarthTube.FanEfficiency = 1.0;
     367             :         }
     368             : 
     369           3 :         thisEarthTube.ConstantTermCoef = state.dataIPShortCut->rNumericArgs(15);
     370           3 :         thisEarthTube.TemperatureTermCoef = state.dataIPShortCut->rNumericArgs(16);
     371           3 :         thisEarthTube.VelocityTermCoef = state.dataIPShortCut->rNumericArgs(17);
     372           3 :         thisEarthTube.VelocitySQTermCoef = state.dataIPShortCut->rNumericArgs(18);
     373             : 
     374           3 :         if (thisEarthTube.ZonePtr > 0) {
     375           3 :             if (RepVarSet(thisEarthTube.ZonePtr)) {
     376           3 :                 RepVarSet(thisEarthTube.ZonePtr) = false;
     377          12 :                 SetupOutputVariable(state,
     378             :                                     "Earth Tube Zone Sensible Cooling Energy",
     379             :                                     OutputProcessor::Unit::J,
     380           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeHeatLoss,
     381             :                                     OutputProcessor::SOVTimeStepType::System,
     382             :                                     OutputProcessor::SOVStoreType::NonState,
     383           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     384          12 :                 SetupOutputVariable(state,
     385             :                                     "Earth Tube Zone Sensible Cooling Rate",
     386             :                                     OutputProcessor::Unit::W,
     387           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeHeatLossRate,
     388             :                                     OutputProcessor::SOVTimeStepType::System,
     389             :                                     OutputProcessor::SOVStoreType::State,
     390           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     391          12 :                 SetupOutputVariable(state,
     392             :                                     "Earth Tube Zone Sensible Heating Energy",
     393             :                                     OutputProcessor::Unit::J,
     394           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeHeatGain,
     395             :                                     OutputProcessor::SOVTimeStepType::System,
     396             :                                     OutputProcessor::SOVStoreType::NonState,
     397           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     398          12 :                 SetupOutputVariable(state,
     399             :                                     "Earth Tube Zone Sensible Heating Rate",
     400             :                                     OutputProcessor::Unit::W,
     401           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeHeatGainRate,
     402             :                                     OutputProcessor::SOVTimeStepType::System,
     403             :                                     OutputProcessor::SOVStoreType::State,
     404           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     405          12 :                 SetupOutputVariable(state,
     406             :                                     "Earth Tube Air Flow Volume",
     407             :                                     OutputProcessor::Unit::m3,
     408           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeVolume,
     409             :                                     OutputProcessor::SOVTimeStepType::System,
     410             :                                     OutputProcessor::SOVStoreType::NonState,
     411           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     412          12 :                 SetupOutputVariable(state,
     413             :                                     "Earth Tube Current Density Air Volume Flow Rate",
     414             :                                     OutputProcessor::Unit::m3_s,
     415           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeVolFlowRate,
     416             :                                     OutputProcessor::SOVTimeStepType::System,
     417             :                                     OutputProcessor::SOVStoreType::State,
     418           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     419          12 :                 SetupOutputVariable(state,
     420             :                                     "Earth Tube Standard Density Air Volume Flow Rate",
     421             :                                     OutputProcessor::Unit::m3_s,
     422           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeVolFlowRateStd,
     423             :                                     OutputProcessor::SOVTimeStepType::System,
     424             :                                     OutputProcessor::SOVStoreType::State,
     425           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     426          12 :                 SetupOutputVariable(state,
     427             :                                     "Earth Tube Air Flow Mass",
     428             :                                     OutputProcessor::Unit::kg,
     429           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeMass,
     430             :                                     OutputProcessor::SOVTimeStepType::System,
     431             :                                     OutputProcessor::SOVStoreType::NonState,
     432           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     433          12 :                 SetupOutputVariable(state,
     434             :                                     "Earth Tube Air Mass Flow Rate",
     435             :                                     OutputProcessor::Unit::kg_s,
     436           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeMassFlowRate,
     437             :                                     OutputProcessor::SOVTimeStepType::System,
     438             :                                     OutputProcessor::SOVStoreType::State,
     439           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     440          12 :                 SetupOutputVariable(state,
     441             :                                     "Earth Tube Water Mass Flow Rate",
     442             :                                     OutputProcessor::Unit::kg_s,
     443           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeWaterMassFlowRate,
     444             :                                     OutputProcessor::SOVTimeStepType::System,
     445             :                                     OutputProcessor::SOVStoreType::State,
     446           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     447          12 :                 SetupOutputVariable(state,
     448             :                                     "Earth Tube Fan Electricity Energy",
     449             :                                     OutputProcessor::Unit::J,
     450           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeFanElec,
     451             :                                     OutputProcessor::SOVTimeStepType::System,
     452             :                                     OutputProcessor::SOVStoreType::NonState,
     453           3 :                                     Zone(thisEarthTube.ZonePtr).Name,
     454             :                                     _,
     455             :                                     "Electricity",
     456             :                                     _,
     457             :                                     _,
     458           3 :                                     "Building");
     459          12 :                 SetupOutputVariable(state,
     460             :                                     "Earth Tube Fan Electricity Rate",
     461             :                                     OutputProcessor::Unit::W,
     462           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeFanElecPower,
     463             :                                     OutputProcessor::SOVTimeStepType::System,
     464             :                                     OutputProcessor::SOVStoreType::State,
     465           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     466          12 :                 SetupOutputVariable(state,
     467             :                                     "Earth Tube Zone Inlet Air Temperature",
     468             :                                     OutputProcessor::Unit::C,
     469           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeAirTemp,
     470             :                                     OutputProcessor::SOVTimeStepType::System,
     471             :                                     OutputProcessor::SOVStoreType::State,
     472           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     473           9 :                 SetupOutputVariable(state,
     474             :                                     "Earth Tube Ground Interface Temperature",
     475             :                                     OutputProcessor::Unit::C,
     476             :                                     thisEarthTube.GroundTempz1z2t,
     477             :                                     OutputProcessor::SOVTimeStepType::System,
     478             :                                     OutputProcessor::SOVStoreType::State,
     479           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     480          12 :                 SetupOutputVariable(state,
     481             :                                     "Earth Tube Outdoor Air Heat Transfer Rate",
     482             :                                     OutputProcessor::Unit::W,
     483           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeOATreatmentPower,
     484             :                                     OutputProcessor::SOVTimeStepType::System,
     485             :                                     OutputProcessor::SOVStoreType::State,
     486           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     487          12 :                 SetupOutputVariable(state,
     488             :                                     "Earth Tube Zone Inlet Wet Bulb Temperature",
     489             :                                     OutputProcessor::Unit::C,
     490           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeWetBulbTemp,
     491             :                                     OutputProcessor::SOVTimeStepType::System,
     492             :                                     OutputProcessor::SOVStoreType::State,
     493           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     494          12 :                 SetupOutputVariable(state,
     495             :                                     "Earth Tube Zone Inlet Humidity Ratio",
     496             :                                     OutputProcessor::Unit::kgWater_kgDryAir,
     497           3 :                                     state.dataEarthTube->ZnRptET(thisEarthTube.ZonePtr).EarthTubeHumRat,
     498             :                                     OutputProcessor::SOVTimeStepType::System,
     499             :                                     OutputProcessor::SOVStoreType::State,
     500           6 :                                     Zone(thisEarthTube.ZonePtr).Name);
     501             :             }
     502             :         }
     503             :     }
     504             : 
     505         739 :     CheckEarthTubesInZones(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound);
     506             : 
     507         739 :     if (ErrorsFound) {
     508           0 :         ShowFatalError(state, cCurrentModuleObject + ": Errors getting input.  Program terminates.");
     509             :     }
     510         739 : }
     511             : 
     512         739 : void CheckEarthTubesInZones(EnergyPlusData &state,
     513             :                             std::string const &ZoneName, // name of zone for error reporting
     514             :                             std::string_view FieldName,  // name of earth tube in input
     515             :                             bool &ErrorsFound            // Found a problem
     516             : )
     517             : {
     518             :     // Check to make sure there is only one earth tube statement per zone
     519         739 :     int numEarthTubes = (int)state.dataEarthTube->EarthTubeSys.size();
     520         741 :     for (int Loop = 1; Loop <= numEarthTubes - 1; ++Loop) {
     521           5 :         for (int Loop1 = Loop + 1; Loop1 <= numEarthTubes; ++Loop1) {
     522           3 :             if (state.dataEarthTube->EarthTubeSys(Loop).ZonePtr == state.dataEarthTube->EarthTubeSys(Loop1).ZonePtr) {
     523           0 :                 ShowSevereError(state, ZoneName + " has more than one " + std::string{FieldName} + " associated with it.");
     524           0 :                 ShowContinueError(state,
     525           0 :                                   "Only one " + std::string{FieldName} + " is allowed per zone.  Check the definitions of " + std::string{FieldName});
     526           0 :                 ShowContinueError(state, "in your input file and make sure that there is only one defined for each zone.");
     527           0 :                 ErrorsFound = true;
     528             :             }
     529             :         }
     530             :     }
     531         739 : }
     532             : 
     533        2106 : void CalcEarthTube(EnergyPlusData &state)
     534             : {
     535             : 
     536             :     // SUBROUTINE INFORMATION:
     537             :     //       AUTHOR         Kwang Ho Lee
     538             :     //       DATE WRITTEN   November 2005
     539             : 
     540             :     // PURPOSE OF THIS SUBROUTINE:
     541             :     // This subroutine simulates the components making up the EarthTube unit.
     542             : 
     543             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     544             :     int Loop;
     545             :     Real64 Process1;        // Variable Used in the Middle of the Calculation
     546             :     Real64 GroundTempz1z2t; // Average Ground Temperature between Depth z1 and z2 at time t
     547             : 
     548             :     Real64 AirThermCond;         // Thermal Conductivity of Air (W/mC)
     549             :     Real64 AirKinemVisco;        // Kinematic Viscosity of Air (m2/s)
     550             :     Real64 AirThermDiffus;       // Thermal Diffusivity of Air (m2/s)
     551             :     Real64 Re;                   // Reynolds Number for Flow Inside Pipe
     552             :     Real64 Pr;                   // Prandtl Number for Flow Inside Pipe
     553             :     Real64 Nu;                   // Nusselt Number for Flow Inside Pipe
     554             :     Real64 fa;                   // Friction Factor of Pipe
     555             :     Real64 PipeHeatTransCoef;    // Convective Heat Transfer Coefficient at Inner Pipe Surface
     556             :     Real64 Rc;                   // Thermal Resistance due to Convection between Air and Pipe Inner Surface
     557             :     Real64 Rp;                   // Thermal Resistance due to Conduction between Pipe Inner and Outer Surface
     558             :     Real64 Rs;                   // Thermal Resistance due to Conduction between Pipe Outer Surface and Soil
     559             :     Real64 Rt;                   // Total Thermal Resistance between Pipe Air and Soil
     560             :     Real64 OverallHeatTransCoef; // Overall Heat Transfer Coefficient of Earth Tube
     561             :     Real64 AverPipeAirVel;       // Average Pipe Air Velocity (m/s)
     562             :     Real64 AirMassFlowRate;      // Actual Mass Flow Rate of Air inside Pipe
     563             :     Real64 AirSpecHeat;          // Specific Heat of Air
     564             :     Real64 AirDensity;           // Density of Air
     565             :     Real64 EVF;
     566             : 
     567        2106 :     int numEarthTubes = (int)state.dataEarthTube->EarthTubeSys.size();
     568        8424 :     for (Loop = 1; Loop <= numEarthTubes; ++Loop) {
     569        6318 :         auto &thisEarthTube = state.dataEarthTube->EarthTubeSys(Loop);
     570        6318 :         int NZ = thisEarthTube.ZonePtr;
     571        6318 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ);
     572        6318 :         thisZoneHB.MCPTE = 0.0;
     573        6318 :         thisZoneHB.MCPE = 0.0;
     574        6318 :         thisZoneHB.EAMFL = 0.0;
     575        6318 :         thisZoneHB.EAMFLxHumRat = 0.0;
     576        6318 :         thisEarthTube.FanPower = 0.0;
     577             : 
     578             :         // Skip this if the zone is below the minimum temperature limit
     579        6318 :         if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ).MAT < thisEarthTube.MinTemperature) continue;
     580             :         // Skip this if the zone is above the maximum temperature limit
     581        6318 :         if (state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ).MAT > thisEarthTube.MaxTemperature) continue;
     582             :         // Skip if below the temperature difference limit
     583        6318 :         if (std::abs(state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ).MAT - state.dataEnvrn->OutDryBulbTemp) < thisEarthTube.DelTemperature)
     584        1492 :             continue;
     585             : 
     586        4826 :         AirDensity =
     587        9652 :             Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
     588        4826 :         AirSpecHeat = Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat);
     589        4826 :         EVF = thisEarthTube.DesignLevel * ScheduleManager::GetCurrentScheduleValue(state, thisEarthTube.SchedPtr);
     590        4826 :         thisZoneHB.MCPE =
     591        9652 :             EVF * AirDensity * AirSpecHeat *
     592        9652 :             (thisEarthTube.ConstantTermCoef +
     593        9652 :              std::abs(state.dataEnvrn->OutDryBulbTemp - state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ).MAT) *
     594        9652 :                  thisEarthTube.TemperatureTermCoef +
     595        4826 :              state.dataEnvrn->WindSpeed * (thisEarthTube.VelocityTermCoef + state.dataEnvrn->WindSpeed * thisEarthTube.VelocitySQTermCoef));
     596             : 
     597        4826 :         thisZoneHB.EAMFL = thisZoneHB.MCPE / AirSpecHeat;
     598        4826 :         if (thisEarthTube.FanEfficiency > 0.0) {
     599        4826 :             thisEarthTube.FanPower = thisZoneHB.EAMFL * thisEarthTube.FanPressure / (thisEarthTube.FanEfficiency * AirDensity);
     600             :         }
     601             : 
     602        4826 :         AverPipeAirVel = EVF / DataGlobalConstants::Pi / pow_2(thisEarthTube.r1);
     603        4826 :         AirMassFlowRate = EVF * AirDensity;
     604             : 
     605             :         // Calculation of Average Ground Temperature between Depth z1 and z2 at time t
     606        9652 :         GroundTempz1z2t = thisEarthTube.AverSoilSurTemp -
     607        9652 :                           thisEarthTube.ApmlSoilSurTemp *
     608        9652 :                               std::exp(-thisEarthTube.z * std::sqrt(DataGlobalConstants::Pi / 365.0 / thisEarthTube.SoilThermDiff)) *
     609        4826 :                               std::cos(2.0 * DataGlobalConstants::Pi / 365.0 *
     610        9652 :                                        (state.dataEnvrn->DayOfYear - thisEarthTube.SoilSurPhaseConst -
     611        4826 :                                         thisEarthTube.z / 2.0 * std::sqrt(365.0 / DataGlobalConstants::Pi / thisEarthTube.SoilThermDiff)));
     612        4826 :         thisEarthTube.GroundTempz1z2t = GroundTempz1z2t;
     613             : 
     614             :         // Calculation of Convective Heat Transfer Coefficient at Inner Pipe Surface
     615        4826 :         AirThermCond = 0.02442 + 0.6992 * state.dataEnvrn->OutDryBulbTemp / 10000.0;
     616        4826 :         AirKinemVisco = (0.1335 + 0.000925 * state.dataEnvrn->OutDryBulbTemp) / 10000.0;
     617        4826 :         AirThermDiffus = (0.0014 * state.dataEnvrn->OutDryBulbTemp + 0.1872) / 10000.0;
     618        4826 :         Re = 2.0 * thisEarthTube.r1 * AverPipeAirVel / AirKinemVisco;
     619        4826 :         Pr = AirKinemVisco / AirThermDiffus;
     620        4826 :         if (Re <= 2300.0) {
     621           0 :             Nu = 3.66;
     622        4826 :         } else if (Re <= 4000.0) {
     623           0 :             fa = std::pow(1.58 * std::log(Re) - 3.28, -2);
     624           0 :             Process1 = (fa / 2.0) * (Re - 1000.0) * Pr / (1.0 + 12.7 * std::sqrt(fa / 2.0) * (std::pow(Pr, 2.0 / 3.0) - 1.0));
     625           0 :             Nu = (Process1 - 3.66) / (1700.0) * Re + (4000.0 * 3.66 - 2300.0 * Process1) / 1700.0;
     626             :         } else {
     627        4826 :             fa = std::pow(1.58 * std::log(Re) - 3.28, -2);
     628        4826 :             Nu = (fa / 2.0) * (Re - 1000.0) * Pr / (1.0 + 12.7 * std::sqrt(fa / 2.0) * (std::pow(Pr, 2.0 / 3.0) - 1.0));
     629             :         }
     630        4826 :         PipeHeatTransCoef = Nu * AirThermCond / 2.0 / thisEarthTube.r1;
     631             : 
     632             :         // Calculation of Thermal Resistance and Overall Heat Transfer Coefficient
     633        4826 :         Rc = 1.0 / 2.0 / DataGlobalConstants::Pi / thisEarthTube.r1 / PipeHeatTransCoef;
     634        4826 :         Rp = std::log((thisEarthTube.r1 + thisEarthTube.r2) / thisEarthTube.r1) / 2.0 / DataGlobalConstants::Pi / thisEarthTube.PipeThermCond;
     635        9652 :         Rs = std::log((thisEarthTube.r1 + thisEarthTube.r2 + thisEarthTube.r3) / (thisEarthTube.r1 + thisEarthTube.r2)) / 2.0 /
     636        4826 :              DataGlobalConstants::Pi / thisEarthTube.SoilThermCond;
     637        4826 :         Rt = Rc + Rp + Rs;
     638        4826 :         OverallHeatTransCoef = 1.0 / Rt;
     639             : 
     640        4826 :         if (AirMassFlowRate * AirSpecHeat == 0.0) {
     641           0 :             thisEarthTube.InsideAirTemp = GroundTempz1z2t;
     642             : 
     643             :         } else {
     644             : 
     645             :             // Calculation of Pipe Outlet Air Temperature
     646        4826 :             if (state.dataEnvrn->OutDryBulbTemp > GroundTempz1z2t) {
     647       14451 :                 Process1 = (std::log(std::abs(state.dataEnvrn->OutDryBulbTemp - GroundTempz1z2t)) * AirMassFlowRate * AirSpecHeat -
     648        4817 :                             OverallHeatTransCoef * thisEarthTube.PipeLength) /
     649        4817 :                            (AirMassFlowRate * AirSpecHeat);
     650        4817 :                 thisEarthTube.InsideAirTemp = std::exp(Process1) + GroundTempz1z2t;
     651           9 :             } else if (state.dataEnvrn->OutDryBulbTemp == GroundTempz1z2t) {
     652           0 :                 thisEarthTube.InsideAirTemp = GroundTempz1z2t;
     653             :             } else {
     654          27 :                 Process1 = (std::log(std::abs(state.dataEnvrn->OutDryBulbTemp - GroundTempz1z2t)) * AirMassFlowRate * AirSpecHeat -
     655           9 :                             OverallHeatTransCoef * thisEarthTube.PipeLength) /
     656           9 :                            (AirMassFlowRate * AirSpecHeat);
     657           9 :                 thisEarthTube.InsideAirTemp = GroundTempz1z2t - std::exp(Process1);
     658             :             }
     659             :         }
     660             : 
     661        4826 :         thisEarthTube.CalcEarthTubeHumRat(state, NZ);
     662             :     }
     663        2106 : }
     664             : 
     665        4826 : void EarthTubeData::CalcEarthTubeHumRat(EnergyPlusData &state, int const NZ)
     666             : { // Zone number (index)
     667             : 
     668             :     // SUBROUTINE INFORMATION:
     669             :     //       AUTHOR         Kwang Ho Lee
     670             :     //       DATE WRITTEN   November 2005
     671             :     //       MODIFIED       Rick Strand, June 2017 (made this a separate subroutine)
     672             : 
     673             :     // PURPOSE OF THIS SUBROUTINE:
     674             :     // This subroutine determines the leaving humidity ratio for the EarthTube
     675             :     // and calculates parameters associated with humidity ratio.
     676             : 
     677        4826 :     Real64 InsideDewPointTemp = Psychrometrics::PsyTdpFnWPb(state, state.dataEnvrn->OutHumRat, state.dataEnvrn->OutBaroPress);
     678        4826 :     Real64 InsideHumRat = 0.0;
     679        4826 :     auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(NZ);
     680             : 
     681        4826 :     if (this->InsideAirTemp >= InsideDewPointTemp) {
     682         617 :         InsideHumRat = state.dataEnvrn->OutHumRat;
     683         617 :         Real64 const InsideEnthalpy = Psychrometrics::PsyHFnTdbW(this->InsideAirTemp, state.dataEnvrn->OutHumRat);
     684             :         // Intake fans will add some heat to the air, raising the temperature for an intake fan...
     685         617 :         if (this->FanType == Ventilation::Intake) {
     686             :             Real64 OutletAirEnthalpy;
     687         205 :             if (thisZoneHB.EAMFL == 0.0) {
     688           0 :                 OutletAirEnthalpy = InsideEnthalpy;
     689             :             } else {
     690         205 :                 OutletAirEnthalpy = InsideEnthalpy + this->FanPower / thisZoneHB.EAMFL;
     691             :             }
     692         205 :             this->AirTemp = Psychrometrics::PsyTdbFnHW(OutletAirEnthalpy, state.dataEnvrn->OutHumRat);
     693             :         } else {
     694         412 :             this->AirTemp = this->InsideAirTemp;
     695             :         }
     696         617 :         thisZoneHB.MCPTE = thisZoneHB.MCPE * this->AirTemp;
     697             : 
     698             :     } else {
     699        4209 :         InsideHumRat = Psychrometrics::PsyWFnTdpPb(state, this->InsideAirTemp, state.dataEnvrn->OutBaroPress);
     700        4209 :         Real64 const InsideEnthalpy = Psychrometrics::PsyHFnTdbW(this->InsideAirTemp, InsideHumRat);
     701             :         // Intake fans will add some heat to the air, raising the temperature for an intake fan...
     702        4209 :         if (this->FanType == Ventilation::Intake) {
     703             :             Real64 OutletAirEnthalpy;
     704        1413 :             if (thisZoneHB.EAMFL == 0.0) {
     705           0 :                 OutletAirEnthalpy = InsideEnthalpy;
     706             :             } else {
     707        1413 :                 OutletAirEnthalpy = InsideEnthalpy + this->FanPower / thisZoneHB.EAMFL;
     708             :             }
     709        1413 :             this->AirTemp = Psychrometrics::PsyTdbFnHW(OutletAirEnthalpy, InsideHumRat);
     710             :         } else {
     711        2796 :             this->AirTemp = this->InsideAirTemp;
     712             :         }
     713        4209 :         thisZoneHB.MCPTE = thisZoneHB.MCPE * this->AirTemp;
     714             :     }
     715             : 
     716        4826 :     this->HumRat = InsideHumRat;
     717        4826 :     this->WetBulbTemp = Psychrometrics::PsyTwbFnTdbWPb(state, this->InsideAirTemp, InsideHumRat, state.dataEnvrn->OutBaroPress);
     718        4826 :     thisZoneHB.EAMFLxHumRat = thisZoneHB.EAMFL * InsideHumRat;
     719        4826 : }
     720             : 
     721        2106 : void ReportEarthTube(EnergyPlusData &state)
     722             : {
     723             : 
     724             :     // SUBROUTINE INFORMATION:
     725             :     //       AUTHOR         Kwang Ho Lee
     726             :     //       DATE WRITTEN   November 2005
     727             :     //       MODIFIED       B. Griffith April 2010 added output reports
     728             : 
     729             :     // PURPOSE OF THIS SUBROUTINE: This subroutine fills remaining report variables.
     730             : 
     731        2106 :     Real64 const ReportingConstant = state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
     732             : 
     733        8424 :     for (int ZoneLoop = 1; ZoneLoop <= state.dataGlobal->NumOfZones; ++ZoneLoop) { // Start of zone loads report variable update loop ...
     734        6318 :         auto &thisZone = state.dataEarthTube->ZnRptET(ZoneLoop);
     735        6318 :         auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneLoop);
     736             : 
     737             :         // Break the infiltration load into heat gain and loss components.
     738             :         Real64 const AirDensity =
     739        6318 :             Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->OutBaroPress, state.dataEnvrn->OutDryBulbTemp, state.dataEnvrn->OutHumRat);
     740        6318 :         Real64 const CpAir = Psychrometrics::PsyCpAirFnW(state.dataEnvrn->OutHumRat);
     741        6318 :         thisZone.EarthTubeVolume = (thisZoneHB.MCPE / CpAir / AirDensity) * ReportingConstant;
     742        6318 :         thisZone.EarthTubeMass = (thisZoneHB.MCPE / CpAir) * ReportingConstant;
     743        6318 :         thisZone.EarthTubeVolFlowRate = thisZoneHB.MCPE / CpAir / AirDensity;
     744        6318 :         thisZone.EarthTubeVolFlowRateStd = thisZoneHB.MCPE / CpAir / state.dataEnvrn->StdRhoAir;
     745        6318 :         thisZone.EarthTubeMassFlowRate = thisZoneHB.MCPE / CpAir;
     746        6318 :         thisZone.EarthTubeWaterMassFlowRate = thisZoneHB.EAMFLxHumRat;
     747             : 
     748        6318 :         thisZone.EarthTubeFanElec = 0.0;
     749        6318 :         thisZone.EarthTubeAirTemp = 0.0;
     750       12636 :         for (auto &thisEarthTube : state.dataEarthTube->EarthTubeSys) {
     751       12636 :             if (thisEarthTube.ZonePtr == ZoneLoop) {
     752        6318 :                 thisZone.EarthTubeFanElec = thisEarthTube.FanPower * ReportingConstant;
     753        6318 :                 thisZone.EarthTubeFanElecPower = thisEarthTube.FanPower;
     754             : 
     755             :                 // Break the EarthTube load into heat gain and loss components.
     756        6318 :                 if (thisZoneHB.ZT > thisEarthTube.AirTemp) {
     757        6318 :                     thisZone.EarthTubeHeatLoss = thisZoneHB.MCPE * (thisZoneHB.ZT - thisEarthTube.AirTemp) * ReportingConstant;
     758        6318 :                     thisZone.EarthTubeHeatLossRate = thisZoneHB.MCPE * (thisZoneHB.ZT - thisEarthTube.AirTemp);
     759        6318 :                     thisZone.EarthTubeHeatGain = 0.0;
     760        6318 :                     thisZone.EarthTubeHeatGainRate = 0.0;
     761           0 :                 } else if (thisZoneHB.ZT <= thisEarthTube.AirTemp) {
     762           0 :                     thisZone.EarthTubeHeatGain = thisZoneHB.MCPE * (thisEarthTube.AirTemp - thisZoneHB.ZT) * ReportingConstant;
     763           0 :                     thisZone.EarthTubeHeatGainRate = thisZoneHB.MCPE * (thisEarthTube.AirTemp - thisZoneHB.ZT);
     764           0 :                     thisZone.EarthTubeHeatLoss = 0.0;
     765           0 :                     thisZone.EarthTubeHeatLossRate = 0.0;
     766             :                 }
     767             : 
     768        6318 :                 thisZone.EarthTubeAirTemp = thisEarthTube.AirTemp;
     769        6318 :                 thisZone.EarthTubeWetBulbTemp = thisEarthTube.WetBulbTemp;
     770        6318 :                 thisZone.EarthTubeHumRat = thisEarthTube.HumRat;
     771        6318 :                 thisZone.EarthTubeOATreatmentPower = thisZoneHB.MCPE * (thisEarthTube.AirTemp - state.dataEnvrn->OutDryBulbTemp);
     772        6318 :                 break; // DO loop
     773             :             }
     774             :         }
     775             : 
     776             :     } // ... end of zone loads report variable update loop.
     777        2106 : }
     778             : 
     779        2313 : } // namespace EnergyPlus::EarthTube

Generated by: LCOV version 1.13