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 : #ifndef HVACControllers_hh_INCLUDED
49 : #define HVACControllers_hh_INCLUDED
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array1D.hh>
53 : #include <ObjexxFCL/Optional.hh>
54 :
55 : // EnergyPlus Headers
56 : #include <EnergyPlus/Data/BaseData.hh>
57 : #include <EnergyPlus/DataAirSystems.hh>
58 : #include <EnergyPlus/DataGlobals.hh>
59 : #include <EnergyPlus/DataHVACControllers.hh>
60 : #include <EnergyPlus/DataRootFinder.hh>
61 : #include <EnergyPlus/EnergyPlus.hh>
62 : #include <EnergyPlus/SetPointManager.hh>
63 :
64 : namespace EnergyPlus {
65 :
66 : // Forward declarations
67 : struct EnergyPlusData;
68 :
69 : namespace HVACControllers {
70 :
71 : // Using/Aliasing
72 : using DataAirSystems::DefinePrimaryAirSystem;
73 : using DataHVACControllers::ControllerAction;
74 : using DataHVACControllers::ControllerMode;
75 : using DataHVACControllers::ControllerSimple_Type;
76 : using DataHVACControllers::iFirstMode;
77 : using DataHVACControllers::iLastMode;
78 : using DataRootFinder::RootFinderDataType;
79 :
80 : // Parameters for controls used here
81 : enum class CtrlVarType
82 : {
83 : Invalid = -1,
84 : NoControlVariable,
85 : Temperature,
86 : HumidityRatio,
87 : TemperatureAndHumidityRatio,
88 : Flow,
89 : Num
90 : };
91 :
92 285 : struct SolutionTrackerType
93 : {
94 : bool DefinedFlag = true; // Flag set to TRUE when tracker is up-to-date. FALSE otherwise.
95 : Real64 ActuatedValue = 0.0; // Actuated value
96 : ControllerMode Mode = ControllerMode::None; // Operational model of controller
97 : };
98 :
99 1929 : struct ControllerPropsType
100 : {
101 : // Members
102 : std::string ControllerName; // Name of the Controller
103 : std::string ControllerType; // Type of Controller
104 : int ControllerType_Num;
105 : CtrlVarType ControlVar; // The type of control variable being sensed
106 : CtrlVarType ActuatorVar; // The variable that the controller will act on ie. flow
107 : ControllerAction Action; // Controller Action - Reverse or Normal
108 : // Controller must be initialized to set MinActuated and MaxActuated
109 : bool InitFirstPass;
110 : // --------------------
111 : // Internal data used for optimal restart across successive calls to SimAirLoop()
112 : // --------------------
113 : int NumCalcCalls; // Number of Calc() calls since last call to Reset()
114 : ControllerMode Mode; // Operational model of controller at current iteration
115 : // Flag indicating whether the current controller simulation was performed from a cold start
116 : // or following a speculative warm restart. Set in the ResetController() routine.
117 : // Used in the CheckController() routine.
118 : bool DoWarmRestartFlag;
119 : // Flag used to decide whether or not it is allowed to reuse the intermediate solution from
120 : // solving the previous controller on the air loop (COLD_START mode only) as the initial guess for
121 : // the current controller.
122 : bool ReuseIntermediateSolutionFlag;
123 : // Flag used to decide whether or not it is possible to reuse the solution from
124 : // the last call to SimAirLoop() as a possible candidate.
125 : bool ReusePreviousSolutionFlag;
126 : // Array of solution trackers. Saved at last call to SimAirLoop() in ManageControllers(iControllerOpEnd)
127 : // The first tracker is used to track the solution when FirstHVACIteration is TRUE.
128 : // The second tracker is used to track the solution at FirstHVACIteration is FALSE.
129 : Array1D<SolutionTrackerType> SolutionTrackers;
130 : // --------------------
131 : // Operational limits at min/max avail values for actuated variable and the corresponding sensed values
132 : // --------------------
133 : Real64 MaxAvailActuated; // kg/s, The maximum actuated variable currently available.
134 : // Reset by simulation at each HVAC iteration
135 : Real64 MaxAvailSensed; // Sensed value at maximum available actuated variable
136 : Real64 MinAvailActuated; // kg/s, The minimum actuated variable currently available.
137 : // Reset by simulation at each HVAC iteration
138 : Real64 MinAvailSensed; // Sensed value at maximum available actuated variable
139 : // --------------------
140 : // User input min/max values for actuated variable
141 : // --------------------
142 : Real64 MaxVolFlowActuated; // m3/s, From User input the Max amount for the actuated variable
143 : Real64 MinVolFlowActuated; // m3/s, From User input the Min amount for the actuated variable
144 : Real64 MaxActuated; // kg/s, From User input the Max amount for the actuated variable
145 : Real64 MinActuated; // kg/s, From User input the Min amount for the actuated variable
146 : // --------------------
147 : // Actuated variable
148 : // --------------------
149 : int ActuatedNode; // The node that is acted upon by the controller
150 : Real64 ActuatedValue; // Value of actuated variable before change by the controller
151 : Real64 NextActuatedValue; // The new control actuated value
152 : PlantLocation ActuatedNodePlantLoc; // Location for actuated node
153 : // --------------------
154 : // Sensed variable
155 : // --------------------
156 : int SensedNode; // The sensed node number from the grid
157 : bool IsSetPointDefinedFlag; // If TRUE indicates that the setpoint has been defined and can
158 : // be used to compute DeltaSensed
159 : Real64 SetPointValue; // Desired setpoint; set in the SetPoint Manager or computed in Init() routine
160 : Real64 SensedValue; // The sensed control variable of any type
161 : Real64 DeltaSensed; // Difference of sensed to setpoint value for calculating proportional gain
162 : Real64 Offset; // This is the tolerance or droop from the error
163 : SetPointManager::CtrlVarType HumRatCntrlType; // iCtrlVarType_HumRat=4,iCtrlVarType_MaxHumRat=5,iCtrlVarType_MinHumRat=6
164 : // --------------------
165 : // Other controller inputs, not yet used
166 : // --------------------
167 : std::string LimitType; // Limit type as in HIGH or LOW
168 : Real64 Range; // The range or hysteresis of the control limit
169 : Real64 Limit; // The Limit value for a Limit Controller
170 : // --------------------
171 : // Trace mechanism
172 : // --------------------
173 : SharedFileHandle TraceFile;
174 : bool FirstTraceFlag; // To detect first individual write operation to individual controller trace file
175 : int BadActionErrCount; // Counts number of incorrect action errors
176 : int BadActionErrIndex; // index to recurring error structure for bad action error
177 : // Fault model for water coil supply air temperature sensor offset
178 : bool FaultyCoilSATFlag; // True if the coil has SAT sensor fault
179 : int FaultyCoilSATIndex; // Index of the fault object corresponding to the coil
180 : Real64 FaultyCoilSATOffset; // Coil SAT sensor offset
181 : bool BypassControllerCalc; // set true for OA sys water coils
182 : int AirLoopControllerIndex; // index to controller on specific air loop
183 :
184 : bool HumRatCtrlOverride; // true if TemperatureAndHumidityRatio control switches to humidity ratio control
185 :
186 : // Default Constructor
187 285 : ControllerPropsType()
188 285 : : ControllerType_Num(ControllerSimple_Type), ControlVar(CtrlVarType::NoControlVariable), ActuatorVar(CtrlVarType::NoControlVariable),
189 : Action(ControllerAction::NoAction), InitFirstPass(true), NumCalcCalls(0), Mode(ControllerMode::None), DoWarmRestartFlag(false),
190 : ReuseIntermediateSolutionFlag(false), ReusePreviousSolutionFlag(false), SolutionTrackers(2), MaxAvailActuated(0.0), MaxAvailSensed(0.0),
191 : MinAvailActuated(0.0), MinAvailSensed(0.0), MaxVolFlowActuated(0.0), MinVolFlowActuated(0.0), MaxActuated(0.0), MinActuated(0.0),
192 : ActuatedNode(0), ActuatedValue(0.0), NextActuatedValue(0.0), ActuatedNodePlantLoc{}, SensedNode(0), IsSetPointDefinedFlag(false),
193 : SetPointValue(0.0), SensedValue(0.0), DeltaSensed(0.0), Offset(0.0), HumRatCntrlType(SetPointManager::CtrlVarType::Invalid), Range(0.0),
194 : Limit(0.0), FirstTraceFlag(true), BadActionErrCount(0), BadActionErrIndex(0), FaultyCoilSATFlag(false), FaultyCoilSATIndex(0),
195 285 : FaultyCoilSATOffset(0.0), BypassControllerCalc(false), AirLoopControllerIndex(0), HumRatCtrlOverride(false)
196 : {
197 285 : }
198 : };
199 :
200 0 : struct ControllerStatsType
201 : {
202 : // Members
203 : Array1D_int NumCalls; // Number of times this controller operated in each mode
204 : Array1D_int TotIterations; // Total number of iterations required to solve this controller
205 : Array1D_int MaxIterations; // Maximum number of iterations required to solve this controller
206 :
207 : // Default Constructor
208 0 : ControllerStatsType()
209 0 : : NumCalls({iFirstMode, iLastMode}, 0), TotIterations({iFirstMode, iLastMode}, 0), MaxIterations({iFirstMode, iLastMode}, 0)
210 : {
211 0 : }
212 : };
213 :
214 0 : struct AirLoopStatsType
215 : {
216 : // Shared_ptr because we need to put this into an Array1D which is not friendly with move-only types
217 : SharedFileHandle TraceFile;
218 : // Used only if > 0. Same size as NumPrimaryAirSys
219 : bool FirstTraceFlag = true; // To detect first trace to air loop trace file
220 : int NumCalls = 0; // Number of times air loop is simulated (number of calls to SimAirLoop)
221 : int NumFailedWarmRestarts = 0; // Number of times speculative warm restart was attempted and failed
222 : int NumSuccessfulWarmRestarts = 0; // Number of times speculative warm restart was attempted and succeeded
223 : int TotSimAirLoopComponents = 0; // Total number of times the SimAirLoopComponents() routine has been invoked
224 : int MaxSimAirLoopComponents = 0; // Maximum number of times the SimAirLoopComponents() routine has been invoked
225 : int TotIterations = 0; // Total number of iterations required to solve the controllers on this air loop
226 : int MaxIterations = 0; // Maximum number of iterations required to solve the controllers on this air loop
227 : Array1D<ControllerStatsType> ControllerStats; // Array of statistics for each controller on this air loop
228 : };
229 :
230 : void ManageControllers(EnergyPlusData &state,
231 : std::string const &ControllerName,
232 : int &ControllerIndex,
233 : bool FirstHVACIteration,
234 : int AirLoopNum, // unused1208
235 : DataHVACControllers::ControllerOperation Operation,
236 : bool &IsConvergedFlag,
237 : bool &IsUpToDateFlag,
238 : bool &BypassOAController,
239 : Optional_bool AllowWarmRestartFlag = _);
240 :
241 : void GetControllerInput(EnergyPlusData &state);
242 :
243 : void ResetController(EnergyPlusData &state, int ControlNum, bool DoWarmRestartFlag, bool &IsConvergedFlag);
244 :
245 : void InitController(EnergyPlusData &state, int ControlNum, bool &IsConvergedFlag);
246 :
247 : void SizeController(EnergyPlusData &state, int ControlNum);
248 :
249 : void CalcSimpleController(EnergyPlusData &state,
250 : int ControlNum,
251 : bool FirstHVACIteration,
252 : bool &IsConvergedFlag,
253 : bool &IsUpToDateFlag,
254 : std::string const &ControllerName // used when errors occur
255 : );
256 :
257 : void FindRootSimpleController(EnergyPlusData &state,
258 : int ControlNum,
259 : bool FirstHVACIteration,
260 : bool &IsConvergedFlag,
261 : bool &IsUpToDateFlag,
262 : std::string const &ControllerName // used when errors occur
263 : );
264 :
265 : void CheckSimpleController(EnergyPlusData &state, int ControlNum, bool &IsConvergedFlag);
266 :
267 : bool CheckMinActiveController(EnergyPlusData &state, int ControlNum);
268 :
269 : bool CheckMaxActiveController(EnergyPlusData &state, int ControlNum);
270 :
271 : void CheckTempAndHumRatCtrl(EnergyPlusData &state, int ControlNum, bool &IsConvergedFlag);
272 :
273 : void SaveSimpleController(EnergyPlusData &state, int ControlNum, bool FirstHVACIteration, bool IsConvergedFlag);
274 :
275 : void UpdateController(EnergyPlusData &state, int ControlNum);
276 :
277 : void ExitCalcController(
278 : EnergyPlusData &state, int ControlNum, Real64 NextActuatedValue, ControllerMode Mode, bool &IsConvergedFlag, bool &IsUpToDateFlag);
279 :
280 : void TrackAirLoopControllers(EnergyPlusData &state,
281 : int AirLoopNum,
282 : DataHVACControllers::ControllerWarmRestart WarmRestartStatus,
283 : int AirLoopIterMax,
284 : int AirLoopIterTot,
285 : int AirLoopNumCalls);
286 :
287 : void TrackAirLoopController(EnergyPlusData &state,
288 : int AirLoopNum, // Air loop index
289 : int AirLoopControlNum // Controller index on this air loop
290 : );
291 :
292 : void DumpAirLoopStatistics(EnergyPlusData &state);
293 :
294 : void WriteAirLoopStatistics(EnergyPlusData &state,
295 : InputOutputFile &statisticsFile,
296 : DefinePrimaryAirSystem const &ThisPrimaryAirSystem,
297 : AirLoopStatsType const &ThisAirLoopStats);
298 :
299 : void SetupAirLoopControllersTracer(EnergyPlusData &state, int AirLoopNum);
300 :
301 : void TraceAirLoopControllers(
302 : EnergyPlusData &state, bool FirstHVACIteration, int AirLoopNum, int AirLoopPass, bool AirLoopConverged, int AirLoopNumCalls);
303 :
304 : void TraceIterationStamp(
305 : EnergyPlusData &state, InputOutputFile &TraceFile, bool FirstHVACIteration, int AirLoopPass, bool AirLoopConverged, int AirLoopNumCalls);
306 :
307 : void TraceAirLoopController(EnergyPlusData &state, InputOutputFile &TraceFile, int ControlNum);
308 :
309 : void SetupIndividualControllerTracer(EnergyPlusData &state, int ControlNum);
310 :
311 : void TraceIndividualController(EnergyPlusData &state,
312 : int ControlNum,
313 : bool FirstHVACIteration,
314 : int AirLoopPass,
315 : DataHVACControllers::ControllerOperation Operation, // Operation to execute
316 : bool IsConvergedFlag);
317 :
318 : std::string CreateHVACTimeString(EnergyPlusData &state);
319 :
320 : std::string CreateHVACStepFullString(EnergyPlusData &state);
321 :
322 : std::string MakeHVACTimeIntervalString(EnergyPlusData &state);
323 :
324 : void CheckControllerListOrder(EnergyPlusData &state);
325 :
326 : void CheckCoilWaterInletNode(EnergyPlusData &state,
327 : int WaterInletNodeNum, // input actuator node number
328 : bool &NodeNotFound // true if matching actuator node not found, false if found
329 : );
330 :
331 : void GetControllerNameAndIndex(EnergyPlusData &state,
332 : int WaterInletNodeNum, // input actuator node number
333 : std::string &ControllerName, // controller name used by water coil
334 : int &ControllerIndex, // controller index used by water coil
335 : bool &ErrorsFound // true if matching actuator node not found
336 : );
337 :
338 : void GetControllerActuatorNodeNum(EnergyPlusData &state,
339 : std::string const &ControllerName, // name of coil controller
340 : int &WaterInletNodeNum, // input actuator node number
341 : bool &NodeNotFound // true if matching actuator node not found, false if found
342 : );
343 :
344 : int GetControllerIndex(EnergyPlusData &state,
345 : std::string const &ControllerName // name of coil controller
346 : );
347 :
348 : } // namespace HVACControllers
349 :
350 1542 : struct HVACControllersData : BaseGlobalStruct
351 : {
352 : int NumControllers = 0; // The number of controllers found in the Input
353 : int NumAirLoopStats = 0; // Same size as NumPrimaryAirSys if controllers
354 : Array1D_bool CheckEquipName;
355 : bool GetControllerInputFlag = true;
356 : bool InitControllerOneTimeFlag = true;
357 : bool InitControllerSetPointCheckFlag = true;
358 : Array1D<HVACControllers::ControllerPropsType> ControllerProps;
359 : Array1D<HVACControllers::RootFinderDataType> RootFinders;
360 : Array1D<HVACControllers::AirLoopStatsType> AirLoopStats; // Statistics array to analyze computational profile for
361 : Array1D_bool MyEnvrnFlag;
362 : Array1D_bool MySizeFlag;
363 : Array1D_bool MyPlantIndexsFlag;
364 :
365 0 : void clear_state() override
366 : {
367 0 : *this = HVACControllersData();
368 0 : }
369 : };
370 :
371 : } // namespace EnergyPlus
372 :
373 : #endif
|