LCOV - code coverage report
Current view: top level - EnergyPlus - SizingAnalysisObjects.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 330 354 93.2 %
Date: 2024-08-24 18:31:18 Functions: 22 22 100.0 %

          Line data    Source code
       1             : // EnergyPlus, Copyright (c) 1996-2024, 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 <map>
      50             : #include <string>
      51             : #include <vector>
      52             : 
      53             : // EnergyPlus Headers
      54             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      55             : #include <EnergyPlus/DataHVACGlobals.hh>
      56             : #include <EnergyPlus/DataSizing.hh>
      57             : #include <EnergyPlus/General.hh>
      58             : #include <EnergyPlus/OutputProcessor.hh>
      59             : #include <EnergyPlus/OutputReportPredefined.hh>
      60             : #include <EnergyPlus/Plant/DataPlant.hh>
      61             : #include <EnergyPlus/SizingAnalysisObjects.hh>
      62             : #include <EnergyPlus/UtilityRoutines.hh>
      63             : #include <EnergyPlus/WeatherManager.hh>
      64             : 
      65             : namespace EnergyPlus {
      66             : 
      67       32801 : ZoneTimestepObject::ZoneTimestepObject()
      68             : {
      69       32801 :     kindOfSim = Constant::KindOfSim::Invalid;
      70       32801 :     envrnNum = 0;
      71       32801 :     dayOfSim = 0;
      72       32801 :     hourOfDay = 0;
      73       32801 :     ztStepsIntoPeriod = 0;
      74       32801 :     stepStartMinute = 0.0;
      75       32801 :     stepEndMinute = 0.0;
      76       32801 :     timeStepDuration = 0.0;
      77       32801 : }
      78             : 
      79       13867 : ZoneTimestepObject::ZoneTimestepObject(
      80             :     Constant::KindOfSim kindSim, // kind of simulation
      81             :     int environmentNum,          // index in Environment data structure, usually Weather::Envrn
      82             :     int daySim,                  // days into simulation period, usually DataGlobals::DayOfSim
      83             :     int hourDay,                 // hour into day, 1-24, filled by DataGlobals::HourOfDay
      84             :     int timeStep,                // time steps into hour, filled by DataGlobals::TimeStep
      85             :     Real64 timeStepDurat,        // duration of timestep in fractional hours, usually OutputProcessor::TimeValue( ZoneIndex ).TimeStep
      86             :     int numOfTimeStepsPerHour    // timesteps in each hour, usually DataGlobals::NumOfTimeStepInHour
      87       13867 :     )
      88       13867 :     : kindOfSim(kindSim), envrnNum(environmentNum), dayOfSim(daySim), hourOfDay(hourDay),
      89             : 
      90       13867 :       timeStepDuration(timeStepDurat)
      91             : {
      92       13867 :     Real64 constexpr minutesPerHour(60.0);
      93       13867 :     int constexpr hoursPerDay(24);
      94             : 
      95       13867 :     stepEndMinute = timeStepDuration * minutesPerHour + (timeStep - 1) * timeStepDuration * minutesPerHour;
      96             : 
      97       13867 :     stepStartMinute = stepEndMinute - timeStepDuration * minutesPerHour;
      98             : 
      99       13867 :     if (stepStartMinute < 0.0) {
     100           0 :         stepStartMinute = 0.0;
     101           0 :         stepEndMinute = timeStepDuration * minutesPerHour;
     102             :     }
     103             : 
     104       13867 :     ztStepsIntoPeriod = ((dayOfSim - 1) * (hoursPerDay * numOfTimeStepsPerHour)) +      // multiple days
     105       13867 :                         ((hourOfDay - 1) * numOfTimeStepsPerHour) +                     // so far this day's hours
     106       13867 :                         round((stepStartMinute / minutesPerHour) / (timeStepDuration)); // into current hour
     107             : 
     108       13867 :     if (ztStepsIntoPeriod < 0) ztStepsIntoPeriod = 0;
     109             : 
     110             :     // We only expect this feature to be used with systems, so there will always be a system timestep update, at least one.
     111       13867 :     hasSystemSubSteps = true;
     112       13867 :     numSubSteps = 1;
     113       13867 :     subSteps.resize(numSubSteps);
     114       13867 : }
     115             : 
     116          78 : SizingLog::SizingLog(double &rVariable) : p_rVariable(rVariable)
     117             : {
     118          78 : }
     119             : 
     120       82038 : int SizingLog::GetZtStepIndex(const ZoneTimestepObject tmpztStepStamp)
     121             : {
     122             : 
     123             :     int vecIndex;
     124             : 
     125       82038 :     if (tmpztStepStamp.ztStepsIntoPeriod > 0) { // discard any negative value for safety
     126       80970 :         vecIndex = envrnStartZtStepIndexMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]] + tmpztStepStamp.ztStepsIntoPeriod;
     127             :     } else {
     128        1068 :         vecIndex = envrnStartZtStepIndexMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]];
     129             :     }
     130             : 
     131             :     // next for safety sake, constrain index to lie inside correct envronment
     132       82038 :     if (vecIndex < envrnStartZtStepIndexMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]]) {
     133           0 :         vecIndex = envrnStartZtStepIndexMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]]; // first step in environment
     134             :     }
     135       82038 :     if (vecIndex > (envrnStartZtStepIndexMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]] +
     136       82038 :                     ztStepCountByEnvrnMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]])) {
     137           0 :         vecIndex = envrnStartZtStepIndexMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]] +
     138           0 :                    ztStepCountByEnvrnMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]]; // last step in environment
     139             :     }
     140       82038 :     return vecIndex;
     141             : }
     142             : 
     143       27360 : void SizingLog::FillZoneStep(ZoneTimestepObject tmpztStepStamp)
     144             : {
     145       27360 :     int index = GetZtStepIndex(tmpztStepStamp);
     146             : 
     147       27360 :     ztStepObj[index].kindOfSim = tmpztStepStamp.kindOfSim;
     148       27360 :     ztStepObj[index].envrnNum = tmpztStepStamp.envrnNum;
     149       27360 :     ztStepObj[index].dayOfSim = tmpztStepStamp.dayOfSim;
     150       27360 :     ztStepObj[index].hourOfDay = tmpztStepStamp.hourOfDay;
     151       27360 :     ztStepObj[index].ztStepsIntoPeriod = tmpztStepStamp.ztStepsIntoPeriod;
     152       27360 :     ztStepObj[index].stepStartMinute = tmpztStepStamp.stepStartMinute;
     153       27360 :     ztStepObj[index].stepEndMinute = tmpztStepStamp.stepEndMinute;
     154       27360 :     ztStepObj[index].timeStepDuration = tmpztStepStamp.timeStepDuration;
     155             : 
     156       27360 :     ztStepObj[index].logDataValue = p_rVariable;
     157       27360 : }
     158             : 
     159       54534 : int SizingLog::GetSysStepZtStepIndex(ZoneTimestepObject tmpztStepStamp)
     160             : {
     161             :     // this method finds a zone timestep for the system timestep update to use
     162             :     // system timesteps are substeps inside a zone timestep, but are updated
     163             :     // before the zone step has been called.
     164             :     // the zone timestamp passed in is now accurate, not lagged, so this is simpler
     165             : 
     166       54534 :     int znStepIndex = GetZtStepIndex(tmpztStepStamp);
     167             : 
     168             :     // safety checks for range
     169       54534 :     if (znStepIndex >= NumOfStepsInLogSet) znStepIndex = NumOfStepsInLogSet - 1;
     170       54534 :     if (znStepIndex < 0) znStepIndex = 0;
     171             : 
     172       54534 :     return znStepIndex;
     173             : }
     174             : 
     175       54534 : void SizingLog::FillSysStep(ZoneTimestepObject tmpztStepStamp, SystemTimestepObject tmpSysStepStamp)
     176             : {
     177             : 
     178       54534 :     int ztIndex(0);
     179       54534 :     int oldNumSubSteps(0);
     180       54534 :     int newNumSubSteps(0);
     181       54534 :     Real64 constexpr MinutesPerHour(60.0);
     182       54534 :     Real64 ZoneStepStartMinutes(0.0);
     183             : 
     184       54534 :     ztIndex = GetSysStepZtStepIndex(tmpztStepStamp);
     185             : 
     186       54534 :     if (ztStepObj[ztIndex].hasSystemSubSteps) {
     187             : 
     188       27174 :         oldNumSubSteps = ztStepObj[ztIndex].numSubSteps;
     189       27174 :         newNumSubSteps = round(tmpztStepStamp.timeStepDuration / tmpSysStepStamp.TimeStepDuration);
     190       27174 :         if (newNumSubSteps != oldNumSubSteps) {
     191           0 :             ztStepObj[ztIndex].subSteps.resize(newNumSubSteps);
     192           0 :             ztStepObj[ztIndex].numSubSteps = newNumSubSteps;
     193             :         }
     194             :     } else {
     195       27360 :         newNumSubSteps = round(tmpztStepStamp.timeStepDuration / tmpSysStepStamp.TimeStepDuration);
     196       27360 :         ztStepObj[ztIndex].subSteps.resize(newNumSubSteps);
     197       27360 :         ztStepObj[ztIndex].numSubSteps = newNumSubSteps;
     198       27360 :         ztStepObj[ztIndex].hasSystemSubSteps = true;
     199             :     }
     200             : 
     201             :     // figure out which index this substep needs to go into
     202       54534 :     ZoneStepStartMinutes = tmpztStepStamp.stepStartMinute;
     203             : 
     204       54534 :     tmpSysStepStamp.stStepsIntoZoneStep =
     205       54534 :         round((((tmpSysStepStamp.CurMinuteStart - ZoneStepStartMinutes) / MinutesPerHour) / tmpSysStepStamp.TimeStepDuration));
     206             : 
     207       54534 :     if ((tmpSysStepStamp.stStepsIntoZoneStep >= 0) && (tmpSysStepStamp.stStepsIntoZoneStep < ztStepObj[ztIndex].numSubSteps)) {
     208       54534 :         ztStepObj[ztIndex].subSteps[tmpSysStepStamp.stStepsIntoZoneStep] = tmpSysStepStamp;
     209       54534 :         ztStepObj[ztIndex].subSteps[tmpSysStepStamp.stStepsIntoZoneStep].LogDataValue = p_rVariable;
     210             :     } else {
     211           0 :         ztStepObj[ztIndex].subSteps[0] = tmpSysStepStamp;
     212           0 :         ztStepObj[ztIndex].subSteps[0].LogDataValue = p_rVariable;
     213             :     }
     214       54534 : }
     215             : 
     216         108 : void SizingLog::AverageSysTimeSteps()
     217             : {
     218             :     Real64 RunningSum;
     219             : 
     220       27468 :     for (auto &zt : ztStepObj) {
     221       27360 :         if (zt.numSubSteps > 0) {
     222       27360 :             RunningSum = 0.0;
     223       81894 :             for (auto &SysT : zt.subSteps) {
     224       54534 :                 RunningSum += SysT.LogDataValue;
     225       27360 :             }
     226       27360 :             zt.logDataValue = RunningSum / double(zt.numSubSteps);
     227             :         }
     228         108 :     }
     229         108 : }
     230             : 
     231         108 : void SizingLog::ProcessRunningAverage()
     232             : {
     233         108 :     Real64 RunningSum = 0.0;
     234         108 :     Real64 divisor = double(timeStepsInAverage);
     235             : 
     236         108 :     std::map<int, int>::iterator end = ztStepCountByEnvrnMap.end();
     237         324 :     for (std::map<int, int>::iterator itr = ztStepCountByEnvrnMap.begin(); itr != end; ++itr) {
     238       27576 :         for (int i = 0; i < itr->second; ++i) { // next inner loop over zone timestep steps
     239             : 
     240       27360 :             if (timeStepsInAverage > 0) {
     241       27360 :                 RunningSum = 0.0;
     242       71136 :                 for (int j = 0; j < timeStepsInAverage; ++j) { //
     243       43776 :                     if ((i - j) < 0) {
     244         168 :                         RunningSum += ztStepObj[envrnStartZtStepIndexMap[itr->first]].logDataValue; // just use first value to fill early steps
     245             :                     } else {
     246       43608 :                         RunningSum += ztStepObj[((i - j) + envrnStartZtStepIndexMap[itr->first])].logDataValue;
     247             :                     }
     248             :                 }
     249       27360 :                 ztStepObj[(i + envrnStartZtStepIndexMap[itr->first])].runningAvgDataValue = RunningSum / divisor;
     250             :             }
     251             :         }
     252         108 :     }
     253         108 : }
     254             : 
     255          72 : ZoneTimestepObject SizingLog::GetLogVariableDataMax(EnergyPlusData &state)
     256             : {
     257             :     Real64 MaxVal;
     258          72 :     ZoneTimestepObject tmpztStepStamp;
     259          72 :     MaxVal = 0.0;
     260             : 
     261          72 :     if (!ztStepObj.empty()) {
     262          72 :         tmpztStepStamp = ztStepObj[0];
     263             :     }
     264             : 
     265       18312 :     for (auto &zt : ztStepObj) {
     266       18240 :         if (zt.envrnNum > 0 && zt.kindOfSim != Constant::KindOfSim::Invalid && zt.runningAvgDataValue > MaxVal) {
     267         595 :             MaxVal = zt.runningAvgDataValue;
     268         595 :             tmpztStepStamp = zt;
     269       17645 :         } else if (zt.envrnNum == 0 && zt.kindOfSim == Constant::KindOfSim::Invalid) { // null timestamp, problem to fix
     270           0 :             ShowWarningMessage(state, "GetLogVariableDataMax: null timestamp in log");
     271             :         }
     272          72 :     }
     273          72 :     return tmpztStepStamp;
     274           0 : }
     275             : 
     276         144 : Real64 SizingLog::GetLogVariableDataAtTimestamp(ZoneTimestepObject tmpztStepStamp)
     277             : {
     278         144 :     int const index = GetZtStepIndex(tmpztStepStamp);
     279             : 
     280         144 :     Real64 const val = ztStepObj[index].runningAvgDataValue;
     281             : 
     282         144 :     return val;
     283             : }
     284             : 
     285          90 : void SizingLog::ReInitLogForIteration()
     286             : {
     287          90 :     ZoneTimestepObject tmpNullztStepObj;
     288             : 
     289       22266 :     for (auto &zt : ztStepObj) {
     290       22176 :         zt = tmpNullztStepObj;
     291          90 :     }
     292          90 : }
     293             : 
     294         639 : void SizingLog::SetupNewEnvironment(int const seedEnvrnNum, int const newEnvrnNum)
     295             : {
     296         639 :     newEnvrnToSeedEnvrnMap[newEnvrnNum] = seedEnvrnNum;
     297         639 : }
     298             : 
     299          78 : int SizingLoggerFramework::SetupVariableSizingLog(EnergyPlusData &state, Real64 &rVariable, int stepsInAverage)
     300             : {
     301          78 :     int VectorLength(0);
     302          78 :     int constexpr HoursPerDay(24);
     303             : 
     304          78 :     SizingLog tmpLog(rVariable);
     305          78 :     tmpLog.NumOfEnvironmentsInLogSet = 0;
     306          78 :     tmpLog.NumOfDesignDaysInLogSet = 0;
     307          78 :     tmpLog.NumberOfSizingPeriodsInLogSet = 0;
     308             : 
     309             :     // search environment structure for sizing periods
     310             :     // this is coded to occur before the additions to Environment structure that will occur to run them as HVAC Sizing sims
     311         345 :     for (int i = 1; i <= state.dataWeather->NumOfEnvrn; ++i) {
     312         267 :         if (state.dataWeather->Environment(i).KindOfEnvrn == Constant::KindOfSim::DesignDay) {
     313         156 :             ++tmpLog.NumOfEnvironmentsInLogSet;
     314         156 :             ++tmpLog.NumOfDesignDaysInLogSet;
     315             :         }
     316         267 :         if (state.dataWeather->Environment(i).KindOfEnvrn == Constant::KindOfSim::RunPeriodDesign) {
     317           0 :             ++tmpLog.NumOfEnvironmentsInLogSet;
     318           0 :             ++tmpLog.NumberOfSizingPeriodsInLogSet;
     319             :         }
     320             :     }
     321             : 
     322             :     // next fill in the count of steps into map
     323         345 :     for (int i = 1; i <= state.dataWeather->NumOfEnvrn; ++i) {
     324             : 
     325         267 :         if (state.dataWeather->Environment(i).KindOfEnvrn == Constant::KindOfSim::DesignDay) {
     326         156 :             tmpLog.ztStepCountByEnvrnMap[i] = HoursPerDay * state.dataGlobal->NumOfTimeStepInHour;
     327             :         }
     328         267 :         if (state.dataWeather->Environment(i).KindOfEnvrn == Constant::KindOfSim::RunPeriodDesign) {
     329           0 :             tmpLog.ztStepCountByEnvrnMap[i] = HoursPerDay * state.dataGlobal->NumOfTimeStepInHour * state.dataWeather->Environment(i).TotalDays;
     330             :         }
     331             :     }
     332             : 
     333          78 :     int stepSum = 0;
     334          78 :     std::map<int, int>::iterator end = tmpLog.ztStepCountByEnvrnMap.end();
     335         234 :     for (std::map<int, int>::iterator itr = tmpLog.ztStepCountByEnvrnMap.begin(); itr != end; ++itr) {
     336             : 
     337         156 :         tmpLog.envrnStartZtStepIndexMap[itr->first] = stepSum;
     338         156 :         stepSum += itr->second;
     339          78 :     }
     340             : 
     341          78 :     tmpLog.timeStepsInAverage = stepsInAverage;
     342             : 
     343          78 :     VectorLength = stepSum;
     344             : 
     345          78 :     tmpLog.NumOfStepsInLogSet = VectorLength;
     346          78 :     tmpLog.ztStepObj.resize(VectorLength);
     347             : 
     348          78 :     logObjs.push_back(tmpLog);
     349          78 :     ++NumOfLogs;
     350          78 :     return NumOfLogs - 1;
     351          78 : }
     352             : 
     353         102 : void SizingLoggerFramework::SetupSizingLogsNewEnvironment(EnergyPlusData &state)
     354             : {
     355             :     using namespace Weather;
     356             : 
     357         741 :     for (auto &l : logObjs) {
     358         639 :         l.SetupNewEnvironment(state.dataWeather->Environment(state.dataWeather->Envrn).SeedEnvrnNum, state.dataWeather->Envrn);
     359         102 :     }
     360         102 : }
     361             : 
     362       13867 : ZoneTimestepObject SizingLoggerFramework::PrepareZoneTimestepStamp(EnergyPlusData &state)
     363             : {
     364             :     // prepare current timing data once and then pass into fill routines
     365             :     // function used by both zone and system frequency log updates
     366             : 
     367       13867 :     int locDayOfSim(1);
     368             : 
     369       13867 :     if (state.dataGlobal->WarmupFlag) { // DayOfSim not okay during warmup, keeps incrementing up during warmup days
     370           0 :         locDayOfSim = 1;
     371             :     } else {
     372       13867 :         locDayOfSim = state.dataGlobal->DayOfSim;
     373             :     }
     374             : 
     375             :     ZoneTimestepObject tmpztStepStamp( // call constructor
     376       13867 :         state.dataGlobal->KindOfSim,
     377       13867 :         state.dataWeather->Envrn,
     378             :         locDayOfSim,
     379       13867 :         state.dataGlobal->HourOfDay,
     380       13867 :         state.dataGlobal->TimeStep,
     381       13867 :         *state.dataOutputProcessor->TimeValue[(int)OutputProcessor::TimeStepType::Zone].TimeStep,
     382       27734 :         state.dataGlobal->NumOfTimeStepInHour);
     383             : 
     384       13867 :     return tmpztStepStamp;
     385             : }
     386             : 
     387        4656 : void SizingLoggerFramework::UpdateSizingLogValuesZoneStep(EnergyPlusData &state)
     388             : {
     389        4656 :     ZoneTimestepObject tmpztStepStamp;
     390             : 
     391        4656 :     tmpztStepStamp = PrepareZoneTimestepStamp(state);
     392             : 
     393       32016 :     for (auto &l : logObjs) {
     394       27360 :         l.FillZoneStep(tmpztStepStamp);
     395        4656 :     }
     396        4656 : }
     397             : 
     398        9211 : void SizingLoggerFramework::UpdateSizingLogValuesSystemStep(EnergyPlusData &state)
     399             : {
     400        9211 :     Real64 constexpr MinutesPerHour(60.0);
     401        9211 :     ZoneTimestepObject tmpztStepStamp;
     402        9211 :     SystemTimestepObject tmpSysStepStamp;
     403             : 
     404        9211 :     tmpztStepStamp = PrepareZoneTimestepStamp(state);
     405             : 
     406             :     // prepare system timestep stamp
     407        9211 :     tmpSysStepStamp.CurMinuteEnd = state.dataOutputProcessor->TimeValue[(int)OutputProcessor::TimeStepType::System].CurMinute;
     408        9211 :     if (tmpSysStepStamp.CurMinuteEnd == 0.0) {
     409           0 :         tmpSysStepStamp.CurMinuteEnd = MinutesPerHour;
     410             :     }
     411        9211 :     tmpSysStepStamp.CurMinuteStart =
     412        9211 :         tmpSysStepStamp.CurMinuteEnd - (*state.dataOutputProcessor->TimeValue[(int)OutputProcessor::TimeStepType::System].TimeStep) * MinutesPerHour;
     413        9211 :     tmpSysStepStamp.TimeStepDuration = *state.dataOutputProcessor->TimeValue[(int)OutputProcessor::TimeStepType::System].TimeStep;
     414             : 
     415       63745 :     for (auto &l : logObjs) {
     416       54534 :         l.FillSysStep(tmpztStepStamp, tmpSysStepStamp);
     417        9211 :     }
     418        9211 : }
     419             : 
     420          13 : void SizingLoggerFramework::IncrementSizingPeriodSet()
     421             : {
     422         103 :     for (auto &l : this->logObjs) {
     423          90 :         l.ReInitLogForIteration();
     424          13 :     }
     425          13 : }
     426             : 
     427          26 : PlantCoinicidentAnalysis::PlantCoinicidentAnalysis(
     428          26 :     std::string loopName, int loopIndex, int nodeNum, Real64 density, Real64 cp, int numStepsInAvg, int sizingIndex)
     429             : {
     430          26 :     name = loopName;
     431          26 :     plantLoopIndex = loopIndex;
     432          26 :     supplySideInletNodeNum = nodeNum;
     433          26 :     densityForSizing = density;
     434          26 :     specificHeatForSizing = cp;
     435          26 :     numTimeStepsInAvg = numStepsInAvg;
     436          26 :     plantSizingIndex = sizingIndex;
     437          26 : }
     438             : 
     439          36 : void PlantCoinicidentAnalysis::ResolveDesignFlowRate(EnergyPlusData &state, int const HVACSizingIterCount)
     440             : {
     441             :     using DataSizing::GlobalCoolingSizingFactorMode;
     442             :     using DataSizing::GlobalHeatingSizingFactorMode;
     443             :     using DataSizing::LoopComponentSizingFactorMode;
     444             :     using DataSizing::NoSizingFactorMode;
     445             : 
     446             :     using namespace DataPlant;
     447             :     using namespace OutputReportPredefined;
     448             :     using HVAC::SmallWaterVolFlow;
     449             :     bool setNewSizes;
     450             :     Real64 sizingFac;
     451             :     Real64 normalizedChange;
     452             :     Real64 newFoundVolFlowRate;
     453             :     Real64 peakLoadCalculatedMassFlow;
     454          36 :     std::string chIteration;
     455          36 :     std::string chSetSizes;
     456          36 :     std::string chDemandTrapUsed;
     457          36 :     bool changedByDemand(false);
     458             :     bool nullStampProblem;
     459             : 
     460             :     // first make sure we have valid time stamps to work with
     461          36 :     if (CheckTimeStampForNull(newFoundMassFlowRateTimeStamp) && CheckTimeStampForNull(NewFoundMaxDemandTimeStamp)) {
     462             :         // problem, don't have valid stamp, don't have any info to report either
     463           0 :         nullStampProblem = true;
     464             :     } else {
     465          36 :         nullStampProblem = false;
     466             :     }
     467             : 
     468          36 :     previousVolDesignFlowRate = state.dataSize->PlantSizData(plantSizingIndex).DesVolFlowRate;
     469             : 
     470          36 :     if (!CheckTimeStampForNull(newFoundMassFlowRateTimeStamp) && (newFoundMassFlowRateTimeStamp.runningAvgDataValue > 0.0)) { // issue 5665, was ||
     471          36 :         newFoundMassFlowRate = newFoundMassFlowRateTimeStamp.runningAvgDataValue;
     472             :     } else {
     473           0 :         newFoundMassFlowRate = 0.0;
     474             :     }
     475             : 
     476             :     // step 3 calculate mdot from max load and delta T
     477          71 :     if ((!CheckTimeStampForNull(NewFoundMaxDemandTimeStamp) && (NewFoundMaxDemandTimeStamp.runningAvgDataValue > 0.0)) &&
     478          35 :         ((specificHeatForSizing * state.dataSize->PlantSizData(plantSizingIndex).DeltaT) > 0.0)) {
     479          35 :         peakLoadCalculatedMassFlow =
     480          35 :             NewFoundMaxDemandTimeStamp.runningAvgDataValue / (specificHeatForSizing * state.dataSize->PlantSizData(plantSizingIndex).DeltaT);
     481             :     } else {
     482           1 :         peakLoadCalculatedMassFlow = 0.0;
     483             :     }
     484             : 
     485          36 :     if (peakLoadCalculatedMassFlow > newFoundMassFlowRate) {
     486          22 :         changedByDemand = true;
     487             :     } else {
     488          14 :         changedByDemand = false;
     489             :     }
     490          36 :     newFoundMassFlowRate = max(newFoundMassFlowRate, peakLoadCalculatedMassFlow); // step 4, take larger of the two
     491             : 
     492          36 :     newFoundVolFlowRate = newFoundMassFlowRate / densityForSizing;
     493             : 
     494             :     // now apply the correct sizing factor depending on input option
     495          36 :     sizingFac = 1.0;
     496          36 :     if (state.dataSize->PlantSizData(plantSizingIndex).SizingFactorOption == NoSizingFactorMode) {
     497          36 :         sizingFac = 1.0;
     498           0 :     } else if (state.dataSize->PlantSizData(plantSizingIndex).SizingFactorOption == GlobalHeatingSizingFactorMode) {
     499           0 :         sizingFac = state.dataSize->GlobalHeatSizingFactor;
     500           0 :     } else if (state.dataSize->PlantSizData(plantSizingIndex).SizingFactorOption == GlobalCoolingSizingFactorMode) {
     501           0 :         sizingFac = state.dataSize->GlobalCoolSizingFactor;
     502           0 :     } else if (state.dataSize->PlantSizData(plantSizingIndex).SizingFactorOption == LoopComponentSizingFactorMode) {
     503             :         // multiplier used for pumps, often 1.0, from component level sizing fractions
     504           0 :         sizingFac = state.dataPlnt->PlantLoop(plantLoopIndex).LoopSide(LoopSideLocation::Supply).Branch(1).PumpSizFac;
     505             :     }
     506             : 
     507          36 :     newAdjustedMassFlowRate = newFoundMassFlowRate * sizingFac; // apply overall heating or cooling sizing factor
     508             : 
     509          36 :     newVolDesignFlowRate = newAdjustedMassFlowRate / densityForSizing;
     510             : 
     511             :     // compare threshold,
     512          36 :     setNewSizes = false;
     513          36 :     normalizedChange = 0.0;
     514          36 :     if (newVolDesignFlowRate > SmallWaterVolFlow && !nullStampProblem) { // do not use zero size or bad stamp data
     515             : 
     516          36 :         normalizedChange = std::abs((newVolDesignFlowRate - previousVolDesignFlowRate) / previousVolDesignFlowRate);
     517          36 :         if (normalizedChange > significantNormalizedChange) {
     518          25 :             anotherIterationDesired = true;
     519          25 :             setNewSizes = true;
     520             :         } else {
     521          11 :             anotherIterationDesired = false;
     522             :         }
     523             :     }
     524             : 
     525          36 :     if (setNewSizes) {
     526             :         // set new size values for rest of simulation
     527          25 :         state.dataSize->PlantSizData(plantSizingIndex).DesVolFlowRate = newVolDesignFlowRate;
     528             : 
     529          25 :         if (state.dataPlnt->PlantLoop(plantLoopIndex).MaxVolFlowRateWasAutoSized) {
     530          25 :             state.dataPlnt->PlantLoop(plantLoopIndex).MaxVolFlowRate = newVolDesignFlowRate;
     531          25 :             state.dataPlnt->PlantLoop(plantLoopIndex).MaxMassFlowRate = newAdjustedMassFlowRate;
     532             :         }
     533          25 :         if (state.dataPlnt->PlantLoop(plantLoopIndex).VolumeWasAutoSized) {
     534             :             // Note this calculation also appears in PlantManager::SizePlantLoop and PlantManager::ResizePlantLoopLevelSizes
     535          25 :             state.dataPlnt->PlantLoop(plantLoopIndex).Volume =
     536          25 :                 state.dataPlnt->PlantLoop(plantLoopIndex).MaxVolFlowRate * state.dataPlnt->PlantLoop(plantLoopIndex).CirculationTime * 60.0;
     537          25 :             state.dataPlnt->PlantLoop(plantLoopIndex).Mass = state.dataPlnt->PlantLoop(plantLoopIndex).Volume * densityForSizing;
     538             :         }
     539             :     }
     540             : 
     541             :     // add a seperate eio summary report about what happened, did demand trap get used, what were the key values.
     542          36 :     if (!state.dataGlobal->sizingAnalysisEioHeaderDoneOnce) {
     543          11 :         print(state.files.eio,
     544             :               "{}",
     545             :               "! <Plant Coincident Sizing Algorithm>,Plant Loop Name,Sizing Pass {#},Measured Mass "
     546             :               "Flow{kg/s},Measured Demand {W},Demand Calculated Mass Flow{kg/s},Sizes Changed {Yes/No},Previous "
     547             :               "Volume Flow Rate {m3/s},New Volume Flow Rate {m3/s},Demand Check Applied {Yes/No},Sizing Factor "
     548             :               "{},Normalized Change {},Specific Heat{J/kg-K},Density {kg/m3}\n");
     549          11 :         state.dataGlobal->sizingAnalysisEioHeaderDoneOnce = true;
     550             :     }
     551          36 :     chIteration = fmt::to_string(HVACSizingIterCount);
     552          36 :     if (setNewSizes) {
     553          25 :         chSetSizes = "Yes";
     554             :     } else {
     555          11 :         chSetSizes = "No";
     556             :     }
     557          36 :     if (changedByDemand) {
     558          22 :         chDemandTrapUsed = "Yes";
     559             :     } else {
     560          14 :         chDemandTrapUsed = "No";
     561             :     }
     562             : 
     563          36 :     print(state.files.eio,
     564             :           "Plant Coincident Sizing Algorithm,{},{},{:.7R},{:.2R},{:.7R},{},{:.6R},{:.6R},{},{:.4R},{:.6R},{:.4R},{:.4R}\n",
     565          36 :           name,
     566             :           chIteration,
     567          36 :           newFoundMassFlowRateTimeStamp.runningAvgDataValue,
     568          36 :           NewFoundMaxDemandTimeStamp.runningAvgDataValue,
     569             :           peakLoadCalculatedMassFlow,
     570             :           chSetSizes,
     571          36 :           previousVolDesignFlowRate,
     572          36 :           newVolDesignFlowRate,
     573             :           chDemandTrapUsed,
     574             :           sizingFac,
     575             :           normalizedChange,
     576          36 :           specificHeatForSizing,
     577          36 :           densityForSizing);
     578             : 
     579             :     // report to sizing summary table called Plant Loop Coincident Design Fluid Flow Rates
     580             : 
     581          72 :     PreDefTableEntry(state,
     582          36 :                      state.dataOutRptPredefined->pdchPlantSizPrevVdot,
     583          72 :                      state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     584             :                      previousVolDesignFlowRate,
     585          36 :                      6);
     586          72 :     PreDefTableEntry(state,
     587          36 :                      state.dataOutRptPredefined->pdchPlantSizMeasVdot,
     588          72 :                      state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     589             :                      newFoundVolFlowRate,
     590          36 :                      6);
     591          72 :     PreDefTableEntry(state,
     592          36 :                      state.dataOutRptPredefined->pdchPlantSizCalcVdot,
     593          72 :                      state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     594             :                      newVolDesignFlowRate,
     595          36 :                      6);
     596             : 
     597          36 :     if (setNewSizes) {
     598          75 :         PreDefTableEntry(state,
     599          25 :                          state.dataOutRptPredefined->pdchPlantSizCoincYesNo,
     600          50 :                          state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     601             :                          "Yes");
     602             :     } else {
     603          33 :         PreDefTableEntry(state,
     604          11 :                          state.dataOutRptPredefined->pdchPlantSizCoincYesNo,
     605          22 :                          state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     606             :                          "No");
     607             :     }
     608             : 
     609          36 :     if (!nullStampProblem) {
     610          36 :         if (!changedByDemand && !CheckTimeStampForNull(newFoundMassFlowRateTimeStamp)) { // bug fix #5665
     611          14 :             if (newFoundMassFlowRateTimeStamp.envrnNum > 0) {                            // protect against invalid index
     612          28 :                 PreDefTableEntry(state,
     613          14 :                                  state.dataOutRptPredefined->pdchPlantSizDesDay,
     614          28 :                                  state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     615          14 :                                  state.dataWeather->Environment(newFoundMassFlowRateTimeStamp.envrnNum).Title);
     616             :             }
     617          28 :             PreDefTableEntry(state,
     618          14 :                              state.dataOutRptPredefined->pdchPlantSizPkTimeDayOfSim,
     619          28 :                              state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     620             :                              newFoundMassFlowRateTimeStamp.dayOfSim);
     621          28 :             PreDefTableEntry(state,
     622          14 :                              state.dataOutRptPredefined->pdchPlantSizPkTimeHour,
     623          28 :                              state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     624          14 :                              newFoundMassFlowRateTimeStamp.hourOfDay - 1);
     625          28 :             PreDefTableEntry(state,
     626          14 :                              state.dataOutRptPredefined->pdchPlantSizPkTimeMin,
     627          28 :                              state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     628             :                              newFoundMassFlowRateTimeStamp.stepStartMinute,
     629          28 :                              0);
     630          22 :         } else if (changedByDemand && !CheckTimeStampForNull(NewFoundMaxDemandTimeStamp)) { // bug fix #5665
     631          22 :             if (NewFoundMaxDemandTimeStamp.envrnNum > 0) {                                  // protect against invalid index
     632          44 :                 PreDefTableEntry(state,
     633          22 :                                  state.dataOutRptPredefined->pdchPlantSizDesDay,
     634          44 :                                  state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     635          22 :                                  state.dataWeather->Environment(NewFoundMaxDemandTimeStamp.envrnNum).Title);
     636             :             }
     637          44 :             PreDefTableEntry(state,
     638          22 :                              state.dataOutRptPredefined->pdchPlantSizPkTimeDayOfSim,
     639          44 :                              state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     640             :                              NewFoundMaxDemandTimeStamp.dayOfSim);
     641          44 :             PreDefTableEntry(state,
     642          22 :                              state.dataOutRptPredefined->pdchPlantSizPkTimeHour,
     643          44 :                              state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     644          22 :                              NewFoundMaxDemandTimeStamp.hourOfDay - 1);
     645          44 :             PreDefTableEntry(state,
     646          22 :                              state.dataOutRptPredefined->pdchPlantSizPkTimeMin,
     647          44 :                              state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     648             :                              NewFoundMaxDemandTimeStamp.stepStartMinute,
     649          44 :                              0);
     650             :         }
     651             :     }
     652          36 : }
     653             : 
     654         144 : bool PlantCoinicidentAnalysis::CheckTimeStampForNull(ZoneTimestepObject testStamp)
     655             : {
     656             : 
     657         144 :     bool isNull = true;
     658             : 
     659         144 :     if (testStamp.envrnNum != 0) {
     660         144 :         isNull = false;
     661             :     }
     662         144 :     if (testStamp.kindOfSim != Constant::KindOfSim::Invalid) {
     663         144 :         isNull = false;
     664             :     }
     665             : 
     666         144 :     return isNull;
     667             : }
     668             : } // namespace EnergyPlus

Generated by: LCOV version 1.14