Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : #ifndef PoweredInductionUnits_hh_INCLUDED
49 : #define PoweredInductionUnits_hh_INCLUDED
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array1D.hh>
53 :
54 : // EnergyPlus Headers
55 : #include <EnergyPlus/Data/BaseData.hh>
56 : #include <EnergyPlus/DataDefineEquip.hh>
57 : #include <EnergyPlus/DataGlobals.hh>
58 : #include <EnergyPlus/EnergyPlus.hh>
59 : #include <EnergyPlus/FluidProperties.hh>
60 : #include <EnergyPlus/Plant/Enums.hh>
61 : #include <EnergyPlus/Plant/PlantLocation.hh>
62 :
63 : namespace EnergyPlus {
64 :
65 : // Forward declarations
66 : struct EnergyPlusData;
67 :
68 : namespace PoweredInductionUnits {
69 :
70 : // Using/Aliasing
71 :
72 : // Data
73 : // MODULE PARAMETER DEFINITIONS
74 : // coil types in this module
75 : enum class HtgCoilType
76 : {
77 : Invalid = -1,
78 : Gas,
79 : Electric,
80 : SimpleHeating,
81 : SteamAirHeating,
82 : Num
83 : };
84 :
85 : static constexpr std::array<std::string_view, static_cast<int>(HtgCoilType::Num)> HCoilNamesUC{
86 : "COIL:HEATING:FUEL", "COIL:HEATING:ELECTRIC", "COIL:HEATING:WATER", "COIL:HEATING:STEAM"};
87 :
88 : static constexpr std::array<std::string_view, static_cast<int>(HtgCoilType::Num)> HCoilNames{
89 : "Coil:Heating:Fuel", "Coil:Heating:Electric", "Coil:Heating:Water", "Coil:Heating:Steam"};
90 :
91 : enum class FanCntrlType
92 : {
93 : Invalid = -1,
94 : ConstantSpeedFan,
95 : VariableSpeedFan,
96 : Num
97 : };
98 : enum class HeatCntrlBehaviorType
99 : {
100 : Invalid = -1,
101 : StagedHeaterBehavior,
102 : ModulatedHeaterBehavior,
103 : Num
104 : };
105 : enum class HeatOpModeType
106 : {
107 : Invalid = -1,
108 : HeaterOff,
109 : ConstantVolumeHeat,
110 : StagedHeatFirstStage,
111 : StagedHeatSecondStage,
112 : ModulatedHeatFirstStage,
113 : ModulatedHeatSecondStage,
114 : ModulatedHeatThirdStage,
115 : Num
116 : };
117 : enum class CoolOpModeType
118 : {
119 : Invalid = -1,
120 : CoolerOff,
121 : ConstantVolumeCool,
122 : CoolFirstStage,
123 : CoolSecondStage,
124 : Num
125 : };
126 :
127 : struct PowIndUnitData
128 : {
129 : // Members
130 : // input data
131 : std::string Name; // name of unit
132 : std::string UnitType; // type of unit
133 : DataDefineEquip::ZnAirLoopEquipType UnitType_Num; // index for type of unit
134 : Sched::Schedule *availSched = nullptr; // availability schedule
135 : Real64 MaxTotAirVolFlow; // m3/s (series)
136 : Real64 MaxTotAirMassFlow; // kg/s (series)
137 : Real64 MaxPriAirVolFlow; // m3/s
138 : Real64 MaxPriAirMassFlow; // kg/s
139 : Real64 MinPriAirFlowFrac; // minimum primary air flow fraction
140 : Real64 MinPriAirMassFlow; // kg/s
141 : Real64 PriDamperPosition; // primary air damper position
142 : Real64 MaxSecAirVolFlow; // m3/s (parallel)
143 : Real64 MaxSecAirMassFlow; // kg/s (parallel)
144 : Real64 FanOnFlowFrac; // frac of primary air flow at which fan turns on (parallel)
145 : Real64 FanOnAirMassFlow; // primary air mass flow rate at which fan turns on (parallel)
146 : int PriAirInNode; // unit primary air inlet node number
147 : int SecAirInNode; // unit secondary air inlet node number
148 : int OutAirNode; // unit air outlet node number
149 : int HCoilInAirNode; // unit mixed air node number
150 : int ControlCompTypeNum;
151 : int CompErrIndex;
152 : std::string MixerName; // name of air mixer component
153 : int Mixer_Num; // index for type of mixer
154 : std::string FanName; // name of fan component
155 : HVAC::FanType fanType; // index for fan type
156 : int Fan_Index; // store index for this fan
157 : Sched::Schedule *fanAvailSched = nullptr; // fan availability schedule
158 : HtgCoilType HCoilType; // index for heating coil type
159 : DataPlant::PlantEquipmentType HCoil_PlantType;
160 : std::string HCoil; // name of heating coil component
161 : int HCoil_Index; // index to this heating coil
162 : Fluid::RefrigProps *HCoil_fluid = nullptr;
163 : Real64 MaxVolHotWaterFlow; // m3/s
164 : Real64 MaxVolHotSteamFlow; // m3/s
165 : Real64 MaxHotWaterFlow; // kg/s
166 : Real64 MaxHotSteamFlow; // kg/s
167 : Real64 MinVolHotWaterFlow; // m3/s
168 : Real64 MinHotSteamFlow; // kg/s
169 : Real64 MinVolHotSteamFlow; // m3/s
170 : Real64 MinHotWaterFlow; // kg/s
171 : int HotControlNode; // hot water control node
172 : int HotCoilOutNodeNum; // outlet of coil
173 : Real64 HotControlOffset; // control tolerance
174 : PlantLocation HWplantLoc; // index for plant component for hot plant coil
175 : int ADUNum; // index of corresponding air distribution unit
176 : bool InducesPlenumAir; // True if secondary air comes from the plenum
177 : // Report data
178 : Real64 HeatingRate; // unit heat addition rate to zone [W]
179 : Real64 HeatingEnergy; // unit heat addition to zone [J]
180 : Real64 SensCoolRate; // unit sensible heat removal rate from zone [W]
181 : Real64 SensCoolEnergy; // unit sensible heat removal from zone [J]
182 : int CtrlZoneNum; // index to control zone
183 : int ctrlZoneInNodeIndex; // index to the control zone inlet node
184 : int AirLoopNum; // index for the air loop that this terminal is connected to.
185 : Real64 OutdoorAirFlowRate; // zone outdoor air volume flow rate
186 : Real64 PriAirMassFlow;
187 : Real64 SecAirMassFlow;
188 :
189 : FanCntrlType fanControlType = FanCntrlType::Invalid; // fan speed control, Constant or VS
190 : Real64 MinFanTurnDownRatio = 0.0; // VS fan minimum speed as fraction of maximum, to facilitate autosizing
191 : Real64 MinTotAirVolFlow = 0.0; // m3/s VS fan on minimum speed
192 : Real64 MinTotAirMassFlow = 0.0; // kg/s VS fan on minimum speed
193 : Real64 MinSecAirVolFlow = 0.0; // m3/s VS fan on minimum speed
194 : Real64 MinSecAirMassFlow = 0.0; // kg/s VS fan on minimum speed
195 : HeatCntrlBehaviorType heatingControlType =
196 : HeatCntrlBehaviorType::Invalid; // heating control scheme, staged or modulated (physical devices) have different control behavior
197 : Real64 designHeatingDAT = 0.0; // C, target heating discharge air temperature during second stage modulated heating behavior
198 : Real64 highLimitDAT = 0.0; // C, maximum limit on heating discharge air temperature, end of third stage modulated heating behavior
199 : Real64 TotMassFlowRate = 0.0; // currrent operating total air mass flow, for reporting
200 : Real64 SecMassFlowRate = 0.0; // current operating secondary air mass flow rate, for reporting
201 : Real64 PriMassFlowRate = 0.0; // current operating primary air mass flow rate, for reporting
202 : Real64 DischargeAirTemp = 0.0; // current operating discharge air temperature at outlet, for reporting
203 : HeatOpModeType heatingOperatingMode = HeatOpModeType::HeaterOff;
204 : CoolOpModeType coolingOperatingMode = CoolOpModeType::CoolerOff;
205 :
206 : int CurOperationControlStage = -1; // integer reference for what stage of control the unit is in
207 : int plenumIndex = 0;
208 : // Default Constructor
209 20 : PowIndUnitData()
210 40 : : UnitType_Num(DataDefineEquip::ZnAirLoopEquipType::Invalid), MaxTotAirVolFlow(0.0), MaxTotAirMassFlow(0.0), MaxPriAirVolFlow(0.0),
211 20 : MaxPriAirMassFlow(0.0), MinPriAirFlowFrac(0.0), MinPriAirMassFlow(0.0), PriDamperPosition(0.0), MaxSecAirVolFlow(0.0),
212 20 : MaxSecAirMassFlow(0.0), FanOnFlowFrac(0.0), FanOnAirMassFlow(0.0), PriAirInNode(0), SecAirInNode(0), OutAirNode(0), HCoilInAirNode(0),
213 60 : ControlCompTypeNum(0), CompErrIndex(0), Mixer_Num(0), fanType(HVAC::FanType::Invalid), Fan_Index(0), HCoilType(HtgCoilType::Invalid),
214 40 : HCoil_PlantType(DataPlant::PlantEquipmentType::Invalid), HCoil_Index(0), MaxVolHotWaterFlow(0.0), MaxVolHotSteamFlow(0.0),
215 20 : MaxHotWaterFlow(0.0), MaxHotSteamFlow(0.0), MinVolHotWaterFlow(0.0), MinHotSteamFlow(0.0), MinVolHotSteamFlow(0.0),
216 40 : MinHotWaterFlow(0.0), HotControlNode(0), HotCoilOutNodeNum(0), HotControlOffset(0.0), HWplantLoc{}, ADUNum(0), InducesPlenumAir(false),
217 20 : HeatingRate(0.0), HeatingEnergy(0.0), SensCoolRate(0.0), SensCoolEnergy(0.0), CtrlZoneNum(0), ctrlZoneInNodeIndex(0), AirLoopNum(0),
218 20 : OutdoorAirFlowRate(0.0)
219 : {
220 20 : }
221 :
222 : void CalcOutdoorAirVolumeFlowRate(EnergyPlusData &state);
223 :
224 : void reportTerminalUnit(EnergyPlusData &state);
225 : };
226 :
227 : void SimPIU(EnergyPlusData &state,
228 : std::string_view CompName, // name of the PIU
229 : bool FirstHVACIteration, // TRUE if first HVAC iteration in time step
230 : int ZoneNum, // index of zone served by PIU
231 : int ZoneNodeNum, // zone node number of zone served by PIU
232 : int &CompIndex // PIU Index in PIU names
233 : );
234 :
235 : void GetPIUs(EnergyPlusData &state);
236 :
237 : void InitPIU(EnergyPlusData &state,
238 : int PIUNum, // number of the current fan coil unit being simulated
239 : bool FirstHVACIteration // TRUE if first zone equip this HVAC step
240 : );
241 :
242 : void SizePIU(EnergyPlusData &state, int PIUNum);
243 :
244 : void CalcSeriesPIU(EnergyPlusData &state,
245 : int PIUNum, // number of the current PIU being simulated
246 : int ZoneNum, // number of zone being served
247 : int ZoneNode, // zone node number
248 : bool FirstHVACIteration // TRUE if 1st HVAC simulation of system timestep
249 : );
250 :
251 : void CalcParallelPIU(EnergyPlusData &state,
252 : int PIUNum, // number of the current PIU being simulated
253 : int ZoneNum, // number of zone being served
254 : int ZoneNode, // zone node number
255 : bool FirstHVACIteration // TRUE if 1st HVAC simulation of system timestep
256 : );
257 :
258 : void ReportPIU(EnergyPlusData &state, int PIUNum); // number of the current fan coil unit being simulated
259 :
260 : void CalcVariableSpeedPIUModulatedHeatingBehavior(EnergyPlusData &state,
261 : int const piuNum, // number of the current PIU being simulated
262 : int const zoneNode, // zone node number
263 : Real64 const zoneLoad,
264 : bool const pri,
265 : Real64 const primaryAirMassFlow);
266 :
267 : void CalcVariableSpeedPIUStagedHeatingBehavior(EnergyPlusData &state,
268 : int const piuNum, // number of the current PIU being simulated
269 : int const zoneNode, // zone node number
270 : Real64 const zoneLoad,
271 : bool const pri,
272 : Real64 const primaryAirMassFlow);
273 :
274 : void
275 : ReportCurOperatingControlStage(EnergyPlusData &state, int const PIUNum, bool const unitOn, HeatOpModeType heaterMode, CoolOpModeType coolingMode);
276 :
277 : // ===================== Utilities =====================================
278 :
279 : bool PIUnitHasMixer(EnergyPlusData &state, std::string_view CompName); // component (mixer) name
280 :
281 : void PIUInducesPlenumAir(EnergyPlusData &state, int NodeNum, int const plenumNum); // induced air node number
282 :
283 : Real64 CalcVariableSpeedPIUHeatingResidual(EnergyPlusData &state,
284 : Real64 const fanSignal,
285 : int const piuNum,
286 : Real64 const targetQznReq,
287 : int const zoneNodeNum,
288 : Real64 const primaryMassFlow,
289 : bool const useDAT,
290 : Real64 const fanTurnDown);
291 :
292 : Real64 CalcVariableSpeedPIUCoolingResidual(
293 : EnergyPlusData &state, Real64 const coolSignal, int const piuNum, Real64 const targetQznReq, int const zoneNodeNum);
294 :
295 : void CalcVariableSpeedPIUCoolingBehavior(EnergyPlusData &state,
296 : int const PIUNum,
297 : int const zoneNode,
298 : Real64 const zoneLoad,
299 : Real64 const loadToHeatSetPt,
300 : Real64 const priAirMassFlowMin,
301 : Real64 const priAirMassFlowMax);
302 :
303 : Real64 CalcVariableSpeedPIUQdotDelivered(
304 : EnergyPlusData &state, int const piuNum, int const zoneNode, bool const useDAT, Real64 const totAirMassFlow, Real64 const fanTurnDown);
305 :
306 : } // namespace PoweredInductionUnits
307 :
308 : struct PoweredInductionUnitsData : BaseGlobalStruct
309 : {
310 :
311 : Array1D_bool CheckEquipName;
312 : bool GetPIUInputFlag = true;
313 : bool MyOneTimeFlag = true;
314 : bool ZoneEquipmentListChecked = false;
315 : int NumPIUs = 0;
316 : int NumSeriesPIUs = 0;
317 : int NumParallelPIUs = 0;
318 : Array1D<PoweredInductionUnits::PowIndUnitData> PIU;
319 : std::unordered_map<std::string, std::string> PiuUniqueNames;
320 : Array1D_bool MyEnvrnFlag;
321 : Array1D_bool MySizeFlag;
322 : Array1D_bool MyPlantScanFlag;
323 :
324 2126 : void init_constant_state([[maybe_unused]] EnergyPlusData &state) override
325 : {
326 2126 : }
327 :
328 1152 : void init_state([[maybe_unused]] EnergyPlusData &state) override
329 : {
330 1152 : }
331 :
332 2100 : void clear_state() override
333 : {
334 2100 : this->CheckEquipName.deallocate();
335 2100 : this->GetPIUInputFlag = true;
336 2100 : this->MyOneTimeFlag = true;
337 2100 : this->ZoneEquipmentListChecked = false;
338 2100 : this->NumPIUs = 0;
339 2100 : this->NumSeriesPIUs = 0;
340 2100 : this->NumParallelPIUs = 0;
341 2100 : this->PIU.deallocate();
342 2100 : this->PiuUniqueNames.clear();
343 2100 : this->MyEnvrnFlag.clear();
344 2100 : this->MySizeFlag.clear();
345 2100 : this->MyPlantScanFlag.clear();
346 2100 : }
347 : };
348 :
349 : } // namespace EnergyPlus
350 :
351 : #endif
|