LCOV - code coverage report
Current view: top level - EnergyPlus - DemandManager.cc (source / functions) Hit Total Coverage
Test: lcov.output.filtered Lines: 538 826 65.1 %
Date: 2024-08-24 18:31:18 Functions: 10 10 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             : // ObjexxFCL Headers
      49             : #include <ObjexxFCL/Fmath.hh>
      50             : 
      51             : // EnergyPlus Headers
      52             : #include <EnergyPlus/Data/EnergyPlusData.hh>
      53             : #include <EnergyPlus/DataEnvironment.hh>
      54             : #include <EnergyPlus/DataHeatBalFanSys.hh>
      55             : #include <EnergyPlus/DataHeatBalance.hh>
      56             : #include <EnergyPlus/DataIPShortCuts.hh>
      57             : #include <EnergyPlus/DataZoneControls.hh>
      58             : #include <EnergyPlus/DemandManager.hh>
      59             : #include <EnergyPlus/GlobalNames.hh>
      60             : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
      61             : #include <EnergyPlus/InternalHeatGains.hh>
      62             : #include <EnergyPlus/MixedAir.hh>
      63             : #include <EnergyPlus/OutputProcessor.hh>
      64             : #include <EnergyPlus/ScheduleManager.hh>
      65             : #include <EnergyPlus/SimulationManager.hh>
      66             : #include <EnergyPlus/UtilityRoutines.hh>
      67             : 
      68             : namespace EnergyPlus::DemandManager {
      69             : 
      70             : // MODULE INFORMATION:
      71             : //       AUTHOR         Peter Graham Ellis
      72             : //       DATE WRITTEN   July 2005
      73             : //       MODIFIED       Simon Vidanovic (March 2015) - Introduced DemandManager:Ventilation
      74             : //       RE-ENGINEERED  na
      75             : 
      76             : // PURPOSE OF THIS MODULE:
      77             : // This module provides controls for demand limiting various loads.
      78             : 
      79             : // METHODOLOGY EMPLOYED:
      80             : // ManageDemand is called from within the ManageHVAC routine after the first pass through SimHVAC, but
      81             : // _before_ any variables are reported or histories are updated.  If the metered demand is above the
      82             : // limit action is taken using the various demand managers to reduce loads.  Exterior energy use, zone
      83             : // heat balance, and HVAC system are then resimulated as necessary.  It is possible to iterate several
      84             : // times through ManageDemand before the final demand managers are established and the timestep can be
      85             : // completed.
      86             : 
      87             : constexpr std::array<std::string_view, static_cast<int>(ManagerType::Num)> ManagerNamesUC{"DEMANDMANAGER:EXTERIORLIGHTS",
      88             :                                                                                           "DEMANDMANAGER:LIGHTS",
      89             :                                                                                           "DEMANDMANAGER:ELECTRICEQUIPMENT",
      90             :                                                                                           "DEMANDMANAGER:THERMOSTATS",
      91             :                                                                                           "DEMANDMANAGER:VENTILATION"};
      92             : constexpr std::array<std::string_view, static_cast<int>(ManagePriorityType::Num)> ManagePriorityNamesUC{"SEQUENTIAL", "OPTIMAL", "ALL"};
      93             : constexpr std::array<std::string_view, static_cast<int>(ManagerLimit::Num)> ManagerLimitNamesUC{"OFF", "FIXED", "VARIABLE", "REDUCTIONRATIO"};
      94             : constexpr std::array<std::string_view, static_cast<int>(ManagerLimit::Num)> ManagerLimitVentNamesUC{"OFF", "FIXEDRATE", "VARIABLE", "REDUCTIONRATIO"};
      95             : constexpr std::array<std::string_view, static_cast<int>(ManagerSelection::Num)> ManagerSelectionNamesUC{"ALL", "ROTATEMANY", "ROTATEONE"};
      96             : 
      97     1977283 : void ManageDemand(EnergyPlusData &state)
      98             : {
      99             : 
     100             :     // SUBROUTINE INFORMATION:
     101             :     //       AUTHOR         Peter Graham Ellis
     102             :     //       DATE WRITTEN   July 2005
     103             : 
     104             :     // Locals
     105             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     106             : 
     107     1977283 :     if (state.dataDemandManager->GetInput && !state.dataGlobal->DoingSizing) {
     108           0 :         GetDemandManagerInput(state);
     109           0 :         GetDemandManagerListInput(state);
     110           0 :         state.dataDemandManager->GetInput = false;
     111             :     }
     112             : 
     113     1977283 :     if (state.dataDemandManager->NumDemandManagerList > 0) {
     114             : 
     115        8064 :         if (state.dataGlobal->WarmupFlag) {
     116        6912 :             state.dataDemandManager->BeginDemandSim = true;
     117        6912 :             if (state.dataDemandManager->ClearHistory) {
     118             :                 // Clear historical variables
     119          24 :                 for (int ListNum = 1; ListNum <= state.dataDemandManager->NumDemandManagerList; ++ListNum) {
     120          12 :                     state.dataDemandManager->DemandManagerList(ListNum).History = 0.0;
     121          12 :                     state.dataDemandManager->DemandManagerList(ListNum).MeterDemand = 0.0;
     122          12 :                     state.dataDemandManager->DemandManagerList(ListNum).AverageDemand = 0.0;
     123          12 :                     state.dataDemandManager->DemandManagerList(ListNum).PeakDemand = 0.0;
     124          12 :                     state.dataDemandManager->DemandManagerList(ListNum).ScheduledLimit = 0.0;
     125          12 :                     state.dataDemandManager->DemandManagerList(ListNum).DemandLimit = 0.0;
     126          12 :                     state.dataDemandManager->DemandManagerList(ListNum).AvoidedDemand = 0.0;
     127          12 :                     state.dataDemandManager->DemandManagerList(ListNum).OverLimit = 0.0;
     128          12 :                     state.dataDemandManager->DemandManagerList(ListNum).OverLimitDuration = 0.0;
     129             :                 } // ListNum
     130             : 
     131             :                 // Clear demand manager variables
     132          84 :                 for (auto &e : state.dataDemandManager->DemandMgr) {
     133          72 :                     e.Active = false;
     134          72 :                     e.ElapsedTime = 0;
     135          72 :                     e.ElapsedRotationTime = 0;
     136          72 :                     e.RotatedLoadNum = 0;
     137             :                 }
     138             :             }
     139        6912 :             state.dataDemandManager->ClearHistory = false;
     140             :         }
     141             : 
     142        8064 :         if (!state.dataGlobal->WarmupFlag && !state.dataGlobal->DoingSizing) {
     143             : 
     144        1152 :             if (state.dataDemandManager->BeginDemandSim) {
     145          12 :                 state.dataDemandManager->BeginDemandSim = false;
     146          12 :                 state.dataDemandManager->ClearHistory = true;
     147             :             }
     148             : 
     149        1152 :             state.dataDemandManager->DemandManagerExtIterations = 0;
     150        1152 :             state.dataDemandManager->DemandManagerHBIterations = 0;
     151        1152 :             state.dataDemandManager->DemandManagerHVACIterations = 0;
     152             : 
     153        1152 :             state.dataDemandManager->firstTime = true;
     154        1152 :             state.dataDemandManager->ResimExt = false;
     155        1152 :             state.dataDemandManager->ResimHB = false;
     156        1152 :             state.dataDemandManager->ResimHVAC = false;
     157             : 
     158        3791 :             while (state.dataDemandManager->firstTime || state.dataDemandManager->ResimExt || state.dataDemandManager->ResimHB ||
     159        1194 :                    state.dataDemandManager->ResimHVAC) {
     160        1445 :                 state.dataDemandManager->firstTime = false;
     161             : 
     162        1445 :                 Resimulate(state, state.dataDemandManager->ResimExt, state.dataDemandManager->ResimHB, state.dataDemandManager->ResimHVAC);
     163        1445 :                 state.dataDemandManager->ResimExt = false;
     164        1445 :                 state.dataDemandManager->ResimHB = false;
     165        1445 :                 state.dataDemandManager->ResimHVAC = false;
     166             : 
     167        1445 :                 SurveyDemandManagers(state); // Determines which Demand Managers can reduce demand
     168             : 
     169        2890 :                 for (int ListNum = 1; ListNum <= state.dataDemandManager->NumDemandManagerList; ++ListNum) {
     170        1445 :                     SimulateDemandManagerList(
     171        1445 :                         state, ListNum, state.dataDemandManager->ResimExt, state.dataDemandManager->ResimHB, state.dataDemandManager->ResimHVAC);
     172             :                 } // ListNum
     173             : 
     174        1445 :                 ActivateDemandManagers(state); // Sets limits on loads
     175             : 
     176        1445 :                 if (state.dataDemandManager->DemandManagerExtIterations + state.dataDemandManager->DemandManagerHBIterations +
     177        1445 :                         state.dataDemandManager->DemandManagerHVACIterations >
     178             :                     500) {
     179             :                     // This error can only happen if there is a bug in the code
     180           0 :                     ShowFatalError(state, "Too many DemandManager iterations. (>500)");
     181           0 :                     break;
     182             :                 }
     183             :             }
     184             : 
     185        2304 :             for (int ListNum = 1; ListNum <= state.dataDemandManager->NumDemandManagerList; ++ListNum) {
     186        1152 :                 ReportDemandManagerList(state, ListNum);
     187             :             } // ListNum
     188             :         }
     189             :     }
     190     1977283 : }
     191             : 
     192        1445 : void SimulateDemandManagerList(EnergyPlusData &state,
     193             :                                int const ListNum,
     194             :                                bool &ResimExt, // Flag to resimulate the exterior energy use simulation
     195             :                                bool &ResimHB,  // Flag to resimulate the heat balance simulation (including HVAC)
     196             :                                bool &ResimHVAC // Flag to resimulate the HVAC simulation
     197             : )
     198             : {
     199             : 
     200             :     // SUBROUTINE INFORMATION:
     201             :     //       AUTHOR         Peter Graham Ellis
     202             :     //       DATE WRITTEN   July 2005
     203             :     //       MODIFIED       Simon Vidanovic (March 2015) - Introduced DemandManager:Ventilation
     204             : 
     205             :     // Using/Aliasing
     206        1445 :     Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
     207             : 
     208             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     209             :     bool OnPeak;
     210             : 
     211        1445 :     auto &demandManagerList = state.dataDemandManager->DemandManagerList(ListNum);
     212             : 
     213        1445 :     demandManagerList.ScheduledLimit = ScheduleManager::GetCurrentScheduleValue(state, demandManagerList.LimitSchedule);
     214        1445 :     demandManagerList.DemandLimit = demandManagerList.ScheduledLimit * demandManagerList.SafetyFraction;
     215             : 
     216        1445 :     demandManagerList.MeterDemand =
     217        1445 :         GetInstantMeterValue(state, demandManagerList.Meter, OutputProcessor::TimeStepType::Zone) / state.dataGlobal->TimeStepZoneSec +
     218        1445 :         GetInstantMeterValue(state, demandManagerList.Meter, OutputProcessor::TimeStepType::System) / TimeStepSysSec;
     219             : 
     220             :     // Calculate average demand over the averaging window including the current timestep meter demand
     221             :     Real64 AverageDemand =
     222        1445 :         demandManagerList.AverageDemand + (demandManagerList.MeterDemand - demandManagerList.History(1)) / demandManagerList.AveragingWindow;
     223             : 
     224        1445 :     if (demandManagerList.PeakSchedule == 0) {
     225        1445 :         OnPeak = true;
     226             :     } else {
     227           0 :         if (ScheduleManager::GetCurrentScheduleValue(state, demandManagerList.PeakSchedule) == 1) {
     228           0 :             OnPeak = true;
     229             :         } else {
     230           0 :             OnPeak = false;
     231             :         }
     232             :     }
     233             : 
     234        1445 :     if (OnPeak) {
     235        1445 :         Real64 OverLimit = AverageDemand - demandManagerList.DemandLimit;
     236             : 
     237        1445 :         if (OverLimit > 0.0) {
     238             : 
     239         329 :             switch (demandManagerList.ManagerPriority) {
     240         329 :             case ManagePriorityType::Sequential: { // Activate first Demand Manager that can reduce demand
     241             : 
     242         999 :                 for (int MgrNum = 1; MgrNum <= demandManagerList.NumOfManager; ++MgrNum) {
     243         963 :                     auto &demandMgr = state.dataDemandManager->DemandMgr(demandManagerList.Manager(MgrNum));
     244             : 
     245         963 :                     if (demandMgr.CanReduceDemand) {
     246         293 :                         demandMgr.Activate = true;
     247             : 
     248         293 :                         switch (demandMgr.Type) {
     249          55 :                         case ManagerType::ExtLights: {
     250          55 :                             ResimExt = true;
     251          55 :                         } break;
     252         196 :                         case ManagerType::Lights:
     253             :                         case ManagerType::ElecEquip: {
     254         196 :                             ResimHB = true;
     255         196 :                             ResimHVAC = true;
     256         196 :                         } break;
     257          42 :                         case ManagerType::Thermostats:
     258             :                         case ManagerType::Ventilation: {
     259          42 :                             ResimHVAC = true;
     260          42 :                         } break;
     261           0 :                         default:
     262           0 :                             break;
     263             :                         }
     264             : 
     265         293 :                         break; // Leave the loop
     266             :                     }
     267             :                 } // MgrNum
     268             : 
     269         329 :             } break;
     270           0 :             case ManagePriorityType::Optimal: {
     271             :                 // Not yet implemented
     272             : 
     273           0 :             } break;
     274           0 :             case ManagePriorityType::All: { // Activate ALL Demand Managers that can reduce demand
     275             : 
     276           0 :                 for (int MgrNum = 1; MgrNum <= demandManagerList.NumOfManager; ++MgrNum) {
     277           0 :                     auto &demandMgr = state.dataDemandManager->DemandMgr(demandManagerList.Manager(MgrNum));
     278             : 
     279           0 :                     if (demandMgr.CanReduceDemand) {
     280           0 :                         demandMgr.Activate = true;
     281             : 
     282           0 :                         switch (demandMgr.Type) {
     283           0 :                         case ManagerType::ExtLights: {
     284           0 :                             ResimExt = true;
     285           0 :                         } break;
     286           0 :                         case ManagerType::Lights:
     287             :                         case ManagerType::ElecEquip: {
     288           0 :                             ResimHB = true;
     289           0 :                             ResimHVAC = true;
     290           0 :                         } break;
     291           0 :                         case ManagerType::Thermostats:
     292             :                         case ManagerType::Ventilation: {
     293           0 :                             ResimHVAC = true;
     294           0 :                         } break;
     295           0 :                         default:
     296           0 :                             break;
     297             :                         }
     298             :                     }
     299             :                 } // MgrNum
     300           0 :             } break;
     301           0 :             default:
     302           0 :                 break;
     303             :             }
     304             :         }
     305             :     }
     306        1445 : }
     307             : 
     308         795 : void GetDemandManagerListInput(EnergyPlusData &state)
     309             : {
     310             : 
     311             :     // SUBROUTINE INFORMATION:
     312             :     //       AUTHOR         Peter Graham Ellis
     313             :     //       DATE WRITTEN   July 2005
     314             :     //       MODIFIED       Simon Vidanovic (March 2015) - Introduced DemandManager:Ventilation
     315             : 
     316             :     // PURPOSE OF THIS SUBROUTINE:
     317             :     // Gets the DEMAND MANAGER LIST input from the input file.
     318             : 
     319             :     // METHODOLOGY EMPLOYED:
     320             :     // Standard EnergyPlus methodology.
     321             : 
     322             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     323             : 
     324         795 :     constexpr std::string_view cCurrentModuleObject = "DemandManagerAssignmentList";
     325         795 :     state.dataDemandManager->NumDemandManagerList = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
     326             : 
     327         795 :     if (state.dataDemandManager->NumDemandManagerList > 0) {
     328             :         int NumAlphas; // Number of elements in the alpha array
     329             :         int NumNums;   // Number of elements in the numeric array
     330             :         int IOStat;    // IO Status when calling get input subroutine
     331           6 :         bool ErrorsFound = false;
     332             : 
     333           6 :         state.dataDemandManager->DemandManagerList.allocate(state.dataDemandManager->NumDemandManagerList);
     334             : 
     335          12 :         for (int ListNum = 1; ListNum <= state.dataDemandManager->NumDemandManagerList; ++ListNum) {
     336             : 
     337           6 :             auto &thisDemandMgrList = state.dataDemandManager->DemandManagerList(ListNum);
     338             : 
     339          18 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     340             :                                                                      cCurrentModuleObject,
     341             :                                                                      ListNum,
     342           6 :                                                                      state.dataIPShortCut->cAlphaArgs,
     343             :                                                                      NumAlphas,
     344           6 :                                                                      state.dataIPShortCut->rNumericArgs,
     345             :                                                                      NumNums,
     346             :                                                                      IOStat,
     347             :                                                                      _,
     348           6 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
     349           6 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
     350           6 :                                                                      state.dataIPShortCut->cNumericFieldNames);
     351             : 
     352           6 :             thisDemandMgrList.Name = state.dataIPShortCut->cAlphaArgs(1);
     353             : 
     354           6 :             thisDemandMgrList.Meter = GetMeterIndex(state, state.dataIPShortCut->cAlphaArgs(2));
     355             : 
     356           6 :             if (thisDemandMgrList.Meter == -1) {
     357           0 :                 ShowSevereError(state, format("Invalid {} = {}", state.dataIPShortCut->cAlphaFieldNames(2), state.dataIPShortCut->cAlphaArgs(2)));
     358           0 :                 ShowContinueError(state, format("Entered in {} = {}", cCurrentModuleObject, thisDemandMgrList.Name));
     359           0 :                 ErrorsFound = true;
     360             : 
     361             :             } else {
     362           6 :                 if ((state.dataOutputProcessor->meters[thisDemandMgrList.Meter]->resource == Constant::eResource::Electricity) ||
     363           0 :                     (state.dataOutputProcessor->meters[thisDemandMgrList.Meter]->resource == Constant::eResource::ElectricityNet)) {
     364             :                 } else {
     365           0 :                     ShowSevereError(state,
     366           0 :                                     format("{} = \"{}\" invalid value {} = \"{}\".",
     367             :                                            cCurrentModuleObject,
     368           0 :                                            thisDemandMgrList.Name,
     369           0 :                                            state.dataIPShortCut->cAlphaFieldNames(2),
     370           0 :                                            state.dataIPShortCut->cAlphaArgs(2)));
     371           0 :                     ShowContinueError(state, "Only Electricity and ElectricityNet meters are currently allowed.");
     372           0 :                     ErrorsFound = true;
     373             :                 }
     374             :             }
     375             : 
     376             :             // Further checking for conflicting DEMAND MANAGER LISTs
     377             : 
     378           6 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(3)) {
     379           6 :                 thisDemandMgrList.LimitSchedule = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(3));
     380             : 
     381           6 :                 if (thisDemandMgrList.LimitSchedule == 0) {
     382           0 :                     ShowSevereError(state,
     383           0 :                                     format("{} = \"{}\" invalid {} = \"{}\" not found.",
     384             :                                            cCurrentModuleObject,
     385           0 :                                            thisDemandMgrList.Name,
     386           0 :                                            state.dataIPShortCut->cAlphaFieldNames(3),
     387           0 :                                            state.dataIPShortCut->cAlphaArgs(3)));
     388           0 :                     ErrorsFound = true;
     389             :                 }
     390             :             }
     391             : 
     392           6 :             thisDemandMgrList.SafetyFraction = state.dataIPShortCut->rNumericArgs(1);
     393             : 
     394           6 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(4)) {
     395           0 :                 thisDemandMgrList.BillingSchedule = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(4));
     396             : 
     397           0 :                 if (thisDemandMgrList.BillingSchedule == 0) {
     398           0 :                     ShowSevereError(state,
     399           0 :                                     format("{} = \"{}\" invalid {} = \"{}\" not found.",
     400             :                                            cCurrentModuleObject,
     401           0 :                                            thisDemandMgrList.Name,
     402           0 :                                            state.dataIPShortCut->cAlphaFieldNames(4),
     403           0 :                                            state.dataIPShortCut->cAlphaArgs(4)));
     404           0 :                     ErrorsFound = true;
     405             :                 }
     406             :             }
     407             : 
     408           6 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(5)) {
     409           0 :                 thisDemandMgrList.PeakSchedule = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(5));
     410             : 
     411           0 :                 if (thisDemandMgrList.PeakSchedule == 0) {
     412           0 :                     ShowSevereError(state,
     413           0 :                                     format("{} = \"{}\" invalid {} = \"{}\" not found.",
     414             :                                            cCurrentModuleObject,
     415           0 :                                            thisDemandMgrList.Name,
     416           0 :                                            state.dataIPShortCut->cAlphaFieldNames(5),
     417           0 :                                            state.dataIPShortCut->cAlphaArgs(5)));
     418           0 :                     ErrorsFound = true;
     419             :                 }
     420             :             }
     421             : 
     422           6 :             thisDemandMgrList.AveragingWindow = max(int(state.dataIPShortCut->rNumericArgs(2) / state.dataGlobal->MinutesPerTimeStep), 1);
     423             :             // Round to nearest timestep
     424             :             // Can make this fancier to include windows that do not fit the timesteps
     425           6 :             thisDemandMgrList.History.allocate(thisDemandMgrList.AveragingWindow);
     426           6 :             thisDemandMgrList.History = 0.0;
     427             : 
     428             :             // Validate Demand Manager Priority
     429           6 :             thisDemandMgrList.ManagerPriority =
     430           6 :                 static_cast<ManagePriorityType>(getEnumValue(ManagePriorityNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(6))));
     431           6 :             ErrorsFound = ErrorsFound || (thisDemandMgrList.ManagerPriority == ManagePriorityType::Invalid);
     432             : 
     433             :             // Get DEMAND MANAGER Type and Name pairs
     434           6 :             thisDemandMgrList.NumOfManager = int((NumAlphas - 6) / 2.0);
     435             : 
     436           6 :             if (thisDemandMgrList.NumOfManager > 0) {
     437           6 :                 thisDemandMgrList.Manager.allocate(thisDemandMgrList.NumOfManager);
     438          42 :                 for (int MgrNum = 1; MgrNum <= thisDemandMgrList.NumOfManager; ++MgrNum) {
     439             : 
     440          36 :                     auto &thisManager = thisDemandMgrList.Manager(MgrNum);
     441             :                     // Validate DEMAND MANAGER Type
     442             :                     ManagerType MgrType =
     443          36 :                         static_cast<ManagerType>(getEnumValue(ManagerNamesUC, Util::makeUPPER(state.dataIPShortCut->cAlphaArgs(MgrNum * 2 + 5))));
     444          36 :                     if (MgrType != ManagerType::Invalid) {
     445          36 :                         thisManager = Util::FindItemInList(state.dataIPShortCut->cAlphaArgs(MgrNum * 2 + 6), state.dataDemandManager->DemandMgr);
     446          36 :                         if (thisManager == 0) {
     447           0 :                             ShowSevereError(state,
     448           0 :                                             format("{} = \"{}\" invalid {} = \"{}\" not found.",
     449             :                                                    cCurrentModuleObject,
     450           0 :                                                    thisDemandMgrList.Name,
     451           0 :                                                    state.dataIPShortCut->cAlphaFieldNames(MgrNum * 2 + 6),
     452           0 :                                                    state.dataIPShortCut->cAlphaArgs(MgrNum * 2 + 6)));
     453           0 :                             ErrorsFound = true;
     454             :                         }
     455             :                     } else {
     456           0 :                         ShowSevereError(state,
     457           0 :                                         format("{} = \"{}\" invalid value {} = \"{}\".",
     458             :                                                cCurrentModuleObject,
     459           0 :                                                thisDemandMgrList.Name,
     460           0 :                                                state.dataIPShortCut->cAlphaFieldNames(MgrNum * 2 + 5),
     461           0 :                                                state.dataIPShortCut->cAlphaArgs(MgrNum * 2 + 5)));
     462           0 :                         ErrorsFound = true;
     463             :                     }
     464             : 
     465             :                     // Check that each is not already referenced using %DemandManagerList field
     466             : 
     467             :                 } // MgrNum
     468             :             }
     469             : 
     470             :             // Setup report variables
     471          12 :             SetupOutputVariable(state,
     472             :                                 "Demand Manager Meter Demand Power",
     473             :                                 Constant::Units::W,
     474           6 :                                 thisDemandMgrList.MeterDemand,
     475             :                                 OutputProcessor::TimeStepType::Zone,
     476             :                                 OutputProcessor::StoreType::Average,
     477           6 :                                 thisDemandMgrList.Name);
     478             : 
     479          12 :             SetupOutputVariable(state,
     480             :                                 "Demand Manager Average Demand Power",
     481             :                                 Constant::Units::W,
     482           6 :                                 thisDemandMgrList.AverageDemand,
     483             :                                 OutputProcessor::TimeStepType::Zone,
     484             :                                 OutputProcessor::StoreType::Average,
     485           6 :                                 thisDemandMgrList.Name);
     486             : 
     487          12 :             SetupOutputVariable(state,
     488             :                                 "Demand Manager Peak Demand Power",
     489             :                                 Constant::Units::W,
     490           6 :                                 thisDemandMgrList.PeakDemand,
     491             :                                 OutputProcessor::TimeStepType::Zone,
     492             :                                 OutputProcessor::StoreType::Average,
     493           6 :                                 thisDemandMgrList.Name);
     494             : 
     495          12 :             SetupOutputVariable(state,
     496             :                                 "Demand Manager Scheduled Limit Power",
     497             :                                 Constant::Units::W,
     498           6 :                                 thisDemandMgrList.ScheduledLimit,
     499             :                                 OutputProcessor::TimeStepType::Zone,
     500             :                                 OutputProcessor::StoreType::Average,
     501           6 :                                 thisDemandMgrList.Name);
     502             : 
     503          12 :             SetupOutputVariable(state,
     504             :                                 "Demand Manager Demand Limit Power",
     505             :                                 Constant::Units::W,
     506           6 :                                 thisDemandMgrList.DemandLimit,
     507             :                                 OutputProcessor::TimeStepType::Zone,
     508             :                                 OutputProcessor::StoreType::Average,
     509           6 :                                 thisDemandMgrList.Name);
     510             : 
     511          12 :             SetupOutputVariable(state,
     512             :                                 "Demand Manager Over Limit Power",
     513             :                                 Constant::Units::W,
     514           6 :                                 thisDemandMgrList.OverLimit,
     515             :                                 OutputProcessor::TimeStepType::Zone,
     516             :                                 OutputProcessor::StoreType::Average,
     517           6 :                                 thisDemandMgrList.Name);
     518             : 
     519          12 :             SetupOutputVariable(state,
     520             :                                 "Demand Manager Over Limit Time",
     521             :                                 Constant::Units::hr,
     522           6 :                                 thisDemandMgrList.OverLimitDuration,
     523             :                                 OutputProcessor::TimeStepType::Zone,
     524             :                                 OutputProcessor::StoreType::Sum,
     525           6 :                                 thisDemandMgrList.Name);
     526             : 
     527           6 :             if (ErrorsFound) {
     528           0 :                 ShowFatalError(state, format("Errors found in processing input for {}.", cCurrentModuleObject));
     529             :             }
     530             : 
     531             :         } // ListNum
     532             : 
     533             :         // Iteration diagnostic reporting for all DEMAND MANAGER LISTs
     534          12 :         SetupOutputVariable(state,
     535             :                             "Demand Manager Exterior Energy Iteration Count",
     536             :                             Constant::Units::None,
     537           6 :                             state.dataDemandManager->DemandManagerExtIterations,
     538             :                             OutputProcessor::TimeStepType::Zone,
     539             :                             OutputProcessor::StoreType::Sum,
     540             :                             "ManageDemand");
     541             : 
     542          12 :         SetupOutputVariable(state,
     543             :                             "Demand Manager Heat Balance Iteration Count",
     544             :                             Constant::Units::None,
     545           6 :                             state.dataDemandManager->DemandManagerHBIterations,
     546             :                             OutputProcessor::TimeStepType::Zone,
     547             :                             OutputProcessor::StoreType::Sum,
     548             :                             "ManageDemand");
     549             : 
     550          12 :         SetupOutputVariable(state,
     551             :                             "Demand Manager HVAC Iteration Count",
     552             :                             Constant::Units::None,
     553           6 :                             state.dataDemandManager->DemandManagerHVACIterations,
     554             :                             OutputProcessor::TimeStepType::Zone,
     555             :                             OutputProcessor::StoreType::Sum,
     556             :                             "ManageDemand");
     557             :     }
     558         795 : }
     559             : 
     560         795 : void GetDemandManagerInput(EnergyPlusData &state)
     561             : {
     562             : 
     563             :     // SUBROUTINE INFORMATION:
     564             :     //       AUTHOR         Peter Graham Ellis
     565             :     //       DATE WRITTEN   July 2005
     566             :     //       MODIFIED       MODIFIED       Simon Vidanovic (March 2015) - Introduced DemandManager:Ventilation
     567             : 
     568             :     // PURPOSE OF THIS SUBROUTINE:
     569             :     // Gets the DEMAND MANAGER input from the input file.
     570             : 
     571             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
     572             :     int NumAlphas;            // Number of elements in the alpha array
     573             :     int NumNums;              // Number of elements in the numeric array
     574             :     int NumParams;            // Number of arguments total in an ObjectDef
     575         795 :     Array1D_string AlphArray; // Character string data
     576         795 :     Array1D<Real64> NumArray; // Numeric data
     577         795 :     bool ErrorsFound(false);
     578             : 
     579         795 :     int MaxAlphas = 0;
     580         795 :     int MaxNums = 0;
     581         795 :     std::string CurrentModuleObject = "DemandManager:ExteriorLights";
     582         795 :     int NumDemandMgrExtLights = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     583         795 :     if (NumDemandMgrExtLights > 0) {
     584           5 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumParams, NumAlphas, NumNums);
     585           5 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     586           5 :         MaxNums = max(MaxNums, NumNums);
     587             :     }
     588         795 :     CurrentModuleObject = "DemandManager:Lights";
     589         795 :     int NumDemandMgrLights = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     590         795 :     if (NumDemandMgrLights > 0) {
     591           6 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumParams, NumAlphas, NumNums);
     592           6 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     593           6 :         MaxNums = max(MaxNums, NumNums);
     594             :     }
     595         795 :     CurrentModuleObject = "DemandManager:ElectricEquipment";
     596         795 :     int NumDemandMgrElecEquip = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     597         795 :     if (NumDemandMgrElecEquip > 0) {
     598           5 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumParams, NumAlphas, NumNums);
     599           5 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     600           5 :         MaxNums = max(MaxNums, NumNums);
     601             :     }
     602         795 :     CurrentModuleObject = "DemandManager:Thermostats";
     603         795 :     int NumDemandMgrThermostats = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     604         795 :     if (NumDemandMgrThermostats > 0) {
     605           5 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumParams, NumAlphas, NumNums);
     606           5 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     607           5 :         MaxNums = max(MaxNums, NumNums);
     608             :     }
     609         795 :     CurrentModuleObject = "DemandManager:Ventilation";
     610         795 :     int NumDemandMgrVentilation = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
     611         795 :     if (NumDemandMgrVentilation > 0) {
     612           5 :         state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumParams, NumAlphas, NumNums);
     613           5 :         MaxAlphas = max(MaxAlphas, NumAlphas);
     614           5 :         MaxNums = max(MaxNums, NumNums);
     615             :     }
     616             : 
     617        1590 :     state.dataDemandManager->NumDemandMgr =
     618         795 :         NumDemandMgrExtLights + NumDemandMgrLights + NumDemandMgrElecEquip + NumDemandMgrThermostats + NumDemandMgrVentilation;
     619             : 
     620         795 :     auto &DemandMgr(state.dataDemandManager->DemandMgr);
     621             : 
     622         795 :     if (state.dataDemandManager->NumDemandMgr > 0) {
     623           6 :         AlphArray.dimension(MaxAlphas, std::string());
     624           6 :         NumArray.dimension(MaxNums, 0.0);
     625             :         int IOStat; // IO Status when calling get input subroutine
     626             : 
     627           6 :         DemandMgr.allocate(state.dataDemandManager->NumDemandMgr);
     628           6 :         state.dataDemandManager->UniqueDemandMgrNames.reserve(state.dataDemandManager->NumDemandMgr);
     629             : 
     630             :         // Get input for DemandManager:ExteriorLights
     631           6 :         int StartIndex = 1;
     632           6 :         int EndIndex = NumDemandMgrExtLights;
     633             : 
     634           6 :         CurrentModuleObject = "DemandManager:ExteriorLights";
     635             : 
     636          11 :         for (int MgrNum = StartIndex; MgrNum <= EndIndex; ++MgrNum) {
     637           5 :             auto &demandMgr = DemandMgr(MgrNum);
     638             : 
     639          15 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     640             :                                                                      CurrentModuleObject,
     641           5 :                                                                      MgrNum - StartIndex + 1,
     642             :                                                                      AlphArray,
     643             :                                                                      NumAlphas,
     644             :                                                                      NumArray,
     645             :                                                                      NumNums,
     646             :                                                                      IOStat,
     647             :                                                                      _,
     648           5 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
     649           5 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
     650           5 :                                                                      state.dataIPShortCut->cNumericFieldNames);
     651           5 :             GlobalNames::VerifyUniqueInterObjectName(state,
     652           5 :                                                      state.dataDemandManager->UniqueDemandMgrNames,
     653           5 :                                                      AlphArray(1),
     654             :                                                      CurrentModuleObject,
     655           5 :                                                      state.dataIPShortCut->cAlphaFieldNames(1),
     656             :                                                      ErrorsFound);
     657           5 :             demandMgr.Name = AlphArray(1);
     658             : 
     659           5 :             demandMgr.Type = ManagerType::ExtLights;
     660             : 
     661           5 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(2)) {
     662           0 :                 demandMgr.AvailSchedule = ScheduleManager::GetScheduleIndex(state, AlphArray(2));
     663             : 
     664           0 :                 if (demandMgr.AvailSchedule == 0) {
     665           0 :                     ShowSevereError(state,
     666           0 :                                     format("{}=\"{}\" invalid {}=\"{}\" not found.",
     667             :                                            CurrentModuleObject,
     668           0 :                                            state.dataIPShortCut->cAlphaArgs(1),
     669           0 :                                            state.dataIPShortCut->cAlphaFieldNames(2),
     670             :                                            AlphArray(2)));
     671           0 :                     ErrorsFound = true;
     672             :                 }
     673             :             } else {
     674           5 :                 demandMgr.AvailSchedule = ScheduleManager::ScheduleAlwaysOn;
     675             :             }
     676             : 
     677             :             // Validate Limiting Control
     678           5 :             demandMgr.LimitControl = static_cast<ManagerLimit>(getEnumValue(ManagerLimitNamesUC, Util::makeUPPER(AlphArray(3))));
     679           5 :             ErrorsFound = ErrorsFound || (demandMgr.LimitControl == ManagerLimit::Invalid);
     680             : 
     681           5 :             if (NumArray(1) == 0.0)
     682           0 :                 demandMgr.LimitDuration = state.dataGlobal->MinutesPerTimeStep;
     683             :             else
     684           5 :                 demandMgr.LimitDuration = NumArray(1);
     685             : 
     686           5 :             demandMgr.LowerLimit = NumArray(2);
     687             : 
     688             :             // Validate Selection Control
     689           5 :             demandMgr.SelectionControl = static_cast<ManagerSelection>(getEnumValue(ManagerSelectionNamesUC, Util::makeUPPER(AlphArray(4))));
     690           5 :             ErrorsFound = ErrorsFound || (demandMgr.SelectionControl == ManagerSelection::Invalid);
     691             : 
     692           5 :             if (NumArray(4) == 0.0)
     693           5 :                 demandMgr.RotationDuration = state.dataGlobal->MinutesPerTimeStep;
     694             :             else
     695           0 :                 demandMgr.RotationDuration = NumArray(4);
     696             : 
     697           5 :             demandMgr.NumOfLoads = NumAlphas - 4;
     698             : 
     699           5 :             if (demandMgr.NumOfLoads > 0) {
     700           5 :                 demandMgr.Load.allocate(demandMgr.NumOfLoads);
     701             : 
     702          10 :                 for (int LoadNum = 1; LoadNum <= demandMgr.NumOfLoads; ++LoadNum) {
     703           5 :                     int LoadPtr = Util::FindItemInList(AlphArray(LoadNum + 4), state.dataExteriorEnergyUse->ExteriorLights);
     704             : 
     705           5 :                     if (LoadPtr > 0) {
     706           5 :                         demandMgr.Load(LoadNum) = LoadPtr;
     707             : 
     708             :                     } else {
     709           0 :                         ShowSevereError(state,
     710           0 :                                         format("{}=\"{}\" invalid {}=\"{}\" not found.",
     711             :                                                CurrentModuleObject,
     712           0 :                                                state.dataIPShortCut->cAlphaArgs(1),
     713           0 :                                                state.dataIPShortCut->cAlphaFieldNames(LoadNum + 4),
     714             :                                                AlphArray(LoadNum + 4)));
     715           0 :                         ErrorsFound = true;
     716             :                     }
     717             :                 } // LoadNum
     718             :             } else {
     719           0 :                 ShowSevereError(state,
     720           0 :                                 format("{}=\"{}\" invalid value for number of loads.", CurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     721           0 :                 ShowContinueError(state, "Number of loads is calculated to be less than one. Demand manager must have at least one load assigned.");
     722           0 :                 ErrorsFound = true;
     723             :             }
     724             : 
     725             :         } // MgrNum
     726             : 
     727             :         // Get input for DemandManager:Lights
     728           6 :         StartIndex = EndIndex + 1;
     729           6 :         EndIndex += NumDemandMgrLights;
     730             : 
     731           6 :         CurrentModuleObject = "DemandManager:Lights";
     732             : 
     733          12 :         for (int MgrNum = StartIndex; MgrNum <= EndIndex; ++MgrNum) {
     734           6 :             auto &demandMgr = DemandMgr(MgrNum);
     735             : 
     736          18 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     737             :                                                                      CurrentModuleObject,
     738           6 :                                                                      MgrNum - StartIndex + 1,
     739             :                                                                      AlphArray,
     740             :                                                                      NumAlphas,
     741             :                                                                      NumArray,
     742             :                                                                      NumNums,
     743             :                                                                      IOStat,
     744             :                                                                      _,
     745           6 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
     746           6 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
     747           6 :                                                                      state.dataIPShortCut->cNumericFieldNames);
     748           6 :             GlobalNames::VerifyUniqueInterObjectName(state,
     749           6 :                                                      state.dataDemandManager->UniqueDemandMgrNames,
     750           6 :                                                      AlphArray(1),
     751             :                                                      CurrentModuleObject,
     752           6 :                                                      state.dataIPShortCut->cAlphaFieldNames(1),
     753             :                                                      ErrorsFound);
     754           6 :             demandMgr.Name = AlphArray(1);
     755             : 
     756           6 :             demandMgr.Type = ManagerType::Lights;
     757             : 
     758           6 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(2)) {
     759           0 :                 demandMgr.AvailSchedule = ScheduleManager::GetScheduleIndex(state, AlphArray(2));
     760             : 
     761           0 :                 if (demandMgr.AvailSchedule == 0) {
     762           0 :                     ShowSevereError(state,
     763           0 :                                     format("{}=\"{}\" invalid {}=\"{}\" not found.",
     764             :                                            CurrentModuleObject,
     765           0 :                                            state.dataIPShortCut->cAlphaArgs(1),
     766           0 :                                            state.dataIPShortCut->cAlphaFieldNames(2),
     767             :                                            AlphArray(2)));
     768           0 :                     ErrorsFound = true;
     769             :                 }
     770             :             } else {
     771           6 :                 demandMgr.AvailSchedule = ScheduleManager::ScheduleAlwaysOn;
     772             :             }
     773             : 
     774             :             // Validate Limiting Control
     775           6 :             demandMgr.LimitControl = static_cast<ManagerLimit>(getEnumValue(ManagerLimitNamesUC, Util::makeUPPER(AlphArray(3))));
     776           6 :             ErrorsFound = ErrorsFound || (demandMgr.LimitControl == ManagerLimit::Invalid);
     777             : 
     778           6 :             if (NumArray(1) == 0.0)
     779           0 :                 demandMgr.LimitDuration = state.dataGlobal->MinutesPerTimeStep;
     780             :             else
     781           6 :                 demandMgr.LimitDuration = NumArray(1);
     782             : 
     783           6 :             demandMgr.LowerLimit = NumArray(2);
     784             : 
     785             :             // Validate Selection Control
     786           6 :             demandMgr.SelectionControl = static_cast<ManagerSelection>(getEnumValue(ManagerSelectionNamesUC, Util::makeUPPER(AlphArray(4))));
     787           6 :             ErrorsFound = ErrorsFound || (demandMgr.SelectionControl == ManagerSelection::Invalid);
     788             : 
     789           6 :             if (NumArray(4) == 0.0)
     790           6 :                 demandMgr.RotationDuration = state.dataGlobal->MinutesPerTimeStep;
     791             :             else
     792           0 :                 demandMgr.RotationDuration = NumArray(4);
     793             : 
     794             :             // Count actual pointers to controlled zones
     795           6 :             demandMgr.NumOfLoads = 0;
     796          12 :             for (int LoadNum = 1; LoadNum <= NumAlphas - 4; ++LoadNum) {
     797           6 :                 int LoadPtr = Util::FindItemInList(AlphArray(LoadNum + 4), state.dataInternalHeatGains->lightsObjects);
     798           6 :                 if (LoadPtr > 0) {
     799           6 :                     demandMgr.NumOfLoads += state.dataInternalHeatGains->lightsObjects(LoadPtr).numOfSpaces;
     800             :                 } else {
     801           0 :                     LoadPtr = Util::FindItemInList(AlphArray(LoadNum + 4), state.dataHeatBal->Lights);
     802           0 :                     if (LoadPtr > 0) {
     803           0 :                         ++demandMgr.NumOfLoads;
     804             :                     } else {
     805           0 :                         ShowSevereError(state,
     806           0 :                                         format("{}=\"{}\" invalid {}=\"{}\" not found.",
     807             :                                                CurrentModuleObject,
     808           0 :                                                state.dataIPShortCut->cAlphaArgs(1),
     809           0 :                                                state.dataIPShortCut->cAlphaFieldNames(LoadNum + 4),
     810             :                                                AlphArray(LoadNum + 4)));
     811           0 :                         ErrorsFound = true;
     812             :                     }
     813             :                 }
     814             :             }
     815             : 
     816             :             //      demandMgr%NumOfLoads = NumAlphas - 4
     817             : 
     818           6 :             if (demandMgr.NumOfLoads > 0) {
     819           6 :                 demandMgr.Load.allocate(demandMgr.NumOfLoads);
     820           6 :                 int LoadNum = 0;
     821          12 :                 for (int Item = 1; Item <= NumAlphas - 4; ++Item) {
     822           6 :                     int LoadPtr = Util::FindItemInList(AlphArray(Item + 4), state.dataInternalHeatGains->lightsObjects);
     823           6 :                     if (LoadPtr > 0) {
     824          36 :                         for (int Item1 = 1; Item1 <= state.dataInternalHeatGains->lightsObjects(LoadPtr).numOfSpaces; ++Item1) {
     825          30 :                             ++LoadNum;
     826          30 :                             demandMgr.Load(LoadNum) = state.dataInternalHeatGains->lightsObjects(LoadPtr).spaceStartPtr + Item1 - 1;
     827             :                         }
     828             :                     } else {
     829           0 :                         LoadPtr = Util::FindItemInList(AlphArray(Item + 4), state.dataHeatBal->Lights);
     830           0 :                         if (LoadPtr > 0) {
     831           0 :                             ++LoadNum;
     832           0 :                             demandMgr.Load(LoadNum) = LoadPtr;
     833             :                         }
     834             :                     }
     835             :                 } // LoadNum
     836             :             } else {
     837           0 :                 ShowSevereError(state,
     838           0 :                                 format("{}=\"{}\" invalid value for number of loads.", CurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     839           0 :                 ShowContinueError(state, "Number of loads is calculated to be less than one. Demand manager must have at least one load assigned.");
     840           0 :                 ErrorsFound = true;
     841             :             }
     842             : 
     843             :         } // MgrNum
     844             : 
     845             :         // Get input for DemandManager:ElectricEquipment
     846           6 :         StartIndex = EndIndex + 1;
     847           6 :         EndIndex += NumDemandMgrElecEquip;
     848             : 
     849           6 :         CurrentModuleObject = "DemandManager:ElectricEquipment";
     850             : 
     851          21 :         for (int MgrNum = StartIndex; MgrNum <= EndIndex; ++MgrNum) {
     852          15 :             auto &demandMgr = DemandMgr(MgrNum);
     853             : 
     854          45 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     855             :                                                                      CurrentModuleObject,
     856          15 :                                                                      MgrNum - StartIndex + 1,
     857             :                                                                      AlphArray,
     858             :                                                                      NumAlphas,
     859             :                                                                      NumArray,
     860             :                                                                      NumNums,
     861             :                                                                      IOStat,
     862             :                                                                      _,
     863          15 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
     864          15 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
     865          15 :                                                                      state.dataIPShortCut->cNumericFieldNames);
     866          15 :             GlobalNames::VerifyUniqueInterObjectName(state,
     867          15 :                                                      state.dataDemandManager->UniqueDemandMgrNames,
     868          15 :                                                      AlphArray(1),
     869             :                                                      CurrentModuleObject,
     870          15 :                                                      state.dataIPShortCut->cAlphaFieldNames(1),
     871             :                                                      ErrorsFound);
     872          15 :             demandMgr.Name = AlphArray(1);
     873             : 
     874          15 :             demandMgr.Type = ManagerType::ElecEquip;
     875             : 
     876          15 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(2)) {
     877           0 :                 demandMgr.AvailSchedule = ScheduleManager::GetScheduleIndex(state, AlphArray(2));
     878             : 
     879           0 :                 if (demandMgr.AvailSchedule == 0) {
     880           0 :                     ShowSevereError(state,
     881           0 :                                     format("{}=\"{}\" invalid {}=\"{}\" not found.",
     882             :                                            CurrentModuleObject,
     883           0 :                                            state.dataIPShortCut->cAlphaArgs(1),
     884           0 :                                            state.dataIPShortCut->cAlphaFieldNames(2),
     885             :                                            AlphArray(2)));
     886           0 :                     ErrorsFound = true;
     887             :                 }
     888             :             } else {
     889          15 :                 demandMgr.AvailSchedule = ScheduleManager::ScheduleAlwaysOn;
     890             :             }
     891             : 
     892             :             // Validate Limiting Control
     893          15 :             demandMgr.LimitControl = static_cast<ManagerLimit>(getEnumValue(ManagerLimitNamesUC, Util::makeUPPER(AlphArray(3))));
     894          15 :             ErrorsFound = ErrorsFound || (demandMgr.LimitControl == ManagerLimit::Invalid);
     895             : 
     896          15 :             if (NumArray(1) == 0.0)
     897           0 :                 demandMgr.LimitDuration = state.dataGlobal->MinutesPerTimeStep;
     898             :             else
     899          15 :                 demandMgr.LimitDuration = NumArray(1);
     900             : 
     901          15 :             demandMgr.LowerLimit = NumArray(2);
     902             : 
     903             :             // Validate Selection Control
     904          15 :             demandMgr.SelectionControl = static_cast<ManagerSelection>(getEnumValue(ManagerSelectionNamesUC, Util::makeUPPER(AlphArray(4))));
     905          15 :             ErrorsFound = ErrorsFound || (demandMgr.SelectionControl == ManagerSelection::Invalid);
     906             : 
     907          15 :             if (NumArray(4) == 0.0)
     908          15 :                 demandMgr.RotationDuration = state.dataGlobal->MinutesPerTimeStep;
     909             :             else
     910           0 :                 demandMgr.RotationDuration = NumArray(4);
     911             : 
     912             :             // Count actual pointers to controlled zones
     913          15 :             demandMgr.NumOfLoads = 0;
     914          30 :             for (int LoadNum = 1; LoadNum <= NumAlphas - 4; ++LoadNum) {
     915          15 :                 int LoadPtr = Util::FindItemInList(AlphArray(LoadNum + 4), state.dataInternalHeatGains->zoneElectricObjects);
     916          15 :                 if (LoadPtr > 0) {
     917           0 :                     demandMgr.NumOfLoads += state.dataInternalHeatGains->zoneElectricObjects(LoadPtr).numOfSpaces;
     918             :                 } else {
     919          15 :                     LoadPtr = Util::FindItemInList(AlphArray(LoadNum + 4), state.dataHeatBal->ZoneElectric);
     920          15 :                     if (LoadPtr > 0) {
     921          15 :                         ++demandMgr.NumOfLoads;
     922             :                     } else {
     923           0 :                         ShowSevereError(state,
     924           0 :                                         format("{}=\"{}\" invalid {}=\"{}\" not found.",
     925             :                                                CurrentModuleObject,
     926           0 :                                                state.dataIPShortCut->cAlphaArgs(1),
     927           0 :                                                state.dataIPShortCut->cAlphaFieldNames(LoadNum + 4),
     928             :                                                AlphArray(LoadNum + 4)));
     929           0 :                         ErrorsFound = true;
     930             :                     }
     931             :                 }
     932             :             }
     933             : 
     934             :             //      demandMgr%NumOfLoads = NumAlphas - 4
     935             : 
     936          15 :             if (demandMgr.NumOfLoads > 0) {
     937          15 :                 demandMgr.Load.allocate(demandMgr.NumOfLoads);
     938          15 :                 int LoadNum = 0;
     939          30 :                 for (int Item = 1; Item <= NumAlphas - 4; ++Item) {
     940          15 :                     int LoadPtr = Util::FindItemInList(AlphArray(Item + 4), state.dataInternalHeatGains->zoneElectricObjects);
     941          15 :                     if (LoadPtr > 0) {
     942           0 :                         for (int Item1 = 1; Item1 <= state.dataInternalHeatGains->zoneElectricObjects(LoadPtr).numOfSpaces; ++Item1) {
     943           0 :                             ++LoadNum;
     944           0 :                             demandMgr.Load(LoadNum) = state.dataInternalHeatGains->zoneElectricObjects(LoadPtr).spaceStartPtr + Item1 - 1;
     945             :                         }
     946             :                     } else {
     947          15 :                         LoadPtr = Util::FindItemInList(AlphArray(Item + 4), state.dataHeatBal->ZoneElectric);
     948          15 :                         if (LoadPtr > 0) {
     949          15 :                             ++LoadNum;
     950          15 :                             demandMgr.Load(LoadNum) = LoadPtr;
     951             :                         }
     952             :                     }
     953             :                 } // LoadNum
     954             :             } else {
     955           0 :                 ShowSevereError(state,
     956           0 :                                 format("{}=\"{}\" invalid value for number of loads.", CurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
     957           0 :                 ShowContinueError(state, "Number of loads is calculated to be less than one. Demand manager must have at least one load assigned.");
     958           0 :                 ErrorsFound = true;
     959             :             }
     960             : 
     961             :         } // MgrNum
     962             : 
     963             :         // Get input for DemandManager:Thermostats
     964           6 :         StartIndex = EndIndex + 1;
     965           6 :         EndIndex += NumDemandMgrThermostats;
     966             : 
     967           6 :         CurrentModuleObject = "DemandManager:Thermostats";
     968             : 
     969          11 :         for (int MgrNum = StartIndex; MgrNum <= EndIndex; ++MgrNum) {
     970           5 :             auto &demandMgr = DemandMgr(MgrNum);
     971             : 
     972          15 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
     973             :                                                                      CurrentModuleObject,
     974           5 :                                                                      MgrNum - StartIndex + 1,
     975             :                                                                      AlphArray,
     976             :                                                                      NumAlphas,
     977             :                                                                      NumArray,
     978             :                                                                      NumNums,
     979             :                                                                      IOStat,
     980             :                                                                      _,
     981           5 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
     982           5 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
     983           5 :                                                                      state.dataIPShortCut->cNumericFieldNames);
     984             : 
     985           5 :             GlobalNames::VerifyUniqueInterObjectName(state,
     986           5 :                                                      state.dataDemandManager->UniqueDemandMgrNames,
     987           5 :                                                      AlphArray(1),
     988             :                                                      CurrentModuleObject,
     989           5 :                                                      state.dataIPShortCut->cAlphaFieldNames(1),
     990             :                                                      ErrorsFound);
     991           5 :             demandMgr.Name = AlphArray(1);
     992             : 
     993           5 :             demandMgr.Type = ManagerType::Thermostats;
     994             : 
     995           5 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(2)) {
     996           0 :                 demandMgr.AvailSchedule = ScheduleManager::GetScheduleIndex(state, AlphArray(2));
     997             : 
     998           0 :                 if (demandMgr.AvailSchedule == 0) {
     999           0 :                     ShowSevereError(state,
    1000           0 :                                     format("{}=\"{}\" invalid {}=\"{}\" not found.",
    1001             :                                            CurrentModuleObject,
    1002           0 :                                            state.dataIPShortCut->cAlphaArgs(1),
    1003           0 :                                            state.dataIPShortCut->cAlphaFieldNames(2),
    1004             :                                            AlphArray(2)));
    1005           0 :                     ErrorsFound = true;
    1006             :                 }
    1007             :             } else {
    1008           5 :                 demandMgr.AvailSchedule = ScheduleManager::ScheduleAlwaysOn;
    1009             :             }
    1010             : 
    1011             :             // Validate Limiting Control
    1012           5 :             demandMgr.LimitControl = static_cast<ManagerLimit>(getEnumValue(ManagerLimitNamesUC, Util::makeUPPER(AlphArray(3))));
    1013           5 :             ErrorsFound = ErrorsFound || (demandMgr.LimitControl == ManagerLimit::Invalid);
    1014             : 
    1015           5 :             if (NumArray(1) == 0.0)
    1016           0 :                 demandMgr.LimitDuration = state.dataGlobal->MinutesPerTimeStep;
    1017             :             else
    1018           5 :                 demandMgr.LimitDuration = NumArray(1);
    1019             : 
    1020           5 :             demandMgr.LowerLimit = NumArray(2);
    1021           5 :             demandMgr.UpperLimit = NumArray(3);
    1022             : 
    1023           5 :             if (demandMgr.LowerLimit > demandMgr.UpperLimit) {
    1024           0 :                 ShowSevereError(state, format("Invalid input for {} = {}", CurrentModuleObject, AlphArray(1)));
    1025           0 :                 ShowContinueError(state,
    1026           0 :                                   format("{} [{:.R2}] > {} [{.R2}]",
    1027           0 :                                          state.dataIPShortCut->cNumericFieldNames(2),
    1028             :                                          NumArray(2),
    1029           0 :                                          state.dataIPShortCut->cNumericFieldNames(3),
    1030             :                                          NumArray(3)));
    1031           0 :                 ShowContinueError(
    1032             :                     state,
    1033           0 :                     format("{} cannot be greater than {}", state.dataIPShortCut->cNumericFieldNames(2), state.dataIPShortCut->cNumericFieldNames(3)));
    1034           0 :                 ErrorsFound = true;
    1035             :             }
    1036             : 
    1037             :             // Validate Selection Control
    1038           5 :             demandMgr.SelectionControl = static_cast<ManagerSelection>(getEnumValue(ManagerSelectionNamesUC, Util::makeUPPER(AlphArray(4))));
    1039           5 :             ErrorsFound = ErrorsFound || (demandMgr.SelectionControl == ManagerSelection::Invalid);
    1040             : 
    1041           5 :             if (NumArray(5) == 0.0)
    1042           5 :                 demandMgr.RotationDuration = state.dataGlobal->MinutesPerTimeStep;
    1043             :             else
    1044           0 :                 demandMgr.RotationDuration = NumArray(5);
    1045             : 
    1046             :             // Count actual pointers to controlled zones
    1047           5 :             demandMgr.NumOfLoads = 0;
    1048          10 :             for (int LoadNum = 1; LoadNum <= NumAlphas - 4; ++LoadNum) {
    1049           5 :                 int LoadPtr = Util::FindItemInList(AlphArray(LoadNum + 4), state.dataZoneCtrls->TStatObjects);
    1050           5 :                 if (LoadPtr > 0) {
    1051           5 :                     demandMgr.NumOfLoads += state.dataZoneCtrls->TStatObjects(LoadPtr).NumOfZones;
    1052             :                 } else {
    1053           0 :                     LoadPtr = Util::FindItemInList(AlphArray(LoadNum + 4), state.dataZoneCtrls->TempControlledZone);
    1054           0 :                     if (LoadPtr > 0) {
    1055           0 :                         ++demandMgr.NumOfLoads;
    1056             :                     } else {
    1057           0 :                         ShowSevereError(state,
    1058           0 :                                         format("{}=\"{}\" invalid {}=\"{}\" not found.",
    1059             :                                                CurrentModuleObject,
    1060           0 :                                                state.dataIPShortCut->cAlphaArgs(1),
    1061           0 :                                                state.dataIPShortCut->cAlphaFieldNames(LoadNum + 4),
    1062             :                                                AlphArray(LoadNum + 4)));
    1063           0 :                         ErrorsFound = true;
    1064             :                     }
    1065             :                 }
    1066             :             }
    1067             : 
    1068           5 :             if (demandMgr.NumOfLoads > 0) {
    1069           5 :                 demandMgr.Load.allocate(demandMgr.NumOfLoads);
    1070           5 :                 int LoadNum = 0;
    1071          10 :                 for (int Item = 1; Item <= NumAlphas - 4; ++Item) {
    1072           5 :                     int LoadPtr = Util::FindItemInList(AlphArray(Item + 4), state.dataZoneCtrls->TStatObjects);
    1073           5 :                     if (LoadPtr > 0) {
    1074          30 :                         for (int Item1 = 1; Item1 <= state.dataZoneCtrls->TStatObjects(LoadPtr).NumOfZones; ++Item1) {
    1075          25 :                             ++LoadNum;
    1076          25 :                             demandMgr.Load(LoadNum) = state.dataZoneCtrls->TStatObjects(LoadPtr).TempControlledZoneStartPtr + Item1 - 1;
    1077             :                         }
    1078             :                     } else {
    1079           0 :                         LoadPtr = Util::FindItemInList(AlphArray(Item + 4), state.dataZoneCtrls->TempControlledZone);
    1080           0 :                         if (LoadPtr > 0) {
    1081           0 :                             ++LoadNum;
    1082           0 :                             demandMgr.Load(LoadNum) = LoadPtr;
    1083             :                         }
    1084             :                     }
    1085             :                 } // LoadNum
    1086             :             } else {
    1087           0 :                 ShowSevereError(state,
    1088           0 :                                 format("{}=\"{}\" invalid value for number of loads.", CurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
    1089           0 :                 ShowContinueError(state, "Number of loads is calculated to be less than one. Demand manager must have at least one load assigned.");
    1090           0 :                 ErrorsFound = true;
    1091             :             }
    1092             :         } // MgrNum
    1093             : 
    1094             :         // Get input for DemandManager:Ventilation
    1095           6 :         StartIndex = EndIndex + 1;
    1096           6 :         EndIndex += NumDemandMgrVentilation;
    1097             : 
    1098           6 :         CurrentModuleObject = "DemandManager:Ventilation";
    1099             : 
    1100          11 :         for (int MgrNum = StartIndex; MgrNum <= EndIndex; ++MgrNum) {
    1101           5 :             auto &demandMgr = DemandMgr(MgrNum);
    1102             : 
    1103          15 :             state.dataInputProcessing->inputProcessor->getObjectItem(state,
    1104             :                                                                      CurrentModuleObject,
    1105           5 :                                                                      MgrNum - StartIndex + 1,
    1106             :                                                                      AlphArray,
    1107             :                                                                      NumAlphas,
    1108             :                                                                      NumArray,
    1109             :                                                                      NumNums,
    1110             :                                                                      IOStat,
    1111             :                                                                      _,
    1112           5 :                                                                      state.dataIPShortCut->lAlphaFieldBlanks,
    1113           5 :                                                                      state.dataIPShortCut->cAlphaFieldNames,
    1114           5 :                                                                      state.dataIPShortCut->cNumericFieldNames);
    1115             : 
    1116           5 :             GlobalNames::VerifyUniqueInterObjectName(state,
    1117           5 :                                                      state.dataDemandManager->UniqueDemandMgrNames,
    1118           5 :                                                      AlphArray(1),
    1119             :                                                      CurrentModuleObject,
    1120           5 :                                                      state.dataIPShortCut->cAlphaFieldNames(1),
    1121             :                                                      ErrorsFound);
    1122           5 :             demandMgr.Name = AlphArray(1);
    1123             : 
    1124           5 :             demandMgr.Type = ManagerType::Ventilation;
    1125             : 
    1126           5 :             if (!state.dataIPShortCut->lAlphaFieldBlanks(2)) {
    1127           0 :                 demandMgr.AvailSchedule = ScheduleManager::GetScheduleIndex(state, AlphArray(2));
    1128             : 
    1129           0 :                 if (demandMgr.AvailSchedule == 0) {
    1130           0 :                     ShowSevereError(state,
    1131           0 :                                     format("{}=\"{}\" invalid {}=\"{}\" not found.",
    1132             :                                            CurrentModuleObject,
    1133           0 :                                            state.dataIPShortCut->cAlphaArgs(1),
    1134           0 :                                            state.dataIPShortCut->cAlphaFieldNames(2),
    1135             :                                            AlphArray(2)));
    1136           0 :                     ErrorsFound = true;
    1137             :                 }
    1138             :             } else {
    1139           5 :                 demandMgr.AvailSchedule = ScheduleManager::ScheduleAlwaysOn;
    1140             :             }
    1141             : 
    1142             :             // Validate Limiting Control
    1143           5 :             demandMgr.LimitControl = static_cast<ManagerLimit>(getEnumValue(ManagerLimitVentNamesUC, Util::makeUPPER(AlphArray(3))));
    1144           5 :             ErrorsFound = ErrorsFound || (demandMgr.LimitControl == ManagerLimit::Invalid);
    1145             : 
    1146           5 :             if (NumArray(1) == 0.0)
    1147           0 :                 demandMgr.LimitDuration = state.dataGlobal->MinutesPerTimeStep;
    1148             :             else
    1149           5 :                 demandMgr.LimitDuration = NumArray(1);
    1150             : 
    1151           5 :             if (demandMgr.LimitControl == ManagerLimit::Fixed) demandMgr.FixedRate = NumArray(2);
    1152           5 :             if (demandMgr.LimitControl == ManagerLimit::ReductionRatio) demandMgr.ReductionRatio = NumArray(3);
    1153             : 
    1154           5 :             demandMgr.LowerLimit = NumArray(4);
    1155             : 
    1156             :             // Validate Selection Control
    1157           5 :             demandMgr.SelectionControl = static_cast<ManagerSelection>(getEnumValue(ManagerSelectionNamesUC, Util::makeUPPER(AlphArray(4))));
    1158           5 :             ErrorsFound = ErrorsFound || (demandMgr.SelectionControl == ManagerSelection::Invalid);
    1159             : 
    1160           5 :             if (NumArray(5) == 0.0)
    1161           5 :                 demandMgr.RotationDuration = state.dataGlobal->MinutesPerTimeStep;
    1162             :             else
    1163           0 :                 demandMgr.RotationDuration = NumArray(5);
    1164             : 
    1165             :             // Count number of string fields for loading Controller:OutdoorAir names. This number must be increased in case if
    1166             :             // new string field is added or decreased if string fields are removed.
    1167           5 :             int AlphaShift = 4;
    1168             : 
    1169             :             // Count actual pointers to air controllers
    1170           5 :             demandMgr.NumOfLoads = 0;
    1171          10 :             for (int LoadNum = 1; LoadNum <= NumAlphas - AlphaShift; ++LoadNum) {
    1172           5 :                 int LoadPtr = MixedAir::GetOAController(state, AlphArray(LoadNum + AlphaShift));
    1173           5 :                 if (LoadPtr > 0) {
    1174           5 :                     ++demandMgr.NumOfLoads;
    1175             :                 } else {
    1176           0 :                     ShowSevereError(state,
    1177           0 :                                     format("{}=\"{}\" invalid {}=\"{}\" not found.",
    1178             :                                            CurrentModuleObject,
    1179           0 :                                            state.dataIPShortCut->cAlphaArgs(1),
    1180           0 :                                            state.dataIPShortCut->cAlphaFieldNames(LoadNum + AlphaShift),
    1181             :                                            AlphArray(LoadNum + AlphaShift)));
    1182           0 :                     ErrorsFound = true;
    1183             :                 }
    1184             :             }
    1185             : 
    1186           5 :             if (demandMgr.NumOfLoads > 0) {
    1187           5 :                 demandMgr.Load.allocate(demandMgr.NumOfLoads);
    1188          10 :                 for (int LoadNum = 1; LoadNum <= NumAlphas - AlphaShift; ++LoadNum) {
    1189           5 :                     int LoadPtr = MixedAir::GetOAController(state, AlphArray(LoadNum + AlphaShift));
    1190           5 :                     if (LoadPtr > 0) {
    1191           5 :                         demandMgr.Load(LoadNum) = LoadPtr;
    1192             :                     }
    1193             :                 }
    1194             :             } else {
    1195           0 :                 ShowSevereError(state,
    1196           0 :                                 format("{}=\"{}\" invalid value for number of loads.", CurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
    1197           0 :                 ShowContinueError(state, "Number of loads is calculated to be less than one. Demand manager must have at least one load assigned.");
    1198           0 :                 ErrorsFound = true;
    1199             :             }
    1200             :         } // MgrNum
    1201             : 
    1202           6 :         AlphArray.deallocate();
    1203           6 :         NumArray.deallocate();
    1204             :     }
    1205             : 
    1206         795 :     if (ErrorsFound) {
    1207           0 :         ShowFatalError(state, "Errors found in processing input for demand managers. Preceding condition causes termination.");
    1208             :     }
    1209         795 : }
    1210             : 
    1211        1445 : void SurveyDemandManagers(EnergyPlusData &state)
    1212             : {
    1213             : 
    1214             :     // SUBROUTINE INFORMATION:
    1215             :     //       AUTHOR         Peter Graham Ellis
    1216             :     //       DATE WRITTEN   July 2005
    1217             : 
    1218             :     // PURPOSE OF THIS SUBROUTINE:
    1219             :     // Checks to see if any demand managers can reduce the load
    1220             : 
    1221             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1222             :     bool CanReduceDemand;
    1223             : 
    1224       10260 :     for (int MgrNum = 1; MgrNum <= state.dataDemandManager->NumDemandMgr; ++MgrNum) {
    1225             : 
    1226        8815 :         auto &demandMgr = state.dataDemandManager->DemandMgr(MgrNum);
    1227             : 
    1228        8815 :         demandMgr.CanReduceDemand = false;
    1229             : 
    1230        8815 :         if (!demandMgr.Available) continue;
    1231        8815 :         if (demandMgr.LimitControl == ManagerLimit::Off) continue;
    1232             : 
    1233        8815 :         if (demandMgr.Active) continue; // This works for FIXED control action, but not VARIABLE
    1234             :         // VARIABLE control could actually reduce demand farther, even if active already
    1235             : 
    1236       11467 :         for (int LoadNum = 1; LoadNum <= demandMgr.NumOfLoads; ++LoadNum) {
    1237       10579 :             int LoadPtr = demandMgr.Load(LoadNum);
    1238             : 
    1239             :             // Check if this load can reduce demand
    1240             :             // Assume FIXED control action for now, needs more sophisticated check for VARIABLE control
    1241       10579 :             LoadInterface(state, DemandAction::CheckCanReduce, MgrNum, LoadPtr, CanReduceDemand);
    1242             : 
    1243       10579 :             if (CanReduceDemand) {
    1244        6139 :                 demandMgr.CanReduceDemand = true;
    1245        6139 :                 break; // If any one load can reduce demand, then the whole demand manager can reduce demand
    1246             :             }
    1247             : 
    1248             :         } // LoadNum
    1249             : 
    1250             :     } // MgrNum
    1251        1445 : }
    1252             : 
    1253        1445 : void ActivateDemandManagers(EnergyPlusData &state)
    1254             : {
    1255             : 
    1256             :     // SUBROUTINE INFORMATION:
    1257             :     //       AUTHOR         Peter Graham Ellis
    1258             :     //       DATE WRITTEN   July 2005
    1259             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1260             :     int LoadPtr;
    1261             : 
    1262       10260 :     for (int MgrNum = 1; MgrNum <= state.dataDemandManager->NumDemandMgr; ++MgrNum) {
    1263             : 
    1264        8815 :         auto &demandMgr = state.dataDemandManager->DemandMgr(MgrNum);
    1265             : 
    1266        8815 :         if (demandMgr.Activate) {
    1267             :             bool CanReduceDemand;
    1268         293 :             demandMgr.Activate = false;
    1269         293 :             demandMgr.Active = true;
    1270             : 
    1271         293 :             switch (demandMgr.SelectionControl) {
    1272         293 :             case ManagerSelection::All: {
    1273             :                 // Turn ON limiting on all loads
    1274         790 :                 for (int LoadNum = 1; LoadNum <= demandMgr.NumOfLoads; ++LoadNum) {
    1275         497 :                     LoadPtr = demandMgr.Load(LoadNum);
    1276         497 :                     LoadInterface(state, DemandAction::SetLimit, MgrNum, LoadPtr, CanReduceDemand);
    1277             :                 } // LoadNum
    1278             : 
    1279         293 :             } break;
    1280           0 :             case ManagerSelection::Many: { // All loads are limited except for one
    1281           0 :                 if (demandMgr.NumOfLoads > 1) {
    1282             : 
    1283             :                     // Turn ON limiting on all loads
    1284           0 :                     for (int LoadNum = 1; LoadNum <= demandMgr.NumOfLoads; ++LoadNum) {
    1285           0 :                         LoadPtr = demandMgr.Load(LoadNum);
    1286           0 :                         LoadInterface(state, DemandAction::SetLimit, MgrNum, LoadPtr, CanReduceDemand);
    1287             :                     } // LoadNum
    1288             : 
    1289             :                     // Set next rotated load (from last time it was active)
    1290           0 :                     int RotatedLoadNum = demandMgr.RotatedLoadNum;
    1291           0 :                     ++RotatedLoadNum;
    1292           0 :                     if (RotatedLoadNum > demandMgr.NumOfLoads) RotatedLoadNum = 1;
    1293           0 :                     demandMgr.RotatedLoadNum = RotatedLoadNum;
    1294             : 
    1295             :                     // Turn OFF limiting for the new rotated load
    1296           0 :                     LoadPtr = demandMgr.Load(RotatedLoadNum);
    1297           0 :                     LoadInterface(state, DemandAction::ClearLimit, MgrNum, LoadPtr, CanReduceDemand);
    1298             :                 } else {
    1299             :                     // Turn ON limiting for the one and only load
    1300           0 :                     LoadPtr = demandMgr.Load(1);
    1301           0 :                     LoadInterface(state, DemandAction::SetLimit, MgrNum, LoadPtr, CanReduceDemand);
    1302             :                 }
    1303             : 
    1304           0 :             } break;
    1305           0 :             case ManagerSelection::One: { // Only one load is limited
    1306           0 :                 if (demandMgr.NumOfLoads > 1) {
    1307             :                     // Turn OFF limiting on all loads
    1308           0 :                     for (int LoadNum = 1; LoadNum <= demandMgr.NumOfLoads; ++LoadNum) {
    1309           0 :                         LoadPtr = demandMgr.Load(LoadNum);
    1310           0 :                         LoadInterface(state, DemandAction::ClearLimit, MgrNum, LoadPtr, CanReduceDemand);
    1311             :                     } // LoadNum
    1312             : 
    1313             :                     // Set next rotated load (from last time it was active)
    1314           0 :                     int RotatedLoadNum = demandMgr.RotatedLoadNum;
    1315           0 :                     ++RotatedLoadNum;
    1316           0 :                     if (RotatedLoadNum > demandMgr.NumOfLoads) RotatedLoadNum = 1;
    1317           0 :                     demandMgr.RotatedLoadNum = RotatedLoadNum;
    1318             : 
    1319             :                     // Turn ON limiting for the new rotated load
    1320           0 :                     LoadPtr = demandMgr.Load(RotatedLoadNum);
    1321           0 :                     LoadInterface(state, DemandAction::SetLimit, MgrNum, LoadPtr, CanReduceDemand);
    1322             :                 } else {
    1323             :                     // Turn ON limiting for the one and only load
    1324           0 :                     LoadPtr = demandMgr.Load(1);
    1325           0 :                     LoadInterface(state, DemandAction::SetLimit, MgrNum, LoadPtr, CanReduceDemand);
    1326             :                 }
    1327           0 :             } break;
    1328           0 :             default:
    1329           0 :                 break;
    1330             :             }
    1331             :         }
    1332             : 
    1333             :     } // MgrNum
    1334        1445 : }
    1335             : 
    1336     2804482 : void UpdateDemandManagers(EnergyPlusData &state)
    1337             : {
    1338             : 
    1339             :     // SUBROUTINE INFORMATION:
    1340             :     //       AUTHOR         Peter Graham Ellis
    1341             :     //       DATE WRITTEN   July 2005
    1342             : 
    1343             :     // PURPOSE OF THIS SUBROUTINE:
    1344             :     // Expires limits and rotates loads after specified time duration.
    1345             :     // It updates availability flags, expires managers that ended in the last timestep, etc.
    1346             : 
    1347             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1348             :     int LoadPtr;
    1349             :     bool Available;
    1350             :     bool CanReduceDemand;
    1351             :     int RotatedLoadNum;
    1352             : 
    1353     2852866 :     for (int MgrNum = 1; MgrNum <= state.dataDemandManager->NumDemandMgr; ++MgrNum) {
    1354             : 
    1355       48384 :         auto &demandMgr = state.dataDemandManager->DemandMgr(MgrNum);
    1356             : 
    1357             :         // Check availability
    1358       48384 :         if (ScheduleManager::GetCurrentScheduleValue(state, demandMgr.AvailSchedule) > 0.0) {
    1359       48384 :             Available = true;
    1360             :         } else {
    1361           0 :             Available = false;
    1362             :         }
    1363             :         //    END IF
    1364             : 
    1365       48384 :         demandMgr.Available = Available;
    1366             : 
    1367             :         // Update demand manager status
    1368       48384 :         if (Available) {
    1369             : 
    1370       48384 :             if (demandMgr.Active) {
    1371             : 
    1372        1172 :                 demandMgr.ElapsedTime += state.dataGlobal->MinutesPerTimeStep;
    1373             : 
    1374             :                 // Check for expiring limit duration
    1375        1172 :                 if (demandMgr.ElapsedTime >= demandMgr.LimitDuration) {
    1376         293 :                     demandMgr.ElapsedTime = 0;
    1377         293 :                     demandMgr.ElapsedRotationTime = 0;
    1378         293 :                     demandMgr.Active = false;
    1379             : 
    1380             :                     // Demand Manager is not available, remove demand limits from all loads
    1381         790 :                     for (int LoadNum = 1; LoadNum <= demandMgr.NumOfLoads; ++LoadNum) {
    1382         497 :                         LoadPtr = demandMgr.Load(LoadNum);
    1383         497 :                         LoadInterface(state, DemandAction::ClearLimit, MgrNum, LoadPtr, CanReduceDemand);
    1384             :                     } // LoadNum
    1385             : 
    1386             :                 } else {
    1387             : 
    1388         879 :                     switch (demandMgr.SelectionControl) {
    1389         879 :                     case ManagerSelection::All: {
    1390             :                         // Do nothing; limits remain on all loads
    1391             : 
    1392         879 :                     } break;
    1393           0 :                     case ManagerSelection::Many: { // All loads are limited except for one
    1394           0 :                         demandMgr.ElapsedRotationTime += state.dataGlobal->MinutesPerTimeStep;
    1395             : 
    1396           0 :                         if (demandMgr.ElapsedRotationTime >= demandMgr.RotationDuration) {
    1397           0 :                             demandMgr.ElapsedRotationTime = 0;
    1398             : 
    1399           0 :                             if (demandMgr.NumOfLoads > 1) {
    1400             :                                 // Turn ON limiting for the old rotated load
    1401           0 :                                 RotatedLoadNum = demandMgr.RotatedLoadNum;
    1402           0 :                                 LoadPtr = demandMgr.Load(RotatedLoadNum);
    1403           0 :                                 LoadInterface(state, DemandAction::SetLimit, MgrNum, LoadPtr, CanReduceDemand);
    1404             : 
    1405             :                                 // Set next rotated load
    1406           0 :                                 ++RotatedLoadNum;
    1407           0 :                                 if (RotatedLoadNum > demandMgr.NumOfLoads) RotatedLoadNum = 1;
    1408           0 :                                 demandMgr.RotatedLoadNum = RotatedLoadNum;
    1409             : 
    1410             :                                 // Turn OFF limiting for the new rotated load
    1411           0 :                                 LoadPtr = demandMgr.Load(RotatedLoadNum);
    1412           0 :                                 LoadInterface(state, DemandAction::ClearLimit, MgrNum, LoadPtr, CanReduceDemand);
    1413             :                             }
    1414             :                         }
    1415             : 
    1416           0 :                     } break;
    1417           0 :                     case ManagerSelection::One: { // Only one load is limited
    1418           0 :                         demandMgr.ElapsedRotationTime += state.dataGlobal->MinutesPerTimeStep;
    1419             : 
    1420           0 :                         if (demandMgr.ElapsedRotationTime >= demandMgr.RotationDuration) {
    1421           0 :                             demandMgr.ElapsedRotationTime = 0;
    1422             : 
    1423           0 :                             if (demandMgr.NumOfLoads > 1) {
    1424             :                                 // Turn OFF limiting for the old rotated load
    1425           0 :                                 RotatedLoadNum = demandMgr.RotatedLoadNum;
    1426           0 :                                 LoadPtr = demandMgr.Load(RotatedLoadNum);
    1427           0 :                                 LoadInterface(state, DemandAction::ClearLimit, MgrNum, LoadPtr, CanReduceDemand);
    1428             : 
    1429             :                                 // Set next rotated load
    1430           0 :                                 ++RotatedLoadNum;
    1431           0 :                                 if (RotatedLoadNum > demandMgr.NumOfLoads) RotatedLoadNum = 1;
    1432           0 :                                 demandMgr.RotatedLoadNum = RotatedLoadNum;
    1433             : 
    1434             :                                 // Turn ON limiting for the new rotated load
    1435           0 :                                 LoadPtr = demandMgr.Load(RotatedLoadNum);
    1436           0 :                                 LoadInterface(state, DemandAction::SetLimit, MgrNum, LoadPtr, CanReduceDemand);
    1437             :                             }
    1438             :                         }
    1439           0 :                     } break;
    1440           0 :                     default:
    1441           0 :                         break;
    1442             :                     }
    1443             :                 }
    1444             :             }
    1445             : 
    1446             :         } else { // Demand Manager is not available
    1447           0 :             demandMgr.Active = false;
    1448             : 
    1449             :             // Demand Manager is not available, remove demand limits from all loads
    1450           0 :             for (int LoadNum = 1; LoadNum <= demandMgr.NumOfLoads; ++LoadNum) {
    1451           0 :                 LoadPtr = demandMgr.Load(LoadNum);
    1452           0 :                 LoadInterface(state, DemandAction::ClearLimit, MgrNum, LoadPtr, CanReduceDemand);
    1453             :             } // LoadNum
    1454             :         }
    1455             : 
    1456             :     } // MgrNum
    1457     2804482 : }
    1458             : 
    1459        1152 : void ReportDemandManagerList(EnergyPlusData &state, int const ListNum)
    1460             : {
    1461             : 
    1462             :     // SUBROUTINE INFORMATION:
    1463             :     //       AUTHOR         Peter Graham Ellis
    1464             :     //       DATE WRITTEN   July 2005
    1465             : 
    1466             :     // PURPOSE OF THIS SUBROUTINE:
    1467             :     // Calculates report variables.
    1468             : 
    1469             :     // METHODOLOGY EMPLOYED:
    1470             :     // Standard EnergyPlus methodology.
    1471             : 
    1472             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1473             :     Real64 BillingPeriod;
    1474             :     int AveragingWindow;
    1475             :     bool OnPeak;
    1476             :     Real64 OverLimit;
    1477             : 
    1478        1152 :     auto &demandManagerList = state.dataDemandManager->DemandManagerList(ListNum);
    1479             : 
    1480        1152 :     if (demandManagerList.BillingSchedule == 0) {
    1481        1152 :         BillingPeriod = state.dataEnvrn->Month;
    1482             :     } else {
    1483           0 :         BillingPeriod = ScheduleManager::GetCurrentScheduleValue(state, demandManagerList.BillingSchedule);
    1484             :     }
    1485             : 
    1486        1152 :     if (demandManagerList.BillingPeriod != BillingPeriod) {
    1487             :         // Reset variables for new billing period
    1488             :         // demandManagerList%History = 0.0        ! Don't reset--continue from previous billing period
    1489             :         // demandManagerList%AverageDemand = 0.0  ! Don't reset--continue from previous billing period
    1490          12 :         demandManagerList.PeakDemand = 0.0;
    1491          12 :         demandManagerList.OverLimitDuration = 0.0;
    1492             : 
    1493          12 :         demandManagerList.BillingPeriod = BillingPeriod;
    1494             :     }
    1495             : 
    1496             :     // Add new timestep to demand history and subtract oldest timestep
    1497        1152 :     AveragingWindow = demandManagerList.AveragingWindow;
    1498        1152 :     demandManagerList.AverageDemand += (demandManagerList.MeterDemand - demandManagerList.History(1)) / AveragingWindow;
    1499             : 
    1500             :     // Update demand history
    1501        1152 :     for (int Item = 1; Item <= AveragingWindow - 1; ++Item) {
    1502           0 :         demandManagerList.History(Item) = demandManagerList.History(Item + 1);
    1503             :     }
    1504        1152 :     demandManagerList.History(AveragingWindow) = demandManagerList.MeterDemand;
    1505             : 
    1506        1152 :     if (demandManagerList.PeakSchedule == 0) {
    1507        1152 :         OnPeak = true;
    1508             :     } else {
    1509           0 :         if (ScheduleManager::GetCurrentScheduleValue(state, demandManagerList.PeakSchedule) == 1) {
    1510           0 :             OnPeak = true;
    1511             :         } else {
    1512           0 :             OnPeak = false;
    1513             :         }
    1514             :     }
    1515             : 
    1516        1152 :     if (OnPeak) {
    1517        1152 :         demandManagerList.PeakDemand = max(demandManagerList.AverageDemand, demandManagerList.PeakDemand);
    1518             : 
    1519        1152 :         OverLimit = demandManagerList.AverageDemand - demandManagerList.ScheduledLimit;
    1520        1152 :         if (OverLimit > 0.0) {
    1521          36 :             demandManagerList.OverLimit = OverLimit;
    1522          36 :             demandManagerList.OverLimitDuration += (state.dataGlobal->MinutesPerTimeStep / 60.0);
    1523             :         } else {
    1524        1116 :             demandManagerList.OverLimit = 0.0;
    1525             :         }
    1526             : 
    1527             :     } else {
    1528           0 :         demandManagerList.OverLimit = 0.0;
    1529             :     }
    1530        1152 : }
    1531             : 
    1532       11573 : void LoadInterface(EnergyPlusData &state, DemandAction const Action, int const MgrNum, int const LoadPtr, bool &CanReduceDemand)
    1533             : {
    1534             : 
    1535             :     // SUBROUTINE INFORMATION:
    1536             :     //       AUTHOR         Peter Graham Ellis
    1537             :     //       DATE WRITTEN   August 2005
    1538             : 
    1539             :     // PURPOSE OF THIS SUBROUTINE:
    1540             :     // Provides a universal interface to handle all communication with the various load objects.
    1541             :     // Demand managers for new types of loads can be easily added with a new CASE statement in this subroutine
    1542             :     // and new GetInput code.
    1543             : 
    1544       11573 :     auto const &demandMgr = state.dataDemandManager->DemandMgr(MgrNum);
    1545             : 
    1546             :     // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
    1547             :     Real64 LowestPower;
    1548             : 
    1549       11573 :     CanReduceDemand = false;
    1550             : 
    1551       11573 :     switch (demandMgr.Type) {
    1552         938 :     case ManagerType::ExtLights: {
    1553         938 :         LowestPower = state.dataExteriorEnergyUse->ExteriorLights(LoadPtr).DesignLevel * demandMgr.LowerLimit;
    1554         938 :         if (Action == DemandAction::CheckCanReduce) {
    1555         828 :             if (state.dataExteriorEnergyUse->ExteriorLights(LoadPtr).Power > LowestPower) CanReduceDemand = true;
    1556         110 :         } else if (Action == DemandAction::SetLimit) {
    1557          55 :             state.dataExteriorEnergyUse->ExteriorLights(LoadPtr).ManageDemand = true;
    1558          55 :             state.dataExteriorEnergyUse->ExteriorLights(LoadPtr).DemandLimit = LowestPower;
    1559          55 :         } else if (Action == DemandAction::ClearLimit) {
    1560          55 :             state.dataExteriorEnergyUse->ExteriorLights(LoadPtr).ManageDemand = false;
    1561             :         }
    1562         938 :     } break;
    1563        5294 :     case ManagerType::Lights: {
    1564        5294 :         LowestPower = state.dataHeatBal->Lights(LoadPtr).DesignLevel * demandMgr.LowerLimit;
    1565        5294 :         if (Action == DemandAction::CheckCanReduce) {
    1566        4784 :             if (state.dataHeatBal->Lights(LoadPtr).Power > LowestPower) CanReduceDemand = true;
    1567         510 :         } else if (Action == DemandAction::SetLimit) {
    1568         255 :             state.dataHeatBal->Lights(LoadPtr).ManageDemand = true;
    1569         255 :             state.dataHeatBal->Lights(LoadPtr).DemandLimit = LowestPower;
    1570         255 :         } else if (Action == DemandAction::ClearLimit) {
    1571         255 :             state.dataHeatBal->Lights(LoadPtr).ManageDemand = false;
    1572             :         }
    1573             : 
    1574        5294 :     } break;
    1575        3131 :     case ManagerType::ElecEquip: {
    1576        3131 :         LowestPower = state.dataHeatBal->ZoneElectric(LoadPtr).DesignLevel * demandMgr.LowerLimit;
    1577        3131 :         if (Action == DemandAction::CheckCanReduce) {
    1578        2841 :             if (state.dataHeatBal->ZoneElectric(LoadPtr).Power > LowestPower) CanReduceDemand = true;
    1579         290 :         } else if (Action == DemandAction::SetLimit) {
    1580         145 :             state.dataHeatBal->ZoneElectric(LoadPtr).ManageDemand = true;
    1581         145 :             state.dataHeatBal->ZoneElectric(LoadPtr).DemandLimit = LowestPower;
    1582         145 :         } else if (Action == DemandAction::ClearLimit) {
    1583         145 :             state.dataHeatBal->ZoneElectric(LoadPtr).ManageDemand = false;
    1584             :         }
    1585        3131 :     } break;
    1586        1233 :     case ManagerType::Thermostats: {
    1587        1233 :         if (Action == DemandAction::CheckCanReduce) {
    1588        1233 :             if (state.dataHeatBalFanSys->ZoneThermostatSetPointLo(state.dataZoneCtrls->TempControlledZone(LoadPtr).ActualZoneNum) >
    1589        1986 :                     demandMgr.LowerLimit ||
    1590         753 :                 state.dataHeatBalFanSys->ZoneThermostatSetPointHi(state.dataZoneCtrls->TempControlledZone(LoadPtr).ActualZoneNum) <
    1591         753 :                     demandMgr.UpperLimit)
    1592        1233 :                 CanReduceDemand = true; // Heating | Cooling
    1593           0 :         } else if (Action == DemandAction::SetLimit) {
    1594           0 :             state.dataZoneCtrls->TempControlledZone(LoadPtr).ManageDemand = true;
    1595           0 :             state.dataZoneCtrls->TempControlledZone(LoadPtr).HeatingResetLimit = demandMgr.LowerLimit;
    1596           0 :             state.dataZoneCtrls->TempControlledZone(LoadPtr).CoolingResetLimit = demandMgr.UpperLimit;
    1597           0 :         } else if (Action == DemandAction::ClearLimit) {
    1598           0 :             state.dataZoneCtrls->TempControlledZone(LoadPtr).ManageDemand = false;
    1599             :         }
    1600        1233 :         if (state.dataZoneCtrls->NumComfortControlledZones > 0) {
    1601           0 :             if (state.dataHeatBalFanSys->ComfortControlType(state.dataZoneCtrls->TempControlledZone(LoadPtr).ActualZoneNum) !=
    1602             :                 HVAC::ThermostatType::Uncontrolled) {
    1603           0 :                 if (Action == DemandAction::CheckCanReduce) {
    1604           0 :                     if (state.dataHeatBalFanSys->ZoneThermostatSetPointLo(state.dataZoneCtrls->ComfortControlledZone(LoadPtr).ActualZoneNum) >
    1605           0 :                             demandMgr.LowerLimit ||
    1606           0 :                         state.dataHeatBalFanSys->ZoneThermostatSetPointHi(state.dataZoneCtrls->ComfortControlledZone(LoadPtr).ActualZoneNum) <
    1607           0 :                             demandMgr.UpperLimit)
    1608           0 :                         CanReduceDemand = true; // Heating
    1609           0 :                 } else if (Action == DemandAction::SetLimit) {
    1610           0 :                     state.dataZoneCtrls->ComfortControlledZone(LoadPtr).ManageDemand = true;
    1611           0 :                     state.dataZoneCtrls->ComfortControlledZone(LoadPtr).HeatingResetLimit = demandMgr.LowerLimit;
    1612           0 :                     state.dataZoneCtrls->ComfortControlledZone(LoadPtr).CoolingResetLimit = demandMgr.UpperLimit;
    1613           0 :                 } else if (Action == DemandAction::ClearLimit) {
    1614           0 :                     state.dataZoneCtrls->ComfortControlledZone(LoadPtr).ManageDemand = false;
    1615             :                 }
    1616             :             }
    1617             :         }
    1618        1233 :     } break;
    1619         977 :     case ManagerType::Ventilation: {
    1620         977 :         Real64 FlowRate(0);
    1621         977 :         FlowRate = MixedAir::OAGetFlowRate(state, LoadPtr);
    1622         977 :         if (Action == DemandAction::CheckCanReduce) {
    1623         893 :             CanReduceDemand = true;
    1624          84 :         } else if (Action == DemandAction::SetLimit) {
    1625          42 :             MixedAir::OASetDemandManagerVentilationState(state, LoadPtr, true);
    1626          42 :             if (demandMgr.LimitControl == ManagerLimit::Fixed) {
    1627          22 :                 MixedAir::OASetDemandManagerVentilationFlow(state, LoadPtr, demandMgr.FixedRate);
    1628          20 :             } else if (demandMgr.LimitControl == ManagerLimit::ReductionRatio) {
    1629          20 :                 Real64 DemandRate(0);
    1630          20 :                 DemandRate = FlowRate * demandMgr.ReductionRatio;
    1631          20 :                 MixedAir::OASetDemandManagerVentilationFlow(state, LoadPtr, DemandRate);
    1632             :             }
    1633          42 :         } else if (Action == DemandAction::ClearLimit) {
    1634          42 :             MixedAir::OASetDemandManagerVentilationState(state, LoadPtr, false);
    1635             :         }
    1636         977 :     } break;
    1637           0 :     default:
    1638           0 :         break;
    1639             :     }
    1640       11573 : }
    1641             : 
    1642         795 : void InitDemandManagers(EnergyPlusData &state)
    1643             : {
    1644             : 
    1645             :     // SUBROUTINE INFORMATION:
    1646             :     //       AUTHOR         Linda Lawrie
    1647             :     //       DATE WRITTEN   September 2010
    1648             : 
    1649             :     // PURPOSE OF THIS SUBROUTINE:
    1650             :     // Provide external call to get Demand manager input after
    1651             :     // appropriate initializations.
    1652             : 
    1653         795 :     if (state.dataDemandManager->GetInput) {
    1654         795 :         GetDemandManagerInput(state);
    1655         795 :         GetDemandManagerListInput(state);
    1656         795 :         state.dataDemandManager->GetInput = false;
    1657             :     }
    1658         795 : }
    1659             : 
    1660             : } // namespace EnergyPlus::DemandManager

Generated by: LCOV version 1.14