Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <cmath>
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array.functions.hh>
53 : #include <ObjexxFCL/Fmath.hh>
54 :
55 : // EnergyPlus Headers
56 : #include <EnergyPlus/Autosizing/Base.hh>
57 : #include <EnergyPlus/BranchNodeConnections.hh>
58 : #include <EnergyPlus/Data/EnergyPlusData.hh>
59 : #include <EnergyPlus/DataDefineEquip.hh>
60 : #include <EnergyPlus/DataEnvironment.hh>
61 : #include <EnergyPlus/DataHVACGlobals.hh>
62 : #include <EnergyPlus/DataLoopNode.hh>
63 : #include <EnergyPlus/DataSizing.hh>
64 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
65 : #include <EnergyPlus/DataZoneEquipment.hh>
66 : #include <EnergyPlus/FluidProperties.hh>
67 : #include <EnergyPlus/General.hh>
68 : #include <EnergyPlus/GeneralRoutines.hh>
69 : #include <EnergyPlus/HVACSingleDuctInduc.hh>
70 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
71 : #include <EnergyPlus/MixerComponent.hh>
72 : #include <EnergyPlus/NodeInputManager.hh>
73 : #include <EnergyPlus/OutputProcessor.hh>
74 : #include <EnergyPlus/OutputReportPredefined.hh>
75 : #include <EnergyPlus/Plant/DataPlant.hh>
76 : #include <EnergyPlus/PlantUtilities.hh>
77 : #include <EnergyPlus/Psychrometrics.hh>
78 : #include <EnergyPlus/ScheduleManager.hh>
79 : #include <EnergyPlus/UtilityRoutines.hh>
80 : #include <EnergyPlus/WaterCoils.hh>
81 :
82 : namespace EnergyPlus {
83 :
84 : namespace HVACSingleDuctInduc {
85 :
86 : // Module containing routines dealing terminal 4 pipe induction terminal units
87 :
88 : // MODULE INFORMATION:
89 : // AUTHOR Fred Buhl
90 : // DATE WRITTEN June 15 2004
91 : // MODIFIED Brent Griffith, Sept 2010, plant upgrades, fluid props
92 :
93 : // PURPOSE OF THIS MODULE:
94 : // To encapsulate the data and algorithms needed to simulate 4 pipe induction terminal units
95 :
96 : // METHODOLOGY EMPLOYED:
97 : // The terminal boxes are modeled as compound components: heating coil, cooling coil and
98 : // mixer. The combined components are controlled to meet the zone load.
99 :
100 11976 : void SimIndUnit(EnergyPlusData &state,
101 : std::string_view CompName, // name of the terminal unit
102 : bool const FirstHVACIteration, // TRUE if first HVAC iteration in time step
103 : int const ZoneNum, // index of zone served by the terminal unit
104 : int const ZoneNodeNum, // zone node number of zone served by the terminal unit
105 : int &CompIndex // which terminal unit in data structure
106 : )
107 : {
108 :
109 : // SUBROUTINE INFORMATION:
110 : // AUTHOR Fred Buhl
111 : // DATE WRITTEN June 18 2004
112 :
113 : // PURPOSE OF THIS SUBROUTINE:
114 : // Manages the simulation of a passive (no fan) induction terminal unit.
115 : // Called from SimZoneAirLoopEquipment in module ZoneAirLoopEquipmentManager.
116 :
117 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
118 : int IUNum; // index of terminal unit being simulated
119 :
120 : // First time SimIndUnit is called, get the input for all the passive terminal induction units
121 11976 : if (state.dataHVACSingleDuctInduc->GetIUInputFlag) {
122 1 : GetIndUnits(state);
123 1 : state.dataHVACSingleDuctInduc->GetIUInputFlag = false;
124 : }
125 :
126 : // Get the induction unit index
127 11976 : if (CompIndex == 0) {
128 4 : IUNum = Util::FindItemInList(CompName, state.dataHVACSingleDuctInduc->IndUnit);
129 4 : if (IUNum == 0) {
130 0 : ShowFatalError(state, format("SimIndUnit: Induction Unit not found={}", CompName));
131 : }
132 4 : CompIndex = IUNum;
133 : } else {
134 11972 : IUNum = CompIndex;
135 11972 : if (IUNum > state.dataHVACSingleDuctInduc->NumIndUnits || IUNum < 1) {
136 0 : ShowFatalError(state,
137 0 : format("SimIndUnit: Invalid CompIndex passed={}, Number of Induction Units={}, System name={}",
138 : CompIndex,
139 0 : state.dataHVACSingleDuctInduc->NumIndUnits,
140 : CompName));
141 : }
142 11972 : if (state.dataHVACSingleDuctInduc->CheckEquipName(IUNum)) {
143 4 : if (CompName != state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name) {
144 0 : ShowFatalError(state,
145 0 : format("SimIndUnit: Invalid CompIndex passed={}, Induction Unit name={}, stored Induction Unit for that index={}",
146 : CompIndex,
147 : CompName,
148 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
149 : }
150 4 : state.dataHVACSingleDuctInduc->CheckEquipName(IUNum) = false;
151 : }
152 : }
153 :
154 11976 : auto &indUnit = state.dataHVACSingleDuctInduc->IndUnit(IUNum);
155 :
156 11976 : state.dataSize->CurTermUnitSizingNum = state.dataDefineEquipment->AirDistUnit(indUnit.ADUNum).TermUnitSizingNum;
157 : // initialize the unit
158 11976 : InitIndUnit(state, IUNum, FirstHVACIteration);
159 :
160 11976 : state.dataSize->TermUnitIU = true;
161 :
162 : // Select the correct unit type
163 11976 : switch (indUnit.UnitType_Num) {
164 11976 : case SingleDuct_CV::FourPipeInduc: {
165 11976 : SimFourPipeIndUnit(state, IUNum, ZoneNum, ZoneNodeNum, FirstHVACIteration);
166 11976 : } break;
167 0 : default: {
168 0 : ShowSevereError(state, format("Illegal Induction Unit Type used={}", indUnit.UnitType));
169 0 : ShowContinueError(state, format("Occurs in Induction Unit={}", indUnit.Name));
170 0 : ShowFatalError(state, "Preceding condition causes termination.");
171 0 : } break;
172 : }
173 :
174 11976 : state.dataSize->TermUnitIU = false;
175 :
176 : // the tasks usually done by the Update and Report routines are not required in a compound terminal unit.
177 :
178 : // Update the current unit's outlet nodes. No update needed
179 :
180 : // Fill the report variables. There are no report variables
181 11976 : indUnit.ReportIndUnit(state);
182 11976 : }
183 :
184 2 : void GetIndUnits(EnergyPlusData &state)
185 : {
186 :
187 : // SUBROUTINE INFORMATION:
188 : // AUTHOR Fred Buhl
189 : // DATE WRITTEN June 15 2004
190 :
191 : // PURPOSE OF THIS SUBROUTINE:
192 : // Obtains input data for passive induction air terminal units and stores it in the
193 : // induction terminal unit data structures
194 :
195 : // METHODOLOGY EMPLOYED:
196 : // Uses "Get" routines to read in data.
197 :
198 : // SUBROUTINE PARAMETER DEFINITIONS:
199 : static constexpr std::string_view RoutineName("GetIndUnits "); // include trailing blank space
200 :
201 2 : Array1D_string Alphas; // Alpha input items for object
202 2 : Array1D_string cAlphaFields; // Alpha field names
203 2 : Array1D_string cNumericFields; // Numeric field names
204 2 : Array1D<Real64> Numbers; // Numeric input items for object
205 2 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
206 2 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
207 2 : int NumAlphas(0); // Number of Alphas for each GetObjectItem call
208 2 : int NumNumbers(0); // Number of Numbers for each GetObjectItem call
209 2 : int TotalArgs(0); // Total number of alpha and numeric arguments (max) for a
210 : // certain object in the input file
211 : int IOStatus; // Used in GetObjectItem
212 2 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
213 :
214 : // find the number of each type of induction unit
215 2 : std::string CurrentModuleObject = "AirTerminal:SingleDuct:ConstantVolume:FourPipeInduction";
216 2 : state.dataHVACSingleDuctInduc->NumFourPipes = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
217 2 : state.dataHVACSingleDuctInduc->NumIndUnits = state.dataHVACSingleDuctInduc->NumFourPipes;
218 : // allocate the data structures
219 2 : state.dataHVACSingleDuctInduc->IndUnit.allocate(state.dataHVACSingleDuctInduc->NumIndUnits);
220 2 : state.dataHVACSingleDuctInduc->CheckEquipName.dimension(state.dataHVACSingleDuctInduc->NumIndUnits, true);
221 :
222 2 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, TotalArgs, NumAlphas, NumNumbers);
223 :
224 2 : Alphas.allocate(NumAlphas);
225 2 : cAlphaFields.allocate(NumAlphas);
226 2 : cNumericFields.allocate(NumNumbers);
227 2 : Numbers.dimension(NumNumbers, 0.0);
228 2 : lAlphaBlanks.dimension(NumAlphas, true);
229 2 : lNumericBlanks.dimension(NumNumbers, true);
230 :
231 : // loop over Series PIUs; get and load the input data
232 6 : for (int IUIndex = 1; IUIndex <= state.dataHVACSingleDuctInduc->NumFourPipes; ++IUIndex) {
233 :
234 4 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
235 : CurrentModuleObject,
236 : IUIndex,
237 : Alphas,
238 : NumAlphas,
239 : Numbers,
240 : NumNumbers,
241 : IOStatus,
242 : lNumericBlanks,
243 : lAlphaBlanks,
244 : cAlphaFields,
245 : cNumericFields);
246 :
247 4 : int IUNum = IUIndex;
248 4 : Util::IsNameEmpty(state, Alphas(1), CurrentModuleObject, ErrorsFound);
249 :
250 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name = Alphas(1);
251 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType = CurrentModuleObject;
252 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType_Num = SingleDuct_CV::FourPipeInduc;
253 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Sched = Alphas(2);
254 4 : if (lAlphaBlanks(2)) {
255 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).SchedPtr = ScheduleManager::ScheduleAlwaysOn;
256 : } else {
257 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).SchedPtr =
258 4 : ScheduleManager::GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer
259 4 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).SchedPtr == 0) {
260 0 : ShowSevereError(state,
261 0 : format("{}{}: invalid {} entered ={} for {}={}",
262 : RoutineName,
263 : CurrentModuleObject,
264 : cAlphaFields(2),
265 : Alphas(2),
266 : cAlphaFields(1),
267 : Alphas(1)));
268 0 : ErrorsFound = true;
269 : }
270 : }
271 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirVolFlow = Numbers(1);
272 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).InducRatio = Numbers(2);
273 4 : if (lNumericBlanks(2)) state.dataHVACSingleDuctInduc->IndUnit(IUNum).InducRatio = 2.5;
274 :
275 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).PriAirInNode =
276 4 : GetOnlySingleNode(state,
277 4 : Alphas(3),
278 : ErrorsFound,
279 : DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeFourPipeInduction,
280 4 : Alphas(1),
281 : DataLoopNode::NodeFluidType::Air,
282 : DataLoopNode::ConnectionType::Inlet,
283 : NodeInputManager::CompFluidStream::Primary,
284 : DataLoopNode::ObjectIsParent,
285 4 : cAlphaFields(3));
286 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).SecAirInNode =
287 4 : GetOnlySingleNode(state,
288 4 : Alphas(4),
289 : ErrorsFound,
290 : DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeFourPipeInduction,
291 4 : Alphas(1),
292 : DataLoopNode::NodeFluidType::Air,
293 : DataLoopNode::ConnectionType::Inlet,
294 : NodeInputManager::CompFluidStream::Primary,
295 : DataLoopNode::ObjectIsParent,
296 4 : cAlphaFields(4));
297 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).OutAirNode =
298 4 : GetOnlySingleNode(state,
299 4 : Alphas(5),
300 : ErrorsFound,
301 : DataLoopNode::ConnectionObjectType::AirTerminalSingleDuctConstantVolumeFourPipeInduction,
302 4 : Alphas(1),
303 : DataLoopNode::NodeFluidType::Air,
304 : DataLoopNode::ConnectionType::Outlet,
305 : NodeInputManager::CompFluidStream::Primary,
306 : DataLoopNode::ObjectIsParent,
307 4 : cAlphaFields(5));
308 :
309 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoilType = Alphas(6); // type (key) of heating coil
310 4 : if (Util::SameString(state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoilType, "Coil:Heating:Water")) {
311 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).HeatingCoilType = DataPlant::PlantEquipmentType::CoilWaterSimpleHeating;
312 : }
313 :
314 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoil = Alphas(7); // name of heating coil object
315 4 : bool IsNotOK = false;
316 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWControlNode = WaterCoils::GetCoilWaterInletNode(
317 4 : state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoilType, state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoil, IsNotOK);
318 4 : if (IsNotOK) {
319 0 : ShowContinueError(state, format("In {} = {}", CurrentModuleObject, state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
320 0 : ShowContinueError(state, "..Only Coil:Heating:Water is allowed.");
321 0 : ErrorsFound = true;
322 : }
323 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolHotWaterFlow = Numbers(3);
324 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MinVolHotWaterFlow = Numbers(4);
325 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).HotControlOffset = Numbers(5);
326 :
327 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoilType = Alphas(8); // type (key) of cooling coil
328 :
329 4 : if (Util::SameString(state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoilType, "Coil:Cooling:Water")) {
330 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CoolingCoilType = DataPlant::PlantEquipmentType::CoilWaterCooling;
331 0 : } else if (Util::SameString(state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoilType, "Coil:Cooling:Water:DetailedGeometry")) {
332 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CoolingCoilType = DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling;
333 : }
334 :
335 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoil = Alphas(9); // name of cooling coil object
336 4 : IsNotOK = false;
337 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWControlNode = WaterCoils::GetCoilWaterInletNode(
338 4 : state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoilType, state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoil, IsNotOK);
339 4 : if (IsNotOK) {
340 0 : ShowContinueError(state, format("In {} = {}", CurrentModuleObject, state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
341 0 : ShowContinueError(state, "..Only Coil:Cooling:Water or Coil:Cooling:Water:DetailedGeometry is allowed.");
342 0 : ErrorsFound = true;
343 : }
344 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolColdWaterFlow = Numbers(6);
345 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MinVolColdWaterFlow = Numbers(7);
346 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).ColdControlOffset = Numbers(8);
347 :
348 : // Get the Zone Mixer name and check that it is OK
349 4 : bool errFlag = false;
350 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MixerName = Alphas(10);
351 4 : MixerComponent::GetZoneMixerIndex(state,
352 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MixerName,
353 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Mixer_Num,
354 : errFlag,
355 : CurrentModuleObject);
356 4 : if (errFlag) {
357 0 : ShowContinueError(state, format("...specified in {} = {}", CurrentModuleObject, state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
358 0 : ErrorsFound = true;
359 : }
360 :
361 : // Add heating coil to component sets array
362 8 : BranchNodeConnections::SetUpCompSets(state,
363 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
364 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
365 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoilType,
366 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoil,
367 4 : Alphas(4),
368 : "UNDEFINED");
369 : // Add cooling coil to component sets array
370 8 : BranchNodeConnections::SetUpCompSets(state,
371 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
372 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
373 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoilType,
374 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoil,
375 : "UNDEFINED",
376 : "UNDEFINED");
377 :
378 : // Register component set data
379 8 : BranchNodeConnections::TestCompSet(state,
380 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
381 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
382 4 : state.dataLoopNodes->NodeID(state.dataHVACSingleDuctInduc->IndUnit(IUNum).PriAirInNode),
383 4 : state.dataLoopNodes->NodeID(state.dataHVACSingleDuctInduc->IndUnit(IUNum).OutAirNode),
384 : "Air Nodes");
385 :
386 24 : for (int ADUNum = 1; ADUNum <= (int)state.dataDefineEquipment->AirDistUnit.size(); ++ADUNum) {
387 20 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).OutAirNode == state.dataDefineEquipment->AirDistUnit(ADUNum).OutletNodeNum) {
388 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).ADUNum = ADUNum;
389 : }
390 : }
391 : // one assumes if there isn't one assigned, it's an error?
392 4 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).ADUNum == 0) {
393 0 : ShowSevereError(state,
394 0 : format("{}No matching Air Distribution Unit, for Unit = [{},{}].",
395 : RoutineName,
396 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
397 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
398 0 : ShowContinueError(
399 : state,
400 0 : format("...should have outlet node={}", state.dataLoopNodes->NodeID(state.dataHVACSingleDuctInduc->IndUnit(IUNum).OutAirNode)));
401 0 : ErrorsFound = true;
402 : } else {
403 : // Fill the Zone Equipment data with the supply air inlet node number of this unit.
404 4 : bool AirNodeFound = false;
405 28 : for (int CtrlZone = 1; CtrlZone <= state.dataGlobal->NumOfZones; ++CtrlZone) {
406 24 : auto &zoneEquipConfig = state.dataZoneEquip->ZoneEquipConfig(CtrlZone);
407 :
408 24 : if (!zoneEquipConfig.IsControlled) continue;
409 36 : for (int SupAirIn = 1; SupAirIn <= zoneEquipConfig.NumInletNodes; ++SupAirIn) {
410 20 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).OutAirNode == zoneEquipConfig.InletNode(SupAirIn)) {
411 4 : if (zoneEquipConfig.AirDistUnitCool(SupAirIn).OutNode > 0) {
412 0 : ShowSevereError(state, "Error in connecting a terminal unit to a zone");
413 0 : ShowContinueError(state,
414 0 : format("{} already connects to another zone",
415 0 : state.dataLoopNodes->NodeID(state.dataHVACSingleDuctInduc->IndUnit(IUNum).OutAirNode)));
416 0 : ShowContinueError(state,
417 0 : format("Occurs for terminal unit {} = {}",
418 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
419 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
420 0 : ShowContinueError(state, "Check terminal unit node names for errors");
421 0 : ErrorsFound = true;
422 : } else {
423 4 : zoneEquipConfig.AirDistUnitCool(SupAirIn).InNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).PriAirInNode;
424 4 : zoneEquipConfig.AirDistUnitCool(SupAirIn).OutNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).OutAirNode;
425 4 : state.dataDefineEquipment->AirDistUnit(state.dataHVACSingleDuctInduc->IndUnit(IUNum).ADUNum).TermUnitSizingNum =
426 4 : zoneEquipConfig.AirDistUnitCool(SupAirIn).TermUnitSizingIndex;
427 4 : state.dataDefineEquipment->AirDistUnit(state.dataHVACSingleDuctInduc->IndUnit(IUNum).ADUNum).ZoneEqNum = CtrlZone;
428 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CtrlZoneNum = CtrlZone;
429 : }
430 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CtrlZoneInNodeIndex = SupAirIn;
431 4 : AirNodeFound = true;
432 4 : break;
433 : }
434 : }
435 : }
436 4 : if (!AirNodeFound) {
437 0 : ShowSevereError(
438 : state,
439 0 : format("The outlet air node from the {} = {}", CurrentModuleObject, state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
440 0 : ShowContinueError(state, format("did not have a matching Zone Equipment Inlet Node, Node ={}", Alphas(3)));
441 0 : ErrorsFound = true;
442 : }
443 : }
444 : // report variable for all single duct air terminals
445 8 : SetupOutputVariable(state,
446 : "Zone Air Terminal Outdoor Air Volume Flow Rate",
447 : Constant::Units::m3_s,
448 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).OutdoorAirFlowRate,
449 : OutputProcessor::TimeStepType::System,
450 : OutputProcessor::StoreType::Average,
451 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name);
452 : }
453 :
454 2 : Alphas.deallocate();
455 2 : cAlphaFields.deallocate();
456 2 : cNumericFields.deallocate();
457 2 : Numbers.deallocate();
458 2 : lAlphaBlanks.deallocate();
459 2 : lNumericBlanks.deallocate();
460 2 : if (ErrorsFound) {
461 0 : ShowFatalError(state, format("{}Errors found in getting input. Preceding conditions cause termination.", RoutineName));
462 : }
463 2 : }
464 :
465 11976 : void InitIndUnit(EnergyPlusData &state,
466 : int const IUNum, // number of the current induction unit being simulated
467 : bool const FirstHVACIteration // TRUE if first air loop solution this HVAC step
468 : )
469 : {
470 :
471 : // SUBROUTINE INFORMATION:
472 : // AUTHOR Fred Buhl
473 : // DATE WRITTEN June 21 2004
474 :
475 : // PURPOSE OF THIS SUBROUTINE:
476 : // This subroutine is for initialization of the passive induction terminal boxes
477 :
478 : // METHODOLOGY EMPLOYED:
479 : // Uses the status flags to trigger initializations.
480 :
481 : // SUBROUTINE PARAMETER DEFINITIONS:
482 : static constexpr std::string_view RoutineName("InitIndUnit");
483 :
484 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
485 : int PriNode; // primary air inlet node number
486 : int SecNode; // secondary air inlet node number
487 : Real64 IndRat; // unit induction ratio
488 : Real64 RhoAir; // air density at outside pressure and standard temperature and humidity
489 : Real64 rho; // local fluid density
490 :
491 11976 : auto &ZoneEquipmentListChecked = state.dataHVACSingleDuctInduc->ZoneEquipmentListChecked;
492 :
493 : // Do the one time initializations
494 11976 : if (state.dataHVACSingleDuctInduc->MyOneTimeFlag) {
495 :
496 1 : state.dataHVACSingleDuctInduc->MyEnvrnFlag.allocate(state.dataHVACSingleDuctInduc->NumIndUnits);
497 1 : state.dataHVACSingleDuctInduc->MySizeFlag.allocate(state.dataHVACSingleDuctInduc->NumIndUnits);
498 1 : state.dataHVACSingleDuctInduc->MyPlantScanFlag.allocate(state.dataHVACSingleDuctInduc->NumIndUnits);
499 1 : state.dataHVACSingleDuctInduc->MyAirDistInitFlag.allocate(state.dataHVACSingleDuctInduc->NumIndUnits);
500 1 : state.dataHVACSingleDuctInduc->MyEnvrnFlag = true;
501 1 : state.dataHVACSingleDuctInduc->MySizeFlag = true;
502 1 : state.dataHVACSingleDuctInduc->MyPlantScanFlag = true;
503 1 : state.dataHVACSingleDuctInduc->MyAirDistInitFlag = true;
504 1 : state.dataHVACSingleDuctInduc->MyOneTimeFlag = false;
505 : }
506 :
507 11976 : if (state.dataHVACSingleDuctInduc->MyPlantScanFlag(IUNum) && allocated(state.dataPlnt->PlantLoop)) {
508 4 : bool errFlag = false;
509 4 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).HeatingCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating) {
510 4 : errFlag = false;
511 8 : PlantUtilities::ScanPlantLoopsForObject(state,
512 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoil,
513 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).HeatingCoilType,
514 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWPlantLoc,
515 : errFlag,
516 : _,
517 : _,
518 : _,
519 : _,
520 : _);
521 : }
522 4 : if (errFlag) {
523 0 : ShowContinueError(state,
524 0 : format("Reference Unit=\"{}\", type={}",
525 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
526 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType));
527 : }
528 4 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).CoolingCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling ||
529 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CoolingCoilType == DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling) {
530 4 : errFlag = false;
531 8 : PlantUtilities::ScanPlantLoopsForObject(state,
532 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoil,
533 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CoolingCoilType,
534 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWPlantLoc,
535 : errFlag,
536 : _,
537 : _,
538 : _,
539 : _,
540 : _);
541 : }
542 4 : if (errFlag) {
543 0 : ShowContinueError(state,
544 0 : format("Reference Unit=\"{}\", type={}",
545 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
546 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType));
547 0 : ShowFatalError(state, "InitIndUnit: Program terminated for previous conditions.");
548 : }
549 4 : state.dataHVACSingleDuctInduc->MyPlantScanFlag(IUNum) = false;
550 11972 : } else if (state.dataHVACSingleDuctInduc->MyPlantScanFlag(IUNum) && !state.dataGlobal->AnyPlantInModel) {
551 0 : state.dataHVACSingleDuctInduc->MyPlantScanFlag(IUNum) = false;
552 : }
553 :
554 11976 : if (state.dataHVACSingleDuctInduc->MyAirDistInitFlag(IUNum)) {
555 : // save the induction ratio in the term unit sizing array for use in the system sizing calculation
556 12 : if (state.dataSize->CurTermUnitSizingNum > 0) {
557 12 : state.dataSize->TermUnitSizing(state.dataSize->CurTermUnitSizingNum).InducRat =
558 12 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).InducRatio;
559 : }
560 12 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).AirLoopNum == 0) {
561 16 : if ((state.dataHVACSingleDuctInduc->IndUnit(IUNum).CtrlZoneNum > 0) &&
562 8 : (state.dataHVACSingleDuctInduc->IndUnit(IUNum).CtrlZoneInNodeIndex > 0)) {
563 8 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).AirLoopNum =
564 8 : state.dataZoneEquip->ZoneEquipConfig(state.dataHVACSingleDuctInduc->IndUnit(IUNum).CtrlZoneNum)
565 8 : .InletNodeAirLoopNum(state.dataHVACSingleDuctInduc->IndUnit(IUNum).CtrlZoneInNodeIndex);
566 8 : state.dataDefineEquipment->AirDistUnit(state.dataHVACSingleDuctInduc->IndUnit(IUNum).ADUNum).AirLoopNum =
567 8 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).AirLoopNum;
568 : }
569 : } else {
570 4 : state.dataHVACSingleDuctInduc->MyAirDistInitFlag(IUNum) = false;
571 : }
572 : }
573 11976 : if (!ZoneEquipmentListChecked && state.dataZoneEquip->ZoneEquipInputsFilled) {
574 1 : ZoneEquipmentListChecked = true;
575 : // Check to see if there is a Air Distribution Unit on the Zone Equipment List
576 5 : for (int Loop = 1; Loop <= state.dataHVACSingleDuctInduc->NumIndUnits; ++Loop) {
577 4 : if (state.dataHVACSingleDuctInduc->IndUnit(Loop).ADUNum == 0) continue;
578 8 : if (DataZoneEquipment::CheckZoneEquipmentList(
579 : state,
580 : "ZONEHVAC:AIRDISTRIBUTIONUNIT",
581 4 : state.dataDefineEquipment->AirDistUnit(state.dataHVACSingleDuctInduc->IndUnit(Loop).ADUNum).Name))
582 4 : continue;
583 0 : ShowSevereError(state,
584 0 : format("InitIndUnit: ADU=[Air Distribution Unit,{}] is not on any ZoneHVAC:EquipmentList.",
585 0 : state.dataDefineEquipment->AirDistUnit(state.dataHVACSingleDuctInduc->IndUnit(Loop).ADUNum).Name));
586 0 : ShowContinueError(state,
587 0 : format("...Unit=[{},{}] will not be simulated.",
588 0 : state.dataHVACSingleDuctInduc->IndUnit(Loop).UnitType,
589 0 : state.dataHVACSingleDuctInduc->IndUnit(Loop).Name));
590 : }
591 : }
592 :
593 11976 : if (!state.dataGlobal->SysSizingCalc && state.dataHVACSingleDuctInduc->MySizeFlag(IUNum)) {
594 :
595 4 : SizeIndUnit(state, IUNum);
596 4 : state.dataHVACSingleDuctInduc->MySizeFlag(IUNum) = false;
597 : }
598 :
599 : // Do the Begin Environment initializations
600 11976 : if (state.dataGlobal->BeginEnvrnFlag && state.dataHVACSingleDuctInduc->MyEnvrnFlag(IUNum)) {
601 24 : RhoAir = state.dataEnvrn->StdRhoAir;
602 24 : PriNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).PriAirInNode;
603 24 : SecNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).SecAirInNode;
604 24 : int OutletNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).OutAirNode;
605 24 : IndRat = state.dataHVACSingleDuctInduc->IndUnit(IUNum).InducRatio;
606 : // set the mass flow rates from the input volume flow rates
607 24 : if (Util::SameString(state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType, "AirTerminal:SingleDuct:ConstantVolume:FourPipeInduction")) {
608 24 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirMassFlow =
609 24 : RhoAir * state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirVolFlow;
610 24 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxPriAirMassFlow =
611 24 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirMassFlow / (1.0 + IndRat);
612 24 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxSecAirMassFlow =
613 24 : IndRat * state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirMassFlow / (1.0 + IndRat);
614 24 : state.dataLoopNodes->Node(PriNode).MassFlowRateMax = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxPriAirMassFlow;
615 24 : state.dataLoopNodes->Node(PriNode).MassFlowRateMin = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxPriAirMassFlow;
616 24 : state.dataLoopNodes->Node(SecNode).MassFlowRateMax = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxSecAirMassFlow;
617 24 : state.dataLoopNodes->Node(SecNode).MassFlowRateMin = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxSecAirMassFlow;
618 24 : state.dataLoopNodes->Node(OutletNode).MassFlowRateMax = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirMassFlow;
619 : }
620 :
621 24 : int HotConNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWControlNode;
622 24 : if (HotConNode > 0 && !state.dataHVACSingleDuctInduc->MyPlantScanFlag(IUNum)) {
623 :
624 24 : rho = FluidProperties::GetDensityGlycol(
625 : state,
626 24 : state.dataPlnt->PlantLoop(state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWPlantLoc.loopNum).FluidName,
627 : Constant::HWInitConvTemp,
628 24 : state.dataPlnt->PlantLoop(state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWPlantLoc.loopNum).FluidIndex,
629 : RoutineName);
630 24 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxHotWaterFlow =
631 24 : rho * state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolHotWaterFlow;
632 24 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MinHotWaterFlow =
633 24 : rho * state.dataHVACSingleDuctInduc->IndUnit(IUNum).MinVolHotWaterFlow;
634 : // get component outlet node from plant structure
635 24 : int HWOutletNode = DataPlant::CompData::getPlantComponent(state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWPlantLoc).NodeNumOut;
636 48 : PlantUtilities::InitComponentNodes(state,
637 24 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MinHotWaterFlow,
638 24 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxHotWaterFlow,
639 : HotConNode,
640 : HWOutletNode);
641 : }
642 :
643 24 : int ColdConNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWControlNode;
644 24 : if (ColdConNode > 0) {
645 24 : rho = FluidProperties::GetDensityGlycol(
646 : state,
647 24 : state.dataPlnt->PlantLoop(state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWPlantLoc.loopNum).FluidName,
648 : Constant::CWInitConvTemp,
649 24 : state.dataPlnt->PlantLoop(state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWPlantLoc.loopNum).FluidIndex,
650 : RoutineName);
651 24 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxColdWaterFlow =
652 24 : rho * state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolColdWaterFlow;
653 24 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MinColdWaterFlow =
654 24 : rho * state.dataHVACSingleDuctInduc->IndUnit(IUNum).MinVolColdWaterFlow;
655 :
656 24 : int CWOutletNode = DataPlant::CompData::getPlantComponent(state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWPlantLoc).NodeNumOut;
657 48 : PlantUtilities::InitComponentNodes(state,
658 24 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MinColdWaterFlow,
659 24 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxColdWaterFlow,
660 : ColdConNode,
661 : CWOutletNode);
662 : }
663 :
664 24 : state.dataHVACSingleDuctInduc->MyEnvrnFlag(IUNum) = false;
665 : } // end one time inits
666 :
667 11976 : if (!state.dataGlobal->BeginEnvrnFlag) {
668 11836 : state.dataHVACSingleDuctInduc->MyEnvrnFlag(IUNum) = true;
669 : }
670 :
671 11976 : PriNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).PriAirInNode;
672 11976 : SecNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).SecAirInNode;
673 :
674 : // Do the start of HVAC time step initializations
675 11976 : if (FirstHVACIteration) {
676 : // check for upstream zero flow. If nonzero and schedule ON, set primary flow to max
677 11992 : if (ScheduleManager::GetCurrentScheduleValue(state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).SchedPtr) > 0.0 &&
678 5988 : state.dataLoopNodes->Node(PriNode).MassFlowRate > 0.0) {
679 5968 : if (Util::SameString(state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
680 : "AirTerminal:SingleDuct:ConstantVolume:FourPipeInduction")) {
681 5968 : state.dataLoopNodes->Node(PriNode).MassFlowRate = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxPriAirMassFlow;
682 5968 : state.dataLoopNodes->Node(SecNode).MassFlowRate = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxSecAirMassFlow;
683 : }
684 : } else {
685 36 : state.dataLoopNodes->Node(PriNode).MassFlowRate = 0.0;
686 36 : state.dataLoopNodes->Node(SecNode).MassFlowRate = 0.0;
687 : }
688 : // reset the max and min avail flows
689 11992 : if (ScheduleManager::GetCurrentScheduleValue(state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).SchedPtr) > 0.0 &&
690 5988 : state.dataLoopNodes->Node(PriNode).MassFlowRateMaxAvail > 0.0) {
691 5968 : if (Util::SameString(state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
692 : "AirTerminal:SingleDuct:ConstantVolume:FourPipeInduction")) {
693 5968 : state.dataLoopNodes->Node(PriNode).MassFlowRateMaxAvail = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxPriAirMassFlow;
694 5968 : state.dataLoopNodes->Node(PriNode).MassFlowRateMinAvail = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxPriAirMassFlow;
695 5968 : state.dataLoopNodes->Node(SecNode).MassFlowRateMaxAvail = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxSecAirMassFlow;
696 5968 : state.dataLoopNodes->Node(SecNode).MassFlowRateMinAvail = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxSecAirMassFlow;
697 : }
698 : } else {
699 36 : state.dataLoopNodes->Node(PriNode).MassFlowRateMaxAvail = 0.0;
700 36 : state.dataLoopNodes->Node(PriNode).MassFlowRateMinAvail = 0.0;
701 36 : state.dataLoopNodes->Node(SecNode).MassFlowRateMaxAvail = 0.0;
702 36 : state.dataLoopNodes->Node(SecNode).MassFlowRateMinAvail = 0.0;
703 : }
704 : }
705 11976 : }
706 :
707 4 : void SizeIndUnit(EnergyPlusData &state, int const IUNum)
708 : {
709 :
710 : // SUBROUTINE INFORMATION:
711 : // AUTHOR Fred Buhl
712 : // DATE WRITTEN June 22 2004
713 : // MODIFIED August 2013 Daeho Kang, add component sizing table entries
714 :
715 : // PURPOSE OF THIS SUBROUTINE:
716 : // This subroutine is for sizing induction terminal units for which flow rates have not been
717 : // specified in the input
718 :
719 : // METHODOLOGY EMPLOYED:
720 : // Accesses zone sizing array for air flow rates and zone and plant sizing arrays to
721 : // calculate coil water flow rates.
722 :
723 : // SUBROUTINE PARAMETER DEFINITIONS:
724 : static constexpr std::string_view RoutineName("SizeIndUnit");
725 :
726 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
727 : Real64 DesCoilLoad;
728 : Real64 Cp; // local fluid specific heat
729 : Real64 rho; // local fluid density
730 :
731 4 : Real64 DesPriVolFlow = 0.0;
732 4 : Real64 CpAir = 0.0;
733 4 : Real64 RhoAir = state.dataEnvrn->StdRhoAir;
734 4 : bool ErrorsFound = false;
735 4 : bool IsAutoSize = false;
736 4 : Real64 MaxTotAirVolFlowDes = 0.0; // Desing size maximum air volume flow for reproting
737 4 : Real64 MaxTotAirVolFlowUser = 0.0; // User hard-sized maximum air volume flow for reporting
738 4 : Real64 MaxVolHotWaterFlowDes = 0.0; // Desing size maximum hot water flow for reproting
739 4 : Real64 MaxVolHotWaterFlowUser = 0.0; // User hard-sized maximum hot water flow for reporting
740 4 : Real64 MaxVolColdWaterFlowDes = 0.0; // Desing size maximum cold water flow for reproting
741 4 : Real64 MaxVolColdWaterFlowUser = 0.0; // User hard-sized maximum cold water flow for reporting
742 :
743 4 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirVolFlow == DataSizing::AutoSize) {
744 4 : IsAutoSize = true;
745 : }
746 :
747 4 : if (state.dataSize->CurZoneEqNum > 0) {
748 4 : if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // simulation continue
749 0 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirVolFlow > 0.0) {
750 0 : BaseSizer::reportSizerOutput(state,
751 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
752 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
753 : "User-Specified Maximum Total Air Flow Rate [m3/s]",
754 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirVolFlow);
755 : }
756 : } else {
757 4 : CheckZoneSizing(state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType, state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name);
758 4 : if (state.dataSize->CurTermUnitSizingNum > 0) {
759 4 : MaxTotAirVolFlowDes = max(state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolVolFlow,
760 4 : state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatVolFlow);
761 : } else {
762 0 : MaxTotAirVolFlowDes = 0.0;
763 : }
764 4 : if (MaxTotAirVolFlowDes < HVAC::SmallAirVolFlow) {
765 0 : MaxTotAirVolFlowDes = 0.0;
766 : }
767 4 : if (IsAutoSize) {
768 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirVolFlow = MaxTotAirVolFlowDes;
769 8 : BaseSizer::reportSizerOutput(state,
770 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
771 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
772 : "Design Size Maximum Total Air Flow Rate [m3/s]",
773 : MaxTotAirVolFlowDes);
774 : } else {
775 0 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirVolFlow > 0.0 && MaxTotAirVolFlowDes > 0.0) {
776 0 : MaxTotAirVolFlowUser = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirVolFlow;
777 0 : BaseSizer::reportSizerOutput(state,
778 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
779 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
780 : "Design Size Maximum Total Air Flow Rate [m3/s]",
781 : MaxTotAirVolFlowDes,
782 : "User-Specified Maximum Total Air Flow Rate [m3/s]",
783 : MaxTotAirVolFlowUser);
784 0 : if (state.dataGlobal->DisplayExtraWarnings) {
785 0 : if ((std::abs(MaxTotAirVolFlowDes - MaxTotAirVolFlowUser) / MaxTotAirVolFlowUser) >
786 0 : state.dataSize->AutoVsHardSizingThreshold) {
787 0 : ShowMessage(state,
788 0 : format("SizeHVACSingleDuctInduction: Potential issue with equipment sizing for {} = \"{}\".",
789 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
790 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
791 0 : ShowContinueError(state, format("User-Specified Maximum Total Air Flow Rate of {:.5R} [m3/s]", MaxTotAirVolFlowUser));
792 0 : ShowContinueError(
793 0 : state, format("differs from Design Size Maximum Total Air Flow Rate of {:.5R} [m3/s]", MaxTotAirVolFlowDes));
794 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
795 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
796 : }
797 : }
798 : }
799 : }
800 : }
801 : }
802 :
803 4 : IsAutoSize = false;
804 4 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolHotWaterFlow == DataSizing::AutoSize) {
805 4 : IsAutoSize = true;
806 : }
807 4 : if ((state.dataSize->CurZoneEqNum > 0) && (state.dataSize->CurTermUnitSizingNum > 0)) {
808 4 : if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // simulation continue
809 0 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolHotWaterFlow > 0.0) {
810 0 : BaseSizer::reportSizerOutput(state,
811 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
812 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
813 : "User-Specified Maximum Hot Water Flow Rate [m3/s]",
814 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolHotWaterFlow);
815 : }
816 : } else {
817 4 : CheckZoneSizing(state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType, state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name);
818 :
819 4 : if (Util::SameString(state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoilType, "Coil:Heating:Water")) {
820 :
821 4 : int CoilWaterInletNode = WaterCoils::GetCoilWaterInletNode(
822 4 : state, "Coil:Heating:Water", state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoil, ErrorsFound);
823 4 : int CoilWaterOutletNode = WaterCoils::GetCoilWaterOutletNode(
824 4 : state, "Coil:Heating:Water", state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoil, ErrorsFound);
825 4 : if (IsAutoSize) {
826 4 : int PltSizHeatNum = PlantUtilities::MyPlantSizingIndex(state,
827 : "Coil:Heating:Water",
828 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoil,
829 : CoilWaterInletNode,
830 : CoilWaterOutletNode,
831 : ErrorsFound);
832 4 : if (PltSizHeatNum > 0) {
833 :
834 4 : if (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatMassFlow >=
835 : HVAC::SmallAirVolFlow) {
836 4 : DesPriVolFlow = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirVolFlow /
837 4 : (1.0 + state.dataHVACSingleDuctInduc->IndUnit(IUNum).InducRatio);
838 4 : CpAir = Psychrometrics::PsyCpAirFnW(
839 4 : state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).HeatDesHumRat);
840 : // the design heating coil load is the zone load minus whatever the central system does. Note that
841 : // DesHeatCoilInTempTU is really the primary air inlet temperature for the unit.
842 4 : if (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtHeatPeak > 0.0) {
843 4 : DesCoilLoad =
844 4 : state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).NonAirSysDesHeatLoad -
845 8 : CpAir * RhoAir * DesPriVolFlow *
846 4 : (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatCoilInTempTU -
847 4 : state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtHeatPeak);
848 : } else {
849 0 : DesCoilLoad = CpAir * RhoAir * DesPriVolFlow *
850 0 : (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneSizThermSetPtLo -
851 0 : state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatCoilInTempTU);
852 : }
853 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).DesHeatingLoad = DesCoilLoad;
854 4 : Cp = FluidProperties::GetSpecificHeatGlycol(
855 : state,
856 4 : state.dataPlnt->PlantLoop(state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWPlantLoc.loopNum).FluidName,
857 : Constant::HWInitConvTemp,
858 4 : state.dataPlnt->PlantLoop(state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWPlantLoc.loopNum).FluidIndex,
859 : RoutineName);
860 :
861 4 : rho = FluidProperties::GetDensityGlycol(
862 : state,
863 4 : state.dataPlnt->PlantLoop(state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWPlantLoc.loopNum).FluidName,
864 : Constant::HWInitConvTemp,
865 4 : state.dataPlnt->PlantLoop(state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWPlantLoc.loopNum).FluidIndex,
866 : RoutineName);
867 :
868 4 : MaxVolHotWaterFlowDes = DesCoilLoad / (state.dataSize->PlantSizData(PltSizHeatNum).DeltaT * Cp * rho);
869 4 : MaxVolHotWaterFlowDes = max(MaxVolHotWaterFlowDes, 0.0);
870 : } else {
871 0 : MaxVolHotWaterFlowDes = 0.0;
872 : }
873 : } else {
874 0 : ShowSevereError(state, "Autosizing of water flow requires a heating loop Sizing:Plant object");
875 0 : ShowContinueError(state,
876 0 : format("Occurs in{} Object={}",
877 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
878 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
879 0 : ErrorsFound = true;
880 : }
881 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolHotWaterFlow = MaxVolHotWaterFlowDes;
882 8 : BaseSizer::reportSizerOutput(state,
883 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
884 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
885 : "Design Size Maximum Hot Water Flow Rate [m3/s]",
886 : MaxVolHotWaterFlowDes);
887 8 : BaseSizer::reportSizerOutput(
888 : state,
889 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
890 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
891 : "Design Size Inlet Air Temperature [C]",
892 4 : state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatCoilInTempTU);
893 8 : BaseSizer::reportSizerOutput(
894 : state,
895 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
896 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
897 : "Design Size Inlet Air Humidity Ratio [kgWater/kgDryAir]",
898 4 : state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesHeatCoilInHumRatTU);
899 : } else {
900 0 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolHotWaterFlow > 0.0 && MaxVolHotWaterFlowDes > 0.0) {
901 0 : MaxVolHotWaterFlowUser = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolHotWaterFlow;
902 0 : BaseSizer::reportSizerOutput(state,
903 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
904 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
905 : "Design Size Maximum Hot Water Flow Rate [m3/s]",
906 : MaxVolHotWaterFlowDes,
907 : "User-Specified Maximum Hot Water Flow Rate [m3/s]",
908 : MaxVolHotWaterFlowUser);
909 0 : if (state.dataGlobal->DisplayExtraWarnings) {
910 0 : if ((std::abs(MaxVolHotWaterFlowDes - MaxVolHotWaterFlowUser) / MaxVolHotWaterFlowUser) >
911 0 : state.dataSize->AutoVsHardSizingThreshold) {
912 0 : ShowMessage(state,
913 0 : format("SizeHVACSingleDuctInduction: Potential issue with equipment sizing for {} = \"{}\".",
914 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
915 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
916 0 : ShowContinueError(state,
917 0 : format("User-Specified Maximum Hot Water Flow Rate of {:.5R} [m3/s]", MaxVolHotWaterFlowUser));
918 0 : ShowContinueError(
919 : state,
920 0 : format("differs from Design Size Maximum Hot Water Flow Rate of {:.5R} [m3/s]", MaxVolHotWaterFlowDes));
921 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
922 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
923 : }
924 : }
925 : }
926 : }
927 : } else {
928 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolHotWaterFlow = 0.0;
929 : }
930 : }
931 : }
932 :
933 4 : IsAutoSize = false;
934 4 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolColdWaterFlow == DataSizing::AutoSize) {
935 4 : IsAutoSize = true;
936 : }
937 4 : if ((state.dataSize->CurZoneEqNum > 0) && (state.dataSize->CurTermUnitSizingNum > 0)) {
938 4 : if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) { // simulation continue
939 0 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolColdWaterFlow > 0.0) {
940 0 : BaseSizer::reportSizerOutput(state,
941 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
942 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
943 : "User-Specified Maximum Cold Water Flow Rate [m3/s]",
944 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolColdWaterFlow);
945 : }
946 : } else {
947 4 : CheckZoneSizing(state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType, state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name);
948 :
949 4 : if (Util::SameString(state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoilType, "Coil:Cooling:Water") ||
950 4 : Util::SameString(state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoilType, "Coil:Cooling:Water:DetailedGeometry")) {
951 :
952 4 : int CoilWaterInletNode = WaterCoils::GetCoilWaterInletNode(state,
953 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoilType,
954 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoil,
955 : ErrorsFound);
956 4 : int CoilWaterOutletNode = WaterCoils::GetCoilWaterOutletNode(state,
957 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoilType,
958 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoil,
959 : ErrorsFound);
960 4 : if (IsAutoSize) {
961 4 : int PltSizCoolNum = PlantUtilities::MyPlantSizingIndex(state,
962 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoilType,
963 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoil,
964 : CoilWaterInletNode,
965 : CoilWaterOutletNode,
966 : ErrorsFound);
967 4 : if (PltSizCoolNum > 0) {
968 :
969 4 : if (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolMassFlow >=
970 : HVAC::SmallAirVolFlow) {
971 4 : DesPriVolFlow = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirVolFlow /
972 4 : (1.0 + state.dataHVACSingleDuctInduc->IndUnit(IUNum).InducRatio);
973 4 : CpAir = Psychrometrics::PsyCpAirFnW(
974 4 : state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).CoolDesHumRat);
975 : // the design cooling coil load is the zone load minus whatever the central system does. Note that
976 : // DesCoolCoilInTempTU is really the primary air inlet temperature for the unit.
977 4 : if (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtCoolPeak > 0.0) {
978 4 : DesCoilLoad =
979 4 : state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).NonAirSysDesCoolLoad -
980 8 : CpAir * RhoAir * DesPriVolFlow *
981 4 : (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneTempAtCoolPeak -
982 4 : state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolCoilInTempTU);
983 : } else {
984 0 : DesCoilLoad = CpAir * RhoAir * DesPriVolFlow *
985 0 : (state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).DesCoolCoilInTempTU -
986 0 : state.dataSize->TermUnitFinalZoneSizing(state.dataSize->CurTermUnitSizingNum).ZoneSizThermSetPtHi);
987 : }
988 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).DesCoolingLoad = DesCoilLoad;
989 4 : Cp = FluidProperties::GetSpecificHeatGlycol(
990 : state,
991 4 : state.dataPlnt->PlantLoop(state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWPlantLoc.loopNum).FluidName,
992 : 5.0,
993 4 : state.dataPlnt->PlantLoop(state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWPlantLoc.loopNum).FluidIndex,
994 : RoutineName);
995 :
996 4 : rho = FluidProperties::GetDensityGlycol(
997 : state,
998 4 : state.dataPlnt->PlantLoop(state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWPlantLoc.loopNum).FluidName,
999 : 5.0,
1000 4 : state.dataPlnt->PlantLoop(state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWPlantLoc.loopNum).FluidIndex,
1001 : RoutineName);
1002 :
1003 4 : MaxVolColdWaterFlowDes = DesCoilLoad / (state.dataSize->PlantSizData(PltSizCoolNum).DeltaT * Cp * rho);
1004 4 : MaxVolColdWaterFlowDes = max(MaxVolColdWaterFlowDes, 0.0);
1005 : } else {
1006 0 : MaxVolColdWaterFlowDes = 0.0;
1007 : }
1008 : } else {
1009 0 : ShowSevereError(state, "Autosizing of water flow requires a cooling loop Sizing:Plant object");
1010 0 : ShowContinueError(state,
1011 0 : format("Occurs in{} Object={}",
1012 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
1013 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
1014 0 : ErrorsFound = true;
1015 : }
1016 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolColdWaterFlow = MaxVolColdWaterFlowDes;
1017 8 : BaseSizer::reportSizerOutput(state,
1018 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
1019 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
1020 : "Design Size Maximum Cold Water Flow Rate [m3/s]",
1021 : MaxVolColdWaterFlowDes);
1022 : } else {
1023 0 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolColdWaterFlow > 0.0 && MaxVolColdWaterFlowDes > 0.0) {
1024 0 : MaxVolColdWaterFlowUser = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolColdWaterFlow;
1025 0 : BaseSizer::reportSizerOutput(state,
1026 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
1027 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name,
1028 : "Design Size Maximum Cold Water Flow Rate [m3/s]",
1029 : MaxVolColdWaterFlowDes,
1030 : "User-Specified Maximum Cold Water Flow Rate [m3/s]",
1031 : MaxVolColdWaterFlowUser);
1032 0 : if (state.dataGlobal->DisplayExtraWarnings) {
1033 0 : if ((std::abs(MaxVolColdWaterFlowDes - MaxVolColdWaterFlowUser) / MaxVolColdWaterFlowUser) >
1034 0 : state.dataSize->AutoVsHardSizingThreshold) {
1035 0 : ShowMessage(state,
1036 0 : format("SizeHVACSingleDuctInduction: Potential issue with equipment sizing for {} = \"{}\".",
1037 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
1038 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
1039 0 : ShowContinueError(
1040 0 : state, format("User-Specified Maximum Cold Water Flow Rate of {:.5R} [m3/s]", MaxVolColdWaterFlowUser));
1041 0 : ShowContinueError(
1042 : state,
1043 0 : format("differs from Design Size Maximum Cold Water Flow Rate of {:.5R} [m3/s]", MaxVolColdWaterFlowDes));
1044 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1045 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1046 : }
1047 : }
1048 : }
1049 : }
1050 : } else {
1051 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolColdWaterFlow = 0.0;
1052 : }
1053 : }
1054 : }
1055 :
1056 4 : if (state.dataSize->CurTermUnitSizingNum > 0) {
1057 4 : auto &termUnitSizing = state.dataSize->TermUnitSizing(state.dataSize->CurTermUnitSizingNum);
1058 :
1059 : // note we save the induced air flow for use by the hw and cw coil sizing routines
1060 4 : termUnitSizing.AirVolFlow = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirVolFlow *
1061 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).InducRatio /
1062 4 : (1.0 + state.dataHVACSingleDuctInduc->IndUnit(IUNum).InducRatio);
1063 : // save the max hot and cold water flows for use in coil sizing
1064 4 : termUnitSizing.MaxHWVolFlow = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolHotWaterFlow;
1065 4 : termUnitSizing.MaxCWVolFlow = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxVolColdWaterFlow;
1066 : // save the design load used for reporting
1067 4 : termUnitSizing.DesCoolingLoad = state.dataHVACSingleDuctInduc->IndUnit(IUNum).DesCoolingLoad;
1068 4 : termUnitSizing.DesHeatingLoad = state.dataHVACSingleDuctInduc->IndUnit(IUNum).DesHeatingLoad;
1069 : // save the induction ratio for use in subsequent sizing calcs
1070 4 : termUnitSizing.InducRat = state.dataHVACSingleDuctInduc->IndUnit(IUNum).InducRatio;
1071 4 : if (Util::SameString(state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoilType, "Coil:Heating:Water")) {
1072 4 : WaterCoils::SetCoilDesFlow(state,
1073 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoilType,
1074 4 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoil,
1075 : termUnitSizing.AirVolFlow,
1076 : ErrorsFound);
1077 : }
1078 4 : if (Util::SameString(state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoilType, "Coil:Cooling:Water:DetailedGeometry")) {
1079 0 : WaterCoils::SetCoilDesFlow(state,
1080 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoilType,
1081 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoil,
1082 : termUnitSizing.AirVolFlow,
1083 : ErrorsFound);
1084 : }
1085 : }
1086 4 : }
1087 :
1088 11976 : void SimFourPipeIndUnit(EnergyPlusData &state,
1089 : int const IUNum, // number of the current unit being simulated
1090 : int const ZoneNum, // number of zone being served
1091 : int const ZoneNodeNum, // zone node number
1092 : bool const FirstHVACIteration // TRUE if 1st HVAC simulation of system timestep
1093 : )
1094 : {
1095 :
1096 : // SUBROUTINE INFORMATION:
1097 : // AUTHOR Fred Buhl
1098 : // DATE WRITTEN June 23 2004
1099 :
1100 : // PURPOSE OF THIS SUBROUTINE:
1101 : // Simulate a 4 pipe induction unit; adjust its heating or cooling
1102 : // coil outputs to match the zone load.
1103 :
1104 : // METHODOLOGY EMPLOYED:
1105 : // (1) From the zone load and the primary air inlet conditions calculate the coil load
1106 : // in the secondary air stream
1107 : // (2) If there is a cooling coil load, set the heating coil off and control the cooling
1108 : // coil to meet the coil load
1109 : // (3) If there is a heating coil load, control the heating coil to meet the load and keep
1110 : // the cooling coil off.
1111 :
1112 : // SUBROUTINE PARAMETER DEFINITIONS:
1113 11976 : int constexpr SolveMaxIter(50);
1114 :
1115 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1116 : Real64 HWFlow; // hot water flow [kg/s]
1117 : Real64 CWFlow; // cold water flow [kg/s]
1118 : Real64 QPriOnly; // unit output with no zone coils active
1119 : Real64 ErrTolerance;
1120 :
1121 11976 : bool UnitOn = true;
1122 11976 : Real64 PowerMet = 0.0;
1123 11976 : Real64 InducRat = state.dataHVACSingleDuctInduc->IndUnit(IUNum).InducRatio;
1124 11976 : int PriNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).PriAirInNode;
1125 11976 : int SecNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).SecAirInNode;
1126 11976 : int OutletNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).OutAirNode;
1127 11976 : int HotControlNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWControlNode;
1128 11976 : int HWOutletNode = DataPlant::CompData::getPlantComponent(state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWPlantLoc).NodeNumOut;
1129 11976 : int ColdControlNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWControlNode;
1130 11976 : int CWOutletNode = DataPlant::CompData::getPlantComponent(state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWPlantLoc).NodeNumOut;
1131 11976 : Real64 PriAirMassFlow = state.dataLoopNodes->Node(PriNode).MassFlowRateMaxAvail;
1132 11976 : Real64 SecAirMassFlow = InducRat * PriAirMassFlow;
1133 11976 : Real64 QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToHeatSP;
1134 11976 : Real64 QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToCoolSP;
1135 : // On the first HVAC iteration the system values are given to the controller, but after that
1136 : // the demand limits are in place and there needs to be feedback to the Zone Equipment
1137 :
1138 11976 : Real64 MaxHotWaterFlow = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxHotWaterFlow;
1139 11976 : PlantUtilities::SetComponentFlowRate(
1140 11976 : state, MaxHotWaterFlow, HotControlNode, HWOutletNode, state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWPlantLoc);
1141 :
1142 11976 : Real64 MinHotWaterFlow = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MinHotWaterFlow;
1143 11976 : PlantUtilities::SetComponentFlowRate(
1144 11976 : state, MinHotWaterFlow, HotControlNode, HWOutletNode, state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWPlantLoc);
1145 :
1146 11976 : Real64 MaxColdWaterFlow = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxColdWaterFlow;
1147 11976 : PlantUtilities::SetComponentFlowRate(
1148 11976 : state, MaxColdWaterFlow, ColdControlNode, CWOutletNode, state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWPlantLoc);
1149 :
1150 11976 : Real64 MinColdWaterFlow = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MinColdWaterFlow;
1151 11976 : PlantUtilities::SetComponentFlowRate(
1152 11976 : state, MinColdWaterFlow, ColdControlNode, CWOutletNode, state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWPlantLoc);
1153 :
1154 11976 : if (ScheduleManager::GetCurrentScheduleValue(state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).SchedPtr) <= 0.0) UnitOn = false;
1155 11976 : if (PriAirMassFlow <= HVAC::SmallMassFlow) UnitOn = false;
1156 :
1157 : // Set the unit's air inlet nodes mass flow rates
1158 11976 : state.dataLoopNodes->Node(PriNode).MassFlowRate = PriAirMassFlow;
1159 11976 : state.dataLoopNodes->Node(SecNode).MassFlowRate = SecAirMassFlow;
1160 : // initialize the water inlet nodes to minimum
1161 : // fire the unit at min water flow
1162 11976 : CalcFourPipeIndUnit(state, IUNum, FirstHVACIteration, ZoneNodeNum, MinHotWaterFlow, MinColdWaterFlow, QPriOnly);
1163 : // the load to be met by the secondary air stream coils is QZnReq-PowerMet
1164 :
1165 11976 : if (UnitOn) {
1166 :
1167 11928 : int SolFlag = 0;
1168 11928 : if (QToHeatSetPt - QPriOnly > HVAC::SmallLoad) {
1169 : // heating coil
1170 : // check that it can meet the load
1171 10099 : CalcFourPipeIndUnit(state, IUNum, FirstHVACIteration, ZoneNodeNum, MaxHotWaterFlow, MinColdWaterFlow, PowerMet);
1172 10099 : if (PowerMet > QToHeatSetPt + HVAC::SmallLoad) {
1173 10095 : ErrTolerance = state.dataHVACSingleDuctInduc->IndUnit(IUNum).HotControlOffset;
1174 : auto f = // (AUTO_OK_LAMBDA)
1175 194726 : [&state, IUNum, FirstHVACIteration, ZoneNodeNum, MinColdWaterFlow, QToHeatSetPt, QPriOnly, PowerMet](Real64 const HWFlow) {
1176 : Real64 UnitOutput;
1177 97363 : CalcFourPipeIndUnit(state, IUNum, FirstHVACIteration, ZoneNodeNum, HWFlow, MinColdWaterFlow, UnitOutput);
1178 97363 : return (QToHeatSetPt - UnitOutput) / (PowerMet - QPriOnly);
1179 10095 : };
1180 10095 : General::SolveRoot(state, ErrTolerance, SolveMaxIter, SolFlag, HWFlow, f, MinHotWaterFlow, MaxHotWaterFlow);
1181 10095 : if (SolFlag == -1) {
1182 0 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWCoilFailNum1 == 0) {
1183 0 : ShowWarningMessage(state,
1184 0 : format("SimFourPipeIndUnit: Hot water coil control failed for {}=\"{}\"",
1185 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
1186 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
1187 0 : ShowContinueErrorTimeStamp(state, "");
1188 0 : ShowContinueError(state, format(" Iteration limit [{}] exceeded in calculating hot water mass flow rate", SolveMaxIter));
1189 : }
1190 0 : ShowRecurringWarningErrorAtEnd(
1191 : state,
1192 0 : format("SimFourPipeIndUnit: Hot water coil control failed (iteration limit [{}]) for {}=\"{}\"",
1193 : SolveMaxIter,
1194 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
1195 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name),
1196 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWCoilFailNum1);
1197 10095 : } else if (SolFlag == -2) {
1198 0 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWCoilFailNum2 == 0) {
1199 0 : ShowWarningMessage(state,
1200 0 : format("SimFourPipeIndUnit: Hot water coil control failed (maximum flow limits) for {}=\"{}\"",
1201 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
1202 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
1203 0 : ShowContinueErrorTimeStamp(state, "");
1204 0 : ShowContinueError(state, "...Bad hot water maximum flow rate limits");
1205 0 : ShowContinueError(state, format("...Given minimum water flow rate={:.3R} kg/s", MinHotWaterFlow));
1206 0 : ShowContinueError(state, format("...Given maximum water flow rate={:.3R} kg/s", MaxHotWaterFlow));
1207 : }
1208 0 : ShowRecurringWarningErrorAtEnd(state,
1209 0 : "SimFourPipeIndUnit: Hot water coil control failed (flow limits) for " +
1210 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType + "=\"" +
1211 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name + "\"",
1212 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWCoilFailNum2,
1213 : MaxHotWaterFlow,
1214 : MinHotWaterFlow,
1215 : _,
1216 : "[kg/s]",
1217 : "[kg/s]");
1218 : }
1219 : }
1220 1829 : } else if (QToCoolSetPt - QPriOnly < -HVAC::SmallLoad) {
1221 : // cooling coil
1222 : // check that it can meet the load
1223 1801 : CalcFourPipeIndUnit(state, IUNum, FirstHVACIteration, ZoneNodeNum, MinHotWaterFlow, MaxColdWaterFlow, PowerMet);
1224 1801 : if (PowerMet < QToCoolSetPt - HVAC::SmallLoad) {
1225 1714 : ErrTolerance = state.dataHVACSingleDuctInduc->IndUnit(IUNum).ColdControlOffset;
1226 : auto f = // (AUTO_OK_LAMBDA)
1227 18654 : [&state, IUNum, FirstHVACIteration, ZoneNodeNum, MinHotWaterFlow, QToCoolSetPt, QPriOnly, PowerMet](Real64 const CWFlow) {
1228 : Real64 UnitOutput;
1229 9327 : CalcFourPipeIndUnit(state, IUNum, FirstHVACIteration, ZoneNodeNum, MinHotWaterFlow, CWFlow, UnitOutput);
1230 9327 : return (QToCoolSetPt - UnitOutput) / (PowerMet - QPriOnly);
1231 1714 : };
1232 1714 : General::SolveRoot(state, ErrTolerance, SolveMaxIter, SolFlag, CWFlow, f, MinColdWaterFlow, MaxColdWaterFlow);
1233 1714 : if (SolFlag == -1) {
1234 0 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWCoilFailNum1 == 0) {
1235 0 : ShowWarningMessage(state,
1236 0 : format("SimFourPipeIndUnit: Cold water coil control failed for {}=\"{}\"",
1237 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
1238 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
1239 0 : ShowContinueErrorTimeStamp(state, "");
1240 0 : ShowContinueError(state,
1241 0 : format(" Iteration limit [{}] exceeded in calculating cold water mass flow rate", SolveMaxIter));
1242 : }
1243 0 : ShowRecurringWarningErrorAtEnd(state,
1244 0 : format("SimFourPipeIndUnit: Cold water coil control failed (iteration limit [{}]) for {}=\"{}",
1245 : SolveMaxIter,
1246 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
1247 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name),
1248 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWCoilFailNum1);
1249 1714 : } else if (SolFlag == -2) {
1250 0 : if (state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWCoilFailNum2 == 0) {
1251 0 : ShowWarningMessage(state,
1252 0 : format("SimFourPipeIndUnit: Cold water coil control failed (maximum flow limits) for {}=\"{}\"",
1253 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType,
1254 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name));
1255 0 : ShowContinueErrorTimeStamp(state, "");
1256 0 : ShowContinueError(state, "...Bad cold water maximum flow rate limits");
1257 0 : ShowContinueError(state, format("...Given minimum water flow rate={:.3R} kg/s", MinColdWaterFlow));
1258 0 : ShowContinueError(state, format("...Given maximum water flow rate={:.3R} kg/s", MaxColdWaterFlow));
1259 : }
1260 0 : ShowRecurringWarningErrorAtEnd(state,
1261 0 : "SimFourPipeIndUnit: Cold water coil control failed (flow limits) for " +
1262 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).UnitType + "=\"" +
1263 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).Name + "\"",
1264 0 : state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWCoilFailNum2,
1265 : MaxColdWaterFlow,
1266 : MinColdWaterFlow,
1267 : _,
1268 : "[kg/s]",
1269 : "[kg/s]");
1270 : }
1271 : }
1272 : } else {
1273 28 : CalcFourPipeIndUnit(state, IUNum, FirstHVACIteration, ZoneNodeNum, MinHotWaterFlow, MinColdWaterFlow, PowerMet);
1274 : }
1275 :
1276 : } else {
1277 : // unit off
1278 48 : CalcFourPipeIndUnit(state, IUNum, FirstHVACIteration, ZoneNodeNum, MinHotWaterFlow, MinColdWaterFlow, PowerMet);
1279 : }
1280 11976 : state.dataLoopNodes->Node(OutletNode).MassFlowRateMax = state.dataHVACSingleDuctInduc->IndUnit(IUNum).MaxTotAirMassFlow;
1281 :
1282 : // At this point we are done. There is no output to report or pass back up: the output provided is calculated
1283 : // one level up in the calling routine SimZoneAirLoopEquipment. All the inlet and outlet flow rates and
1284 : // conditions have been set by CalcFourPipeIndUnit either explicitly or as a result of the simple component calls.
1285 11976 : }
1286 :
1287 130642 : void CalcFourPipeIndUnit(EnergyPlusData &state,
1288 : int const IUNum, // Unit index
1289 : bool const FirstHVACIteration, // flag for 1st HVAV iteration in the time step
1290 : int const ZoneNode, // zone node number
1291 : Real64 const HWFlow, // hot water flow (kg/s)
1292 : Real64 const CWFlow, // cold water flow (kg/s)
1293 : Real64 &LoadMet // load met by unit (watts)
1294 : )
1295 : {
1296 :
1297 : // SUBROUTINE INFORMATION:
1298 : // AUTHOR Fred Buhl
1299 : // DATE WRITTEN June 2004
1300 :
1301 : // PURPOSE OF THIS SUBROUTINE:
1302 : // Simulate the components making up the 4 pipe induction unit.
1303 :
1304 : // METHODOLOGY EMPLOYED:
1305 : // Simulates the unit components sequentially in the air flow direction.
1306 :
1307 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1308 : int OutletNode; // unit air outlet node
1309 : int PriNode; // unit primary air inlet node
1310 : int HotControlNode; // the hot water inlet node
1311 : int ColdControlNode; // the cold water inlet node
1312 : Real64 PriAirMassFlow; // primary air mass flow rate [kg/s]
1313 : Real64 SecAirMassFlow; // secondary air mass flow rate [kg/s]
1314 : Real64 TotAirMassFlow; // total air mass flow rate [kg/s]
1315 : Real64 InducRat; // induction ratio
1316 : Real64 mdotHW; // local temporary hot water flow rate [kg/s]
1317 : Real64 mdotCW; // local temporary cold water flow rate [kg/s]
1318 : int HWOutletNode;
1319 : int CWOutletNode;
1320 :
1321 130642 : PriNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).PriAirInNode;
1322 130642 : OutletNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).OutAirNode;
1323 130642 : PriAirMassFlow = state.dataLoopNodes->Node(PriNode).MassFlowRateMaxAvail;
1324 130642 : InducRat = state.dataHVACSingleDuctInduc->IndUnit(IUNum).InducRatio;
1325 130642 : SecAirMassFlow = InducRat * PriAirMassFlow;
1326 130642 : TotAirMassFlow = PriAirMassFlow + SecAirMassFlow;
1327 130642 : HotControlNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWControlNode;
1328 130642 : HWOutletNode = DataPlant::CompData::getPlantComponent(state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWPlantLoc).NodeNumOut;
1329 :
1330 130642 : ColdControlNode = state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWControlNode;
1331 130642 : CWOutletNode = DataPlant::CompData::getPlantComponent(state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWPlantLoc).NodeNumOut;
1332 :
1333 130642 : mdotHW = HWFlow;
1334 130642 : PlantUtilities::SetComponentFlowRate(state, mdotHW, HotControlNode, HWOutletNode, state.dataHVACSingleDuctInduc->IndUnit(IUNum).HWPlantLoc);
1335 :
1336 : // Node(HotControlNode)%MassFlowRate = HWFlow
1337 :
1338 130642 : mdotCW = CWFlow;
1339 130642 : PlantUtilities::SetComponentFlowRate(state, mdotCW, ColdControlNode, CWOutletNode, state.dataHVACSingleDuctInduc->IndUnit(IUNum).CWPlantLoc);
1340 : // Node(ColdControlNode)%MassFlowRate = CWFlow
1341 :
1342 261284 : WaterCoils::SimulateWaterCoilComponents(
1343 130642 : state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoil, FirstHVACIteration, state.dataHVACSingleDuctInduc->IndUnit(IUNum).HCoil_Num);
1344 261284 : WaterCoils::SimulateWaterCoilComponents(
1345 130642 : state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoil, FirstHVACIteration, state.dataHVACSingleDuctInduc->IndUnit(IUNum).CCoil_Num);
1346 130642 : MixerComponent::SimAirMixer(
1347 130642 : state, state.dataHVACSingleDuctInduc->IndUnit(IUNum).MixerName, state.dataHVACSingleDuctInduc->IndUnit(IUNum).Mixer_Num);
1348 130642 : LoadMet = TotAirMassFlow * Psychrometrics::PsyDeltaHSenFnTdb2W2Tdb1W1(state.dataLoopNodes->Node(OutletNode).Temp,
1349 130642 : state.dataLoopNodes->Node(OutletNode).HumRat,
1350 130642 : state.dataLoopNodes->Node(ZoneNode).Temp,
1351 130642 : state.dataLoopNodes->Node(ZoneNode).HumRat);
1352 130642 : }
1353 :
1354 6 : bool FourPipeInductionUnitHasMixer(EnergyPlusData &state, std::string_view CompName) // component (mixer) name
1355 : {
1356 :
1357 : // FUNCTION INFORMATION:
1358 : // AUTHOR Linda Lawrie
1359 : // DATE WRITTEN September 2011
1360 :
1361 : // PURPOSE OF THIS FUNCTION:
1362 : // Given a mixer name, this routine determines if that mixer is found on PIUnits.
1363 :
1364 6 : if (state.dataHVACSingleDuctInduc->GetIUInputFlag) {
1365 1 : GetIndUnits(state);
1366 1 : state.dataHVACSingleDuctInduc->GetIUInputFlag = false;
1367 : }
1368 :
1369 6 : if (state.dataHVACSingleDuctInduc->NumIndUnits > 0) {
1370 4 : int ItemNum = Util::FindItemInList(CompName, state.dataHVACSingleDuctInduc->IndUnit, &IndUnitData::MixerName);
1371 4 : if (ItemNum > 0) return true;
1372 : }
1373 :
1374 2 : return false;
1375 : }
1376 :
1377 11976 : void IndUnitData::ReportIndUnit(EnergyPlusData &state)
1378 : {
1379 : // set zone OA volume flow rate
1380 11976 : this->CalcOutdoorAirVolumeFlowRate(state);
1381 11976 : }
1382 :
1383 11976 : void IndUnitData::CalcOutdoorAirVolumeFlowRate(EnergyPlusData &state)
1384 : {
1385 : // calculates zone outdoor air volume flow rate using the supply air flow rate and OA fraction
1386 11976 : if (this->AirLoopNum > 0) {
1387 11972 : this->OutdoorAirFlowRate = (state.dataLoopNodes->Node(this->PriAirInNode).MassFlowRate / state.dataEnvrn->StdRhoAir) *
1388 11972 : state.dataAirLoop->AirLoopFlow(this->AirLoopNum).OAFrac;
1389 : } else {
1390 4 : this->OutdoorAirFlowRate = 0.0;
1391 : }
1392 11976 : }
1393 :
1394 4 : void IndUnitData::reportTerminalUnit(EnergyPlusData &state)
1395 : {
1396 : // populate the predefined equipment summary report related to air terminals
1397 4 : auto &orp = state.dataOutRptPredefined;
1398 4 : auto &adu = state.dataDefineEquipment->AirDistUnit(this->ADUNum);
1399 4 : if (!state.dataSize->TermUnitFinalZoneSizing.empty()) {
1400 4 : auto &sizing = state.dataSize->TermUnitFinalZoneSizing(adu.TermUnitSizingNum);
1401 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermMinFlow, adu.Name, sizing.DesCoolVolFlowMin);
1402 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermMinOutdoorFlow, adu.Name, sizing.MinOA);
1403 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermSupCoolingSP, adu.Name, sizing.CoolDesTemp);
1404 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermSupHeatingSP, adu.Name, sizing.HeatDesTemp);
1405 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermHeatingCap, adu.Name, sizing.DesHeatLoad);
1406 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermCoolingCap, adu.Name, sizing.DesCoolLoad);
1407 : }
1408 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermTypeInp, adu.Name, this->UnitType);
1409 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermPrimFlow, adu.Name, this->MaxPriAirMassFlow);
1410 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermSecdFlow, adu.Name, this->MaxSecAirMassFlow);
1411 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermMinFlowSch, adu.Name, "n/a");
1412 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermMaxFlowReh, adu.Name, "n/a");
1413 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermMinOAflowSch, adu.Name, "n/a");
1414 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermHeatCoilType, adu.Name, this->HCoilType);
1415 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermCoolCoilType, adu.Name, this->CCoilType);
1416 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermFanType, adu.Name, "n/a");
1417 4 : OutputReportPredefined::PreDefTableEntry(state, orp->pdchAirTermFanName, adu.Name, "n/a");
1418 4 : }
1419 :
1420 : } // namespace HVACSingleDuctInduc
1421 :
1422 : } // namespace EnergyPlus
|