Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2023, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <algorithm>
50 : #include <cmath>
51 :
52 : // ObjexxFCL Headers
53 : #include <ObjexxFCL/Array.functions.hh>
54 : #include <ObjexxFCL/Array2D.hh>
55 : #include <ObjexxFCL/Fmath.hh>
56 :
57 : // EnergyPlus Headers
58 : #include <AirflowNetwork/Elements.hpp>
59 : #include <AirflowNetwork/Solver.hpp>
60 : #include <EnergyPlus/CurveManager.hh>
61 : #include <EnergyPlus/Data/EnergyPlusData.hh>
62 : #include <EnergyPlus/DataAirLoop.hh>
63 : #include <EnergyPlus/DataAirSystems.hh>
64 : #include <EnergyPlus/DataContaminantBalance.hh>
65 : #include <EnergyPlus/DataEnvironment.hh>
66 : #include <EnergyPlus/DataGlobalConstants.hh>
67 : #include <EnergyPlus/DataHVACGlobals.hh>
68 : #include <EnergyPlus/DataHeatBalFanSys.hh>
69 : #include <EnergyPlus/DataHeatBalance.hh>
70 : #include <EnergyPlus/DataIPShortCuts.hh>
71 : #include <EnergyPlus/DataLoopNode.hh>
72 : #include <EnergyPlus/DataZoneControls.hh>
73 : #include <EnergyPlus/DataZoneEquipment.hh>
74 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
75 : #include <EnergyPlus/NodeInputManager.hh>
76 : #include <EnergyPlus/OutputProcessor.hh>
77 : #include <EnergyPlus/Plant/DataPlant.hh>
78 : #include <EnergyPlus/Psychrometrics.hh>
79 : #include <EnergyPlus/ScheduleManager.hh>
80 : #include <EnergyPlus/SystemAvailabilityManager.hh>
81 : #include <EnergyPlus/ThermalComfort.hh>
82 : #include <EnergyPlus/UtilityRoutines.hh>
83 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
84 :
85 : namespace EnergyPlus {
86 :
87 : namespace SystemAvailabilityManager {
88 :
89 : // Module containing the System Availability Manager routines
90 :
91 : // MODULE INFORMATION:
92 : // AUTHOR Fred Buhl
93 : // DATE WRITTEN August 2001
94 : // MODIFIED February 2004, PGE: Added plant managers.
95 : // MODIFIED March 2007, LG: Added hybrid ventilation control.
96 : // August 2008, R. Raustad - FSEC: added 2 new scheduled sys avail managers
97 : // March 2011, Chandan Sharma - FSEC: Added zone sys avail managers
98 : // August 2013, Xiufeng Pang (XP) - added algorithms for optimal start
99 : // RE-ENGINEERED na
100 :
101 : // PURPOSE OF THIS MODULE
102 : // To encapsulate the data and algorithms required to
103 : // determine system (loop) availability and "cycle on" status.
104 :
105 : // METHODOLOGY EMPLOYED:
106 : // Previous time step node data and current zone thermostat setpoints are used
107 : // in a set of fixed, precoded algorithms to determine the current time step
108 : // on/off status of systems and loops.
109 :
110 : // USE STATEMENTS:
111 : // Use statements for data only modules
112 : using namespace DataHVACGlobals;
113 : using namespace ScheduleManager;
114 :
115 : // Hybrid Ventilation parameters
116 : int constexpr HybridVentMode_No = 0; // No hybrid ventilation control
117 : int constexpr HybridVentMode_Temp = 1; // Temperature control
118 : int constexpr HybridVentMode_Enth = 2; // Enthalpy control
119 : int constexpr HybridVentMode_DewPoint = 3; // Dew point control
120 : int constexpr HybridVentMode_OA = 4; // Outdoor air control
121 : int constexpr HybridVentMode_OperT80 = 5; // Operative temperature control with 80% acceptability limits
122 : int constexpr HybridVentMode_OperT90 = 6; // Operative temperature control with 90% acceptability limits
123 : int constexpr HybridVentMode_CO2 = 7; // CO2 control
124 :
125 : int constexpr HybridVentCtrl_NoAction = 0; // No hybrid ventilation control
126 : int constexpr HybridVentCtrl_Open = 1; // Open windows or doors
127 : int constexpr HybridVentCtrl_Close = 2; // Close windows or doors
128 :
129 : static constexpr std::array<std::string_view, static_cast<int>(DataPlant::SystemAvailabilityType::Num)> SystemAvailabilityTypeNamesUC{
130 : "AVAILABILITYMANAGER:SCHEDULED",
131 : "AVAILABILITYMANAGER:SCHEDULEDON",
132 : "AVAILABILITYMANAGER:SCHEDULEDOFF",
133 : "AVAILABILITYMANAGER:NIGHTCYCLE",
134 : "AVAILABILITYMANAGER:DIFFERENTIALTHERMOSTAT",
135 : "AVAILABILITYMANAGER:HIGHTEMPERATURETURNOFF",
136 : "AVAILABILITYMANAGER:HIGHTEMPERATURETURNON",
137 : "AVAILABILITYMANAGER:LOWTEMPERATURETURNOFF",
138 : "AVAILABILITYMANAGER:LOWTEMPERATURETURNON",
139 : "AVAILABILITYMANAGER:NIGHTVENTILATION",
140 : "AVAILABILITYMANAGER:HYBRIDVENTILATION",
141 : "AVAILABILITYMANAGER:OPTIMUMSTART"};
142 :
143 : static constexpr std::array<std::string_view, static_cast<int>(DataPlant::SystemAvailabilityType::Num)> SystemAvailabilityTypeNamesCC{
144 : "AvailabilityManager:Scheduled",
145 : "AvailabilityManager:ScheduledOn",
146 : "AvailabilityManager:ScheduledOff",
147 : "AvailabilityManager:NightCycle",
148 : "AvailabilityManager:DifferentialThermostat",
149 : "AvailabilityManager:HighTemperatureTurnOff",
150 : "AvailabilityManager:HighTemperatureTurnOn",
151 : "AvailabilityManager:LowTemperatureTurnOff",
152 : "AvailabilityManager:LowTemperatureTurnOn",
153 : "AvailabilityManager:NightVentilation",
154 : "AvailabilityManager:HybridVentilation",
155 : "AvailabilityManager:OptimumStart"};
156 :
157 2638872 : void ManageSystemAvailability(EnergyPlusData &state)
158 : {
159 :
160 : // SUBROUTINE INFORMATION:
161 : // AUTHOR Fred Buhl
162 : // DATE WRITTEN August 2001
163 : // MODIFIED L. Gu, April, 2007. Added hybrid ventilation control
164 : // Chandan Sharma, March 2011/July 2012 - FSEC: Added zone sys avail managers
165 : // RE-ENGINEERED na
166 :
167 : // PURPOSE OF THIS SUBROUTINE:
168 : // Manage the simulation of the System Availability Managers
169 :
170 : using DataZoneEquipment::NumValidSysAvailZoneComponents;
171 : using namespace DataLoopNode;
172 : using namespace DataAirLoop;
173 : using namespace DataPlant;
174 :
175 : int PriAirSysNum; // Primary Air System index
176 : int PriAirSysAvailMgrNum; // Index of Sys Avail Manager in a Primary Air System
177 : int PlantNum; // Plant Loop index
178 : int PlantAvailMgrNum; // Index of Plant Avail Manager in a Plant Loop
179 : int AvailStatus;
180 : int PreviousStatus;
181 : int ZoneInSysNum;
182 : int CtrldZoneNum;
183 : int HybridVentNum; // Hybrid ventilation control number
184 : int ZoneEquipType; // Type of ZoneHVAC:* component
185 : int CompNum; // Index of ZoneHVAC:* component
186 : int ZoneCompAvailMgrNum; // Index of availability manager associated with the ZoneHVAC:* component
187 2638872 : int constexpr DummyArgument(1); // This variable is used when SimSysAvailManager is called for a ZoneHVAC:* component
188 :
189 2638872 : if (state.dataSystemAvailabilityManager->GetAvailMgrInputFlag) {
190 250 : GetSysAvailManagerInputs(state);
191 250 : state.dataSystemAvailabilityManager->GetAvailMgrInputFlag = false;
192 250 : return;
193 : }
194 :
195 2638622 : InitSysAvailManagers(state);
196 :
197 6859801 : for (PriAirSysNum = 1; PriAirSysNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++PriAirSysNum) { // loop over the primary air systems
198 :
199 4221179 : PreviousStatus = state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).AvailStatus; // Save the previous status for differential thermostat
200 4221179 : state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).AvailStatus = NoAction; // initialize the availability to "take no action"
201 :
202 8022340 : for (PriAirSysAvailMgrNum = 1; PriAirSysAvailMgrNum <= state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).NumAvailManagers;
203 : ++PriAirSysAvailMgrNum) { // loop over the avail managers in system
204 :
205 12405576 : SimSysAvailManager(state,
206 4135192 : state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).AvailManagerType(PriAirSysAvailMgrNum),
207 4135192 : state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).AvailManagerName(PriAirSysAvailMgrNum),
208 4135192 : state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).AvailManagerNum(PriAirSysAvailMgrNum),
209 : PriAirSysNum,
210 : PreviousStatus,
211 : AvailStatus);
212 :
213 4135192 : if (AvailStatus == ForceOff) {
214 334031 : state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).AvailStatus = ForceOff;
215 334031 : break; // Fans forced off takes precedence
216 3801161 : } else if (AvailStatus == CycleOnZoneFansOnly) {
217 0 : state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).AvailStatus = CycleOnZoneFansOnly; // zone fans only takes next precedence
218 3801161 : } else if ((AvailStatus == CycleOn) && (state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).AvailStatus == NoAction)) {
219 2388948 : state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).AvailStatus = CycleOn; // cycle on is lowest precedence
220 : }
221 :
222 : } // end of availability manager loop
223 :
224 : // Add hybrid ventilation control
225 4221179 : if (state.dataHVACGlobal->NumHybridVentSysAvailMgrs > 0) {
226 62969 : for (HybridVentNum = 1; HybridVentNum <= state.dataHVACGlobal->NumHybridVentSysAvailMgrs; ++HybridVentNum) {
227 62969 : if (state.dataSystemAvailabilityManager->HybridVentData(HybridVentNum).AirLoopNum == PriAirSysNum &&
228 29532 : state.dataSystemAvailabilityManager->HybridVentData(HybridVentNum).VentilationCtrl == HybridVentCtrl_Open) {
229 4309 : state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).AvailStatus = ForceOff; // Force the system off
230 : }
231 : }
232 : }
233 :
234 : // loop over the zones served by the system and set the zone equipment availability
235 17272592 : for (ZoneInSysNum = 1; ZoneInSysNum <= state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).NumZonesCooled; ++ZoneInSysNum) {
236 :
237 13051413 : CtrldZoneNum = state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).CoolCtrlZoneNums(ZoneInSysNum);
238 13051413 : state.dataZoneEquip->ZoneEquipAvail(CtrldZoneNum) = state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).AvailStatus;
239 : }
240 :
241 : } // end of primary air system loop
242 :
243 5493625 : for (PlantNum = 1; PlantNum <= state.dataHVACGlobal->NumPlantLoops; ++PlantNum) {
244 :
245 2855003 : PreviousStatus = state.dataPlnt->PlantAvailMgr(PlantNum).AvailStatus; // Save the previous status for differential thermostat
246 2855003 : state.dataPlnt->PlantAvailMgr(PlantNum).AvailStatus = NoAction; // Initialize the availability to "take no action"
247 :
248 3012080 : for (PlantAvailMgrNum = 1; PlantAvailMgrNum <= state.dataPlnt->PlantAvailMgr(PlantNum).NumAvailManagers;
249 : ++PlantAvailMgrNum) { // loop over the avail managers in plant
250 :
251 612738 : SimSysAvailManager(state,
252 204246 : state.dataPlnt->PlantAvailMgr(PlantNum).AvailManagerType(PlantAvailMgrNum),
253 204246 : state.dataPlnt->PlantAvailMgr(PlantNum).AvailManagerName(PlantAvailMgrNum),
254 204246 : state.dataPlnt->PlantAvailMgr(PlantNum).AvailManagerNum(PlantAvailMgrNum),
255 : PlantNum,
256 : PreviousStatus,
257 : AvailStatus);
258 :
259 204246 : if (AvailStatus != NoAction) {
260 47169 : state.dataPlnt->PlantAvailMgr(PlantNum).AvailStatus = AvailStatus;
261 47169 : break; // First manager to do anything other than "NoAction" gets to set the availability
262 : }
263 :
264 : } // end of availability manager loop
265 :
266 : } // end of plant loop
267 :
268 2638622 : auto &ZoneComp = state.dataHVACGlobal->ZoneComp;
269 39579330 : for (ZoneEquipType = 1; ZoneEquipType <= NumValidSysAvailZoneComponents;
270 : ++ZoneEquipType) { // loop over the zone equipment types which allow system avail managers
271 36940708 : if (allocated(ZoneComp)) {
272 36940708 : if (ZoneComp(ZoneEquipType).TotalNumComp > 0) {
273 2857439 : for (CompNum = 1; CompNum <= ZoneComp(ZoneEquipType).TotalNumComp; ++CompNum) {
274 2340235 : if (allocated(ZoneComp(ZoneEquipType).ZoneCompAvailMgrs)) {
275 2340235 : if (ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).NumAvailManagers > 0) {
276 : // Save the previous status for differential thermostat
277 6018 : PreviousStatus = ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailStatus;
278 : // initialize the availability to "take no action"
279 6018 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailStatus = NoAction;
280 13965 : for (ZoneCompAvailMgrNum = 1;
281 13965 : ZoneCompAvailMgrNum <= ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).NumAvailManagers;
282 : ++ZoneCompAvailMgrNum) {
283 : // loop over the avail managers in ZoneHVAC:* components
284 24009 : SimSysAvailManager(state,
285 8003 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailManagerType(ZoneCompAvailMgrNum),
286 8003 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailManagerName(ZoneCompAvailMgrNum),
287 8003 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailManagerNum(ZoneCompAvailMgrNum),
288 : DummyArgument,
289 : PreviousStatus,
290 : AvailStatus,
291 : ZoneEquipType,
292 : CompNum);
293 8003 : if (AvailStatus == ForceOff) {
294 56 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailStatus = ForceOff;
295 56 : break; // Fans forced off takes precedence
296 10750 : } else if ((AvailStatus == CycleOn) &&
297 2803 : (ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailStatus == NoAction)) {
298 : // cycle on is next precedence
299 2803 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailStatus = CycleOn;
300 : }
301 : } // end of availability manager loop
302 : }
303 : } else {
304 0 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailStatus = NoAction;
305 : }
306 2340235 : if (ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).ZoneNum > 0) {
307 2337013 : if (state.dataHVACGlobal->NumHybridVentSysAvailMgrs > 0) {
308 32322 : for (HybridVentNum = 1; HybridVentNum <= state.dataHVACGlobal->NumHybridVentSysAvailMgrs; ++HybridVentNum) {
309 18114 : if (!state.dataSystemAvailabilityManager->HybridVentData(HybridVentNum).HybridVentMgrConnectedToAirLoop) {
310 28416 : if (state.dataSystemAvailabilityManager->HybridVentData(HybridVentNum).ControlledZoneNum ==
311 14208 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).ZoneNum) {
312 7340 : if (state.dataSystemAvailabilityManager->HybridVentData(HybridVentNum).VentilationCtrl ==
313 : HybridVentCtrl_Open) {
314 1337 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailStatus = ForceOff;
315 : }
316 : }
317 : }
318 : }
319 : }
320 : }
321 : }
322 : }
323 : }
324 : } // end of zone equip types
325 : }
326 :
327 771 : void GetSysAvailManagerInputs(EnergyPlusData &state)
328 : {
329 :
330 : // SUBROUTINE INFORMATION:
331 : // AUTHOR Fred Buhl
332 : // DATE WRITTEN August 2001
333 : // MODIFIED na
334 : // RE-ENGINEERED na
335 :
336 : // PURPOSE OF THIS SUBROUTINE:
337 : // Obtains input data for System Availability Managers and stores it in
338 : // appropriate data structures.
339 :
340 : // METHODOLOGY EMPLOYED:
341 : // Uses InputProcessor "Get" routines to obtain data.
342 :
343 : // Using/Aliasing
344 : using NodeInputManager::GetOnlySingleNode;
345 : using NodeInputManager::MarkNode;
346 : using namespace DataLoopNode;
347 : using DataZoneEquipment::cValidSysAvailManagerCompTypes;
348 : using DataZoneEquipment::NumValidSysAvailZoneComponents;
349 :
350 : // SUBROUTINE PARAMETER DEFINITIONS:
351 : static constexpr std::string_view RoutineName("GetSysAvailManagerInputs: "); // include trailing blank
352 :
353 771 : constexpr std::array<std::string_view, static_cast<int>(ControlAlgorithm::Num)> ControlAlgorithmNamesUC = {
354 : "CONSTANTTEMPERATUREGRADIENT", "ADAPTIVETEMPERATUREGRADIENT", "ADAPTIVEASHRAE", "CONSTANTSTARTTIME"};
355 :
356 771 : constexpr std::array<std::string_view, static_cast<int>(CyclingRunTimeControl::Num)> CyclingRunTimeControlNamesUC{
357 : "FIXEDRUNTIME",
358 : "THERMOSTAT",
359 : "THERMOSTATWITHMINIMUMRUNTIME",
360 : };
361 :
362 771 : constexpr std::array<std::string_view, static_cast<int>(NightCycleControlType::Num)> NightCycleControlTypeNamesUC{
363 : "STAYOFF",
364 : "CYCLEONANY",
365 : "CYCLEONCONTROLZONE",
366 : "CYCLEONANYZONEFANSONLY",
367 : "CYCLEONANYCOOLINGORHEATINGZONE",
368 : "CYCLEONANYCOOLINGZONE",
369 : "CYCLEONANYHEATINGZONE",
370 : "CYCLEONANYHEATINGZONEFANSONLY",
371 : };
372 :
373 771 : constexpr std::array<std::string_view, static_cast<int>(OptimumStartControlType::Num)> OptimumStartControlTypeNamesUC{
374 : "STAYOFF",
375 : "CONTROLZONE",
376 : "MAXIMUMOFZONELIST",
377 : };
378 :
379 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
380 1542 : Array1D_string cAlphaFieldNames;
381 1542 : Array1D_string cNumericFieldNames;
382 1542 : Array1D_bool lNumericFieldBlanks;
383 1542 : Array1D_bool lAlphaFieldBlanks;
384 1542 : Array1D_string cAlphaArgs;
385 1542 : Array1D<Real64> rNumericArgs;
386 : int NumAlphas; // Number of Alphas for each GetObjectItem call
387 : int NumNumbers; // Number of Numbers for each GetObjectItem call
388 771 : int maxAlphas = 0; // maximum number of alphas for this set of objects
389 771 : int maxNumbers = 0; // maximum number of numbers for this set of objects
390 : int numArgs; // maximum number of arguments for this set of objects
391 : int IOStatus; // Used in GetObjectItem
392 771 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
393 : int SysAvailNum; // DO loop index for all System Availability Managers
394 : int CyclingTimeSteps;
395 : int ZoneEquipType;
396 : int TotalNumComp;
397 :
398 : // Get the number of occurrences of each type of manager and read in data
399 10023 : for (int currentModuleObjectCount = 0; currentModuleObjectCount < static_cast<int>(DataPlant::SystemAvailabilityType::Num);
400 : ++currentModuleObjectCount) {
401 9252 : std::string_view cCurrentModuleObject = SystemAvailabilityTypeNamesCC[currentModuleObjectCount];
402 9252 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, cCurrentModuleObject, numArgs, NumAlphas, NumNumbers);
403 9252 : maxNumbers = max(maxNumbers, NumNumbers);
404 9252 : maxAlphas = max(maxAlphas, NumAlphas);
405 : }
406 :
407 771 : cAlphaFieldNames.allocate(maxAlphas);
408 771 : cAlphaArgs.allocate(maxAlphas);
409 771 : lAlphaFieldBlanks.dimension(maxAlphas, false);
410 771 : cNumericFieldNames.allocate(maxNumbers);
411 771 : rNumericArgs.dimension(maxNumbers, 0.0);
412 771 : lNumericFieldBlanks.dimension(maxNumbers, false);
413 :
414 771 : if (!allocated(state.dataHVACGlobal->ZoneComp)) {
415 771 : state.dataHVACGlobal->ZoneComp.allocate(NumValidSysAvailZoneComponents);
416 : }
417 :
418 11565 : for (ZoneEquipType = 1; ZoneEquipType <= NumValidSysAvailZoneComponents; ++ZoneEquipType) {
419 10794 : if (!allocated(state.dataHVACGlobal->ZoneComp(ZoneEquipType).ZoneCompAvailMgrs)) {
420 10794 : TotalNumComp = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cValidSysAvailManagerCompTypes(ZoneEquipType));
421 10794 : state.dataHVACGlobal->ZoneComp(ZoneEquipType).TotalNumComp = TotalNumComp;
422 10794 : if (TotalNumComp > 0) {
423 173 : state.dataHVACGlobal->ZoneComp(ZoneEquipType).ZoneCompAvailMgrs.allocate(TotalNumComp);
424 : }
425 : }
426 : }
427 :
428 771 : std::string_view cCurrentModuleObject = SystemAvailabilityTypeNamesCC[static_cast<int>(DataPlant::SystemAvailabilityType::Scheduled)];
429 771 : state.dataSystemAvailabilityManager->NumSchedSysAvailMgrs =
430 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
431 :
432 771 : if (state.dataSystemAvailabilityManager->NumSchedSysAvailMgrs > 0) {
433 :
434 397 : state.dataSystemAvailabilityManager->SchedData.allocate(state.dataSystemAvailabilityManager->NumSchedSysAvailMgrs);
435 :
436 1035 : for (SysAvailNum = 1; SysAvailNum <= state.dataSystemAvailabilityManager->NumSchedSysAvailMgrs; ++SysAvailNum) {
437 :
438 638 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
439 : cCurrentModuleObject,
440 : SysAvailNum,
441 : cAlphaArgs,
442 : NumAlphas,
443 : rNumericArgs,
444 : NumNumbers,
445 : IOStatus,
446 : lNumericFieldBlanks,
447 : lAlphaFieldBlanks,
448 : cAlphaFieldNames,
449 : cNumericFieldNames);
450 :
451 638 : auto &schedMgr = state.dataSystemAvailabilityManager->SchedData(SysAvailNum);
452 638 : schedMgr.Name = cAlphaArgs(1);
453 638 : schedMgr.MgrType = DataPlant::SystemAvailabilityType::Scheduled;
454 :
455 638 : schedMgr.SchedPtr = GetScheduleIndex(state, cAlphaArgs(2));
456 638 : if (schedMgr.SchedPtr == 0) {
457 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
458 0 : ShowContinueError(state, "not found: " + cAlphaFieldNames(2) + "=\"" + cAlphaArgs(2) + "\".");
459 0 : ErrorsFound = true;
460 : }
461 :
462 1276 : SetupOutputVariable(state,
463 : "Availability Manager Scheduled Control Status",
464 : OutputProcessor::Unit::None,
465 : schedMgr.AvailStatus,
466 : OutputProcessor::SOVTimeStepType::System,
467 : OutputProcessor::SOVStoreType::Average,
468 638 : schedMgr.Name);
469 :
470 : } // SysAvailNum
471 : }
472 :
473 771 : cCurrentModuleObject = SystemAvailabilityTypeNamesCC[static_cast<int>(DataPlant::SystemAvailabilityType::ScheduledOn)];
474 771 : state.dataSystemAvailabilityManager->NumSchedOnSysAvailMgrs =
475 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
476 :
477 771 : if (state.dataSystemAvailabilityManager->NumSchedOnSysAvailMgrs > 0) {
478 :
479 4 : state.dataSystemAvailabilityManager->SchedOnData.allocate(state.dataSystemAvailabilityManager->NumSchedOnSysAvailMgrs);
480 :
481 8 : for (SysAvailNum = 1; SysAvailNum <= state.dataSystemAvailabilityManager->NumSchedOnSysAvailMgrs; ++SysAvailNum) {
482 :
483 4 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
484 : cCurrentModuleObject,
485 : SysAvailNum,
486 : cAlphaArgs,
487 : NumAlphas,
488 : rNumericArgs,
489 : NumNumbers,
490 : IOStatus,
491 : lNumericFieldBlanks,
492 : lAlphaFieldBlanks,
493 : cAlphaFieldNames,
494 : cNumericFieldNames);
495 :
496 4 : auto &schedOnMgr = state.dataSystemAvailabilityManager->SchedOnData(SysAvailNum);
497 4 : schedOnMgr.Name = cAlphaArgs(1);
498 4 : schedOnMgr.MgrType = DataPlant::SystemAvailabilityType::ScheduledOn;
499 :
500 4 : schedOnMgr.SchedPtr = GetScheduleIndex(state, cAlphaArgs(2));
501 4 : if (schedOnMgr.SchedPtr == 0) {
502 0 : ShowSevereError(state, format("{}{} = \"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
503 0 : ShowContinueError(state, "not found: " + cAlphaFieldNames(2) + "=\"" + cAlphaArgs(2) + "\".");
504 0 : ErrorsFound = true;
505 : }
506 :
507 8 : SetupOutputVariable(state,
508 : "Availability Manager Scheduled On Control Status",
509 : OutputProcessor::Unit::None,
510 : schedOnMgr.AvailStatus,
511 : OutputProcessor::SOVTimeStepType::System,
512 : OutputProcessor::SOVStoreType::Average,
513 4 : schedOnMgr.Name);
514 :
515 : } // SysAvailNum
516 : }
517 :
518 771 : cCurrentModuleObject = SystemAvailabilityTypeNamesCC[static_cast<int>(DataPlant::SystemAvailabilityType::ScheduledOff)];
519 771 : state.dataSystemAvailabilityManager->NumSchedOffSysAvailMgrs =
520 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
521 :
522 771 : if (state.dataSystemAvailabilityManager->NumSchedOffSysAvailMgrs > 0) {
523 :
524 5 : state.dataSystemAvailabilityManager->SchedOffData.allocate(state.dataSystemAvailabilityManager->NumSchedOffSysAvailMgrs);
525 :
526 10 : for (SysAvailNum = 1; SysAvailNum <= state.dataSystemAvailabilityManager->NumSchedOffSysAvailMgrs; ++SysAvailNum) {
527 :
528 5 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
529 : cCurrentModuleObject,
530 : SysAvailNum,
531 : cAlphaArgs,
532 : NumAlphas,
533 : rNumericArgs,
534 : NumNumbers,
535 : IOStatus,
536 : lNumericFieldBlanks,
537 : lAlphaFieldBlanks,
538 : cAlphaFieldNames,
539 : cNumericFieldNames);
540 :
541 5 : auto &schedOffMgr = state.dataSystemAvailabilityManager->SchedOffData(SysAvailNum);
542 5 : schedOffMgr.Name = cAlphaArgs(1);
543 5 : schedOffMgr.MgrType = DataPlant::SystemAvailabilityType::ScheduledOff;
544 :
545 5 : schedOffMgr.SchedPtr = GetScheduleIndex(state, cAlphaArgs(2));
546 5 : if (schedOffMgr.SchedPtr == 0) {
547 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
548 0 : ShowContinueError(state, "not found: " + cAlphaFieldNames(2) + "=\"" + cAlphaArgs(2) + "\".");
549 0 : ErrorsFound = true;
550 : }
551 :
552 10 : SetupOutputVariable(state,
553 : "Availability Manager Scheduled Off Control Status",
554 : OutputProcessor::Unit::None,
555 : schedOffMgr.AvailStatus,
556 : OutputProcessor::SOVTimeStepType::System,
557 : OutputProcessor::SOVStoreType::Average,
558 5 : schedOffMgr.Name);
559 :
560 : } // SysAvailNum
561 : }
562 :
563 771 : cCurrentModuleObject = SystemAvailabilityTypeNamesCC[static_cast<int>(DataPlant::SystemAvailabilityType::NightCycle)];
564 771 : state.dataSystemAvailabilityManager->NumNCycSysAvailMgrs =
565 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
566 771 : CyclingTimeSteps = 0;
567 :
568 771 : if (state.dataSystemAvailabilityManager->NumNCycSysAvailMgrs > 0) {
569 :
570 127 : state.dataSystemAvailabilityManager->NightCycleData.allocate(state.dataSystemAvailabilityManager->NumNCycSysAvailMgrs);
571 :
572 655 : for (SysAvailNum = 1; SysAvailNum <= state.dataSystemAvailabilityManager->NumNCycSysAvailMgrs; ++SysAvailNum) {
573 :
574 528 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
575 : cCurrentModuleObject,
576 : SysAvailNum,
577 : cAlphaArgs,
578 : NumAlphas,
579 : rNumericArgs,
580 : NumNumbers,
581 : IOStatus,
582 : lNumericFieldBlanks,
583 : lAlphaFieldBlanks,
584 : cAlphaFieldNames,
585 : cNumericFieldNames);
586 :
587 528 : auto &nightCycleMgr = state.dataSystemAvailabilityManager->NightCycleData(SysAvailNum);
588 528 : nightCycleMgr.Name = cAlphaArgs(1);
589 528 : nightCycleMgr.MgrType = DataPlant::SystemAvailabilityType::NightCycle;
590 528 : nightCycleMgr.TempTolRange = rNumericArgs(1);
591 528 : CyclingTimeSteps = nint((rNumericArgs(2) / DataGlobalConstants::SecInHour) * double(state.dataGlobal->NumOfTimeStepInHour));
592 528 : CyclingTimeSteps = max(1, CyclingTimeSteps);
593 528 : nightCycleMgr.CyclingTimeSteps = CyclingTimeSteps;
594 528 : nightCycleMgr.SchedPtr = GetScheduleIndex(state, cAlphaArgs(2));
595 528 : if (nightCycleMgr.SchedPtr == 0) {
596 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
597 0 : ShowContinueError(state, "not found: " + cAlphaFieldNames(2) + "=\"" + cAlphaArgs(2) + "\".");
598 0 : ErrorsFound = true;
599 : }
600 528 : nightCycleMgr.FanSched = cAlphaArgs(3);
601 528 : nightCycleMgr.FanSchedPtr = GetScheduleIndex(state, cAlphaArgs(3));
602 528 : if (nightCycleMgr.FanSchedPtr == 0) {
603 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
604 0 : ShowContinueError(state, "not found: " + cAlphaFieldNames(3) + "=\"" + cAlphaArgs(3) + "\".");
605 0 : ErrorsFound = true;
606 : }
607 :
608 528 : nightCycleMgr.nightCycleControlType = static_cast<NightCycleControlType>(
609 1056 : getEnumerationValue(NightCycleControlTypeNamesUC, UtilityRoutines::MakeUPPERCase(cAlphaArgs(4))));
610 :
611 528 : assert(nightCycleMgr.nightCycleControlType != NightCycleControlType::Invalid);
612 :
613 : // Cycling Run Time Control Type
614 528 : nightCycleMgr.cyclingRunTimeControl = static_cast<CyclingRunTimeControl>(
615 1056 : getEnumerationValue(CyclingRunTimeControlNamesUC, UtilityRoutines::MakeUPPERCase(cAlphaArgs(5))));
616 :
617 528 : assert(nightCycleMgr.cyclingRunTimeControl != CyclingRunTimeControl::Invalid);
618 :
619 : // Control zone or zonelist
620 528 : if (!lAlphaFieldBlanks(6)) {
621 3 : nightCycleMgr.CtrlZoneListName = cAlphaArgs(6);
622 3 : int ZoneNum = UtilityRoutines::FindItemInList(cAlphaArgs(6), state.dataHeatBal->Zone);
623 3 : if (ZoneNum > 0) {
624 3 : nightCycleMgr.NumOfCtrlZones = 1;
625 3 : nightCycleMgr.CtrlZonePtrs.allocate(1);
626 3 : nightCycleMgr.CtrlZonePtrs(1) = ZoneNum;
627 : } else {
628 0 : int zoneListNum = 0;
629 0 : if (state.dataHeatBal->NumOfZoneLists > 0)
630 0 : zoneListNum = UtilityRoutines::FindItemInList(cAlphaArgs(6), state.dataHeatBal->ZoneList);
631 0 : if (zoneListNum > 0) {
632 0 : int NumZones = state.dataHeatBal->ZoneList(zoneListNum).NumOfZones;
633 0 : nightCycleMgr.NumOfCtrlZones = NumZones;
634 0 : nightCycleMgr.CtrlZonePtrs.allocate(NumZones);
635 0 : for (int zoneNumInList = 1; zoneNumInList <= NumZones; ++zoneNumInList) {
636 0 : nightCycleMgr.CtrlZonePtrs(zoneNumInList) = state.dataHeatBal->ZoneList(zoneListNum).Zone(zoneNumInList);
637 : }
638 : } else {
639 0 : ShowSevereError(state,
640 0 : format(R"({}{}="{}" invalid {}="{}" not found.)",
641 : RoutineName,
642 : cCurrentModuleObject,
643 : cAlphaArgs(1),
644 : cAlphaFieldNames(6),
645 0 : cAlphaArgs(6)));
646 0 : ErrorsFound = true;
647 : }
648 : }
649 525 : } else if (nightCycleMgr.nightCycleControlType == NightCycleControlType::OnControlZone) {
650 0 : ShowSevereError(state,
651 0 : format("{}{} = \"{}\" {} required when \"{}\" = {}.",
652 : RoutineName,
653 : cCurrentModuleObject,
654 : cAlphaArgs(1),
655 : cAlphaFieldNames(6),
656 : cAlphaFieldNames(4),
657 0 : cAlphaArgs(4)));
658 0 : ErrorsFound = true;
659 : }
660 :
661 : // Cooling zone or zonelist
662 528 : if (!lAlphaFieldBlanks(7)) {
663 2 : nightCycleMgr.CoolingZoneListName = cAlphaArgs(7);
664 2 : int ZoneNum = UtilityRoutines::FindItemInList(cAlphaArgs(7), state.dataHeatBal->Zone);
665 2 : if (ZoneNum > 0) {
666 0 : nightCycleMgr.NumOfCoolingZones = 1;
667 0 : nightCycleMgr.CoolingZonePtrs.allocate(1);
668 0 : nightCycleMgr.CoolingZonePtrs(1) = ZoneNum;
669 : } else {
670 2 : int zoneListNum = 0;
671 2 : if (state.dataHeatBal->NumOfZoneLists > 0)
672 2 : zoneListNum = UtilityRoutines::FindItemInList(cAlphaArgs(7), state.dataHeatBal->ZoneList);
673 2 : if (zoneListNum > 0) {
674 2 : int NumZones = state.dataHeatBal->ZoneList(zoneListNum).NumOfZones;
675 2 : nightCycleMgr.NumOfCoolingZones = NumZones;
676 2 : nightCycleMgr.CoolingZonePtrs.allocate(NumZones);
677 8 : for (int zoneNumInList = 1; zoneNumInList <= NumZones; ++zoneNumInList) {
678 6 : nightCycleMgr.CoolingZonePtrs(zoneNumInList) = state.dataHeatBal->ZoneList(zoneListNum).Zone(zoneNumInList);
679 : }
680 : } else {
681 0 : ShowSevereError(state,
682 0 : format(R"({}{}="{}" invalid {}="{}" not found.)",
683 : RoutineName,
684 : cCurrentModuleObject,
685 : cAlphaArgs(1),
686 : cAlphaFieldNames(7),
687 0 : cAlphaArgs(7)));
688 0 : ErrorsFound = true;
689 : }
690 : }
691 : }
692 :
693 : // Heating zone or zonelist
694 528 : if (!lAlphaFieldBlanks(8)) {
695 2 : nightCycleMgr.HeatingZoneListName = cAlphaArgs(8);
696 2 : int ZoneNum = UtilityRoutines::FindItemInList(cAlphaArgs(8), state.dataHeatBal->Zone);
697 2 : if (ZoneNum > 0) {
698 2 : nightCycleMgr.NumOfHeatingZones = 1;
699 2 : nightCycleMgr.HeatingZonePtrs.allocate(1);
700 2 : nightCycleMgr.HeatingZonePtrs(1) = ZoneNum;
701 : } else {
702 0 : int zoneListNum = 0;
703 0 : if (state.dataHeatBal->NumOfZoneLists > 0)
704 0 : zoneListNum = UtilityRoutines::FindItemInList(cAlphaArgs(8), state.dataHeatBal->ZoneList);
705 0 : if (zoneListNum > 0) {
706 0 : int NumZones = state.dataHeatBal->ZoneList(zoneListNum).NumOfZones;
707 0 : nightCycleMgr.NumOfHeatingZones = NumZones;
708 0 : nightCycleMgr.HeatingZonePtrs.allocate(NumZones);
709 0 : for (int zoneNumInList = 1; zoneNumInList <= NumZones; ++zoneNumInList) {
710 0 : nightCycleMgr.HeatingZonePtrs(zoneNumInList) = state.dataHeatBal->ZoneList(zoneListNum).Zone(zoneNumInList);
711 : }
712 : } else {
713 0 : ShowSevereError(state,
714 0 : format(R"({}{}="{}" invalid {}="{}" not found.)",
715 : RoutineName,
716 : cCurrentModuleObject,
717 : cAlphaArgs(1),
718 : cAlphaFieldNames(8),
719 0 : cAlphaArgs(8)));
720 0 : ErrorsFound = true;
721 : }
722 : }
723 : }
724 :
725 : // HeatZnFan zone or zonelist
726 528 : if (!lAlphaFieldBlanks(9)) {
727 2 : nightCycleMgr.HeatZnFanZoneListName = cAlphaArgs(9);
728 2 : int ZoneNum = UtilityRoutines::FindItemInList(cAlphaArgs(9), state.dataHeatBal->Zone);
729 2 : if (ZoneNum > 0) {
730 0 : nightCycleMgr.NumOfHeatZnFanZones = 1;
731 0 : nightCycleMgr.HeatZnFanZonePtrs.allocate(1);
732 0 : nightCycleMgr.HeatZnFanZonePtrs(1) = ZoneNum;
733 : } else {
734 2 : int zoneListNum = 0;
735 2 : if (state.dataHeatBal->NumOfZoneLists > 0)
736 2 : zoneListNum = UtilityRoutines::FindItemInList(cAlphaArgs(9), state.dataHeatBal->ZoneList);
737 2 : if (zoneListNum > 0) {
738 2 : int NumZones = state.dataHeatBal->ZoneList(zoneListNum).NumOfZones;
739 2 : nightCycleMgr.NumOfHeatZnFanZones = NumZones;
740 2 : nightCycleMgr.HeatZnFanZonePtrs.allocate(NumZones);
741 6 : for (int zoneNumInList = 1; zoneNumInList <= NumZones; ++zoneNumInList) {
742 4 : nightCycleMgr.HeatZnFanZonePtrs(zoneNumInList) = state.dataHeatBal->ZoneList(zoneListNum).Zone(zoneNumInList);
743 : }
744 : } else {
745 0 : ShowSevereError(state,
746 0 : format(R"({}{}="{}" invalid {}="{}" not found.)",
747 : RoutineName,
748 : cCurrentModuleObject,
749 : cAlphaArgs(1),
750 : cAlphaFieldNames(9),
751 0 : cAlphaArgs(9)));
752 0 : ErrorsFound = true;
753 : }
754 : }
755 : }
756 :
757 1056 : SetupOutputVariable(state,
758 : "Availability Manager Night Cycle Control Status",
759 : OutputProcessor::Unit::None,
760 : nightCycleMgr.AvailStatus,
761 : OutputProcessor::SOVTimeStepType::System,
762 : OutputProcessor::SOVStoreType::Average,
763 528 : nightCycleMgr.Name);
764 :
765 : } // SysAvailNum
766 : }
767 :
768 771 : cCurrentModuleObject = SystemAvailabilityTypeNamesCC[static_cast<int>(DataPlant::SystemAvailabilityType::OptimumStart)];
769 771 : state.dataSystemAvailabilityManager->NumOptStartSysAvailMgrs =
770 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
771 771 : CyclingTimeSteps = 0;
772 :
773 771 : if (state.dataSystemAvailabilityManager->NumOptStartSysAvailMgrs > 0) {
774 : // Array size of variable type OptStartSysAvailMgrData is updated
775 1 : state.dataSystemAvailabilityManager->OptimumStartData.allocate(state.dataSystemAvailabilityManager->NumOptStartSysAvailMgrs);
776 :
777 2 : for (SysAvailNum = 1; SysAvailNum <= state.dataSystemAvailabilityManager->NumOptStartSysAvailMgrs; ++SysAvailNum) {
778 :
779 1 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
780 : cCurrentModuleObject,
781 : SysAvailNum,
782 : cAlphaArgs,
783 : NumAlphas,
784 : rNumericArgs,
785 : NumNumbers,
786 : IOStatus,
787 : lNumericFieldBlanks,
788 : lAlphaFieldBlanks,
789 : cAlphaFieldNames,
790 : cNumericFieldNames);
791 :
792 1 : auto &optimumStartMgr = state.dataSystemAvailabilityManager->OptimumStartData(SysAvailNum);
793 1 : optimumStartMgr.Name = cAlphaArgs(1);
794 1 : optimumStartMgr.MgrType = DataPlant::SystemAvailabilityType::OptimumStart;
795 1 : optimumStartMgr.SchedPtr = GetScheduleIndex(state, cAlphaArgs(2));
796 1 : if (optimumStartMgr.SchedPtr == 0) {
797 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
798 0 : ShowContinueError(state, "not found: " + cAlphaFieldNames(2) + "=\"" + cAlphaArgs(2) + "\".");
799 0 : ErrorsFound = true;
800 : }
801 1 : optimumStartMgr.FanSched = cAlphaArgs(3);
802 1 : optimumStartMgr.FanSchedPtr = GetScheduleIndex(state, cAlphaArgs(3));
803 1 : if (optimumStartMgr.FanSchedPtr == 0) {
804 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
805 0 : ShowContinueError(state, "not found: " + cAlphaFieldNames(3) + "=\"" + cAlphaArgs(3) + "\".");
806 0 : ErrorsFound = true;
807 : }
808 :
809 1 : optimumStartMgr.MaxOptStartTime = rNumericArgs(1);
810 :
811 1 : optimumStartMgr.optimumStartControlType = static_cast<OptimumStartControlType>(
812 2 : getEnumerationValue(OptimumStartControlTypeNamesUC, UtilityRoutines::MakeUPPERCase(cAlphaArgs(4))));
813 :
814 1 : if (optimumStartMgr.optimumStartControlType == OptimumStartControlType::Invalid) {
815 0 : optimumStartMgr.optimumStartControlType = OptimumStartControlType::ControlZone;
816 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
817 0 : ShowSevereError(state, format("{} incorrect value: {} =\"{}\".", RoutineName, cAlphaFieldNames(4), cAlphaArgs(4)));
818 0 : ErrorsFound = true;
819 : }
820 :
821 1 : if (optimumStartMgr.optimumStartControlType == OptimumStartControlType::ControlZone) {
822 0 : optimumStartMgr.CtrlZoneName = cAlphaArgs(5);
823 0 : optimumStartMgr.ZoneNum = UtilityRoutines::FindItemInList(cAlphaArgs(5), state.dataHeatBal->Zone);
824 0 : if (optimumStartMgr.ZoneNum == 0) {
825 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
826 0 : ShowSevereError(state, "not found: " + cAlphaFieldNames(5) + "=\"" + cAlphaArgs(5) + "\".");
827 0 : ErrorsFound = true;
828 : }
829 : }
830 :
831 1 : if (optimumStartMgr.optimumStartControlType == OptimumStartControlType::MaximumOfZoneList) {
832 1 : optimumStartMgr.ZoneListName = cAlphaArgs(6);
833 2 : for (int zoneListNum = 1; zoneListNum <= state.dataHeatBal->NumOfZoneLists; ++zoneListNum) {
834 1 : if (state.dataHeatBal->ZoneList(zoneListNum).Name == cAlphaArgs(6)) {
835 1 : optimumStartMgr.NumOfZones = state.dataHeatBal->ZoneList(zoneListNum).NumOfZones;
836 1 : optimumStartMgr.ZonePtrs.allocate(state.dataHeatBal->ZoneList(zoneListNum).NumOfZones);
837 5 : for (int zoneNumInList = 1; zoneNumInList <= state.dataHeatBal->ZoneList(zoneListNum).NumOfZones; ++zoneNumInList) {
838 4 : optimumStartMgr.ZonePtrs(zoneNumInList) = state.dataHeatBal->ZoneList(zoneListNum).Zone(zoneNumInList);
839 : }
840 : }
841 : }
842 1 : optimumStartMgr.NumOfZones = UtilityRoutines::FindItemInList(cAlphaArgs(6), state.dataHeatBal->ZoneList);
843 1 : if (optimumStartMgr.NumOfZones == 0) {
844 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
845 0 : ShowSevereError(state, "not found: " + cAlphaFieldNames(6) + "=\"" + cAlphaArgs(6) + "\".");
846 0 : ErrorsFound = true;
847 : }
848 : }
849 :
850 1 : optimumStartMgr.controlAlgorithm =
851 2 : static_cast<ControlAlgorithm>(getEnumerationValue(ControlAlgorithmNamesUC, UtilityRoutines::MakeUPPERCase(cAlphaArgs(7))));
852 :
853 1 : assert(optimumStartMgr.controlAlgorithm != ControlAlgorithm::Invalid);
854 :
855 1 : switch (optimumStartMgr.controlAlgorithm) {
856 0 : case ControlAlgorithm::ConstantTemperatureGradient: {
857 0 : optimumStartMgr.ConstTGradCool = rNumericArgs(2);
858 0 : optimumStartMgr.ConstTGradHeat = rNumericArgs(3);
859 0 : } break;
860 :
861 1 : case ControlAlgorithm::AdaptiveTemperatureGradient: {
862 1 : optimumStartMgr.InitTGradCool = rNumericArgs(4);
863 1 : optimumStartMgr.InitTGradHeat = rNumericArgs(5);
864 1 : optimumStartMgr.NumPreDays = rNumericArgs(7);
865 1 : } break;
866 :
867 0 : case ControlAlgorithm::ConstantStartTime: {
868 0 : optimumStartMgr.ConstStartTime = rNumericArgs(6);
869 0 : } break;
870 :
871 0 : default:
872 0 : break;
873 : }
874 :
875 2 : SetupOutputVariable(state,
876 : "Availability Manager Optimum Start Control Status",
877 : OutputProcessor::Unit::None,
878 : optimumStartMgr.AvailStatus,
879 : OutputProcessor::SOVTimeStepType::System,
880 : OutputProcessor::SOVStoreType::Average,
881 1 : optimumStartMgr.Name);
882 :
883 : // add
884 2 : SetupOutputVariable(state,
885 : "Availability Manager Optimum Start Time Before Occupancy",
886 : OutputProcessor::Unit::hr,
887 : optimumStartMgr.NumHoursBeforeOccupancy,
888 : OutputProcessor::SOVTimeStepType::System,
889 : OutputProcessor::SOVStoreType::Average,
890 : optimumStartMgr.Name,
891 1 : "Daily");
892 : }
893 : }
894 :
895 771 : cCurrentModuleObject = SystemAvailabilityTypeNamesCC[static_cast<int>(DataPlant::SystemAvailabilityType::DiffThermo)];
896 771 : state.dataSystemAvailabilityManager->NumDiffTSysAvailMgrs =
897 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
898 :
899 771 : if (state.dataSystemAvailabilityManager->NumDiffTSysAvailMgrs > 0) {
900 :
901 2 : state.dataSystemAvailabilityManager->DiffThermoData.allocate(state.dataSystemAvailabilityManager->NumDiffTSysAvailMgrs);
902 :
903 4 : for (SysAvailNum = 1; SysAvailNum <= state.dataSystemAvailabilityManager->NumDiffTSysAvailMgrs; ++SysAvailNum) {
904 :
905 2 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
906 : cCurrentModuleObject,
907 : SysAvailNum,
908 : cAlphaArgs,
909 : NumAlphas,
910 : rNumericArgs,
911 : NumNumbers,
912 : IOStatus,
913 : lNumericFieldBlanks,
914 : lAlphaFieldBlanks,
915 : cAlphaFieldNames,
916 : cNumericFieldNames);
917 :
918 2 : auto &diffThermoMgr = state.dataSystemAvailabilityManager->DiffThermoData(SysAvailNum);
919 2 : diffThermoMgr.Name = cAlphaArgs(1);
920 2 : diffThermoMgr.MgrType = DataPlant::SystemAvailabilityType::DiffThermo;
921 :
922 2 : diffThermoMgr.HotNode = GetOnlySingleNode(state,
923 2 : cAlphaArgs(2),
924 : ErrorsFound,
925 : DataLoopNode::ConnectionObjectType::AvailabilityManagerDifferentialThermostat,
926 2 : cAlphaArgs(1),
927 : DataLoopNode::NodeFluidType::Blank,
928 : DataLoopNode::ConnectionType::Sensor,
929 : NodeInputManager::CompFluidStream::Primary,
930 2 : ObjectIsNotParent);
931 4 : MarkNode(state,
932 : diffThermoMgr.HotNode,
933 : DataLoopNode::ConnectionObjectType::AvailabilityManagerDifferentialThermostat,
934 2 : cAlphaArgs(1),
935 : "Hot Node");
936 2 : diffThermoMgr.ColdNode = GetOnlySingleNode(state,
937 2 : cAlphaArgs(3),
938 : ErrorsFound,
939 : DataLoopNode::ConnectionObjectType::AvailabilityManagerDifferentialThermostat,
940 2 : cAlphaArgs(1),
941 : DataLoopNode::NodeFluidType::Blank,
942 : DataLoopNode::ConnectionType::Sensor,
943 : NodeInputManager::CompFluidStream::Primary,
944 2 : ObjectIsNotParent);
945 4 : MarkNode(state,
946 : diffThermoMgr.ColdNode,
947 : DataLoopNode::ConnectionObjectType::AvailabilityManagerDifferentialThermostat,
948 2 : cAlphaArgs(1),
949 : "Cold Node");
950 :
951 2 : diffThermoMgr.TempDiffOn = rNumericArgs(1);
952 :
953 2 : if (NumNumbers > 1) {
954 2 : diffThermoMgr.TempDiffOff = rNumericArgs(2);
955 : } else {
956 0 : diffThermoMgr.TempDiffOff = diffThermoMgr.TempDiffOn;
957 : }
958 :
959 2 : if (diffThermoMgr.TempDiffOff > diffThermoMgr.TempDiffOn) {
960 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
961 0 : ShowContinueError(state, "The " + cNumericFieldNames(2) + " is greater than the " + cNumericFieldNames(1) + '.');
962 0 : ErrorsFound = true;
963 : }
964 :
965 4 : SetupOutputVariable(state,
966 : "Availability Manager Differential Thermostat Control Status",
967 : OutputProcessor::Unit::None,
968 : diffThermoMgr.AvailStatus,
969 : OutputProcessor::SOVTimeStepType::System,
970 : OutputProcessor::SOVStoreType::Average,
971 2 : diffThermoMgr.Name);
972 :
973 : } // SysAvailNum
974 : }
975 :
976 771 : cCurrentModuleObject = SystemAvailabilityTypeNamesCC[static_cast<int>(DataPlant::SystemAvailabilityType::HiTempTOff)];
977 771 : state.dataSystemAvailabilityManager->NumHiTurnOffSysAvailMgrs =
978 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
979 :
980 771 : if (state.dataSystemAvailabilityManager->NumHiTurnOffSysAvailMgrs > 0) {
981 2 : state.dataSystemAvailabilityManager->HiTurnOffData.allocate(state.dataSystemAvailabilityManager->NumHiTurnOffSysAvailMgrs);
982 :
983 4 : for (SysAvailNum = 1; SysAvailNum <= state.dataSystemAvailabilityManager->NumHiTurnOffSysAvailMgrs; ++SysAvailNum) {
984 :
985 2 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
986 : cCurrentModuleObject,
987 : SysAvailNum,
988 : cAlphaArgs,
989 : NumAlphas,
990 : rNumericArgs,
991 : NumNumbers,
992 : IOStatus,
993 : lNumericFieldBlanks,
994 : lAlphaFieldBlanks,
995 : cAlphaFieldNames,
996 : cNumericFieldNames);
997 :
998 2 : auto &hiTurnOffMgr = state.dataSystemAvailabilityManager->HiTurnOffData(SysAvailNum);
999 2 : hiTurnOffMgr.Name = cAlphaArgs(1);
1000 2 : hiTurnOffMgr.MgrType = DataPlant::SystemAvailabilityType::HiTempTOff;
1001 :
1002 2 : hiTurnOffMgr.Node = GetOnlySingleNode(state,
1003 2 : cAlphaArgs(2),
1004 : ErrorsFound,
1005 : DataLoopNode::ConnectionObjectType::AvailabilityManagerHighTemperatureTurnOff,
1006 2 : cAlphaArgs(1),
1007 : DataLoopNode::NodeFluidType::Blank,
1008 : DataLoopNode::ConnectionType::Sensor,
1009 : NodeInputManager::CompFluidStream::Primary,
1010 2 : ObjectIsNotParent);
1011 4 : MarkNode(state,
1012 : hiTurnOffMgr.Node,
1013 : DataLoopNode::ConnectionObjectType::AvailabilityManagerHighTemperatureTurnOff,
1014 2 : cAlphaArgs(1),
1015 : "Sensor Node");
1016 :
1017 2 : hiTurnOffMgr.Temp = rNumericArgs(1);
1018 :
1019 4 : SetupOutputVariable(state,
1020 : "Availability Manager High Temperature Turn Off Control Status",
1021 : OutputProcessor::Unit::None,
1022 : hiTurnOffMgr.AvailStatus,
1023 : OutputProcessor::SOVTimeStepType::System,
1024 : OutputProcessor::SOVStoreType::Average,
1025 2 : hiTurnOffMgr.Name);
1026 :
1027 : } // SysAvailNum
1028 : }
1029 :
1030 771 : cCurrentModuleObject = SystemAvailabilityTypeNamesCC[static_cast<int>(DataPlant::SystemAvailabilityType::HiTempTOn)];
1031 771 : state.dataSystemAvailabilityManager->NumHiTurnOnSysAvailMgrs =
1032 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
1033 :
1034 771 : if (state.dataSystemAvailabilityManager->NumHiTurnOnSysAvailMgrs > 0) {
1035 :
1036 5 : state.dataSystemAvailabilityManager->HiTurnOnData.allocate(state.dataSystemAvailabilityManager->NumHiTurnOnSysAvailMgrs);
1037 :
1038 10 : for (SysAvailNum = 1; SysAvailNum <= state.dataSystemAvailabilityManager->NumHiTurnOnSysAvailMgrs; ++SysAvailNum) {
1039 :
1040 5 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1041 : cCurrentModuleObject,
1042 : SysAvailNum,
1043 : cAlphaArgs,
1044 : NumAlphas,
1045 : rNumericArgs,
1046 : NumNumbers,
1047 : IOStatus,
1048 : lNumericFieldBlanks,
1049 : lAlphaFieldBlanks,
1050 : cAlphaFieldNames,
1051 : cNumericFieldNames);
1052 :
1053 5 : auto &hiTurnOnMgr = state.dataSystemAvailabilityManager->HiTurnOnData(SysAvailNum);
1054 5 : hiTurnOnMgr.Name = cAlphaArgs(1);
1055 5 : hiTurnOnMgr.MgrType = DataPlant::SystemAvailabilityType::HiTempTOn;
1056 :
1057 5 : hiTurnOnMgr.Node = GetOnlySingleNode(state,
1058 5 : cAlphaArgs(2),
1059 : ErrorsFound,
1060 : DataLoopNode::ConnectionObjectType::AvailabilityManagerHighTemperatureTurnOn,
1061 5 : cAlphaArgs(1),
1062 : DataLoopNode::NodeFluidType::Blank,
1063 : DataLoopNode::ConnectionType::Sensor,
1064 : NodeInputManager::CompFluidStream::Primary,
1065 5 : ObjectIsNotParent);
1066 10 : MarkNode(state,
1067 : hiTurnOnMgr.Node,
1068 : DataLoopNode::ConnectionObjectType::AvailabilityManagerHighTemperatureTurnOn,
1069 5 : cAlphaArgs(1),
1070 : "Sensor Node");
1071 :
1072 5 : hiTurnOnMgr.Temp = rNumericArgs(1);
1073 :
1074 10 : SetupOutputVariable(state,
1075 : "Availability Manager High Temperature Turn On Control Status",
1076 : OutputProcessor::Unit::None,
1077 : hiTurnOnMgr.AvailStatus,
1078 : OutputProcessor::SOVTimeStepType::System,
1079 : OutputProcessor::SOVStoreType::Average,
1080 5 : hiTurnOnMgr.Name);
1081 :
1082 : } // SysAvailNum
1083 : }
1084 :
1085 771 : cCurrentModuleObject = SystemAvailabilityTypeNamesCC[static_cast<int>(DataPlant::SystemAvailabilityType::LoTempTOff)];
1086 771 : state.dataSystemAvailabilityManager->NumLoTurnOffSysAvailMgrs =
1087 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
1088 :
1089 771 : if (state.dataSystemAvailabilityManager->NumLoTurnOffSysAvailMgrs > 0) {
1090 :
1091 44 : state.dataSystemAvailabilityManager->LoTurnOffData.allocate(state.dataSystemAvailabilityManager->NumLoTurnOffSysAvailMgrs);
1092 :
1093 94 : for (SysAvailNum = 1; SysAvailNum <= state.dataSystemAvailabilityManager->NumLoTurnOffSysAvailMgrs; ++SysAvailNum) {
1094 :
1095 50 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1096 : cCurrentModuleObject,
1097 : SysAvailNum,
1098 : cAlphaArgs,
1099 : NumAlphas,
1100 : rNumericArgs,
1101 : NumNumbers,
1102 : IOStatus,
1103 : lNumericFieldBlanks,
1104 : lAlphaFieldBlanks,
1105 : cAlphaFieldNames,
1106 : cNumericFieldNames);
1107 :
1108 50 : auto &loTurnOffMgr = state.dataSystemAvailabilityManager->LoTurnOffData(SysAvailNum);
1109 50 : loTurnOffMgr.Name = cAlphaArgs(1);
1110 50 : loTurnOffMgr.MgrType = DataPlant::SystemAvailabilityType::LoTempTOff;
1111 :
1112 50 : loTurnOffMgr.Node = GetOnlySingleNode(state,
1113 50 : cAlphaArgs(2),
1114 : ErrorsFound,
1115 : DataLoopNode::ConnectionObjectType::AvailabilityManagerLowTemperatureTurnOff,
1116 50 : cAlphaArgs(1),
1117 : DataLoopNode::NodeFluidType::Blank,
1118 : DataLoopNode::ConnectionType::Sensor,
1119 : NodeInputManager::CompFluidStream::Primary,
1120 50 : ObjectIsNotParent);
1121 100 : MarkNode(state,
1122 : loTurnOffMgr.Node,
1123 : DataLoopNode::ConnectionObjectType::AvailabilityManagerLowTemperatureTurnOff,
1124 50 : cAlphaArgs(1),
1125 : "Sensor Node");
1126 :
1127 50 : loTurnOffMgr.Temp = rNumericArgs(1);
1128 :
1129 50 : if (!lAlphaFieldBlanks(3)) {
1130 36 : loTurnOffMgr.SchedPtr = GetScheduleIndex(state, cAlphaArgs(3));
1131 36 : if (loTurnOffMgr.SchedPtr == 0) {
1132 0 : ShowSevereError(state, format("{}{}=\"{}\" not found.", RoutineName, cAlphaFieldNames(3), cAlphaArgs(3)));
1133 0 : ShowContinueError(state, format("Occurs in {}=\"{}\".", cCurrentModuleObject, cAlphaArgs(1)));
1134 0 : ErrorsFound = true;
1135 : }
1136 : } else {
1137 14 : loTurnOffMgr.SchedPtr = 0;
1138 : }
1139 :
1140 100 : SetupOutputVariable(state,
1141 : "Availability Manager Low Temperature Turn Off Control Status",
1142 : OutputProcessor::Unit::None,
1143 : loTurnOffMgr.AvailStatus,
1144 : OutputProcessor::SOVTimeStepType::System,
1145 : OutputProcessor::SOVStoreType::Average,
1146 50 : loTurnOffMgr.Name);
1147 :
1148 : } // SysAvailNum
1149 : }
1150 :
1151 771 : cCurrentModuleObject = SystemAvailabilityTypeNamesCC[static_cast<int>(DataPlant::SystemAvailabilityType::LoTempTOn)];
1152 771 : state.dataSystemAvailabilityManager->NumLoTurnOnSysAvailMgrs =
1153 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
1154 :
1155 771 : if (state.dataSystemAvailabilityManager->NumLoTurnOnSysAvailMgrs > 0) {
1156 :
1157 2 : state.dataSystemAvailabilityManager->LoTurnOnData.allocate(state.dataSystemAvailabilityManager->NumLoTurnOnSysAvailMgrs);
1158 :
1159 4 : for (SysAvailNum = 1; SysAvailNum <= state.dataSystemAvailabilityManager->NumLoTurnOnSysAvailMgrs; ++SysAvailNum) {
1160 :
1161 2 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1162 : cCurrentModuleObject,
1163 : SysAvailNum,
1164 : cAlphaArgs,
1165 : NumAlphas,
1166 : rNumericArgs,
1167 : NumNumbers,
1168 : IOStatus,
1169 : lNumericFieldBlanks,
1170 : lAlphaFieldBlanks,
1171 : cAlphaFieldNames,
1172 : cNumericFieldNames);
1173 :
1174 2 : auto &loTurnOnMgr = state.dataSystemAvailabilityManager->LoTurnOnData(SysAvailNum);
1175 2 : loTurnOnMgr.Name = cAlphaArgs(1);
1176 2 : loTurnOnMgr.MgrType = DataPlant::SystemAvailabilityType::LoTempTOn;
1177 :
1178 2 : loTurnOnMgr.Node = GetOnlySingleNode(state,
1179 2 : cAlphaArgs(2),
1180 : ErrorsFound,
1181 : DataLoopNode::ConnectionObjectType::AvailabilityManagerLowTemperatureTurnOn,
1182 2 : cAlphaArgs(1),
1183 : DataLoopNode::NodeFluidType::Blank,
1184 : DataLoopNode::ConnectionType::Sensor,
1185 : NodeInputManager::CompFluidStream::Primary,
1186 2 : ObjectIsNotParent);
1187 4 : MarkNode(state,
1188 : loTurnOnMgr.Node,
1189 : DataLoopNode::ConnectionObjectType::AvailabilityManagerLowTemperatureTurnOn,
1190 2 : cAlphaArgs(1),
1191 : "Sensor Node");
1192 :
1193 2 : loTurnOnMgr.Temp = rNumericArgs(1);
1194 :
1195 4 : SetupOutputVariable(state,
1196 : "Availability Manager Low Temperature Turn On Control Status",
1197 : OutputProcessor::Unit::None,
1198 : loTurnOnMgr.AvailStatus,
1199 : OutputProcessor::SOVTimeStepType::System,
1200 : OutputProcessor::SOVStoreType::Average,
1201 2 : loTurnOnMgr.Name);
1202 :
1203 : } // SysAvailNum
1204 : }
1205 :
1206 771 : cCurrentModuleObject = SystemAvailabilityTypeNamesCC[static_cast<int>(DataPlant::SystemAvailabilityType::NightVent)];
1207 771 : state.dataSystemAvailabilityManager->NumNVentSysAvailMgrs =
1208 771 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
1209 :
1210 771 : if (state.dataSystemAvailabilityManager->NumNVentSysAvailMgrs > 0) {
1211 :
1212 1 : state.dataSystemAvailabilityManager->NightVentData.allocate(state.dataSystemAvailabilityManager->NumNVentSysAvailMgrs);
1213 :
1214 2 : for (SysAvailNum = 1; SysAvailNum <= state.dataSystemAvailabilityManager->NumNVentSysAvailMgrs; ++SysAvailNum) {
1215 :
1216 1 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
1217 : cCurrentModuleObject,
1218 : SysAvailNum,
1219 : cAlphaArgs,
1220 : NumAlphas,
1221 : rNumericArgs,
1222 : NumNumbers,
1223 : IOStatus,
1224 : lNumericFieldBlanks,
1225 : lAlphaFieldBlanks,
1226 : cAlphaFieldNames,
1227 : cNumericFieldNames);
1228 :
1229 1 : auto &nightVentMgr = state.dataSystemAvailabilityManager->NightVentData(SysAvailNum);
1230 1 : nightVentMgr.Name = cAlphaArgs(1);
1231 1 : nightVentMgr.MgrType = DataPlant::SystemAvailabilityType::NightVent;
1232 :
1233 1 : nightVentMgr.SchedPtr = GetScheduleIndex(state, cAlphaArgs(2));
1234 1 : if (nightVentMgr.SchedPtr == 0) {
1235 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
1236 0 : ShowContinueError(state, "not found: " + cAlphaFieldNames(2) + "=\"" + cAlphaArgs(2) + "\".");
1237 0 : ErrorsFound = true;
1238 : }
1239 1 : nightVentMgr.FanSched = cAlphaArgs(3);
1240 1 : nightVentMgr.FanSchedPtr = GetScheduleIndex(state, cAlphaArgs(3));
1241 1 : if (nightVentMgr.FanSchedPtr == 0) {
1242 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
1243 0 : ShowContinueError(state, "not found: " + cAlphaFieldNames(3) + "=\"" + cAlphaArgs(3) + "\".");
1244 0 : ErrorsFound = true;
1245 : }
1246 1 : nightVentMgr.VentTempSched = cAlphaArgs(4);
1247 1 : nightVentMgr.VentTempSchedPtr = GetScheduleIndex(state, cAlphaArgs(4));
1248 1 : if (nightVentMgr.VentTempSchedPtr == 0) {
1249 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
1250 0 : ShowContinueError(state, "not found: " + cAlphaFieldNames(4) + "=\"" + cAlphaArgs(4) + "\".");
1251 0 : ErrorsFound = true;
1252 : }
1253 1 : nightVentMgr.VentDelT = rNumericArgs(1);
1254 1 : nightVentMgr.VentTempLowLim = rNumericArgs(2);
1255 1 : nightVentMgr.VentFlowFrac = rNumericArgs(3);
1256 1 : nightVentMgr.CtrlZoneName = cAlphaArgs(5);
1257 1 : nightVentMgr.ZoneNum = UtilityRoutines::FindItemInList(cAlphaArgs(5), state.dataHeatBal->Zone);
1258 1 : if (nightVentMgr.ZoneNum == 0) {
1259 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, cAlphaArgs(1)));
1260 0 : ShowContinueError(state, "not found: " + cAlphaFieldNames(5) + "=\"" + cAlphaArgs(5) + "\".");
1261 0 : ErrorsFound = true;
1262 : }
1263 :
1264 2 : SetupOutputVariable(state,
1265 : "Availability Manager Night Ventilation Control Status",
1266 : OutputProcessor::Unit::None,
1267 : nightVentMgr.AvailStatus,
1268 : OutputProcessor::SOVTimeStepType::System,
1269 : OutputProcessor::SOVStoreType::Average,
1270 1 : nightVentMgr.Name);
1271 :
1272 : } // SysAvailNum
1273 : }
1274 :
1275 771 : cAlphaFieldNames.deallocate();
1276 771 : cAlphaArgs.deallocate();
1277 771 : lAlphaFieldBlanks.deallocate();
1278 771 : cNumericFieldNames.deallocate();
1279 771 : rNumericArgs.deallocate();
1280 771 : lNumericFieldBlanks.deallocate();
1281 :
1282 771 : if (ErrorsFound) {
1283 0 : ShowFatalError(state, format("{}Errors found in input. Preceding condition(s) cause termination.", RoutineName));
1284 : }
1285 771 : }
1286 :
1287 704 : void GetSysAvailManagerListInputs(EnergyPlusData &state)
1288 : {
1289 :
1290 : // SUBROUTINE INFORMATION:
1291 : // AUTHOR Linda Lawrie
1292 : // DATE WRITTEN August 2007
1293 : // MODIFIED na
1294 : // RE-ENGINEERED na
1295 :
1296 : // PURPOSE OF THIS SUBROUTINE:
1297 : // This routine gets the System Availability Manager List object input and stores
1298 : // it for later retrieval of items from the Plant and Air Loops.
1299 :
1300 704 : if (state.dataSystemAvailabilityManager->GetAvailMgrInputFlag) {
1301 521 : GetSysAvailManagerInputs(state);
1302 521 : state.dataSystemAvailabilityManager->GetAvailMgrInputFlag = false;
1303 : }
1304 :
1305 704 : bool ErrorsFound = false;
1306 1408 : std::string cCurrentModuleObject = "AvailabilityManagerAssignmentList";
1307 704 : auto &ip = state.dataInputProcessing->inputProcessor;
1308 :
1309 704 : state.dataSystemAvailabilityManager->NumAvailManagerLists = ip->getNumObjectsFound(state, cCurrentModuleObject);
1310 :
1311 704 : if (state.dataSystemAvailabilityManager->NumAvailManagerLists > 0) {
1312 :
1313 524 : state.dataSystemAvailabilityManager->ListData.allocate(state.dataSystemAvailabilityManager->NumAvailManagerLists);
1314 1048 : auto const instances = ip->epJSON.find(cCurrentModuleObject);
1315 524 : auto const &objectSchemaProps = ip->getObjectSchemaProps(state, cCurrentModuleObject);
1316 :
1317 524 : auto &instancesValue = instances.value();
1318 524 : int Item = 0;
1319 1741 : for (auto instance = instancesValue.begin(); instance != instancesValue.end(); ++instance) {
1320 1217 : ++Item;
1321 1217 : auto const &objectFields = instance.value();
1322 2434 : auto const &thisObjectName = UtilityRoutines::MakeUPPERCase(instance.key());
1323 1217 : ip->markObjectAsUsed(cCurrentModuleObject, instance.key());
1324 1217 : auto &mgrList = state.dataSystemAvailabilityManager->ListData(Item);
1325 1217 : mgrList.Name = thisObjectName;
1326 :
1327 2434 : auto extensibles = objectFields.find("managers");
1328 1217 : auto const &extensionSchemaProps = objectSchemaProps["managers"]["items"]["properties"];
1329 1217 : if (extensibles != objectFields.end()) {
1330 2434 : auto extensiblesArray = extensibles.value();
1331 1217 : int numExtensibles = extensiblesArray.size();
1332 1217 : mgrList.NumItems = numExtensibles;
1333 1217 : mgrList.AvailManagerName.allocate(numExtensibles);
1334 1217 : mgrList.AvailManagerType.allocate(numExtensibles);
1335 2450 : for (int extItem = 1; extItem <= numExtensibles; ++extItem) {
1336 1233 : mgrList.AvailManagerName = "";
1337 1233 : mgrList.AvailManagerType = DataPlant::SystemAvailabilityType::Invalid;
1338 : }
1339 :
1340 1217 : int listItem = 0;
1341 2450 : for (nlohmann::json const &extensibleInstance : extensiblesArray) {
1342 1233 : ++listItem;
1343 1233 : mgrList.AvailManagerName(listItem) =
1344 2466 : ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "availability_manager_name");
1345 : std::string availManagerObjType =
1346 2466 : ip->getAlphaFieldValue(extensibleInstance, extensionSchemaProps, "availability_manager_object_type");
1347 1233 : mgrList.AvailManagerType(listItem) = static_cast<DataPlant::SystemAvailabilityType>(
1348 2466 : getEnumerationValue(SystemAvailabilityTypeNamesUC, UtilityRoutines::MakeUPPERCase(availManagerObjType)));
1349 1233 : if (mgrList.AvailManagerType(listItem) == DataPlant::SystemAvailabilityType::HybridVent)
1350 0 : mgrList.AvailManagerType(listItem) = DataPlant::SystemAvailabilityType::Invalid;
1351 : // these are validated individually in the GetPlant, GetSystem and GetZoneEq lists
1352 : }
1353 : }
1354 : }
1355 :
1356 524 : if (ErrorsFound) {
1357 0 : ShowFatalError(state, "GetSysAvailManagerListInputs: Program terminates due to preceding conditions.");
1358 : }
1359 : }
1360 704 : }
1361 :
1362 854 : void GetPlantAvailabilityManager(EnergyPlusData &state,
1363 : std::string const &AvailabilityListName, // name that should be an Availability Manager List Name
1364 : int const Loop, // which loop this is
1365 : int const NumPlantLoops, // Total number of plant loops
1366 : bool &ErrorsFound // true if certain errors are detected here
1367 : )
1368 : {
1369 :
1370 : // SUBROUTINE INFORMATION:
1371 : // AUTHOR Linda Lawrie
1372 : // DATE WRITTEN August 2007
1373 : // MODIFIED na
1374 : // RE-ENGINEERED na
1375 :
1376 : // PURPOSE OF THIS SUBROUTINE:
1377 : // This subroutine gets the plant availability manager data for the indicated
1378 : // loop. If the PlantAvailMgr structure has not been allocated, it will be allocated
1379 : // to "number of plant loops".
1380 :
1381 : using namespace DataPlant;
1382 :
1383 : int Found;
1384 : int Num;
1385 :
1386 854 : if (state.dataSystemAvailabilityManager->GetAvailListsInput) {
1387 428 : GetSysAvailManagerListInputs(state);
1388 428 : state.dataSystemAvailabilityManager->GetAvailListsInput = false;
1389 : }
1390 :
1391 854 : if (!allocated(state.dataPlnt->PlantAvailMgr)) {
1392 0 : state.dataPlnt->PlantAvailMgr.allocate(NumPlantLoops);
1393 : }
1394 :
1395 854 : Found = 0;
1396 854 : if (state.dataSystemAvailabilityManager->NumAvailManagerLists > 0)
1397 700 : Found = UtilityRoutines::FindItemInList(AvailabilityListName, state.dataSystemAvailabilityManager->ListData);
1398 :
1399 854 : if (Found != 0) {
1400 42 : state.dataPlnt->PlantAvailMgr(Loop).NumAvailManagers = state.dataSystemAvailabilityManager->ListData(Found).NumItems;
1401 42 : state.dataPlnt->PlantAvailMgr(Loop).AvailStatus = NoAction;
1402 42 : state.dataPlnt->PlantAvailMgr(Loop).StartTime = 0;
1403 42 : state.dataPlnt->PlantAvailMgr(Loop).StopTime = 0;
1404 42 : state.dataPlnt->PlantAvailMgr(Loop).AvailManagerName.allocate(state.dataPlnt->PlantAvailMgr(Loop).NumAvailManagers);
1405 42 : state.dataPlnt->PlantAvailMgr(Loop).AvailManagerType.allocate(state.dataPlnt->PlantAvailMgr(Loop).NumAvailManagers);
1406 42 : state.dataPlnt->PlantAvailMgr(Loop).AvailManagerNum.allocate(state.dataPlnt->PlantAvailMgr(Loop).NumAvailManagers);
1407 92 : for (Num = 1; Num <= state.dataPlnt->PlantAvailMgr(Loop).NumAvailManagers; ++Num) {
1408 50 : state.dataPlnt->PlantAvailMgr(Loop).AvailManagerName(Num) =
1409 50 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerName(Num);
1410 50 : state.dataPlnt->PlantAvailMgr(Loop).AvailManagerNum(Num) = 0;
1411 50 : state.dataPlnt->PlantAvailMgr(Loop).AvailManagerType(Num) =
1412 50 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerType(Num);
1413 50 : if (state.dataPlnt->PlantAvailMgr(Loop).AvailManagerType(Num) == DataPlant::SystemAvailabilityType::Invalid) {
1414 0 : ShowSevereError(state,
1415 0 : format("GetPlantLoopData/GetPlantAvailabilityManager: Invalid System Availability Manager Type entered=\"{}\".",
1416 : SystemAvailabilityTypeNamesUC[static_cast<int>(
1417 0 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerType(Num))]));
1418 0 : ShowContinueError(state, "Occurs in AvailabilityManagerAssignmentList=\"" + AvailabilityListName + "\".");
1419 0 : ErrorsFound = true;
1420 : }
1421 52 : if (state.dataSystemAvailabilityManager->ListData(Found).AvailManagerType(Num) == SystemAvailabilityType::DiffThermo &&
1422 2 : Num != state.dataPlnt->PlantAvailMgr(Loop).NumAvailManagers) {
1423 0 : ShowWarningError(state,
1424 0 : "GetPlantLoopData/GetPlantAvailabilityManager: AvailabilityManager:DifferentialThermostat=\"" +
1425 0 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerName(Num) + "\".");
1426 0 : ShowContinueError(
1427 : state, "...is not the last manager on the AvailabilityManagerAssignmentList. Any remaining managers will not be used.");
1428 0 : ShowContinueError(state, "Occurs in AvailabilityManagerAssignmentList =\"" + AvailabilityListName + "\".");
1429 : }
1430 100 : if (state.dataSystemAvailabilityManager->ListData(Found).AvailManagerType(Num) == SystemAvailabilityType::NightVent ||
1431 50 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerType(Num) == SystemAvailabilityType::NightCycle) {
1432 0 : ShowSevereError(state,
1433 0 : format("GetPlantLoopData/GetPlantAvailabilityManager: Invalid System Availability Manager Type entered=\"{}\".",
1434 : SystemAvailabilityTypeNamesUC[static_cast<int>(
1435 0 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerType(Num))]));
1436 0 : ShowContinueError(state, "...this manager is not used in a Plant Loop.");
1437 0 : ShowContinueError(state, "Occurs in AvailabilityManagerAssignmentList=\"" + AvailabilityListName + "\".");
1438 0 : ErrorsFound = true;
1439 : }
1440 : } // End of Num Loop
1441 :
1442 : } else {
1443 812 : if (AvailabilityListName != "") {
1444 3 : ShowWarningError(state,
1445 2 : "GetPlantLoopData/GetPlantAvailabilityManager: AvailabilityManagerAssignmentList=" + AvailabilityListName +
1446 : " not found in lists. No availability will be used.");
1447 : }
1448 812 : state.dataPlnt->PlantAvailMgr(Loop).NumAvailManagers = 0;
1449 812 : state.dataPlnt->PlantAvailMgr(Loop).AvailStatus = NoAction;
1450 812 : state.dataPlnt->PlantAvailMgr(Loop).AvailManagerName.allocate(state.dataPlnt->PlantAvailMgr(Loop).NumAvailManagers);
1451 812 : state.dataPlnt->PlantAvailMgr(Loop).AvailManagerType.allocate(state.dataPlnt->PlantAvailMgr(Loop).NumAvailManagers);
1452 812 : state.dataPlnt->PlantAvailMgr(Loop).AvailManagerNum.allocate(state.dataPlnt->PlantAvailMgr(Loop).NumAvailManagers);
1453 : }
1454 854 : }
1455 :
1456 1177 : void GetAirLoopAvailabilityManager(EnergyPlusData &state,
1457 : std::string const &AvailabilityListName, // name that should be an Availability Manager List Name
1458 : int const Loop, // which loop this is
1459 : int const NumAirLoops, // Total number of air loops
1460 : bool &ErrorsFound // true if certain errors are detected here
1461 : )
1462 : {
1463 :
1464 : // SUBROUTINE INFORMATION:
1465 : // AUTHOR Linda Lawrie
1466 : // DATE WRITTEN August 2007
1467 : // MODIFIED na
1468 : // RE-ENGINEERED na
1469 :
1470 : // PURPOSE OF THIS SUBROUTINE:
1471 : // This subroutine gets the availability manager data for the indicated air
1472 : // loop or for the indicated type of zone equipment component.
1473 : // If the PriAirSysAvailMgr structure has not been allocated, it will be allocated
1474 : // to "number of air loops".
1475 :
1476 : using namespace DataAirLoop;
1477 :
1478 : int Found;
1479 : int Num;
1480 : // INTEGER :: CompNumAvailManagers ! Number of availability managers associated with a ZoneHVAC:* component
1481 :
1482 1177 : if (state.dataSystemAvailabilityManager->GetAvailListsInput) {
1483 174 : GetSysAvailManagerListInputs(state);
1484 174 : state.dataSystemAvailabilityManager->GetAvailListsInput = false;
1485 : }
1486 :
1487 1177 : if (!allocated(state.dataAirLoop->PriAirSysAvailMgr)) {
1488 524 : state.dataAirLoop->PriAirSysAvailMgr.allocate(NumAirLoops);
1489 : }
1490 :
1491 1177 : Found = 0;
1492 1177 : if (state.dataSystemAvailabilityManager->NumAvailManagerLists > 0)
1493 1134 : Found = UtilityRoutines::FindItemInList(AvailabilityListName, state.dataSystemAvailabilityManager->ListData);
1494 :
1495 1177 : if (Found != 0) {
1496 1134 : state.dataAirLoop->PriAirSysAvailMgr(Loop).NumAvailManagers = state.dataSystemAvailabilityManager->ListData(Found).NumItems;
1497 1134 : state.dataAirLoop->PriAirSysAvailMgr(Loop).AvailStatus = NoAction;
1498 1134 : state.dataAirLoop->PriAirSysAvailMgr(Loop).StartTime = 0;
1499 1134 : state.dataAirLoop->PriAirSysAvailMgr(Loop).StopTime = 0;
1500 1134 : state.dataAirLoop->PriAirSysAvailMgr(Loop).ReqSupplyFrac = 1.0;
1501 1134 : state.dataAirLoop->PriAirSysAvailMgr(Loop).AvailManagerName.allocate(state.dataAirLoop->PriAirSysAvailMgr(Loop).NumAvailManagers);
1502 1134 : state.dataAirLoop->PriAirSysAvailMgr(Loop).AvailManagerType.allocate(state.dataAirLoop->PriAirSysAvailMgr(Loop).NumAvailManagers);
1503 1134 : state.dataAirLoop->PriAirSysAvailMgr(Loop).AvailManagerNum.allocate(state.dataAirLoop->PriAirSysAvailMgr(Loop).NumAvailManagers);
1504 2275 : for (Num = 1; Num <= state.dataAirLoop->PriAirSysAvailMgr(Loop).NumAvailManagers; ++Num) {
1505 1141 : state.dataAirLoop->PriAirSysAvailMgr(Loop).AvailManagerName(Num) =
1506 1141 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerName(Num);
1507 1141 : state.dataAirLoop->PriAirSysAvailMgr(Loop).AvailManagerNum(Num) = 0;
1508 1141 : state.dataAirLoop->PriAirSysAvailMgr(Loop).AvailManagerType(Num) =
1509 1141 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerType(Num);
1510 1141 : if (state.dataAirLoop->PriAirSysAvailMgr(Loop).AvailManagerType(Num) == DataPlant::SystemAvailabilityType::Invalid) {
1511 0 : ShowSevereError(
1512 : state,
1513 0 : format("GetAirPathData/GetAirLoopAvailabilityManager: Invalid AvailabilityManagerAssignmentList Type entered=\"{}\".",
1514 : SystemAvailabilityTypeNamesUC[static_cast<int>(
1515 0 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerType(Num))]));
1516 0 : ShowContinueError(state,
1517 0 : "Occurs in AvailabilityManagerAssignmentList=\"" +
1518 0 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerName(Num) + "\".");
1519 0 : ErrorsFound = true;
1520 : }
1521 1141 : if (state.dataSystemAvailabilityManager->ListData(Found).AvailManagerType(Num) == DataPlant::SystemAvailabilityType::DiffThermo &&
1522 0 : Num != state.dataAirLoop->PriAirSysAvailMgr(Loop).NumAvailManagers) {
1523 0 : ShowWarningError(state,
1524 0 : "GetAirPathData/GetAirLoopAvailabilityManager: AvailabilityManager:DifferentialThermostat=\"" +
1525 0 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerName(Num) + "\".");
1526 0 : ShowContinueError(
1527 : state, "...is not the last manager on the AvailabilityManagerAssignmentList. Any remaining managers will not be used.");
1528 0 : ShowContinueError(state,
1529 0 : "Occurs in AvailabilityManagerAssignmentList=\"" +
1530 0 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerName(Num) + "\".");
1531 : }
1532 : } // End of Num Loop
1533 :
1534 : } else {
1535 43 : if (AvailabilityListName != "") {
1536 0 : ShowWarningError(state,
1537 0 : "GetAirPathData/GetAirLoopAvailabilityManager: AvailabilityManagerAssignmentList=" + AvailabilityListName +
1538 : " not found in lists. No availability will be used.");
1539 : }
1540 43 : state.dataAirLoop->PriAirSysAvailMgr(Loop).NumAvailManagers = 0;
1541 43 : state.dataAirLoop->PriAirSysAvailMgr(Loop).AvailStatus = NoAction;
1542 43 : state.dataAirLoop->PriAirSysAvailMgr(Loop).AvailManagerName.allocate(state.dataAirLoop->PriAirSysAvailMgr(Loop).NumAvailManagers);
1543 43 : state.dataAirLoop->PriAirSysAvailMgr(Loop).AvailManagerType.allocate(state.dataAirLoop->PriAirSysAvailMgr(Loop).NumAvailManagers);
1544 43 : state.dataAirLoop->PriAirSysAvailMgr(Loop).AvailManagerNum.allocate(state.dataAirLoop->PriAirSysAvailMgr(Loop).NumAvailManagers);
1545 : }
1546 1177 : }
1547 :
1548 5277063 : void GetZoneEqAvailabilityManager(EnergyPlusData &state,
1549 : int const ZoneEquipType, // Type of ZoneHVAC:* component
1550 : int const CompNum, // Index of a particular ZoneHVAC:* component
1551 : bool &ErrorsFound // true if certain errors are detected here
1552 : )
1553 : {
1554 :
1555 : // SUBROUTINE INFORMATION:
1556 : // AUTHOR Linda Lawrie
1557 : // DATE WRITTEN April 2011
1558 : // MODIFIED Chandan Sharma, March 2011/July 2012 - FSEC: Added zone sys avail managers
1559 : // RE-ENGINEERED na
1560 :
1561 : // PURPOSE OF THIS SUBROUTINE:
1562 : // This subroutine gets the availability manager data for the indicated type of zone
1563 : // equipment component.
1564 : // If not allocated, ZoneComp structure will be allocated to "Total num of zone equip types" and
1565 : // ZoneCompAvailMgrs structure will be allocated to "Total number of components of the indicated type".
1566 :
1567 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1568 10554126 : std::string AvailabilityListName; // name that should be an Availability Manager List Name
1569 : int Found;
1570 : int Num;
1571 : int CompNumAvailManagers; // Number of availability managers associated with a ZoneHVAC:* component
1572 :
1573 5277063 : auto &ZoneComp = state.dataHVACGlobal->ZoneComp;
1574 :
1575 5277063 : if (state.dataSystemAvailabilityManager->GetAvailListsInput) {
1576 102 : GetSysAvailManagerListInputs(state);
1577 102 : state.dataSystemAvailabilityManager->GetAvailListsInput = false;
1578 : }
1579 :
1580 5277063 : if (ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).Input) { // when both air loop and zone eq avail managers are present, zone
1581 : // avail mngrs list name has not been read in first time through here
1582 : // (see end of if block)
1583 1614 : AvailabilityListName = ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailManagerListName;
1584 1614 : Found = 0;
1585 1614 : if (state.dataSystemAvailabilityManager->NumAvailManagerLists > 0)
1586 846 : Found = UtilityRoutines::FindItemInList(AvailabilityListName, state.dataSystemAvailabilityManager->ListData);
1587 1614 : if (Found != 0) {
1588 2 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).NumAvailManagers = state.dataSystemAvailabilityManager->ListData(Found).NumItems;
1589 2 : CompNumAvailManagers = ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).NumAvailManagers;
1590 2 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailStatus = NoAction;
1591 2 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).StartTime = 0;
1592 2 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).StopTime = 0;
1593 2 : if (!allocated(ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailManagerName)) {
1594 2 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailManagerName.allocate(CompNumAvailManagers);
1595 2 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailManagerType.allocate(CompNumAvailManagers);
1596 2 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailManagerNum.allocate(CompNumAvailManagers);
1597 : }
1598 5 : for (Num = 1; Num <= ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).NumAvailManagers; ++Num) {
1599 3 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailManagerName(Num) =
1600 3 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerName(Num);
1601 3 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailManagerNum(Num) = 0;
1602 3 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailManagerType(Num) =
1603 3 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerType(Num);
1604 3 : if (ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).AvailManagerType(Num) == DataPlant::SystemAvailabilityType::Invalid) {
1605 0 : ShowSevereError(state,
1606 0 : format("GetZoneEqAvailabilityManager: Invalid AvailabilityManagerAssignmentList Type entered=\"{}\".",
1607 : SystemAvailabilityTypeNamesUC[static_cast<int>(
1608 0 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerType(Num))]));
1609 0 : ShowContinueError(state,
1610 0 : "Occurs in AvailabilityManagerAssignmentList=\"" +
1611 0 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerName(Num) + "\".");
1612 0 : ErrorsFound = true;
1613 : }
1614 3 : if (state.dataSystemAvailabilityManager->ListData(Found).AvailManagerType(Num) == DataPlant::SystemAvailabilityType::DiffThermo &&
1615 0 : Num != ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).NumAvailManagers) {
1616 0 : ShowWarningError(state,
1617 0 : "GetZoneEqAvailabilityManager: AvailabilityManager:DifferentialThermostat=\"" +
1618 0 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerName(Num) + "\".");
1619 0 : ShowContinueError(
1620 : state, "...is not the last manager on the AvailabilityManagerAssignmentList. Any remaining managers will not be used.");
1621 0 : ShowContinueError(state,
1622 0 : "Occurs in AvailabilityManagerAssignmentList=\"" +
1623 0 : state.dataSystemAvailabilityManager->ListData(Found).AvailManagerName(Num) + "\".");
1624 : }
1625 : } // End of Num Loop
1626 : }
1627 1614 : if (ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).Count > 0 || Found > 0)
1628 807 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).Input = false;
1629 1614 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).Count += 1;
1630 : }
1631 5277063 : }
1632 :
1633 2638622 : void InitSysAvailManagers(EnergyPlusData &state)
1634 : {
1635 :
1636 : // SUBROUTINE INFORMATION:
1637 : // AUTHOR Fred Buhl
1638 : // DATE WRITTEN August 2001
1639 : // MODIFIED Brent Griffith, CR8376 initialize to NoAction every timestep
1640 :
1641 : // PURPOSE OF THIS SUBROUTINE:
1642 : // This subroutine is for initializations of the System Availability Manager objects.
1643 :
1644 : // METHODOLOGY EMPLOYED:
1645 : // Uses the status flags to trigger initializations.
1646 :
1647 : using DataZoneEquipment::NumValidSysAvailZoneComponents;
1648 :
1649 : int SysAvailNum; // DO loop indes for Sys Avail Manager objects
1650 : int ZoneEquipType;
1651 : int ZoneListNum;
1652 : int ScanZoneListNum;
1653 : int ZoneNum;
1654 : // One time initializations
1655 :
1656 2638622 : if (state.dataSystemAvailabilityManager->InitSysAvailManagers_MyOneTimeFlag) {
1657 :
1658 770 : for (SysAvailNum = 1; SysAvailNum <= state.dataSystemAvailabilityManager->NumOptStartSysAvailMgrs; ++SysAvailNum) {
1659 1 : auto &optimumStartMgr = state.dataSystemAvailabilityManager->OptimumStartData(SysAvailNum);
1660 1 : if (optimumStartMgr.optimumStartControlType == OptimumStartControlType::MaximumOfZoneList) {
1661 : // a zone list
1662 1 : ZoneListNum = UtilityRoutines::FindItemInList(optimumStartMgr.ZoneListName, state.dataHeatBal->ZoneList);
1663 1 : if (ZoneListNum > 0) {
1664 1 : optimumStartMgr.NumOfZones = state.dataHeatBal->ZoneList(ZoneListNum).NumOfZones;
1665 1 : if (!allocated(optimumStartMgr.ZonePtrs)) {
1666 0 : optimumStartMgr.ZonePtrs.allocate({1, state.dataHeatBal->ZoneList(ZoneListNum).NumOfZones});
1667 : }
1668 5 : for (ScanZoneListNum = 1; ScanZoneListNum <= state.dataHeatBal->ZoneList(ZoneListNum).NumOfZones; ++ScanZoneListNum) {
1669 4 : ZoneNum = state.dataHeatBal->ZoneList(ZoneListNum).Zone(ScanZoneListNum);
1670 4 : optimumStartMgr.ZonePtrs(ScanZoneListNum) = ZoneNum;
1671 : }
1672 : }
1673 : }
1674 : }
1675 :
1676 769 : state.dataSystemAvailabilityManager->InitSysAvailManagers_MyOneTimeFlag = false;
1677 :
1678 : } // end 1 time initializations
1679 :
1680 : // initialize individual availability managers to no action (CR 8376 reporting issue)
1681 2638622 : if (allocated(state.dataSystemAvailabilityManager->SchedData))
1682 3298133 : for (auto &e : state.dataSystemAvailabilityManager->SchedData)
1683 1918504 : e.AvailStatus = NoAction;
1684 2638622 : if (allocated(state.dataSystemAvailabilityManager->SchedOnData))
1685 20950 : for (auto &e : state.dataSystemAvailabilityManager->SchedOnData)
1686 10475 : e.AvailStatus = NoAction;
1687 2638622 : if (allocated(state.dataSystemAvailabilityManager->SchedOffData))
1688 24922 : for (auto &e : state.dataSystemAvailabilityManager->SchedOffData)
1689 12461 : e.AvailStatus = NoAction;
1690 2638622 : if (allocated(state.dataSystemAvailabilityManager->NightCycleData))
1691 2533527 : for (auto &e : state.dataSystemAvailabilityManager->NightCycleData)
1692 2054931 : e.AvailStatus = NoAction;
1693 2638622 : if (allocated(state.dataSystemAvailabilityManager->NightVentData))
1694 3642 : for (auto &e : state.dataSystemAvailabilityManager->NightVentData)
1695 1821 : e.AvailStatus = NoAction;
1696 2638622 : if (allocated(state.dataSystemAvailabilityManager->DiffThermoData))
1697 7538 : for (auto &e : state.dataSystemAvailabilityManager->DiffThermoData)
1698 3769 : e.AvailStatus = NoAction;
1699 2638622 : if (allocated(state.dataSystemAvailabilityManager->HiTurnOffData))
1700 7538 : for (auto &e : state.dataSystemAvailabilityManager->HiTurnOffData)
1701 3769 : e.AvailStatus = NoAction;
1702 2638622 : if (allocated(state.dataSystemAvailabilityManager->HiTurnOnData))
1703 72834 : for (auto &e : state.dataSystemAvailabilityManager->HiTurnOnData)
1704 36417 : e.AvailStatus = NoAction;
1705 2638622 : if (allocated(state.dataSystemAvailabilityManager->LoTurnOffData))
1706 457683 : for (auto &e : state.dataSystemAvailabilityManager->LoTurnOffData)
1707 233865 : e.AvailStatus = NoAction;
1708 2638622 : if (allocated(state.dataSystemAvailabilityManager->LoTurnOnData))
1709 7538 : for (auto &e : state.dataSystemAvailabilityManager->LoTurnOnData)
1710 3769 : e.AvailStatus = NoAction;
1711 2638622 : if (allocated(state.dataSystemAvailabilityManager->OptimumStartData)) {
1712 10108 : for (auto &e : state.dataSystemAvailabilityManager->OptimumStartData) {
1713 5054 : e.AvailStatus = NoAction;
1714 5054 : e.isSimulated = false;
1715 : }
1716 : }
1717 : // HybridVentSysAvailMgrData%AvailStatus= NoAction
1718 39579330 : for (ZoneEquipType = 1; ZoneEquipType <= NumValidSysAvailZoneComponents; ++ZoneEquipType) { // loop over the zone equipment types
1719 36940708 : if (allocated(state.dataHVACGlobal->ZoneComp)) {
1720 36940708 : if (state.dataHVACGlobal->ZoneComp(ZoneEquipType).TotalNumComp > 0)
1721 2857439 : for (auto &e : state.dataHVACGlobal->ZoneComp(ZoneEquipType).ZoneCompAvailMgrs)
1722 2340235 : e.AvailStatus = NoAction;
1723 : }
1724 : }
1725 2638622 : }
1726 :
1727 4347536 : void SimSysAvailManager(EnergyPlusData &state,
1728 : const DataPlant::SystemAvailabilityType SysAvailType,
1729 : std::string const &SysAvailName,
1730 : int &SysAvailNum,
1731 : int const PriAirSysNum, // Primary Air System index. If being called for a ZoneHVAC:* component
1732 : int const PreviousStatus,
1733 : int &AvailStatus,
1734 : Optional_int_const ZoneEquipType, // Type of ZoneHVAC:* equipment component
1735 : Optional_int_const CompNum // Index of ZoneHVAC:* equipment component
1736 : )
1737 : {
1738 :
1739 : // SUBROUTINE INFORMATION:
1740 : // AUTHOR Fred Buhl
1741 : // DATE WRITTEN August 2001
1742 : // MODIFIED na
1743 : // RE-ENGINEERED na
1744 :
1745 : // PURPOSE OF THIS SUBROUTINE
1746 : // Loop over all the System Availability Managers and invoke the correct
1747 : // System Availability Manager algorithm.
1748 :
1749 : // Using/Aliasing
1750 :
1751 4347536 : switch (SysAvailType) {
1752 2087557 : case DataPlant::SystemAvailabilityType::Scheduled: { // 'AvailabilityManager:Scheduled'
1753 2087557 : if (SysAvailNum == 0) {
1754 635 : SysAvailNum = UtilityRoutines::FindItemInList(SysAvailName, state.dataSystemAvailabilityManager->SchedData);
1755 : }
1756 2087557 : if (SysAvailNum > 0) {
1757 2087557 : CalcSchedSysAvailMgr(state, SysAvailNum, AvailStatus);
1758 : } else {
1759 0 : ShowFatalError(state, "SimSysAvailManager: AvailabilityManager:Scheduled not found: " + SysAvailName);
1760 : }
1761 :
1762 2087557 : } break;
1763 10475 : case DataPlant::SystemAvailabilityType::ScheduledOn: { // 'AvailabilityManager:ScheduledOn'
1764 10475 : if (SysAvailNum == 0) {
1765 4 : SysAvailNum = UtilityRoutines::FindItemInList(SysAvailName, state.dataSystemAvailabilityManager->SchedOnData);
1766 : }
1767 10475 : if (SysAvailNum > 0) {
1768 10475 : CalcSchedOnSysAvailMgr(state, SysAvailNum, AvailStatus);
1769 : } else {
1770 0 : ShowFatalError(state, "SimSysAvailManager: AvailabilityManager:ScheduledOn not found: " + SysAvailName);
1771 : }
1772 :
1773 10475 : } break;
1774 12460 : case DataPlant::SystemAvailabilityType::ScheduledOff: { // 'AvailabilityManager:ScheduledOff'
1775 12460 : if (SysAvailNum == 0) {
1776 5 : SysAvailNum = UtilityRoutines::FindItemInList(SysAvailName, state.dataSystemAvailabilityManager->SchedOffData);
1777 : }
1778 12460 : if (SysAvailNum > 0) {
1779 12460 : CalcSchedOffSysAvailMgr(state, SysAvailNum, AvailStatus);
1780 : } else {
1781 0 : ShowFatalError(state, "SimSysAvailManager: AvailabilityManager:ScheduledOff not found: " + SysAvailName);
1782 : }
1783 :
1784 12460 : } break;
1785 1986024 : case DataPlant::SystemAvailabilityType::NightCycle: { // 'AvailabilityManager:NightCycle'
1786 1986024 : if (SysAvailNum == 0) {
1787 487 : SysAvailNum = UtilityRoutines::FindItemInList(SysAvailName, state.dataSystemAvailabilityManager->NightCycleData);
1788 : }
1789 1986024 : if (SysAvailNum > 0) {
1790 1986024 : CalcNCycSysAvailMgr(state, SysAvailNum, PriAirSysNum, AvailStatus, ZoneEquipType, CompNum);
1791 : } else {
1792 0 : ShowFatalError(state, "SimSysAvailManager: AvailabilityManager:NightCycle not found: " + SysAvailName);
1793 : }
1794 :
1795 1986024 : } break;
1796 5054 : case DataPlant::SystemAvailabilityType::OptimumStart: { // 'AvailabilityManager:OptimumStart'
1797 5054 : if (SysAvailNum == 0) {
1798 1 : SysAvailNum = UtilityRoutines::FindItemInList(SysAvailName, state.dataSystemAvailabilityManager->OptimumStartData);
1799 : }
1800 5054 : if (SysAvailNum > 0) {
1801 5054 : CalcOptStartSysAvailMgr(state, SysAvailNum, PriAirSysNum, AvailStatus, ZoneEquipType, CompNum);
1802 : } else {
1803 0 : ShowFatalError(state, "SimSysAvailManager: AvailabilityManager:OptimumStart not found: " + SysAvailName);
1804 : }
1805 :
1806 5054 : } break;
1807 1821 : case DataPlant::SystemAvailabilityType::NightVent: { // 'AvailabilityManager:NightVentilation'
1808 1821 : if (SysAvailNum == 0) {
1809 1 : SysAvailNum = UtilityRoutines::FindItemInList(SysAvailName, state.dataSystemAvailabilityManager->NightVentData);
1810 : }
1811 1821 : if (SysAvailNum > 0) {
1812 1821 : CalcNVentSysAvailMgr(state, SysAvailNum, PriAirSysNum, AvailStatus, ZoneEquipType);
1813 : } else {
1814 0 : ShowFatalError(state, "SimSysAvailManager: AvailabilityManager:NightVentilation not found: " + SysAvailName);
1815 : }
1816 :
1817 1821 : } break;
1818 3670 : case DataPlant::SystemAvailabilityType::DiffThermo: { // 'AvailabilityManager:DifferentialThermostat'
1819 3670 : if (SysAvailNum == 0) {
1820 2 : SysAvailNum = UtilityRoutines::FindItemInList(SysAvailName, state.dataSystemAvailabilityManager->DiffThermoData);
1821 : }
1822 3670 : if (SysAvailNum > 0) {
1823 3670 : CalcDiffTSysAvailMgr(state, SysAvailNum, PreviousStatus, AvailStatus);
1824 : } else {
1825 0 : ShowFatalError(state, "SimSysAvailManager: AvailabilityManager:DifferentialThermostat not found: " + SysAvailName);
1826 : }
1827 3670 : } break;
1828 3769 : case DataPlant::SystemAvailabilityType::HiTempTOff: { // 'AvailabilityManager:HighTemperatureTurnOff'
1829 3769 : if (SysAvailNum == 0) {
1830 2 : SysAvailNum = UtilityRoutines::FindItemInList(SysAvailName, state.dataSystemAvailabilityManager->HiTurnOffData);
1831 : }
1832 3769 : if (SysAvailNum > 0) {
1833 3769 : CalcHiTurnOffSysAvailMgr(state, SysAvailNum, AvailStatus);
1834 : } else {
1835 0 : ShowFatalError(state, "SimSysAvailManager: AvailabilityManager:HighTemperatureTurnOff not found: " + SysAvailName);
1836 : }
1837 3769 : } break;
1838 11920 : case DataPlant::SystemAvailabilityType::HiTempTOn: { // 'AvailabilityManager:HighTemperatureTurnOn'
1839 11920 : if (SysAvailNum == 0) {
1840 3 : SysAvailNum = UtilityRoutines::FindItemInList(SysAvailName, state.dataSystemAvailabilityManager->HiTurnOnData);
1841 : }
1842 11920 : if (SysAvailNum > 0) {
1843 11920 : CalcHiTurnOnSysAvailMgr(state, SysAvailNum, AvailStatus);
1844 : } else {
1845 0 : ShowFatalError(state, "SimSysAvailManager: AvailabilityManager:HighTemperatureTurnOn not found: " + SysAvailName);
1846 : }
1847 11920 : } break;
1848 221017 : case DataPlant::SystemAvailabilityType::LoTempTOff: { // 'AvailabilityManager:LowTemperatureTurnOff'
1849 221017 : if (SysAvailNum == 0) {
1850 47 : SysAvailNum = UtilityRoutines::FindItemInList(SysAvailName, state.dataSystemAvailabilityManager->LoTurnOffData);
1851 : }
1852 221017 : if (SysAvailNum > 0) {
1853 221017 : CalcLoTurnOffSysAvailMgr(state, SysAvailNum, AvailStatus);
1854 : } else {
1855 0 : ShowFatalError(state, "SimSysAvailManager: AvailabilityManager:LowTemperatureTurnOff not found: " + SysAvailName);
1856 : }
1857 :
1858 221017 : } break;
1859 3769 : case DataPlant::SystemAvailabilityType::LoTempTOn: { // 'AvailabilityManager:LowTemperatureTurnOn'
1860 3769 : if (SysAvailNum == 0) {
1861 2 : SysAvailNum = UtilityRoutines::FindItemInList(SysAvailName, state.dataSystemAvailabilityManager->LoTurnOnData);
1862 : }
1863 3769 : if (SysAvailNum > 0) {
1864 3769 : CalcLoTurnOnSysAvailMgr(state, SysAvailNum, AvailStatus);
1865 : } else {
1866 0 : ShowFatalError(state, "SimSysAvailManager: AvailabilityManager:LowTemperatureTurnOn not found: " + SysAvailName);
1867 : }
1868 :
1869 3769 : } break;
1870 0 : default: {
1871 0 : ShowSevereError(state, format("AvailabilityManager Type not found: {}", SysAvailType));
1872 0 : ShowContinueError(state, "Occurs in Manager=" + SysAvailName);
1873 0 : ShowFatalError(state, "Preceding condition causes termination.");
1874 : }
1875 : }
1876 4347536 : }
1877 :
1878 2087557 : void CalcSchedSysAvailMgr(EnergyPlusData &state,
1879 : int const SysAvailNum, // number of the current scheduled system availability manager
1880 : int &AvailStatus // System status indicator
1881 : )
1882 : {
1883 :
1884 : // SUBROUTINE INFORMATION:
1885 : // AUTHOR Fred Buhl
1886 : // DATE WRITTEN August 2001
1887 : // MODIFIED na
1888 : // RE-ENGINEERED na
1889 :
1890 : // PURPOSE OF THIS SUBROUTINE:
1891 : // Set AvailStatus indicator for a primary air loop, plant loop or ZoneHVAC component.
1892 :
1893 : // METHODOLOGY EMPLOYED:
1894 : // Looks at the System Availability Manager schedule and sets the
1895 : // AvailStatus indicator accordingly. Mostly a useless algorithm
1896 : // since the fan schedules can do the same thing.
1897 :
1898 2087557 : if (GetCurrentScheduleValue(state, state.dataSystemAvailabilityManager->SchedData(SysAvailNum).SchedPtr) > 0.0) {
1899 1772961 : AvailStatus = CycleOn;
1900 : } else {
1901 314596 : AvailStatus = ForceOff;
1902 : }
1903 :
1904 2087557 : state.dataSystemAvailabilityManager->SchedData(SysAvailNum).AvailStatus = AvailStatus;
1905 2087557 : }
1906 :
1907 10475 : void CalcSchedOnSysAvailMgr(EnergyPlusData &state,
1908 : int const SysAvailNum, // number of the current scheduled on system availability manager
1909 : int &AvailStatus // System status indicator
1910 : )
1911 : {
1912 :
1913 : // SUBROUTINE INFORMATION:
1914 : // AUTHOR R. Raustad - FSEC
1915 : // DATE WRITTEN August 2008
1916 : // MODIFIED na
1917 : // RE-ENGINEERED na
1918 :
1919 : // PURPOSE OF THIS SUBROUTINE:
1920 : // Set AvailStatus indicator for a primary air loop, plant loop or ZoneHVAC component.
1921 :
1922 : // METHODOLOGY EMPLOYED:
1923 : // Looks at the System Availability Manager schedule and sets the
1924 : // AvailStatus indicator accordingly. If the schedule value is > 0
1925 : // the availability status is CycleOn, ELSE the status is NoAction.
1926 :
1927 10475 : if (GetCurrentScheduleValue(state, state.dataSystemAvailabilityManager->SchedOnData(SysAvailNum).SchedPtr) > 0.0) {
1928 7099 : AvailStatus = CycleOn;
1929 : } else {
1930 3376 : AvailStatus = NoAction;
1931 : }
1932 :
1933 10475 : state.dataSystemAvailabilityManager->SchedOnData(SysAvailNum).AvailStatus = AvailStatus;
1934 10475 : }
1935 :
1936 12460 : void CalcSchedOffSysAvailMgr(EnergyPlusData &state,
1937 : int const SysAvailNum, // number of the current scheduled off system availability manager
1938 : int &AvailStatus // System status indicator
1939 : )
1940 : {
1941 :
1942 : // SUBROUTINE INFORMATION:
1943 : // AUTHOR R. Raustad - FSEC
1944 : // DATE WRITTEN August 2008
1945 : // MODIFIED na
1946 : // RE-ENGINEERED na
1947 :
1948 : // PURPOSE OF THIS SUBROUTINE:
1949 : // Set AvailStatus indicator for a primary air loop, plant loop or ZoneHVAC component.
1950 :
1951 : // METHODOLOGY EMPLOYED:
1952 : // Looks at the System Availability Manager schedule and sets the
1953 : // AvailStatus indicator accordingly. If the schedule value is = 0
1954 : // the availability status is ForceOff, ELSE the status is NoAction.
1955 :
1956 12460 : if (GetCurrentScheduleValue(state, state.dataSystemAvailabilityManager->SchedOffData(SysAvailNum).SchedPtr) == 0.0) {
1957 3432 : AvailStatus = ForceOff;
1958 : } else {
1959 9028 : AvailStatus = NoAction;
1960 : }
1961 :
1962 12460 : state.dataSystemAvailabilityManager->SchedOffData(SysAvailNum).AvailStatus = AvailStatus;
1963 12460 : }
1964 :
1965 1986024 : void CalcNCycSysAvailMgr(EnergyPlusData &state,
1966 : int const SysAvailNum, // number of the current scheduled system availability manager
1967 : int const PriAirSysNum, // number of the primary air system affected by this Avail. Manager
1968 : int &AvailStatus, // System status indicator
1969 : Optional_int_const ZoneEquipType, // Type of ZoneHVAC equipment component
1970 : Optional_int_const CompNum // Index of ZoneHVAC equipment component
1971 : )
1972 : {
1973 :
1974 : // SUBROUTINE INFORMATION:
1975 : // AUTHOR Fred Buhl
1976 : // DATE WRITTEN August 2001
1977 : // MODIFIED March 2011, Chandan Sharma - FSEC: Allowed night cycle
1978 : // availability manager to work for ZoneHVAC component
1979 : // RE-ENGINEERED na
1980 :
1981 : // PURPOSE OF THIS SUBROUTINE:
1982 : // Set AvailStatus indicator for a primary air loop or ZoneHVAC component.
1983 :
1984 : // METHODOLOGY EMPLOYED:
1985 : // For air loop, depending on the type of control, looks at 1 named zone or all the zones
1986 : // attached to a primary air system, compares zone temperature to the setup
1987 : // or setback thermostat setpoint, and sets the AvailStaus indicator according
1988 : // to whether the system needs to be cycled on or not.
1989 : // For ZoneHVAC component, uses the exact same method as above but only looks at the
1990 : // zone where component is located.
1991 :
1992 : using namespace DataAirLoop;
1993 :
1994 : int StartTime;
1995 : int StopTime;
1996 : int ZoneInSysNum;
1997 : Real64 TempTol;
1998 1986024 : auto &ZoneCompNCControlType = state.dataSystemAvailabilityManager->ZoneCompNCControlType;
1999 :
2000 1986024 : auto &ZoneComp = state.dataHVACGlobal->ZoneComp;
2001 1986024 : if (present(ZoneEquipType)) {
2002 6018 : if (state.dataGlobal->WarmupFlag && state.dataGlobal->BeginDayFlag) {
2003 : // reset start/stop times at beginning of each day during warmup to prevent non-convergence due to rotating start times
2004 75 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).StartTime = state.dataGlobal->SimTimeSteps;
2005 75 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).StopTime = state.dataGlobal->SimTimeSteps;
2006 : }
2007 :
2008 6018 : StartTime = ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).StartTime;
2009 6018 : StopTime = ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).StopTime;
2010 6018 : if (state.dataSystemAvailabilityManager->CalcNCycSysAvailMgr_OneTimeFlag) {
2011 2 : ZoneCompNCControlType.dimension(state.dataSystemAvailabilityManager->NumNCycSysAvailMgrs, true);
2012 2 : state.dataSystemAvailabilityManager->CalcNCycSysAvailMgr_OneTimeFlag = false;
2013 : }
2014 : } else {
2015 1980006 : if (state.dataGlobal->WarmupFlag && state.dataGlobal->BeginDayFlag) {
2016 : // reset start/stop times at beginning of each day during warmup to prevent non-convergence due to rotating start times
2017 27584 : state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).StartTime = state.dataGlobal->SimTimeSteps;
2018 27584 : state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).StopTime = state.dataGlobal->SimTimeSteps;
2019 : }
2020 :
2021 1980006 : StartTime = state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).StartTime;
2022 1980006 : StopTime = state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).StopTime;
2023 : }
2024 : // CR 7913 changed to allow during warmup
2025 1986024 : auto &nightCycleMgr = state.dataSystemAvailabilityManager->NightCycleData(SysAvailNum);
2026 1986024 : if ((GetCurrentScheduleValue(state, nightCycleMgr.SchedPtr) <= 0.0) || (GetCurrentScheduleValue(state, nightCycleMgr.FanSchedPtr) > 0.0)) {
2027 853872 : AvailStatus = NoAction;
2028 853872 : nightCycleMgr.AvailStatus = AvailStatus; // CR 8358
2029 853872 : return;
2030 : }
2031 :
2032 1132152 : if (nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::FixedRunTime) {
2033 1128739 : TempTol = 0.5 * nightCycleMgr.TempTolRange;
2034 : } else {
2035 3413 : TempTol = 0.05;
2036 : }
2037 :
2038 1132152 : if (present(ZoneEquipType)) {
2039 8940 : if (state.dataGlobal->SimTimeSteps >= StartTime && state.dataGlobal->SimTimeSteps < StopTime &&
2040 3867 : (nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::FixedRunTime ||
2041 1749 : nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::ThermostatWithMinimumRunTime)) { // if cycled on
2042 2118 : AvailStatus = CycleOn;
2043 4161 : } else if (state.dataGlobal->SimTimeSteps == StopTime &&
2044 1575 : nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::FixedRunTime) { // if end of cycle run time, shut down if fan off
2045 120 : AvailStatus = NoAction;
2046 : } else {
2047 :
2048 2466 : switch (nightCycleMgr.nightCycleControlType) { // select type of night cycle control
2049 :
2050 0 : case NightCycleControlType::Off: {
2051 0 : AvailStatus = NoAction;
2052 0 : } break;
2053 2466 : case NightCycleControlType::OnControlZone: {
2054 :
2055 2466 : int ZoneNum = nightCycleMgr.CtrlZonePtrs(1);
2056 :
2057 2466 : switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) { // select on thermostat control
2058 :
2059 0 : case DataHVACGlobals::ThermostatType::SingleHeating: {
2060 0 : if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) < state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) - TempTol) {
2061 0 : AvailStatus = CycleOn;
2062 : } else {
2063 0 : AvailStatus = NoAction;
2064 : }
2065 :
2066 0 : } break;
2067 0 : case DataHVACGlobals::ThermostatType::SingleCooling: {
2068 0 : if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) > state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) + TempTol) {
2069 0 : AvailStatus = CycleOn;
2070 : } else {
2071 0 : AvailStatus = NoAction;
2072 : }
2073 :
2074 0 : } break;
2075 0 : case DataHVACGlobals::ThermostatType::SingleHeatCool: {
2076 0 : if ((state.dataHeatBalFanSys->TempTstatAir(ZoneNum) <
2077 0 : state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) - TempTol) ||
2078 0 : (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) >
2079 0 : state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) + TempTol)) {
2080 0 : AvailStatus = CycleOn;
2081 : } else {
2082 0 : AvailStatus = NoAction;
2083 : }
2084 :
2085 0 : } break;
2086 2466 : case DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand: {
2087 4497 : if ((state.dataHeatBalFanSys->TempTstatAir(ZoneNum) < state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum) - TempTol) ||
2088 2031 : (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) > state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum) + TempTol)) {
2089 685 : AvailStatus = CycleOn;
2090 : } else {
2091 1781 : AvailStatus = NoAction;
2092 : }
2093 :
2094 2466 : } break;
2095 0 : default: {
2096 0 : AvailStatus = NoAction;
2097 : }
2098 : } // end select on thermostat control
2099 2466 : } break;
2100 0 : case NightCycleControlType::OnAny:
2101 : case NightCycleControlType::OnZoneFansOnly: {
2102 0 : if (ZoneCompNCControlType(SysAvailNum)) {
2103 0 : ShowWarningError(state,
2104 0 : "AvailabilityManager:NightCycle = " + nightCycleMgr.Name + ", is specified for a ZoneHVAC component.");
2105 0 : ShowContinueError(state, "The only valid Control Types for ZoneHVAC components are CycleOnControlZone and StayOff.");
2106 0 : ShowContinueError(state, "Night Cycle operation will not be modeled for ZoneHVAC components that reference this manager.");
2107 0 : ZoneCompNCControlType(SysAvailNum) = false;
2108 : }
2109 0 : AvailStatus = NoAction;
2110 0 : } break;
2111 0 : default: {
2112 0 : AvailStatus = NoAction;
2113 0 : break;
2114 : }
2115 : } // end select type of night cycle control
2116 :
2117 2466 : if (AvailStatus == CycleOn) { // reset the start and stop times
2118 685 : if (nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::Thermostat) { // Cycling Run Time is ignored
2119 0 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).StartTime = state.dataGlobal->SimTimeSteps;
2120 0 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).StopTime = state.dataGlobal->SimTimeSteps;
2121 : } else {
2122 685 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).StartTime = state.dataGlobal->SimTimeSteps;
2123 685 : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(CompNum).StopTime = state.dataGlobal->SimTimeSteps + nightCycleMgr.CyclingTimeSteps;
2124 : }
2125 : }
2126 : }
2127 : } else {
2128 2212596 : if (state.dataGlobal->SimTimeSteps >= StartTime && state.dataGlobal->SimTimeSteps < StopTime &&
2129 542574 : (nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::FixedRunTime ||
2130 0 : nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::ThermostatWithMinimumRunTime)) { // if cycled on
2131 542574 : AvailStatus = nightCycleMgr.PriorAvailStatus;
2132 542574 : if (nightCycleMgr.nightCycleControlType == NightCycleControlType::OnZoneFansOnly) AvailStatus = CycleOnZoneFansOnly;
2133 914985 : } else if (state.dataGlobal->SimTimeSteps == StopTime &&
2134 330111 : nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::FixedRunTime) { // if end of cycle run time, shut down if fan off
2135 330111 : AvailStatus = NoAction;
2136 : } else {
2137 :
2138 254763 : switch (nightCycleMgr.nightCycleControlType) { // select type of night cycle control
2139 :
2140 4119 : case NightCycleControlType::Off: {
2141 4119 : AvailStatus = NoAction;
2142 4119 : } break;
2143 250636 : case NightCycleControlType::OnAny:
2144 : case NightCycleControlType::OnZoneFansOnly: {
2145 :
2146 : // If no zones cooled, Availstatus could be "unknown"
2147 250636 : AvailStatus = NoAction;
2148 :
2149 666961 : for (ZoneInSysNum = 1; ZoneInSysNum <= state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).NumZonesCooled;
2150 : ++ZoneInSysNum) { // loop over zones in system
2151 :
2152 479785 : int ZoneNum = state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).CoolCtrlZoneNums(ZoneInSysNum);
2153 :
2154 479785 : switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) {
2155 0 : case DataHVACGlobals::ThermostatType::SingleHeating: {
2156 0 : if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) <
2157 0 : state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) - TempTol) {
2158 0 : AvailStatus = CycleOn;
2159 : } else {
2160 0 : AvailStatus = NoAction;
2161 : }
2162 0 : } break;
2163 0 : case DataHVACGlobals::ThermostatType::SingleCooling: {
2164 0 : if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) >
2165 0 : state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) + TempTol) {
2166 0 : AvailStatus = CycleOn;
2167 : } else {
2168 0 : AvailStatus = NoAction;
2169 : }
2170 0 : } break;
2171 0 : case DataHVACGlobals::ThermostatType::SingleHeatCool: {
2172 0 : if ((state.dataHeatBalFanSys->TempTstatAir(ZoneNum) <
2173 0 : state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) - TempTol) ||
2174 0 : (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) >
2175 0 : state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) + TempTol)) {
2176 0 : AvailStatus = CycleOn;
2177 : } else {
2178 0 : AvailStatus = NoAction;
2179 : }
2180 0 : } break;
2181 479785 : case DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand: {
2182 959570 : if ((state.dataHeatBalFanSys->TempTstatAir(ZoneNum) <
2183 913298 : state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum) - TempTol) ||
2184 433513 : (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) >
2185 433513 : state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum) + TempTol)) {
2186 63460 : AvailStatus = CycleOn;
2187 : } else {
2188 416325 : AvailStatus = NoAction;
2189 : }
2190 479785 : } break;
2191 0 : default: {
2192 0 : AvailStatus = NoAction;
2193 : }
2194 : } // end select on thermostat control
2195 479785 : if (AvailStatus == CycleOn) break; // loop break
2196 187176 : } // end loop over zones in system
2197 250636 : } break;
2198 0 : case NightCycleControlType::OnControlZone: {
2199 0 : AvailStatus = NoAction;
2200 0 : if (CoolingZoneOutOfTolerance(state, nightCycleMgr.CtrlZonePtrs, nightCycleMgr.NumOfCtrlZones, TempTol)) AvailStatus = CycleOn;
2201 0 : if (HeatingZoneOutOfTolerance(state, nightCycleMgr.CtrlZonePtrs, nightCycleMgr.NumOfCtrlZones, TempTol)) AvailStatus = CycleOn;
2202 0 : } break;
2203 8 : case NightCycleControlType::OnAnyCoolingOrHeatingZone: {
2204 8 : if (CoolingZoneOutOfTolerance(state, nightCycleMgr.CoolingZonePtrs, nightCycleMgr.NumOfCoolingZones, TempTol)) {
2205 0 : AvailStatus = CycleOn;
2206 8 : } else if (HeatingZoneOutOfTolerance(state, nightCycleMgr.HeatingZonePtrs, nightCycleMgr.NumOfHeatingZones, TempTol)) {
2207 0 : AvailStatus = CycleOn;
2208 8 : } else if (HeatingZoneOutOfTolerance(state, nightCycleMgr.HeatZnFanZonePtrs, nightCycleMgr.NumOfHeatZnFanZones, TempTol)) {
2209 0 : AvailStatus = CycleOnZoneFansOnly;
2210 : } else {
2211 8 : AvailStatus = NoAction;
2212 : }
2213 8 : } break;
2214 0 : case NightCycleControlType::OnAnyCoolingZone: {
2215 0 : if (CoolingZoneOutOfTolerance(state, nightCycleMgr.CoolingZonePtrs, nightCycleMgr.NumOfCoolingZones, TempTol)) {
2216 0 : AvailStatus = CycleOn;
2217 : } else {
2218 0 : AvailStatus = NoAction;
2219 : }
2220 0 : } break;
2221 0 : case NightCycleControlType::OnAnyHeatingZone: {
2222 0 : if (HeatingZoneOutOfTolerance(state, nightCycleMgr.HeatingZonePtrs, nightCycleMgr.NumOfHeatingZones, TempTol)) {
2223 0 : AvailStatus = CycleOn;
2224 0 : } else if (HeatingZoneOutOfTolerance(state, nightCycleMgr.HeatZnFanZonePtrs, nightCycleMgr.NumOfHeatZnFanZones, TempTol)) {
2225 0 : AvailStatus = CycleOnZoneFansOnly;
2226 : } else {
2227 0 : AvailStatus = NoAction;
2228 : }
2229 0 : } break;
2230 0 : case NightCycleControlType::OnAnyHeatingZoneFansOnly: {
2231 0 : if (HeatingZoneOutOfTolerance(state, nightCycleMgr.HeatZnFanZonePtrs, nightCycleMgr.NumOfHeatZnFanZones, TempTol)) {
2232 0 : AvailStatus = CycleOnZoneFansOnly;
2233 : } else {
2234 0 : AvailStatus = NoAction;
2235 : }
2236 0 : } break;
2237 0 : default:
2238 0 : AvailStatus = NoAction;
2239 : } // end select type of night cycle control
2240 :
2241 254763 : if ((AvailStatus == CycleOn) || (AvailStatus == CycleOnZoneFansOnly)) { // reset the start and stop times
2242 63460 : if (nightCycleMgr.nightCycleControlType == NightCycleControlType::OnZoneFansOnly) AvailStatus = CycleOnZoneFansOnly;
2243 : // issue #6151
2244 63460 : if (nightCycleMgr.cyclingRunTimeControl == CyclingRunTimeControl::Thermostat) { // Cycling Run Time is ignored
2245 0 : state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).StartTime = state.dataGlobal->SimTimeSteps;
2246 0 : state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).StopTime = state.dataGlobal->SimTimeSteps;
2247 : } else {
2248 63460 : state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).StartTime = state.dataGlobal->SimTimeSteps;
2249 63460 : state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).StopTime = state.dataGlobal->SimTimeSteps + nightCycleMgr.CyclingTimeSteps;
2250 : }
2251 : }
2252 : }
2253 : }
2254 1132152 : nightCycleMgr.AvailStatus = AvailStatus;
2255 1132152 : nightCycleMgr.PriorAvailStatus = AvailStatus;
2256 : }
2257 :
2258 8 : bool CoolingZoneOutOfTolerance(EnergyPlusData &state,
2259 : Array1D_int const ZonePtrList, // list of controlled zone pointers
2260 : int const NumZones, // number of zones in list
2261 : Real64 const TempTolerance // temperature tolerance
2262 : )
2263 : {
2264 : // Check if any zone temperature is above the cooling setpoint plus tolerance
2265 32 : for (int Index = 1; Index <= NumZones; ++Index) { // loop over zones in list
2266 24 : int ZoneNum = ZonePtrList(Index);
2267 :
2268 24 : switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) {
2269 0 : case DataHVACGlobals::ThermostatType::SingleCooling:
2270 : case DataHVACGlobals::ThermostatType::SingleHeatCool:
2271 0 : if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) > state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) + TempTolerance) {
2272 0 : return true; // return on the first zone found
2273 : }
2274 0 : break;
2275 24 : case DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand:
2276 24 : if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) > state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum) + TempTolerance) {
2277 0 : return true; // return on the first zone found
2278 : }
2279 24 : break;
2280 0 : default:
2281 0 : break;
2282 : }
2283 : }
2284 8 : return false;
2285 : }
2286 :
2287 16 : bool HeatingZoneOutOfTolerance(EnergyPlusData &state,
2288 : Array1D_int const ZonePtrList, // list of controlled zone pointers
2289 : int const NumZones, // number of zones in list
2290 : Real64 const TempTolerance // temperature tolerance
2291 : )
2292 : {
2293 : // Check if any zone temperature is below the heating setpoint less tolerance
2294 40 : for (int Index = 1; Index <= NumZones; ++Index) { // loop over zones in list
2295 24 : int ZoneNum = ZonePtrList(Index);
2296 : {
2297 24 : auto const tstatType(state.dataHeatBalFanSys->TempControlType(ZoneNum));
2298 :
2299 24 : if ((tstatType == DataHVACGlobals::ThermostatType::SingleHeating) || (tstatType == DataHVACGlobals::ThermostatType::SingleHeatCool)) {
2300 0 : if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) <
2301 0 : state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum) - TempTolerance) {
2302 0 : return true; // return on the first zone found
2303 : }
2304 24 : } else if (tstatType == DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand) {
2305 24 : if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) < state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum) - TempTolerance) {
2306 0 : return true; // return on the first zone found
2307 : }
2308 : }
2309 : }
2310 : }
2311 16 : return false;
2312 : }
2313 :
2314 5054 : void CalcOptStartSysAvailMgr(EnergyPlusData &state,
2315 : int const SysAvailNum, // number of the current scheduled system availability manager
2316 : int const PriAirSysNum, // number of the primary air system affected by this Avail. Manager
2317 : int &AvailStatus, // System status indicator
2318 : [[maybe_unused]] Optional_int_const ZoneEquipType, // Type of ZoneHVAC equipment component
2319 : [[maybe_unused]] Optional_int_const CompNum // Index of ZoneHVAC equipment component
2320 : )
2321 : {
2322 :
2323 : // SUBROUTINE INFORMATION:
2324 : // AUTHOR Xiufeng Pang (XP)
2325 : // DATE WRITTEN August 2013
2326 : // MODIFIED
2327 : // RE-ENGINEERED
2328 :
2329 : // PURPOSE OF THIS SUBROUTINE:
2330 : // Set AvailStatus indicator for a primary air loop, plant loop or ZoneHVAC component
2331 :
2332 : // METHODOLOGY EMPLOYED:
2333 : // Sets the AvailStatus indicator according to the
2334 : // optimum start algorithm
2335 :
2336 : // Using/Aliasing
2337 : using namespace DataAirLoop;
2338 :
2339 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2340 :
2341 : int ScheduleIndex;
2342 10108 : Array2D<Real64> DayValues;
2343 10108 : Array2D<Real64> DayValuesTmr;
2344 : int JDay;
2345 : int TmrJDay;
2346 : int TmrDayOfWeek;
2347 : int ZoneNum;
2348 : Real64 FanStartTime;
2349 : Real64 FanStartTimeTmr;
2350 : Real64 PreStartTime;
2351 : Real64 PreStartTimeTmr;
2352 : Real64 DeltaTime;
2353 : Real64 TempDiff;
2354 : Real64 TempDiffHi;
2355 : Real64 TempDiffLo;
2356 5054 : bool FirstTimeATGFlag(true);
2357 5054 : bool OverNightStartFlag(false); // Flag to indicate the optimum start starts before mid night.
2358 5054 : bool CycleOnFlag(false);
2359 5054 : bool OSReportVarFlag(true);
2360 : int NumPreDays;
2361 : int NumOfZonesInList;
2362 : Real64 AdaTempGradHeat;
2363 : Real64 AdaTempGradCool;
2364 5054 : Real64 ATGUpdateTime1(0.0);
2365 5054 : Real64 ATGUpdateTime2(0.0);
2366 5054 : Real64 ATGUpdateTemp1(0.0);
2367 5054 : Real64 ATGUpdateTemp2(0.0);
2368 5054 : bool ATGUpdateFlag1(false);
2369 5054 : bool ATGUpdateFlag2(false);
2370 : int ATGCounter;
2371 : int ATGWCZoneNumHi;
2372 : int ATGWCZoneNumLo;
2373 : Real64 NumHoursBeforeOccupancy; // Variable to store the number of hours before occupancy in optimum start period
2374 : bool exitLoop; // exit loop on found data
2375 :
2376 5054 : auto &OptStartMgr(state.dataSystemAvailabilityManager->OptimumStartData(SysAvailNum));
2377 :
2378 : // some avail managers may be used in air loop and plant availability manager lists, if so they only need be simulated once
2379 5054 : if (OptStartMgr.isSimulated) {
2380 0 : AvailStatus = OptStartMgr.AvailStatus;
2381 0 : return;
2382 : }
2383 5054 : OptStartMgr.isSimulated = true;
2384 :
2385 : // update air loop specific data
2386 5054 : TempDiffLo = OptStartMgr.TempDiffLo;
2387 5054 : TempDiffHi = OptStartMgr.TempDiffHi;
2388 5054 : ATGWCZoneNumLo = OptStartMgr.ATGWCZoneNumLo;
2389 5054 : ATGWCZoneNumHi = OptStartMgr.ATGWCZoneNumHi;
2390 5054 : CycleOnFlag = OptStartMgr.CycleOnFlag;
2391 5054 : ATGUpdateFlag1 = OptStartMgr.ATGUpdateFlag1;
2392 5054 : ATGUpdateFlag2 = OptStartMgr.ATGUpdateFlag2;
2393 5054 : NumHoursBeforeOccupancy = OptStartMgr.NumHoursBeforeOccupancy;
2394 5054 : FirstTimeATGFlag = OptStartMgr.FirstTimeATGFlag;
2395 5054 : OverNightStartFlag = OptStartMgr.OverNightStartFlag;
2396 5054 : OSReportVarFlag = OptStartMgr.OSReportVarFlag;
2397 :
2398 5054 : if (OptStartMgr.controlAlgorithm == ControlAlgorithm::AdaptiveTemperatureGradient) {
2399 5054 : NumPreDays = OptStartMgr.NumPreDays;
2400 5054 : if (!allocated(state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat)) {
2401 1 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat.allocate(NumPreDays);
2402 1 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool.allocate(NumPreDays);
2403 : }
2404 5054 : if (!allocated(OptStartMgr.AdaTempGradTrdHeat)) {
2405 1 : OptStartMgr.AdaTempGradTrdHeat.allocate(NumPreDays);
2406 1 : OptStartMgr.AdaTempGradTrdHeat = 0.0;
2407 1 : OptStartMgr.AdaTempGradTrdCool.allocate(NumPreDays);
2408 1 : OptStartMgr.AdaTempGradTrdCool = 0.0;
2409 : }
2410 5054 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat = OptStartMgr.AdaTempGradTrdHeat;
2411 5054 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool = OptStartMgr.AdaTempGradTrdCool;
2412 5054 : AdaTempGradHeat = OptStartMgr.AdaTempGradHeat;
2413 5054 : AdaTempGradCool = OptStartMgr.AdaTempGradCool;
2414 5054 : ATGUpdateTime1 = OptStartMgr.ATGUpdateTime1;
2415 5054 : ATGUpdateTime2 = OptStartMgr.ATGUpdateTime2;
2416 5054 : ATGUpdateTemp1 = OptStartMgr.ATGUpdateTemp1;
2417 5054 : ATGUpdateTemp2 = OptStartMgr.ATGUpdateTemp2;
2418 : }
2419 :
2420 5054 : auto &OptStartData = state.dataHVACGlobal->OptStartData;
2421 :
2422 : // add or use a new variable OptStartSysAvailMgrData(SysAvailNum)%FanSchIndex
2423 5054 : if (state.dataGlobal->KickOffSimulation) {
2424 12 : AvailStatus = NoAction;
2425 : } else {
2426 5042 : ScheduleIndex = GetScheduleIndex(state, OptStartMgr.FanSched);
2427 5042 : JDay = state.dataEnvrn->DayOfYear;
2428 5042 : TmrJDay = JDay + 1;
2429 5042 : TmrDayOfWeek = state.dataEnvrn->DayOfWeekTomorrow;
2430 :
2431 5042 : DayValues.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
2432 5042 : DayValuesTmr.allocate(state.dataGlobal->NumOfTimeStepInHour, 24);
2433 5042 : if (!allocated(OptStartData.OptStartFlag)) {
2434 1 : OptStartData.OptStartFlag.allocate(state.dataGlobal->NumOfZones);
2435 1 : OptStartData.OccStartTime.allocate(state.dataGlobal->NumOfZones);
2436 : }
2437 5042 : if (!allocated(OptStartData.ActualZoneNum)) OptStartData.ActualZoneNum.allocate(state.dataGlobal->NumOfZones);
2438 :
2439 : // OptStartFlag needs to be reset each timestep to not stay set to true post-occupancy
2440 5042 : OptStartData.OptStartFlag = false;
2441 :
2442 : // reset OptStartData once per beginning of day
2443 5042 : if (state.dataGlobal->BeginDayFlag) {
2444 66 : NumHoursBeforeOccupancy = 0.0; // Initialize the hours of optimum start period. This variable is for reporting purpose.
2445 66 : if (state.dataSystemAvailabilityManager->BeginOfDayResetFlag) {
2446 16 : OptStartData.OccStartTime = 22.99; // initialize the zone occupancy start time
2447 16 : state.dataSystemAvailabilityManager->BeginOfDayResetFlag = false;
2448 : }
2449 : }
2450 5042 : if (!state.dataGlobal->BeginDayFlag) state.dataSystemAvailabilityManager->BeginOfDayResetFlag = true;
2451 :
2452 5042 : GetScheduleValuesForDay(state, ScheduleIndex, DayValues);
2453 5042 : GetScheduleValuesForDay(state, ScheduleIndex, DayValuesTmr, TmrJDay, TmrDayOfWeek);
2454 :
2455 5042 : FanStartTime = 0.0;
2456 5042 : FanStartTimeTmr = 0.0;
2457 5042 : exitLoop = false;
2458 35294 : for (int I = 1; I <= 24; ++I) {
2459 216806 : for (int J = 1; J <= state.dataGlobal->NumOfTimeStepInHour; ++J) {
2460 186554 : if (DayValues(J, I) <= 0.0) continue;
2461 5042 : FanStartTime = I - 1 + 1.0 / state.dataGlobal->NumOfTimeStepInHour * J - 0.01;
2462 5042 : exitLoop = true;
2463 5042 : break;
2464 : }
2465 35294 : if (exitLoop) break;
2466 : }
2467 :
2468 5042 : exitLoop = false;
2469 35294 : for (int I = 1; I <= 24; ++I) {
2470 216806 : for (int J = 1; J <= state.dataGlobal->NumOfTimeStepInHour; ++J) {
2471 186554 : if (DayValuesTmr(J, I) <= 0.0) continue;
2472 5042 : FanStartTimeTmr = I - 1 + 1.0 / state.dataGlobal->NumOfTimeStepInHour * J - 0.01;
2473 5042 : exitLoop = true;
2474 5042 : break;
2475 : }
2476 35294 : if (exitLoop) break;
2477 : }
2478 :
2479 5042 : if (FanStartTimeTmr == 0.0) FanStartTimeTmr = 24.0;
2480 :
2481 : // Pass the start time to ZoneTempPredictorCorrector
2482 30252 : for (int counter = 1; counter <= state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).NumZonesCooled; ++counter) {
2483 25210 : int actZoneNum = state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).CoolCtrlZoneNums(counter);
2484 25210 : OptStartData.OccStartTime(actZoneNum) = FanStartTime;
2485 25210 : OptStartData.ActualZoneNum(actZoneNum) = actZoneNum;
2486 : }
2487 5042 : for (int counter = 1; counter <= state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).NumZonesHeated; ++counter) {
2488 0 : int actZoneNum = state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).HeatCtrlZoneNums(counter);
2489 0 : OptStartData.OccStartTime(actZoneNum) = FanStartTime;
2490 0 : OptStartData.ActualZoneNum(actZoneNum) = actZoneNum;
2491 : }
2492 :
2493 5042 : if (state.dataEnvrn->DSTIndicator > 0) {
2494 0 : --FanStartTime;
2495 0 : --FanStartTimeTmr;
2496 : }
2497 :
2498 5042 : switch (OptStartMgr.controlAlgorithm) {
2499 0 : case ControlAlgorithm::ConstantStartTime: {
2500 0 : if (OptStartMgr.optimumStartControlType == OptimumStartControlType::Off) {
2501 0 : AvailStatus = NoAction;
2502 : } else {
2503 0 : DeltaTime = OptStartMgr.ConstStartTime;
2504 0 : if (DeltaTime > OptStartMgr.MaxOptStartTime) {
2505 0 : DeltaTime = OptStartMgr.MaxOptStartTime;
2506 : }
2507 0 : PreStartTime = FanStartTime - DeltaTime;
2508 0 : if (PreStartTime < 0.0) PreStartTime = -0.1;
2509 0 : PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
2510 0 : if (PreStartTimeTmr < 0.0) {
2511 0 : PreStartTimeTmr += 24.0;
2512 0 : OverNightStartFlag = true;
2513 : } else {
2514 0 : OverNightStartFlag = false;
2515 : }
2516 0 : if (!OverNightStartFlag) {
2517 0 : if (FanStartTime == 0.0 || state.dataGlobal->PreviousHour > FanStartTime) {
2518 0 : AvailStatus = NoAction;
2519 0 : OSReportVarFlag = true;
2520 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime) {
2521 0 : if (OSReportVarFlag) {
2522 0 : NumHoursBeforeOccupancy = DeltaTime;
2523 0 : OSReportVarFlag = false;
2524 : }
2525 0 : AvailStatus = CycleOn;
2526 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2527 : } else {
2528 0 : AvailStatus = NoAction;
2529 0 : OSReportVarFlag = true;
2530 : }
2531 : } else {
2532 0 : if (FanStartTime == 0.0 || (state.dataGlobal->HourOfDay > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
2533 0 : AvailStatus = NoAction;
2534 0 : OSReportVarFlag = true;
2535 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
2536 0 : if (OSReportVarFlag) {
2537 0 : NumHoursBeforeOccupancy = DeltaTime;
2538 0 : OSReportVarFlag = false;
2539 : }
2540 0 : AvailStatus = CycleOn;
2541 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2542 : } else {
2543 0 : AvailStatus = NoAction;
2544 0 : OSReportVarFlag = true;
2545 : }
2546 : }
2547 : }
2548 0 : } break;
2549 0 : case ControlAlgorithm::ConstantTemperatureGradient: {
2550 0 : if (OptStartMgr.optimumStartControlType == OptimumStartControlType::ControlZone) {
2551 0 : ZoneNum = OptStartMgr.ZoneNum;
2552 0 : if ((!allocated(state.dataHeatBalFanSys->TempTstatAir)) || (!allocated(state.dataHeatBalFanSys->ZoneThermostatSetPointLo)) ||
2553 0 : (!allocated(state.dataHeatBalFanSys->ZoneThermostatSetPointHi))) {
2554 0 : TempDiff = 0.0;
2555 : } else {
2556 0 : if (!CycleOnFlag) {
2557 0 : if (allocated(state.dataZoneCtrls->OccRoomTSetPointHeat) && allocated(state.dataZoneCtrls->OccRoomTSetPointCool)) {
2558 0 : TempDiffHi = state.dataHeatBalFanSys->TempTstatAir(ZoneNum) - state.dataZoneCtrls->OccRoomTSetPointCool(ZoneNum);
2559 0 : TempDiffLo = state.dataHeatBalFanSys->TempTstatAir(ZoneNum) - state.dataZoneCtrls->OccRoomTSetPointHeat(ZoneNum);
2560 : } else {
2561 0 : TempDiffHi = 0.0;
2562 0 : TempDiffLo = 0.0;
2563 : }
2564 : }
2565 : }
2566 :
2567 0 : if (TempDiffHi < 0.0) {
2568 0 : TempDiff = TempDiffLo;
2569 0 : if (TempDiff < 0.0) { // Heating Mode
2570 0 : TempDiff = std::abs(TempDiff);
2571 0 : DeltaTime = TempDiff / OptStartMgr.ConstTGradHeat;
2572 0 : if (DeltaTime > OptStartMgr.MaxOptStartTime) {
2573 0 : DeltaTime = OptStartMgr.MaxOptStartTime;
2574 : }
2575 0 : PreStartTime = FanStartTime - DeltaTime;
2576 0 : if (PreStartTime < 0) PreStartTime = -0.1;
2577 0 : PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
2578 0 : if (PreStartTimeTmr < 0) {
2579 0 : PreStartTimeTmr += 24.0;
2580 0 : OverNightStartFlag = true;
2581 : } else {
2582 0 : OverNightStartFlag = false;
2583 : }
2584 0 : if (!OverNightStartFlag) {
2585 0 : if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
2586 0 : CycleOnFlag = false;
2587 0 : OSReportVarFlag = true;
2588 0 : } else if (CycleOnFlag) {
2589 0 : AvailStatus = CycleOn;
2590 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2591 0 : if (state.dataGlobal->CurrentTime > FanStartTime) CycleOnFlag = false;
2592 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime) {
2593 0 : AvailStatus = CycleOn;
2594 0 : CycleOnFlag = true;
2595 0 : if (OSReportVarFlag) {
2596 0 : NumHoursBeforeOccupancy = DeltaTime;
2597 0 : OSReportVarFlag = false;
2598 : }
2599 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2600 : } else {
2601 0 : AvailStatus = NoAction;
2602 0 : CycleOnFlag = false;
2603 0 : OSReportVarFlag = true;
2604 : }
2605 : } else {
2606 0 : if (FanStartTime == 0.0 ||
2607 0 : (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
2608 0 : AvailStatus = NoAction;
2609 0 : CycleOnFlag = false;
2610 0 : OSReportVarFlag = true;
2611 0 : } else if (CycleOnFlag) {
2612 0 : AvailStatus = CycleOn;
2613 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2614 0 : if (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime < PreStartTimeTmr)
2615 0 : CycleOnFlag = false;
2616 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
2617 0 : if (OSReportVarFlag) {
2618 0 : NumHoursBeforeOccupancy = DeltaTime;
2619 0 : OSReportVarFlag = false;
2620 : }
2621 0 : AvailStatus = CycleOn;
2622 0 : CycleOnFlag = true;
2623 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2624 : } else {
2625 0 : AvailStatus = NoAction;
2626 0 : CycleOnFlag = false;
2627 0 : OSReportVarFlag = true;
2628 : }
2629 : }
2630 : } else {
2631 0 : AvailStatus = NoAction;
2632 0 : CycleOnFlag = false;
2633 : }
2634 0 : } else if (state.dataZoneCtrls->OccRoomTSetPointCool(ZoneNum) < 50.0) { // Cooling Mode
2635 0 : TempDiff = TempDiffHi;
2636 0 : DeltaTime = TempDiff / OptStartMgr.ConstTGradCool;
2637 0 : if (DeltaTime > OptStartMgr.MaxOptStartTime) {
2638 0 : DeltaTime = OptStartMgr.MaxOptStartTime;
2639 : }
2640 0 : PreStartTime = FanStartTime - DeltaTime;
2641 0 : if (PreStartTime < 0) PreStartTime = -0.1;
2642 0 : PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
2643 0 : if (PreStartTimeTmr < 0) {
2644 0 : PreStartTimeTmr += 24.0;
2645 0 : OverNightStartFlag = true;
2646 : } else {
2647 0 : OverNightStartFlag = false;
2648 : }
2649 0 : if (!OverNightStartFlag) {
2650 0 : if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
2651 0 : AvailStatus = NoAction;
2652 0 : CycleOnFlag = false;
2653 0 : OSReportVarFlag = true;
2654 0 : } else if (CycleOnFlag) {
2655 0 : AvailStatus = CycleOn;
2656 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2657 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime) {
2658 0 : if (OSReportVarFlag) {
2659 0 : NumHoursBeforeOccupancy = DeltaTime;
2660 0 : OSReportVarFlag = false;
2661 : }
2662 0 : AvailStatus = CycleOn;
2663 0 : CycleOnFlag = true;
2664 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2665 : } else {
2666 0 : AvailStatus = NoAction;
2667 0 : CycleOnFlag = false;
2668 0 : OSReportVarFlag = true;
2669 : }
2670 : } else {
2671 0 : if (FanStartTime == 0.0 ||
2672 0 : (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
2673 0 : AvailStatus = NoAction;
2674 0 : CycleOnFlag = false;
2675 0 : OSReportVarFlag = true;
2676 0 : } else if (CycleOnFlag) {
2677 0 : AvailStatus = CycleOn;
2678 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2679 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
2680 0 : if (OSReportVarFlag) {
2681 0 : NumHoursBeforeOccupancy = DeltaTime;
2682 0 : OSReportVarFlag = false;
2683 : }
2684 0 : AvailStatus = CycleOn;
2685 0 : CycleOnFlag = true;
2686 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2687 : } else {
2688 0 : AvailStatus = NoAction;
2689 0 : CycleOnFlag = false;
2690 0 : OSReportVarFlag = true;
2691 : }
2692 : }
2693 : } else {
2694 0 : AvailStatus = NoAction;
2695 0 : CycleOnFlag = false;
2696 : }
2697 0 : } else if (OptStartMgr.optimumStartControlType == OptimumStartControlType::MaximumOfZoneList) {
2698 :
2699 0 : NumOfZonesInList = OptStartMgr.NumOfZones;
2700 0 : if ((!allocated(state.dataHeatBalFanSys->TempTstatAir)) || (!allocated(state.dataHeatBalFanSys->ZoneThermostatSetPointLo)) ||
2701 0 : (!allocated(state.dataHeatBalFanSys->ZoneThermostatSetPointHi))) {
2702 0 : TempDiff = 0.0;
2703 : } else {
2704 0 : if (!CycleOnFlag) {
2705 0 : if (allocated(state.dataZoneCtrls->OccRoomTSetPointHeat) && allocated(state.dataZoneCtrls->OccRoomTSetPointCool)) {
2706 0 : TempDiffHi = 0.0;
2707 0 : TempDiffLo = 0.0;
2708 0 : for (ZoneNum = 1; ZoneNum <= NumOfZonesInList; ++ZoneNum) {
2709 0 : TempDiff = state.dataHeatBalFanSys->TempTstatAir(OptStartMgr.ZonePtrs(ZoneNum)) -
2710 0 : state.dataZoneCtrls->OccRoomTSetPointCool(OptStartMgr.ZonePtrs(ZoneNum));
2711 0 : TempDiffHi = max(TempDiffHi, TempDiff);
2712 0 : TempDiff = state.dataHeatBalFanSys->TempTstatAir(OptStartMgr.ZonePtrs(ZoneNum)) -
2713 0 : state.dataZoneCtrls->OccRoomTSetPointHeat(OptStartMgr.ZonePtrs(ZoneNum));
2714 0 : TempDiffLo = min(TempDiffLo, TempDiff);
2715 : }
2716 : } else {
2717 0 : TempDiffHi = 0.0;
2718 0 : TempDiffLo = 0.0;
2719 : }
2720 : }
2721 : }
2722 0 : if ((TempDiffHi < 0.0 && TempDiffLo < 0.0) || (std::abs(TempDiffLo) > std::abs(TempDiffHi) && TempDiffLo < 0)) { // Heating Mode
2723 0 : TempDiff = TempDiffLo;
2724 0 : TempDiff = std::abs(TempDiff);
2725 0 : DeltaTime = TempDiff / OptStartMgr.ConstTGradHeat;
2726 0 : if (DeltaTime > OptStartMgr.MaxOptStartTime) {
2727 0 : DeltaTime = OptStartMgr.MaxOptStartTime;
2728 : }
2729 0 : PreStartTime = FanStartTime - DeltaTime;
2730 0 : if (PreStartTime < 0) PreStartTime = -0.1;
2731 0 : PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
2732 0 : if (PreStartTimeTmr < 0) {
2733 0 : PreStartTimeTmr += 24.0;
2734 0 : OverNightStartFlag = true;
2735 : } else {
2736 0 : OverNightStartFlag = false;
2737 : }
2738 0 : if (!OverNightStartFlag) {
2739 0 : if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
2740 0 : AvailStatus = NoAction;
2741 0 : CycleOnFlag = false;
2742 0 : OSReportVarFlag = true;
2743 0 : } else if (CycleOnFlag) {
2744 0 : AvailStatus = CycleOn;
2745 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2746 0 : if (state.dataGlobal->CurrentTime > FanStartTime) CycleOnFlag = false;
2747 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime) {
2748 0 : if (OSReportVarFlag) {
2749 0 : NumHoursBeforeOccupancy = DeltaTime;
2750 0 : OSReportVarFlag = false;
2751 : }
2752 0 : AvailStatus = CycleOn;
2753 0 : CycleOnFlag = true;
2754 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2755 : } else {
2756 0 : AvailStatus = NoAction;
2757 0 : CycleOnFlag = false;
2758 0 : OSReportVarFlag = true;
2759 : }
2760 : } else {
2761 0 : if (FanStartTime == 0.0 ||
2762 0 : (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
2763 0 : AvailStatus = NoAction;
2764 0 : CycleOnFlag = false;
2765 0 : OSReportVarFlag = true;
2766 0 : } else if (CycleOnFlag) {
2767 0 : AvailStatus = CycleOn;
2768 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2769 0 : if (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime < PreStartTimeTmr)
2770 0 : CycleOnFlag = false;
2771 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
2772 0 : if (OSReportVarFlag) {
2773 0 : NumHoursBeforeOccupancy = DeltaTime;
2774 0 : OSReportVarFlag = false;
2775 : }
2776 0 : AvailStatus = CycleOn;
2777 0 : CycleOnFlag = true;
2778 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2779 : } else {
2780 0 : AvailStatus = NoAction;
2781 0 : CycleOnFlag = false;
2782 0 : OSReportVarFlag = true;
2783 : }
2784 : }
2785 0 : } else if (TempDiffHi <= 0.0 && TempDiffLo >= 0.0) { // not heating and not cooling
2786 0 : AvailStatus = NoAction;
2787 0 : CycleOnFlag = false;
2788 0 : TempDiffHi = 0.0;
2789 0 : TempDiffLo = 0.0;
2790 0 : } else if (TempDiffHi < 30.0) { // Cooling Mode
2791 0 : TempDiff = TempDiffHi;
2792 0 : DeltaTime = TempDiff / OptStartMgr.ConstTGradCool;
2793 0 : if (DeltaTime > OptStartMgr.MaxOptStartTime) {
2794 0 : DeltaTime = OptStartMgr.MaxOptStartTime;
2795 : }
2796 0 : PreStartTime = FanStartTime - DeltaTime;
2797 0 : if (PreStartTime < 0) PreStartTime = -0.1;
2798 0 : PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
2799 0 : if (PreStartTimeTmr < 0) {
2800 0 : PreStartTimeTmr += 24.0;
2801 0 : OverNightStartFlag = true;
2802 : } else {
2803 0 : OverNightStartFlag = false;
2804 : }
2805 0 : if (!OverNightStartFlag) {
2806 0 : if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
2807 0 : AvailStatus = NoAction;
2808 0 : CycleOnFlag = false;
2809 0 : OSReportVarFlag = true;
2810 0 : } else if (CycleOnFlag) {
2811 0 : AvailStatus = CycleOn;
2812 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2813 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime) {
2814 0 : if (OSReportVarFlag) {
2815 0 : NumHoursBeforeOccupancy = DeltaTime;
2816 0 : OSReportVarFlag = false;
2817 : }
2818 0 : AvailStatus = CycleOn;
2819 0 : CycleOnFlag = true;
2820 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2821 : } else {
2822 0 : AvailStatus = NoAction;
2823 0 : CycleOnFlag = false;
2824 0 : OSReportVarFlag = true;
2825 : }
2826 : } else {
2827 0 : if (FanStartTime == 0.0 ||
2828 0 : (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
2829 0 : AvailStatus = NoAction;
2830 0 : CycleOnFlag = false;
2831 0 : OSReportVarFlag = true;
2832 0 : } else if (CycleOnFlag) {
2833 0 : AvailStatus = CycleOn;
2834 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2835 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
2836 0 : if (OSReportVarFlag) {
2837 0 : NumHoursBeforeOccupancy = DeltaTime;
2838 0 : OSReportVarFlag = false;
2839 : }
2840 0 : AvailStatus = CycleOn;
2841 0 : CycleOnFlag = true;
2842 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2843 : } else {
2844 0 : AvailStatus = NoAction;
2845 0 : CycleOnFlag = false;
2846 0 : OSReportVarFlag = true;
2847 : }
2848 : }
2849 : } else {
2850 0 : AvailStatus = NoAction;
2851 0 : CycleOnFlag = false;
2852 : }
2853 : } else {
2854 0 : AvailStatus = NoAction;
2855 : }
2856 0 : } break;
2857 5042 : case ControlAlgorithm::AdaptiveTemperatureGradient: {
2858 :
2859 5042 : if (OptStartMgr.optimumStartControlType == OptimumStartControlType::ControlZone) {
2860 0 : ZoneNum = OptStartMgr.ZoneNum;
2861 0 : if ((!allocated(state.dataHeatBalFanSys->TempTstatAir)) || (!allocated(state.dataHeatBalFanSys->ZoneThermostatSetPointLo)) ||
2862 0 : (!allocated(state.dataHeatBalFanSys->ZoneThermostatSetPointHi))) {
2863 0 : TempDiff = 0.0;
2864 : } else {
2865 0 : if (!CycleOnFlag) {
2866 0 : if (allocated(state.dataZoneCtrls->OccRoomTSetPointHeat) && allocated(state.dataZoneCtrls->OccRoomTSetPointCool)) {
2867 0 : TempDiffHi = state.dataHeatBalFanSys->TempTstatAir(ZoneNum) - state.dataZoneCtrls->OccRoomTSetPointCool(ZoneNum);
2868 0 : TempDiffLo = state.dataHeatBalFanSys->TempTstatAir(ZoneNum) - state.dataZoneCtrls->OccRoomTSetPointHeat(ZoneNum);
2869 : } else {
2870 0 : TempDiffHi = 0.0;
2871 0 : TempDiffLo = 0.0;
2872 : }
2873 : }
2874 : }
2875 : // Store adaptive temperature gradients for previous days and calculate the adaptive temp gradients
2876 : //-----------------------------------------------------------------------------
2877 0 : if (state.dataGlobal->WarmupFlag) {
2878 0 : AdaTempGradHeat = OptStartMgr.InitTGradHeat;
2879 0 : AdaTempGradCool = OptStartMgr.InitTGradCool;
2880 0 : } else if (state.dataGlobal->DayOfSim == 1 && state.dataGlobal->BeginDayFlag) {
2881 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat = OptStartMgr.InitTGradHeat;
2882 0 : AdaTempGradHeat = OptStartMgr.InitTGradHeat;
2883 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool = OptStartMgr.InitTGradCool;
2884 0 : AdaTempGradCool = OptStartMgr.InitTGradCool;
2885 : } else {
2886 0 : if (state.dataGlobal->BeginDayFlag && FirstTimeATGFlag) {
2887 0 : FirstTimeATGFlag = false;
2888 0 : AdaTempGradHeat += state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(NumPreDays) / NumPreDays -
2889 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(1) / NumPreDays;
2890 0 : AdaTempGradCool += state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(NumPreDays) / NumPreDays -
2891 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(1) / NumPreDays;
2892 0 : if (FanStartTime > 0) {
2893 0 : for (ATGCounter = 1; ATGCounter <= NumPreDays - 1; ++ATGCounter) {
2894 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(ATGCounter) =
2895 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(ATGCounter + 1);
2896 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(ATGCounter) =
2897 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(ATGCounter + 1);
2898 : }
2899 : }
2900 : }
2901 : }
2902 :
2903 0 : if (state.dataGlobal->CurrentTime >= 1.0) FirstTimeATGFlag = true;
2904 : //------------------------------------------------------------------------------
2905 :
2906 0 : if (TempDiffHi < 0.0) {
2907 0 : TempDiff = TempDiffLo;
2908 0 : if (TempDiff < 0.0) { // Heating Mode
2909 0 : TempDiff = std::abs(TempDiff);
2910 0 : DeltaTime = TempDiff / AdaTempGradHeat;
2911 0 : if (DeltaTime > OptStartMgr.MaxOptStartTime) {
2912 0 : DeltaTime = OptStartMgr.MaxOptStartTime;
2913 : }
2914 0 : PreStartTime = FanStartTime - DeltaTime;
2915 0 : if (PreStartTime < 0.0) PreStartTime = -0.1;
2916 0 : PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
2917 0 : if (PreStartTimeTmr < 0.0) {
2918 0 : PreStartTimeTmr += 24.0;
2919 0 : OverNightStartFlag = true;
2920 : } else {
2921 0 : OverNightStartFlag = false;
2922 : }
2923 0 : if (!OverNightStartFlag) {
2924 0 : if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
2925 0 : AvailStatus = NoAction;
2926 0 : CycleOnFlag = false;
2927 0 : OSReportVarFlag = true;
2928 0 : } else if (CycleOnFlag) {
2929 0 : AvailStatus = CycleOn;
2930 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2931 0 : if (state.dataGlobal->CurrentTime > FanStartTime) CycleOnFlag = false;
2932 : // Calculate the current day actual temperature gradient --------------------------
2933 0 : if (!state.dataGlobal->WarmupFlag) {
2934 0 : if (ATGUpdateFlag1) {
2935 0 : ATGUpdateTime1 = state.dataGlobal->CurrentTime;
2936 0 : ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
2937 0 : ATGUpdateFlag1 = false;
2938 : }
2939 0 : if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) >= state.dataZoneCtrls->OccRoomTSetPointHeat(ZoneNum) &&
2940 : ATGUpdateFlag2) {
2941 0 : ATGUpdateTime2 = state.dataGlobal->CurrentTime;
2942 0 : ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
2943 0 : ATGUpdateFlag2 = false;
2944 0 : if (std::abs(ATGUpdateTime2 - ATGUpdateTime1) > 1.e-10) {
2945 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(NumPreDays) =
2946 0 : (ATGUpdateTemp2 - ATGUpdateTemp1) / (ATGUpdateTime2 - ATGUpdateTime1);
2947 : } else {
2948 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(NumPreDays) =
2949 0 : (ATGUpdateTemp2 - ATGUpdateTemp1) * state.dataGlobal->NumOfTimeStepInHour;
2950 : }
2951 : }
2952 : }
2953 : //---------------------------------------------------------------------------------
2954 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime) {
2955 0 : if (OSReportVarFlag) {
2956 0 : NumHoursBeforeOccupancy = DeltaTime;
2957 0 : OSReportVarFlag = false;
2958 : }
2959 0 : AvailStatus = CycleOn;
2960 0 : CycleOnFlag = true;
2961 0 : ATGUpdateFlag1 = true;
2962 0 : ATGUpdateFlag2 = true;
2963 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2964 : } else {
2965 0 : AvailStatus = NoAction;
2966 0 : CycleOnFlag = false;
2967 0 : OSReportVarFlag = true;
2968 : }
2969 : } else {
2970 0 : if (FanStartTime == 0.0 ||
2971 0 : (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
2972 0 : AvailStatus = NoAction;
2973 0 : CycleOnFlag = false;
2974 0 : OSReportVarFlag = true;
2975 0 : } else if (CycleOnFlag) {
2976 0 : AvailStatus = CycleOn;
2977 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
2978 0 : if (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime < PreStartTimeTmr)
2979 0 : CycleOnFlag = false;
2980 : // Calculate the current day actual temperature gradient --------------------------
2981 0 : if (!state.dataGlobal->WarmupFlag) {
2982 0 : if (ATGUpdateFlag1) {
2983 0 : ATGUpdateTime1 = state.dataGlobal->CurrentTime;
2984 0 : ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
2985 0 : ATGUpdateFlag1 = false;
2986 : }
2987 0 : if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) >= state.dataZoneCtrls->OccRoomTSetPointHeat(ZoneNum) &&
2988 : ATGUpdateFlag2) {
2989 0 : ATGUpdateTime2 = state.dataGlobal->CurrentTime;
2990 0 : ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
2991 0 : ATGUpdateFlag2 = false;
2992 0 : if (std::abs(ATGUpdateTime2 - ATGUpdateTime1 + 24.0) > 1.e-10) {
2993 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(NumPreDays) =
2994 0 : (ATGUpdateTemp2 - ATGUpdateTemp1) / (ATGUpdateTime2 - ATGUpdateTime1 + 24.0);
2995 : } else {
2996 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(NumPreDays) =
2997 0 : (ATGUpdateTemp2 - ATGUpdateTemp1) * state.dataGlobal->NumOfTimeStepInHour;
2998 : }
2999 : }
3000 : }
3001 : //---------------------------------------------------------------------------------
3002 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
3003 0 : if (OSReportVarFlag) {
3004 0 : NumHoursBeforeOccupancy = DeltaTime;
3005 0 : OSReportVarFlag = false;
3006 : }
3007 0 : AvailStatus = CycleOn;
3008 0 : CycleOnFlag = true;
3009 0 : ATGUpdateFlag1 = true;
3010 0 : ATGUpdateFlag2 = true;
3011 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
3012 : } else {
3013 0 : AvailStatus = NoAction;
3014 0 : CycleOnFlag = false;
3015 0 : OSReportVarFlag = true;
3016 : }
3017 : }
3018 : } else {
3019 0 : AvailStatus = NoAction;
3020 0 : CycleOnFlag = false;
3021 : }
3022 0 : } else if (state.dataZoneCtrls->OccRoomTSetPointCool(ZoneNum) < 50.0) { // Cooling Mode
3023 0 : TempDiff = TempDiffHi;
3024 0 : DeltaTime = TempDiff / AdaTempGradCool;
3025 0 : if (DeltaTime > OptStartMgr.MaxOptStartTime) {
3026 0 : DeltaTime = OptStartMgr.MaxOptStartTime;
3027 : }
3028 0 : PreStartTime = FanStartTime - DeltaTime;
3029 0 : if (PreStartTime < 0.0) PreStartTime = -0.1;
3030 0 : PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
3031 0 : if (PreStartTimeTmr < 0.0) {
3032 0 : PreStartTimeTmr += 24.0;
3033 0 : OverNightStartFlag = true;
3034 : } else {
3035 0 : OverNightStartFlag = false;
3036 : }
3037 0 : if (!OverNightStartFlag) {
3038 0 : if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
3039 0 : AvailStatus = NoAction;
3040 0 : CycleOnFlag = false;
3041 0 : OSReportVarFlag = true;
3042 0 : } else if (CycleOnFlag) {
3043 0 : if (OSReportVarFlag) {
3044 0 : NumHoursBeforeOccupancy = DeltaTime;
3045 0 : OSReportVarFlag = false;
3046 : }
3047 0 : AvailStatus = CycleOn;
3048 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
3049 0 : if (!state.dataGlobal->WarmupFlag) {
3050 0 : if (ATGUpdateFlag1) {
3051 0 : ATGUpdateTime1 = state.dataGlobal->CurrentTime;
3052 0 : ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
3053 0 : ATGUpdateFlag1 = false;
3054 : }
3055 0 : if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) <= state.dataZoneCtrls->OccRoomTSetPointCool(ZoneNum) &&
3056 : ATGUpdateFlag2) {
3057 0 : ATGUpdateTime2 = state.dataGlobal->CurrentTime;
3058 0 : ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
3059 0 : ATGUpdateFlag2 = false;
3060 0 : if (std::abs(ATGUpdateTime2 - ATGUpdateTime1) > 1.e-10) {
3061 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(NumPreDays) =
3062 0 : (ATGUpdateTemp1 - ATGUpdateTemp2) / (ATGUpdateTime2 - ATGUpdateTime1);
3063 : } else {
3064 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(NumPreDays) =
3065 0 : (ATGUpdateTemp1 - ATGUpdateTemp2) * state.dataGlobal->NumOfTimeStepInHour;
3066 : }
3067 : }
3068 : }
3069 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime) {
3070 0 : AvailStatus = CycleOn;
3071 0 : CycleOnFlag = true;
3072 0 : ATGUpdateFlag1 = true;
3073 0 : ATGUpdateFlag2 = true;
3074 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
3075 : } else {
3076 0 : AvailStatus = NoAction;
3077 0 : CycleOnFlag = false;
3078 0 : OSReportVarFlag = true;
3079 : }
3080 : } else {
3081 0 : if (FanStartTime == 0.0 ||
3082 0 : (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
3083 0 : AvailStatus = NoAction;
3084 0 : CycleOnFlag = false;
3085 0 : OSReportVarFlag = true;
3086 0 : } else if (CycleOnFlag) {
3087 0 : AvailStatus = CycleOn;
3088 0 : if (!state.dataGlobal->WarmupFlag) {
3089 0 : if (ATGUpdateFlag1) {
3090 0 : ATGUpdateTime1 = state.dataGlobal->CurrentTime;
3091 0 : ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
3092 0 : ATGUpdateFlag1 = false;
3093 : }
3094 0 : if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) <= state.dataZoneCtrls->OccRoomTSetPointCool(ZoneNum) &&
3095 : ATGUpdateFlag2) {
3096 0 : ATGUpdateTime2 = state.dataGlobal->CurrentTime;
3097 0 : ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ZoneNum);
3098 0 : ATGUpdateFlag2 = false;
3099 0 : if (std::abs(ATGUpdateTime2 - ATGUpdateTime1 + 24.0) > 1.e-10) {
3100 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(NumPreDays) =
3101 0 : (ATGUpdateTemp1 - ATGUpdateTemp2) / (ATGUpdateTime2 - ATGUpdateTime1 + 24.0);
3102 : } else {
3103 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(NumPreDays) =
3104 0 : (ATGUpdateTemp1 - ATGUpdateTemp2) * state.dataGlobal->NumOfTimeStepInHour;
3105 : }
3106 : }
3107 : }
3108 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
3109 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
3110 0 : if (OSReportVarFlag) {
3111 0 : NumHoursBeforeOccupancy = DeltaTime;
3112 0 : OSReportVarFlag = false;
3113 : }
3114 0 : AvailStatus = CycleOn;
3115 0 : CycleOnFlag = true;
3116 0 : ATGUpdateFlag1 = true;
3117 0 : ATGUpdateFlag2 = true;
3118 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
3119 : } else {
3120 0 : AvailStatus = NoAction;
3121 0 : CycleOnFlag = false;
3122 0 : OSReportVarFlag = true;
3123 : }
3124 : }
3125 : } else { // Not heating nor cooling mode
3126 0 : AvailStatus = NoAction;
3127 0 : CycleOnFlag = false;
3128 : }
3129 5042 : } else if (OptStartMgr.optimumStartControlType == OptimumStartControlType::MaximumOfZoneList) {
3130 :
3131 5042 : NumOfZonesInList = OptStartMgr.NumOfZones;
3132 5042 : ATGWCZoneNumHi = OptStartMgr.ZonePtrs(1);
3133 5042 : ATGWCZoneNumLo = OptStartMgr.ZonePtrs(1);
3134 10084 : if ((!allocated(state.dataHeatBalFanSys->TempTstatAir)) || (!allocated(state.dataHeatBalFanSys->ZoneThermostatSetPointLo)) ||
3135 5042 : (!allocated(state.dataHeatBalFanSys->ZoneThermostatSetPointHi))) {
3136 0 : TempDiff = 0.0;
3137 : } else {
3138 5042 : if (!CycleOnFlag) {
3139 3572 : if (allocated(state.dataZoneCtrls->OccRoomTSetPointHeat) && allocated(state.dataZoneCtrls->OccRoomTSetPointCool)) {
3140 3572 : TempDiffHi = 0.0;
3141 3572 : TempDiffLo = 0.0;
3142 3572 : ATGWCZoneNumHi = OptStartMgr.ZonePtrs(1);
3143 3572 : ATGWCZoneNumLo = OptStartMgr.ZonePtrs(1);
3144 17860 : for (ZoneNum = 1; ZoneNum <= NumOfZonesInList; ++ZoneNum) {
3145 28576 : TempDiff = state.dataHeatBalFanSys->TempTstatAir(OptStartMgr.ZonePtrs(ZoneNum)) -
3146 14288 : state.dataZoneCtrls->OccRoomTSetPointCool(OptStartMgr.ZonePtrs(ZoneNum));
3147 14288 : TempDiffHi = max(TempDiffHi, TempDiff);
3148 : // Store the worse case zone number for actual temperature gradient calculation
3149 14288 : if (TempDiff == TempDiffHi) {
3150 982 : ATGWCZoneNumHi = OptStartMgr.ZonePtrs(ZoneNum);
3151 : }
3152 28576 : TempDiff = state.dataHeatBalFanSys->TempTstatAir(OptStartMgr.ZonePtrs(ZoneNum)) -
3153 14288 : state.dataZoneCtrls->OccRoomTSetPointHeat(OptStartMgr.ZonePtrs(ZoneNum));
3154 14288 : TempDiffLo = min(TempDiffLo, TempDiff);
3155 14288 : if (TempDiff == TempDiffLo) {
3156 4162 : ATGWCZoneNumLo = OptStartMgr.ZonePtrs(ZoneNum);
3157 : }
3158 : }
3159 : } else {
3160 0 : TempDiffHi = 0.0;
3161 0 : TempDiffLo = 0.0;
3162 : }
3163 : }
3164 : }
3165 : // Store adaptive temperature gradients for previous days and calculate the adaptive temp gradients
3166 : //-----------------------------------------------------------------------------
3167 5042 : if (state.dataGlobal->WarmupFlag) {
3168 4398 : AdaTempGradHeat = OptStartMgr.InitTGradHeat;
3169 4398 : AdaTempGradCool = OptStartMgr.InitTGradCool;
3170 644 : } else if (state.dataGlobal->DayOfSim == 1 && state.dataGlobal->BeginDayFlag) {
3171 7 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat = OptStartMgr.InitTGradHeat;
3172 7 : AdaTempGradHeat = OptStartMgr.InitTGradHeat;
3173 7 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool = OptStartMgr.InitTGradCool;
3174 7 : AdaTempGradCool = OptStartMgr.InitTGradCool;
3175 : } else {
3176 637 : if (state.dataGlobal->BeginDayFlag && FirstTimeATGFlag) {
3177 0 : FirstTimeATGFlag = false;
3178 0 : AdaTempGradHeat += state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(NumPreDays) / NumPreDays -
3179 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(1) / NumPreDays;
3180 0 : AdaTempGradCool += state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(NumPreDays) / NumPreDays -
3181 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(1) / NumPreDays;
3182 0 : if (FanStartTime > 0) {
3183 0 : for (ATGCounter = 1; ATGCounter <= NumPreDays - 1; ++ATGCounter) {
3184 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(ATGCounter) =
3185 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(ATGCounter + 1);
3186 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(ATGCounter) =
3187 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(ATGCounter + 1);
3188 : }
3189 : }
3190 : }
3191 : }
3192 :
3193 5042 : if (state.dataGlobal->CurrentTime >= 1.0) FirstTimeATGFlag = true;
3194 : //------------------------------------------------------------------------------
3195 :
3196 5042 : if ((TempDiffHi < 0.0 && TempDiffLo < 0.0) || (std::abs(TempDiffLo) > std::abs(TempDiffHi) && TempDiffLo < 0.0)) { // Heating Mode
3197 3254 : TempDiff = TempDiffLo;
3198 3254 : TempDiff = std::abs(TempDiff);
3199 3254 : DeltaTime = TempDiff / AdaTempGradHeat;
3200 3254 : if (DeltaTime > OptStartMgr.MaxOptStartTime) {
3201 0 : DeltaTime = OptStartMgr.MaxOptStartTime;
3202 : }
3203 3254 : PreStartTime = FanStartTime - DeltaTime;
3204 3254 : if (PreStartTime < 0.0) PreStartTime = -0.1;
3205 3254 : PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
3206 3254 : if (PreStartTimeTmr < 0.0) {
3207 0 : PreStartTimeTmr += 24.0;
3208 0 : OverNightStartFlag = true;
3209 : } else {
3210 3254 : OverNightStartFlag = false;
3211 : }
3212 3254 : if (!OverNightStartFlag) {
3213 3254 : if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
3214 1940 : OSReportVarFlag = true;
3215 1940 : AvailStatus = NoAction;
3216 1940 : CycleOnFlag = false;
3217 1314 : } else if (CycleOnFlag) {
3218 1002 : AvailStatus = CycleOn;
3219 1002 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
3220 1002 : if (state.dataGlobal->CurrentTime > FanStartTime) CycleOnFlag = false;
3221 : // Calculate the current day actual temperature gradient --------------------------
3222 1002 : if (!state.dataGlobal->WarmupFlag) {
3223 128 : if (ATGUpdateFlag1) {
3224 1 : ATGUpdateTime1 = state.dataGlobal->CurrentTime;
3225 1 : ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumLo);
3226 1 : ATGUpdateFlag1 = false;
3227 : }
3228 256 : if (state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumLo) >=
3229 128 : state.dataZoneCtrls->OccRoomTSetPointHeat(ATGWCZoneNumLo) &&
3230 : ATGUpdateFlag2) {
3231 0 : ATGUpdateTime2 = state.dataGlobal->CurrentTime;
3232 0 : ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumLo);
3233 0 : ATGUpdateFlag2 = false;
3234 0 : if (std::abs(ATGUpdateTime2 - ATGUpdateTime1) > 1.e-10) {
3235 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(NumPreDays) =
3236 0 : (ATGUpdateTemp2 - ATGUpdateTemp1) / (ATGUpdateTime2 - ATGUpdateTime1);
3237 : } else {
3238 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(NumPreDays) =
3239 0 : (ATGUpdateTemp2 - ATGUpdateTemp1) * state.dataGlobal->NumOfTimeStepInHour;
3240 : }
3241 : }
3242 : }
3243 : //---------------------------------------------------------------------------------
3244 312 : } else if (PreStartTime < state.dataGlobal->CurrentTime) {
3245 9 : if (OSReportVarFlag) {
3246 9 : NumHoursBeforeOccupancy = DeltaTime;
3247 9 : OSReportVarFlag = false;
3248 : }
3249 9 : AvailStatus = CycleOn;
3250 9 : CycleOnFlag = true;
3251 9 : ATGUpdateFlag1 = true;
3252 9 : ATGUpdateFlag2 = true;
3253 9 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
3254 : } else {
3255 303 : AvailStatus = NoAction;
3256 303 : CycleOnFlag = false;
3257 303 : OSReportVarFlag = true;
3258 : }
3259 : } else {
3260 0 : if (FanStartTime == 0.0 ||
3261 0 : (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
3262 0 : AvailStatus = NoAction;
3263 0 : CycleOnFlag = false;
3264 0 : OSReportVarFlag = true;
3265 0 : } else if (CycleOnFlag) {
3266 0 : AvailStatus = CycleOn;
3267 : // Calculate the current day actual temperature gradient --------------------------
3268 0 : if (!state.dataGlobal->WarmupFlag) {
3269 0 : if (ATGUpdateFlag1) {
3270 0 : ATGUpdateTime1 = state.dataGlobal->CurrentTime;
3271 0 : ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumLo);
3272 0 : ATGUpdateFlag1 = false;
3273 : }
3274 0 : if (state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumLo) >=
3275 0 : state.dataZoneCtrls->OccRoomTSetPointHeat(ATGWCZoneNumLo) &&
3276 : ATGUpdateFlag2) {
3277 0 : ATGUpdateTime2 = state.dataGlobal->CurrentTime;
3278 0 : ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumLo);
3279 0 : ATGUpdateFlag2 = false;
3280 0 : if (std::abs(ATGUpdateTime2 - ATGUpdateTime1 + 24.0) > 1.e-10) {
3281 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(NumPreDays) =
3282 0 : (ATGUpdateTemp2 - ATGUpdateTemp1) / (ATGUpdateTime2 - ATGUpdateTime1 + 24.0);
3283 : } else {
3284 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat(NumPreDays) =
3285 0 : (ATGUpdateTemp2 - ATGUpdateTemp1) * state.dataGlobal->NumOfTimeStepInHour;
3286 : }
3287 : }
3288 : }
3289 : //---------------------------------------------------------------------------------
3290 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
3291 0 : if (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime < PreStartTimeTmr)
3292 0 : CycleOnFlag = false;
3293 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
3294 0 : if (OSReportVarFlag) {
3295 0 : NumHoursBeforeOccupancy = DeltaTime;
3296 0 : OSReportVarFlag = false;
3297 : }
3298 0 : AvailStatus = CycleOn;
3299 0 : CycleOnFlag = true;
3300 0 : ATGUpdateFlag1 = true;
3301 0 : ATGUpdateFlag2 = true;
3302 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
3303 : } else {
3304 0 : AvailStatus = NoAction;
3305 0 : CycleOnFlag = false;
3306 0 : OSReportVarFlag = true;
3307 : }
3308 : }
3309 1788 : } else if (TempDiffHi <= 0.0 && TempDiffLo >= 0.0) { // not heating and not cooling
3310 804 : AvailStatus = NoAction;
3311 804 : CycleOnFlag = false;
3312 804 : TempDiffHi = 0.0;
3313 804 : TempDiffLo = 0.0;
3314 984 : } else if (TempDiffHi < 30.0) { // Cooling Mode
3315 984 : TempDiff = TempDiffHi;
3316 984 : DeltaTime = TempDiff / AdaTempGradCool;
3317 984 : if (DeltaTime > OptStartMgr.MaxOptStartTime) {
3318 0 : DeltaTime = OptStartMgr.MaxOptStartTime;
3319 : }
3320 984 : PreStartTime = FanStartTime - DeltaTime;
3321 984 : if (PreStartTime < 0) PreStartTime = -0.1;
3322 984 : PreStartTimeTmr = FanStartTimeTmr - DeltaTime;
3323 984 : if (PreStartTimeTmr < 0) {
3324 0 : PreStartTimeTmr += 24.0;
3325 0 : OverNightStartFlag = true;
3326 : } else {
3327 984 : OverNightStartFlag = false;
3328 : }
3329 984 : if (!OverNightStartFlag) {
3330 984 : if (FanStartTime == 0.0 || state.dataGlobal->CurrentTime > FanStartTime) {
3331 180 : AvailStatus = NoAction;
3332 180 : CycleOnFlag = false;
3333 180 : OSReportVarFlag = true;
3334 804 : } else if (CycleOnFlag) {
3335 452 : AvailStatus = CycleOn;
3336 : // Calculate the current day actual temperature gradient --------------------------
3337 452 : if (!state.dataGlobal->WarmupFlag) {
3338 78 : if (ATGUpdateFlag1) {
3339 1 : ATGUpdateTime1 = state.dataGlobal->CurrentTime;
3340 1 : ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumHi);
3341 1 : ATGUpdateFlag1 = false;
3342 : }
3343 156 : if (state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumHi) <=
3344 78 : state.dataZoneCtrls->OccRoomTSetPointCool(ATGWCZoneNumHi) &&
3345 : ATGUpdateFlag2) {
3346 1 : ATGUpdateTime2 = state.dataGlobal->CurrentTime;
3347 1 : ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumHi);
3348 1 : ATGUpdateFlag2 = false;
3349 1 : if (std::abs(ATGUpdateTime2 - ATGUpdateTime1) > 1.e-10) {
3350 1 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(NumPreDays) =
3351 1 : (ATGUpdateTemp1 - ATGUpdateTemp2) / (ATGUpdateTime2 - ATGUpdateTime1);
3352 : } else {
3353 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(NumPreDays) =
3354 0 : (ATGUpdateTemp1 - ATGUpdateTemp2) * state.dataGlobal->NumOfTimeStepInHour;
3355 : }
3356 : }
3357 : }
3358 : //---------------------------------------------------------------------------------
3359 452 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
3360 352 : } else if (PreStartTime < state.dataGlobal->CurrentTime) {
3361 7 : if (OSReportVarFlag) {
3362 7 : NumHoursBeforeOccupancy = DeltaTime;
3363 7 : OSReportVarFlag = false;
3364 : }
3365 7 : AvailStatus = CycleOn;
3366 7 : CycleOnFlag = true;
3367 7 : ATGUpdateFlag1 = true;
3368 7 : ATGUpdateFlag2 = true;
3369 7 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
3370 : } else {
3371 345 : AvailStatus = NoAction;
3372 345 : CycleOnFlag = false;
3373 345 : OSReportVarFlag = true;
3374 : }
3375 : } else {
3376 0 : if (FanStartTime == 0.0 ||
3377 0 : (state.dataGlobal->CurrentTime > FanStartTime && state.dataGlobal->CurrentTime <= PreStartTimeTmr)) {
3378 0 : AvailStatus = NoAction;
3379 0 : CycleOnFlag = false;
3380 0 : OSReportVarFlag = true;
3381 0 : } else if (CycleOnFlag) {
3382 0 : AvailStatus = CycleOn;
3383 : // Calculate the current day actual temperature gradient --------------------------
3384 0 : if (!state.dataGlobal->WarmupFlag) {
3385 0 : if (ATGUpdateFlag1) {
3386 0 : ATGUpdateTime1 = state.dataGlobal->CurrentTime;
3387 0 : ATGUpdateTemp1 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumHi);
3388 0 : ATGUpdateFlag1 = false;
3389 : }
3390 0 : if (state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumHi) <=
3391 0 : state.dataZoneCtrls->OccRoomTSetPointCool(ATGWCZoneNumHi) &&
3392 : ATGUpdateFlag2) {
3393 0 : ATGUpdateTime2 = state.dataGlobal->CurrentTime;
3394 0 : ATGUpdateTemp2 = state.dataHeatBalFanSys->TempTstatAir(ATGWCZoneNumHi);
3395 0 : ATGUpdateFlag2 = false;
3396 0 : if (std::abs(ATGUpdateTime2 - ATGUpdateTime1 + 24.0) > 1.e-10) {
3397 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(NumPreDays) =
3398 0 : (ATGUpdateTemp1 - ATGUpdateTemp2) / (ATGUpdateTime2 - ATGUpdateTime1 + 24.0);
3399 : } else {
3400 0 : state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool(NumPreDays) =
3401 0 : (ATGUpdateTemp1 - ATGUpdateTemp2) * state.dataGlobal->NumOfTimeStepInHour;
3402 : }
3403 : }
3404 : }
3405 : //---------------------------------------------------------------------------------
3406 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
3407 0 : } else if (PreStartTime < state.dataGlobal->CurrentTime || PreStartTimeTmr < state.dataGlobal->CurrentTime) {
3408 0 : if (OSReportVarFlag) {
3409 0 : NumHoursBeforeOccupancy = DeltaTime;
3410 0 : OSReportVarFlag = false;
3411 : }
3412 0 : AvailStatus = CycleOn;
3413 0 : CycleOnFlag = true;
3414 0 : ATGUpdateFlag2 = true;
3415 0 : ATGUpdateFlag1 = true;
3416 0 : OptStartMgr.SetOptStartFlag(state, PriAirSysNum);
3417 : } else {
3418 0 : AvailStatus = NoAction;
3419 0 : CycleOnFlag = false;
3420 0 : OSReportVarFlag = true;
3421 : }
3422 : }
3423 : } else {
3424 0 : AvailStatus = NoAction;
3425 0 : CycleOnFlag = false;
3426 : }
3427 : } else {
3428 0 : AvailStatus = NoAction;
3429 : }
3430 5042 : } break;
3431 0 : case ControlAlgorithm::AdaptiveASHRAE: {
3432 0 : AvailStatus = NoAction;
3433 0 : } break;
3434 0 : default:
3435 0 : break;
3436 : }
3437 : }
3438 :
3439 5054 : OptStartMgr.AvailStatus = AvailStatus;
3440 5054 : OptStartMgr.NumHoursBeforeOccupancy = NumHoursBeforeOccupancy;
3441 5054 : OptStartMgr.TempDiffLo = TempDiffLo;
3442 5054 : OptStartMgr.TempDiffHi = TempDiffHi;
3443 5054 : OptStartMgr.ATGWCZoneNumLo = ATGWCZoneNumLo;
3444 5054 : OptStartMgr.ATGWCZoneNumHi = ATGWCZoneNumHi;
3445 5054 : OptStartMgr.CycleOnFlag = CycleOnFlag;
3446 5054 : OptStartMgr.ATGUpdateFlag1 = ATGUpdateFlag1;
3447 5054 : OptStartMgr.ATGUpdateFlag2 = ATGUpdateFlag2;
3448 5054 : OptStartMgr.FirstTimeATGFlag = FirstTimeATGFlag;
3449 5054 : OptStartMgr.OverNightStartFlag = OverNightStartFlag;
3450 5054 : OptStartMgr.OSReportVarFlag = OSReportVarFlag;
3451 5054 : if (OptStartMgr.controlAlgorithm == ControlAlgorithm::AdaptiveTemperatureGradient) {
3452 5054 : OptStartMgr.AdaTempGradTrdHeat = state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdHeat;
3453 5054 : OptStartMgr.AdaTempGradTrdCool = state.dataSystemAvailabilityManager->OptStart_AdaTempGradTrdCool;
3454 5054 : OptStartMgr.AdaTempGradHeat = AdaTempGradHeat;
3455 5054 : OptStartMgr.AdaTempGradCool = AdaTempGradCool;
3456 5054 : OptStartMgr.ATGUpdateTime1 = ATGUpdateTime1;
3457 5054 : OptStartMgr.ATGUpdateTime2 = ATGUpdateTime2;
3458 5054 : OptStartMgr.ATGUpdateTemp1 = ATGUpdateTemp1;
3459 5054 : OptStartMgr.ATGUpdateTemp2 = ATGUpdateTemp2;
3460 : }
3461 : }
3462 :
3463 1470 : void SysAvailManagerOptimumStart::SetOptStartFlag(EnergyPlusData &state, int const AirLoopNum)
3464 : {
3465 : // Set the OptStartFlag true for all zones on the air loop
3466 1470 : auto const &thisAirToZoneNodeInfo(state.dataAirLoop->AirToZoneNodeInfo(AirLoopNum));
3467 8820 : for (int counter = 1; counter <= thisAirToZoneNodeInfo.NumZonesCooled; ++counter) {
3468 7350 : state.dataHVACGlobal->OptStartData.OptStartFlag(thisAirToZoneNodeInfo.CoolCtrlZoneNums(counter)) = true;
3469 : }
3470 1470 : for (int counter = 1; counter <= thisAirToZoneNodeInfo.NumZonesHeated; ++counter) {
3471 0 : state.dataHVACGlobal->OptStartData.OptStartFlag(thisAirToZoneNodeInfo.HeatCtrlZoneNums(counter)) = true;
3472 : }
3473 1470 : }
3474 1821 : void CalcNVentSysAvailMgr(EnergyPlusData &state,
3475 : int const SysAvailNum, // number of the current scheduled system availability manager
3476 : int const PriAirSysNum, // number of the primary air system affected by this Avail. Manager
3477 : int &AvailStatus, // System status indicator
3478 : Optional_int_const ZoneEquipType // Type of zone equipment component
3479 : )
3480 : {
3481 :
3482 : // SUBROUTINE INFORMATION:
3483 : // AUTHOR Fred Buhl
3484 : // DATE WRITTEN December 2004
3485 : // MODIFIED March 2011, Chandan Sharma - FSEC: Allowed night ventilation
3486 : // availability manager to work for zone component
3487 : // RE-ENGINEERED na
3488 :
3489 : // PURPOSE OF THIS SUBROUTINE:
3490 : // Set AvailStatus indicator for a primary air loop and ZoneHVAC component and sets a specified flow
3491 : // rate fraction for the air loop for use during night ventilation.
3492 :
3493 : // METHODOLOGY EMPLOYED:
3494 : // Looks at outside and indoor conditions to determine if night ventilation
3495 : // is beneficial. If it is and it is scheduled on the AvailStatus is set to cycle
3496 : // on and the loop flow rate fractionis set to the specified night ventilation
3497 : // value.
3498 :
3499 : using namespace DataAirLoop;
3500 :
3501 : int ZoneInSysNum;
3502 : bool TempCheck; // TRUE if one zone's temperature is above the value of the vent temp sched
3503 : bool DelTCheck; // TRUE if the control zone temperature - outside temperature > VentDelT
3504 : bool LowLimCheck; // TRUE if one zones's air temperature is below this value
3505 : Real64 VentTemp; // value of the ventilation temperature schedule
3506 :
3507 1821 : TempCheck = false;
3508 1821 : DelTCheck = false;
3509 1821 : LowLimCheck = false;
3510 : // check if night venting allowed: not allowed if avail sched is off or fan sched is on
3511 : // CR 7913 changed to allow during warmup
3512 1821 : auto &nightVentMgr = state.dataSystemAvailabilityManager->NightVentData(SysAvailNum);
3513 1821 : if ((GetCurrentScheduleValue(state, nightVentMgr.SchedPtr) <= 0.0) || (GetCurrentScheduleValue(state, nightVentMgr.FanSchedPtr) > 0.0)) {
3514 1821 : AvailStatus = NoAction;
3515 : } else {
3516 :
3517 0 : VentTemp = GetCurrentScheduleValue(state, nightVentMgr.VentTempSchedPtr);
3518 0 : int ControlZoneNum = nightVentMgr.ZoneNum;
3519 :
3520 0 : if (present(ZoneEquipType)) {
3521 : // if the room temperature is greater than the vent temp sched value, set the vent temp check to TRUE
3522 0 : if (state.dataHeatBalFanSys->TempTstatAir(ControlZoneNum) > VentTemp) {
3523 0 : TempCheck = true;
3524 : }
3525 : // if the room temperature is less than the low limit set the low limit check to TRUE
3526 0 : if (state.dataHeatBalFanSys->TempTstatAir(ControlZoneNum) < nightVentMgr.VentTempLowLim) {
3527 0 : LowLimCheck = true;
3528 : }
3529 : } else {
3530 0 : for (ZoneInSysNum = 1; ZoneInSysNum <= state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).NumZonesCooled;
3531 : ++ZoneInSysNum) { // loop over zones in system
3532 :
3533 0 : int ZoneNum = state.dataAirLoop->AirToZoneNodeInfo(PriAirSysNum).CoolCtrlZoneNums(ZoneInSysNum);
3534 : // if the room temperature is greater than the vent temp sched value, set the vent temp check to TRUE
3535 0 : if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) > VentTemp) {
3536 0 : TempCheck = true;
3537 : }
3538 : // if the room temperature is less than the low limit set the low limit check to TRUE
3539 0 : if (state.dataHeatBalFanSys->TempTstatAir(ZoneNum) < nightVentMgr.VentTempLowLim) {
3540 0 : LowLimCheck = true;
3541 : }
3542 : }
3543 : }
3544 : // If the difference between the control zone temperature and the outside temperature is greater than
3545 : // the specified night venting delta T then set the delta T check to TRUE
3546 0 : if ((state.dataHeatBalFanSys->TempTstatAir(ControlZoneNum) - state.dataEnvrn->OutDryBulbTemp) > nightVentMgr.VentDelT) {
3547 0 : DelTCheck = true;
3548 : }
3549 : // If the limit requirements are met turn on night ventilation
3550 0 : if (TempCheck && DelTCheck && !LowLimCheck) {
3551 0 : AvailStatus = CycleOn;
3552 : } else {
3553 0 : AvailStatus = NoAction;
3554 : }
3555 : }
3556 :
3557 1821 : if (!present(ZoneEquipType)) {
3558 1821 : if (AvailStatus == CycleOn) {
3559 0 : state.dataAirLoop->AirLoopControlInfo(PriAirSysNum).LoopFlowRateSet = true;
3560 0 : state.dataAirLoop->AirLoopControlInfo(PriAirSysNum).NightVent = true;
3561 0 : state.dataAirLoop->AirLoopFlow(PriAirSysNum).ReqSupplyFrac = nightVentMgr.VentFlowFrac;
3562 : }
3563 : }
3564 :
3565 1821 : nightVentMgr.AvailStatus = AvailStatus;
3566 1821 : }
3567 :
3568 3670 : void CalcDiffTSysAvailMgr(EnergyPlusData &state,
3569 : int const SysAvailNum, // Number of the current scheduled system availability manager
3570 : int const PreviousStatus, // System status for the previous timestep
3571 : int &AvailStatus // System status indicator
3572 : )
3573 : {
3574 :
3575 : // SUBROUTINE INFORMATION:
3576 : // AUTHOR Peter Graham Ellis
3577 : // DATE WRITTEN February 2004
3578 : // MODIFIED na
3579 : // RE-ENGINEERED na
3580 :
3581 : // PURPOSE OF THIS SUBROUTINE:
3582 : // Set AvailStatus indicator for a plant loop, primary air loop or ZoneHVAC component.
3583 :
3584 : // METHODOLOGY EMPLOYED:
3585 :
3586 : Real64 DeltaTemp;
3587 :
3588 3670 : auto &diffThermoMgr = state.dataSystemAvailabilityManager->DiffThermoData(SysAvailNum);
3589 3670 : DeltaTemp = state.dataLoopNodes->Node(diffThermoMgr.HotNode).Temp - state.dataLoopNodes->Node(diffThermoMgr.ColdNode).Temp;
3590 :
3591 3670 : if (DeltaTemp >= diffThermoMgr.TempDiffOn) {
3592 1150 : AvailStatus = CycleOn;
3593 2520 : } else if (DeltaTemp <= diffThermoMgr.TempDiffOff) {
3594 1748 : AvailStatus = ForceOff;
3595 : } else {
3596 :
3597 772 : if (PreviousStatus == NoAction) {
3598 0 : AvailStatus = ForceOff;
3599 : } else {
3600 772 : AvailStatus = PreviousStatus; // No change, but not "NoAction"; it should always be on or off.
3601 : }
3602 : }
3603 :
3604 3670 : diffThermoMgr.AvailStatus = AvailStatus;
3605 3670 : }
3606 :
3607 3769 : void CalcHiTurnOffSysAvailMgr(EnergyPlusData &state,
3608 : int const SysAvailNum, // Number of the current scheduled system availability manager
3609 : int &AvailStatus // System status indicator
3610 : )
3611 : {
3612 :
3613 : // SUBROUTINE INFORMATION:
3614 : // AUTHOR Peter Graham Ellis
3615 : // DATE WRITTEN February 2004
3616 : // MODIFIED na
3617 : // RE-ENGINEERED na
3618 :
3619 : // PURPOSE OF THIS SUBROUTINE:
3620 : // Set AvailStatus indicator for a plant loop, primary air loop or ZoneHVAC component.
3621 :
3622 7538 : if (state.dataLoopNodes->Node(state.dataSystemAvailabilityManager->HiTurnOffData(SysAvailNum).Node).Temp >=
3623 3769 : state.dataSystemAvailabilityManager->HiTurnOffData(SysAvailNum).Temp) {
3624 0 : AvailStatus = ForceOff;
3625 : } else {
3626 3769 : AvailStatus = NoAction;
3627 : }
3628 :
3629 3769 : state.dataSystemAvailabilityManager->HiTurnOffData(SysAvailNum).AvailStatus = AvailStatus;
3630 3769 : }
3631 :
3632 11920 : void CalcHiTurnOnSysAvailMgr(EnergyPlusData &state,
3633 : int const SysAvailNum, // Number of the current scheduled system availability manager
3634 : int &AvailStatus // System status indicator
3635 : )
3636 : {
3637 :
3638 : // SUBROUTINE INFORMATION:
3639 : // AUTHOR Peter Graham Ellis
3640 : // DATE WRITTEN February 2004
3641 : // MODIFIED na
3642 : // RE-ENGINEERED na
3643 :
3644 : // PURPOSE OF THIS SUBROUTINE:
3645 : // Set AvailStatus indicator for a plant loop, primary air loop or ZoneHVAC component.
3646 :
3647 23840 : if (state.dataLoopNodes->Node(state.dataSystemAvailabilityManager->HiTurnOnData(SysAvailNum).Node).Temp >=
3648 11920 : state.dataSystemAvailabilityManager->HiTurnOnData(SysAvailNum).Temp) {
3649 1479 : AvailStatus = CycleOn;
3650 : } else {
3651 10441 : AvailStatus = NoAction;
3652 : }
3653 :
3654 11920 : state.dataSystemAvailabilityManager->HiTurnOnData(SysAvailNum).AvailStatus = AvailStatus;
3655 11920 : }
3656 :
3657 221017 : void CalcLoTurnOffSysAvailMgr(EnergyPlusData &state,
3658 : int const SysAvailNum, // Number of the current scheduled system availability manager
3659 : int &AvailStatus // System status indicator
3660 : )
3661 : {
3662 :
3663 : // SUBROUTINE INFORMATION:
3664 : // AUTHOR Peter Graham Ellis
3665 : // DATE WRITTEN February 2004
3666 : // MODIFIED na
3667 : // RE-ENGINEERED na
3668 :
3669 : // PURPOSE OF THIS SUBROUTINE:
3670 : // Set AvailStatus indicator for a plant loop, primary air loop or ZoneHVAC component.
3671 :
3672 : // If applicability schedule is off, then availability manager is inactive, return no action
3673 221017 : auto &loTurnOffMgr = state.dataSystemAvailabilityManager->LoTurnOffData(SysAvailNum);
3674 221017 : if (loTurnOffMgr.SchedPtr > 0) {
3675 179658 : if (GetCurrentScheduleValue(state, loTurnOffMgr.SchedPtr) <= 0.0) {
3676 2727 : AvailStatus = NoAction;
3677 2727 : loTurnOffMgr.AvailStatus = AvailStatus;
3678 2727 : return;
3679 : }
3680 : }
3681 :
3682 : // Availability manager is active, check temperature limit
3683 218290 : if (state.dataLoopNodes->Node(loTurnOffMgr.Node).Temp <= loTurnOffMgr.Temp) {
3684 59459 : AvailStatus = ForceOff;
3685 : } else {
3686 158831 : AvailStatus = NoAction;
3687 : }
3688 :
3689 218290 : loTurnOffMgr.AvailStatus = AvailStatus;
3690 : }
3691 :
3692 3769 : void CalcLoTurnOnSysAvailMgr(EnergyPlusData &state,
3693 : int const SysAvailNum, // Number of the current scheduled system availability manager
3694 : int &AvailStatus // System status indicator
3695 : )
3696 : {
3697 :
3698 : // SUBROUTINE INFORMATION:
3699 : // AUTHOR Peter Graham Ellis
3700 : // DATE WRITTEN February 2004
3701 : // MODIFIED na
3702 : // RE-ENGINEERED na
3703 :
3704 : // PURPOSE OF THIS SUBROUTINE:
3705 : // Set AvailStatus indicator for a plant loop, primary air loop or ZoneHVAC component.
3706 :
3707 7538 : if (state.dataLoopNodes->Node(state.dataSystemAvailabilityManager->LoTurnOnData(SysAvailNum).Node).Temp <=
3708 3769 : state.dataSystemAvailabilityManager->LoTurnOnData(SysAvailNum).Temp) {
3709 99 : AvailStatus = CycleOn;
3710 : } else {
3711 3670 : AvailStatus = NoAction;
3712 : }
3713 :
3714 3769 : state.dataSystemAvailabilityManager->LoTurnOnData(SysAvailNum).AvailStatus = AvailStatus;
3715 3769 : }
3716 :
3717 3623760 : void ManageHybridVentilation(EnergyPlusData &state)
3718 : {
3719 : // SUBROUTINE INFORMATION:
3720 : // AUTHOR Lixing Gu
3721 : // DATE WRITTEN March 2007
3722 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
3723 : // RE-ENGINEERED na
3724 :
3725 : // PURPOSE OF THIS SUBROUTINE:
3726 : // Manage the simulation of the Hybrid Ventilation Control System Availability Managers
3727 :
3728 : using namespace DataLoopNode;
3729 : using namespace DataAirLoop;
3730 :
3731 : int PriAirSysNum; // Primary Air System index
3732 : int SysAvailNum;
3733 :
3734 3623760 : if (state.dataSystemAvailabilityManager->GetHybridInputFlag) {
3735 770 : GetHybridVentilationInputs(state);
3736 770 : state.dataSystemAvailabilityManager->GetHybridInputFlag = false;
3737 : }
3738 :
3739 3623760 : if (state.dataHVACGlobal->NumHybridVentSysAvailMgrs == 0) return;
3740 :
3741 42093 : InitHybridVentSysAvailMgr(state);
3742 :
3743 91565 : for (SysAvailNum = 1; SysAvailNum <= state.dataHVACGlobal->NumHybridVentSysAvailMgrs; ++SysAvailNum) {
3744 49472 : if (state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).HybridVentMgrConnectedToAirLoop) {
3745 65988 : for (PriAirSysNum = 1; PriAirSysNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++PriAirSysNum) {
3746 29532 : if (state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).AirLoopNum == PriAirSysNum)
3747 29532 : CalcHybridVentSysAvailMgr(state, SysAvailNum, PriAirSysNum);
3748 : }
3749 : } else {
3750 : // Hybrid ventilation manager is applied to zone component
3751 13016 : if (state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).SimHybridVentSysAvailMgr) {
3752 7338 : CalcHybridVentSysAvailMgr(state, SysAvailNum);
3753 : }
3754 : }
3755 : }
3756 : }
3757 :
3758 771 : void GetHybridVentilationInputs(EnergyPlusData &state)
3759 : {
3760 :
3761 : // SUBROUTINE INFORMATION:
3762 : // AUTHOR Lixing Gu
3763 : // DATE WRITTEN March 2007
3764 : // MODIFIED L. GU, 6/23/08, Added more controls, including simple airflow objects
3765 : // RE-ENGINEERED na
3766 :
3767 : // PURPOSE OF THIS SUBROUTINE:
3768 : // Obtains input data for Hybrid Ventilation Control System Availability Managers and stores it in
3769 : // appropriate data structures.
3770 :
3771 : // METHODOLOGY EMPLOYED:
3772 : // Uses InputProcessor "Get" routines to obtain data.
3773 :
3774 : // Using/Aliasing
3775 : using NodeInputManager::GetOnlySingleNode;
3776 : using NodeInputManager::MarkNode;
3777 : using namespace DataLoopNode;
3778 :
3779 : using Curve::CurveValue;
3780 : using Curve::GetCurveIndex;
3781 : using Curve::GetCurveMinMaxValues;
3782 :
3783 : // SUBROUTINE PARAMETER DEFINITIONS:
3784 : static constexpr std::string_view RoutineName("GetHybridVentilationInputs: "); // include trailing blank
3785 :
3786 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3787 : int NumAlphas; // Number of Alphas for each GetObjectItem call
3788 : int NumNumbers; // Number of Numbers for each GetObjectItem call
3789 : int IOStatus; // Used in GetObjectItem
3790 771 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
3791 : int SysAvailNum; // DO loop index for all System Availability Managers
3792 : Real64 SchedMin; // Minimum value specified in a schedule
3793 : Real64 SchedMax; // Maximum value specified in a schedule
3794 : Real64 CurveMin; // Minimum value specified in a curve
3795 : Real64 CurveMax; // Maximum value specified in a curve
3796 : Real64 CurveVal; // Curve value
3797 :
3798 771 : auto &NumHybridVentSysAvailMgrs = state.dataHVACGlobal->NumHybridVentSysAvailMgrs;
3799 771 : auto &HybridVentSysAvailAirLoopNum = state.dataHVACGlobal->HybridVentSysAvailAirLoopNum;
3800 771 : auto &HybridVentSysAvailActualZoneNum = state.dataHVACGlobal->HybridVentSysAvailActualZoneNum;
3801 771 : auto &HybridVentSysAvailVentCtrl = state.dataHVACGlobal->HybridVentSysAvailVentCtrl;
3802 771 : auto &HybridVentSysAvailANCtrlStatus = state.dataHVACGlobal->HybridVentSysAvailANCtrlStatus;
3803 771 : auto &HybridVentSysAvailMaster = state.dataHVACGlobal->HybridVentSysAvailMaster;
3804 771 : auto &HybridVentSysAvailWindModifier = state.dataHVACGlobal->HybridVentSysAvailWindModifier;
3805 :
3806 : // Get the number of occurrences of each type of System Availability Manager
3807 771 : std::string_view cCurrentModuleObject = SystemAvailabilityTypeNamesCC[static_cast<int>(DataPlant::SystemAvailabilityType::HybridVent)];
3808 771 : NumHybridVentSysAvailMgrs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
3809 :
3810 771 : if (NumHybridVentSysAvailMgrs == 0) return;
3811 :
3812 : // Allocate the data arrays
3813 9 : state.dataSystemAvailabilityManager->HybridVentData.allocate(NumHybridVentSysAvailMgrs);
3814 9 : HybridVentSysAvailAirLoopNum.allocate(NumHybridVentSysAvailMgrs);
3815 9 : HybridVentSysAvailActualZoneNum.allocate(NumHybridVentSysAvailMgrs);
3816 9 : HybridVentSysAvailVentCtrl.allocate(NumHybridVentSysAvailMgrs);
3817 9 : HybridVentSysAvailANCtrlStatus.allocate(NumHybridVentSysAvailMgrs);
3818 9 : HybridVentSysAvailMaster.allocate(NumHybridVentSysAvailMgrs);
3819 9 : HybridVentSysAvailWindModifier.allocate(NumHybridVentSysAvailMgrs);
3820 9 : HybridVentSysAvailANCtrlStatus = 0;
3821 9 : HybridVentSysAvailMaster = 0;
3822 :
3823 19 : for (SysAvailNum = 1; SysAvailNum <= NumHybridVentSysAvailMgrs; ++SysAvailNum) {
3824 :
3825 70 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
3826 : cCurrentModuleObject,
3827 : SysAvailNum,
3828 10 : state.dataIPShortCut->cAlphaArgs,
3829 : NumAlphas,
3830 10 : state.dataIPShortCut->rNumericArgs,
3831 : NumNumbers,
3832 : IOStatus,
3833 10 : state.dataIPShortCut->lNumericFieldBlanks,
3834 10 : state.dataIPShortCut->lAlphaFieldBlanks,
3835 10 : state.dataIPShortCut->cAlphaFieldNames,
3836 10 : state.dataIPShortCut->cNumericFieldNames);
3837 :
3838 10 : auto &hybridVentMgr = state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum);
3839 10 : hybridVentMgr.Name = state.dataIPShortCut->cAlphaArgs(1);
3840 10 : hybridVentMgr.MgrType = DataPlant::SystemAvailabilityType::HybridVent;
3841 :
3842 10 : hybridVentMgr.AirLoopName = state.dataIPShortCut->cAlphaArgs(2);
3843 :
3844 10 : if (state.dataIPShortCut->lAlphaFieldBlanks(2)) { // Hybrid ventilation manager applied to zone
3845 2 : hybridVentMgr.HybridVentMgrConnectedToAirLoop = false;
3846 : }
3847 10 : hybridVentMgr.ControlZoneName = state.dataIPShortCut->cAlphaArgs(3);
3848 : // Check zone number
3849 10 : hybridVentMgr.ControlledZoneNum = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(3), state.dataHeatBal->Zone);
3850 10 : if (hybridVentMgr.ControlledZoneNum == 0) {
3851 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
3852 0 : ShowContinueError(state,
3853 0 : "not found: " + state.dataIPShortCut->cAlphaFieldNames(3) + "=\"" + state.dataIPShortCut->cAlphaArgs(3) + "\".");
3854 0 : ErrorsFound = true;
3855 : }
3856 :
3857 10 : hybridVentMgr.ControlModeSchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(4));
3858 10 : if (hybridVentMgr.ControlModeSchedPtr == 0) {
3859 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
3860 0 : ShowContinueError(state,
3861 0 : "not found: " + state.dataIPShortCut->cAlphaFieldNames(4) + "=\"" + state.dataIPShortCut->cAlphaArgs(4) + "\".");
3862 0 : ErrorsFound = true;
3863 : }
3864 :
3865 : // Check schedule values
3866 10 : SchedMin = GetScheduleMinValue(state, hybridVentMgr.ControlModeSchedPtr);
3867 10 : SchedMax = GetScheduleMaxValue(state, hybridVentMgr.ControlModeSchedPtr);
3868 10 : if (SchedMin == 0 && SchedMax == 0) {
3869 2 : ShowWarningError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
3870 6 : ShowContinueError(state,
3871 4 : state.dataIPShortCut->cAlphaFieldNames(4) + "=\"" + state.dataIPShortCut->cAlphaArgs(4) +
3872 : "\" specifies control mode 0 for all entries.");
3873 6 : ShowContinueError(state,
3874 4 : "All zones using this " + state.dataIPShortCut->cAlphaFieldNames(4) + " have no hybrid ventilation control.");
3875 : }
3876 10 : if (SchedMax > 7.0) {
3877 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
3878 0 : ShowContinueError(state,
3879 0 : state.dataIPShortCut->cAlphaFieldNames(4) + "=\"" + state.dataIPShortCut->cAlphaArgs(4) +
3880 : "\", the maximum schedule value should be 7. However, ");
3881 0 : ShowContinueError(state, format("the maximum entered value in the schedule is {:.1T}", SchedMax));
3882 0 : ErrorsFound = true;
3883 : }
3884 10 : if (SchedMin < 0.0) {
3885 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
3886 0 : ShowContinueError(state,
3887 0 : state.dataIPShortCut->cAlphaFieldNames(4) + "=\"" + state.dataIPShortCut->cAlphaArgs(4) +
3888 : "the minimum schedule value should be 0. However, ");
3889 0 : ShowContinueError(state, format("the minimum entered value in the schedule is {:.1T}", SchedMin));
3890 0 : ErrorsFound = true;
3891 : }
3892 10 : if (SchedMax == 7.0 && !state.dataContaminantBalance->Contaminant.CO2Simulation) {
3893 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
3894 0 : ShowContinueError(state,
3895 0 : state.dataIPShortCut->cAlphaFieldNames(4) + "=\"" + state.dataIPShortCut->cAlphaArgs(4) +
3896 : "\", When the schedule value is 7, carbon dioxide (CO2) control is requested. ");
3897 0 : ShowContinueError(state, "However, CO2 simulation is not enabled. Please use ZoneAirContaminantBalance object to simulate CO2.");
3898 0 : ErrorsFound = true;
3899 : }
3900 : // Read use weather rain indicator
3901 10 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(5), "YES")) {
3902 10 : hybridVentMgr.UseRainIndicator = true;
3903 0 : } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(5), "NO")) {
3904 0 : hybridVentMgr.UseRainIndicator = false;
3905 : } else {
3906 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
3907 0 : ShowContinueError(
3908 0 : state, "..invalid value: " + state.dataIPShortCut->cAlphaFieldNames(5) + "=\"" + state.dataIPShortCut->cAlphaArgs(5) + "\".");
3909 0 : ShowContinueError(state, "Valid choices are Yes or No.");
3910 0 : ErrorsFound = true;
3911 : }
3912 :
3913 : // Check max wind speed
3914 10 : if (NumNumbers > 0) {
3915 10 : hybridVentMgr.MaxWindSpeed = state.dataIPShortCut->rNumericArgs(1);
3916 10 : if (state.dataIPShortCut->rNumericArgs(1) > 40.0 || state.dataIPShortCut->rNumericArgs(1) < 0.0) {
3917 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
3918 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(1) + " is beyond the range.");
3919 0 : ShowContinueError(
3920 : state,
3921 0 : format("The input value is {:.0T}. The allowed value must be >= 0 and <= 40 m/s", state.dataIPShortCut->rNumericArgs(1)));
3922 0 : ErrorsFound = true;
3923 : }
3924 : }
3925 :
3926 : // Read Max and Min outdoor temperature
3927 10 : if (NumNumbers > 1) {
3928 10 : hybridVentMgr.MinOutdoorTemp = state.dataIPShortCut->rNumericArgs(2);
3929 10 : if (state.dataIPShortCut->rNumericArgs(2) > 100.0 || state.dataIPShortCut->rNumericArgs(2) < -100.0) {
3930 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
3931 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(2) + " is beyond the range.");
3932 0 : ShowContinueError(state,
3933 0 : format("The input value is {:.0T}. The allowed value must be between -100 C and +100 C",
3934 0 : state.dataIPShortCut->rNumericArgs(2)));
3935 0 : ErrorsFound = true;
3936 : }
3937 : }
3938 10 : if (NumNumbers > 2) {
3939 10 : hybridVentMgr.MaxOutdoorTemp = state.dataIPShortCut->rNumericArgs(3);
3940 10 : if (state.dataIPShortCut->rNumericArgs(3) > 100.0 || state.dataIPShortCut->rNumericArgs(3) < -100.0) {
3941 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
3942 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(3) + " is beyond the range.");
3943 0 : ShowContinueError(state,
3944 0 : format("The input value is {:.0T}. The allowed value must be between -100 C and +100 C",
3945 0 : state.dataIPShortCut->rNumericArgs(3)));
3946 0 : ErrorsFound = true;
3947 : }
3948 : }
3949 : // Ensure MaxTemp >= MinTemp
3950 10 : if (state.dataIPShortCut->rNumericArgs(2) >= state.dataIPShortCut->rNumericArgs(3)) {
3951 0 : ShowSevereError(state,
3952 0 : format("{}{}=\"{}\" The {} must be less than the {}",
3953 : RoutineName,
3954 : cCurrentModuleObject,
3955 0 : state.dataIPShortCut->cAlphaArgs(1),
3956 0 : state.dataIPShortCut->cNumericFieldNames(2),
3957 0 : state.dataIPShortCut->cNumericFieldNames(3)));
3958 0 : ShowContinueError(state,
3959 0 : format("The {} is {:.0T}. The {} is {:.0T}.",
3960 0 : state.dataIPShortCut->cNumericFieldNames(2),
3961 0 : state.dataIPShortCut->rNumericArgs(2),
3962 0 : state.dataIPShortCut->cNumericFieldNames(3),
3963 0 : state.dataIPShortCut->rNumericArgs(3)));
3964 0 : ErrorsFound = true;
3965 : }
3966 :
3967 : // Read Max and Min outdoor enthalpy
3968 10 : if (NumNumbers > 3) {
3969 10 : hybridVentMgr.MinOutdoorEnth = state.dataIPShortCut->rNumericArgs(4);
3970 10 : if (state.dataIPShortCut->rNumericArgs(4) > 300000.0 || state.dataIPShortCut->rNumericArgs(4) < 0.0) {
3971 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
3972 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(4) + " is beyond the range.");
3973 0 : ShowContinueError(state,
3974 0 : format("The input value is {:.0T}. The allowed value must be between 0 and 300000 J/kg",
3975 0 : state.dataIPShortCut->rNumericArgs(4)));
3976 0 : ErrorsFound = true;
3977 : }
3978 : }
3979 10 : if (NumNumbers > 4) {
3980 10 : hybridVentMgr.MaxOutdoorEnth = state.dataIPShortCut->rNumericArgs(5);
3981 10 : if (state.dataIPShortCut->rNumericArgs(5) > 300000.0 || state.dataIPShortCut->rNumericArgs(5) < 0.0) {
3982 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
3983 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(5) + " is beyond the range.");
3984 0 : ShowContinueError(state,
3985 0 : format("The input value is {:.0T}. The allowed value must be between 0 and 300000 J/kg",
3986 0 : state.dataIPShortCut->rNumericArgs(5)));
3987 0 : ErrorsFound = true;
3988 : }
3989 : }
3990 : // Ensure MaxEnth >= MiniEnth
3991 10 : if (state.dataIPShortCut->rNumericArgs(4) >= state.dataIPShortCut->rNumericArgs(5)) {
3992 0 : ShowSevereError(state,
3993 0 : format("{}{}=\"{}\" The {} must be less than the {}",
3994 : RoutineName,
3995 : cCurrentModuleObject,
3996 0 : state.dataIPShortCut->cAlphaArgs(1),
3997 0 : state.dataIPShortCut->cNumericFieldNames(4),
3998 0 : state.dataIPShortCut->cNumericFieldNames(5)));
3999 0 : ShowContinueError(state,
4000 0 : format("The {} is {:.0T}. The {} is {:.0T}.",
4001 0 : state.dataIPShortCut->cNumericFieldNames(4),
4002 0 : state.dataIPShortCut->rNumericArgs(4),
4003 0 : state.dataIPShortCut->cNumericFieldNames(5),
4004 0 : state.dataIPShortCut->rNumericArgs(5)));
4005 0 : ErrorsFound = true;
4006 : }
4007 :
4008 : // Read Max and Min outdoor dew point
4009 10 : if (NumNumbers > 5) {
4010 10 : hybridVentMgr.MinOutdoorDewPoint = state.dataIPShortCut->rNumericArgs(6);
4011 10 : if (state.dataIPShortCut->rNumericArgs(6) > 100.0 || state.dataIPShortCut->rNumericArgs(6) < -100.0) {
4012 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4013 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(6) + " is beyond the range.");
4014 0 : ShowContinueError(state,
4015 0 : format("The input value is {:.0T}. The allowed value must be between -100 C and +100 C",
4016 0 : state.dataIPShortCut->rNumericArgs(6)));
4017 0 : ErrorsFound = true;
4018 : }
4019 : }
4020 10 : if (NumNumbers > 6) {
4021 10 : hybridVentMgr.MaxOutdoorDewPoint = state.dataIPShortCut->rNumericArgs(7);
4022 10 : if (state.dataIPShortCut->rNumericArgs(7) > 100.0 || state.dataIPShortCut->rNumericArgs(7) < -100.0) {
4023 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4024 0 : ShowContinueError(state, state.dataIPShortCut->cNumericFieldNames(7) + " is beyond the range.");
4025 0 : ShowContinueError(state,
4026 0 : format("The input value is {:.0T}. The allowed value must be between -100 C and +100 C",
4027 0 : state.dataIPShortCut->rNumericArgs(7)));
4028 0 : ErrorsFound = true;
4029 : }
4030 : }
4031 : // Ensure MaxTemp >= MinTemp
4032 10 : if (state.dataIPShortCut->rNumericArgs(6) >= state.dataIPShortCut->rNumericArgs(7)) {
4033 0 : ShowSevereError(state,
4034 0 : format("{}{}=\"{}\" The {} must be less than the {}",
4035 : RoutineName,
4036 : cCurrentModuleObject,
4037 0 : state.dataIPShortCut->cAlphaArgs(1),
4038 0 : state.dataIPShortCut->cNumericFieldNames(6),
4039 0 : state.dataIPShortCut->cNumericFieldNames(7)));
4040 0 : ShowContinueError(state,
4041 0 : format("The {} is {:.0T}. The {} is {:.0T}.",
4042 0 : state.dataIPShortCut->cNumericFieldNames(6),
4043 0 : state.dataIPShortCut->rNumericArgs(6),
4044 0 : state.dataIPShortCut->cNumericFieldNames(7),
4045 0 : state.dataIPShortCut->rNumericArgs(7)));
4046 0 : ErrorsFound = true;
4047 : }
4048 :
4049 10 : hybridVentMgr.MinOASched = state.dataIPShortCut->cAlphaArgs(6);
4050 10 : hybridVentMgr.MinOASchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(6));
4051 10 : if (hybridVentMgr.MinOASchedPtr == 0) {
4052 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4053 0 : ShowContinueError(state,
4054 0 : "..not found: " + state.dataIPShortCut->cAlphaFieldNames(6) + "=\"" + state.dataIPShortCut->cAlphaArgs(6) + "\".");
4055 0 : ErrorsFound = true;
4056 : }
4057 10 : SchedMin = GetScheduleMinValue(state, hybridVentMgr.MinOASchedPtr);
4058 10 : if (SchedMin < 0.0) {
4059 0 : ShowSevereError(state,
4060 0 : format(R"({}{}="{}", Schedule value must be >= 0 in {}="{}".)",
4061 : RoutineName,
4062 : cCurrentModuleObject,
4063 0 : state.dataIPShortCut->cAlphaArgs(1),
4064 0 : state.dataIPShortCut->cAlphaFieldNames(6),
4065 0 : state.dataIPShortCut->cAlphaArgs(6)));
4066 0 : ShowContinueError(state, format("The minimum schedule value is {:.1T}", SchedMin));
4067 0 : ErrorsFound = true;
4068 : }
4069 :
4070 10 : if (!state.dataIPShortCut->lAlphaFieldBlanks(7)) {
4071 5 : hybridVentMgr.OpeningFactorFWS = GetCurveIndex(state, state.dataIPShortCut->cAlphaArgs(7));
4072 5 : if (hybridVentMgr.OpeningFactorFWS <= 0) {
4073 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4074 0 : ShowContinueError(
4075 0 : state, " not found: " + state.dataIPShortCut->cAlphaFieldNames(7) + "=\"" + state.dataIPShortCut->cAlphaArgs(7) + "\".");
4076 0 : ErrorsFound = true;
4077 : } else {
4078 5 : GetCurveMinMaxValues(state, hybridVentMgr.OpeningFactorFWS, CurveMin, CurveMax);
4079 5 : if (CurveMin < 0.0) {
4080 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4081 0 : ShowContinueError(state,
4082 0 : "The minimum wind speed used in " + state.dataIPShortCut->cAlphaFieldNames(7) + "=\"" +
4083 0 : state.dataIPShortCut->cAlphaArgs(7) + "should be greater than or equal to 0.0 (m/s)");
4084 0 : ShowContinueError(state, "Curve minimum value appears to be less than 0.");
4085 0 : ErrorsFound = true;
4086 : }
4087 5 : CurveVal = CurveValue(state, hybridVentMgr.OpeningFactorFWS, CurveMin);
4088 5 : if (CurveVal < 0.0) {
4089 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4090 0 : ShowContinueError(state,
4091 0 : "The minimum value of " + state.dataIPShortCut->cAlphaFieldNames(7) +
4092 : " must be greater than or equal to 0.0 at the minimum value of wind speed.");
4093 0 : ShowContinueError(state, state.dataIPShortCut->cAlphaFieldNames(7) + "=\"" + state.dataIPShortCut->cAlphaArgs(7) + "\".");
4094 0 : ShowContinueError(state, format("Curve output at the minimum wind speed = {:.3T}", CurveVal));
4095 0 : ErrorsFound = true;
4096 : }
4097 5 : CurveVal = CurveValue(state, hybridVentMgr.OpeningFactorFWS, CurveMax);
4098 5 : if (CurveVal > 1.0) {
4099 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4100 0 : ShowContinueError(state,
4101 0 : "The maximum value of " + state.dataIPShortCut->cAlphaFieldNames(7) +
4102 : " must be less than or equal to 1.0 at the maximum value of wind speed.");
4103 0 : ShowContinueError(state, state.dataIPShortCut->cAlphaFieldNames(7) + "=\"" + state.dataIPShortCut->cAlphaArgs(7) + "\".");
4104 0 : ShowContinueError(state, format("Curve output at the maximum wind speed = {:.3T}", CurveVal));
4105 0 : ErrorsFound = true;
4106 : }
4107 : // Check curve type
4108 5 : ErrorsFound |= Curve::CheckCurveDims(state,
4109 : hybridVentMgr.OpeningFactorFWS, // Curve index
4110 : {1}, // Valid dimensions
4111 : RoutineName, // Routine name
4112 : cCurrentModuleObject, // Object Type
4113 : hybridVentMgr.Name, // Object Name
4114 5 : state.dataIPShortCut->cAlphaFieldNames(7)); // Field Name
4115 : }
4116 : }
4117 :
4118 10 : hybridVentMgr.ANControlTypeSchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(8));
4119 10 : if (hybridVentMgr.ANControlTypeSchedPtr > 0) {
4120 3 : HybridVentSysAvailMaster(SysAvailNum) = hybridVentMgr.ControlledZoneNum;
4121 : // Check schedule values
4122 3 : SchedMin = GetScheduleMinValue(state, hybridVentMgr.ANControlTypeSchedPtr);
4123 3 : SchedMax = GetScheduleMaxValue(state, hybridVentMgr.ANControlTypeSchedPtr);
4124 3 : HybridVentSysAvailANCtrlStatus(SysAvailNum) = hybridVentMgr.ANControlTypeSchedPtr;
4125 3 : if (SchedMax > 1.0) {
4126 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4127 0 : ShowContinueError(state,
4128 0 : " For " + state.dataIPShortCut->cAlphaFieldNames(8) + "=\"" + state.dataIPShortCut->cAlphaArgs(8) + "\",");
4129 0 : ShowContinueError(state, "the maximum schedule value should be 1. However, ");
4130 0 : ShowContinueError(state, format("the maximum entered value in the schedule is {:.1T}", SchedMax));
4131 0 : ErrorsFound = true;
4132 : }
4133 3 : if (SchedMin < 0.0) {
4134 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4135 0 : ShowContinueError(state,
4136 0 : "For " + state.dataIPShortCut->cAlphaFieldNames(8) + "=\"" + state.dataIPShortCut->cAlphaArgs(8) + "\",");
4137 0 : ShowContinueError(state, "the minimum schedule value should be 0. However, ");
4138 0 : ShowContinueError(state, format("the minimum entered value in the schedule is {:.1T}", SchedMin));
4139 0 : ErrorsFound = true;
4140 : }
4141 : }
4142 :
4143 10 : hybridVentMgr.SimpleControlTypeSchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(9));
4144 10 : if (hybridVentMgr.SimpleControlTypeSchedPtr > 0 && hybridVentMgr.ANControlTypeSchedPtr > 0) {
4145 0 : ShowWarningError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4146 0 : ShowContinueError(state,
4147 0 : "The inputs for" + state.dataIPShortCut->cAlphaFieldNames(8) + " and " + state.dataIPShortCut->cAlphaFieldNames(9) +
4148 : " are valid.");
4149 0 : ShowContinueError(state, "But both objects cannot work at the same time. The Simple Airflow Control is disabled");
4150 0 : hybridVentMgr.SimpleControlTypeSchedPtr = 0;
4151 10 : } else if (hybridVentMgr.SimpleControlTypeSchedPtr > 0) {
4152 : // Check schedule values
4153 2 : SchedMin = GetScheduleMinValue(state, hybridVentMgr.SimpleControlTypeSchedPtr);
4154 2 : SchedMax = GetScheduleMaxValue(state, hybridVentMgr.SimpleControlTypeSchedPtr);
4155 2 : if (SchedMax > 1.0) {
4156 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4157 0 : ShowContinueError(state,
4158 0 : "For " + state.dataIPShortCut->cAlphaFieldNames(9) + "=\"" + state.dataIPShortCut->cAlphaArgs(9) + "\",");
4159 0 : ShowContinueError(state, "the maximum schedule value should be 1. However, ");
4160 0 : ShowContinueError(state, format("the maximum entered value in the schedule is {:.1T}", SchedMax));
4161 0 : ErrorsFound = true;
4162 : }
4163 2 : if (SchedMin < 0.0) {
4164 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4165 0 : ShowContinueError(state,
4166 0 : "For " + state.dataIPShortCut->cAlphaFieldNames(9) + "=\"" + state.dataIPShortCut->cAlphaArgs(9) + "\",");
4167 0 : ShowContinueError(state, "the minimum schedule value should be 0. However, ");
4168 0 : ShowContinueError(state, format("the minimum entered value in the schedule is {:.1T}", SchedMin));
4169 0 : ErrorsFound = true;
4170 : }
4171 : }
4172 :
4173 10 : if (hybridVentMgr.SimpleControlTypeSchedPtr > 0) {
4174 2 : hybridVentMgr.VentilationName = state.dataIPShortCut->cAlphaArgs(10);
4175 2 : if (state.dataHeatBal->TotVentilation > 0) {
4176 2 : hybridVentMgr.VentilationPtr =
4177 2 : UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(10), state.dataHeatBal->Ventilation);
4178 2 : HybridVentSysAvailMaster(SysAvailNum) = hybridVentMgr.VentilationPtr;
4179 2 : SchedMax = GetScheduleMaxValue(state, hybridVentMgr.SimpleControlTypeSchedPtr);
4180 2 : if (hybridVentMgr.VentilationPtr <= 0 && int(SchedMax) == 1) {
4181 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4182 0 : ShowContinueError(state,
4183 0 : state.dataIPShortCut->cAlphaFieldNames(10) + "=\"" + state.dataIPShortCut->cAlphaArgs(10) +
4184 : "\" is required and not found.");
4185 0 : ErrorsFound = true;
4186 : } // Otherwise check later
4187 : }
4188 : }
4189 :
4190 : // Check simple airflow object
4191 10 : if (hybridVentMgr.SimpleControlTypeSchedPtr > 0 && hybridVentMgr.VentilationPtr > 0) {
4192 2 : if (hybridVentMgr.ControlledZoneNum != state.dataHeatBal->Ventilation(hybridVentMgr.VentilationPtr).ZonePtr) {
4193 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4194 0 : ShowContinueError(state,
4195 0 : "The Zone name specified in the Ventilation object " +
4196 0 : state.dataHeatBal->Zone(state.dataHeatBal->Ventilation(hybridVentMgr.VentilationPtr).ZonePtr).Name);
4197 0 : ShowContinueError(state,
4198 0 : "is not equal to the " + state.dataIPShortCut->cAlphaFieldNames(3) + "=\"" +
4199 0 : state.dataIPShortCut->cAlphaArgs(3) + "\".");
4200 0 : ErrorsFound = true;
4201 : }
4202 : }
4203 :
4204 12 : if (hybridVentMgr.SimpleControlTypeSchedPtr > 0 &&
4205 2 : state.afn->simulation_control.type != AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
4206 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, hybridVentMgr.Name));
4207 0 : ShowContinueError(state, "The simple airflow objects are used for natural ventilation calculation.");
4208 0 : ShowContinueError(state,
4209 : "The Airflow Network model is not allowed to perform. Please set the control type = NoMultizoneOrDistribution");
4210 0 : ErrorsFound = true;
4211 : }
4212 :
4213 10 : if (hybridVentMgr.SimpleControlTypeSchedPtr == 0) {
4214 8 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
4215 0 : ShowWarningError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, hybridVentMgr.Name));
4216 0 : ShowContinueError(state, "The Airflow Network model is not available for Hybrid Ventilation Control.");
4217 8 : } else if (state.afn->simulation_control.type == AirflowNetwork::ControlType::MultizoneWithDistributionOnlyDuringFanOperation) {
4218 0 : ShowWarningError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, hybridVentMgr.Name));
4219 0 : ShowContinueError(state, "Please check the AirflowNetwork Control field in the AirflowNetwork:SimulationControl object.");
4220 0 : ShowContinueError(state, "The suggested choices are MultizoneWithDistribution or MultizoneWithoutDistribution.");
4221 : }
4222 : }
4223 :
4224 : // Disallow combination of simple control and OA control mode
4225 10 : SchedMax = GetScheduleMaxValue(state, hybridVentMgr.ControlModeSchedPtr);
4226 10 : if (hybridVentMgr.SimpleControlTypeSchedPtr > 0 && SchedMax == 4.0) {
4227 0 : ShowSevereError(state, format("{}{}=\"{}\"", RoutineName, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1)));
4228 0 : ShowContinueError(state,
4229 0 : "The outdoor ventilation air control type defined in " + state.dataIPShortCut->cAlphaArgs(4) +
4230 0 : " cannot work together with " + state.dataIPShortCut->cAlphaFieldNames(9));
4231 0 : ErrorsFound = true;
4232 : }
4233 :
4234 10 : if (!state.dataIPShortCut->lNumericFieldBlanks(8)) {
4235 1 : hybridVentMgr.MinOperTime = state.dataIPShortCut->rNumericArgs(8);
4236 : }
4237 10 : if (!state.dataIPShortCut->lNumericFieldBlanks(9)) {
4238 1 : hybridVentMgr.MinVentTime = state.dataIPShortCut->rNumericArgs(9);
4239 : }
4240 :
4241 : } // SysAvailNum
4242 :
4243 9 : if (NumHybridVentSysAvailMgrs > 1) {
4244 2 : for (SysAvailNum = 2; SysAvailNum <= NumHybridVentSysAvailMgrs; ++SysAvailNum) {
4245 1 : if (state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum - 1).ANControlTypeSchedPtr > 0) {
4246 1 : if (state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).SimpleControlTypeSchedPtr > 0) {
4247 0 : ShowSevereError(state,
4248 0 : format("The AirflowNetwork model is used for natural ventilation calculation in {}=\"{}\"",
4249 : cCurrentModuleObject,
4250 0 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum - 1).Name));
4251 0 : ShowContinueError(state,
4252 0 : format("The simple airflow objects are used for natural ventilation calculation in {}=\"{}\"",
4253 : cCurrentModuleObject,
4254 0 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).Name));
4255 0 : ShowContinueError(state, "The hybrid ventilation control requires the same models to calculate natural ventilation");
4256 0 : ErrorsFound = true;
4257 : }
4258 : }
4259 1 : if (state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum - 1).SimpleControlTypeSchedPtr > 0) {
4260 0 : if (state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).ANControlTypeSchedPtr > 0) {
4261 0 : ShowSevereError(state,
4262 0 : format("The Airflow Network model is used for natural ventilation calculation in {}=\"{}\"",
4263 : cCurrentModuleObject,
4264 0 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).Name));
4265 0 : ShowContinueError(state,
4266 0 : format("The simple airflow objects are used for natural ventilation calculation in {}=\"{}\"",
4267 : cCurrentModuleObject,
4268 0 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum - 1).Name));
4269 0 : ShowContinueError(state, "The hybrid ventilation control requires the same models to calculate natural ventilation");
4270 0 : ErrorsFound = true;
4271 : }
4272 : }
4273 : } // SysAvailNum
4274 : }
4275 :
4276 9 : if (ErrorsFound) {
4277 0 : ShowFatalError(state, format("{} Errors found in input. Preceding condition(s) cause termination.", RoutineName));
4278 : }
4279 :
4280 : // Set up output variables
4281 19 : for (SysAvailNum = 1; SysAvailNum <= NumHybridVentSysAvailMgrs; ++SysAvailNum) {
4282 10 : if (state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).HybridVentMgrConnectedToAirLoop) {
4283 32 : SetupOutputVariable(state,
4284 : "Availability Manager Hybrid Ventilation Control Status",
4285 : OutputProcessor::Unit::None,
4286 8 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).VentilationCtrl,
4287 : OutputProcessor::SOVTimeStepType::System,
4288 : OutputProcessor::SOVStoreType::Average,
4289 16 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).AirLoopName);
4290 32 : SetupOutputVariable(state,
4291 : "Availability Manager Hybrid Ventilation Control Mode",
4292 : OutputProcessor::Unit::None,
4293 8 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).ControlMode,
4294 : OutputProcessor::SOVTimeStepType::System,
4295 : OutputProcessor::SOVStoreType::Average,
4296 16 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).AirLoopName);
4297 : } else {
4298 8 : SetupOutputVariable(state,
4299 : "Availability Manager Hybrid Ventilation Control Status",
4300 : OutputProcessor::Unit::None,
4301 2 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).VentilationCtrl,
4302 : OutputProcessor::SOVTimeStepType::System,
4303 : OutputProcessor::SOVStoreType::Average,
4304 4 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).ControlZoneName);
4305 8 : SetupOutputVariable(state,
4306 : "Availability Manager Hybrid Ventilation Control Mode",
4307 : OutputProcessor::Unit::None,
4308 2 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).ControlMode,
4309 : OutputProcessor::SOVTimeStepType::System,
4310 : OutputProcessor::SOVStoreType::Average,
4311 4 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).ControlZoneName);
4312 : }
4313 :
4314 10 : if (state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).MinOperTime > 0) {
4315 4 : SetupOutputVariable(state,
4316 : "Hybrid Ventilation Control HVAC System Operation Elapsed Time",
4317 : OutputProcessor::Unit::min,
4318 1 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).TimeOperDuration,
4319 : OutputProcessor::SOVTimeStepType::System,
4320 : OutputProcessor::SOVStoreType::Average,
4321 2 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).Name);
4322 : }
4323 :
4324 10 : if (state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).MinVentTime > 0) {
4325 4 : SetupOutputVariable(state,
4326 : "Hybrid Ventilation Control Natural Ventilation Elapsed Time",
4327 : OutputProcessor::Unit::min,
4328 1 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).TimeVentDuration,
4329 : OutputProcessor::SOVTimeStepType::System,
4330 : OutputProcessor::SOVStoreType::Average,
4331 2 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).Name);
4332 : }
4333 :
4334 20 : if (CheckScheduleValue(
4335 29 : state, state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).ControlModeSchedPtr, HybridVentMode_OperT80) ||
4336 9 : CheckScheduleValue(
4337 9 : state, state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).ControlModeSchedPtr, HybridVentMode_OperT90)) {
4338 4 : SetupOutputVariable(state,
4339 : "Hybrid Ventilation Operative Temperature",
4340 : OutputProcessor::Unit::C,
4341 1 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).OperativeTemp,
4342 : OutputProcessor::SOVTimeStepType::System,
4343 : OutputProcessor::SOVStoreType::Average,
4344 2 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).Name);
4345 4 : SetupOutputVariable(state,
4346 : "Hybrid Ventilation Lower Limit Operative Temperature",
4347 : OutputProcessor::Unit::C,
4348 1 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).minAdaTem,
4349 : OutputProcessor::SOVTimeStepType::System,
4350 : OutputProcessor::SOVStoreType::Average,
4351 2 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).Name);
4352 4 : SetupOutputVariable(state,
4353 : "Hybrid Ventilation Upper Limit Operative Temperature",
4354 : OutputProcessor::Unit::C,
4355 1 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).maxAdaTem,
4356 : OutputProcessor::SOVTimeStepType::System,
4357 : OutputProcessor::SOVStoreType::Average,
4358 2 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).Name);
4359 : }
4360 :
4361 10 : if (CheckScheduleValue(state, state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).ControlModeSchedPtr, HybridVentMode_CO2)) {
4362 4 : SetupOutputVariable(state,
4363 : "Hybrid Ventilation CO2 Concentration",
4364 : OutputProcessor::Unit::ppm,
4365 1 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).CO2,
4366 : OutputProcessor::SOVTimeStepType::System,
4367 : OutputProcessor::SOVStoreType::Average,
4368 2 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).Name);
4369 : }
4370 : }
4371 : }
4372 :
4373 42093 : void InitHybridVentSysAvailMgr(EnergyPlusData &state)
4374 : {
4375 :
4376 : // SUBROUTINE INFORMATION:
4377 : // AUTHOR Lixing Gu
4378 : // DATE WRITTEN March 2007
4379 : // MODIFIED na
4380 : // RE-ENGINEERED na
4381 :
4382 : // PURPOSE OF THIS SUBROUTINE:
4383 : // This subroutine is for initializations of the Hybrid Ventilation Control System Availability Manager
4384 :
4385 : // METHODOLOGY EMPLOYED:
4386 : // Uses the status flags to trigger initializations.
4387 :
4388 : // Using/Aliasing
4389 : using DataZoneEquipment::NumValidSysAvailZoneComponents;
4390 :
4391 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4392 42093 : auto &MyOneTimeFlag = state.dataSystemAvailabilityManager->MyOneTimeFlag;
4393 42093 : auto &MyEnvrnFlag = state.dataSystemAvailabilityManager->MyEnvrnFlag;
4394 : int SysAvailNum; // DO loop index for Sys Avail Manager objects
4395 42093 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
4396 : int AirLoopNum; // Air loop number
4397 : int AirLoopCount; // Air loop name count
4398 : Real64 SchedMax; // Maximum value specified in a schedule
4399 : int SysAvailIndex; // Hybrid Ventilation Sys Avail Manager index
4400 : int ZoneEquipType;
4401 : int HybridVentNum;
4402 :
4403 42093 : auto &NumHybridVentSysAvailMgrs = state.dataHVACGlobal->NumHybridVentSysAvailMgrs;
4404 42093 : auto &HybridVentSysAvailAirLoopNum = state.dataHVACGlobal->HybridVentSysAvailAirLoopNum;
4405 42093 : auto &HybridVentSysAvailActualZoneNum = state.dataHVACGlobal->HybridVentSysAvailActualZoneNum;
4406 42093 : auto &HybridVentSysAvailVentCtrl = state.dataHVACGlobal->HybridVentSysAvailVentCtrl;
4407 42093 : auto &HybridVentSysAvailMaster = state.dataHVACGlobal->HybridVentSysAvailMaster;
4408 42093 : auto &HybridVentSysAvailWindModifier = state.dataHVACGlobal->HybridVentSysAvailWindModifier;
4409 42093 : auto &ZoneComp = state.dataHVACGlobal->ZoneComp;
4410 :
4411 : // One time initializations
4412 42093 : if (MyOneTimeFlag && allocated(state.dataZoneEquip->ZoneEquipConfig) && allocated(state.dataAirSystemsData->PrimaryAirSystems)) {
4413 :
4414 : // Ensure the controlled zone is listed and defined in an HVAC Air Loop
4415 19 : for (SysAvailNum = 1; SysAvailNum <= NumHybridVentSysAvailMgrs; ++SysAvailNum) {
4416 10 : auto &hybridVentMgr = state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum);
4417 10 : if (hybridVentMgr.SimpleControlTypeSchedPtr > 0 && state.dataHeatBal->TotVentilation > 0 && hybridVentMgr.VentilationPtr == 0) {
4418 0 : hybridVentMgr.VentilationPtr = UtilityRoutines::FindItemInList(hybridVentMgr.VentilationName, state.dataHeatBal->Ventilation);
4419 0 : HybridVentSysAvailMaster(SysAvailNum) = hybridVentMgr.VentilationPtr;
4420 0 : SchedMax = GetScheduleMaxValue(state, hybridVentMgr.SimpleControlTypeSchedPtr);
4421 0 : if (hybridVentMgr.VentilationPtr <= 0 && int(SchedMax) == 1) {
4422 0 : ShowSevereError(state, "ZoneVentilation Object Name=\"" + hybridVentMgr.VentilationName + "\" is required and not found.");
4423 0 : ShowContinueError(state, "Occurs in AvailabilityManager:HybridVentilation=\"" + hybridVentMgr.Name + "\".");
4424 0 : ErrorsFound = true;
4425 : }
4426 : }
4427 : // Check air loop number
4428 19 : for (AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) { // loop over the primary air systems
4429 9 : if (UtilityRoutines::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Name, hybridVentMgr.AirLoopName)) {
4430 8 : hybridVentMgr.AirLoopNum = AirLoopNum;
4431 : }
4432 : }
4433 10 : HybridVentSysAvailAirLoopNum(SysAvailNum) = hybridVentMgr.AirLoopNum;
4434 10 : HybridVentSysAvailActualZoneNum(SysAvailNum) = hybridVentMgr.ControlledZoneNum;
4435 :
4436 10 : bool zoneFound = false;
4437 10 : int ControlledZoneNum = hybridVentMgr.ControlledZoneNum;
4438 10 : if (hybridVentMgr.HybridVentMgrConnectedToAirLoop) {
4439 8 : if (hybridVentMgr.ControlledZoneNum > 0) {
4440 16 : for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
4441 8 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode) == hybridVentMgr.AirLoopNum) {
4442 8 : zoneFound = true;
4443 : }
4444 : }
4445 8 : if (!zoneFound) {
4446 0 : ShowSevereError(state,
4447 0 : format("{}, The controlled zone ={} is not served by this Air Loop={}",
4448 0 : SystemAvailabilityTypeNamesUC[static_cast<int>(hybridVentMgr.MgrType)],
4449 : hybridVentMgr.ControlZoneName,
4450 0 : hybridVentMgr.AirLoopName));
4451 0 : ErrorsFound = true;
4452 : }
4453 : }
4454 : }
4455 20 : if (std::any_of(state.dataSystemAvailabilityManager->HybridVentData.begin(),
4456 20 : state.dataSystemAvailabilityManager->HybridVentData.end(),
4457 10 : [](SystemAvailabilityManager::SysAvailManagerHybridVent const &e) { return e.HybridVentMgrConnectedToAirLoop; })) {
4458 18 : for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
4459 18 : if (state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode) == hybridVentMgr.AirLoopNum &&
4460 9 : hybridVentMgr.AirLoopNum > 0) {
4461 17 : for (HybridVentNum = 1; HybridVentNum <= NumHybridVentSysAvailMgrs; ++HybridVentNum) {
4462 9 : if (!state.dataSystemAvailabilityManager->HybridVentData(HybridVentNum).HybridVentMgrConnectedToAirLoop &&
4463 : (HybridVentNum != SysAvailNum)) {
4464 1 : if (ControlledZoneNum == state.dataSystemAvailabilityManager->HybridVentData(HybridVentNum).ControlledZoneNum &&
4465 : ControlledZoneNum > 0) {
4466 0 : ShowWarningError(state,
4467 0 : "AvailabilityManager:HybridVentilation = \"" +
4468 0 : state.dataSystemAvailabilityManager->HybridVentData(HybridVentNum).Name +
4469 0 : "\" has the controlled zone name = \"" +
4470 0 : state.dataSystemAvailabilityManager->HybridVentData(HybridVentNum).ControlZoneName +
4471 : "\".");
4472 0 : ShowContinueError(state,
4473 0 : "This controlled zone already has hybrid ventilation control through this air loop = \"" +
4474 0 : hybridVentMgr.AirLoopName + "\".");
4475 0 : ShowContinueError(state,
4476 0 : "Only AvailabilityManager:HybridVentilation = \"" + hybridVentMgr.Name +
4477 : "\" will be simulated. Simulation continues...");
4478 : } else {
4479 1 : state.dataSystemAvailabilityManager->HybridVentData(HybridVentNum).SimHybridVentSysAvailMgr = true;
4480 : }
4481 : }
4482 : }
4483 : }
4484 : }
4485 : } else {
4486 2 : for (auto &e : state.dataSystemAvailabilityManager->HybridVentData)
4487 1 : e.SimHybridVentSysAvailMgr = true;
4488 : }
4489 :
4490 10 : if (hybridVentMgr.ControlledZoneNum == 0) {
4491 0 : ShowSevereError(state,
4492 0 : format("{}, The controlled zone is not defined correctly ={}",
4493 0 : SystemAvailabilityTypeNamesUC[static_cast<int>(hybridVentMgr.MgrType)],
4494 0 : hybridVentMgr.ControlZoneName));
4495 0 : ErrorsFound = true;
4496 : }
4497 : // check schedule value for adaptive temperature control
4498 19 : if (CheckScheduleValue(state, hybridVentMgr.ControlModeSchedPtr, 5.0) ||
4499 9 : CheckScheduleValue(state, hybridVentMgr.ControlModeSchedPtr, 6.0)) {
4500 1 : if (!state.dataHeatBal->AdaptiveComfortRequested_ASH55) {
4501 0 : ShowSevereError(state, "GetHybridVentilationInputs: AvailabilityManager:HybridVentilation =\"" + hybridVentMgr.Name + "\"");
4502 0 : ShowContinueError(state,
4503 0 : "Ventilation Control Mode Schedule Name =\"" +
4504 0 : state.dataScheduleMgr->Schedule(hybridVentMgr.ControlModeSchedPtr).Name +
4505 : "\", When the schedule value is 5 or 6, operative temperature control is requested. ");
4506 0 : ShowContinueError(state,
4507 : "However, AdaptiveASH55 is not entered in the Thermal Comfort Model Type fields in the People object.");
4508 0 : ErrorsFound = true;
4509 : }
4510 : }
4511 : }
4512 :
4513 : // Ensure an airloop name is not used more than once in the hybrid ventilation control objects
4514 17 : for (AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) { // loop over the primary air systems
4515 8 : AirLoopCount = 0;
4516 17 : for (SysAvailNum = 1; SysAvailNum <= NumHybridVentSysAvailMgrs; ++SysAvailNum) {
4517 9 : if (UtilityRoutines::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Name,
4518 9 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).AirLoopName)) {
4519 8 : ++AirLoopCount;
4520 8 : if (AirLoopCount > 1) SysAvailIndex = SysAvailNum;
4521 : }
4522 : }
4523 8 : if (AirLoopCount > 1) {
4524 0 : ShowSevereError(state,
4525 0 : format("{}, The AirLoopHVAC name found more than once={}",
4526 : SystemAvailabilityTypeNamesUC[static_cast<int>(
4527 0 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailIndex).MgrType)],
4528 0 : state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Name));
4529 0 : ShowContinueError(state, "Each AirLoopHVAC allows one hybrid ventilation control object.");
4530 0 : ErrorsFound = true;
4531 : }
4532 : }
4533 :
4534 9 : if (ErrorsFound) {
4535 0 : ShowFatalError(state, "Errors found in getting AvailabilityManager:* inputs");
4536 : }
4537 :
4538 9 : MyOneTimeFlag = false;
4539 :
4540 : } // end 1 time initializations
4541 :
4542 91565 : for (SysAvailNum = 1; SysAvailNum <= NumHybridVentSysAvailMgrs; ++SysAvailNum) {
4543 49472 : auto &hybridVentMgr = state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum);
4544 49472 : hybridVentMgr.ControlMode = GetCurrentScheduleValue(state, hybridVentMgr.ControlModeSchedPtr);
4545 : // -1 means that the value will be determined inside CalcHybridVentSysAvailMgr.
4546 : // IF the value is still -1, the program will stop.
4547 49472 : HybridVentSysAvailVentCtrl(SysAvailNum) = -1;
4548 49472 : HybridVentSysAvailWindModifier(SysAvailNum) = -1.0;
4549 : }
4550 :
4551 42093 : if (allocated(state.dataSystemAvailabilityManager->HybridVentData))
4552 91565 : for (auto &e : state.dataSystemAvailabilityManager->HybridVentData)
4553 49472 : e.AvailStatus = NoAction;
4554 :
4555 631395 : for (ZoneEquipType = 1; ZoneEquipType <= NumValidSysAvailZoneComponents; ++ZoneEquipType) { // loop over the zone equipment types
4556 589302 : if (allocated(ZoneComp)) {
4557 540974 : if (ZoneComp(ZoneEquipType).TotalNumComp > 0)
4558 37300 : for (auto &e : ZoneComp(ZoneEquipType).ZoneCompAvailMgrs)
4559 24286 : e.AvailStatus = NoAction;
4560 : }
4561 : }
4562 :
4563 42093 : if (state.dataGlobal->BeginEnvrnFlag && MyEnvrnFlag) {
4564 138 : for (SysAvailNum = 1; SysAvailNum <= NumHybridVentSysAvailMgrs; ++SysAvailNum) {
4565 74 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).TimeVentDuration = 0.0;
4566 74 : state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).TimeOperDuration = 0.0;
4567 : }
4568 64 : MyEnvrnFlag = false;
4569 : }
4570 42093 : if (!state.dataGlobal->BeginEnvrnFlag) {
4571 41889 : MyEnvrnFlag = true;
4572 : }
4573 : // check minimum operation time
4574 42093 : state.dataSystemAvailabilityManager->CurrentEndTime = state.dataGlobal->CurrentTime + state.dataHVACGlobal->SysTimeElapsed;
4575 78484 : if (state.dataSystemAvailabilityManager->CurrentEndTime > state.dataSystemAvailabilityManager->CurrentEndTimeLast &&
4576 36391 : state.dataHVACGlobal->TimeStepSys >= state.dataSystemAvailabilityManager->TimeStepSysLast) {
4577 78990 : for (SysAvailNum = 1; SysAvailNum <= NumHybridVentSysAvailMgrs; ++SysAvailNum) {
4578 42599 : auto &hybridVentMgr = state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum);
4579 42599 : if (hybridVentMgr.VentilationCtrl == HybridVentCtrl_NoAction) {
4580 19228 : hybridVentMgr.TimeOperDuration = 0.0;
4581 19228 : hybridVentMgr.TimeVentDuration = 0.0;
4582 : }
4583 42599 : if (hybridVentMgr.MinVentTime > 0.0) {
4584 2697 : if (hybridVentMgr.VentilationCtrl == HybridVentCtrl_Open) {
4585 91 : hybridVentMgr.TimeVentDuration +=
4586 91 : (state.dataSystemAvailabilityManager->CurrentEndTime - state.dataSystemAvailabilityManager->CurrentEndTimeLast) * 60.0;
4587 91 : hybridVentMgr.TimeOperDuration = 0.0;
4588 : }
4589 : }
4590 42599 : if (hybridVentMgr.MinOperTime > 0.0) {
4591 2697 : if (hybridVentMgr.VentilationCtrl == HybridVentCtrl_Close) {
4592 1037 : hybridVentMgr.TimeOperDuration +=
4593 1037 : (state.dataSystemAvailabilityManager->CurrentEndTime - state.dataSystemAvailabilityManager->CurrentEndTimeLast) * 60.0;
4594 1037 : hybridVentMgr.TimeVentDuration = 0.0;
4595 : }
4596 : }
4597 : }
4598 : }
4599 42093 : state.dataSystemAvailabilityManager->TimeStepSysLast = state.dataHVACGlobal->TimeStepSys;
4600 42093 : state.dataSystemAvailabilityManager->CurrentEndTimeLast = state.dataSystemAvailabilityManager->CurrentEndTime;
4601 42093 : }
4602 :
4603 36870 : void CalcHybridVentSysAvailMgr(EnergyPlusData &state,
4604 : int const SysAvailNum, // number of the current scheduled system availability manager
4605 : Optional_int_const PriAirSysNum // number of the primary air system affected by this Avail. Manager
4606 : )
4607 : {
4608 :
4609 : // SUBROUTINE INFORMATION:
4610 : // AUTHOR Lixing Gu
4611 : // DATE WRITTEN March 2007
4612 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
4613 : // RE-ENGINEERED na
4614 :
4615 : // PURPOSE OF THIS SUBROUTINE:
4616 : // Set AvailStatus indicator for a primary air loop and AirflowNetwork model to prevent
4617 : // windows or doors open during HVAC system operation
4618 :
4619 : // METHODOLOGY EMPLOYED:
4620 : // Looks at outside and indoor conditions to determine if hybrid ventilation
4621 : // is beneficial. If it is and it is scheduled on the AvailStatus is set to cycle
4622 : // on and open windows or doors.
4623 :
4624 : using namespace DataAirLoop;
4625 : using Curve::CurveValue;
4626 : using DataZoneEquipment::NumValidSysAvailZoneComponents;
4627 : using Psychrometrics::PsyHFnTdbW;
4628 : using Psychrometrics::PsyRhFnTdbWPb;
4629 : using Psychrometrics::PsyTdpFnWPb;
4630 : using Psychrometrics::PsyWFnTdbRhPb;
4631 :
4632 : int HStatZoneNum; // Humidity control zone number
4633 : Real64 ZoneAirEnthalpy; // Zone air enthalpy
4634 : Real64 ZoneAirDewPoint; // Zone air dew point temperature
4635 : Real64 ZoneAirRH; // Zone air relative humidity
4636 : Real64 TempExt; // Outdoor dry bulb temperature at zone height
4637 : Real64 WindExt; // Outdoor wind speed at zone height
4638 : Real64 WSetPoint; // Humidity ratio setpoint from a given RH setpoint schedule
4639 : Real64 OASetPoint; // Outdoor air setpoint from a given OA setpoint schedule
4640 : Real64 ACH; // Zone air change per hour
4641 : bool found; // Used for humidistat object
4642 : bool HybridVentModeOA; // USed to check whether HybridVentModeOA is allowed
4643 : Real64 ZoneRHHumidifyingSetPoint; // Zone humidifying setpoint (%)
4644 : Real64 ZoneRHDehumidifyingSetPoint; // Zone dehumidifying setpoint (%)
4645 : int SimpleControlType; // Simple control type from a schedule: 0 individual, 1 global
4646 : int i; // Array index
4647 : Real64 minAdaTem; // minimum adaptive temperature for adaptive temperature control
4648 : Real64 maxAdaTem; // maximum adaptive temperature for adaptive temperature control
4649 : bool KeepStatus; // true, if minimum time operation is needed
4650 : int ZoneEquipType;
4651 : int ZoneCompNum;
4652 : int AirLoopNum;
4653 : int Num;
4654 : int AvailStatus;
4655 :
4656 36870 : KeepStatus = false;
4657 36870 : auto &hybridVentMgr = state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum);
4658 36870 : if (hybridVentMgr.TimeVentDuration > 0.0 && hybridVentMgr.TimeVentDuration <= hybridVentMgr.MinVentTime) {
4659 92 : KeepStatus = true;
4660 : }
4661 36870 : if (hybridVentMgr.TimeOperDuration > 0.0 && hybridVentMgr.TimeOperDuration <= hybridVentMgr.MinOperTime) {
4662 146 : KeepStatus = true;
4663 : }
4664 :
4665 36870 : int ZoneNum = hybridVentMgr.ControlledZoneNum;
4666 36870 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
4667 36870 : if (!KeepStatus) hybridVentMgr.VentilationCtrl = HybridVentCtrl_NoAction;
4668 36870 : TempExt = state.dataHeatBal->Zone(ZoneNum).OutDryBulbTemp;
4669 36870 : WindExt = state.dataHeatBal->Zone(ZoneNum).WindSpeed;
4670 36870 : hybridVentMgr.OperativeTemp = 0.0;
4671 36870 : hybridVentMgr.minAdaTem = 0.0;
4672 36870 : hybridVentMgr.maxAdaTem = 0.0;
4673 :
4674 36870 : if (!KeepStatus) {
4675 36632 : switch (hybridVentMgr.ControlMode) {
4676 :
4677 9372 : case HybridVentMode_No: {
4678 9372 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_NoAction;
4679 :
4680 : // Temperature control
4681 9372 : } break;
4682 21395 : case HybridVentMode_Temp: {
4683 21395 : if (TempExt >= hybridVentMgr.MinOutdoorTemp && TempExt <= hybridVentMgr.MaxOutdoorTemp) {
4684 14216 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Open;
4685 : } else {
4686 7179 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4687 : }
4688 :
4689 : // Enthalpy control
4690 21395 : } break;
4691 323 : case HybridVentMode_Enth: {
4692 323 : ZoneAirEnthalpy = PsyHFnTdbW(thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat);
4693 323 : if (state.dataEnvrn->OutEnthalpy >= hybridVentMgr.MinOutdoorEnth && state.dataEnvrn->OutEnthalpy <= hybridVentMgr.MaxOutdoorEnth) {
4694 0 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Open;
4695 : } else {
4696 323 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4697 : }
4698 :
4699 : // Dew point control
4700 323 : } break;
4701 94 : case HybridVentMode_DewPoint: {
4702 146 : if (state.dataEnvrn->OutDewPointTemp >= hybridVentMgr.MinOutdoorDewPoint &&
4703 52 : state.dataEnvrn->OutDewPointTemp <= hybridVentMgr.MaxOutdoorDewPoint) {
4704 52 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Open;
4705 : } else {
4706 42 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4707 : }
4708 :
4709 94 : } break;
4710 4609 : case HybridVentMode_OA: {
4711 4609 : OASetPoint = GetCurrentScheduleValue(state, hybridVentMgr.MinOASchedPtr);
4712 4609 : ACH = 0.0;
4713 4609 : HybridVentModeOA = true;
4714 4609 : if (!hybridVentMgr.HybridVentMgrConnectedToAirLoop) {
4715 3905 : if (state.afn->simulation_control.type == AirflowNetwork::ControlType::NoMultizoneOrDistribution) {
4716 0 : HybridVentModeOA = false;
4717 : }
4718 : }
4719 :
4720 4609 : if (hybridVentMgr.ANControlTypeSchedPtr > 0 && HybridVentModeOA) {
4721 3905 : state.afn->manage_balance(true);
4722 3905 : ACH = state.afn->zone_OA_change_rate(ZoneNum);
4723 : }
4724 4609 : if (ACH > OASetPoint) {
4725 964 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Open;
4726 : } else {
4727 3645 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4728 : }
4729 :
4730 4609 : } break;
4731 341 : case HybridVentMode_OperT80: {
4732 341 : if (state.dataThermalComforts->runningAverageASH >= 10.0 && state.dataThermalComforts->runningAverageASH <= 33.5) {
4733 299 : hybridVentMgr.OperativeTemp = 0.5 * (thisZoneHB.MAT + state.dataHeatBal->ZoneMRT(ZoneNum));
4734 299 : minAdaTem = 0.31 * state.dataThermalComforts->runningAverageASH + 14.3;
4735 299 : maxAdaTem = 0.31 * state.dataThermalComforts->runningAverageASH + 21.3;
4736 299 : hybridVentMgr.minAdaTem = minAdaTem;
4737 299 : hybridVentMgr.maxAdaTem = maxAdaTem;
4738 299 : if (hybridVentMgr.OperativeTemp <= maxAdaTem && hybridVentMgr.OperativeTemp >= minAdaTem) {
4739 232 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Open;
4740 : } else {
4741 67 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4742 : }
4743 : } else {
4744 42 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4745 : }
4746 :
4747 341 : } break;
4748 361 : case HybridVentMode_OperT90: {
4749 361 : if (state.dataThermalComforts->runningAverageASH >= 10.0 && state.dataThermalComforts->runningAverageASH <= 33.5) {
4750 319 : hybridVentMgr.OperativeTemp = 0.5 * (thisZoneHB.MAT + state.dataHeatBal->ZoneMRT(ZoneNum));
4751 319 : minAdaTem = 0.31 * state.dataThermalComforts->runningAverageASH + 15.3;
4752 319 : maxAdaTem = 0.31 * state.dataThermalComforts->runningAverageASH + 20.3;
4753 319 : hybridVentMgr.minAdaTem = minAdaTem;
4754 319 : hybridVentMgr.maxAdaTem = maxAdaTem;
4755 319 : if (hybridVentMgr.OperativeTemp <= maxAdaTem && hybridVentMgr.OperativeTemp >= minAdaTem) {
4756 216 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Open;
4757 : } else {
4758 103 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4759 : }
4760 : } else {
4761 42 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4762 : }
4763 :
4764 361 : } break;
4765 137 : case HybridVentMode_CO2: {
4766 137 : hybridVentMgr.CO2 = state.dataContaminantBalance->ZoneAirCO2(ZoneNum);
4767 137 : if (state.dataContaminantBalance->ZoneAirCO2(ZoneNum) > state.dataContaminantBalance->ZoneCO2SetPoint(ZoneNum)) {
4768 95 : if (hybridVentMgr.HybridVentMgrConnectedToAirLoop) {
4769 95 : AirLoopNum = hybridVentMgr.AirLoopNum;
4770 190 : for (Num = 1; Num <= state.dataAirLoop->PriAirSysAvailMgr(hybridVentMgr.AirLoopNum).NumAvailManagers; ++Num) {
4771 380 : SimSysAvailManager(state,
4772 95 : state.dataAirLoop->PriAirSysAvailMgr(AirLoopNum).AvailManagerType(Num),
4773 95 : state.dataAirLoop->PriAirSysAvailMgr(AirLoopNum).AvailManagerName(Num),
4774 95 : state.dataAirLoop->PriAirSysAvailMgr(AirLoopNum).AvailManagerNum(Num),
4775 : AirLoopNum,
4776 95 : state.dataAirLoop->PriAirSysAvailMgr(AirLoopNum).AvailStatus,
4777 : AvailStatus);
4778 : }
4779 95 : if (AvailStatus == CycleOn) {
4780 95 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4781 : } else {
4782 0 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Open;
4783 : }
4784 0 : } else if (hybridVentMgr.SimHybridVentSysAvailMgr) {
4785 0 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Open;
4786 0 : for (ZoneEquipType = 1; ZoneEquipType <= NumValidSysAvailZoneComponents; ++ZoneEquipType) {
4787 0 : for (ZoneCompNum = 1; ZoneCompNum <= state.dataHVACGlobal->ZoneComp(ZoneEquipType).TotalNumComp; ++ZoneCompNum) {
4788 0 : if (state.dataHVACGlobal->ZoneComp(ZoneEquipType).ZoneCompAvailMgrs(ZoneCompNum).AvailStatus == CycleOn) {
4789 0 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4790 0 : break;
4791 : }
4792 : }
4793 : }
4794 : } else {
4795 0 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Open;
4796 : }
4797 : }
4798 137 : } break;
4799 0 : default: {
4800 0 : ShowSevereError(state,
4801 0 : format("{}: incorrect Control Type: {}",
4802 0 : SystemAvailabilityTypeNamesUC[static_cast<int>(hybridVentMgr.MgrType)],
4803 0 : hybridVentMgr.AirLoopName));
4804 0 : ShowFatalError(
4805 : state,
4806 0 : format("Errors found in getting {} Control mode value", SystemAvailabilityTypeNamesUC[static_cast<int>(hybridVentMgr.MgrType)]));
4807 : }
4808 : }
4809 :
4810 36632 : if (hybridVentMgr.VentilationCtrl == HybridVentCtrl_Open) {
4811 :
4812 : // Temperature and enthalpy control
4813 15680 : if (hybridVentMgr.ControlMode == HybridVentMode_Temp || hybridVentMgr.ControlMode == HybridVentMode_Enth) {
4814 :
4815 14216 : switch (state.dataHeatBalFanSys->TempControlType(ZoneNum)) {
4816 :
4817 0 : case DataHVACGlobals::ThermostatType::SingleHeating: {
4818 0 : if (thisZoneHB.MAT < state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum)) {
4819 0 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4820 : }
4821 :
4822 0 : } break;
4823 2076 : case DataHVACGlobals::ThermostatType::SingleCooling: {
4824 2076 : if (thisZoneHB.MAT > state.dataHeatBalFanSys->TempZoneThermostatSetPoint(ZoneNum)) {
4825 1703 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4826 : }
4827 :
4828 2076 : } break;
4829 0 : case DataHVACGlobals::ThermostatType::SingleHeatCool: {
4830 0 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4831 0 : ++hybridVentMgr.SingleHCErrCount;
4832 0 : if (hybridVentMgr.SingleHCErrCount < 2) {
4833 0 : ShowWarningError(state,
4834 0 : "Hybrid ventilation control: " + hybridVentMgr.AirLoopName +
4835 : ": The zone temperature control type is ThermostatSetpoint:SingleHeatingOrCooling. Natural "
4836 : "ventilation is not allowed.");
4837 0 : ShowContinueErrorTimeStamp(state, "");
4838 : } else {
4839 0 : ShowRecurringWarningErrorAtEnd(
4840 : state,
4841 0 : "Hybrid ventilation control: " + hybridVentMgr.AirLoopName +
4842 : ": No natural ventilation continues with a ThermostatSetpoint:SingleHeatingOrCooling type...",
4843 : hybridVentMgr.SingleHCErrIndex,
4844 0 : double(hybridVentMgr.ControlMode),
4845 0 : double(hybridVentMgr.ControlMode));
4846 : }
4847 :
4848 0 : } break;
4849 12140 : case DataHVACGlobals::ThermostatType::DualSetPointWithDeadBand: {
4850 24275 : if ((thisZoneHB.MAT < state.dataHeatBalFanSys->ZoneThermostatSetPointLo(ZoneNum)) ||
4851 12135 : (thisZoneHB.MAT > state.dataHeatBalFanSys->ZoneThermostatSetPointHi(ZoneNum))) {
4852 8371 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4853 : }
4854 :
4855 12140 : } break;
4856 0 : default:
4857 0 : break;
4858 : } // end select on thermostat control
4859 : }
4860 :
4861 : // Dew point control mode
4862 15680 : if (hybridVentMgr.ControlMode == HybridVentMode_DewPoint) {
4863 52 : ZoneAirRH = PsyRhFnTdbWPb(state, thisZoneHB.MAT, thisZoneHB.ZoneAirHumRat, state.dataEnvrn->OutBaroPress) * 100.0;
4864 52 : ZoneAirDewPoint = PsyTdpFnWPb(state, thisZoneHB.ZoneAirHumRat, state.dataEnvrn->OutBaroPress);
4865 52 : if (state.dataZoneCtrls->NumHumidityControlZones == 0) {
4866 0 : ++hybridVentMgr.DewPointNoRHErrCount;
4867 0 : if (hybridVentMgr.DewPointNoRHErrCount < 2) {
4868 0 : ShowWarningError(state,
4869 0 : "Hybrid ventilation control: Dew point control mode is selected, but no ZoneControl:Humidistat object=" +
4870 : hybridVentMgr.AirLoopName);
4871 0 : ShowContinueError(state, "The hybrid ventilation control is triggered by outdoor min and max dewpoint only.");
4872 0 : ShowContinueError(state, "HVAC system may turn off when outdoor dewpoint is between min and max dewpoint.");
4873 0 : ShowContinueErrorTimeStamp(state, "");
4874 : } else {
4875 0 : ShowRecurringWarningErrorAtEnd(state,
4876 0 : "Hybrid ventilation control: " + hybridVentMgr.AirLoopName +
4877 : ": no ZoneControl:Humidistat object continues...",
4878 : hybridVentMgr.DewPointNoRHErrIndex,
4879 0 : double(hybridVentMgr.ControlMode),
4880 0 : double(hybridVentMgr.ControlMode));
4881 : }
4882 : }
4883 52 : found = false;
4884 104 : for (HStatZoneNum = 1; HStatZoneNum <= state.dataZoneCtrls->NumHumidityControlZones; ++HStatZoneNum) {
4885 52 : if (state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).ActualZoneNum == ZoneNum) {
4886 52 : found = true;
4887 52 : ZoneRHHumidifyingSetPoint =
4888 52 : GetCurrentScheduleValue(state, state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).HumidifyingSchedIndex);
4889 52 : ZoneRHDehumidifyingSetPoint =
4890 52 : GetCurrentScheduleValue(state, state.dataZoneCtrls->HumidityControlZone(HStatZoneNum).DehumidifyingSchedIndex);
4891 52 : if (ZoneAirRH > ZoneRHDehumidifyingSetPoint) { // Need dehumidification
4892 0 : WSetPoint =
4893 0 : PsyWFnTdbRhPb(state, thisZoneHB.MAT, (ZoneRHDehumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress);
4894 0 : if (WSetPoint < state.dataEnvrn->OutHumRat) hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4895 52 : } else if (ZoneAirRH < ZoneRHHumidifyingSetPoint) { // Need humidification
4896 52 : WSetPoint = PsyWFnTdbRhPb(state, thisZoneHB.MAT, (ZoneRHHumidifyingSetPoint / 100.0), state.dataEnvrn->OutBaroPress);
4897 52 : if (WSetPoint > state.dataEnvrn->OutHumRat) hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4898 : } else {
4899 0 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4900 : }
4901 : }
4902 : }
4903 52 : if (!found && state.dataZoneCtrls->NumHumidityControlZones > 0) {
4904 0 : ++hybridVentMgr.DewPointErrCount;
4905 0 : if (hybridVentMgr.DewPointErrCount < 2) {
4906 0 : ShowWarningError(state,
4907 : "Hybrid ventilation control: The zone for dew point control mode is different from the zone for "
4908 0 : "ZoneControl:Humidistat=" +
4909 : hybridVentMgr.AirLoopName);
4910 0 : ShowContinueError(
4911 0 : state, "The Zone name for hybrid control is " + state.dataHeatBal->Zone(ZoneNum).Name + ". Humidistat has no impact");
4912 0 : ShowContinueError(state, "HVAC system may turn off when outdoor dewpoint is between min and max dewpoint.");
4913 0 : ShowContinueErrorTimeStamp(state, "");
4914 : } else {
4915 0 : ShowRecurringWarningErrorAtEnd(state,
4916 0 : "Hybrid ventilation control: " + hybridVentMgr.AirLoopName +
4917 : " No humidistat control impact continues...",
4918 : hybridVentMgr.DewPointErrIndex,
4919 0 : double(hybridVentMgr.ControlMode),
4920 0 : double(hybridVentMgr.ControlMode));
4921 : }
4922 : }
4923 : }
4924 :
4925 : // Outdoor ventilation air control mode
4926 15680 : if (hybridVentMgr.ControlMode == HybridVentMode_OA) {
4927 : }
4928 : }
4929 : }
4930 :
4931 36870 : if (WindExt > hybridVentMgr.MaxWindSpeed) {
4932 0 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4933 : }
4934 :
4935 36870 : if (state.dataEnvrn->IsRain && hybridVentMgr.UseRainIndicator) {
4936 0 : hybridVentMgr.VentilationCtrl = HybridVentCtrl_Close;
4937 : }
4938 : // Sent a signal to the AirflowNetwork to ensure large onpenings are close or open based on this logic
4939 36870 : state.dataHVACGlobal->HybridVentSysAvailVentCtrl(SysAvailNum) = hybridVentMgr.VentilationCtrl;
4940 36870 : if (state.dataHVACGlobal->HybridVentSysAvailVentCtrl(SysAvailNum) < 0) {
4941 : // Fatal error
4942 0 : ShowFatalError(state,
4943 : "Hybrid ventilation control: the ventilation control status is beyond the range. Please check input of control "
4944 : "mode schedule");
4945 : }
4946 :
4947 36870 : if (hybridVentMgr.HybridVentMgrConnectedToAirLoop) {
4948 29532 : if (hybridVentMgr.VentilationCtrl == HybridVentCtrl_Close) {
4949 16450 : state.dataAirLoop->PriAirSysAvailMgr(PriAirSysNum).AvailStatus = CycleOn;
4950 : }
4951 : }
4952 :
4953 36870 : if (hybridVentMgr.VentilationCtrl == HybridVentCtrl_Open && hybridVentMgr.ANControlTypeSchedPtr > 0 && hybridVentMgr.OpeningFactorFWS > 0) {
4954 2848 : state.dataHVACGlobal->HybridVentSysAvailWindModifier(SysAvailNum) = CurveValue(state, hybridVentMgr.OpeningFactorFWS, WindExt);
4955 : }
4956 :
4957 : // Set up flags to control simple airflow objects
4958 36870 : if (hybridVentMgr.AirLoopNum > 0 && hybridVentMgr.SimpleControlTypeSchedPtr > 0) {
4959 5179 : SimpleControlType = GetCurrentScheduleValue(state, hybridVentMgr.SimpleControlTypeSchedPtr);
4960 25895 : for (int ControlledZoneNum = 1; ControlledZoneNum <= state.dataGlobal->NumOfZones; ++ControlledZoneNum) {
4961 36253 : for (int zoneInNode = 1; zoneInNode <= state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).NumInletNodes; ++zoneInNode) {
4962 15537 : if (hybridVentMgr.AirLoopNum == state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).InletNodeAirLoopNum(zoneInNode)) {
4963 : // Setup flag for ventilation objects
4964 62148 : for (i = 1; i <= state.dataHeatBal->TotVentilation; ++i) {
4965 46611 : if (state.dataHeatBal->Ventilation(i).ZonePtr == ControlledZoneNum) {
4966 15537 : state.dataHeatBal->Ventilation(i).HybridControlType = DataHeatBalance::HybridCtrlType::Indiv;
4967 15537 : if (hybridVentMgr.VentilationCtrl == HybridVentCtrl_Close) {
4968 12972 : state.dataHeatBal->Ventilation(i).HybridControlType = DataHeatBalance::HybridCtrlType::Close;
4969 : } else {
4970 2565 : if (SimpleControlType == 1) {
4971 1800 : state.dataHeatBal->Ventilation(i).HybridControlType = DataHeatBalance::HybridCtrlType::Global;
4972 1800 : state.dataHeatBal->Ventilation(i).HybridControlMasterNum = hybridVentMgr.VentilationPtr;
4973 : }
4974 : }
4975 : }
4976 : }
4977 : // Setup flag for Mixing objects
4978 46611 : for (i = 1; i <= state.dataHeatBal->TotMixing; ++i) {
4979 31074 : if (state.dataHeatBal->Mixing(i).ZonePtr == ControlledZoneNum) {
4980 10358 : state.dataHeatBal->Mixing(i).HybridControlType = DataHeatBalance::HybridCtrlType::Indiv;
4981 10358 : if (hybridVentMgr.VentilationCtrl == HybridVentCtrl_Close) {
4982 8648 : state.dataHeatBal->Mixing(i).HybridControlType = DataHeatBalance::HybridCtrlType::Close;
4983 : } else {
4984 1710 : if (SimpleControlType == 1) {
4985 1200 : state.dataHeatBal->Mixing(i).HybridControlType = DataHeatBalance::HybridCtrlType::Global;
4986 1200 : state.dataHeatBal->Mixing(i).HybridControlMasterNum = hybridVentMgr.VentilationPtr;
4987 : }
4988 : }
4989 : }
4990 : }
4991 : }
4992 : }
4993 5179 : }
4994 31691 : } else if (hybridVentMgr.SimpleControlTypeSchedPtr > 0) {
4995 3433 : SimpleControlType = GetCurrentScheduleValue(state, hybridVentMgr.SimpleControlTypeSchedPtr);
4996 : // Hybrid ventilation manager is applied to zone component
4997 : // setup flag for ventilation objects
4998 6866 : for (i = 1; i <= state.dataHeatBal->TotVentilation; ++i) {
4999 3433 : if (state.dataHeatBal->Ventilation(i).ZonePtr == hybridVentMgr.ControlledZoneNum) {
5000 3433 : state.dataHeatBal->Ventilation(i).HybridControlType = DataHeatBalance::HybridCtrlType::Indiv;
5001 3433 : if (hybridVentMgr.VentilationCtrl == HybridVentCtrl_Close) {
5002 2419 : state.dataHeatBal->Ventilation(i).HybridControlType = DataHeatBalance::HybridCtrlType::Close;
5003 : } else {
5004 1014 : if (SimpleControlType == 1) {
5005 857 : state.dataHeatBal->Ventilation(i).HybridControlType = DataHeatBalance::HybridCtrlType::Global;
5006 857 : state.dataHeatBal->Ventilation(i).HybridControlMasterNum = hybridVentMgr.VentilationPtr;
5007 : }
5008 : }
5009 : }
5010 : }
5011 : // Setup flag for Mixing objects
5012 6866 : for (i = 1; i <= state.dataHeatBal->TotMixing; ++i) {
5013 3433 : if (state.dataHeatBal->Mixing(i).ZonePtr == hybridVentMgr.ControlledZoneNum) {
5014 3433 : state.dataHeatBal->Mixing(i).HybridControlType = DataHeatBalance::HybridCtrlType::Indiv;
5015 3433 : if (hybridVentMgr.VentilationCtrl == HybridVentCtrl_Close) {
5016 2419 : state.dataHeatBal->Mixing(i).HybridControlType = DataHeatBalance::HybridCtrlType::Close;
5017 : } else {
5018 1014 : if (SimpleControlType == 1) {
5019 857 : state.dataHeatBal->Mixing(i).HybridControlType = DataHeatBalance::HybridCtrlType::Global;
5020 857 : state.dataHeatBal->Mixing(i).HybridControlMasterNum = hybridVentMgr.VentilationPtr;
5021 : }
5022 : }
5023 : }
5024 : }
5025 : }
5026 36870 : }
5027 :
5028 1 : bool GetHybridVentilationControlStatus(EnergyPlusData &state, int const ZoneNum) // Index of zone
5029 : {
5030 :
5031 : // SUBROUTINE INFORMATION:
5032 : // AUTHOR Lixing Gu
5033 : // DATE WRITTEN July 2010
5034 : // MODIFIED na
5035 : // RE-ENGINEERED na
5036 :
5037 : // PURPOSE OF THIS SUBROUTINE:
5038 : // This routine was designed to find whether this zone is controlled by hybrid ventilation
5039 : // ventilation control option.
5040 :
5041 : // Return value
5042 : bool VentControl; // Set to true if ventilation control in the same zone
5043 :
5044 : int SysAvailNum; // index to system availability manager number
5045 :
5046 1 : if (state.dataSystemAvailabilityManager->GetHybridInputFlag) { // First time subroutine has been entered
5047 1 : GetHybridVentilationInputs(state);
5048 1 : state.dataSystemAvailabilityManager->GetHybridInputFlag = false;
5049 : }
5050 :
5051 1 : VentControl = false;
5052 :
5053 1 : for (SysAvailNum = 1; SysAvailNum <= state.dataHVACGlobal->NumHybridVentSysAvailMgrs; ++SysAvailNum) {
5054 0 : if (state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).ControlledZoneNum == ZoneNum) {
5055 0 : if (state.dataSystemAvailabilityManager->HybridVentData(SysAvailNum).SimpleControlTypeSchedPtr > 0) {
5056 0 : VentControl = true;
5057 : }
5058 : }
5059 : }
5060 :
5061 1 : return VentControl;
5062 : }
5063 :
5064 : } // namespace SystemAvailabilityManager
5065 :
5066 2313 : } // namespace EnergyPlus
|