LCOV - code coverage report
Current view: top level - EnergyPlus - SizingAnalysisObjects.cc (source / functions) Coverage Total Hit
Test: lcov.output.filtered Lines: 92.2 % 346 319
Test Date: 2025-06-02 07:23:51 Functions: 100.0 % 22 22

            Line data    Source code
       1              : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
       2              : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
       3              : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
       4              : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
       5              : // contributors. All rights reserved.
       6              : //
       7              : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
       8              : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
       9              : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
      10              : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
      11              : // derivative works, and perform publicly and display publicly, and to permit others to do so.
      12              : //
      13              : // Redistribution and use in source and binary forms, with or without modification, are permitted
      14              : // provided that the following conditions are met:
      15              : //
      16              : // (1) Redistributions of source code must retain the above copyright notice, this list of
      17              : //     conditions and the following disclaimer.
      18              : //
      19              : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
      20              : //     conditions and the following disclaimer in the documentation and/or other materials
      21              : //     provided with the distribution.
      22              : //
      23              : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
      24              : //     the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
      25              : //     used to endorse or promote products derived from this software without specific prior
      26              : //     written permission.
      27              : //
      28              : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
      29              : //     without changes from the version obtained under this License, or (ii) Licensee makes a
      30              : //     reference solely to the software portion of its product, Licensee must refer to the
      31              : //     software as "EnergyPlus version X" software, where "X" is the version number Licensee
      32              : //     obtained under this License and may not use a different name for the software. Except as
      33              : //     specifically required in this Section (4), Licensee shall not use in a company name, a
      34              : //     product name, in advertising, publicity, or other promotional activities any name, trade
      35              : //     name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
      36              : //     similar designation, without the U.S. Department of Energy's prior written consent.
      37              : //
      38              : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
      39              : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
      40              : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
      41              : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
      42              : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
      43              : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
      44              : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
      45              : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
      46              : // POSSIBILITY OF SUCH DAMAGE.
      47              : 
      48              : // 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        18934 : ZoneTimestepObject::ZoneTimestepObject()
      68              : {
      69        18934 :     kindOfSim = Constant::KindOfSim::Invalid;
      70        18934 :     envrnNum = 0;
      71        18934 :     dayOfSim = 0;
      72        18934 :     hourOfDay = 0;
      73        18934 :     ztStepsIntoPeriod = 0;
      74        18934 :     stepStartMinute = 0.0;
      75        18934 :     stepEndMinute = 0.0;
      76        18934 :     timeStepDuration = 0.0;
      77        18934 : }
      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) {
     109            0 :         ztStepsIntoPeriod = 0;
     110              :     }
     111              : 
     112              :     // We only expect this feature to be used with systems, so there will always be a system timestep update, at least one.
     113        13867 :     hasSystemSubSteps = true;
     114        13867 :     numSubSteps = 1;
     115        13867 :     subSteps.resize(numSubSteps);
     116        13867 : }
     117              : 
     118           78 : SizingLog::SizingLog(double &rVariable) : p_rVariable(rVariable)
     119              : {
     120           78 : }
     121              : 
     122        82038 : int SizingLog::GetZtStepIndex(const ZoneTimestepObject tmpztStepStamp)
     123              : {
     124              : 
     125              :     int vecIndex;
     126              : 
     127        82038 :     if (tmpztStepStamp.ztStepsIntoPeriod > 0) { // discard any negative value for safety
     128        80970 :         vecIndex = envrnStartZtStepIndexMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]] + tmpztStepStamp.ztStepsIntoPeriod;
     129              :     } else {
     130         1068 :         vecIndex = envrnStartZtStepIndexMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]];
     131              :     }
     132              : 
     133              :     // next for safety sake, constrain index to lie inside correct environment
     134        82038 :     if (vecIndex < envrnStartZtStepIndexMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]]) {
     135            0 :         vecIndex = envrnStartZtStepIndexMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]]; // first step in environment
     136              :     }
     137        82038 :     if (vecIndex > (envrnStartZtStepIndexMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]] +
     138        82038 :                     ztStepCountByEnvrnMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]])) {
     139            0 :         vecIndex = envrnStartZtStepIndexMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]] +
     140            0 :                    ztStepCountByEnvrnMap[newEnvrnToSeedEnvrnMap[tmpztStepStamp.envrnNum]]; // last step in environment
     141              :     }
     142        82038 :     return vecIndex;
     143              : }
     144              : 
     145        27360 : void SizingLog::FillZoneStep(ZoneTimestepObject tmpztStepStamp)
     146              : {
     147        27360 :     int index = GetZtStepIndex(tmpztStepStamp);
     148              : 
     149        27360 :     ztStepObj[index].kindOfSim = tmpztStepStamp.kindOfSim;
     150        27360 :     ztStepObj[index].envrnNum = tmpztStepStamp.envrnNum;
     151        27360 :     ztStepObj[index].dayOfSim = tmpztStepStamp.dayOfSim;
     152        27360 :     ztStepObj[index].hourOfDay = tmpztStepStamp.hourOfDay;
     153        27360 :     ztStepObj[index].ztStepsIntoPeriod = tmpztStepStamp.ztStepsIntoPeriod;
     154        27360 :     ztStepObj[index].stepStartMinute = tmpztStepStamp.stepStartMinute;
     155        27360 :     ztStepObj[index].stepEndMinute = tmpztStepStamp.stepEndMinute;
     156        27360 :     ztStepObj[index].timeStepDuration = tmpztStepStamp.timeStepDuration;
     157              : 
     158        27360 :     ztStepObj[index].logDataValue = p_rVariable;
     159        27360 : }
     160              : 
     161        54534 : int SizingLog::GetSysStepZtStepIndex(ZoneTimestepObject tmpztStepStamp)
     162              : {
     163              :     // this method finds a zone timestep for the system timestep update to use
     164              :     // system timesteps are substeps inside a zone timestep, but are updated
     165              :     // before the zone step has been called.
     166              :     // the zone timestamp passed in is now accurate, not lagged, so this is simpler
     167              : 
     168        54534 :     int znStepIndex = GetZtStepIndex(tmpztStepStamp);
     169              : 
     170              :     // safety checks for range
     171        54534 :     if (znStepIndex >= NumOfStepsInLogSet) {
     172            0 :         znStepIndex = NumOfStepsInLogSet - 1;
     173              :     }
     174        54534 :     if (znStepIndex < 0) {
     175            0 :         znStepIndex = 0;
     176              :     }
     177              : 
     178        54534 :     return znStepIndex;
     179              : }
     180              : 
     181        54534 : void SizingLog::FillSysStep(ZoneTimestepObject tmpztStepStamp, SystemTimestepObject tmpSysStepStamp)
     182              : {
     183              : 
     184              :     int newNumSubSteps;
     185        54534 :     Real64 constexpr MinutesPerHour(60.0);
     186              : 
     187        54534 :     int ztIndex = GetSysStepZtStepIndex(tmpztStepStamp);
     188              : 
     189        54534 :     if (ztStepObj[ztIndex].hasSystemSubSteps) {
     190              : 
     191        27174 :         int oldNumSubSteps = ztStepObj[ztIndex].numSubSteps;
     192        27174 :         newNumSubSteps = round(tmpztStepStamp.timeStepDuration / tmpSysStepStamp.TimeStepDuration);
     193        27174 :         if (newNumSubSteps != oldNumSubSteps) {
     194            0 :             ztStepObj[ztIndex].subSteps.resize(newNumSubSteps);
     195            0 :             ztStepObj[ztIndex].numSubSteps = newNumSubSteps;
     196              :         }
     197              :     } else {
     198        27360 :         newNumSubSteps = round(tmpztStepStamp.timeStepDuration / tmpSysStepStamp.TimeStepDuration);
     199        27360 :         ztStepObj[ztIndex].subSteps.resize(newNumSubSteps);
     200        27360 :         ztStepObj[ztIndex].numSubSteps = newNumSubSteps;
     201        27360 :         ztStepObj[ztIndex].hasSystemSubSteps = true;
     202              :     }
     203              : 
     204              :     // figure out which index this substep needs to go into
     205        54534 :     Real64 ZoneStepStartMinutes = tmpztStepStamp.stepStartMinute;
     206              : 
     207        54534 :     tmpSysStepStamp.stStepsIntoZoneStep =
     208        54534 :         round((((tmpSysStepStamp.CurMinuteStart - ZoneStepStartMinutes) / MinutesPerHour) / tmpSysStepStamp.TimeStepDuration));
     209              : 
     210        54534 :     if ((tmpSysStepStamp.stStepsIntoZoneStep >= 0) && (tmpSysStepStamp.stStepsIntoZoneStep < ztStepObj[ztIndex].numSubSteps)) {
     211        54534 :         ztStepObj[ztIndex].subSteps[tmpSysStepStamp.stStepsIntoZoneStep] = tmpSysStepStamp;
     212        54534 :         ztStepObj[ztIndex].subSteps[tmpSysStepStamp.stStepsIntoZoneStep].LogDataValue = p_rVariable;
     213              :     } else {
     214            0 :         ztStepObj[ztIndex].subSteps[0] = tmpSysStepStamp;
     215            0 :         ztStepObj[ztIndex].subSteps[0].LogDataValue = p_rVariable;
     216              :     }
     217        54534 : }
     218              : 
     219          108 : void SizingLog::AverageSysTimeSteps()
     220              : {
     221              :     Real64 RunningSum;
     222              : 
     223        27468 :     for (auto &zt : ztStepObj) {
     224        27360 :         if (zt.numSubSteps > 0) {
     225        27360 :             RunningSum = 0.0;
     226        81894 :             for (auto const &SysT : zt.subSteps) {
     227        54534 :                 RunningSum += SysT.LogDataValue;
     228        27360 :             }
     229        27360 :             zt.logDataValue = RunningSum / double(zt.numSubSteps);
     230              :         }
     231          108 :     }
     232          108 : }
     233              : 
     234          108 : void SizingLog::ProcessRunningAverage()
     235              : {
     236          108 :     Real64 RunningSum = 0.0;
     237          108 :     Real64 divisor = double(timeStepsInAverage);
     238              : 
     239          108 :     std::map<int, int>::iterator end = ztStepCountByEnvrnMap.end();
     240          324 :     for (std::map<int, int>::iterator itr = ztStepCountByEnvrnMap.begin(); itr != end; ++itr) {
     241        27576 :         for (int i = 0; i < itr->second; ++i) { // next inner loop over zone timestep steps
     242              : 
     243        27360 :             if (timeStepsInAverage > 0) {
     244        27360 :                 RunningSum = 0.0;
     245        71136 :                 for (int j = 0; j < timeStepsInAverage; ++j) { //
     246        43776 :                     if ((i - j) < 0) {
     247          168 :                         RunningSum += ztStepObj[envrnStartZtStepIndexMap[itr->first]].logDataValue; // just use first value to fill early steps
     248              :                     } else {
     249        43608 :                         RunningSum += ztStepObj[((i - j) + envrnStartZtStepIndexMap[itr->first])].logDataValue;
     250              :                     }
     251              :                 }
     252        27360 :                 ztStepObj[(i + envrnStartZtStepIndexMap[itr->first])].runningAvgDataValue = RunningSum / divisor;
     253              :             }
     254              :         }
     255          108 :     }
     256          108 : }
     257              : 
     258           72 : ZoneTimestepObject SizingLog::GetLogVariableDataMax(EnergyPlusData &state)
     259              : {
     260           72 :     ZoneTimestepObject tmpztStepStamp;
     261           72 :     Real64 MaxVal = 0.0;
     262              : 
     263           72 :     if (!ztStepObj.empty()) {
     264           72 :         tmpztStepStamp = ztStepObj[0];
     265              :     }
     266              : 
     267        18312 :     for (auto const &zt : ztStepObj) {
     268        18240 :         if (zt.envrnNum > 0 && zt.kindOfSim != Constant::KindOfSim::Invalid && zt.runningAvgDataValue > MaxVal) {
     269          594 :             MaxVal = zt.runningAvgDataValue;
     270          594 :             tmpztStepStamp = zt;
     271        17646 :         } else if (zt.envrnNum == 0 && zt.kindOfSim == Constant::KindOfSim::Invalid) { // null timestamp, problem to fix
     272            0 :             ShowWarningMessage(state, "GetLogVariableDataMax: null timestamp in log");
     273              :         }
     274           72 :     }
     275           72 :     return tmpztStepStamp;
     276            0 : }
     277              : 
     278          144 : Real64 SizingLog::GetLogVariableDataAtTimestamp(ZoneTimestepObject tmpztStepStamp)
     279              : {
     280          144 :     int const index = GetZtStepIndex(tmpztStepStamp);
     281          144 :     return ztStepObj[index].runningAvgDataValue;
     282              : }
     283              : 
     284           90 : void SizingLog::ReInitLogForIteration()
     285              : {
     286           90 :     ZoneTimestepObject tmpNullztStepObj;
     287           90 :     std::fill(ztStepObj.begin(), ztStepObj.end(), tmpNullztStepObj);
     288           90 : }
     289              : 
     290          639 : void SizingLog::SetupNewEnvironment(int const seedEnvrnNum, int const newEnvrnNum)
     291              : {
     292          639 :     newEnvrnToSeedEnvrnMap[newEnvrnNum] = seedEnvrnNum;
     293          639 : }
     294              : 
     295           78 : int SizingLoggerFramework::SetupVariableSizingLog(EnergyPlusData &state, Real64 &rVariable, int stepsInAverage)
     296              : {
     297           78 :     int constexpr HoursPerDay = 24;
     298              : 
     299           78 :     SizingLog tmpLog(rVariable);
     300           78 :     tmpLog.NumOfEnvironmentsInLogSet = 0;
     301           78 :     tmpLog.NumOfDesignDaysInLogSet = 0;
     302           78 :     tmpLog.NumberOfSizingPeriodsInLogSet = 0;
     303              : 
     304              :     // search environment structure for sizing periods
     305              :     // this is coded to occur before the additions to Environment structure that will occur to run them as HVAC Sizing sims
     306          345 :     for (int i = 1; i <= state.dataWeather->NumOfEnvrn; ++i) {
     307          267 :         if (state.dataWeather->Environment(i).KindOfEnvrn == Constant::KindOfSim::DesignDay) {
     308          156 :             ++tmpLog.NumOfEnvironmentsInLogSet;
     309          156 :             ++tmpLog.NumOfDesignDaysInLogSet;
     310              :         }
     311          267 :         if (state.dataWeather->Environment(i).KindOfEnvrn == Constant::KindOfSim::RunPeriodDesign) {
     312            0 :             ++tmpLog.NumOfEnvironmentsInLogSet;
     313            0 :             ++tmpLog.NumberOfSizingPeriodsInLogSet;
     314              :         }
     315              :     }
     316              : 
     317              :     // next fill in the count of steps into map
     318          345 :     for (int i = 1; i <= state.dataWeather->NumOfEnvrn; ++i) {
     319              : 
     320          267 :         if (state.dataWeather->Environment(i).KindOfEnvrn == Constant::KindOfSim::DesignDay) {
     321          156 :             tmpLog.ztStepCountByEnvrnMap[i] = HoursPerDay * state.dataGlobal->TimeStepsInHour;
     322              :         }
     323          267 :         if (state.dataWeather->Environment(i).KindOfEnvrn == Constant::KindOfSim::RunPeriodDesign) {
     324            0 :             tmpLog.ztStepCountByEnvrnMap[i] = HoursPerDay * state.dataGlobal->TimeStepsInHour * state.dataWeather->Environment(i).TotalDays;
     325              :         }
     326              :     }
     327              : 
     328           78 :     int stepSum = 0;
     329           78 :     std::map<int, int>::iterator end = tmpLog.ztStepCountByEnvrnMap.end();
     330          234 :     for (std::map<int, int>::iterator itr = tmpLog.ztStepCountByEnvrnMap.begin(); itr != end; ++itr) {
     331              : 
     332          156 :         tmpLog.envrnStartZtStepIndexMap[itr->first] = stepSum;
     333          156 :         stepSum += itr->second;
     334           78 :     }
     335              : 
     336           78 :     tmpLog.timeStepsInAverage = stepsInAverage;
     337              : 
     338           78 :     int VectorLength = stepSum;
     339              : 
     340           78 :     tmpLog.NumOfStepsInLogSet = VectorLength;
     341           78 :     tmpLog.ztStepObj.resize(VectorLength);
     342              : 
     343           78 :     logObjs.push_back(tmpLog);
     344           78 :     ++NumOfLogs;
     345           78 :     return NumOfLogs - 1;
     346           78 : }
     347              : 
     348          102 : void SizingLoggerFramework::SetupSizingLogsNewEnvironment(EnergyPlusData &state)
     349              : {
     350              :     using namespace Weather;
     351              : 
     352          741 :     for (auto &l : logObjs) {
     353          639 :         l.SetupNewEnvironment(state.dataWeather->Environment(state.dataWeather->Envrn).SeedEnvrnNum, state.dataWeather->Envrn);
     354          102 :     }
     355          102 : }
     356              : 
     357        13867 : ZoneTimestepObject SizingLoggerFramework::PrepareZoneTimestepStamp(EnergyPlusData &state)
     358              : {
     359              :     // prepare current timing data once and then pass into fill routines
     360              :     // function used by both zone and system frequency log updates
     361              : 
     362              :     int locDayOfSim;
     363              : 
     364        13867 :     if (state.dataGlobal->WarmupFlag) { // DayOfSim not okay during warmup, keeps incrementing up during warmup days
     365            0 :         locDayOfSim = 1;
     366              :     } else {
     367        13867 :         locDayOfSim = state.dataGlobal->DayOfSim;
     368              :     }
     369              : 
     370              :     ZoneTimestepObject tmpztStepStamp( // call constructor
     371        13867 :         state.dataGlobal->KindOfSim,
     372        13867 :         state.dataWeather->Envrn,
     373              :         locDayOfSim,
     374        13867 :         state.dataGlobal->HourOfDay,
     375        13867 :         state.dataGlobal->TimeStep,
     376        13867 :         *state.dataOutputProcessor->TimeValue[(int)OutputProcessor::TimeStepType::Zone].TimeStep,
     377        27734 :         state.dataGlobal->TimeStepsInHour);
     378              : 
     379        13867 :     return tmpztStepStamp;
     380              : }
     381              : 
     382         4656 : void SizingLoggerFramework::UpdateSizingLogValuesZoneStep(EnergyPlusData &state)
     383              : {
     384         4656 :     ZoneTimestepObject tmpztStepStamp = PrepareZoneTimestepStamp(state);
     385              : 
     386        32016 :     for (auto &l : logObjs) {
     387        27360 :         l.FillZoneStep(tmpztStepStamp);
     388         4656 :     }
     389         4656 : }
     390              : 
     391         9211 : void SizingLoggerFramework::UpdateSizingLogValuesSystemStep(EnergyPlusData &state)
     392              : {
     393         9211 :     Real64 constexpr MinutesPerHour = 60.0;
     394         9211 :     ZoneTimestepObject tmpztStepStamp = PrepareZoneTimestepStamp(state);
     395         9211 :     SystemTimestepObject tmpSysStepStamp;
     396              : 
     397              :     // prepare system timestep stamp
     398         9211 :     tmpSysStepStamp.CurMinuteEnd = state.dataOutputProcessor->TimeValue[(int)OutputProcessor::TimeStepType::System].CurMinute;
     399         9211 :     if (tmpSysStepStamp.CurMinuteEnd == 0.0) {
     400            0 :         tmpSysStepStamp.CurMinuteEnd = MinutesPerHour;
     401              :     }
     402         9211 :     tmpSysStepStamp.CurMinuteStart =
     403         9211 :         tmpSysStepStamp.CurMinuteEnd - (*state.dataOutputProcessor->TimeValue[(int)OutputProcessor::TimeStepType::System].TimeStep) * MinutesPerHour;
     404         9211 :     tmpSysStepStamp.TimeStepDuration = *state.dataOutputProcessor->TimeValue[(int)OutputProcessor::TimeStepType::System].TimeStep;
     405              : 
     406        63745 :     for (auto &l : logObjs) {
     407        54534 :         l.FillSysStep(tmpztStepStamp, tmpSysStepStamp);
     408         9211 :     }
     409         9211 : }
     410              : 
     411           13 : void SizingLoggerFramework::IncrementSizingPeriodSet()
     412              : {
     413          103 :     for (auto &l : this->logObjs) {
     414           90 :         l.ReInitLogForIteration();
     415           13 :     }
     416           13 : }
     417              : 
     418           26 : PlantCoinicidentAnalysis::PlantCoinicidentAnalysis(
     419           52 :     std::string loopName, int loopIndex, int nodeNum, Real64 density, Real64 cp, int numStepsInAvg, int sizingIndex)
     420              : {
     421           26 :     name = loopName;
     422           26 :     plantLoopIndex = loopIndex;
     423           26 :     supplySideInletNodeNum = nodeNum;
     424           26 :     densityForSizing = density;
     425           26 :     specificHeatForSizing = cp;
     426           26 :     numTimeStepsInAvg = numStepsInAvg;
     427           26 :     plantSizingIndex = sizingIndex;
     428           26 : }
     429              : 
     430           36 : void PlantCoinicidentAnalysis::ResolveDesignFlowRate(EnergyPlusData &state, int const HVACSizingIterCount)
     431              : {
     432              :     using DataSizing::GlobalCoolingSizingFactorMode;
     433              :     using DataSizing::GlobalHeatingSizingFactorMode;
     434              :     using DataSizing::LoopComponentSizingFactorMode;
     435              :     using DataSizing::NoSizingFactorMode;
     436              : 
     437              :     using namespace DataPlant;
     438              :     using namespace OutputReportPredefined;
     439              :     using HVAC::SmallWaterVolFlow;
     440              :     bool setNewSizes;
     441              :     Real64 sizingFac;
     442              :     Real64 normalizedChange;
     443              :     Real64 newFoundVolFlowRate;
     444              :     Real64 peakLoadCalculatedMassFlow;
     445           36 :     std::string chIteration;
     446           36 :     std::string chSetSizes;
     447           36 :     std::string chDemandTrapUsed;
     448           36 :     bool changedByDemand(false);
     449              :     bool nullStampProblem;
     450              : 
     451              :     // first make sure we have valid time stamps to work with
     452           36 :     if (CheckTimeStampForNull(newFoundMassFlowRateTimeStamp) && CheckTimeStampForNull(NewFoundMaxDemandTimeStamp)) {
     453              :         // problem, don't have valid stamp, don't have any info to report either
     454            0 :         nullStampProblem = true;
     455              :     } else {
     456           36 :         nullStampProblem = false;
     457              :     }
     458              : 
     459           36 :     previousVolDesignFlowRate = state.dataSize->PlantSizData(plantSizingIndex).DesVolFlowRate;
     460              : 
     461           36 :     if (!CheckTimeStampForNull(newFoundMassFlowRateTimeStamp) && (newFoundMassFlowRateTimeStamp.runningAvgDataValue > 0.0)) { // issue 5665, was ||
     462           36 :         newFoundMassFlowRate = newFoundMassFlowRateTimeStamp.runningAvgDataValue;
     463              :     } else {
     464            0 :         newFoundMassFlowRate = 0.0;
     465              :     }
     466              : 
     467              :     // step 3 calculate mdot from max load and delta T
     468           71 :     if ((!CheckTimeStampForNull(NewFoundMaxDemandTimeStamp) && (NewFoundMaxDemandTimeStamp.runningAvgDataValue > 0.0)) &&
     469           35 :         ((specificHeatForSizing * state.dataSize->PlantSizData(plantSizingIndex).DeltaT) > 0.0)) {
     470           35 :         peakLoadCalculatedMassFlow =
     471           35 :             NewFoundMaxDemandTimeStamp.runningAvgDataValue / (specificHeatForSizing * state.dataSize->PlantSizData(plantSizingIndex).DeltaT);
     472              :     } else {
     473            1 :         peakLoadCalculatedMassFlow = 0.0;
     474              :     }
     475              : 
     476           36 :     if (peakLoadCalculatedMassFlow > newFoundMassFlowRate) {
     477           22 :         changedByDemand = true;
     478              :     } else {
     479           14 :         changedByDemand = false;
     480              :     }
     481           36 :     newFoundMassFlowRate = max(newFoundMassFlowRate, peakLoadCalculatedMassFlow); // step 4, take larger of the two
     482              : 
     483           36 :     newFoundVolFlowRate = newFoundMassFlowRate / densityForSizing;
     484              : 
     485              :     // now apply the correct sizing factor depending on input option
     486           36 :     sizingFac = 1.0;
     487           36 :     if (state.dataSize->PlantSizData(plantSizingIndex).SizingFactorOption == NoSizingFactorMode) {
     488           36 :         sizingFac = 1.0;
     489            0 :     } else if (state.dataSize->PlantSizData(plantSizingIndex).SizingFactorOption == GlobalHeatingSizingFactorMode) {
     490            0 :         sizingFac = state.dataSize->GlobalHeatSizingFactor;
     491            0 :     } else if (state.dataSize->PlantSizData(plantSizingIndex).SizingFactorOption == GlobalCoolingSizingFactorMode) {
     492            0 :         sizingFac = state.dataSize->GlobalCoolSizingFactor;
     493            0 :     } else if (state.dataSize->PlantSizData(plantSizingIndex).SizingFactorOption == LoopComponentSizingFactorMode) {
     494              :         // multiplier used for pumps, often 1.0, from component level sizing fractions
     495            0 :         sizingFac = state.dataPlnt->PlantLoop(plantLoopIndex).LoopSide(LoopSideLocation::Supply).Branch(1).PumpSizFac;
     496              :     }
     497              : 
     498           36 :     newAdjustedMassFlowRate = newFoundMassFlowRate * sizingFac; // apply overall heating or cooling sizing factor
     499              : 
     500           36 :     newVolDesignFlowRate = newAdjustedMassFlowRate / densityForSizing;
     501              : 
     502              :     // compare threshold,
     503           36 :     setNewSizes = false;
     504           36 :     normalizedChange = 0.0;
     505           36 :     if (newVolDesignFlowRate > SmallWaterVolFlow && !nullStampProblem) { // do not use zero size or bad stamp data
     506              : 
     507           36 :         normalizedChange = std::abs((newVolDesignFlowRate - previousVolDesignFlowRate) / previousVolDesignFlowRate);
     508           36 :         if (normalizedChange > significantNormalizedChange) {
     509           25 :             anotherIterationDesired = true;
     510           25 :             setNewSizes = true;
     511              :         } else {
     512           11 :             anotherIterationDesired = false;
     513              :         }
     514              :     }
     515              : 
     516           36 :     if (setNewSizes) {
     517              :         // set new size values for rest of simulation
     518           25 :         state.dataSize->PlantSizData(plantSizingIndex).DesVolFlowRate = newVolDesignFlowRate;
     519              : 
     520           25 :         if (state.dataPlnt->PlantLoop(plantLoopIndex).MaxVolFlowRateWasAutoSized) {
     521           25 :             state.dataPlnt->PlantLoop(plantLoopIndex).MaxVolFlowRate = newVolDesignFlowRate;
     522           25 :             state.dataPlnt->PlantLoop(plantLoopIndex).MaxMassFlowRate = newAdjustedMassFlowRate;
     523              :         }
     524           25 :         if (state.dataPlnt->PlantLoop(plantLoopIndex).VolumeWasAutoSized) {
     525              :             // Note this calculation also appears in PlantManager::SizePlantLoop and PlantManager::ResizePlantLoopLevelSizes
     526           25 :             state.dataPlnt->PlantLoop(plantLoopIndex).Volume =
     527           25 :                 state.dataPlnt->PlantLoop(plantLoopIndex).MaxVolFlowRate * state.dataPlnt->PlantLoop(plantLoopIndex).CirculationTime * 60.0;
     528           25 :             state.dataPlnt->PlantLoop(plantLoopIndex).Mass = state.dataPlnt->PlantLoop(plantLoopIndex).Volume * densityForSizing;
     529              :         }
     530              :     }
     531              : 
     532              :     // add a separate eio summary report about what happened, did demand trap get used, what were the key values.
     533           36 :     if (!state.dataGlobal->sizingAnalysisEioHeaderDoneOnce) {
     534           11 :         print(state.files.eio,
     535              :               "{}",
     536              :               "! <Plant Coincident Sizing Algorithm>,Plant Loop Name,Sizing Pass {#},Measured Mass "
     537              :               "Flow{kg/s},Measured Demand {W},Demand Calculated Mass Flow{kg/s},Sizes Changed {Yes/No},Previous "
     538              :               "Volume Flow Rate {m3/s},New Volume Flow Rate {m3/s},Demand Check Applied {Yes/No},Sizing Factor "
     539              :               "{},Normalized Change {},Specific Heat{J/kg-K},Density {kg/m3}\n");
     540           11 :         state.dataGlobal->sizingAnalysisEioHeaderDoneOnce = true;
     541              :     }
     542           36 :     chIteration = fmt::to_string(HVACSizingIterCount);
     543           36 :     if (setNewSizes) {
     544           25 :         chSetSizes = "Yes";
     545              :     } else {
     546           11 :         chSetSizes = "No";
     547              :     }
     548           36 :     if (changedByDemand) {
     549           22 :         chDemandTrapUsed = "Yes";
     550              :     } else {
     551           14 :         chDemandTrapUsed = "No";
     552              :     }
     553              : 
     554           36 :     print(state.files.eio,
     555              :           "Plant Coincident Sizing Algorithm,{},{},{:.7R},{:.2R},{:.7R},{},{:.6R},{:.6R},{},{:.4R},{:.6R},{:.4R},{:.4R}\n",
     556           36 :           name,
     557              :           chIteration,
     558           36 :           newFoundMassFlowRateTimeStamp.runningAvgDataValue,
     559           36 :           NewFoundMaxDemandTimeStamp.runningAvgDataValue,
     560              :           peakLoadCalculatedMassFlow,
     561              :           chSetSizes,
     562           36 :           previousVolDesignFlowRate,
     563           36 :           newVolDesignFlowRate,
     564              :           chDemandTrapUsed,
     565              :           sizingFac,
     566              :           normalizedChange,
     567           36 :           specificHeatForSizing,
     568           36 :           densityForSizing);
     569              : 
     570              :     // report to sizing summary table called Plant Loop Coincident Design Fluid Flow Rates
     571              : 
     572           72 :     PreDefTableEntry(state,
     573           36 :                      state.dataOutRptPredefined->pdchPlantSizPrevVdot,
     574           72 :                      state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     575              :                      previousVolDesignFlowRate,
     576           36 :                      6);
     577           72 :     PreDefTableEntry(state,
     578           36 :                      state.dataOutRptPredefined->pdchPlantSizMeasVdot,
     579           72 :                      state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     580              :                      newFoundVolFlowRate,
     581           36 :                      6);
     582           72 :     PreDefTableEntry(state,
     583           36 :                      state.dataOutRptPredefined->pdchPlantSizCalcVdot,
     584           72 :                      state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     585              :                      newVolDesignFlowRate,
     586           36 :                      6);
     587              : 
     588           36 :     if (setNewSizes) {
     589           75 :         PreDefTableEntry(state,
     590           25 :                          state.dataOutRptPredefined->pdchPlantSizCoincYesNo,
     591           50 :                          state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     592              :                          "Yes");
     593              :     } else {
     594           33 :         PreDefTableEntry(state,
     595           11 :                          state.dataOutRptPredefined->pdchPlantSizCoincYesNo,
     596           22 :                          state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     597              :                          "No");
     598              :     }
     599              : 
     600           36 :     if (!nullStampProblem) {
     601           36 :         if (!changedByDemand && !CheckTimeStampForNull(newFoundMassFlowRateTimeStamp)) { // bug fix #5665
     602           14 :             if (newFoundMassFlowRateTimeStamp.envrnNum > 0) {                            // protect against invalid index
     603           28 :                 PreDefTableEntry(state,
     604           14 :                                  state.dataOutRptPredefined->pdchPlantSizDesDay,
     605           28 :                                  state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     606           14 :                                  state.dataWeather->Environment(newFoundMassFlowRateTimeStamp.envrnNum).Title);
     607              :             }
     608           28 :             PreDefTableEntry(state,
     609           14 :                              state.dataOutRptPredefined->pdchPlantSizPkTimeDayOfSim,
     610           28 :                              state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     611              :                              newFoundMassFlowRateTimeStamp.dayOfSim);
     612           28 :             PreDefTableEntry(state,
     613           14 :                              state.dataOutRptPredefined->pdchPlantSizPkTimeHour,
     614           28 :                              state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     615           14 :                              newFoundMassFlowRateTimeStamp.hourOfDay - 1);
     616           28 :             PreDefTableEntry(state,
     617           14 :                              state.dataOutRptPredefined->pdchPlantSizPkTimeMin,
     618           28 :                              state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     619              :                              newFoundMassFlowRateTimeStamp.stepStartMinute,
     620           28 :                              0);
     621           22 :         } else if (changedByDemand && !CheckTimeStampForNull(NewFoundMaxDemandTimeStamp)) { // bug fix #5665
     622           22 :             if (NewFoundMaxDemandTimeStamp.envrnNum > 0) {                                  // protect against invalid index
     623           44 :                 PreDefTableEntry(state,
     624           22 :                                  state.dataOutRptPredefined->pdchPlantSizDesDay,
     625           44 :                                  state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     626           22 :                                  state.dataWeather->Environment(NewFoundMaxDemandTimeStamp.envrnNum).Title);
     627              :             }
     628           44 :             PreDefTableEntry(state,
     629           22 :                              state.dataOutRptPredefined->pdchPlantSizPkTimeDayOfSim,
     630           44 :                              state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     631              :                              NewFoundMaxDemandTimeStamp.dayOfSim);
     632           44 :             PreDefTableEntry(state,
     633           22 :                              state.dataOutRptPredefined->pdchPlantSizPkTimeHour,
     634           44 :                              state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     635           22 :                              NewFoundMaxDemandTimeStamp.hourOfDay - 1);
     636           44 :             PreDefTableEntry(state,
     637           22 :                              state.dataOutRptPredefined->pdchPlantSizPkTimeMin,
     638           44 :                              state.dataPlnt->PlantLoop(plantLoopIndex).Name + " Sizing Pass " + chIteration,
     639              :                              NewFoundMaxDemandTimeStamp.stepStartMinute,
     640           44 :                              0);
     641              :         }
     642              :     }
     643           36 : }
     644              : 
     645          144 : bool PlantCoinicidentAnalysis::CheckTimeStampForNull(ZoneTimestepObject testStamp)
     646              : {
     647              : 
     648          144 :     bool isNull = true;
     649              : 
     650          144 :     if (testStamp.envrnNum != 0) {
     651          144 :         isNull = false;
     652              :     }
     653          144 :     if (testStamp.kindOfSim != Constant::KindOfSim::Invalid) {
     654          144 :         isNull = false;
     655              :     }
     656              : 
     657          144 :     return isNull;
     658              : }
     659              : } // namespace EnergyPlus
        

Generated by: LCOV version 2.0-1