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 : // 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/Coils/CoilCoolingDX.hh>
59 : #include <EnergyPlus/DXCoils.hh>
60 : #include <EnergyPlus/Data/EnergyPlusData.hh>
61 : #include <EnergyPlus/DataAirLoop.hh>
62 : #include <EnergyPlus/DataAirSystems.hh>
63 : #include <EnergyPlus/DataEnvironment.hh>
64 : #include <EnergyPlus/DataGlobals.hh>
65 : #include <EnergyPlus/DataLoopNode.hh>
66 : #include <EnergyPlus/DataSizing.hh>
67 : #include <EnergyPlus/DataZoneControls.hh>
68 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
69 : #include <EnergyPlus/DataZoneEquipment.hh>
70 : #include <EnergyPlus/EMSManager.hh>
71 : #include <EnergyPlus/Fans.hh>
72 : #include <EnergyPlus/FluidProperties.hh>
73 : #include <EnergyPlus/General.hh>
74 : #include <EnergyPlus/GeneralRoutines.hh>
75 : #include <EnergyPlus/HVACDXHeatPumpSystem.hh>
76 : #include <EnergyPlus/HVACHXAssistedCoolingCoil.hh>
77 : #include <EnergyPlus/HVACUnitaryBypassVAV.hh>
78 : #include <EnergyPlus/HeatingCoils.hh>
79 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
80 : #include <EnergyPlus/MixedAir.hh>
81 : #include <EnergyPlus/MixerComponent.hh>
82 : #include <EnergyPlus/NodeInputManager.hh>
83 : #include <EnergyPlus/OutputProcessor.hh>
84 : #include <EnergyPlus/Plant/DataPlant.hh>
85 : #include <EnergyPlus/PlantUtilities.hh>
86 : #include <EnergyPlus/Psychrometrics.hh>
87 : #include <EnergyPlus/ScheduleManager.hh>
88 : #include <EnergyPlus/SetPointManager.hh>
89 : #include <EnergyPlus/SteamCoils.hh>
90 : #include <EnergyPlus/UtilityRoutines.hh>
91 : #include <EnergyPlus/VariableSpeedCoils.hh>
92 : #include <EnergyPlus/WaterCoils.hh>
93 : #include <EnergyPlus/ZonePlenum.hh>
94 :
95 : namespace EnergyPlus {
96 :
97 : namespace HVACUnitaryBypassVAV {
98 :
99 : // Module containing the routines for modeling changeover-bypass VAV systems
100 :
101 : // MODULE INFORMATION:
102 : // AUTHOR Richard Raustad
103 : // DATE WRITTEN July 2006
104 : // MODIFIED B. Nigusse, FSEC - January 2012 - Added steam and hot water heating coils
105 :
106 : // PURPOSE OF THIS MODULE:
107 : // To encapsulate the data and algorithms needed to simulate changeover-bypass
108 : // variable-air-volume (CBVAV) systems, which are considered "Air Loop Equipment" in EnergyPlus
109 :
110 : // METHODOLOGY EMPLOYED:
111 : // Units are modeled as a collection of components: outside air mixer,
112 : // supply air fan, DX cooling coil, DX/gas/elec heating coil, and variable volume boxes.
113 : // Control is accomplished by calculating the load in all zones to determine a mode of operation.
114 : // The system will either cool, heat, or operate based on fan mode selection.
115 :
116 : // The CBVAV system is initialized with no load (coils off) to determine the outlet temperature.
117 : // A setpoint temperature is calculated on FirstHVACIteration = TRUE to force one VAV box fully open.
118 : // Once the setpoint is calculated, the inlet node mass flow rate on FirstHVACIteration = FALSE is used to
119 : // determine the bypass fraction. The simulation converges quickly on mass flow rate. If the zone
120 : // temperatures float in the deadband, additional iterations are required to converge on mass flow rate.
121 :
122 : // REFERENCES:
123 : // "Temp & VVT Commercial Comfort Systems," Engineering Training Manual, Technical Development Program, Carrier Corp., 1995.
124 : // "VariTrac Changeover Bypass VAV (Tracker System CB)," VAV-PRC003-EN, Trane Company, June 2004.
125 : // "Ventilation for Changeover-Bypass VAV Systems," D. Stanke, ASHRAE Journal Vol. 46, No. 11, November 2004.
126 : // Lawrence Berkeley Laboratory. Nov. 1993. DOE-2 Supplement Version 2.1E, Winklemann et.al.
127 :
128 0 : void SimUnitaryBypassVAV(EnergyPlusData &state,
129 : std::string_view CompName, // Name of the CBVAV system
130 : bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system time step
131 : int const AirLoopNum, // air loop index
132 : int &CompIndex // Index to changeover-bypass VAV system
133 : )
134 : {
135 :
136 : // SUBROUTINE INFORMATION:
137 : // AUTHOR Richard Raustad
138 : // DATE WRITTEN July 2006
139 :
140 : // PURPOSE OF THIS SUBROUTINE:
141 : // Manages the simulation of a changeover-bypass VAV system. Called from SimAirServingZones.
142 :
143 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
144 0 : int CBVAVNum = 0; // Index of CBVAV system being simulated
145 0 : Real64 QUnitOut = 0.0; // Sensible capacity delivered by this air loop system
146 :
147 : // First time SimUnitaryBypassVAV is called, get the input for all the CBVAVs
148 0 : if (state.dataHVACUnitaryBypassVAV->GetInputFlag) {
149 0 : GetCBVAV(state);
150 0 : state.dataHVACUnitaryBypassVAV->GetInputFlag = false;
151 : }
152 :
153 : // Find the correct changeover-bypass VAV unit
154 0 : if (CompIndex == 0) {
155 0 : CBVAVNum = Util::FindItemInList(CompName, state.dataHVACUnitaryBypassVAV->CBVAV);
156 0 : if (CBVAVNum == 0) {
157 0 : ShowFatalError(state, format("SimUnitaryBypassVAV: Unit not found={}", CompName));
158 : }
159 0 : CompIndex = CBVAVNum;
160 : } else {
161 0 : CBVAVNum = CompIndex;
162 0 : if (CBVAVNum > state.dataHVACUnitaryBypassVAV->NumCBVAV || CBVAVNum < 1) {
163 0 : ShowFatalError(state,
164 0 : format("SimUnitaryBypassVAV: Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
165 : CBVAVNum,
166 0 : state.dataHVACUnitaryBypassVAV->NumCBVAV,
167 : CompName));
168 : }
169 0 : if (state.dataHVACUnitaryBypassVAV->CheckEquipName(CBVAVNum)) {
170 0 : if (CompName != state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum).Name) {
171 0 : ShowFatalError(state,
172 0 : format("SimUnitaryBypassVAV: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
173 : CBVAVNum,
174 : CompName,
175 0 : state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum).Name));
176 : }
177 0 : state.dataHVACUnitaryBypassVAV->CheckEquipName(CBVAVNum) = false;
178 : }
179 : }
180 :
181 0 : Real64 OnOffAirFlowRatio = 0.0; // Ratio of compressor ON airflow to average airflow over timestep
182 0 : bool HXUnitOn = true; // flag to enable heat exchanger
183 :
184 : // Initialize the changeover-bypass VAV system
185 0 : InitCBVAV(state, CBVAVNum, FirstHVACIteration, AirLoopNum, OnOffAirFlowRatio, HXUnitOn);
186 :
187 : // Simulate the unit
188 0 : SimCBVAV(state, CBVAVNum, FirstHVACIteration, QUnitOut, OnOffAirFlowRatio, HXUnitOn);
189 :
190 : // Report the result of the simulation
191 0 : ReportCBVAV(state, CBVAVNum);
192 0 : }
193 :
194 1 : void SimCBVAV(EnergyPlusData &state,
195 : int const CBVAVNum, // Index of the current CBVAV system being simulated
196 : bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
197 : Real64 &QSensUnitOut, // Sensible delivered capacity [W]
198 : Real64 &OnOffAirFlowRatio, // Ratio of compressor ON airflow to AVERAGE airflow over timestep
199 : bool const HXUnitOn // flag to enable heat exchanger
200 : )
201 : {
202 :
203 : // SUBROUTINE INFORMATION:
204 : // AUTHOR Richard Raustad
205 : // DATE WRITTEN July 2006
206 :
207 : // PURPOSE OF THIS SUBROUTINE:
208 : // Simulate a changeover-bypass VAV system.
209 :
210 : // METHODOLOGY EMPLOYED:
211 : // Calls ControlCBVAVOutput to obtain the desired unit output
212 :
213 1 : QSensUnitOut = 0.0; // probably don't need this initialization
214 :
215 1 : auto &changeOverByPassVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
216 :
217 : // zero the fan and DX coils electricity consumption
218 1 : state.dataHVACGlobal->DXElecCoolingPower = 0.0;
219 1 : state.dataHVACGlobal->DXElecHeatingPower = 0.0;
220 1 : state.dataHVACGlobal->ElecHeatingCoilPower = 0.0;
221 1 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = 0.0;
222 1 : state.dataHVACGlobal->DefrostElecPower = 0.0;
223 :
224 : // initialize local variables
225 1 : bool UnitOn = true;
226 1 : int OutletNode = changeOverByPassVAV.AirOutNode;
227 1 : int InletNode = changeOverByPassVAV.AirInNode;
228 1 : Real64 AirMassFlow = state.dataLoopNodes->Node(InletNode).MassFlowRate;
229 1 : Real64 PartLoadFrac = 0.0;
230 :
231 : // set the on/off flags
232 1 : if (changeOverByPassVAV.fanOp == HVAC::FanOp::Cycling) {
233 : // cycling unit only runs if there is a cooling or heating load.
234 0 : if (changeOverByPassVAV.HeatCoolMode == 0 || AirMassFlow < HVAC::SmallMassFlow) {
235 0 : UnitOn = false;
236 : }
237 1 : } else if (changeOverByPassVAV.fanOp == HVAC::FanOp::Continuous) {
238 : // continuous unit: fan runs if scheduled on; coil runs only if there is a cooling or heating load
239 1 : if (AirMassFlow < HVAC::SmallMassFlow) {
240 0 : UnitOn = false;
241 : }
242 : }
243 :
244 1 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
245 :
246 1 : if (UnitOn) {
247 1 : ControlCBVAVOutput(state, CBVAVNum, FirstHVACIteration, PartLoadFrac, OnOffAirFlowRatio, HXUnitOn);
248 : } else {
249 0 : CalcCBVAV(state, CBVAVNum, FirstHVACIteration, PartLoadFrac, QSensUnitOut, OnOffAirFlowRatio, HXUnitOn);
250 : }
251 1 : if (changeOverByPassVAV.modeChanged) {
252 : // set outlet node SP for mixed air SP manager
253 0 : state.dataLoopNodes->Node(changeOverByPassVAV.AirOutNode).TempSetPoint = CalcSetPointTempTarget(state, CBVAVNum);
254 0 : if (changeOverByPassVAV.OutNodeSPMIndex > 0) { // update mixed air SPM if exists
255 0 : state.dataSetPointManager->spms(changeOverByPassVAV.OutNodeSPMIndex)->calculate(state); // update mixed air SP based on new mode
256 0 : SetPointManager::UpdateMixedAirSetPoints(state); // need to know control node to fire off just one of these, do this later
257 : }
258 : }
259 :
260 : // calculate delivered capacity
261 1 : AirMassFlow = state.dataLoopNodes->Node(OutletNode).MassFlowRate;
262 :
263 1 : Real64 QTotUnitOut = AirMassFlow * (state.dataLoopNodes->Node(OutletNode).Enthalpy - state.dataLoopNodes->Node(InletNode).Enthalpy);
264 :
265 1 : Real64 MinOutletHumRat = min(state.dataLoopNodes->Node(InletNode).HumRat, state.dataLoopNodes->Node(OutletNode).HumRat);
266 :
267 1 : QSensUnitOut = AirMassFlow * (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, MinOutletHumRat) -
268 1 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, MinOutletHumRat));
269 :
270 : // report variables
271 1 : changeOverByPassVAV.CompPartLoadRatio = state.dataHVACUnitaryBypassVAV->SaveCompressorPLR;
272 1 : if (UnitOn) {
273 1 : changeOverByPassVAV.FanPartLoadRatio = 1.0;
274 : } else {
275 0 : changeOverByPassVAV.FanPartLoadRatio = 0.0;
276 : }
277 :
278 1 : changeOverByPassVAV.TotCoolEnergyRate = std::abs(min(0.0, QTotUnitOut));
279 1 : changeOverByPassVAV.TotHeatEnergyRate = std::abs(max(0.0, QTotUnitOut));
280 1 : changeOverByPassVAV.SensCoolEnergyRate = std::abs(min(0.0, QSensUnitOut));
281 1 : changeOverByPassVAV.SensHeatEnergyRate = std::abs(max(0.0, QSensUnitOut));
282 1 : changeOverByPassVAV.LatCoolEnergyRate = std::abs(min(0.0, (QTotUnitOut - QSensUnitOut)));
283 1 : changeOverByPassVAV.LatHeatEnergyRate = std::abs(max(0.0, (QTotUnitOut - QSensUnitOut)));
284 :
285 1 : Real64 HeatingPower = 0.0; // DX Htg coil Plus CrankCase electric power use or electric heating coil [W]
286 1 : Real64 locDefrostPower = 0.0;
287 1 : if (changeOverByPassVAV.HeatCoilType == HVAC::CoilType::DXHeatingEmpirical) {
288 0 : HeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
289 0 : locDefrostPower = state.dataHVACGlobal->DefrostElecPower;
290 1 : } else if (changeOverByPassVAV.HeatCoilType == HVAC::CoilType::HeatingAirToAirVariableSpeed) {
291 1 : HeatingPower = state.dataHVACGlobal->DXElecHeatingPower;
292 1 : locDefrostPower = state.dataHVACGlobal->DefrostElecPower;
293 0 : } else if (changeOverByPassVAV.HeatCoilType == HVAC::CoilType::HeatingElectric) {
294 0 : HeatingPower = state.dataHVACGlobal->ElecHeatingCoilPower;
295 : } else {
296 0 : HeatingPower = 0.0;
297 : }
298 :
299 1 : Real64 locFanElecPower = state.dataFans->fans(changeOverByPassVAV.FanIndex)->totalPower;
300 :
301 1 : changeOverByPassVAV.ElecPower = locFanElecPower + state.dataHVACGlobal->DXElecCoolingPower + HeatingPower + locDefrostPower;
302 1 : }
303 :
304 2 : void GetCBVAV(EnergyPlusData &state)
305 : {
306 :
307 : // SUBROUTINE INFORMATION:
308 : // AUTHOR Richard Raustad
309 : // DATE WRITTEN July 2006
310 : // MODIFIED Bereket Nigusse, FSEC, April 2011: added OA Mixer object type
311 :
312 : // PURPOSE OF THIS SUBROUTINE:
313 : // Obtains input data for changeover-bypass VAV systems and stores it in CBVAV data structures
314 :
315 : // METHODOLOGY EMPLOYED:
316 : // Uses "Get" routines to read in data.
317 :
318 : // SUBROUTINE PARAMETER DEFINITIONS:
319 : static constexpr std::string_view routineName = "GetCBVAV";
320 : static constexpr std::string_view getUnitaryHeatCoolVAVChangeoverBypass("GetUnitaryHeatCool:VAVChangeoverBypass");
321 :
322 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
323 : int NumAlphas; // Number of Alphas for each GetObjectItem call
324 : int NumNumbers; // Number of Numbers for each GetObjectItem call
325 : int IOStatus; // Used in GetObjectItem
326 2 : std::string CompSetFanInlet; // Used in SetUpCompSets call
327 2 : std::string CompSetFanOutlet; // Used in SetUpCompSets call
328 2 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
329 2 : bool DXErrorsFound(false); // Set to true if errors in get coil input
330 2 : Array1D_int OANodeNums(4); // Node numbers of OA mixer (OA, EA, RA, MA)
331 : bool DXCoilErrFlag; // used in warning messages
332 :
333 2 : Array1D_string Alphas(20, "");
334 2 : Array1D<Real64> Numbers(9, 0.0);
335 4 : Array1D_string cAlphaFields(20, "");
336 2 : Array1D_string cNumericFields(9, "");
337 2 : Array1D_bool lAlphaBlanks(20, true);
338 2 : Array1D_bool lNumericBlanks(9, true);
339 :
340 : // find the number of each type of CBVAV unit
341 2 : std::string CurrentModuleObject = "AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass";
342 :
343 : // Update Num in state and make local convenience copy
344 4 : int NumCBVAV = state.dataHVACUnitaryBypassVAV->NumCBVAV =
345 2 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
346 :
347 : // allocate the data structures
348 2 : state.dataHVACUnitaryBypassVAV->CBVAV.resize(NumCBVAV);
349 2 : state.dataHVACUnitaryBypassVAV->CheckEquipName.dimension(NumCBVAV, true);
350 :
351 : // loop over CBVAV units; get and load the input data
352 4 : for (int CBVAVNum = 1; CBVAVNum <= NumCBVAV; ++CBVAVNum) {
353 2 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
354 : CurrentModuleObject,
355 : CBVAVNum,
356 : Alphas,
357 : NumAlphas,
358 : Numbers,
359 : NumNumbers,
360 : IOStatus,
361 : lNumericBlanks,
362 : lAlphaBlanks,
363 : cAlphaFields,
364 : cNumericFields);
365 :
366 2 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
367 :
368 2 : thisCBVAV.Name = Alphas(1);
369 :
370 2 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, thisCBVAV.Name};
371 :
372 2 : thisCBVAV.UnitType = CurrentModuleObject;
373 2 : if (lAlphaBlanks(2)) {
374 1 : thisCBVAV.availSched = Sched::GetScheduleAlwaysOn(state);
375 1 : } else if ((thisCBVAV.availSched = Sched::GetSchedule(state, Alphas(2))) == nullptr) {
376 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(2), Alphas(2));
377 0 : ErrorsFound = true;
378 : }
379 :
380 2 : thisCBVAV.MaxCoolAirVolFlow = Numbers(1);
381 2 : if (thisCBVAV.MaxCoolAirVolFlow <= 0.0 && thisCBVAV.MaxCoolAirVolFlow != DataSizing::AutoSize) {
382 0 : ShowSevereError(state, format("{} illegal {} = {:.7T}", CurrentModuleObject, cNumericFields(1), Numbers(1)));
383 0 : ShowContinueError(state, format("{} must be greater than zero.", cNumericFields(1)));
384 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
385 0 : ErrorsFound = true;
386 : }
387 :
388 2 : thisCBVAV.MaxHeatAirVolFlow = Numbers(2);
389 2 : if (thisCBVAV.MaxHeatAirVolFlow <= 0.0 && thisCBVAV.MaxHeatAirVolFlow != DataSizing::AutoSize) {
390 0 : ShowSevereError(state, format("{} illegal {} = {:.7T}", CurrentModuleObject, cNumericFields(2), Numbers(2)));
391 0 : ShowContinueError(state, format("{} must be greater than zero.", cNumericFields(2)));
392 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
393 0 : ErrorsFound = true;
394 : }
395 :
396 2 : thisCBVAV.MaxNoCoolHeatAirVolFlow = Numbers(3);
397 2 : if (thisCBVAV.MaxNoCoolHeatAirVolFlow < 0.0 && thisCBVAV.MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize) {
398 0 : ShowSevereError(state, format("{} illegal {} = {:.7T}", CurrentModuleObject, cNumericFields(3), Numbers(3)));
399 0 : ShowContinueError(state, format("{} must be greater than or equal to zero.", cNumericFields(3)));
400 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
401 0 : ErrorsFound = true;
402 : }
403 :
404 2 : thisCBVAV.CoolOutAirVolFlow = Numbers(4);
405 2 : if (thisCBVAV.CoolOutAirVolFlow < 0.0 && thisCBVAV.CoolOutAirVolFlow != DataSizing::AutoSize) {
406 0 : ShowSevereError(state, format("{} illegal {} = {:.7T}", CurrentModuleObject, cNumericFields(4), Numbers(4)));
407 0 : ShowContinueError(state, format("{} must be greater than or equal to zero.", cNumericFields(4)));
408 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
409 0 : ErrorsFound = true;
410 : }
411 :
412 2 : thisCBVAV.HeatOutAirVolFlow = Numbers(5);
413 2 : if (thisCBVAV.HeatOutAirVolFlow < 0.0 && thisCBVAV.HeatOutAirVolFlow != DataSizing::AutoSize) {
414 0 : ShowSevereError(state, format("{} illegal {} = {:.7T}", CurrentModuleObject, cNumericFields(5), Numbers(5)));
415 0 : ShowContinueError(state, format("{} must be greater than or equal to zero.", cNumericFields(5)));
416 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
417 0 : ErrorsFound = true;
418 : }
419 :
420 2 : thisCBVAV.NoCoolHeatOutAirVolFlow = Numbers(6);
421 2 : if (thisCBVAV.NoCoolHeatOutAirVolFlow < 0.0 && thisCBVAV.NoCoolHeatOutAirVolFlow != DataSizing::AutoSize) {
422 0 : ShowSevereError(state, format("{} illegal {} = {:.7T}", CurrentModuleObject, cNumericFields(6), Numbers(6)));
423 0 : ShowContinueError(state, format("{} must be greater than or equal to zero.", cNumericFields(6)));
424 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
425 0 : ErrorsFound = true;
426 : }
427 :
428 2 : thisCBVAV.outAirSched = Sched::GetSchedule(state, Alphas(3));
429 2 : if (thisCBVAV.outAirSched != nullptr) {
430 0 : if (!thisCBVAV.outAirSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 1.0)) {
431 0 : Sched::ShowSevereBadMinMax(state, eoh, cAlphaFields(3), Alphas(3), Clusive::In, 0.0, Clusive::In, 1.0);
432 0 : ErrorsFound = true;
433 : }
434 : }
435 :
436 2 : thisCBVAV.AirInNode =
437 2 : NodeInputManager::GetOnlySingleNode(state,
438 2 : Alphas(4),
439 : ErrorsFound,
440 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass,
441 2 : Alphas(1),
442 : DataLoopNode::NodeFluidType::Air,
443 : DataLoopNode::ConnectionType::Inlet,
444 : NodeInputManager::CompFluidStream::Primary,
445 : DataLoopNode::ObjectIsParent);
446 :
447 2 : std::string MixerInletNodeName = Alphas(5);
448 2 : std::string SplitterOutletNodeName = Alphas(6);
449 :
450 2 : thisCBVAV.AirOutNode =
451 2 : NodeInputManager::GetOnlySingleNode(state,
452 2 : Alphas(7),
453 : ErrorsFound,
454 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass,
455 2 : Alphas(1),
456 : DataLoopNode::NodeFluidType::Air,
457 : DataLoopNode::ConnectionType::Outlet,
458 : NodeInputManager::CompFluidStream::Primary,
459 : DataLoopNode::ObjectIsParent);
460 :
461 2 : thisCBVAV.SplitterOutletAirNode =
462 2 : NodeInputManager::GetOnlySingleNode(state,
463 : SplitterOutletNodeName,
464 : ErrorsFound,
465 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass,
466 2 : Alphas(1),
467 : DataLoopNode::NodeFluidType::Air,
468 : DataLoopNode::ConnectionType::Internal,
469 : NodeInputManager::CompFluidStream::Primary,
470 : DataLoopNode::ObjectIsParent);
471 :
472 2 : if (NumAlphas > 19 && !lAlphaBlanks(20)) {
473 0 : thisCBVAV.PlenumMixerInletAirNode =
474 0 : NodeInputManager::GetOnlySingleNode(state,
475 0 : Alphas(20),
476 : ErrorsFound,
477 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass,
478 0 : Alphas(1),
479 : DataLoopNode::NodeFluidType::Air,
480 : DataLoopNode::ConnectionType::Internal,
481 : NodeInputManager::CompFluidStream::Primary,
482 : DataLoopNode::ObjectIsParent);
483 0 : thisCBVAV.PlenumMixerInletAirNode =
484 0 : NodeInputManager::GetOnlySingleNode(state,
485 0 : Alphas(20),
486 : ErrorsFound,
487 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass,
488 0 : Alphas(1) + "_PlenumMixerInlet",
489 : DataLoopNode::NodeFluidType::Air,
490 : DataLoopNode::ConnectionType::Outlet,
491 : NodeInputManager::CompFluidStream::Primary,
492 : DataLoopNode::ObjectIsParent);
493 : }
494 :
495 2 : thisCBVAV.plenumIndex = ZonePlenum::getReturnPlenumIndexFromInletNode(state, thisCBVAV.PlenumMixerInletAirNode);
496 2 : thisCBVAV.mixerIndex = MixerComponent::getZoneMixerIndexFromInletNode(state, thisCBVAV.PlenumMixerInletAirNode);
497 2 : if (thisCBVAV.plenumIndex > 0 && thisCBVAV.mixerIndex > 0) {
498 0 : ShowSevereError(state, format("{}: {}", CurrentModuleObject, thisCBVAV.Name));
499 0 : ShowContinueError(state, format("Illegal connection for {} = \"{}\".", cAlphaFields(20), Alphas(20)));
500 0 : ShowContinueError(
501 0 : state, format("{} cannot be connected to both an AirloopHVAC:ReturnPlenum and an AirloopHVAC:ZoneMixer.", cAlphaFields(20)));
502 0 : ErrorsFound = true;
503 2 : } else if (thisCBVAV.plenumIndex == 0 && thisCBVAV.mixerIndex == 0 && thisCBVAV.PlenumMixerInletAirNode > 0) {
504 0 : ShowSevereError(state, format("{}: {}", CurrentModuleObject, thisCBVAV.Name));
505 0 : ShowContinueError(state, format("Illegal connection for {} = \"{}\".", cAlphaFields(20), Alphas(20)));
506 0 : ShowContinueError(
507 : state,
508 0 : format("{} must be connected to an AirloopHVAC:ReturnPlenum or AirloopHVAC:ZoneMixer. No connection found.", cAlphaFields(20)));
509 0 : ErrorsFound = true;
510 : }
511 :
512 2 : thisCBVAV.MixerInletAirNode =
513 2 : NodeInputManager::GetOnlySingleNode(state,
514 : MixerInletNodeName,
515 : ErrorsFound,
516 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass,
517 2 : Alphas(1),
518 : DataLoopNode::NodeFluidType::Air,
519 : DataLoopNode::ConnectionType::Internal,
520 : NodeInputManager::CompFluidStream::Primary,
521 : DataLoopNode::ObjectIsParent);
522 :
523 2 : thisCBVAV.MixerInletAirNode =
524 4 : NodeInputManager::GetOnlySingleNode(state,
525 : MixerInletNodeName,
526 : ErrorsFound,
527 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass,
528 4 : Alphas(1) + "_Mixer",
529 : DataLoopNode::NodeFluidType::Air,
530 : DataLoopNode::ConnectionType::Outlet,
531 : NodeInputManager::CompFluidStream::Primary,
532 : DataLoopNode::ObjectIsParent);
533 :
534 2 : thisCBVAV.SplitterOutletAirNode =
535 4 : NodeInputManager::GetOnlySingleNode(state,
536 : SplitterOutletNodeName,
537 : ErrorsFound,
538 : DataLoopNode::ConnectionObjectType::AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass,
539 4 : Alphas(1) + "_Splitter",
540 : DataLoopNode::NodeFluidType::Air,
541 : DataLoopNode::ConnectionType::Inlet,
542 : NodeInputManager::CompFluidStream::Primary,
543 : DataLoopNode::ObjectIsParent);
544 :
545 2 : thisCBVAV.OAMixType = Alphas(8);
546 2 : thisCBVAV.OAMixName = Alphas(9);
547 :
548 2 : bool errFlag = false;
549 2 : ValidateComponent(state, thisCBVAV.OAMixType, thisCBVAV.OAMixName, errFlag, CurrentModuleObject);
550 2 : if (errFlag) {
551 0 : ShowContinueError(state, format("specified in {} = \"{}\".", CurrentModuleObject, thisCBVAV.Name));
552 0 : ErrorsFound = true;
553 : } else {
554 : // Get OA Mixer node numbers
555 2 : OANodeNums = MixedAir::GetOAMixerNodeNumbers(state, thisCBVAV.OAMixName, errFlag);
556 2 : if (errFlag) {
557 0 : ShowContinueError(state, format("that was specified in {} = {}", CurrentModuleObject, thisCBVAV.Name));
558 0 : ShowContinueError(state, "..OutdoorAir:Mixer is required. Enter an OutdoorAir:Mixer object with this name.");
559 0 : ErrorsFound = true;
560 : } else {
561 2 : thisCBVAV.MixerOutsideAirNode = OANodeNums(1);
562 2 : thisCBVAV.MixerReliefAirNode = OANodeNums(2);
563 : // thisCBVAV%MixerInletAirNode = OANodeNums(3)
564 2 : thisCBVAV.MixerMixedAirNode = OANodeNums(4);
565 : }
566 : }
567 :
568 2 : if (thisCBVAV.MixerInletAirNode != OANodeNums(3)) {
569 0 : ShowSevereError(state, format("{}: {}", CurrentModuleObject, thisCBVAV.Name));
570 0 : ShowContinueError(state, format("Illegal {} = {}.", cAlphaFields(5), MixerInletNodeName));
571 0 : ShowContinueError(
572 0 : state, format("{} must be the same as the return air stream node specified in the OutdoorAir:Mixer object.", cAlphaFields(5)));
573 0 : ErrorsFound = true;
574 : }
575 :
576 2 : if (thisCBVAV.MixerInletAirNode == thisCBVAV.AirInNode) {
577 0 : ShowSevereError(state, format("{}: {}", CurrentModuleObject, thisCBVAV.Name));
578 0 : ShowContinueError(state, format("Illegal {} = {}.", cAlphaFields(5), MixerInletNodeName));
579 0 : ShowContinueError(state, format("{} must be different than the {}.", cAlphaFields(5), cAlphaFields(4)));
580 0 : ErrorsFound = true;
581 : }
582 :
583 2 : if (thisCBVAV.SplitterOutletAirNode == thisCBVAV.AirOutNode) {
584 0 : ShowSevereError(state, format("{}: {}", CurrentModuleObject, thisCBVAV.Name));
585 0 : ShowContinueError(state, format("Illegal {} = {}.", cAlphaFields(6), SplitterOutletNodeName));
586 0 : ShowContinueError(state, format("{} must be different than the {}.", cAlphaFields(6), cAlphaFields(7)));
587 0 : ErrorsFound = true;
588 : }
589 :
590 : // required field must be Key=Fan:ConstantVolume, Fan:OnOff or Fan:SystemModel and read in as upper case
591 2 : thisCBVAV.fanType = static_cast<HVAC::FanType>(getEnumValue(HVAC::fanTypeNamesUC, Alphas(10)));
592 2 : assert(thisCBVAV.fanType != HVAC::FanType::Invalid);
593 :
594 2 : thisCBVAV.FanName = Alphas(11);
595 2 : int fanOutletNode(0);
596 :
597 : // check that the fan exists
598 2 : if ((thisCBVAV.FanIndex = Fans::GetFanIndex(state, thisCBVAV.FanName)) == 0) {
599 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(11), thisCBVAV.FanName);
600 0 : ErrorsFound = true;
601 0 : thisCBVAV.FanVolFlow = 9999.0;
602 : } else {
603 2 : auto *fan = state.dataFans->fans(thisCBVAV.FanIndex);
604 2 : thisCBVAV.FanInletNodeNum = fan->inletNodeNum;
605 2 : fanOutletNode = fan->outletNodeNum;
606 2 : thisCBVAV.FanVolFlow = fan->maxAirFlowRate;
607 : }
608 :
609 : // required field must be Key=BlowThrough or DrawThrough and read in as BLOWTHROUGH or DRAWTHROUGH
610 2 : thisCBVAV.fanPlace = static_cast<HVAC::FanPlace>(getEnumValue(HVAC::fanPlaceNamesUC, Alphas(12)));
611 :
612 2 : if (thisCBVAV.fanPlace == HVAC::FanPlace::DrawThru) {
613 1 : if (thisCBVAV.SplitterOutletAirNode != fanOutletNode) {
614 0 : ShowSevereError(state, format("{}: {}", CurrentModuleObject, thisCBVAV.Name));
615 0 : ShowContinueError(state, format("Illegal {} = {}.", cAlphaFields(6), SplitterOutletNodeName));
616 0 : ShowContinueError(state,
617 0 : format("{} must be the same as the fan outlet node specified in {} = {}: {} when draw through {} is selected.",
618 : cAlphaFields(6),
619 : cAlphaFields(10),
620 : Alphas(10),
621 0 : thisCBVAV.FanName,
622 : cAlphaFields(11)));
623 0 : ErrorsFound = true;
624 : }
625 : }
626 :
627 2 : if (thisCBVAV.FanVolFlow != DataSizing::AutoSize) {
628 2 : if (thisCBVAV.FanVolFlow < thisCBVAV.MaxCoolAirVolFlow && thisCBVAV.MaxCoolAirVolFlow != DataSizing::AutoSize) {
629 0 : ShowWarningError(state,
630 0 : format("{} - air flow rate = {:.7T} in {} = {} is less than the ",
631 : CurrentModuleObject,
632 0 : thisCBVAV.FanVolFlow,
633 : cAlphaFields(11),
634 0 : thisCBVAV.FanName) +
635 0 : cNumericFields(1));
636 0 : ShowContinueError(state, format(" {} is reset to the fan flow rate and the simulation continues.", cNumericFields(1)));
637 0 : ShowContinueError(state, format(" Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
638 0 : thisCBVAV.MaxCoolAirVolFlow = thisCBVAV.FanVolFlow;
639 : }
640 2 : if (thisCBVAV.FanVolFlow < thisCBVAV.MaxHeatAirVolFlow && thisCBVAV.MaxHeatAirVolFlow != DataSizing::AutoSize) {
641 0 : ShowWarningError(state,
642 0 : format("{} - air flow rate = {:.7T} in {} = {} is less than the ",
643 : CurrentModuleObject,
644 0 : thisCBVAV.FanVolFlow,
645 : cAlphaFields(11),
646 0 : thisCBVAV.FanName) +
647 0 : cNumericFields(2));
648 0 : ShowContinueError(state, format(" {} is reset to the fan flow rate and the simulation continues.", cNumericFields(2)));
649 0 : ShowContinueError(state, format(" Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
650 0 : thisCBVAV.MaxHeatAirVolFlow = thisCBVAV.FanVolFlow;
651 : }
652 : }
653 :
654 : // only check that OA flow in cooling is >= SA flow in cooling when they are not autosized
655 2 : if (thisCBVAV.CoolOutAirVolFlow > thisCBVAV.MaxCoolAirVolFlow && thisCBVAV.CoolOutAirVolFlow != DataSizing::AutoSize &&
656 0 : thisCBVAV.MaxCoolAirVolFlow != DataSizing::AutoSize) {
657 0 : ShowWarningError(state, format("{}: {} cannot be greater than {}", CurrentModuleObject, cNumericFields(4), cNumericFields(1)));
658 0 : ShowContinueError(state, format(" {} is reset to the fan flow rate and the simulation continues.", cNumericFields(4)));
659 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
660 0 : thisCBVAV.CoolOutAirVolFlow = thisCBVAV.FanVolFlow;
661 : }
662 :
663 : // only check that SA flow in heating is >= OA flow in heating when they are not autosized
664 2 : if (thisCBVAV.HeatOutAirVolFlow > thisCBVAV.MaxHeatAirVolFlow && thisCBVAV.HeatOutAirVolFlow != DataSizing::AutoSize &&
665 0 : thisCBVAV.MaxHeatAirVolFlow != DataSizing::AutoSize) {
666 0 : ShowWarningError(state, format("{}: {} cannot be greater than {}", CurrentModuleObject, cNumericFields(5), cNumericFields(2)));
667 0 : ShowContinueError(state, format(" {} is reset to the fan flow rate and the simulation continues.", cNumericFields(5)));
668 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
669 0 : thisCBVAV.HeatOutAirVolFlow = thisCBVAV.FanVolFlow;
670 : }
671 :
672 2 : std::string thisCoolCoilType = Alphas(14);
673 2 : thisCBVAV.CoolCoilType = static_cast<HVAC::CoilType>(getEnumValue(HVAC::coilTypeNamesUC, thisCoolCoilType));
674 2 : thisCBVAV.DXCoolCoilName = Alphas(15);
675 :
676 2 : if (thisCBVAV.CoolCoilType == HVAC::CoilType::DXCoolingSingleSpeed) {
677 1 : DXCoilErrFlag = false;
678 1 : DXCoils::GetDXCoilIndex(state, thisCBVAV.DXCoolCoilName, thisCBVAV.DXCoolCoilIndexNum, DXCoilErrFlag, thisCoolCoilType);
679 1 : if (DXCoilErrFlag) {
680 0 : ShowContinueError(state, format("...occurs in {} \"{}\"", thisCBVAV.UnitType, thisCBVAV.Name));
681 0 : ErrorsFound = true;
682 : } else {
683 1 : thisCBVAV.DXCoilInletNode = state.dataDXCoils->DXCoil(thisCBVAV.DXCoolCoilIndexNum).AirInNode;
684 1 : thisCBVAV.DXCoilOutletNode = state.dataDXCoils->DXCoil(thisCBVAV.DXCoolCoilIndexNum).AirOutNode;
685 1 : thisCBVAV.CondenserNodeNum = state.dataDXCoils->DXCoil(thisCBVAV.DXCoolCoilIndexNum).CondenserInletNodeNum(1);
686 : }
687 1 : } else if (thisCBVAV.CoolCoilType == HVAC::CoilType::CoolingAirToAirVariableSpeed) {
688 1 : DXCoilErrFlag = false;
689 1 : thisCBVAV.DXCoolCoilIndexNum =
690 1 : VariableSpeedCoils::GetCoilIndexVariableSpeed(state, thisCoolCoilType, thisCBVAV.DXCoolCoilName, DXCoilErrFlag);
691 1 : if (DXCoilErrFlag) {
692 0 : ShowContinueError(state, format("...occurs in {} \"{}\"", thisCBVAV.UnitType, thisCBVAV.Name));
693 0 : ErrorsFound = true;
694 : } else {
695 1 : thisCBVAV.DXCoilInletNode = state.dataVariableSpeedCoils->VarSpeedCoil(thisCBVAV.DXCoolCoilIndexNum).AirInletNodeNum;
696 1 : thisCBVAV.DXCoilOutletNode = state.dataVariableSpeedCoils->VarSpeedCoil(thisCBVAV.DXCoolCoilIndexNum).AirOutletNodeNum;
697 1 : thisCBVAV.CondenserNodeNum = state.dataVariableSpeedCoils->VarSpeedCoil(thisCBVAV.DXCoolCoilIndexNum).CondenserInletNodeNum;
698 : }
699 0 : } else if (thisCBVAV.CoolCoilType == HVAC::CoilType::DXCoolingHXAssisted) {
700 0 : DXCoilErrFlag = false;
701 : int ActualCoolCoilType =
702 0 : HVACHXAssistedCoolingCoil::GetCoilObjectTypeNum(state, thisCoolCoilType, thisCBVAV.DXCoolCoilName, DXErrorsFound);
703 0 : if (DXErrorsFound) {
704 0 : ShowSevereError(state, format("{}: {}", CurrentModuleObject, thisCBVAV.Name));
705 0 : ShowContinueError(state, format("CoilSystem:Cooling:DX:HeatExchangerAssisted \"{}\" not found.", thisCBVAV.DXCoolCoilName));
706 0 : ErrorsFound = true;
707 : } else {
708 0 : if (ActualCoolCoilType == HVAC::CoilDX_CoolingSingleSpeed) {
709 0 : DXCoils::GetDXCoilIndex(
710 : state,
711 0 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, thisCoolCoilType, thisCBVAV.DXCoolCoilName, DXCoilErrFlag),
712 0 : thisCBVAV.DXCoolCoilIndexNum,
713 : DXCoilErrFlag,
714 : "Coil:Cooling:DX:SingleSpeed");
715 0 : if (DXCoilErrFlag) {
716 0 : ShowContinueError(state, format("...occurs in {} \"{}\"", thisCBVAV.UnitType, thisCBVAV.Name));
717 0 : ErrorsFound = true;
718 : } else {
719 : // the "coil" nodes are actually the parent nodes of the wrapped HX
720 0 : thisCBVAV.DXCoilInletNode =
721 0 : HVACHXAssistedCoolingCoil::GetCoilInletNode(state, thisCoolCoilType, thisCBVAV.DXCoolCoilName, DXErrorsFound);
722 0 : thisCBVAV.DXCoilOutletNode =
723 0 : HVACHXAssistedCoolingCoil::GetCoilOutletNode(state, thisCoolCoilType, thisCBVAV.DXCoolCoilName, DXErrorsFound);
724 : // the DX coil holds the condenser inlet node number
725 0 : thisCBVAV.CondenserNodeNum = state.dataDXCoils->DXCoil(thisCBVAV.DXCoolCoilIndexNum).CondenserInletNodeNum(1);
726 : }
727 0 : } else if (ActualCoolCoilType == HVAC::Coil_CoolingAirToAirVariableSpeed) {
728 0 : thisCBVAV.DXCoolCoilIndexNum = VariableSpeedCoils::GetCoilIndexVariableSpeed(
729 : state,
730 : "Coil:Cooling:DX:VariableSpeed",
731 0 : HVACHXAssistedCoolingCoil::GetHXDXCoilName(state, thisCoolCoilType, thisCBVAV.DXCoolCoilName, DXCoilErrFlag),
732 : DXCoilErrFlag);
733 0 : if (DXCoilErrFlag) {
734 0 : ShowContinueError(state, format("...occurs in {} \"{}\"", thisCBVAV.UnitType, thisCBVAV.Name));
735 0 : ErrorsFound = true;
736 : } else {
737 0 : thisCBVAV.DXCoilInletNode = state.dataVariableSpeedCoils->VarSpeedCoil(thisCBVAV.DXCoolCoilIndexNum).AirInletNodeNum;
738 0 : thisCBVAV.DXCoilOutletNode = state.dataVariableSpeedCoils->VarSpeedCoil(thisCBVAV.DXCoolCoilIndexNum).AirOutletNodeNum;
739 0 : thisCBVAV.CondenserNodeNum =
740 0 : state.dataVariableSpeedCoils->VarSpeedCoil(thisCBVAV.DXCoolCoilIndexNum).CondenserInletNodeNum;
741 : }
742 0 : } else if (ActualCoolCoilType == HVAC::CoilDX_Cooling) {
743 0 : thisCBVAV.DXCoolCoilIndexNum = CoilCoolingDX::factory(state, thisCBVAV.DXCoolCoilName);
744 0 : if (thisCBVAV.DXCoolCoilIndexNum == -1) {
745 0 : ShowContinueError(state, format("...occurs in {} \"{}\"", thisCBVAV.UnitType, thisCBVAV.Name));
746 0 : ErrorsFound = true;
747 : } else {
748 0 : auto const &newCoil = state.dataCoilCoolingDX->coilCoolingDXs[thisCBVAV.DXCoolCoilIndexNum];
749 0 : thisCBVAV.DXCoilInletNode = newCoil.evapInletNodeIndex;
750 0 : thisCBVAV.DXCoilOutletNode = newCoil.evapOutletNodeIndex;
751 0 : thisCBVAV.CondenserNodeNum = newCoil.condInletNodeIndex;
752 : }
753 : }
754 : }
755 0 : } else if (thisCBVAV.CoolCoilType == HVAC::CoilType::DXCoolingTwoStageWHumControl) {
756 0 : DXCoilErrFlag = false;
757 0 : DXCoils::GetDXCoilIndex(state, thisCBVAV.DXCoolCoilName, thisCBVAV.DXCoolCoilIndexNum, DXCoilErrFlag, thisCoolCoilType);
758 0 : if (DXCoilErrFlag) {
759 0 : ShowContinueError(state, format("...occurs in {} \"{}\"", thisCBVAV.UnitType, thisCBVAV.Name));
760 0 : ErrorsFound = true;
761 : } else {
762 0 : thisCBVAV.DXCoilInletNode = state.dataDXCoils->DXCoil(thisCBVAV.DXCoolCoilIndexNum).AirInNode;
763 0 : thisCBVAV.DXCoilOutletNode = state.dataDXCoils->DXCoil(thisCBVAV.DXCoolCoilIndexNum).AirOutNode;
764 0 : thisCBVAV.CondenserNodeNum = state.dataDXCoils->DXCoil(thisCBVAV.DXCoolCoilIndexNum).CondenserInletNodeNum(1);
765 : }
766 : }
767 :
768 2 : thisCBVAV.fanOpModeSched = Sched::GetSchedule(state, Alphas(13));
769 2 : if (thisCBVAV.fanOpModeSched != nullptr) {
770 0 : if (!thisCBVAV.fanOpModeSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 1.0)) {
771 0 : Sched::ShowSevereBadMinMax(state, eoh, cAlphaFields(13), Alphas(13), Clusive::In, 0.0, Clusive::In, 1.0);
772 0 : ShowContinueError(state, "A value of 0 represents cycling fan mode, any other value up to 1 represents constant fan mode.");
773 0 : ErrorsFound = true;
774 : }
775 :
776 : // Check supply air fan operating mode for cycling fan, if NOT cycling fan set AirFlowControl
777 0 : if (!thisCBVAV.fanOpModeSched->checkMinMaxVals(state, Clusive::In, 0.0, Clusive::In, 0.0)) { // Autodesk:Note Range is 0 to 0?
778 : // set air flow control mode,
779 : // UseCompressorOnFlow = operate at last cooling or heating air flow requested when compressor is off
780 : // UseCompressorOffFlow = operate at value specified by user (no input for this object type, UseCompONFlow)
781 : // AirFlowControl only valid if fan opmode = HVAC::FanOp::Continuous
782 0 : thisCBVAV.AirFlowControl =
783 0 : (thisCBVAV.MaxNoCoolHeatAirVolFlow == 0.0) ? AirFlowCtrlMode::UseCompressorOnFlow : AirFlowCtrlMode::UseCompressorOffFlow;
784 : }
785 :
786 : } else {
787 2 : if (!lAlphaBlanks(13)) {
788 1 : ShowWarningError(state, format("{}: {}", CurrentModuleObject, thisCBVAV.Name));
789 2 : ShowContinueError(state,
790 2 : format("{} = {} not found. Supply air fan operating mode set to constant operation and simulation continues.",
791 : cAlphaFields(13),
792 : Alphas(13)));
793 : }
794 2 : thisCBVAV.fanOp = HVAC::FanOp::Continuous;
795 2 : if (thisCBVAV.MaxNoCoolHeatAirVolFlow == 0.0) {
796 0 : thisCBVAV.AirFlowControl = AirFlowCtrlMode::UseCompressorOnFlow;
797 : } else {
798 2 : thisCBVAV.AirFlowControl = AirFlowCtrlMode::UseCompressorOffFlow;
799 : }
800 : }
801 :
802 : // Check FanVolFlow, must be >= CBVAV flow
803 2 : if (thisCBVAV.FanVolFlow != DataSizing::AutoSize) {
804 2 : if (thisCBVAV.FanVolFlow < thisCBVAV.MaxNoCoolHeatAirVolFlow && thisCBVAV.MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize &&
805 0 : thisCBVAV.MaxNoCoolHeatAirVolFlow != 0.0) {
806 0 : ShowWarningError(state,
807 0 : format("{} - air flow rate = {:.7T} in {} = {} is less than ",
808 : CurrentModuleObject,
809 0 : thisCBVAV.FanVolFlow,
810 : cAlphaFields(11),
811 0 : thisCBVAV.FanName) +
812 0 : cNumericFields(3));
813 0 : ShowContinueError(state, format(" {} is reset to the fan flow rate and the simulation continues.", cNumericFields(3)));
814 0 : ShowContinueError(state, format(" Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
815 0 : thisCBVAV.MaxNoCoolHeatAirVolFlow = thisCBVAV.FanVolFlow;
816 : }
817 : }
818 : // only check that OA flow when compressor is OFF is >= SA flow when compressor is OFF when both are not autosized and
819 : // that MaxNoCoolHeatAirVolFlow is /= 0 (trigger to use compressor ON flow, see AirFlowControl variable initialization above)
820 2 : if (thisCBVAV.NoCoolHeatOutAirVolFlow > thisCBVAV.MaxNoCoolHeatAirVolFlow && thisCBVAV.NoCoolHeatOutAirVolFlow != DataSizing::AutoSize &&
821 0 : thisCBVAV.MaxNoCoolHeatAirVolFlow != DataSizing::AutoSize && thisCBVAV.MaxNoCoolHeatAirVolFlow != 0.0) {
822 0 : ShowWarningError(state, format("{}: {} cannot be greater than {}", CurrentModuleObject, cNumericFields(6), cNumericFields(3)));
823 0 : ShowContinueError(state, format(" {} is reset to the fan flow rate and the simulation continues.", cNumericFields(6)));
824 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
825 0 : thisCBVAV.NoCoolHeatOutAirVolFlow = thisCBVAV.FanVolFlow;
826 : }
827 :
828 2 : std::string thisHeatCoilType = Alphas(16);
829 2 : thisCBVAV.HeatCoilType = static_cast<HVAC::CoilType>(getEnumValue(HVAC::coilTypeNamesUC, thisHeatCoilType));
830 2 : thisCBVAV.HeatCoilName = Alphas(17);
831 :
832 2 : DXCoilErrFlag = false;
833 2 : if (thisCBVAV.HeatCoilType == HVAC::CoilType::DXHeatingEmpirical) {
834 0 : DXCoils::GetDXCoilIndex(state,
835 0 : thisCBVAV.HeatCoilName,
836 0 : thisCBVAV.DXHeatCoilIndexNum,
837 : DXCoilErrFlag,
838 0 : HVAC::coilTypeNamesUC[static_cast<int>(thisCBVAV.HeatCoilType)]);
839 0 : if (DXCoilErrFlag) {
840 0 : ShowContinueError(state, format("...occurs in {} \"{}\"", thisCBVAV.UnitType, thisCBVAV.Name));
841 0 : ErrorsFound = true;
842 : } else {
843 0 : thisCBVAV.MinOATCompressor = state.dataDXCoils->DXCoil(thisCBVAV.DXHeatCoilIndexNum).MinOATCompressor;
844 0 : thisCBVAV.HeatingCoilInletNode = state.dataDXCoils->DXCoil(thisCBVAV.DXHeatCoilIndexNum).AirInNode;
845 0 : thisCBVAV.HeatingCoilOutletNode = state.dataDXCoils->DXCoil(thisCBVAV.DXHeatCoilIndexNum).AirOutNode;
846 : }
847 2 : } else if (thisCBVAV.HeatCoilType == HVAC::CoilType::HeatingAirToAirVariableSpeed) {
848 2 : thisCBVAV.DXHeatCoilIndexNum = VariableSpeedCoils::GetCoilIndexVariableSpeed(
849 1 : state, HVAC::cAllCoilTypes(static_cast<int>(thisCBVAV.HeatCoilType) + 1), thisCBVAV.HeatCoilName, DXCoilErrFlag);
850 1 : if (DXCoilErrFlag) {
851 0 : ShowContinueError(state, format("...occurs in {} \"{}\"", thisCBVAV.UnitType, thisCBVAV.Name));
852 0 : ErrorsFound = true;
853 : } else {
854 1 : thisCBVAV.MinOATCompressor = state.dataVariableSpeedCoils->VarSpeedCoil(thisCBVAV.DXHeatCoilIndexNum).MinOATCompressor;
855 1 : thisCBVAV.HeatingCoilInletNode = state.dataVariableSpeedCoils->VarSpeedCoil(thisCBVAV.DXHeatCoilIndexNum).AirInletNodeNum;
856 1 : thisCBVAV.HeatingCoilOutletNode = state.dataVariableSpeedCoils->VarSpeedCoil(thisCBVAV.DXHeatCoilIndexNum).AirOutletNodeNum;
857 : }
858 1 : } else if (thisCBVAV.HeatCoilType == HVAC::CoilType::HeatingGasOrOtherFuel || thisCBVAV.HeatCoilType == HVAC::CoilType::HeatingElectric) {
859 1 : HeatingCoils::GetCoilIndex(state, thisCBVAV.HeatCoilName, thisCBVAV.DXHeatCoilIndexNum, DXCoilErrFlag);
860 1 : if (DXCoilErrFlag) {
861 0 : ShowContinueError(state, format("...occurs in {} \"{}\"", thisCBVAV.UnitType, thisCBVAV.Name));
862 0 : ErrorsFound = true;
863 : } else {
864 1 : thisCBVAV.MinOATCompressor = -999.9;
865 1 : thisCBVAV.HeatingCoilInletNode = state.dataHeatingCoils->HeatingCoil(thisCBVAV.DXHeatCoilIndexNum).AirInletNodeNum;
866 1 : thisCBVAV.HeatingCoilOutletNode = state.dataHeatingCoils->HeatingCoil(thisCBVAV.DXHeatCoilIndexNum).AirOutletNodeNum;
867 : }
868 0 : } else if (thisCBVAV.HeatCoilType == HVAC::CoilType::HeatingWater) {
869 0 : thisCBVAV.DXHeatCoilIndexNum = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", thisCBVAV.HeatCoilName, DXCoilErrFlag);
870 0 : if (DXCoilErrFlag) {
871 0 : ShowContinueError(state, format("...occurs in {} \"{}\"", thisCBVAV.UnitType, thisCBVAV.Name));
872 0 : ErrorsFound = true;
873 : } else {
874 0 : thisCBVAV.CoilControlNode = state.dataWaterCoils->WaterCoil(thisCBVAV.DXHeatCoilIndexNum).WaterInletNodeNum;
875 0 : thisCBVAV.MaxHeatCoilFluidFlow = state.dataWaterCoils->WaterCoil(thisCBVAV.DXHeatCoilIndexNum).MaxWaterVolFlowRate;
876 0 : thisCBVAV.HeatingCoilInletNode = state.dataWaterCoils->WaterCoil(thisCBVAV.DXHeatCoilIndexNum).AirInletNodeNum;
877 0 : thisCBVAV.HeatingCoilOutletNode = state.dataWaterCoils->WaterCoil(thisCBVAV.DXHeatCoilIndexNum).AirOutletNodeNum;
878 : }
879 0 : } else if (thisCBVAV.HeatCoilType == HVAC::CoilType::HeatingSteam) {
880 0 : thisCBVAV.HeatCoilIndex = SteamCoils::GetSteamCoilIndex(state, "COIL:HEATING:STEAM", thisCBVAV.HeatCoilName, DXCoilErrFlag);
881 0 : if (DXCoilErrFlag) {
882 0 : ShowContinueError(state, format("...occurs in {} \"{}\"", thisCBVAV.UnitType, thisCBVAV.Name));
883 0 : ErrorsFound = true;
884 : } else {
885 0 : thisCBVAV.HeatingCoilInletNode = state.dataSteamCoils->SteamCoil(thisCBVAV.HeatCoilIndex).AirInletNodeNum;
886 0 : thisCBVAV.HeatingCoilOutletNode = state.dataSteamCoils->SteamCoil(thisCBVAV.HeatCoilIndex).AirOutletNodeNum;
887 0 : thisCBVAV.CoilControlNode = state.dataSteamCoils->SteamCoil(thisCBVAV.HeatCoilIndex).SteamInletNodeNum;
888 0 : thisCBVAV.MaxHeatCoilFluidFlow = state.dataSteamCoils->SteamCoil(thisCBVAV.HeatCoilIndex).MaxSteamVolFlowRate;
889 0 : Real64 SteamDensity = Fluid::GetSteam(state)->getSatDensity(
890 0 : state, state.dataHVACUnitaryBypassVAV->TempSteamIn, 1.0, getUnitaryHeatCoolVAVChangeoverBypass);
891 0 : if (thisCBVAV.MaxHeatCoilFluidFlow > 0.0) {
892 0 : thisCBVAV.MaxHeatCoilFluidFlow = thisCBVAV.MaxHeatCoilFluidFlow * SteamDensity;
893 : }
894 : }
895 : }
896 :
897 2 : if (thisCBVAV.DXCoilOutletNode != thisCBVAV.HeatingCoilInletNode) {
898 0 : ShowSevereError(state, format("{} illegal coil placement. Cooling coil must be upstream of heating coil.", CurrentModuleObject));
899 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
900 0 : ErrorsFound = true;
901 : }
902 :
903 2 : if (thisCBVAV.fanPlace == HVAC::FanPlace::BlowThru) {
904 1 : if (thisCBVAV.SplitterOutletAirNode != thisCBVAV.HeatingCoilOutletNode) {
905 0 : ShowSevereError(state, format("{}: {}", CurrentModuleObject, thisCBVAV.Name));
906 0 : ShowContinueError(state, format("Illegal {} = {}.", cAlphaFields(6), SplitterOutletNodeName));
907 0 : ShowContinueError(
908 : state,
909 0 : format(
910 : "{} must be the same as the outlet node specified in the heating coil object = {}: {} when blow through {} is selected.",
911 : cAlphaFields(6),
912 0 : HVAC::coilTypeNamesUC[static_cast<int>(thisCBVAV.HeatCoilType)],
913 0 : thisCBVAV.HeatCoilName,
914 : cAlphaFields(12)));
915 0 : ErrorsFound = true;
916 : }
917 1 : if (thisCBVAV.MixerMixedAirNode != thisCBVAV.FanInletNodeNum) {
918 0 : ShowSevereError(state, format("{}: {}", CurrentModuleObject, thisCBVAV.Name));
919 0 : ShowContinueError(state,
920 0 : format("Illegal {}. The fan inlet node name must be the same as the mixed air node specified in the {} = {} "
921 : "when blow through {} is selected.",
922 : cAlphaFields(11),
923 : cAlphaFields(9),
924 0 : thisCBVAV.OAMixName,
925 : cAlphaFields(12)));
926 0 : ErrorsFound = true;
927 : }
928 : }
929 :
930 2 : if (thisCBVAV.fanPlace == HVAC::FanPlace::DrawThru) {
931 1 : if (thisCBVAV.MixerMixedAirNode != thisCBVAV.DXCoilInletNode) {
932 0 : ShowSevereError(state, format("{}: {}", CurrentModuleObject, thisCBVAV.Name));
933 0 : ShowContinueError(state,
934 0 : format("Illegal cooling coil placement. The cooling coil inlet node name must be the same as the mixed air "
935 : "node specified in the {} = {} when draw through {} is selected.",
936 : cAlphaFields(9),
937 0 : thisCBVAV.OAMixName,
938 : cAlphaFields(12)));
939 0 : ErrorsFound = true;
940 : }
941 : }
942 :
943 2 : if (Util::SameString(Alphas(18), "CoolingPriority")) {
944 1 : thisCBVAV.PriorityControl = PriorityCtrlMode::CoolingPriority;
945 1 : } else if (Util::SameString(Alphas(18), "HeatingPriority")) {
946 0 : thisCBVAV.PriorityControl = PriorityCtrlMode::HeatingPriority;
947 1 : } else if (Util::SameString(Alphas(18), "ZonePriority")) {
948 1 : thisCBVAV.PriorityControl = PriorityCtrlMode::ZonePriority;
949 0 : } else if (Util::SameString(Alphas(18), "LoadPriority")) {
950 0 : thisCBVAV.PriorityControl = PriorityCtrlMode::LoadPriority;
951 : } else {
952 0 : ShowSevereError(state, format("{} illegal {} = {}", CurrentModuleObject, cAlphaFields(18), Alphas(18)));
953 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
954 0 : ShowContinueError(state, "Valid choices are CoolingPriority, HeatingPriority, ZonePriority or LoadPriority.");
955 0 : ErrorsFound = true;
956 : }
957 :
958 2 : if (Numbers(7) > 0.0) {
959 2 : thisCBVAV.MinLATCooling = Numbers(7);
960 : } else {
961 0 : thisCBVAV.MinLATCooling = 10.0;
962 : }
963 :
964 2 : if (Numbers(8) > 0.0) {
965 2 : thisCBVAV.MaxLATHeating = Numbers(8);
966 : } else {
967 0 : thisCBVAV.MaxLATHeating = 50.0;
968 : }
969 :
970 2 : if (thisCBVAV.MinLATCooling > thisCBVAV.MaxLATHeating) {
971 0 : ShowWarningError(state, format("{}: illegal leaving air temperature specified.", CurrentModuleObject));
972 0 : ShowContinueError(state, format("Resetting {} equal to {} and the simulation continues.", cNumericFields(7), cNumericFields(8)));
973 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
974 0 : thisCBVAV.MinLATCooling = thisCBVAV.MaxLATHeating;
975 : }
976 :
977 : // Dehumidification control mode
978 2 : if (Util::SameString(Alphas(19), "None")) {
979 2 : thisCBVAV.DehumidControlType = DehumidControl::None;
980 0 : } else if (Util::SameString(Alphas(19), "")) {
981 0 : thisCBVAV.DehumidControlType = DehumidControl::None;
982 0 : } else if (Util::SameString(Alphas(19), "Multimode")) {
983 0 : if (thisCBVAV.CoolCoilType == HVAC::CoilType::DXCoolingTwoStageWHumControl) {
984 0 : thisCBVAV.DehumidControlType = DehumidControl::Multimode;
985 : } else {
986 0 : ShowWarningError(state, format("Invalid {} = {}", cAlphaFields(19), Alphas(19)));
987 0 : ShowContinueError(state, format("In {} \"{}\".", CurrentModuleObject, thisCBVAV.Name));
988 0 : ShowContinueError(state, format("Valid only with {} = Coil:Cooling:DX:TwoStageWithHumidityControlMode.", cAlphaFields(14)));
989 0 : ShowContinueError(state, format("Setting {} to \"None\" and the simulation continues.", cAlphaFields(19)));
990 0 : thisCBVAV.DehumidControlType = DehumidControl::None;
991 : }
992 0 : } else if (Util::SameString(Alphas(19), "CoolReheat")) {
993 0 : if (thisCBVAV.CoolCoilType == HVAC::CoilType::DXCoolingTwoStageWHumControl) {
994 0 : thisCBVAV.DehumidControlType = DehumidControl::CoolReheat;
995 : } else {
996 0 : ShowWarningError(state, format("Invalid {} = {}", cAlphaFields(19), Alphas(19)));
997 0 : ShowContinueError(state, format("In {} \"{}\".", CurrentModuleObject, thisCBVAV.Name));
998 0 : ShowContinueError(state, format("Valid only with {} = Coil:Cooling:DX:TwoStageWithHumidityControlMode.", cAlphaFields(14)));
999 0 : ShowContinueError(state, format("Setting {} to \"None\" and the simulation continues.", cAlphaFields(19)));
1000 0 : thisCBVAV.DehumidControlType = DehumidControl::None;
1001 : }
1002 : } else {
1003 0 : ShowSevereError(state, format("Invalid {} ={}", cAlphaFields(19), Alphas(19)));
1004 0 : ShowContinueError(state, format("In {} \"{}\".", CurrentModuleObject, thisCBVAV.Name));
1005 : }
1006 :
1007 2 : if (NumNumbers > 8) {
1008 0 : thisCBVAV.minModeChangeTime = Numbers(9);
1009 : }
1010 :
1011 : // Initialize last mode of compressor operation
1012 2 : thisCBVAV.LastMode = HeatingMode;
1013 :
1014 2 : if (thisCBVAV.fanType == HVAC::FanType::OnOff || thisCBVAV.fanType == HVAC::FanType::Constant) {
1015 2 : HVAC::FanType fanType2 = state.dataFans->fans(thisCBVAV.FanIndex)->type;
1016 2 : if (thisCBVAV.fanType != fanType2) {
1017 0 : ShowWarningError(
1018 : state,
1019 0 : format("{} has {} = {} which is inconsistent with the fan object.", CurrentModuleObject, cAlphaFields(10), Alphas(10)));
1020 0 : ShowContinueError(state, format("Occurs in {} = {}", CurrentModuleObject, thisCBVAV.Name));
1021 0 : ShowContinueError(state,
1022 0 : format(" The fan object ({}) is actually a valid fan type and the simulation continues.", thisCBVAV.FanName));
1023 0 : ShowContinueError(state, " Node connections errors may result due to the inconsistent fan type.");
1024 : }
1025 : }
1026 :
1027 : // Add fan to component sets array
1028 2 : if (thisCBVAV.fanPlace == HVAC::FanPlace::BlowThru) {
1029 1 : CompSetFanInlet = state.dataLoopNodes->NodeID(thisCBVAV.MixerMixedAirNode);
1030 1 : CompSetFanOutlet = state.dataLoopNodes->NodeID(thisCBVAV.DXCoilInletNode);
1031 : } else {
1032 1 : CompSetFanInlet = state.dataLoopNodes->NodeID(thisCBVAV.HeatingCoilOutletNode);
1033 1 : CompSetFanOutlet = SplitterOutletNodeName;
1034 : }
1035 2 : std::string CompSetCoolInlet = state.dataLoopNodes->NodeID(thisCBVAV.DXCoilInletNode);
1036 2 : std::string CompSetCoolOutlet = state.dataLoopNodes->NodeID(thisCBVAV.DXCoilOutletNode);
1037 :
1038 : // Add fan to component sets array
1039 4 : BranchNodeConnections::SetUpCompSets(
1040 2 : state, thisCBVAV.UnitType, thisCBVAV.Name, Alphas(10), thisCBVAV.FanName, CompSetFanInlet, CompSetFanOutlet);
1041 :
1042 : // Add cooling coil to component sets array
1043 4 : BranchNodeConnections::SetUpCompSets(state,
1044 : thisCBVAV.UnitType,
1045 : thisCBVAV.Name,
1046 2 : HVAC::coilTypeNamesUC[static_cast<int>(thisCBVAV.CoolCoilType)],
1047 : thisCBVAV.DXCoolCoilName,
1048 : CompSetCoolInlet,
1049 : CompSetCoolOutlet);
1050 :
1051 : // Add heating coil to component sets array
1052 6 : BranchNodeConnections::SetUpCompSets(state,
1053 : thisCBVAV.UnitType,
1054 : thisCBVAV.Name,
1055 2 : HVAC::coilTypeNamesUC[static_cast<int>(thisCBVAV.HeatCoilType)],
1056 : thisCBVAV.HeatCoilName,
1057 2 : state.dataLoopNodes->NodeID(thisCBVAV.HeatingCoilInletNode),
1058 2 : state.dataLoopNodes->NodeID(thisCBVAV.HeatingCoilOutletNode));
1059 :
1060 : // Set up component set for OA mixer - use OA node and Mixed air node
1061 4 : BranchNodeConnections::SetUpCompSets(state,
1062 : thisCBVAV.UnitType,
1063 : thisCBVAV.Name,
1064 : thisCBVAV.OAMixType,
1065 : thisCBVAV.OAMixName,
1066 2 : state.dataLoopNodes->NodeID(thisCBVAV.MixerOutsideAirNode),
1067 2 : state.dataLoopNodes->NodeID(thisCBVAV.MixerMixedAirNode));
1068 :
1069 4 : BranchNodeConnections::TestCompSet(state,
1070 : thisCBVAV.UnitType,
1071 : thisCBVAV.Name,
1072 2 : state.dataLoopNodes->NodeID(thisCBVAV.AirInNode),
1073 2 : state.dataLoopNodes->NodeID(thisCBVAV.AirOutNode),
1074 : "Air Nodes");
1075 :
1076 : // Find air loop associated with CBVAV system
1077 4 : for (int AirLoopNum = 1; AirLoopNum <= state.dataHVACGlobal->NumPrimaryAirSys; ++AirLoopNum) {
1078 4 : for (int BranchNum = 1; BranchNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).NumBranches; ++BranchNum) {
1079 2 : for (int CompNum = 1; CompNum <= state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).TotalComponents;
1080 : ++CompNum) {
1081 2 : if (!Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).Name,
1082 4 : thisCBVAV.Name) ||
1083 2 : !Util::SameString(state.dataAirSystemsData->PrimaryAirSystems(AirLoopNum).Branch(BranchNum).Comp(CompNum).TypeOf,
1084 : thisCBVAV.UnitType)) {
1085 0 : continue;
1086 : }
1087 2 : thisCBVAV.AirLoopNumber = AirLoopNum;
1088 : // Should EXIT here or do other checking?
1089 2 : break;
1090 : }
1091 : }
1092 : }
1093 :
1094 2 : if (thisCBVAV.AirLoopNumber > 0) {
1095 2 : thisCBVAV.NumControlledZones = state.dataAirLoop->AirToZoneNodeInfo(thisCBVAV.AirLoopNumber).NumZonesCooled;
1096 2 : thisCBVAV.ControlledZoneNum.allocate(thisCBVAV.NumControlledZones);
1097 2 : thisCBVAV.ControlledZoneNodeNum.allocate(thisCBVAV.NumControlledZones);
1098 2 : thisCBVAV.CBVAVBoxOutletNode.allocate(thisCBVAV.NumControlledZones);
1099 2 : thisCBVAV.ZoneSequenceCoolingNum.allocate(thisCBVAV.NumControlledZones);
1100 2 : thisCBVAV.ZoneSequenceHeatingNum.allocate(thisCBVAV.NumControlledZones);
1101 :
1102 2 : thisCBVAV.ControlledZoneNum = 0;
1103 4 : for (int AirLoopZoneNum = 1; AirLoopZoneNum <= state.dataAirLoop->AirToZoneNodeInfo(thisCBVAV.AirLoopNumber).NumZonesCooled;
1104 : ++AirLoopZoneNum) {
1105 4 : thisCBVAV.ControlledZoneNum(AirLoopZoneNum) =
1106 2 : state.dataAirLoop->AirToZoneNodeInfo(thisCBVAV.AirLoopNumber).CoolCtrlZoneNums(AirLoopZoneNum);
1107 2 : if (thisCBVAV.ControlledZoneNum(AirLoopZoneNum) > 0) {
1108 4 : thisCBVAV.ControlledZoneNodeNum(AirLoopZoneNum) =
1109 2 : state.dataZoneEquip->ZoneEquipConfig(thisCBVAV.ControlledZoneNum(AirLoopZoneNum)).ZoneNode;
1110 4 : thisCBVAV.CBVAVBoxOutletNode(AirLoopZoneNum) =
1111 2 : state.dataAirLoop->AirToZoneNodeInfo(thisCBVAV.AirLoopNumber).CoolZoneInletNodes(AirLoopZoneNum);
1112 : // check for thermostat in controlled zone
1113 2 : bool FoundTstatZone = false;
1114 2 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
1115 0 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != thisCBVAV.ControlledZoneNum(AirLoopZoneNum)) {
1116 0 : continue;
1117 : }
1118 0 : FoundTstatZone = true;
1119 : }
1120 2 : if (!FoundTstatZone) {
1121 2 : ShowWarningError(state, format("{} \"{}\"", CurrentModuleObject, thisCBVAV.Name));
1122 4 : ShowContinueError(state,
1123 4 : format("Thermostat not found in zone = {} and the simulation continues.",
1124 2 : state.dataZoneEquip->ZoneEquipConfig(thisCBVAV.ControlledZoneNum(AirLoopZoneNum)).ZoneName));
1125 6 : ShowContinueError(state, "This zone will not be controlled to a temperature setpoint.");
1126 : }
1127 2 : int zoneNum = thisCBVAV.ControlledZoneNum(AirLoopZoneNum);
1128 2 : int zoneInlet = thisCBVAV.CBVAVBoxOutletNode(AirLoopZoneNum);
1129 : // setup zone equipment sequence information based on finding matching air terminal
1130 2 : if (state.dataZoneEquip->ZoneEquipConfig(zoneNum).EquipListIndex > 0) {
1131 2 : int coolingPriority = 0;
1132 2 : int heatingPriority = 0;
1133 2 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(zoneNum).EquipListIndex)
1134 2 : .getPrioritiesForInletNode(state, zoneInlet, coolingPriority, heatingPriority);
1135 2 : thisCBVAV.ZoneSequenceCoolingNum(AirLoopZoneNum) = coolingPriority;
1136 2 : thisCBVAV.ZoneSequenceHeatingNum(AirLoopZoneNum) = heatingPriority;
1137 : }
1138 2 : if (thisCBVAV.ZoneSequenceCoolingNum(AirLoopZoneNum) == 0 || thisCBVAV.ZoneSequenceHeatingNum(AirLoopZoneNum) == 0) {
1139 0 : ShowSevereError(
1140 : state,
1141 0 : format("AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass, \"{}\": Airloop air terminal in the zone equipment list for "
1142 : "zone = {} not found or is not allowed Zone Equipment Cooling or Heating Sequence = 0.",
1143 0 : thisCBVAV.Name,
1144 0 : state.dataZoneEquip->ZoneEquipConfig(zoneNum).ZoneName));
1145 0 : ErrorsFound = true;
1146 : }
1147 : } else {
1148 0 : ShowSevereError(state, "Controlled Zone node not found.");
1149 0 : ErrorsFound = true;
1150 : }
1151 : }
1152 : } else {
1153 : }
1154 :
1155 2 : } // CBVAVNum = 1,NumCBVAV
1156 :
1157 2 : if (ErrorsFound) {
1158 0 : ShowFatalError(state, format("GetCBVAV: Errors found in getting {} input.", CurrentModuleObject));
1159 : }
1160 :
1161 4 : for (int CBVAVNum = 1; CBVAVNum <= NumCBVAV; ++CBVAVNum) {
1162 : // Setup Report variables
1163 2 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
1164 4 : SetupOutputVariable(state,
1165 : "Unitary System Total Heating Rate",
1166 : Constant::Units::W,
1167 2 : thisCBVAV.TotHeatEnergyRate,
1168 : OutputProcessor::TimeStepType::System,
1169 : OutputProcessor::StoreType::Average,
1170 2 : thisCBVAV.Name);
1171 4 : SetupOutputVariable(state,
1172 : "Unitary System Total Heating Energy",
1173 : Constant::Units::J,
1174 2 : thisCBVAV.TotHeatEnergy,
1175 : OutputProcessor::TimeStepType::System,
1176 : OutputProcessor::StoreType::Sum,
1177 2 : thisCBVAV.Name);
1178 4 : SetupOutputVariable(state,
1179 : "Unitary System Total Cooling Rate",
1180 : Constant::Units::W,
1181 2 : thisCBVAV.TotCoolEnergyRate,
1182 : OutputProcessor::TimeStepType::System,
1183 : OutputProcessor::StoreType::Average,
1184 2 : thisCBVAV.Name);
1185 4 : SetupOutputVariable(state,
1186 : "Unitary System Total Cooling Energy",
1187 : Constant::Units::J,
1188 2 : thisCBVAV.TotCoolEnergy,
1189 : OutputProcessor::TimeStepType::System,
1190 : OutputProcessor::StoreType::Sum,
1191 2 : thisCBVAV.Name);
1192 4 : SetupOutputVariable(state,
1193 : "Unitary System Sensible Heating Rate",
1194 : Constant::Units::W,
1195 2 : thisCBVAV.SensHeatEnergyRate,
1196 : OutputProcessor::TimeStepType::System,
1197 : OutputProcessor::StoreType::Average,
1198 2 : thisCBVAV.Name);
1199 4 : SetupOutputVariable(state,
1200 : "Unitary System Sensible Heating Energy",
1201 : Constant::Units::J,
1202 2 : thisCBVAV.SensHeatEnergy,
1203 : OutputProcessor::TimeStepType::System,
1204 : OutputProcessor::StoreType::Sum,
1205 2 : thisCBVAV.Name);
1206 4 : SetupOutputVariable(state,
1207 : "Unitary System Sensible Cooling Rate",
1208 : Constant::Units::W,
1209 2 : thisCBVAV.SensCoolEnergyRate,
1210 : OutputProcessor::TimeStepType::System,
1211 : OutputProcessor::StoreType::Average,
1212 2 : thisCBVAV.Name);
1213 4 : SetupOutputVariable(state,
1214 : "Unitary System Sensible Cooling Energy",
1215 : Constant::Units::J,
1216 2 : thisCBVAV.SensCoolEnergy,
1217 : OutputProcessor::TimeStepType::System,
1218 : OutputProcessor::StoreType::Sum,
1219 2 : thisCBVAV.Name);
1220 4 : SetupOutputVariable(state,
1221 : "Unitary System Latent Heating Rate",
1222 : Constant::Units::W,
1223 2 : thisCBVAV.LatHeatEnergyRate,
1224 : OutputProcessor::TimeStepType::System,
1225 : OutputProcessor::StoreType::Average,
1226 2 : thisCBVAV.Name);
1227 4 : SetupOutputVariable(state,
1228 : "Unitary System Latent Heating Energy",
1229 : Constant::Units::J,
1230 2 : thisCBVAV.LatHeatEnergy,
1231 : OutputProcessor::TimeStepType::System,
1232 : OutputProcessor::StoreType::Sum,
1233 2 : thisCBVAV.Name);
1234 4 : SetupOutputVariable(state,
1235 : "Unitary System Latent Cooling Rate",
1236 : Constant::Units::W,
1237 2 : thisCBVAV.LatCoolEnergyRate,
1238 : OutputProcessor::TimeStepType::System,
1239 : OutputProcessor::StoreType::Average,
1240 2 : thisCBVAV.Name);
1241 4 : SetupOutputVariable(state,
1242 : "Unitary System Latent Cooling Energy",
1243 : Constant::Units::J,
1244 2 : thisCBVAV.LatCoolEnergy,
1245 : OutputProcessor::TimeStepType::System,
1246 : OutputProcessor::StoreType::Sum,
1247 2 : thisCBVAV.Name);
1248 4 : SetupOutputVariable(state,
1249 : "Unitary System Electricity Rate",
1250 : Constant::Units::W,
1251 2 : thisCBVAV.ElecPower,
1252 : OutputProcessor::TimeStepType::System,
1253 : OutputProcessor::StoreType::Average,
1254 2 : thisCBVAV.Name);
1255 4 : SetupOutputVariable(state,
1256 : "Unitary System Electricity Energy",
1257 : Constant::Units::J,
1258 2 : thisCBVAV.ElecConsumption,
1259 : OutputProcessor::TimeStepType::System,
1260 : OutputProcessor::StoreType::Sum,
1261 2 : thisCBVAV.Name);
1262 4 : SetupOutputVariable(state,
1263 : "Unitary System Fan Part Load Ratio",
1264 : Constant::Units::None,
1265 2 : thisCBVAV.FanPartLoadRatio,
1266 : OutputProcessor::TimeStepType::System,
1267 : OutputProcessor::StoreType::Average,
1268 2 : thisCBVAV.Name);
1269 4 : SetupOutputVariable(state,
1270 : "Unitary System Compressor Part Load Ratio",
1271 : Constant::Units::None,
1272 2 : thisCBVAV.CompPartLoadRatio,
1273 : OutputProcessor::TimeStepType::System,
1274 : OutputProcessor::StoreType::Average,
1275 2 : thisCBVAV.Name);
1276 4 : SetupOutputVariable(state,
1277 : "Unitary System Bypass Air Mass Flow Rate",
1278 : Constant::Units::kg_s,
1279 2 : thisCBVAV.BypassMassFlowRate,
1280 : OutputProcessor::TimeStepType::System,
1281 : OutputProcessor::StoreType::Average,
1282 2 : thisCBVAV.Name);
1283 4 : SetupOutputVariable(state,
1284 : "Unitary System Air Outlet Setpoint Temperature",
1285 : Constant::Units::C,
1286 2 : thisCBVAV.OutletTempSetPoint,
1287 : OutputProcessor::TimeStepType::System,
1288 : OutputProcessor::StoreType::Average,
1289 2 : thisCBVAV.Name);
1290 2 : SetupOutputVariable(state,
1291 : "Unitary System Operating Mode Index",
1292 : Constant::Units::None,
1293 2 : thisCBVAV.HeatCoolMode,
1294 : OutputProcessor::TimeStepType::System,
1295 : OutputProcessor::StoreType::Average,
1296 2 : thisCBVAV.Name);
1297 : }
1298 2 : }
1299 :
1300 17 : void InitCBVAV(EnergyPlusData &state,
1301 : int const CBVAVNum, // Index of the current CBVAV unit being simulated
1302 : bool const FirstHVACIteration, // TRUE if first HVAC iteration
1303 : int const AirLoopNum, // air loop index
1304 : Real64 &OnOffAirFlowRatio, // Ratio of compressor ON airflow to average airflow over timestep
1305 : bool const HXUnitOn // flag to enable heat exchanger
1306 : )
1307 : {
1308 :
1309 : // SUBROUTINE INFORMATION:
1310 : // AUTHOR Richard Raustad
1311 : // DATE WRITTEN July 2006
1312 : // MODIFIED B. Griffith, May 2009, EMS setpoint check
1313 :
1314 : // PURPOSE OF THIS SUBROUTINE:
1315 : // This subroutine is for initializations of the changeover-bypass VAV system components.
1316 :
1317 : // METHODOLOGY EMPLOYED:
1318 : // Uses the status flags to trigger initializations. The CBVAV system is simulated with no load (coils off) to
1319 : // determine the outlet temperature. A setpoint temperature is calculated on FirstHVACIteration = TRUE.
1320 : // Once the setpoint is calculated, the inlet mass flow rate on FirstHVACIteration = FALSE is used to
1321 : // determine the bypass fraction. The simulation converges quickly on mass flow rate. If the zone
1322 : // temperatures float in the deadband, additional iterations are required to converge on mass flow rate.
1323 :
1324 : // SUBROUTINE PARAMETER DEFINITIONS:
1325 : static constexpr std::string_view RoutineName("InitCBVAV");
1326 :
1327 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1328 : Real64 QSensUnitOut; // Output of CBVAV system with coils off
1329 : Real64 OutsideAirMultiplier; // Outside air multiplier schedule (= 1.0 if no schedule)
1330 : Real64 QCoilActual; // actual CBVAV steam heating coil load met (W)
1331 : bool ErrorFlag; // local error flag returned from data mining
1332 : Real64 mdot; // heating coil fluid mass flow rate, kg/s
1333 :
1334 17 : auto &cBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
1335 17 : int NumCBVAV = state.dataHVACUnitaryBypassVAV->NumCBVAV;
1336 :
1337 17 : int InNode = cBVAV.AirInNode;
1338 17 : int OutNode = cBVAV.AirOutNode;
1339 :
1340 : // Do the one time initializations
1341 17 : if (state.dataHVACUnitaryBypassVAV->MyOneTimeFlag) {
1342 :
1343 5 : state.dataHVACUnitaryBypassVAV->MyEnvrnFlag.allocate(NumCBVAV);
1344 5 : state.dataHVACUnitaryBypassVAV->MySizeFlag.allocate(NumCBVAV);
1345 5 : state.dataHVACUnitaryBypassVAV->MyPlantScanFlag.allocate(NumCBVAV);
1346 5 : state.dataHVACUnitaryBypassVAV->MyEnvrnFlag = true;
1347 5 : state.dataHVACUnitaryBypassVAV->MySizeFlag = true;
1348 5 : state.dataHVACUnitaryBypassVAV->MyPlantScanFlag = true;
1349 :
1350 5 : state.dataHVACUnitaryBypassVAV->MyOneTimeFlag = false;
1351 : // speed up test based on code from 16 years ago to correct cycling fan economizer defect
1352 : // see https://github.com/NREL/EnergyPlusArchive/commit/a2202f8a168fd0330bf3a45392833405e8bd08f2
1353 : // This test sets simple flag so air loop doesn't iterate twice each pass (reverts above change)
1354 : // AirLoopControlInfo(AirplantLoc.loopNum).Simple = true;
1355 : }
1356 :
1357 17 : if (state.dataHVACUnitaryBypassVAV->MyPlantScanFlag(CBVAVNum) && allocated(state.dataPlnt->PlantLoop)) {
1358 0 : if ((cBVAV.HeatCoilType == HVAC::CoilType::HeatingWater) || (cBVAV.HeatCoilType == HVAC::CoilType::HeatingSteam)) {
1359 0 : bool ErrorsFound = false; // Set to true if errors in input, fatal at end of routine
1360 0 : if (cBVAV.HeatCoilType == HVAC::CoilType::HeatingWater) {
1361 :
1362 0 : ErrorFlag = false;
1363 0 : PlantUtilities::ScanPlantLoopsForObject(
1364 0 : state, cBVAV.HeatCoilName, DataPlant::PlantEquipmentType::CoilWaterSimpleHeating, cBVAV.plantLoc, ErrorFlag, _, _, _, _, _);
1365 0 : if (ErrorFlag) {
1366 0 : ShowFatalError(state, "InitCBVAV: Program terminated for previous conditions.");
1367 : }
1368 :
1369 0 : cBVAV.MaxHeatCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", cBVAV.HeatCoilName, ErrorsFound);
1370 :
1371 0 : if (cBVAV.MaxHeatCoilFluidFlow > 0.0) {
1372 : Real64 FluidDensity =
1373 0 : state.dataPlnt->PlantLoop(cBVAV.plantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
1374 0 : cBVAV.MaxHeatCoilFluidFlow =
1375 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", cBVAV.HeatCoilName, ErrorsFound) * FluidDensity;
1376 : }
1377 :
1378 0 : } else if (cBVAV.HeatCoilType == HVAC::CoilType::HeatingSteam) {
1379 :
1380 0 : ErrorFlag = false;
1381 0 : PlantUtilities::ScanPlantLoopsForObject(
1382 0 : state, cBVAV.HeatCoilName, DataPlant::PlantEquipmentType::CoilSteamAirHeating, cBVAV.plantLoc, ErrorFlag, _, _, _, _, _);
1383 :
1384 0 : if (ErrorFlag) {
1385 0 : ShowFatalError(state, "InitCBVAV: Program terminated for previous conditions.");
1386 : }
1387 :
1388 0 : cBVAV.MaxHeatCoilFluidFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, cBVAV.HeatCoilIndex, ErrorsFound);
1389 :
1390 0 : if (cBVAV.MaxHeatCoilFluidFlow > 0.0) {
1391 : // Why is TempSteamIn a state variable of the entire module?
1392 : Real64 FluidDensity =
1393 0 : Fluid::GetSteam(state)->getSatDensity(state, state.dataHVACUnitaryBypassVAV->TempSteamIn, 1.0, RoutineName);
1394 :
1395 0 : cBVAV.MaxHeatCoilFluidFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, cBVAV.HeatCoilIndex, ErrorsFound) * FluidDensity;
1396 : }
1397 : }
1398 :
1399 0 : if (ErrorsFound) {
1400 0 : ShowContinueError(state, format("Occurs in {} = {}", "AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass", cBVAV.Name));
1401 : }
1402 : // fill outlet node for heating coil
1403 0 : cBVAV.CoilOutletNode = DataPlant::CompData::getPlantComponent(state, cBVAV.plantLoc).NodeNumOut;
1404 0 : state.dataHVACUnitaryBypassVAV->MyPlantScanFlag(CBVAVNum) = false;
1405 :
1406 0 : } else { // CBVAV is not connected to plant
1407 0 : state.dataHVACUnitaryBypassVAV->MyPlantScanFlag(CBVAVNum) = false;
1408 : }
1409 17 : } else if (state.dataHVACUnitaryBypassVAV->MyPlantScanFlag(CBVAVNum) && !state.dataGlobal->AnyPlantInModel) {
1410 5 : state.dataHVACUnitaryBypassVAV->MyPlantScanFlag(CBVAVNum) = false;
1411 : }
1412 :
1413 17 : if (!state.dataGlobal->SysSizingCalc && state.dataHVACUnitaryBypassVAV->MySizeFlag(CBVAVNum)) {
1414 4 : SizeCBVAV(state, CBVAVNum);
1415 : // Pass the fan cycling schedule index up to the air loop. Set the air loop unitary system flag.
1416 4 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).cycFanSched = cBVAV.fanOpModeSched;
1417 : // Set UnitarySys flag to FALSE and let the heating coil autosize independently of the cooling coil
1418 4 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySys = false;
1419 4 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).fanOp = cBVAV.fanOp;
1420 : // check for set point manager on outlet node of CBVAV
1421 4 : cBVAV.OutNodeSPMIndex = SetPointManager::GetSetPointManagerIndexByNode(state,
1422 : OutNode,
1423 : HVAC::CtrlVarType::Temp,
1424 : SetPointManager::SPMType::MixedAir,
1425 : true); // isRefNode
1426 4 : state.dataHVACUnitaryBypassVAV->MySizeFlag(CBVAVNum) = false;
1427 : }
1428 :
1429 : // Do the Begin Environment initializations
1430 17 : if (state.dataGlobal->BeginEnvrnFlag && state.dataHVACUnitaryBypassVAV->MyEnvrnFlag(CBVAVNum)) {
1431 1 : int MixerOutsideAirNode = cBVAV.MixerOutsideAirNode;
1432 1 : Real64 RhoAir = state.dataEnvrn->StdRhoAir;
1433 : // set the mass flow rates from the input volume flow rates
1434 1 : cBVAV.MaxCoolAirMassFlow = RhoAir * cBVAV.MaxCoolAirVolFlow;
1435 1 : cBVAV.CoolOutAirMassFlow = RhoAir * cBVAV.CoolOutAirVolFlow;
1436 1 : cBVAV.MaxHeatAirMassFlow = RhoAir * cBVAV.MaxHeatAirVolFlow;
1437 1 : cBVAV.HeatOutAirMassFlow = RhoAir * cBVAV.HeatOutAirVolFlow;
1438 1 : cBVAV.MaxNoCoolHeatAirMassFlow = RhoAir * cBVAV.MaxNoCoolHeatAirVolFlow;
1439 1 : cBVAV.NoCoolHeatOutAirMassFlow = RhoAir * cBVAV.NoCoolHeatOutAirVolFlow;
1440 : // set the node max and min mass flow rates
1441 1 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMax = max(cBVAV.CoolOutAirMassFlow, cBVAV.HeatOutAirMassFlow);
1442 1 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMaxAvail = max(cBVAV.CoolOutAirMassFlow, cBVAV.HeatOutAirMassFlow);
1443 1 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMin = 0.0;
1444 1 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMinAvail = 0.0;
1445 1 : state.dataLoopNodes->Node(InNode).MassFlowRateMax = max(cBVAV.MaxCoolAirMassFlow, cBVAV.MaxHeatAirMassFlow);
1446 1 : state.dataLoopNodes->Node(InNode).MassFlowRateMaxAvail = max(cBVAV.MaxCoolAirMassFlow, cBVAV.MaxHeatAirMassFlow);
1447 1 : state.dataLoopNodes->Node(InNode).MassFlowRateMin = 0.0;
1448 1 : state.dataLoopNodes->Node(InNode).MassFlowRateMinAvail = 0.0;
1449 1 : state.dataLoopNodes->Node(OutNode).Temp = state.dataLoopNodes->Node(InNode).Temp;
1450 1 : state.dataLoopNodes->Node(OutNode).HumRat = state.dataLoopNodes->Node(InNode).HumRat;
1451 1 : state.dataLoopNodes->Node(OutNode).Enthalpy = state.dataLoopNodes->Node(InNode).Enthalpy;
1452 1 : state.dataLoopNodes->Node(cBVAV.MixerReliefAirNode) = state.dataLoopNodes->Node(MixerOutsideAirNode);
1453 1 : state.dataHVACUnitaryBypassVAV->MyEnvrnFlag(CBVAVNum) = false;
1454 1 : cBVAV.LastMode = HeatingMode;
1455 1 : cBVAV.changeOverTimer = -1.0;
1456 : // set fluid-side hardware limits
1457 1 : if (cBVAV.CoilControlNode > 0) {
1458 : // If water coil max water flow rate is autosized, simulate once in order to mine max water flow rate
1459 0 : if (cBVAV.MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
1460 0 : if (cBVAV.HeatCoilType == HVAC::CoilType::HeatingWater) {
1461 0 : WaterCoils::SimulateWaterCoilComponents(state, cBVAV.HeatCoilName, FirstHVACIteration, cBVAV.HeatCoilIndex);
1462 0 : ErrorFlag = false;
1463 0 : Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", cBVAV.HeatCoilName, ErrorFlag);
1464 0 : if (ErrorFlag) {
1465 0 : ShowContinueError(state, format("Occurs in {} = {}", "AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass", cBVAV.Name));
1466 : }
1467 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
1468 : Real64 FluidDensity =
1469 0 : state.dataPlnt->PlantLoop(cBVAV.plantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
1470 0 : cBVAV.MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * FluidDensity;
1471 : }
1472 : }
1473 0 : if (cBVAV.HeatCoilType == HVAC::CoilType::HeatingSteam) {
1474 0 : SteamCoils::SimulateSteamCoilComponents(state,
1475 : cBVAV.HeatCoilName,
1476 : FirstHVACIteration,
1477 0 : cBVAV.HeatCoilIndex,
1478 0 : 1.0,
1479 : QCoilActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
1480 0 : ErrorFlag = false;
1481 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(state, cBVAV.HeatCoilIndex, ErrorFlag);
1482 0 : if (ErrorFlag) {
1483 0 : ShowContinueError(state, format("Occurs in {} = {}", "AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass", cBVAV.Name));
1484 : }
1485 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
1486 : Real64 FluidDensity =
1487 0 : Fluid::GetSteam(state)->getSatDensity(state, state.dataHVACUnitaryBypassVAV->TempSteamIn, 1.0, RoutineName);
1488 0 : cBVAV.MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * FluidDensity;
1489 : }
1490 : }
1491 : } // end of IF(cBVAV%MaxHeatCoilFluidFlow .EQ. DataSizing::AutoSize)THEN
1492 :
1493 0 : PlantUtilities::InitComponentNodes(state, 0.0, cBVAV.MaxHeatCoilFluidFlow, cBVAV.CoilControlNode, cBVAV.CoilOutletNode);
1494 :
1495 : } // end of IF(cBVAV%CoilControlNode .GT. 0)THEN
1496 : } // end one time inits
1497 :
1498 17 : if (!state.dataGlobal->BeginEnvrnFlag) {
1499 16 : state.dataHVACUnitaryBypassVAV->MyEnvrnFlag(CBVAVNum) = true;
1500 : }
1501 :
1502 : // IF CBVAV system was not autosized and the fan is autosized, check that fan volumetric flow rate is greater than CBVAV flow rates
1503 17 : if (cBVAV.CheckFanFlow) {
1504 :
1505 5 : if (!state.dataGlobal->DoingSizing && cBVAV.FanVolFlow != DataSizing::AutoSize) {
1506 4 : std::string CurrentModuleObject = "AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass";
1507 : // Check fan versus system supply air flow rates
1508 4 : if (cBVAV.FanVolFlow < cBVAV.MaxCoolAirVolFlow) {
1509 0 : ShowWarningError(state,
1510 0 : format("{} - air flow rate = {:.7T} in fan object {} is less than the maximum CBVAV system air flow rate when "
1511 : "cooling is required ({:.7T}).",
1512 : CurrentModuleObject,
1513 0 : cBVAV.FanVolFlow,
1514 0 : cBVAV.FanName,
1515 0 : cBVAV.MaxCoolAirVolFlow));
1516 0 : ShowContinueError(
1517 : state, " The CBVAV system flow rate when cooling is required is reset to the fan flow rate and the simulation continues.");
1518 0 : ShowContinueError(state, format(" Occurs in Changeover-bypass VAV system = {}", cBVAV.Name));
1519 0 : cBVAV.MaxCoolAirVolFlow = cBVAV.FanVolFlow;
1520 : }
1521 4 : if (cBVAV.FanVolFlow < cBVAV.MaxHeatAirVolFlow) {
1522 0 : ShowWarningError(state,
1523 0 : format("{} - air flow rate = {:.7T} in fan object {} is less than the maximum CBVAV system air flow rate when "
1524 : "heating is required ({:.7T}).",
1525 : CurrentModuleObject,
1526 0 : cBVAV.FanVolFlow,
1527 0 : cBVAV.FanName,
1528 0 : cBVAV.MaxHeatAirVolFlow));
1529 0 : ShowContinueError(
1530 : state, " The CBVAV system flow rate when heating is required is reset to the fan flow rate and the simulation continues.");
1531 0 : ShowContinueError(state, format(" Occurs in Changeover-bypass VAV system = {}", cBVAV.Name));
1532 0 : cBVAV.MaxHeatAirVolFlow = cBVAV.FanVolFlow;
1533 : }
1534 4 : if (cBVAV.FanVolFlow < cBVAV.MaxNoCoolHeatAirVolFlow && cBVAV.MaxNoCoolHeatAirVolFlow != 0.0) {
1535 0 : ShowWarningError(state,
1536 0 : format("{} - air flow rate = {:.7T} in fan object {} is less than the maximum CBVAV system air flow rate when "
1537 : "no heating or cooling is needed ({:.7T}).",
1538 : CurrentModuleObject,
1539 0 : cBVAV.FanVolFlow,
1540 0 : cBVAV.FanName,
1541 0 : cBVAV.MaxNoCoolHeatAirVolFlow));
1542 0 : ShowContinueError(state,
1543 : " The CBVAV system flow rate when no heating or cooling is needed is reset to the fan flow rate and the "
1544 : "simulation continues.");
1545 0 : ShowContinueError(state, format(" Occurs in Changeover-bypass VAV system = {}", cBVAV.Name));
1546 0 : cBVAV.MaxNoCoolHeatAirVolFlow = cBVAV.FanVolFlow;
1547 : }
1548 : // Check fan versus outdoor air flow rates
1549 4 : if (cBVAV.FanVolFlow < cBVAV.CoolOutAirVolFlow) {
1550 0 : ShowWarningError(state,
1551 0 : format("{} - air flow rate = {:.7T} in fan object {} is less than the maximum CBVAV outdoor air flow rate when "
1552 : "cooling is required ({:.7T}).",
1553 : CurrentModuleObject,
1554 0 : cBVAV.FanVolFlow,
1555 0 : cBVAV.FanName,
1556 0 : cBVAV.CoolOutAirVolFlow));
1557 0 : ShowContinueError(
1558 : state, " The CBVAV outdoor flow rate when cooling is required is reset to the fan flow rate and the simulation continues.");
1559 0 : ShowContinueError(state, format(" Occurs in Changeover-bypass VAV system = {}", cBVAV.Name));
1560 0 : cBVAV.CoolOutAirVolFlow = cBVAV.FanVolFlow;
1561 : }
1562 4 : if (cBVAV.FanVolFlow < cBVAV.HeatOutAirVolFlow) {
1563 0 : ShowWarningError(state,
1564 0 : format("{} - air flow rate = {:.7T} in fan object {} is less than the maximum CBVAV outdoor air flow rate when "
1565 : "heating is required ({:.7T}).",
1566 : CurrentModuleObject,
1567 0 : cBVAV.FanVolFlow,
1568 0 : cBVAV.FanName,
1569 0 : cBVAV.HeatOutAirVolFlow));
1570 0 : ShowContinueError(
1571 : state, " The CBVAV outdoor flow rate when heating is required is reset to the fan flow rate and the simulation continues.");
1572 0 : ShowContinueError(state, format(" Occurs in Changeover-bypass VAV system = {}", cBVAV.Name));
1573 0 : cBVAV.HeatOutAirVolFlow = cBVAV.FanVolFlow;
1574 : }
1575 4 : if (cBVAV.FanVolFlow < cBVAV.NoCoolHeatOutAirVolFlow) {
1576 0 : ShowWarningError(state,
1577 0 : format("{} - air flow rate = {:.7T} in fan object {} is less than the maximum CBVAV outdoor air flow rate when "
1578 : "no heating or cooling is needed ({:.7T}).",
1579 : CurrentModuleObject,
1580 0 : cBVAV.FanVolFlow,
1581 0 : cBVAV.FanName,
1582 0 : cBVAV.NoCoolHeatOutAirVolFlow));
1583 0 : ShowContinueError(state,
1584 : " The CBVAV outdoor flow rate when no heating or cooling is needed is reset to the fan flow rate and the "
1585 : "simulation continues.");
1586 0 : ShowContinueError(state, format(" Occurs in Changeover-bypass VAV system = {}", cBVAV.Name));
1587 0 : cBVAV.NoCoolHeatOutAirVolFlow = cBVAV.FanVolFlow;
1588 : }
1589 4 : int MixerOutsideAirNode = cBVAV.MixerOutsideAirNode;
1590 4 : Real64 RhoAir = state.dataEnvrn->StdRhoAir;
1591 : // set the mass flow rates from the reset volume flow rates
1592 4 : cBVAV.MaxCoolAirMassFlow = RhoAir * cBVAV.MaxCoolAirVolFlow;
1593 4 : cBVAV.CoolOutAirMassFlow = RhoAir * cBVAV.CoolOutAirVolFlow;
1594 4 : cBVAV.MaxHeatAirMassFlow = RhoAir * cBVAV.MaxHeatAirVolFlow;
1595 4 : cBVAV.HeatOutAirMassFlow = RhoAir * cBVAV.HeatOutAirVolFlow;
1596 4 : cBVAV.MaxNoCoolHeatAirMassFlow = RhoAir * cBVAV.MaxNoCoolHeatAirVolFlow;
1597 4 : cBVAV.NoCoolHeatOutAirMassFlow = RhoAir * cBVAV.NoCoolHeatOutAirVolFlow;
1598 : // set the node max and min mass flow rates based on reset volume flow rates
1599 4 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMax = max(cBVAV.CoolOutAirMassFlow, cBVAV.HeatOutAirMassFlow);
1600 4 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMaxAvail = max(cBVAV.CoolOutAirMassFlow, cBVAV.HeatOutAirMassFlow);
1601 4 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMin = 0.0;
1602 4 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMinAvail = 0.0;
1603 4 : state.dataLoopNodes->Node(InNode).MassFlowRateMax = max(cBVAV.MaxCoolAirMassFlow, cBVAV.MaxHeatAirMassFlow);
1604 4 : state.dataLoopNodes->Node(InNode).MassFlowRateMaxAvail = max(cBVAV.MaxCoolAirMassFlow, cBVAV.MaxHeatAirMassFlow);
1605 4 : state.dataLoopNodes->Node(InNode).MassFlowRateMin = 0.0;
1606 4 : state.dataLoopNodes->Node(InNode).MassFlowRateMinAvail = 0.0;
1607 4 : state.dataLoopNodes->Node(OutNode).Temp = state.dataLoopNodes->Node(InNode).Temp;
1608 4 : state.dataLoopNodes->Node(OutNode).HumRat = state.dataLoopNodes->Node(InNode).HumRat;
1609 4 : state.dataLoopNodes->Node(OutNode).Enthalpy = state.dataLoopNodes->Node(InNode).Enthalpy;
1610 4 : state.dataLoopNodes->Node(cBVAV.MixerReliefAirNode) = state.dataLoopNodes->Node(MixerOutsideAirNode);
1611 4 : cBVAV.CheckFanFlow = false;
1612 4 : if (cBVAV.FanVolFlow > 0.0) {
1613 4 : cBVAV.HeatingSpeedRatio = cBVAV.MaxHeatAirVolFlow / cBVAV.FanVolFlow;
1614 4 : cBVAV.CoolingSpeedRatio = cBVAV.MaxCoolAirVolFlow / cBVAV.FanVolFlow;
1615 4 : cBVAV.NoHeatCoolSpeedRatio = cBVAV.MaxNoCoolHeatAirVolFlow / cBVAV.FanVolFlow;
1616 : }
1617 4 : }
1618 : }
1619 :
1620 17 : if (cBVAV.fanOpModeSched != nullptr) {
1621 0 : cBVAV.fanOp = (cBVAV.fanOpModeSched->getCurrentVal() == 0.0) ? HVAC::FanOp::Cycling : HVAC::FanOp::Continuous;
1622 : }
1623 :
1624 : // Returns load only for zones requesting cooling (heating). If in deadband, Qzoneload = 0.
1625 17 : if (FirstHVACIteration) {
1626 14 : cBVAV.modeChanged = false;
1627 : }
1628 17 : GetZoneLoads(state, CBVAVNum);
1629 :
1630 17 : OutsideAirMultiplier = (cBVAV.outAirSched != nullptr) ? cBVAV.outAirSched->getCurrentVal() : 1.0;
1631 :
1632 : // Set the inlet node mass flow rate
1633 17 : if (cBVAV.fanOp == HVAC::FanOp::Continuous) {
1634 : // constant fan mode
1635 1 : if (cBVAV.HeatCoolMode == HeatingMode) {
1636 1 : state.dataHVACUnitaryBypassVAV->CompOnMassFlow = cBVAV.MaxHeatAirMassFlow;
1637 1 : state.dataHVACUnitaryBypassVAV->CompOnFlowRatio = cBVAV.HeatingSpeedRatio;
1638 1 : state.dataHVACUnitaryBypassVAV->OACompOnMassFlow = cBVAV.HeatOutAirMassFlow * OutsideAirMultiplier;
1639 0 : } else if (cBVAV.HeatCoolMode == CoolingMode) {
1640 0 : state.dataHVACUnitaryBypassVAV->CompOnMassFlow = cBVAV.MaxCoolAirMassFlow;
1641 0 : state.dataHVACUnitaryBypassVAV->CompOnFlowRatio = cBVAV.CoolingSpeedRatio;
1642 0 : state.dataHVACUnitaryBypassVAV->OACompOnMassFlow = cBVAV.CoolOutAirMassFlow * OutsideAirMultiplier;
1643 : } else {
1644 0 : state.dataHVACUnitaryBypassVAV->CompOnMassFlow = cBVAV.MaxNoCoolHeatAirMassFlow;
1645 0 : state.dataHVACUnitaryBypassVAV->CompOnFlowRatio = cBVAV.NoHeatCoolSpeedRatio;
1646 0 : state.dataHVACUnitaryBypassVAV->OACompOnMassFlow = cBVAV.NoCoolHeatOutAirMassFlow * OutsideAirMultiplier;
1647 : }
1648 :
1649 1 : if (cBVAV.AirFlowControl == AirFlowCtrlMode::UseCompressorOnFlow) {
1650 1 : if (cBVAV.LastMode == HeatingMode) {
1651 1 : state.dataHVACUnitaryBypassVAV->CompOffMassFlow = cBVAV.MaxHeatAirMassFlow;
1652 1 : state.dataHVACUnitaryBypassVAV->CompOffFlowRatio = cBVAV.HeatingSpeedRatio;
1653 1 : state.dataHVACUnitaryBypassVAV->OACompOffMassFlow = cBVAV.HeatOutAirMassFlow * OutsideAirMultiplier;
1654 : } else {
1655 0 : state.dataHVACUnitaryBypassVAV->CompOffMassFlow = cBVAV.MaxCoolAirMassFlow;
1656 0 : state.dataHVACUnitaryBypassVAV->CompOffFlowRatio = cBVAV.CoolingSpeedRatio;
1657 0 : state.dataHVACUnitaryBypassVAV->OACompOffMassFlow = cBVAV.CoolOutAirMassFlow * OutsideAirMultiplier;
1658 : }
1659 : } else {
1660 0 : state.dataHVACUnitaryBypassVAV->CompOffMassFlow = cBVAV.MaxNoCoolHeatAirMassFlow;
1661 0 : state.dataHVACUnitaryBypassVAV->CompOffFlowRatio = cBVAV.NoHeatCoolSpeedRatio;
1662 0 : state.dataHVACUnitaryBypassVAV->OACompOffMassFlow = cBVAV.NoCoolHeatOutAirMassFlow * OutsideAirMultiplier;
1663 : }
1664 : } else {
1665 : // cycling fan mode
1666 16 : if (cBVAV.HeatCoolMode == HeatingMode) {
1667 4 : state.dataHVACUnitaryBypassVAV->CompOnMassFlow = cBVAV.MaxHeatAirMassFlow;
1668 4 : state.dataHVACUnitaryBypassVAV->CompOnFlowRatio = cBVAV.HeatingSpeedRatio;
1669 4 : state.dataHVACUnitaryBypassVAV->OACompOnMassFlow = cBVAV.HeatOutAirMassFlow * OutsideAirMultiplier;
1670 12 : } else if (cBVAV.HeatCoolMode == CoolingMode) {
1671 8 : state.dataHVACUnitaryBypassVAV->CompOnMassFlow = cBVAV.MaxCoolAirMassFlow;
1672 8 : state.dataHVACUnitaryBypassVAV->CompOnFlowRatio = cBVAV.CoolingSpeedRatio;
1673 8 : state.dataHVACUnitaryBypassVAV->OACompOnMassFlow = cBVAV.CoolOutAirMassFlow * OutsideAirMultiplier;
1674 : } else {
1675 4 : state.dataHVACUnitaryBypassVAV->CompOnMassFlow = cBVAV.MaxCoolAirMassFlow;
1676 4 : state.dataHVACUnitaryBypassVAV->CompOnFlowRatio = cBVAV.CoolingSpeedRatio;
1677 4 : state.dataHVACUnitaryBypassVAV->OACompOnMassFlow = cBVAV.CoolOutAirMassFlow * OutsideAirMultiplier;
1678 : }
1679 16 : state.dataHVACUnitaryBypassVAV->CompOffMassFlow = 0.0;
1680 16 : state.dataHVACUnitaryBypassVAV->CompOffFlowRatio = 0.0;
1681 16 : state.dataHVACUnitaryBypassVAV->OACompOffMassFlow = 0.0;
1682 : }
1683 :
1684 : // Check for correct control node at outlet of unit
1685 17 : if (cBVAV.HumRatMaxCheck) {
1686 5 : if (cBVAV.DehumidControlType != DehumidControl::None) {
1687 0 : if (state.dataLoopNodes->Node(OutNode).HumRatMax == DataLoopNode::SensedNodeFlagValue) {
1688 0 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
1689 0 : ShowWarningError(state, format("Unitary System:VAV:ChangeOverBypass = {}", cBVAV.Name));
1690 0 : ShowContinueError(state,
1691 : "Use SetpointManager:SingleZone:Humidity:Maximum to place a humidity setpoint at the air outlet node of "
1692 : "the unitary system.");
1693 0 : ShowContinueError(state, "Setting Dehumidification Control Type to None and simulation continues.");
1694 0 : cBVAV.DehumidControlType = DehumidControl::None;
1695 : } else {
1696 : // need call to EMS to check node
1697 0 : bool EMSSetPointCheck = false;
1698 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(state, OutNode, HVAC::CtrlVarType::MaxHumRat, EMSSetPointCheck);
1699 0 : state.dataLoopNodes->NodeSetpointCheck(OutNode).needsSetpointChecking = false;
1700 0 : if (EMSSetPointCheck) {
1701 : // There is no plugin anyways, so we now we have a bad condition.
1702 0 : ShowWarningError(state, format("Unitary System:VAV:ChangeOverBypass = {}", cBVAV.Name));
1703 0 : ShowContinueError(state,
1704 : "Use SetpointManager:SingleZone:Humidity:Maximum to place a humidity setpoint at the air outlet node "
1705 : "of the unitary system.");
1706 0 : ShowContinueError(
1707 : state, "Or use an EMS Actuator to place a maximum humidity setpoint at the air outlet node of the unitary system.");
1708 0 : ShowContinueError(state, "Setting Dehumidification Control Type to None and simulation continues.");
1709 0 : cBVAV.DehumidControlType = DehumidControl::None;
1710 : }
1711 : }
1712 : }
1713 0 : cBVAV.HumRatMaxCheck = false;
1714 : } else {
1715 5 : cBVAV.HumRatMaxCheck = false;
1716 : }
1717 : }
1718 :
1719 : // Set the inlet node mass flow rate
1720 17 : if (cBVAV.availSched->getCurrentVal() > 0.0 && state.dataHVACUnitaryBypassVAV->CompOnMassFlow != 0.0) {
1721 16 : OnOffAirFlowRatio = 1.0;
1722 16 : if (FirstHVACIteration) {
1723 13 : state.dataLoopNodes->Node(cBVAV.AirInNode).MassFlowRate = state.dataHVACUnitaryBypassVAV->CompOnMassFlow;
1724 13 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate = state.dataHVACUnitaryBypassVAV->CompOnMassFlow;
1725 13 : state.dataLoopNodes->Node(cBVAV.MixerOutsideAirNode).MassFlowRate = state.dataHVACUnitaryBypassVAV->OACompOnMassFlow;
1726 13 : state.dataLoopNodes->Node(cBVAV.MixerReliefAirNode).MassFlowRate = state.dataHVACUnitaryBypassVAV->OACompOnMassFlow;
1727 13 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction = 0.0;
1728 13 : state.dataHVACUnitaryBypassVAV->PartLoadFrac = 0.0;
1729 : } else {
1730 3 : if (cBVAV.HeatCoolMode != 0) {
1731 3 : state.dataHVACUnitaryBypassVAV->PartLoadFrac = 1.0;
1732 : } else {
1733 0 : state.dataHVACUnitaryBypassVAV->PartLoadFrac = 0.0;
1734 : }
1735 3 : if (cBVAV.fanOp == HVAC::FanOp::Cycling) {
1736 3 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction = 0.0;
1737 : } else {
1738 0 : if (cBVAV.PlenumMixerInletAirNode == 0) {
1739 0 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction = max(
1740 0 : 0.0, 1.0 - (state.dataLoopNodes->Node(cBVAV.AirInNode).MassFlowRate / state.dataHVACUnitaryBypassVAV->CompOnMassFlow));
1741 : }
1742 : }
1743 : }
1744 : } else {
1745 1 : state.dataHVACUnitaryBypassVAV->PartLoadFrac = 0.0;
1746 1 : state.dataLoopNodes->Node(cBVAV.AirInNode).MassFlowRate = 0.0;
1747 1 : state.dataLoopNodes->Node(cBVAV.AirOutNode).MassFlowRate = 0.0;
1748 1 : state.dataLoopNodes->Node(cBVAV.AirOutNode).MassFlowRateMaxAvail = 0.0;
1749 :
1750 1 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate = 0.0;
1751 1 : state.dataLoopNodes->Node(cBVAV.MixerOutsideAirNode).MassFlowRate = 0.0;
1752 1 : state.dataLoopNodes->Node(cBVAV.MixerReliefAirNode).MassFlowRate = 0.0;
1753 :
1754 1 : OnOffAirFlowRatio = 1.0;
1755 1 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction = 0.0;
1756 : }
1757 :
1758 17 : CalcCBVAV(state, CBVAVNum, FirstHVACIteration, state.dataHVACUnitaryBypassVAV->PartLoadFrac, QSensUnitOut, OnOffAirFlowRatio, HXUnitOn);
1759 :
1760 : // If unit is scheduled OFF, setpoint is equal to inlet node temperature.
1761 17 : if (cBVAV.availSched->getCurrentVal() == 0.0) {
1762 0 : cBVAV.OutletTempSetPoint = state.dataLoopNodes->Node(InNode).Temp;
1763 0 : return;
1764 : }
1765 :
1766 17 : SetAverageAirFlow(state, CBVAVNum, OnOffAirFlowRatio);
1767 :
1768 17 : if (FirstHVACIteration) {
1769 14 : cBVAV.OutletTempSetPoint = CalcSetPointTempTarget(state, CBVAVNum);
1770 : }
1771 :
1772 : // The setpoint is used to control the DX coils at their respective outlet nodes (not the unit outlet), correct
1773 : // for fan heat for draw thru units only (fan heat is included at the outlet of each coil when blowthru is used)
1774 17 : cBVAV.CoilTempSetPoint = cBVAV.OutletTempSetPoint;
1775 17 : if (cBVAV.fanPlace == HVAC::FanPlace::DrawThru) {
1776 0 : cBVAV.CoilTempSetPoint -= (state.dataLoopNodes->Node(cBVAV.AirOutNode).Temp - state.dataLoopNodes->Node(cBVAV.FanInletNodeNum).Temp);
1777 : }
1778 :
1779 17 : if (FirstHVACIteration) {
1780 14 : if (cBVAV.HeatCoilType == HVAC::CoilType::HeatingWater) {
1781 0 : WaterCoils::SimulateWaterCoilComponents(state, cBVAV.HeatCoilName, FirstHVACIteration, cBVAV.HeatCoilIndex);
1782 :
1783 : // set air-side and steam-side mass flow rates
1784 0 : state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).MassFlowRate = state.dataHVACUnitaryBypassVAV->CompOnMassFlow;
1785 0 : mdot = cBVAV.MaxHeatCoilFluidFlow;
1786 0 : PlantUtilities::SetComponentFlowRate(state, mdot, cBVAV.CoilControlNode, cBVAV.CoilOutletNode, cBVAV.plantLoc);
1787 :
1788 : // simulate water coil to find operating capacity
1789 0 : WaterCoils::SimulateWaterCoilComponents(state, cBVAV.HeatCoilName, FirstHVACIteration, cBVAV.HeatCoilIndex, QCoilActual);
1790 0 : cBVAV.DesignSuppHeatingCapacity = QCoilActual;
1791 :
1792 : } // from IF(MSHeatPump(MSHeatPumpNum)%SuppHeatCoilType == HVAC::Coil_HeatingWater) THEN
1793 :
1794 14 : if (cBVAV.HeatCoilType == HVAC::CoilType::HeatingSteam) {
1795 :
1796 : // set air-side and steam-side mass flow rates
1797 0 : state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).MassFlowRate = state.dataHVACUnitaryBypassVAV->CompOnMassFlow;
1798 0 : mdot = cBVAV.MaxHeatCoilFluidFlow;
1799 0 : PlantUtilities::SetComponentFlowRate(state, mdot, cBVAV.CoilControlNode, cBVAV.CoilOutletNode, cBVAV.plantLoc);
1800 :
1801 : // simulate steam coil to find operating capacity
1802 0 : SteamCoils::SimulateSteamCoilComponents(state,
1803 : cBVAV.HeatCoilName,
1804 : FirstHVACIteration,
1805 0 : cBVAV.HeatCoilIndex,
1806 0 : 1.0,
1807 : QCoilActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
1808 0 : cBVAV.DesignSuppHeatingCapacity = QCoilActual;
1809 :
1810 : } // from IF(cBVAV%HeatCoilType == HVAC::Coil_HeatingSteam) THEN
1811 : } // from IF( FirstHVACIteration ) THEN
1812 :
1813 17 : if ((cBVAV.HeatCoolMode == 0 && cBVAV.fanOp == HVAC::FanOp::Cycling) || state.dataHVACUnitaryBypassVAV->CompOnMassFlow == 0.0) {
1814 4 : state.dataHVACUnitaryBypassVAV->PartLoadFrac = 0.0;
1815 4 : state.dataLoopNodes->Node(cBVAV.AirInNode).MassFlowRate = 0.0;
1816 4 : state.dataLoopNodes->Node(cBVAV.AirOutNode).MassFlowRateMaxAvail = 0.0;
1817 4 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate = 0.0;
1818 4 : state.dataLoopNodes->Node(cBVAV.MixerOutsideAirNode).MassFlowRate = 0.0;
1819 4 : state.dataLoopNodes->Node(cBVAV.MixerReliefAirNode).MassFlowRate = 0.0;
1820 : }
1821 : }
1822 :
1823 4 : void SizeCBVAV(EnergyPlusData &state, int const CBVAVNum) // Index to CBVAV system
1824 : {
1825 :
1826 : // SUBROUTINE INFORMATION:
1827 : // AUTHOR Richard Raustad
1828 : // DATE WRITTEN July 2006
1829 :
1830 : // PURPOSE OF THIS SUBROUTINE:
1831 : // This subroutine is for sizing changeover-bypass VAV components.
1832 :
1833 : // METHODOLOGY EMPLOYED:
1834 : // Obtains flow rates from the zone sizing arrays.
1835 :
1836 4 : int curSysNum = state.dataSize->CurSysNum;
1837 4 : int curOASysNum = state.dataSize->CurOASysNum;
1838 :
1839 4 : auto &cBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
1840 :
1841 4 : if (curSysNum > 0 && curOASysNum == 0) {
1842 4 : state.dataAirSystemsData->PrimaryAirSystems(curSysNum).supFanNum = cBVAV.FanIndex;
1843 4 : state.dataAirSystemsData->PrimaryAirSystems(curSysNum).supFanType = cBVAV.fanType;
1844 4 : state.dataAirSystemsData->PrimaryAirSystems(curSysNum).supFanPlace = cBVAV.fanPlace;
1845 : }
1846 :
1847 4 : if (cBVAV.MaxCoolAirVolFlow == DataSizing::AutoSize) {
1848 :
1849 1 : if (curSysNum > 0) {
1850 :
1851 1 : CheckSysSizing(state, cBVAV.UnitType, cBVAV.Name);
1852 1 : cBVAV.MaxCoolAirVolFlow = state.dataSize->FinalSysSizing(curSysNum).DesMainVolFlow;
1853 1 : if (cBVAV.FanVolFlow < cBVAV.MaxCoolAirVolFlow && cBVAV.FanVolFlow != DataSizing::AutoSize) {
1854 0 : cBVAV.MaxCoolAirVolFlow = cBVAV.FanVolFlow;
1855 0 : ShowWarningError(state, format("{} \"{}\"", cBVAV.UnitType, cBVAV.Name));
1856 0 : ShowContinueError(state,
1857 : "The CBVAV system supply air fan air flow rate is less than the autosized value for the maximum air flow rate "
1858 : "in cooling mode. Consider autosizing the fan for this simulation.");
1859 0 : ShowContinueError(
1860 : state, "The maximum air flow rate in cooling mode is reset to the supply air fan flow rate and the simulation continues.");
1861 : }
1862 1 : if (cBVAV.MaxCoolAirVolFlow < HVAC::SmallAirVolFlow) {
1863 0 : cBVAV.MaxCoolAirVolFlow = 0.0;
1864 : }
1865 1 : BaseSizer::reportSizerOutput(state, cBVAV.UnitType, cBVAV.Name, "maximum cooling air flow rate [m3/s]", cBVAV.MaxCoolAirVolFlow);
1866 : }
1867 : }
1868 :
1869 4 : if (cBVAV.MaxHeatAirVolFlow == DataSizing::AutoSize) {
1870 :
1871 1 : if (curSysNum > 0) {
1872 :
1873 1 : CheckSysSizing(state, cBVAV.UnitType, cBVAV.Name);
1874 1 : cBVAV.MaxHeatAirVolFlow = state.dataSize->FinalSysSizing(curSysNum).DesMainVolFlow;
1875 1 : if (cBVAV.FanVolFlow < cBVAV.MaxHeatAirVolFlow && cBVAV.FanVolFlow != DataSizing::AutoSize) {
1876 0 : cBVAV.MaxHeatAirVolFlow = cBVAV.FanVolFlow;
1877 0 : ShowWarningError(state, format("{} \"{}\"", cBVAV.UnitType, cBVAV.Name));
1878 0 : ShowContinueError(state,
1879 : "The CBVAV system supply air fan air flow rate is less than the autosized value for the maximum air flow rate "
1880 : "in heating mode. Consider autosizing the fan for this simulation.");
1881 0 : ShowContinueError(
1882 : state, "The maximum air flow rate in heating mode is reset to the supply air fan flow rate and the simulation continues.");
1883 : }
1884 1 : if (cBVAV.MaxHeatAirVolFlow < HVAC::SmallAirVolFlow) {
1885 0 : cBVAV.MaxHeatAirVolFlow = 0.0;
1886 : }
1887 1 : BaseSizer::reportSizerOutput(state, cBVAV.UnitType, cBVAV.Name, "maximum heating air flow rate [m3/s]", cBVAV.MaxHeatAirVolFlow);
1888 : }
1889 : }
1890 :
1891 4 : if (cBVAV.MaxNoCoolHeatAirVolFlow == DataSizing::AutoSize) {
1892 :
1893 1 : if (curSysNum > 0) {
1894 :
1895 1 : CheckSysSizing(state, cBVAV.UnitType, cBVAV.Name);
1896 1 : cBVAV.MaxNoCoolHeatAirVolFlow = state.dataSize->FinalSysSizing(curSysNum).DesMainVolFlow;
1897 1 : if (cBVAV.FanVolFlow < cBVAV.MaxNoCoolHeatAirVolFlow && cBVAV.FanVolFlow != DataSizing::AutoSize) {
1898 0 : cBVAV.MaxNoCoolHeatAirVolFlow = cBVAV.FanVolFlow;
1899 0 : ShowWarningError(state, format("{} \"{}\"", cBVAV.UnitType, cBVAV.Name));
1900 0 : ShowContinueError(state,
1901 : "The CBVAV system supply air fan air flow rate is less than the autosized value for the maximum air flow rate "
1902 : "when no heating or cooling is needed. Consider autosizing the fan for this simulation.");
1903 0 : ShowContinueError(state,
1904 : "The maximum air flow rate when no heating or cooling is needed is reset to the supply air fan flow rate and "
1905 : "the simulation continues.");
1906 : }
1907 1 : if (cBVAV.MaxNoCoolHeatAirVolFlow < HVAC::SmallAirVolFlow) {
1908 0 : cBVAV.MaxNoCoolHeatAirVolFlow = 0.0;
1909 : }
1910 :
1911 1 : BaseSizer::reportSizerOutput(
1912 : state, cBVAV.UnitType, cBVAV.Name, "maximum air flow rate when compressor/coil is off [m3/s]", cBVAV.MaxNoCoolHeatAirVolFlow);
1913 : }
1914 : }
1915 :
1916 4 : if (cBVAV.CoolOutAirVolFlow == DataSizing::AutoSize) {
1917 :
1918 1 : if (curSysNum > 0) {
1919 :
1920 1 : CheckSysSizing(state, cBVAV.UnitType, cBVAV.Name);
1921 1 : cBVAV.CoolOutAirVolFlow = state.dataSize->FinalSysSizing(curSysNum).DesOutAirVolFlow;
1922 1 : if (cBVAV.FanVolFlow < cBVAV.CoolOutAirVolFlow && cBVAV.FanVolFlow != DataSizing::AutoSize) {
1923 0 : cBVAV.CoolOutAirVolFlow = cBVAV.FanVolFlow;
1924 0 : ShowWarningError(state, format("{} \"{}\"", cBVAV.UnitType, cBVAV.Name));
1925 0 : ShowContinueError(state,
1926 : "The CBVAV system supply air fan air flow rate is less than the autosized value for the outdoor air flow rate "
1927 : "in cooling mode. Consider autosizing the fan for this simulation.");
1928 0 : ShowContinueError(
1929 : state, "The outdoor air flow rate in cooling mode is reset to the supply air fan flow rate and the simulation continues.");
1930 : }
1931 1 : if (cBVAV.CoolOutAirVolFlow < HVAC::SmallAirVolFlow) {
1932 0 : cBVAV.CoolOutAirVolFlow = 0.0;
1933 : }
1934 1 : BaseSizer::reportSizerOutput(
1935 : state, cBVAV.UnitType, cBVAV.Name, "maximum outside air flow rate in cooling [m3/s]", cBVAV.CoolOutAirVolFlow);
1936 : }
1937 : }
1938 :
1939 4 : if (cBVAV.HeatOutAirVolFlow == DataSizing::AutoSize) {
1940 :
1941 1 : if (curSysNum > 0) {
1942 :
1943 1 : CheckSysSizing(state, cBVAV.UnitType, cBVAV.Name);
1944 1 : cBVAV.HeatOutAirVolFlow = state.dataSize->FinalSysSizing(curSysNum).DesOutAirVolFlow;
1945 1 : if (cBVAV.FanVolFlow < cBVAV.HeatOutAirVolFlow && cBVAV.FanVolFlow != DataSizing::AutoSize) {
1946 0 : cBVAV.HeatOutAirVolFlow = cBVAV.FanVolFlow;
1947 0 : ShowContinueError(state,
1948 : "The CBVAV system supply air fan air flow rate is less than the autosized value for the outdoor air flow rate "
1949 : "in heating mode. Consider autosizing the fan for this simulation.");
1950 0 : ShowContinueError(
1951 : state, "The outdoor air flow rate in heating mode is reset to the supply air fan flow rate and the simulation continues.");
1952 : }
1953 1 : if (cBVAV.HeatOutAirVolFlow < HVAC::SmallAirVolFlow) {
1954 0 : cBVAV.HeatOutAirVolFlow = 0.0;
1955 : }
1956 1 : BaseSizer::reportSizerOutput(
1957 : state, cBVAV.UnitType, cBVAV.Name, "maximum outdoor air flow rate in heating [m3/s]", cBVAV.CoolOutAirVolFlow);
1958 : }
1959 : }
1960 :
1961 4 : if (cBVAV.NoCoolHeatOutAirVolFlow == DataSizing::AutoSize) {
1962 :
1963 1 : if (curSysNum > 0) {
1964 :
1965 1 : CheckSysSizing(state, cBVAV.UnitType, cBVAV.Name);
1966 1 : cBVAV.NoCoolHeatOutAirVolFlow = state.dataSize->FinalSysSizing(curSysNum).DesOutAirVolFlow;
1967 1 : if (cBVAV.FanVolFlow < cBVAV.NoCoolHeatOutAirVolFlow && cBVAV.FanVolFlow != DataSizing::AutoSize) {
1968 0 : cBVAV.NoCoolHeatOutAirVolFlow = cBVAV.FanVolFlow;
1969 0 : ShowContinueError(state,
1970 : "The CBVAV system supply air fan air flow rate is less than the autosized value for the outdoor air flow rate "
1971 : "when no heating or cooling is needed. Consider autosizing the fan for this simulation.");
1972 0 : ShowContinueError(state,
1973 : "The outdoor air flow rate when no heating or cooling is needed is reset to the supply air fan flow rate and "
1974 : "the simulation continues.");
1975 : }
1976 1 : if (cBVAV.NoCoolHeatOutAirVolFlow < HVAC::SmallAirVolFlow) {
1977 0 : cBVAV.NoCoolHeatOutAirVolFlow = 0.0;
1978 : }
1979 1 : BaseSizer::reportSizerOutput(
1980 : state, cBVAV.UnitType, cBVAV.Name, "maximum outdoor air flow rate when compressor is off [m3/s]", cBVAV.NoCoolHeatOutAirVolFlow);
1981 : }
1982 : }
1983 4 : }
1984 :
1985 7 : void ControlCBVAVOutput(EnergyPlusData &state,
1986 : int const CBVAVNum, // Index to CBVAV system
1987 : bool const FirstHVACIteration, // Flag for 1st HVAC iteration
1988 : Real64 &PartLoadFrac, // Unit part load fraction
1989 : Real64 &OnOffAirFlowRatio, // Ratio of compressor ON airflow to AVERAGE airflow over timestep
1990 : bool const HXUnitOn // flag to enable heat exchanger
1991 : )
1992 : {
1993 :
1994 : // SUBROUTINE INFORMATION:
1995 : // AUTHOR Richard Raustad
1996 : // DATE WRITTEN July 2006
1997 :
1998 : // PURPOSE OF THIS SUBROUTINE:
1999 : // Determine the part load fraction of the CBVAV system for this time step.
2000 :
2001 : // METHODOLOGY EMPLOYED:
2002 : // Use RegulaFalsi technique to iterate on part-load ratio until convergence is achieved.
2003 :
2004 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2005 7 : Real64 FullOutput = 0; // Unit full output when compressor is operating [W]
2006 7 : PartLoadFrac = 0.0;
2007 :
2008 7 : auto &cBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2009 :
2010 7 : if (cBVAV.availSched->getCurrentVal() == 0.0) {
2011 0 : return;
2012 : }
2013 :
2014 : // Get operating result
2015 7 : PartLoadFrac = 1.0;
2016 7 : CalcCBVAV(state, CBVAVNum, FirstHVACIteration, PartLoadFrac, FullOutput, OnOffAirFlowRatio, HXUnitOn);
2017 :
2018 11 : if ((state.dataLoopNodes->Node(cBVAV.AirOutNode).Temp - cBVAV.OutletTempSetPoint) > HVAC::SmallTempDiff && cBVAV.HeatCoolMode > 0 &&
2019 4 : PartLoadFrac < 1.0) {
2020 0 : CalcCBVAV(state, CBVAVNum, FirstHVACIteration, PartLoadFrac, FullOutput, OnOffAirFlowRatio, HXUnitOn);
2021 : }
2022 : }
2023 :
2024 30 : void CalcCBVAV(EnergyPlusData &state,
2025 : int const CBVAVNum, // Unit index in fan coil array
2026 : bool const FirstHVACIteration, // Flag for 1st HVAC iteration
2027 : Real64 &PartLoadFrac, // Compressor part load fraction
2028 : Real64 &LoadMet, // Load met by unit (W)
2029 : Real64 &OnOffAirFlowRatio, // Ratio of compressor ON airflow to AVERAGE airflow over timestep
2030 : bool const HXUnitOn // flag to enable heat exchanger
2031 : )
2032 : {
2033 :
2034 : // SUBROUTINE INFORMATION:
2035 : // AUTHOR Richard Raustad
2036 : // DATE WRITTEN July 2006
2037 :
2038 : // PURPOSE OF THIS SUBROUTINE:
2039 : // Simulate the components making up the changeover-bypass VAV system.
2040 :
2041 : // METHODOLOGY EMPLOYED:
2042 : // Simulates the unit components sequentially in the air flow direction.
2043 :
2044 : // SUBROUTINE PARAMETER DEFINITIONS:
2045 30 : int constexpr MaxIte(500); // Maximum number of iterations
2046 :
2047 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2048 : Real64 MinHumRat; // Minimum humidity ratio for sensible capacity calculation (kg/kg)
2049 : int SolFla; // Flag of RegulaFalsi solver
2050 : Real64 QHeater; // Load to be met by heater [W]
2051 : Real64 QHeaterActual; // actual heating load met [W]
2052 : Real64 CpAir; // Specific heat of air [J/kg-K]
2053 : Real64 ApproachTemp;
2054 : Real64 DesiredDewPoint;
2055 : Real64 OutdoorDryBulbTemp; // Dry-bulb temperature at outdoor condenser
2056 : Real64 OutdoorBaroPress; // Barometric pressure at outdoor condenser
2057 :
2058 30 : auto &cBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2059 :
2060 30 : int OutletNode = cBVAV.AirOutNode;
2061 30 : int InletNode = cBVAV.AirInNode;
2062 30 : if (cBVAV.CondenserNodeNum > 0) {
2063 0 : OutdoorDryBulbTemp = state.dataLoopNodes->Node(cBVAV.CondenserNodeNum).Temp;
2064 0 : OutdoorBaroPress = state.dataLoopNodes->Node(cBVAV.CondenserNodeNum).Press;
2065 : } else {
2066 30 : OutdoorDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
2067 30 : OutdoorBaroPress = state.dataEnvrn->OutBaroPress;
2068 : }
2069 :
2070 30 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = 0.0;
2071 :
2072 : // Bypass excess system air through bypass duct and calculate new mixed air conditions at OA mixer inlet node
2073 30 : if (cBVAV.plenumIndex > 0 || cBVAV.mixerIndex > 0) {
2074 13 : Real64 saveMixerInletAirNodeFlow = state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate;
2075 13 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode) = state.dataLoopNodes->Node(InletNode);
2076 13 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate = saveMixerInletAirNodeFlow;
2077 13 : } else {
2078 17 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).Temp =
2079 17 : (1.0 - state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction) * state.dataLoopNodes->Node(InletNode).Temp +
2080 17 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction * state.dataLoopNodes->Node(OutletNode).Temp;
2081 17 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).HumRat =
2082 17 : (1.0 - state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction) * state.dataLoopNodes->Node(InletNode).HumRat +
2083 17 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction * state.dataLoopNodes->Node(OutletNode).HumRat;
2084 17 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).Enthalpy = Psychrometrics::PsyHFnTdbW(
2085 17 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).Temp, state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).HumRat);
2086 : }
2087 30 : MixedAir::SimOAMixer(state, cBVAV.OAMixName, cBVAV.OAMixIndex);
2088 :
2089 30 : if (cBVAV.fanPlace == HVAC::FanPlace::BlowThru) {
2090 2 : state.dataFans->fans(cBVAV.FanIndex)
2091 2 : ->simulate(state, FirstHVACIteration, state.dataHVACUnitaryBypassVAV->FanSpeedRatio, _, 1.0 / OnOffAirFlowRatio);
2092 : }
2093 : // Simulate cooling coil if zone load is negative (cooling load)
2094 30 : if (cBVAV.HeatCoolMode == CoolingMode) {
2095 16 : if (OutdoorDryBulbTemp >= cBVAV.MinOATCompressor) {
2096 16 : switch (cBVAV.CoolCoilType) {
2097 0 : case HVAC::CoilType::DXCoolingHXAssisted: {
2098 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
2099 : cBVAV.DXCoolCoilName,
2100 : FirstHVACIteration,
2101 : HVAC::CompressorOp::On,
2102 : PartLoadFrac,
2103 0 : cBVAV.CoolCoilCompIndex,
2104 : HVAC::FanOp::Continuous,
2105 : HXUnitOn);
2106 0 : if (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp <= cBVAV.CoilTempSetPoint) {
2107 : // If coil inlet temp is already below the setpoint, simulated with coil off
2108 0 : PartLoadFrac = 0.0;
2109 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
2110 : cBVAV.DXCoolCoilName,
2111 : FirstHVACIteration,
2112 : HVAC::CompressorOp::Off,
2113 : PartLoadFrac,
2114 0 : cBVAV.CoolCoilCompIndex,
2115 : HVAC::FanOp::Continuous,
2116 : HXUnitOn);
2117 0 : } else if (state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp < cBVAV.CoilTempSetPoint) {
2118 0 : auto f = [&state, CBVAVNum, FirstHVACIteration, HXUnitOn](Real64 const PartLoadFrac) {
2119 0 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2120 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
2121 : thisCBVAV.DXCoolCoilName,
2122 : FirstHVACIteration,
2123 : HVAC::CompressorOp::On,
2124 : PartLoadFrac,
2125 0 : thisCBVAV.CoolCoilCompIndex,
2126 : HVAC::FanOp::Continuous,
2127 0 : HXUnitOn);
2128 :
2129 0 : Real64 OutletAirTemp = state.dataLoopNodes->Node(thisCBVAV.DXCoilOutletNode).Temp;
2130 0 : return thisCBVAV.CoilTempSetPoint - OutletAirTemp;
2131 0 : };
2132 0 : General::SolveRoot(state, HVAC::SmallTempDiff, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
2133 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
2134 : cBVAV.DXCoolCoilName,
2135 : FirstHVACIteration,
2136 : HVAC::CompressorOp::On,
2137 : PartLoadFrac,
2138 0 : cBVAV.CoolCoilCompIndex,
2139 : HVAC::FanOp::Continuous,
2140 : HXUnitOn);
2141 0 : if (SolFla == -1 && !state.dataGlobal->WarmupFlag) {
2142 0 : if (cBVAV.HXDXIterationExceeded < 1) {
2143 0 : ++cBVAV.HXDXIterationExceeded;
2144 0 : ShowWarningError(state,
2145 0 : format("Iteration limit exceeded calculating HX assisted DX unit part-load ratio, for unit = {}",
2146 0 : cBVAV.DXCoolCoilName));
2147 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
2148 0 : ShowContinueErrorTimeStamp(
2149 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
2150 : } else {
2151 0 : ShowRecurringWarningErrorAtEnd(
2152 : state,
2153 0 : cBVAV.Name + ", Iteration limit exceeded for HX assisted DX unit part-load ratio error continues.",
2154 0 : cBVAV.HXDXIterationExceededIndex,
2155 : PartLoadFrac,
2156 : PartLoadFrac);
2157 : }
2158 0 : } else if (SolFla == -2 && !state.dataGlobal->WarmupFlag) {
2159 0 : PartLoadFrac = max(0.0,
2160 : min(1.0,
2161 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp - cBVAV.CoilTempSetPoint) /
2162 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp -
2163 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp)));
2164 0 : if (cBVAV.HXDXIterationFailed < 1) {
2165 0 : ++cBVAV.HXDXIterationFailed;
2166 0 : ShowSevereError(
2167 : state,
2168 0 : format("HX assisted DX unit part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
2169 0 : cBVAV.DXCoolCoilName));
2170 0 : ShowContinueErrorTimeStamp(
2171 : state,
2172 0 : format("An estimated part-load ratio of {:.3R}will be used and the simulation continues. Occurrence info:",
2173 : PartLoadFrac));
2174 : } else {
2175 0 : ShowRecurringWarningErrorAtEnd(state,
2176 0 : cBVAV.Name +
2177 : ", Part-load ratio calculation failed for HX assisted DX unit error continues.",
2178 0 : cBVAV.HXDXIterationFailedIndex,
2179 : PartLoadFrac,
2180 : PartLoadFrac);
2181 : }
2182 : }
2183 : }
2184 0 : } break;
2185 16 : case HVAC::CoilType::DXCoolingSingleSpeed: {
2186 32 : DXCoils::SimDXCoil(state,
2187 : cBVAV.DXCoolCoilName,
2188 : HVAC::CompressorOp::On,
2189 : FirstHVACIteration,
2190 16 : cBVAV.CoolCoilCompIndex,
2191 : HVAC::FanOp::Continuous,
2192 : PartLoadFrac,
2193 : OnOffAirFlowRatio);
2194 16 : if (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp <= cBVAV.CoilTempSetPoint) {
2195 : // If coil inlet temp is already below the setpoint, simulated with coil off
2196 1 : PartLoadFrac = 0.0;
2197 2 : DXCoils::SimDXCoil(state,
2198 : cBVAV.DXCoolCoilName,
2199 : HVAC::CompressorOp::On,
2200 : FirstHVACIteration,
2201 1 : cBVAV.CoolCoilCompIndex,
2202 : HVAC::FanOp::Continuous,
2203 : PartLoadFrac,
2204 : OnOffAirFlowRatio);
2205 15 : } else if (state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp < cBVAV.CoilTempSetPoint) {
2206 25 : auto f = [&state, CBVAVNum, OnOffAirFlowRatio](Real64 const PartLoadFrac) {
2207 20 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2208 40 : DXCoils::CalcDoe2DXCoil(state,
2209 : thisCBVAV.CoolCoilCompIndex,
2210 : HVAC::CompressorOp::On,
2211 : false,
2212 : PartLoadFrac,
2213 : HVAC::FanOp::Continuous,
2214 : _,
2215 20 : OnOffAirFlowRatio);
2216 20 : Real64 OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(thisCBVAV.CoolCoilCompIndex);
2217 20 : return thisCBVAV.CoilTempSetPoint - OutletAirTemp;
2218 5 : };
2219 5 : General::SolveRoot(state, HVAC::SmallTempDiff, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
2220 10 : DXCoils::SimDXCoil(state,
2221 : cBVAV.DXCoolCoilName,
2222 : HVAC::CompressorOp::On,
2223 : FirstHVACIteration,
2224 5 : cBVAV.CoolCoilCompIndex,
2225 : HVAC::FanOp::Continuous,
2226 : PartLoadFrac,
2227 : OnOffAirFlowRatio);
2228 5 : if (SolFla == -1 && !state.dataGlobal->WarmupFlag) {
2229 0 : if (cBVAV.DXIterationExceeded < 1) {
2230 0 : ++cBVAV.DXIterationExceeded;
2231 0 : ShowWarningError(
2232 : state,
2233 0 : format("Iteration limit exceeded calculating DX unit part-load ratio, for unit = {}", cBVAV.DXCoolCoilName));
2234 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
2235 0 : ShowContinueErrorTimeStamp(
2236 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
2237 : } else {
2238 0 : ShowRecurringWarningErrorAtEnd(
2239 : state,
2240 0 : cBVAV.Name + ", Iteration limit exceeded for DX unit part-load ratio calculation error continues.",
2241 0 : cBVAV.DXIterationExceededIndex,
2242 : PartLoadFrac,
2243 : PartLoadFrac);
2244 : }
2245 5 : } else if (SolFla == -2 && !state.dataGlobal->WarmupFlag) {
2246 0 : PartLoadFrac = max(0.0,
2247 : min(1.0,
2248 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp - cBVAV.CoilTempSetPoint) /
2249 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp -
2250 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp)));
2251 0 : if (cBVAV.DXIterationFailed < 1) {
2252 0 : ++cBVAV.DXIterationFailed;
2253 0 : ShowSevereError(state,
2254 0 : format("DX unit part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
2255 0 : cBVAV.DXCoolCoilName));
2256 0 : ShowContinueErrorTimeStamp(
2257 : state,
2258 0 : format("An estimated part-load ratio of {:.3R}will be used and the simulation continues. Occurrence info:",
2259 : PartLoadFrac));
2260 : } else {
2261 0 : ShowRecurringWarningErrorAtEnd(state,
2262 0 : cBVAV.Name + ", Part-load ratio calculation failed for DX unit error continues.",
2263 0 : cBVAV.DXIterationFailedIndex,
2264 : PartLoadFrac,
2265 : PartLoadFrac);
2266 : }
2267 : }
2268 : }
2269 16 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(cBVAV.DXCoolCoilIndexNum);
2270 16 : } break;
2271 0 : case HVAC::CoilType::CoolingAirToAirVariableSpeed: {
2272 0 : Real64 QZnReq(0.0); // Zone load (W), input to variable-speed DX coil
2273 0 : Real64 QLatReq(0.0); // Zone latent load, input to variable-speed DX coil
2274 0 : Real64 LocalOnOffAirFlowRatio(1.0); // ratio of compressor on flow to average flow over time step
2275 0 : Real64 LocalPartLoadFrac(0.0);
2276 0 : Real64 SpeedRatio(0.0);
2277 0 : int SpeedNum(1);
2278 0 : bool errorFlag(false);
2279 0 : int maxNumSpeeds = VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, cBVAV.DXCoolCoilName, errorFlag);
2280 0 : Real64 DesOutTemp = cBVAV.CoilTempSetPoint;
2281 : // Get no load result
2282 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2283 : cBVAV.DXCoolCoilName,
2284 0 : cBVAV.CoolCoilCompIndex,
2285 : HVAC::FanOp::Continuous,
2286 : HVAC::CompressorOp::Off,
2287 : LocalPartLoadFrac,
2288 : SpeedNum,
2289 : SpeedRatio,
2290 : QZnReq,
2291 : QLatReq);
2292 :
2293 0 : Real64 NoOutput = state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).MassFlowRate *
2294 0 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp,
2295 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat) -
2296 0 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp,
2297 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat));
2298 :
2299 : // Get full load result
2300 0 : LocalPartLoadFrac = 1.0;
2301 0 : SpeedNum = maxNumSpeeds;
2302 0 : SpeedRatio = 1.0;
2303 0 : QZnReq = 0.001; // to indicate the coil is running
2304 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2305 : cBVAV.DXCoolCoilName,
2306 0 : cBVAV.CoolCoilCompIndex,
2307 : HVAC::FanOp::Continuous,
2308 : HVAC::CompressorOp::On,
2309 : LocalPartLoadFrac,
2310 : SpeedNum,
2311 : SpeedRatio,
2312 : QZnReq,
2313 : QLatReq);
2314 :
2315 0 : Real64 FullOutput = state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).MassFlowRate *
2316 0 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp,
2317 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat) -
2318 0 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp,
2319 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat));
2320 0 : Real64 ReqOutput = state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).MassFlowRate *
2321 0 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat) -
2322 0 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp,
2323 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat));
2324 :
2325 0 : Real64 loadAccuracy(0.001); // Watts, power
2326 0 : Real64 tempAccuracy(0.001); // delta C, temperature
2327 0 : if ((NoOutput - ReqOutput) < loadAccuracy) { // IF NoOutput is lower than (more cooling than required) or very near
2328 : // the ReqOutput, do not run the compressor
2329 0 : LocalPartLoadFrac = 0.0;
2330 0 : SpeedNum = 1;
2331 0 : SpeedRatio = 0.0;
2332 0 : QZnReq = 0.0;
2333 : // Get no load result
2334 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2335 : cBVAV.DXCoolCoilName,
2336 0 : cBVAV.CoolCoilCompIndex,
2337 : HVAC::FanOp::Continuous,
2338 : HVAC::CompressorOp::Off,
2339 : LocalPartLoadFrac,
2340 : SpeedNum,
2341 : SpeedRatio,
2342 : QZnReq,
2343 : QLatReq);
2344 :
2345 0 : } else if ((FullOutput - ReqOutput) > loadAccuracy) {
2346 : // If the FullOutput is greater than (insufficient cooling) or very near the ReqOutput,
2347 : // run the compressor at LocalPartLoadFrac = 1.
2348 0 : LocalPartLoadFrac = 1.0;
2349 0 : SpeedNum = maxNumSpeeds;
2350 0 : SpeedRatio = 1.0;
2351 : // Else find the PLR to meet the load
2352 : } else {
2353 : // OutletTempDXCoil is the full capacity outlet temperature at LocalPartLoadFrac = 1 from the CALL above. If this
2354 : // temp is greater than the desired outlet temp, then run the compressor at LocalPartLoadFrac = 1, otherwise find
2355 : // the operating PLR.
2356 0 : Real64 OutletTempDXCoil = state.dataVariableSpeedCoils->VarSpeedCoil(cBVAV.CoolCoilCompIndex).OutletAirDBTemp;
2357 0 : if (OutletTempDXCoil > DesOutTemp) {
2358 0 : LocalPartLoadFrac = 1.0;
2359 0 : SpeedNum = maxNumSpeeds;
2360 0 : SpeedRatio = 1.0;
2361 : } else {
2362 : // run at lowest speed
2363 0 : LocalPartLoadFrac = 1.0;
2364 0 : SpeedNum = 1;
2365 0 : SpeedRatio = 1.0;
2366 0 : QZnReq = 0.001; // to indicate the coil is running
2367 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2368 : cBVAV.DXCoolCoilName,
2369 0 : cBVAV.CoolCoilCompIndex,
2370 : HVAC::FanOp::Continuous,
2371 : HVAC::CompressorOp::On,
2372 : LocalPartLoadFrac,
2373 : SpeedNum,
2374 : SpeedRatio,
2375 : QZnReq,
2376 : QLatReq,
2377 : LocalOnOffAirFlowRatio);
2378 :
2379 0 : Real64 TempSpeedOut = state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).MassFlowRate *
2380 0 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp,
2381 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat) -
2382 0 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp,
2383 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat));
2384 : Real64 TempSpeedReqst =
2385 0 : state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).MassFlowRate *
2386 0 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat) -
2387 0 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp,
2388 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat));
2389 :
2390 0 : if ((TempSpeedOut - TempSpeedReqst) > tempAccuracy) {
2391 : // Check to see which speed to meet the load
2392 0 : LocalPartLoadFrac = 1.0;
2393 0 : SpeedRatio = 1.0;
2394 0 : for (int I = 2; I <= maxNumSpeeds; ++I) {
2395 0 : SpeedNum = I;
2396 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2397 : cBVAV.DXCoolCoilName,
2398 0 : cBVAV.CoolCoilCompIndex,
2399 : HVAC::FanOp::Continuous,
2400 : HVAC::CompressorOp::On,
2401 : LocalPartLoadFrac,
2402 : SpeedNum,
2403 : SpeedRatio,
2404 : QZnReq,
2405 : QLatReq,
2406 : LocalOnOffAirFlowRatio);
2407 :
2408 0 : TempSpeedOut = state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).MassFlowRate *
2409 0 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp,
2410 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat) -
2411 0 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp,
2412 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat));
2413 0 : TempSpeedReqst =
2414 0 : state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).MassFlowRate *
2415 0 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat) -
2416 0 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp,
2417 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat));
2418 :
2419 0 : if ((TempSpeedOut - TempSpeedReqst) < tempAccuracy) {
2420 0 : SpeedNum = I;
2421 0 : break;
2422 : }
2423 : }
2424 : // now find the speed ratio for the found speednum
2425 0 : auto f = [&state, CBVAVNum, SpeedNum, DesOutTemp](Real64 const SpeedRatio) {
2426 0 : auto const &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2427 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2428 : Real64 OutletAirTemp; // outlet air temperature [C]
2429 0 : Real64 QZnReqCycling = 0.001;
2430 0 : Real64 QLatReqCycling = 0.0;
2431 0 : Real64 OnOffAirFlowRatioCycling = 1.0;
2432 0 : Real64 partLoadRatio = 1.0;
2433 0 : int CoilIndex = thisCBVAV.CoolCoilCompIndex;
2434 0 : HVAC::FanOp fanOp = HVAC::FanOp::Continuous;
2435 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2436 : "",
2437 : CoilIndex,
2438 : fanOp,
2439 : HVAC::CompressorOp::On,
2440 : partLoadRatio,
2441 : SpeedNum,
2442 : SpeedRatio,
2443 : QZnReqCycling,
2444 : QLatReqCycling,
2445 : OnOffAirFlowRatioCycling);
2446 :
2447 0 : OutletAirTemp = state.dataVariableSpeedCoils->VarSpeedCoil(CoilIndex).OutletAirDBTemp;
2448 0 : return DesOutTemp - OutletAirTemp;
2449 0 : };
2450 0 : General::SolveRoot(state, tempAccuracy, MaxIte, SolFla, SpeedRatio, f, 1.0e-10, 1.0);
2451 :
2452 0 : if (SolFla == -1) {
2453 0 : if (!state.dataGlobal->WarmupFlag) {
2454 0 : if (cBVAV.DXIterationExceeded < 4) {
2455 0 : ++cBVAV.DXIterationExceeded;
2456 0 : ShowWarningError(state,
2457 0 : format("{} - Iteration limit exceeded calculating VS DX coil speed ratio for coil named "
2458 : "{}, in Unitary system named{}",
2459 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2460 0 : cBVAV.DXCoolCoilName,
2461 0 : cBVAV.Name));
2462 0 : ShowContinueError(state, format("Calculated speed ratio = {:.4R}", SpeedRatio));
2463 0 : ShowContinueErrorTimeStamp(
2464 : state, "The calculated speed ratio will be used and the simulation continues. Occurrence info:");
2465 : }
2466 0 : ShowRecurringWarningErrorAtEnd(state,
2467 0 : format("{} \"{}\" - Iteration limit exceeded calculating speed ratio error "
2468 : "continues. Speed Ratio statistics follow.",
2469 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2470 0 : cBVAV.DXCoolCoilName),
2471 0 : cBVAV.DXIterationExceededIndex,
2472 : LocalPartLoadFrac,
2473 : LocalPartLoadFrac);
2474 : }
2475 0 : } else if (SolFla == -2) {
2476 0 : if (!state.dataGlobal->WarmupFlag) {
2477 0 : if (cBVAV.DXIterationFailed < 4) {
2478 0 : ++cBVAV.DXIterationFailed;
2479 0 : ShowWarningError(state,
2480 0 : format("{} - DX unit speed ratio calculation failed: solver limits exceeded, for coil "
2481 : "named {}, in Unitary system named{}",
2482 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2483 0 : cBVAV.DXCoolCoilName,
2484 0 : cBVAV.Name));
2485 0 : ShowContinueError(state, format("Estimated speed ratio = {:.3R}", TempSpeedReqst / TempSpeedOut));
2486 0 : ShowContinueErrorTimeStamp(
2487 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
2488 : }
2489 0 : ShowRecurringWarningErrorAtEnd(
2490 : state,
2491 0 : format(
2492 : "{} \"{}\" - DX unit speed ratio calculation failed error continues. speed ratio statistics follow.",
2493 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2494 0 : cBVAV.DXCoolCoilName),
2495 0 : cBVAV.DXIterationFailedIndex,
2496 : SpeedRatio,
2497 : SpeedRatio);
2498 : }
2499 0 : SpeedRatio = TempSpeedReqst / TempSpeedOut;
2500 : }
2501 : } else {
2502 : // cycling compressor at lowest speed number, find part load fraction
2503 0 : auto f = [&state, CBVAVNum, DesOutTemp](Real64 const PartLoadRatio) {
2504 0 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2505 0 : int speedNum = 1;
2506 0 : Real64 speedRatio = 0.0;
2507 0 : Real64 QZnReqCycling = 0.001;
2508 0 : Real64 QLatReqCycling = 0.0;
2509 0 : Real64 OnOffAirFlowRatioCycling = 1.0;
2510 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2511 : "",
2512 0 : thisCBVAV.CoolCoilCompIndex,
2513 : HVAC::FanOp::Continuous,
2514 : HVAC::CompressorOp::On,
2515 : PartLoadRatio,
2516 : speedNum,
2517 : speedRatio,
2518 : QZnReqCycling,
2519 : QLatReqCycling,
2520 : OnOffAirFlowRatioCycling);
2521 :
2522 0 : Real64 OutletAirTemp = state.dataVariableSpeedCoils->VarSpeedCoil(thisCBVAV.CoolCoilCompIndex).OutletAirDBTemp;
2523 0 : return DesOutTemp - OutletAirTemp;
2524 0 : };
2525 0 : General::SolveRoot(state, tempAccuracy, MaxIte, SolFla, LocalPartLoadFrac, f, 1.0e-10, 1.0);
2526 0 : if (SolFla == -1) {
2527 0 : if (!state.dataGlobal->WarmupFlag) {
2528 0 : if (cBVAV.DXCyclingIterationExceeded < 4) {
2529 0 : ++cBVAV.DXCyclingIterationExceeded;
2530 0 : ShowWarningError(state,
2531 0 : format("{} - Iteration limit exceeded calculating VS DX unit low speed cycling ratio, "
2532 : "for coil named {}, in Unitary system named{}",
2533 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2534 0 : cBVAV.DXCoolCoilName,
2535 0 : cBVAV.Name));
2536 0 : ShowContinueError(state, format("Estimated cycling ratio = {:.3R}", (TempSpeedReqst / TempSpeedOut)));
2537 0 : ShowContinueError(state, format("Calculated cycling ratio = {:.3R}", LocalPartLoadFrac));
2538 0 : ShowContinueErrorTimeStamp(
2539 : state, "The calculated cycling ratio will be used and the simulation continues. Occurrence info:");
2540 : }
2541 0 : ShowRecurringWarningErrorAtEnd(
2542 : state,
2543 0 : format(" {} \"{}\" - Iteration limit exceeded calculating low speed cycling ratio "
2544 : "error continues. Sensible PLR statistics follow.",
2545 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2546 0 : cBVAV.DXCoolCoilName),
2547 0 : cBVAV.DXCyclingIterationExceededIndex,
2548 : LocalPartLoadFrac,
2549 : LocalPartLoadFrac);
2550 : }
2551 0 : } else if (SolFla == -2) {
2552 :
2553 0 : if (!state.dataGlobal->WarmupFlag) {
2554 0 : if (cBVAV.DXCyclingIterationFailed < 4) {
2555 0 : ++cBVAV.DXCyclingIterationFailed;
2556 0 : ShowWarningError(
2557 : state,
2558 0 : format("{} - DX unit low speed cycling ratio calculation failed: limits exceeded, for unit = {}",
2559 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2560 0 : cBVAV.Name));
2561 0 : ShowContinueError(state,
2562 0 : format("Estimated low speed cycling ratio = {:.3R}", TempSpeedReqst / TempSpeedOut));
2563 0 : ShowContinueErrorTimeStamp(state,
2564 : "The estimated low speed cycling ratio will be used and the simulation "
2565 : "continues. Occurrence info:");
2566 : }
2567 0 : ShowRecurringWarningErrorAtEnd(state,
2568 0 : format("{} \"{}\" - DX unit low speed cycling ratio calculation failed error "
2569 : "continues. cycling ratio statistics follow.",
2570 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2571 0 : cBVAV.DXCoolCoilName),
2572 0 : cBVAV.DXCyclingIterationFailedIndex,
2573 : LocalPartLoadFrac,
2574 : LocalPartLoadFrac);
2575 : }
2576 0 : LocalPartLoadFrac = TempSpeedReqst / TempSpeedOut;
2577 : }
2578 : }
2579 : }
2580 : }
2581 :
2582 0 : if (LocalPartLoadFrac > 1.0) {
2583 0 : LocalPartLoadFrac = 1.0;
2584 0 : } else if (LocalPartLoadFrac < 0.0) {
2585 0 : LocalPartLoadFrac = 0.0;
2586 : }
2587 0 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = VariableSpeedCoils::getVarSpeedPartLoadRatio(state, cBVAV.CoolCoilCompIndex);
2588 : // variable-speed air-to-air cooling coil, end -------------------------
2589 0 : } break;
2590 0 : case HVAC::CoilType::DXCoolingTwoStageWHumControl: {
2591 : // Coil:Cooling:DX:TwoStageWithHumidityControlMode
2592 : // formerly (v3 and beyond) Coil:DX:MultiMode:CoolingEmpirical
2593 :
2594 : // If DXCoolingSystem runs with a cooling load then set PartLoadFrac on Cooling System and the Mass Flow
2595 : // Multimode coil will switch to enhanced dehumidification if available and needed, but it
2596 : // still runs to meet the sensible load
2597 :
2598 : // Determine required part load for normal mode
2599 :
2600 : // Get full load result
2601 0 : HVAC::CoilMode DehumidMode = HVAC::CoilMode::Normal; // Dehumidification mode (0=normal, 1=enhanced)
2602 0 : cBVAV.DehumidificationMode = DehumidMode;
2603 0 : DXCoils::SimDXCoilMultiMode(state,
2604 : cBVAV.DXCoolCoilName,
2605 : HVAC::CompressorOp::On,
2606 : FirstHVACIteration,
2607 : PartLoadFrac,
2608 : DehumidMode,
2609 0 : cBVAV.CoolCoilCompIndex,
2610 : HVAC::FanOp::Continuous);
2611 0 : if (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp <= cBVAV.CoilTempSetPoint) {
2612 0 : PartLoadFrac = 0.0;
2613 0 : DXCoils::SimDXCoilMultiMode(state,
2614 : cBVAV.DXCoolCoilName,
2615 : HVAC::CompressorOp::On,
2616 : FirstHVACIteration,
2617 : PartLoadFrac,
2618 : DehumidMode,
2619 0 : cBVAV.CoolCoilCompIndex,
2620 : HVAC::FanOp::Continuous);
2621 0 : } else if (state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp > cBVAV.CoilTempSetPoint) {
2622 0 : PartLoadFrac = 1.0;
2623 : } else {
2624 0 : auto f = [&state, CBVAVNum, DehumidMode](Real64 const PartLoadRatio) {
2625 0 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2626 0 : DXCoils::SimDXCoilMultiMode(state,
2627 : "",
2628 : HVAC::CompressorOp::On,
2629 : false,
2630 : PartLoadRatio,
2631 : DehumidMode,
2632 0 : thisCBVAV.CoolCoilCompIndex,
2633 : HVAC::FanOp::Continuous);
2634 0 : return thisCBVAV.CoilTempSetPoint - state.dataDXCoils->DXCoilOutletTemp(thisCBVAV.CoolCoilCompIndex);
2635 0 : };
2636 0 : General::SolveRoot(state, HVAC::SmallTempDiff, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
2637 0 : if (SolFla == -1) {
2638 0 : if (cBVAV.MMDXIterationExceeded < 1) {
2639 0 : ++cBVAV.MMDXIterationExceeded;
2640 0 : ShowWarningError(state,
2641 0 : format("Iteration limit exceeded calculating DX unit part-load ratio, for unit={}", cBVAV.Name));
2642 0 : ShowContinueErrorTimeStamp(state, format("Part-load ratio returned = {:.2R}", PartLoadFrac));
2643 0 : ShowContinueErrorTimeStamp(
2644 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
2645 : } else {
2646 0 : ShowRecurringWarningErrorAtEnd(state,
2647 0 : cBVAV.Name +
2648 : ", Iteration limit exceeded calculating DX unit part-load ratio error continues.",
2649 0 : cBVAV.MMDXIterationExceededIndex,
2650 : PartLoadFrac,
2651 : PartLoadFrac);
2652 : }
2653 0 : } else if (SolFla == -2) {
2654 0 : PartLoadFrac = max(0.0,
2655 : min(1.0,
2656 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp - cBVAV.CoilTempSetPoint) /
2657 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp -
2658 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp)));
2659 0 : if (cBVAV.MMDXIterationFailed < 1) {
2660 0 : ++cBVAV.MMDXIterationFailed;
2661 0 : ShowSevereError(
2662 : state,
2663 0 : format("DX unit part-load ratio calculation failed: part-load ratio limits exceeded, for unit={}", cBVAV.Name));
2664 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
2665 0 : ShowContinueErrorTimeStamp(
2666 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
2667 : } else {
2668 0 : ShowRecurringWarningErrorAtEnd(state,
2669 0 : cBVAV.Name + ", Part-load ratio calculation failed for DX unit error continues.",
2670 0 : cBVAV.MMDXIterationFailedIndex,
2671 : PartLoadFrac,
2672 : PartLoadFrac);
2673 : }
2674 : }
2675 : }
2676 :
2677 : // If humidity setpoint is not satisfied and humidity control type is Multimode,
2678 : // then turn on enhanced dehumidification mode 1
2679 :
2680 0 : if ((state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat > state.dataLoopNodes->Node(OutletNode).HumRatMax) &&
2681 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).HumRat > state.dataLoopNodes->Node(OutletNode).HumRatMax) &&
2682 0 : (cBVAV.DehumidControlType == DehumidControl::Multimode) && state.dataLoopNodes->Node(OutletNode).HumRatMax > 0.0) {
2683 :
2684 : // Determine required part load for enhanced dehumidification mode 1
2685 :
2686 : // Get full load result
2687 0 : PartLoadFrac = 1.0;
2688 0 : DehumidMode = HVAC::CoilMode::Enhanced;
2689 0 : cBVAV.DehumidificationMode = DehumidMode;
2690 0 : DXCoils::SimDXCoilMultiMode(state,
2691 : cBVAV.DXCoolCoilName,
2692 : HVAC::CompressorOp::On,
2693 : FirstHVACIteration,
2694 : PartLoadFrac,
2695 : DehumidMode,
2696 0 : cBVAV.CoolCoilCompIndex,
2697 : HVAC::FanOp::Continuous);
2698 0 : if (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp <= cBVAV.CoilTempSetPoint) {
2699 0 : PartLoadFrac = 0.0;
2700 0 : } else if (state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp > cBVAV.CoilTempSetPoint) {
2701 0 : PartLoadFrac = 1.0;
2702 : } else {
2703 0 : auto f = [&state, CBVAVNum, DehumidMode](Real64 const PartLoadRatio) {
2704 0 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2705 0 : DXCoils::SimDXCoilMultiMode(state,
2706 : "",
2707 : HVAC::CompressorOp::On,
2708 : false,
2709 : PartLoadRatio,
2710 : DehumidMode,
2711 0 : thisCBVAV.CoolCoilCompIndex,
2712 : HVAC::FanOp::Continuous);
2713 0 : return thisCBVAV.CoilTempSetPoint - state.dataDXCoils->DXCoilOutletTemp(thisCBVAV.CoolCoilCompIndex);
2714 0 : };
2715 0 : General::SolveRoot(state, HVAC::SmallTempDiff, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
2716 0 : if (SolFla == -1) {
2717 0 : if (cBVAV.DMDXIterationExceeded < 1) {
2718 0 : ++cBVAV.DMDXIterationExceeded;
2719 0 : ShowWarningError(
2720 : state,
2721 0 : format("Iteration limit exceeded calculating DX unit dehumidifying part-load ratio, for unit = {}",
2722 0 : cBVAV.Name));
2723 0 : ShowContinueErrorTimeStamp(state, format("Part-load ratio returned={:.2R}", PartLoadFrac));
2724 0 : ShowContinueErrorTimeStamp(
2725 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
2726 : } else {
2727 0 : ShowRecurringWarningErrorAtEnd(
2728 : state,
2729 0 : cBVAV.Name + ", Iteration limit exceeded calculating DX unit dehumidifying part-load ratio error continues.",
2730 0 : cBVAV.DMDXIterationExceededIndex,
2731 : PartLoadFrac,
2732 : PartLoadFrac);
2733 : }
2734 0 : } else if (SolFla == -2) {
2735 0 : PartLoadFrac = max(0.0,
2736 : min(1.0,
2737 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp - cBVAV.CoilTempSetPoint) /
2738 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp -
2739 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp)));
2740 0 : if (cBVAV.DMDXIterationFailed < 1) {
2741 0 : ++cBVAV.DMDXIterationFailed;
2742 0 : ShowSevereError(state,
2743 0 : format("DX unit dehumidifying part-load ratio calculation failed: part-load ratio limits "
2744 : "exceeded, for unit = {}",
2745 0 : cBVAV.Name));
2746 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
2747 0 : ShowContinueErrorTimeStamp(
2748 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
2749 : } else {
2750 0 : ShowRecurringWarningErrorAtEnd(
2751 : state,
2752 0 : cBVAV.Name + ", Dehumidifying part-load ratio calculation failed for DX unit error continues.",
2753 0 : cBVAV.DMDXIterationFailedIndex,
2754 : PartLoadFrac,
2755 : PartLoadFrac);
2756 : }
2757 : }
2758 : }
2759 : } // End if humidity ratio setpoint not met - multimode humidity control
2760 :
2761 : // If humidity setpoint is not satisfied and humidity control type is CoolReheat,
2762 : // then run to meet latent load
2763 :
2764 0 : if ((state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat > state.dataLoopNodes->Node(OutletNode).HumRatMax) &&
2765 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).HumRat > state.dataLoopNodes->Node(OutletNode).HumRatMax) &&
2766 0 : (cBVAV.DehumidControlType == DehumidControl::CoolReheat) && state.dataLoopNodes->Node(OutletNode).HumRatMax > 0.0) {
2767 :
2768 : // Determine revised desired outlet temperature - use approach temperature control strategy
2769 : // based on CONTROLLER:SIMPLE TEMPANDHUMRAT control type.
2770 :
2771 : // Calculate the approach temperature (difference between SA dry-bulb temp and SA dew point temp)
2772 0 : ApproachTemp = state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp -
2773 0 : Psychrometrics::PsyTdpFnWPb(state, state.dataLoopNodes->Node(OutletNode).HumRat, OutdoorBaroPress);
2774 : // Calculate the dew point temperature at the SA humidity ratio setpoint
2775 0 : DesiredDewPoint = Psychrometrics::PsyTdpFnWPb(state, state.dataLoopNodes->Node(OutletNode).HumRatMax, OutdoorBaroPress);
2776 : // Adjust the calculated dew point temperature by the approach temp
2777 0 : cBVAV.CoilTempSetPoint = min(cBVAV.CoilTempSetPoint, (DesiredDewPoint + ApproachTemp));
2778 :
2779 : // Determine required part load for cool reheat at adjusted DesiredOutletTemp
2780 :
2781 : // Get full load result
2782 0 : PartLoadFrac = 1.0;
2783 0 : DehumidMode = HVAC::CoilMode::Normal;
2784 0 : cBVAV.DehumidificationMode = DehumidMode;
2785 0 : DXCoils::SimDXCoilMultiMode(state,
2786 : cBVAV.DXCoolCoilName,
2787 : HVAC::CompressorOp::On,
2788 : FirstHVACIteration,
2789 : PartLoadFrac,
2790 : DehumidMode,
2791 0 : cBVAV.CoolCoilCompIndex,
2792 : HVAC::FanOp::Continuous);
2793 0 : if (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp <= cBVAV.CoilTempSetPoint) {
2794 0 : PartLoadFrac = 0.0;
2795 0 : } else if (state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp > cBVAV.CoilTempSetPoint) {
2796 0 : PartLoadFrac = 1.0;
2797 : } else {
2798 0 : auto f = [&state, CBVAVNum, DehumidMode](Real64 const PartLoadRatio) {
2799 0 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2800 0 : DXCoils::SimDXCoilMultiMode(state,
2801 : "",
2802 : HVAC::CompressorOp::On,
2803 : false,
2804 : PartLoadRatio,
2805 : DehumidMode,
2806 0 : thisCBVAV.CoolCoilCompIndex,
2807 : HVAC::FanOp::Continuous);
2808 0 : return thisCBVAV.CoilTempSetPoint - state.dataDXCoils->DXCoilOutletTemp(thisCBVAV.CoolCoilCompIndex);
2809 0 : };
2810 0 : General::SolveRoot(state, HVAC::SmallTempDiff, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
2811 0 : if (SolFla == -1) {
2812 0 : if (cBVAV.CRDXIterationExceeded < 1) {
2813 0 : ++cBVAV.CRDXIterationExceeded;
2814 0 : ShowWarningError(state,
2815 0 : format("Iteration limit exceeded calculating DX unit cool reheat part-load ratio, for unit = {}",
2816 0 : cBVAV.Name));
2817 0 : ShowContinueErrorTimeStamp(state, format("Part-load ratio returned = {:.2R}", PartLoadFrac));
2818 0 : ShowContinueErrorTimeStamp(
2819 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
2820 : } else {
2821 0 : ShowRecurringWarningErrorAtEnd(
2822 : state,
2823 0 : cBVAV.Name + ", Iteration limit exceeded calculating cool reheat part-load ratio DX unit error continues.",
2824 0 : cBVAV.CRDXIterationExceededIndex,
2825 : PartLoadFrac,
2826 : PartLoadFrac);
2827 : }
2828 0 : } else if (SolFla == -2) {
2829 0 : PartLoadFrac = max(0.0,
2830 : min(1.0,
2831 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp - cBVAV.CoilTempSetPoint) /
2832 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp -
2833 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp)));
2834 0 : if (cBVAV.CRDXIterationFailed < 1) {
2835 0 : ++cBVAV.CRDXIterationFailed;
2836 0 : ShowSevereError(
2837 : state,
2838 0 : format(
2839 : "DX unit cool reheat part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
2840 0 : cBVAV.Name));
2841 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
2842 0 : ShowContinueErrorTimeStamp(
2843 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
2844 : } else {
2845 0 : ShowRecurringWarningErrorAtEnd(
2846 : state,
2847 0 : cBVAV.Name + ", Dehumidifying part-load ratio calculation failed for DX unit error continues.",
2848 0 : cBVAV.DMDXIterationFailedIndex,
2849 : PartLoadFrac,
2850 : PartLoadFrac);
2851 : }
2852 : }
2853 : }
2854 : } // End if humidity ratio setpoint not met - CoolReheat humidity control
2855 :
2856 0 : if (PartLoadFrac > 1.0) {
2857 0 : PartLoadFrac = 1.0;
2858 0 : } else if (PartLoadFrac < 0.0) {
2859 0 : PartLoadFrac = 0.0;
2860 : }
2861 0 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(cBVAV.DXCoolCoilIndexNum);
2862 0 : } break;
2863 0 : default: {
2864 0 : ShowFatalError(
2865 0 : state, format("SimCBVAV System: Invalid DX Cooling Coil={}", HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)]));
2866 0 : } break;
2867 : }
2868 : } else { // IF(OutdoorDryBulbTemp .GE. cBVAV%MinOATCompressor)THEN
2869 : // Simulate DX cooling coil with compressor off
2870 0 : if (cBVAV.CoolCoilType == HVAC::CoilType::DXCoolingHXAssisted) {
2871 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
2872 : cBVAV.DXCoolCoilName,
2873 : FirstHVACIteration,
2874 : HVAC::CompressorOp::Off,
2875 : 0.0,
2876 0 : cBVAV.CoolCoilCompIndex,
2877 : HVAC::FanOp::Continuous,
2878 : HXUnitOn);
2879 0 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(cBVAV.DXCoolCoilIndexNum);
2880 0 : } else if (cBVAV.CoolCoilType == HVAC::CoilType::DXCoolingSingleSpeed) {
2881 0 : DXCoils::SimDXCoil(state,
2882 : cBVAV.DXCoolCoilName,
2883 : HVAC::CompressorOp::Off,
2884 : FirstHVACIteration,
2885 0 : cBVAV.CoolCoilCompIndex,
2886 : HVAC::FanOp::Continuous,
2887 0 : 0.0,
2888 : OnOffAirFlowRatio);
2889 0 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(cBVAV.DXCoolCoilIndexNum);
2890 0 : } else if (cBVAV.CoolCoilType == HVAC::CoilType::DXCoolingTwoStageWHumControl) {
2891 0 : DXCoils::SimDXCoilMultiMode(state,
2892 : cBVAV.DXCoolCoilName,
2893 : HVAC::CompressorOp::Off,
2894 : FirstHVACIteration,
2895 : 0.0,
2896 : HVAC::CoilMode::Normal,
2897 0 : cBVAV.CoolCoilCompIndex,
2898 : HVAC::FanOp::Continuous);
2899 0 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(cBVAV.DXCoolCoilIndexNum);
2900 0 : } else if (cBVAV.CoolCoilType == HVAC::CoilType::CoolingAirToAirVariableSpeed) {
2901 : // Real64 PartLoadFrac(0.0);
2902 0 : Real64 LocalPartLoadFrac = 0.0;
2903 0 : Real64 QZnReq = 0.0; // Zone load (W), input to variable-speed DX coil
2904 0 : Real64 QLatReq = 0.0; // Zone latent load, input to variable-speed DX coil
2905 0 : Real64 SpeedRatio = 0.0;
2906 0 : int SpeedNum = 1;
2907 : // Get no load result
2908 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2909 : cBVAV.DXCoolCoilName,
2910 0 : cBVAV.CoolCoilCompIndex,
2911 : HVAC::FanOp::Continuous,
2912 : HVAC::CompressorOp::Off,
2913 : LocalPartLoadFrac,
2914 : SpeedNum,
2915 : SpeedRatio,
2916 : QZnReq,
2917 : QLatReq);
2918 0 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = VariableSpeedCoils::getVarSpeedPartLoadRatio(state, cBVAV.CoolCoilCompIndex);
2919 : }
2920 : }
2921 :
2922 : // Simulate cooling coil with compressor off if zone requires heating
2923 : } else { // HeatCoolMode == HeatingMode and no cooling is required, set PLR to 0
2924 14 : if (cBVAV.CoolCoilType == HVAC::CoilType::DXCoolingHXAssisted) {
2925 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
2926 : cBVAV.DXCoolCoilName,
2927 : FirstHVACIteration,
2928 : HVAC::CompressorOp::Off,
2929 : 0.0,
2930 0 : cBVAV.CoolCoilCompIndex,
2931 : HVAC::FanOp::Continuous,
2932 : HXUnitOn);
2933 14 : } else if (cBVAV.CoolCoilType == HVAC::CoilType::DXCoolingSingleSpeed) {
2934 36 : DXCoils::SimDXCoil(state,
2935 : cBVAV.DXCoolCoilName,
2936 : HVAC::CompressorOp::Off,
2937 : FirstHVACIteration,
2938 12 : cBVAV.CoolCoilCompIndex,
2939 : HVAC::FanOp::Continuous,
2940 24 : 0.0,
2941 : OnOffAirFlowRatio);
2942 2 : } else if (cBVAV.CoolCoilType == HVAC::CoilType::CoolingAirToAirVariableSpeed) {
2943 2 : Real64 QZnReq = 0.0; // Zone load (W), input to variable-speed DX coil
2944 2 : Real64 QLatReq = 0.0; // Zone latent load, input to variable-speed DX coil
2945 2 : Real64 LocalPartLoadFrac = 0.0;
2946 2 : Real64 SpeedRatio = 0.0;
2947 2 : int SpeedNum = 1;
2948 : // run model with no load
2949 2 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2950 : cBVAV.DXCoolCoilName,
2951 2 : cBVAV.CoolCoilCompIndex,
2952 : HVAC::FanOp::Continuous,
2953 : HVAC::CompressorOp::Off,
2954 : LocalPartLoadFrac,
2955 : SpeedNum,
2956 : SpeedRatio,
2957 : QZnReq,
2958 : QLatReq);
2959 :
2960 0 : } else if (cBVAV.CoolCoilType == HVAC::CoilType::DXCoolingTwoStageWHumControl) {
2961 0 : DXCoils::SimDXCoilMultiMode(state,
2962 : cBVAV.DXCoolCoilName,
2963 : HVAC::CompressorOp::Off,
2964 : FirstHVACIteration,
2965 : 0.0,
2966 : HVAC::CoilMode::Normal,
2967 0 : cBVAV.CoolCoilCompIndex,
2968 : HVAC::FanOp::Continuous);
2969 : }
2970 : }
2971 :
2972 : // Simulate the heating coil based on coil type
2973 30 : switch (cBVAV.HeatCoilType) {
2974 0 : case HVAC::CoilType::DXHeatingEmpirical: {
2975 : // Simulate DX heating coil if zone load is positive (heating load)
2976 0 : if (cBVAV.HeatCoolMode == HeatingMode) {
2977 0 : if (OutdoorDryBulbTemp > cBVAV.MinOATCompressor) {
2978 : // simulate the DX heating coil
2979 : // vs coil issue
2980 :
2981 0 : DXCoils::SimDXCoil(state,
2982 : cBVAV.HeatCoilName,
2983 : HVAC::CompressorOp::On,
2984 : FirstHVACIteration,
2985 0 : cBVAV.HeatCoilIndex,
2986 : HVAC::FanOp::Continuous,
2987 : PartLoadFrac,
2988 : OnOffAirFlowRatio);
2989 0 : if (state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).Temp > cBVAV.CoilTempSetPoint &&
2990 0 : state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).Temp < cBVAV.CoilTempSetPoint) {
2991 : // iterate to find PLR at CoilTempSetPoint
2992 0 : auto f = [&state, CBVAVNum, OnOffAirFlowRatio](Real64 const PartLoadFrac) {
2993 0 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2994 0 : DXCoils::CalcDXHeatingCoil(state, thisCBVAV.HeatCoilIndex, PartLoadFrac, HVAC::FanOp::Continuous, OnOffAirFlowRatio);
2995 0 : Real64 OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(thisCBVAV.HeatCoilIndex);
2996 0 : Real64 par2 = min(thisCBVAV.CoilTempSetPoint, thisCBVAV.MaxLATHeating);
2997 0 : return par2 - OutletAirTemp;
2998 0 : };
2999 0 : General::SolveRoot(state, HVAC::SmallTempDiff, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
3000 0 : DXCoils::SimDXCoil(state,
3001 : cBVAV.HeatCoilName,
3002 : HVAC::CompressorOp::On,
3003 : FirstHVACIteration,
3004 0 : cBVAV.HeatCoilIndex,
3005 : HVAC::FanOp::Continuous,
3006 : PartLoadFrac,
3007 : OnOffAirFlowRatio);
3008 0 : if (SolFla == -1 && !state.dataGlobal->WarmupFlag) {
3009 0 : ShowWarningError(
3010 0 : state, format("Iteration limit exceeded calculating DX unit part-load ratio, for unit = {}", cBVAV.HeatCoilName));
3011 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
3012 0 : ShowContinueErrorTimeStamp(state,
3013 : "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
3014 0 : } else if (SolFla == -2 && !state.dataGlobal->WarmupFlag) {
3015 0 : ShowSevereError(state,
3016 0 : format("DX unit part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
3017 0 : cBVAV.HeatCoilName));
3018 0 : ShowContinueErrorTimeStamp(
3019 : state,
3020 0 : format("A part-load ratio of {:.3R}will be used and the simulation continues. Occurrence info:", PartLoadFrac));
3021 0 : ShowContinueError(state, "Please send this information to the EnergyPlus support group.");
3022 : }
3023 : }
3024 : } else { // OAT .LT. MinOATCompressor
3025 : // simulate DX heating coil with compressor off
3026 0 : DXCoils::SimDXCoil(state,
3027 : cBVAV.HeatCoilName,
3028 : HVAC::CompressorOp::Off,
3029 : FirstHVACIteration,
3030 0 : cBVAV.HeatCoilIndex,
3031 : HVAC::FanOp::Continuous,
3032 0 : 0.0,
3033 : OnOffAirFlowRatio);
3034 : }
3035 0 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(cBVAV.DXHeatCoilIndexNum);
3036 : } else { // HeatCoolMode = CoolingMode
3037 : // simulate DX heating coil with compressor off when cooling load is required
3038 0 : DXCoils::SimDXCoil(state,
3039 : cBVAV.HeatCoilName,
3040 : HVAC::CompressorOp::Off,
3041 : FirstHVACIteration,
3042 0 : cBVAV.HeatCoilIndex,
3043 : HVAC::FanOp::Continuous,
3044 0 : 0.0,
3045 : OnOffAirFlowRatio);
3046 : }
3047 0 : } break;
3048 2 : case HVAC::CoilType::HeatingAirToAirVariableSpeed: {
3049 2 : Real64 QZnReq = 0.0; // Zone load (W), input to variable-speed DX coil
3050 2 : Real64 QLatReq = 0.0; // Zone latent load, input to variable-speed DX coil
3051 2 : Real64 LocalOnOffAirFlowRatio = 1.0; // ratio of compressor on flow to average flow over time step
3052 2 : Real64 LocalPartLoadFrac = 0.0;
3053 2 : Real64 SpeedRatio = 0.0;
3054 2 : int SpeedNum = 1;
3055 2 : bool errorFlag = false;
3056 2 : int maxNumSpeeds = VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, cBVAV.HeatCoilName, errorFlag);
3057 2 : Real64 DesOutTemp = cBVAV.CoilTempSetPoint;
3058 : // Get no load result
3059 2 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3060 : cBVAV.HeatCoilName,
3061 2 : cBVAV.DXHeatCoilIndexNum,
3062 : HVAC::FanOp::Continuous,
3063 : HVAC::CompressorOp::Off,
3064 : LocalPartLoadFrac,
3065 : SpeedNum,
3066 : SpeedRatio,
3067 : QZnReq,
3068 : QLatReq);
3069 :
3070 2 : Real64 NoOutput = state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).MassFlowRate *
3071 2 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).Temp,
3072 2 : state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).HumRat) -
3073 2 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).Temp,
3074 2 : state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).HumRat));
3075 2 : Real64 TempNoOutput = state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).Temp;
3076 : // Real64 NoLoadHumRatOut = VariableSpeedCoils::VarSpeedCoil( CBVAV( CBVAVNum ).CoolCoilCompIndex ).OutletAirHumRat;
3077 :
3078 : // Get full load result
3079 2 : LocalPartLoadFrac = 1.0;
3080 2 : SpeedNum = maxNumSpeeds;
3081 2 : SpeedRatio = 1.0;
3082 2 : QZnReq = 0.001; // to indicate the coil is running
3083 2 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3084 : cBVAV.HeatCoilName,
3085 2 : cBVAV.DXHeatCoilIndexNum,
3086 : HVAC::FanOp::Continuous,
3087 : HVAC::CompressorOp::On,
3088 : LocalPartLoadFrac,
3089 : SpeedNum,
3090 : SpeedRatio,
3091 : QZnReq,
3092 : QLatReq);
3093 :
3094 : // Real64 FullLoadHumRatOut = VariableSpeedCoils::VarSpeedCoil( CBVAV( CBVAVNum ).CoolCoilCompIndex ).OutletAirHumRat;
3095 2 : Real64 FullOutput = state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).MassFlowRate *
3096 2 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).Temp,
3097 2 : state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).HumRat) -
3098 2 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).Temp,
3099 2 : state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).HumRat));
3100 2 : Real64 ReqOutput = state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).MassFlowRate *
3101 2 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).HumRat) -
3102 2 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).Temp,
3103 2 : state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).HumRat));
3104 :
3105 2 : Real64 loadAccuracy = 0.001; // Watts, power
3106 2 : Real64 tempAccuracy = 0.001; // delta C, temperature
3107 2 : if ((NoOutput - ReqOutput) > -loadAccuracy) { // IF NoOutput is higher than (more heating than required) or very near the
3108 : // ReqOutput, do not run the compressor
3109 1 : LocalPartLoadFrac = 0.0;
3110 1 : SpeedNum = 1;
3111 1 : SpeedRatio = 0.0;
3112 1 : QZnReq = 0.0;
3113 : // call again with coil off
3114 1 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3115 : cBVAV.HeatCoilName,
3116 1 : cBVAV.DXHeatCoilIndexNum,
3117 : HVAC::FanOp::Continuous,
3118 : HVAC::CompressorOp::Off,
3119 : LocalPartLoadFrac,
3120 : SpeedNum,
3121 : SpeedRatio,
3122 : QZnReq,
3123 : QLatReq);
3124 :
3125 1 : } else if ((FullOutput - ReqOutput) < loadAccuracy) { // If the FullOutput is less than (insufficient cooling) or very near
3126 : // the ReqOutput, run the compressor at LocalPartLoadFrac = 1.
3127 : // which we just did so nothing to be done
3128 :
3129 : } else { // Else find how the coil is modulating (speed level and speed ratio or part load between off and speed 1) to meet the load
3130 : // OutletTempDXCoil is the full capacity outlet temperature at LocalPartLoadFrac = 1 from the CALL above. If this temp is
3131 : // greater than the desired outlet temp, then run the compressor at LocalPartLoadFrac = 1, otherwise find the operating PLR.
3132 1 : Real64 OutletTempDXCoil = state.dataVariableSpeedCoils->VarSpeedCoil(cBVAV.DXHeatCoilIndexNum).OutletAirDBTemp;
3133 1 : if (OutletTempDXCoil < DesOutTemp) {
3134 0 : LocalPartLoadFrac = 1.0;
3135 0 : SpeedNum = maxNumSpeeds;
3136 0 : SpeedRatio = 1.0;
3137 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3138 : cBVAV.HeatCoilName,
3139 0 : cBVAV.DXHeatCoilIndexNum,
3140 : HVAC::FanOp::Continuous,
3141 : HVAC::CompressorOp::On,
3142 : LocalPartLoadFrac,
3143 : SpeedNum,
3144 : SpeedRatio,
3145 : QZnReq,
3146 : QLatReq,
3147 : LocalOnOffAirFlowRatio);
3148 : } else {
3149 : // run at lowest speed
3150 1 : LocalPartLoadFrac = 1.0;
3151 1 : SpeedNum = 1;
3152 1 : SpeedRatio = 1.0;
3153 1 : QZnReq = 0.001; // to indicate the coil is running
3154 1 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3155 : cBVAV.HeatCoilName,
3156 1 : cBVAV.DXHeatCoilIndexNum,
3157 : HVAC::FanOp::Continuous,
3158 : HVAC::CompressorOp::On,
3159 : LocalPartLoadFrac,
3160 : SpeedNum,
3161 : SpeedRatio,
3162 : QZnReq,
3163 : QLatReq,
3164 : LocalOnOffAirFlowRatio);
3165 :
3166 1 : Real64 TempSpeedOut = state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).Temp;
3167 1 : Real64 TempSpeedOutSpeed1 = TempSpeedOut;
3168 :
3169 1 : if ((TempSpeedOut - DesOutTemp) < tempAccuracy) {
3170 : // Check to see which speed to meet the load
3171 0 : LocalPartLoadFrac = 1.0;
3172 0 : SpeedRatio = 1.0;
3173 0 : for (int I = 2; I <= maxNumSpeeds; ++I) {
3174 0 : SpeedNum = I;
3175 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3176 : cBVAV.HeatCoilName,
3177 0 : cBVAV.DXHeatCoilIndexNum,
3178 : HVAC::FanOp::Continuous,
3179 : HVAC::CompressorOp::On,
3180 : LocalPartLoadFrac,
3181 : SpeedNum,
3182 : SpeedRatio,
3183 : QZnReq,
3184 : QLatReq,
3185 : LocalOnOffAirFlowRatio);
3186 :
3187 0 : TempSpeedOut = state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).Temp;
3188 :
3189 0 : if ((TempSpeedOut - DesOutTemp) > tempAccuracy) {
3190 0 : SpeedNum = I;
3191 0 : break;
3192 : }
3193 : }
3194 : // now find the speed ratio for the found speednum
3195 0 : int const vsCoilIndex = cBVAV.DXHeatCoilIndexNum;
3196 0 : auto f = [&state, vsCoilIndex, DesOutTemp, SpeedNum](Real64 const x) {
3197 0 : return HVACDXHeatPumpSystem::VSCoilSpeedResidual(state, x, vsCoilIndex, DesOutTemp, SpeedNum, HVAC::FanOp::Continuous);
3198 0 : };
3199 0 : General::SolveRoot(state, tempAccuracy, MaxIte, SolFla, SpeedRatio, f, 1.0e-10, 1.0);
3200 :
3201 0 : if (SolFla == -1) {
3202 0 : if (!state.dataGlobal->WarmupFlag) {
3203 0 : if (cBVAV.DXHeatIterationExceeded < 4) {
3204 0 : ++cBVAV.DXHeatIterationExceeded;
3205 0 : ShowWarningError(state,
3206 0 : format("{} - Iteration limit exceeded calculating VS DX coil speed ratio for coil named {}, in "
3207 : "Unitary system named{}",
3208 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3209 0 : cBVAV.HeatCoilName,
3210 0 : cBVAV.Name));
3211 0 : ShowContinueError(state, format("Calculated speed ratio = {:.4R}", SpeedRatio));
3212 0 : ShowContinueErrorTimeStamp(
3213 : state, "The calculated speed ratio will be used and the simulation continues. Occurrence info:");
3214 : }
3215 0 : ShowRecurringWarningErrorAtEnd(state,
3216 0 : format("{} \"{}\" - Iteration limit exceeded calculating speed ratio error continues. "
3217 : "Speed Ratio statistics follow.",
3218 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3219 0 : cBVAV.HeatCoilName),
3220 0 : cBVAV.DXHeatIterationExceededIndex,
3221 : LocalPartLoadFrac,
3222 : LocalPartLoadFrac);
3223 : }
3224 0 : } else if (SolFla == -2) {
3225 :
3226 0 : if (!state.dataGlobal->WarmupFlag) {
3227 0 : if (cBVAV.DXHeatIterationFailed < 4) {
3228 0 : ++cBVAV.DXHeatIterationFailed;
3229 0 : ShowWarningError(state,
3230 0 : format("{} - DX unit speed ratio calculation failed: solver limits exceeded, for coil named {}, "
3231 : "in Unitary system named{}",
3232 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3233 0 : cBVAV.HeatCoilName,
3234 0 : cBVAV.Name));
3235 0 : ShowContinueErrorTimeStamp(state,
3236 : " Speed ratio will be set to 0.5, and the simulation continues. Occurrence info:");
3237 : }
3238 0 : ShowRecurringWarningErrorAtEnd(
3239 : state,
3240 0 : format("{} \"{}\" - DX unit speed ratio calculation failed error continues. speed ratio statistics follow.",
3241 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3242 0 : cBVAV.HeatCoilName),
3243 0 : cBVAV.DXHeatIterationFailedIndex,
3244 : SpeedRatio,
3245 : SpeedRatio);
3246 : }
3247 0 : SpeedRatio = 0.5;
3248 : }
3249 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3250 : cBVAV.HeatCoilName,
3251 0 : cBVAV.DXHeatCoilIndexNum,
3252 : HVAC::FanOp::Continuous,
3253 : HVAC::CompressorOp::On,
3254 : LocalPartLoadFrac,
3255 : SpeedNum,
3256 : SpeedRatio,
3257 : QZnReq,
3258 : QLatReq,
3259 : LocalOnOffAirFlowRatio);
3260 : } else {
3261 : // cycling compressor at lowest speed number, find part load fraction
3262 1 : int VSCoilIndex = cBVAV.DXHeatCoilIndexNum;
3263 3 : auto f = [&state, VSCoilIndex, DesOutTemp](Real64 const x) {
3264 3 : return HVACDXHeatPumpSystem::VSCoilCyclingResidual(state, x, VSCoilIndex, DesOutTemp, HVAC::FanOp::Continuous);
3265 1 : };
3266 1 : General::SolveRoot(state, tempAccuracy, MaxIte, SolFla, LocalPartLoadFrac, f, 1.0e-10, 1.0);
3267 1 : if (SolFla == -1) {
3268 0 : if (!state.dataGlobal->WarmupFlag) {
3269 0 : if (cBVAV.DXHeatCyclingIterationExceeded < 4) {
3270 0 : ++cBVAV.DXHeatCyclingIterationExceeded;
3271 0 : ShowWarningError(state,
3272 0 : format("{} - Iteration limit exceeded calculating VS DX unit low speed cycling ratio, for coil "
3273 : "named {}, in Unitary system named{}",
3274 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3275 0 : cBVAV.HeatCoilName,
3276 0 : cBVAV.Name));
3277 0 : ShowContinueError(state, format("Estimated cycling ratio = {:.3R}", (DesOutTemp / TempSpeedOut)));
3278 0 : ShowContinueError(state, format("Calculated cycling ratio = {:.3R}", LocalPartLoadFrac));
3279 0 : ShowContinueErrorTimeStamp(
3280 : state, "The calculated cycling ratio will be used and the simulation continues. Occurrence info:");
3281 : }
3282 0 : ShowRecurringWarningErrorAtEnd(state,
3283 0 : format("{} \"{}\" - Iteration limit exceeded calculating low speed cycling ratio "
3284 : "error continues. Sensible PLR statistics follow.",
3285 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3286 0 : cBVAV.HeatCoilName),
3287 0 : cBVAV.DXHeatCyclingIterationExceededIndex,
3288 : LocalPartLoadFrac,
3289 : LocalPartLoadFrac);
3290 : }
3291 1 : } else if (SolFla == -2) {
3292 :
3293 0 : if (!state.dataGlobal->WarmupFlag) {
3294 0 : if (cBVAV.DXHeatCyclingIterationFailed < 4) {
3295 0 : ++cBVAV.DXHeatCyclingIterationFailed;
3296 0 : ShowWarningError(state,
3297 0 : format("{} - DX unit low speed cycling ratio calculation failed: limits exceeded, for unit = {}",
3298 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3299 0 : cBVAV.Name));
3300 0 : ShowContinueError(state,
3301 0 : format("Estimated low speed cycling ratio = {:.3R}",
3302 0 : (DesOutTemp - TempNoOutput) / (TempSpeedOutSpeed1 - TempNoOutput)));
3303 0 : ShowContinueErrorTimeStamp(
3304 : state, "The estimated low speed cycling ratio will be used and the simulation continues. Occurrence info:");
3305 : }
3306 0 : ShowRecurringWarningErrorAtEnd(state,
3307 0 : format("{} \"{}\" - DX unit low speed cycling ratio calculation failed error "
3308 : "continues. cycling ratio statistics follow.",
3309 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3310 0 : cBVAV.HeatCoilName),
3311 0 : cBVAV.DXHeatCyclingIterationFailedIndex,
3312 : LocalPartLoadFrac,
3313 : LocalPartLoadFrac);
3314 : }
3315 0 : LocalPartLoadFrac = (DesOutTemp - TempNoOutput) / (TempSpeedOutSpeed1 - TempNoOutput);
3316 : }
3317 1 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3318 : cBVAV.HeatCoilName,
3319 1 : cBVAV.DXHeatCoilIndexNum,
3320 : HVAC::FanOp::Continuous,
3321 : HVAC::CompressorOp::On,
3322 : LocalPartLoadFrac,
3323 : SpeedNum,
3324 : SpeedRatio,
3325 : QZnReq,
3326 : QLatReq,
3327 : LocalOnOffAirFlowRatio);
3328 : }
3329 : }
3330 : }
3331 :
3332 2 : if (LocalPartLoadFrac > 1.0) {
3333 0 : LocalPartLoadFrac = 1.0;
3334 2 : } else if (LocalPartLoadFrac < 0.0) {
3335 0 : LocalPartLoadFrac = 0.0;
3336 : }
3337 2 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = VariableSpeedCoils::getVarSpeedPartLoadRatio(state, cBVAV.DXHeatCoilIndexNum);
3338 2 : } break;
3339 28 : case HVAC::CoilType::HeatingGasOrOtherFuel:
3340 : case HVAC::CoilType::HeatingElectric:
3341 : case HVAC::CoilType::HeatingWater:
3342 : case HVAC::CoilType::HeatingSteam: { // not a DX heating coil
3343 28 : if (cBVAV.HeatCoolMode == HeatingMode) {
3344 8 : CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).HumRat);
3345 8 : QHeater = state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).MassFlowRate * CpAir *
3346 8 : (cBVAV.CoilTempSetPoint - state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).Temp);
3347 : } else {
3348 20 : QHeater = 0.0;
3349 : }
3350 : // Added None DX heating coils calling point
3351 28 : state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).TempSetPoint = cBVAV.CoilTempSetPoint;
3352 28 : CalcNonDXHeatingCoils(state, CBVAVNum, FirstHVACIteration, QHeater, cBVAV.fanOp, QHeaterActual);
3353 28 : } break;
3354 0 : default: {
3355 0 : ShowFatalError(state, format("SimCBVAV System: Invalid Heating Coil={}", HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)]));
3356 0 : } break;
3357 : }
3358 :
3359 30 : if (cBVAV.fanPlace == HVAC::FanPlace::DrawThru) {
3360 0 : state.dataFans->fans(cBVAV.FanIndex)
3361 0 : ->simulate(state, FirstHVACIteration, state.dataHVACUnitaryBypassVAV->FanSpeedRatio, _, 1.0 / OnOffAirFlowRatio, _);
3362 : }
3363 30 : int splitterOutNode = cBVAV.SplitterOutletAirNode;
3364 30 : state.dataLoopNodes->Node(splitterOutNode).MassFlowRateSetPoint = state.dataLoopNodes->Node(OutletNode).MassFlowRateSetPoint;
3365 30 : state.dataLoopNodes->Node(OutletNode) = state.dataLoopNodes->Node(splitterOutNode);
3366 30 : state.dataLoopNodes->Node(OutletNode).TempSetPoint = cBVAV.OutletTempSetPoint;
3367 30 : state.dataLoopNodes->Node(OutletNode).MassFlowRate =
3368 30 : (1.0 - state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction) * state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate;
3369 : // report variable
3370 30 : cBVAV.BypassMassFlowRate =
3371 30 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction * state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate;
3372 : // initialize bypass duct connected to mixer or plenum with flow rate and conditions
3373 30 : if (cBVAV.plenumIndex > 0 || cBVAV.mixerIndex > 0) {
3374 13 : int plenumOrMixerInletNode = cBVAV.PlenumMixerInletAirNode;
3375 13 : state.dataLoopNodes->Node(plenumOrMixerInletNode) = state.dataLoopNodes->Node(splitterOutNode);
3376 13 : state.dataLoopNodes->Node(plenumOrMixerInletNode).MassFlowRate =
3377 13 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction * state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate;
3378 13 : state.dataLoopNodes->Node(plenumOrMixerInletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(plenumOrMixerInletNode).MassFlowRate;
3379 13 : state.dataAirLoop->AirLoopFlow(cBVAV.AirLoopNumber).BypassMassFlow = state.dataLoopNodes->Node(plenumOrMixerInletNode).MassFlowRate;
3380 : }
3381 :
3382 : // calculate sensible load met using delta enthalpy at a constant (minimum) humidity ratio)
3383 30 : MinHumRat = min(state.dataLoopNodes->Node(InletNode).HumRat, state.dataLoopNodes->Node(OutletNode).HumRat);
3384 30 : LoadMet =
3385 30 : state.dataLoopNodes->Node(OutletNode).MassFlowRate * (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, MinHumRat) -
3386 30 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, MinHumRat));
3387 :
3388 : // calculate OA fraction used for zone OA volume flow rate calc
3389 30 : state.dataAirLoop->AirLoopFlow(cBVAV.AirLoopNumber).OAFrac = 0.0;
3390 30 : if (state.dataLoopNodes->Node(cBVAV.AirOutNode).MassFlowRate > 0.0) {
3391 28 : state.dataAirLoop->AirLoopFlow(cBVAV.AirLoopNumber).OAFrac =
3392 28 : state.dataLoopNodes->Node(cBVAV.MixerOutsideAirNode).MassFlowRate / state.dataLoopNodes->Node(cBVAV.AirOutNode).MassFlowRate;
3393 : }
3394 30 : }
3395 :
3396 18 : void GetZoneLoads(EnergyPlusData &state,
3397 : int const CBVAVNum // Index to CBVAV unit being simulated
3398 : )
3399 : {
3400 :
3401 : // SUBROUTINE INFORMATION:
3402 : // AUTHOR Richard Raustad
3403 : // DATE WRITTEN July 2006
3404 :
3405 : // PURPOSE OF THIS SUBROUTINE:
3406 : // This subroutine is used to poll the thermostats in each zone and determine the
3407 : // mode of operation, either cooling, heating, or none.
3408 :
3409 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3410 18 : Real64 ZoneLoad = 0.0; // Total load in controlled zone [W]
3411 18 : int lastDayOfSim(0); // used during warmup to reset changeOverTimer since need to do same thing next warmup day
3412 :
3413 18 : auto &cBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
3414 :
3415 18 : int dayOfSim = state.dataGlobal->DayOfSim; // DayOfSim increments during Warmup when it actually simulates the same day
3416 18 : if (state.dataGlobal->WarmupFlag) {
3417 : // when warmupday increments then reset timer
3418 0 : if (lastDayOfSim != dayOfSim) {
3419 0 : cBVAV.changeOverTimer = -1.0; // reset to default (thisTime always > -1)
3420 : }
3421 0 : lastDayOfSim = dayOfSim;
3422 0 : dayOfSim = 1; // reset so that thisTime is <= 24 during warmup
3423 : }
3424 18 : Real64 thisTime = (dayOfSim - 1) * 24 + state.dataGlobal->HourOfDay - 1 + (state.dataGlobal->TimeStep - 1) * state.dataGlobal->TimeStepZone +
3425 18 : state.dataHVACGlobal->SysTimeElapsed;
3426 :
3427 18 : if (thisTime <= cBVAV.changeOverTimer) {
3428 5 : cBVAV.modeChanged = true;
3429 5 : return;
3430 : }
3431 :
3432 13 : Real64 QZoneReqCool = 0.0; // Total cooling load in all controlled zones [W]
3433 13 : Real64 QZoneReqHeat = 0.0; // Total heating load in all controlled zones [W]
3434 13 : cBVAV.NumZonesCooled = 0;
3435 13 : cBVAV.NumZonesHeated = 0;
3436 13 : cBVAV.HeatCoolMode = 0;
3437 :
3438 26 : for (int ZoneNum = 1; ZoneNum <= cBVAV.NumControlledZones; ++ZoneNum) {
3439 13 : int actualZoneNum = cBVAV.ControlledZoneNum(ZoneNum);
3440 13 : int coolSeqNum = cBVAV.ZoneSequenceCoolingNum(ZoneNum);
3441 13 : int heatSeqNum = cBVAV.ZoneSequenceHeatingNum(ZoneNum);
3442 13 : if (coolSeqNum > 0 && heatSeqNum > 0) {
3443 : Real64 ZoneLoadToCoolSPSequenced =
3444 13 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(actualZoneNum).SequencedOutputRequiredToCoolingSP(coolSeqNum);
3445 : Real64 ZoneLoadToHeatSPSequenced =
3446 13 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(actualZoneNum).SequencedOutputRequiredToHeatingSP(heatSeqNum);
3447 13 : if (ZoneLoadToHeatSPSequenced > 0.0 && ZoneLoadToCoolSPSequenced > 0.0) {
3448 4 : ZoneLoad = ZoneLoadToHeatSPSequenced;
3449 9 : } else if (ZoneLoadToHeatSPSequenced < 0.0 && ZoneLoadToCoolSPSequenced < 0.0) {
3450 5 : ZoneLoad = ZoneLoadToCoolSPSequenced;
3451 4 : } else if (ZoneLoadToHeatSPSequenced <= 0.0 && ZoneLoadToCoolSPSequenced >= 0.0) {
3452 4 : ZoneLoad = 0.0;
3453 : }
3454 13 : } else {
3455 0 : ZoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(actualZoneNum).RemainingOutputRequired;
3456 : }
3457 :
3458 13 : if (!state.dataZoneEnergyDemand->CurDeadBandOrSetback(actualZoneNum)) {
3459 13 : if (ZoneLoad > HVAC::SmallLoad) {
3460 4 : QZoneReqHeat += ZoneLoad;
3461 4 : ++cBVAV.NumZonesHeated;
3462 9 : } else if (ZoneLoad < -HVAC::SmallLoad) {
3463 5 : QZoneReqCool += ZoneLoad;
3464 5 : ++cBVAV.NumZonesCooled;
3465 : }
3466 : }
3467 : }
3468 :
3469 13 : switch (cBVAV.PriorityControl) {
3470 7 : case PriorityCtrlMode::CoolingPriority: {
3471 7 : if (QZoneReqCool < 0.0) {
3472 4 : cBVAV.HeatCoolMode = CoolingMode;
3473 3 : } else if (QZoneReqHeat > 0.0) {
3474 3 : cBVAV.HeatCoolMode = HeatingMode;
3475 : }
3476 7 : } break;
3477 1 : case PriorityCtrlMode::HeatingPriority: {
3478 1 : if (QZoneReqHeat > 0.0) {
3479 1 : cBVAV.HeatCoolMode = HeatingMode;
3480 0 : } else if (QZoneReqCool < 0.0) {
3481 0 : cBVAV.HeatCoolMode = CoolingMode;
3482 : }
3483 1 : } break;
3484 1 : case PriorityCtrlMode::ZonePriority: {
3485 1 : if (cBVAV.NumZonesHeated > cBVAV.NumZonesCooled) {
3486 0 : if (QZoneReqHeat > 0.0) {
3487 0 : cBVAV.HeatCoolMode = HeatingMode;
3488 0 : } else if (QZoneReqCool < 0.0) {
3489 0 : cBVAV.HeatCoolMode = CoolingMode;
3490 : }
3491 1 : } else if (cBVAV.NumZonesCooled > cBVAV.NumZonesHeated) {
3492 1 : if (QZoneReqCool < 0.0) {
3493 1 : cBVAV.HeatCoolMode = CoolingMode;
3494 0 : } else if (QZoneReqHeat > 0.0) {
3495 0 : cBVAV.HeatCoolMode = HeatingMode;
3496 : }
3497 : } else {
3498 0 : if (std::abs(QZoneReqCool) > std::abs(QZoneReqHeat) && QZoneReqCool != 0.0) {
3499 0 : cBVAV.HeatCoolMode = CoolingMode;
3500 0 : } else if (std::abs(QZoneReqCool) < std::abs(QZoneReqHeat) && QZoneReqHeat != 0.0) {
3501 0 : cBVAV.HeatCoolMode = HeatingMode;
3502 0 : } else if (std::abs(QZoneReqCool) == std::abs(QZoneReqHeat) && QZoneReqCool != 0.0) {
3503 0 : cBVAV.HeatCoolMode = CoolingMode;
3504 : }
3505 : }
3506 1 : } break;
3507 0 : case PriorityCtrlMode::LoadPriority: {
3508 0 : if (std::abs(QZoneReqCool) > std::abs(QZoneReqHeat) && QZoneReqCool != 0.0) {
3509 0 : cBVAV.HeatCoolMode = CoolingMode;
3510 0 : } else if (std::abs(QZoneReqCool) < std::abs(QZoneReqHeat) && QZoneReqHeat != 0.0) {
3511 0 : cBVAV.HeatCoolMode = HeatingMode;
3512 0 : } else if (cBVAV.NumZonesHeated > cBVAV.NumZonesCooled) {
3513 0 : if (QZoneReqHeat > 0.0) {
3514 0 : cBVAV.HeatCoolMode = HeatingMode;
3515 0 : } else if (QZoneReqCool < 0.0) {
3516 0 : cBVAV.HeatCoolMode = CoolingMode;
3517 : }
3518 0 : } else if (cBVAV.NumZonesHeated < cBVAV.NumZonesCooled) {
3519 0 : if (QZoneReqCool < 0.0) {
3520 0 : cBVAV.HeatCoolMode = CoolingMode;
3521 0 : } else if (QZoneReqHeat > 0.0) {
3522 0 : cBVAV.HeatCoolMode = HeatingMode;
3523 : }
3524 : } else {
3525 0 : if (QZoneReqCool < 0.0) {
3526 0 : cBVAV.HeatCoolMode = CoolingMode;
3527 0 : } else if (QZoneReqHeat > 0.0) {
3528 0 : cBVAV.HeatCoolMode = HeatingMode;
3529 : }
3530 : }
3531 0 : break;
3532 4 : default:
3533 4 : break;
3534 : }
3535 : }
3536 :
3537 13 : if (cBVAV.LastMode != cBVAV.HeatCoolMode) {
3538 7 : cBVAV.changeOverTimer = thisTime + cBVAV.minModeChangeTime;
3539 7 : cBVAV.LastMode = cBVAV.HeatCoolMode;
3540 7 : cBVAV.modeChanged = true;
3541 : }
3542 : }
3543 :
3544 14 : Real64 CalcSetPointTempTarget(EnergyPlusData &state, int const CBVAVNumber) // Index to changeover-bypass VAV system
3545 : {
3546 :
3547 : // FUNCTION INFORMATION:
3548 : // AUTHOR Richard Raustad
3549 : // DATE WRITTEN August 2006
3550 :
3551 : // PURPOSE OF THIS FUNCTION:
3552 : // Calculate outlet air node temperature setpoint
3553 :
3554 : // METHODOLOGY EMPLOYED:
3555 : // Calculate an outlet temperature to satisfy zone loads. This temperature is calculated
3556 : // based on 1 zone's VAV box fully opened. The other VAV boxes are partially open (modulated).
3557 :
3558 : // Return value
3559 : Real64 CalcSetPointTempTarget;
3560 :
3561 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3562 : Real64 ZoneLoad; // Zone load sensed by thermostat [W]
3563 : Real64 QToCoolSetPt; // Zone load to cooling setpoint [W]
3564 : Real64 QToHeatSetPt; // Zone load to heating setpoint [W]
3565 : Real64 SupplyAirTemp; // Supply air temperature required to meet load [C]
3566 : Real64 SupplyAirTempToHeatSetPt; // Supply air temperature required to reach the heating setpoint [C]
3567 : Real64 SupplyAirTempToCoolSetPt; // Supply air temperature required to reach the cooling setpoint [C]
3568 :
3569 14 : auto &cBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNumber);
3570 :
3571 14 : Real64 DXCoolCoilInletTemp = state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp;
3572 14 : Real64 OutAirTemp = state.dataLoopNodes->Node(cBVAV.AirOutNode).Temp;
3573 14 : Real64 OutAirHumRat = state.dataLoopNodes->Node(cBVAV.AirOutNode).HumRat;
3574 :
3575 14 : if (cBVAV.HeatCoolMode == CoolingMode) { // Cooling required
3576 6 : CalcSetPointTempTarget = 99999.0;
3577 8 : } else if (cBVAV.HeatCoolMode == HeatingMode) { // Heating required
3578 4 : CalcSetPointTempTarget = -99999.0;
3579 : }
3580 14 : Real64 TSupplyToHeatSetPtMax = -99999.0; // Maximum of the supply air temperatures required to reach the heating setpoint [C]
3581 14 : Real64 TSupplyToCoolSetPtMin = 99999.0; // Minimum of the supply air temperatures required to reach the cooling setpoint [C]
3582 :
3583 28 : for (int ZoneNum = 1; ZoneNum <= cBVAV.NumControlledZones; ++ZoneNum) {
3584 14 : int ZoneNodeNum = cBVAV.ControlledZoneNodeNum(ZoneNum);
3585 14 : int BoxOutletNodeNum = cBVAV.CBVAVBoxOutletNode(ZoneNum);
3586 14 : if ((cBVAV.ZoneSequenceCoolingNum(ZoneNum) > 0) && (cBVAV.ZoneSequenceHeatingNum(ZoneNum) > 0)) {
3587 14 : QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum))
3588 14 : .SequencedOutputRequiredToCoolingSP(cBVAV.ZoneSequenceCoolingNum(ZoneNum));
3589 14 : QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum))
3590 14 : .SequencedOutputRequiredToHeatingSP(cBVAV.ZoneSequenceHeatingNum(ZoneNum));
3591 14 : if (QToHeatSetPt > 0.0 && QToCoolSetPt > 0.0) {
3592 4 : ZoneLoad = QToHeatSetPt;
3593 10 : } else if (QToHeatSetPt < 0.0 && QToCoolSetPt < 0.0) {
3594 6 : ZoneLoad = QToCoolSetPt;
3595 4 : } else if (QToHeatSetPt <= 0.0 && QToCoolSetPt >= 0.0) {
3596 4 : ZoneLoad = 0.0;
3597 : }
3598 : } else {
3599 0 : ZoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum)).RemainingOutputRequired;
3600 0 : QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum)).OutputRequiredToCoolingSP;
3601 0 : QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum)).OutputRequiredToHeatingSP;
3602 : }
3603 :
3604 14 : Real64 CpSupplyAir = Psychrometrics::PsyCpAirFnW(OutAirHumRat);
3605 :
3606 : // Find the supply air temperature that will force the box to full flow
3607 14 : if (BoxOutletNodeNum > 0) {
3608 14 : if (state.dataLoopNodes->Node(BoxOutletNodeNum).MassFlowRateMax == 0.0) {
3609 0 : SupplyAirTemp = state.dataLoopNodes->Node(ZoneNodeNum).Temp;
3610 : } else {
3611 : // The target supply air temperature is based on current zone temp and load and max box flow rate
3612 14 : SupplyAirTemp = state.dataLoopNodes->Node(ZoneNodeNum).Temp +
3613 14 : ZoneLoad / (CpSupplyAir * state.dataLoopNodes->Node(BoxOutletNodeNum).MassFlowRateMax);
3614 : }
3615 : } else {
3616 0 : SupplyAirTemp = state.dataLoopNodes->Node(ZoneNodeNum).Temp;
3617 : }
3618 :
3619 : // Save the MIN (cooling) or MAX (heating) temperature for coil control
3620 : // One box will always operate at maximum damper position minimizing overall system energy use
3621 14 : if (cBVAV.HeatCoolMode == CoolingMode) {
3622 6 : CalcSetPointTempTarget = min(SupplyAirTemp, CalcSetPointTempTarget);
3623 8 : } else if (cBVAV.HeatCoolMode == HeatingMode) {
3624 4 : CalcSetPointTempTarget = max(SupplyAirTemp, CalcSetPointTempTarget);
3625 : } else {
3626 : // Should use CpAirAtCoolSetPoint or CpAirAtHeatSetPoint here?
3627 : // If so, use ZoneThermostatSetPointLo(ZoneNum) and ZoneThermostatSetPointHi(ZoneNum)
3628 : // along with the zone humidity ratio
3629 4 : if (state.dataLoopNodes->Node(BoxOutletNodeNum).MassFlowRateMax == 0.0) {
3630 0 : SupplyAirTempToHeatSetPt = state.dataLoopNodes->Node(ZoneNodeNum).Temp;
3631 0 : SupplyAirTempToCoolSetPt = state.dataLoopNodes->Node(ZoneNodeNum).Temp;
3632 : } else {
3633 4 : SupplyAirTempToHeatSetPt = state.dataLoopNodes->Node(ZoneNodeNum).Temp +
3634 4 : QToHeatSetPt / (CpSupplyAir * state.dataLoopNodes->Node(BoxOutletNodeNum).MassFlowRateMax);
3635 4 : SupplyAirTempToCoolSetPt = state.dataLoopNodes->Node(ZoneNodeNum).Temp +
3636 4 : QToCoolSetPt / (CpSupplyAir * state.dataLoopNodes->Node(BoxOutletNodeNum).MassFlowRateMax);
3637 : }
3638 4 : TSupplyToHeatSetPtMax = max(SupplyAirTempToHeatSetPt, TSupplyToHeatSetPtMax);
3639 4 : TSupplyToCoolSetPtMin = min(SupplyAirTempToCoolSetPt, TSupplyToCoolSetPtMin);
3640 : }
3641 : }
3642 :
3643 : // Account for floating condition where cooling/heating is required to avoid overshooting setpoint
3644 14 : if (cBVAV.HeatCoolMode == 0) {
3645 4 : if (cBVAV.fanOp == HVAC::FanOp::Continuous) {
3646 0 : if (OutAirTemp > TSupplyToCoolSetPtMin) {
3647 0 : CalcSetPointTempTarget = TSupplyToCoolSetPtMin;
3648 0 : } else if (OutAirTemp < TSupplyToHeatSetPtMax) {
3649 0 : CalcSetPointTempTarget = TSupplyToHeatSetPtMax;
3650 : } else {
3651 0 : CalcSetPointTempTarget = OutAirTemp;
3652 : }
3653 : } else { // Reset setpoint to inlet air temp if unit is OFF and in cycling fan mode
3654 4 : CalcSetPointTempTarget = state.dataLoopNodes->Node(cBVAV.AirInNode).Temp;
3655 : }
3656 : // Reset cooling/heating mode to OFF if mixed air inlet temperature is below/above setpoint temperature.
3657 : // HeatCoolMode = 0 for OFF, 1 for cooling, 2 for heating
3658 10 : } else if (cBVAV.HeatCoolMode == CoolingMode) {
3659 6 : if (DXCoolCoilInletTemp < CalcSetPointTempTarget) {
3660 0 : CalcSetPointTempTarget = DXCoolCoilInletTemp;
3661 : }
3662 4 : } else if (cBVAV.HeatCoolMode == HeatingMode) {
3663 4 : if (DXCoolCoilInletTemp > CalcSetPointTempTarget) {
3664 0 : CalcSetPointTempTarget = DXCoolCoilInletTemp;
3665 : }
3666 : }
3667 :
3668 : // Limit outlet node temperature to MAX/MIN specified in input
3669 14 : if (CalcSetPointTempTarget < cBVAV.MinLATCooling) {
3670 0 : CalcSetPointTempTarget = cBVAV.MinLATCooling;
3671 : }
3672 14 : if (CalcSetPointTempTarget > cBVAV.MaxLATHeating) {
3673 0 : CalcSetPointTempTarget = cBVAV.MaxLATHeating;
3674 : }
3675 :
3676 14 : return CalcSetPointTempTarget;
3677 : }
3678 :
3679 17 : void SetAverageAirFlow(EnergyPlusData &state,
3680 : int const CBVAVNum, // Index to CBVAV system
3681 : Real64 &OnOffAirFlowRatio // Ratio of compressor ON airflow to average airflow over timestep
3682 : )
3683 : {
3684 :
3685 : // SUBROUTINE INFORMATION:
3686 : // AUTHOR Richard Raustad
3687 : // DATE WRITTEN July 2006
3688 :
3689 : // PURPOSE OF THIS SUBROUTINE:
3690 : // Set the average air mass flow rates for this time step
3691 : // Set OnOffAirFlowRatio to be used by DX coils
3692 :
3693 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3694 : Real64 ZoneMassFlow; // Zone mass flow rate required to meet zone load [kg/s]
3695 : Real64 ZoneLoad; // Zone load calculated by ZoneTempPredictor [W]
3696 :
3697 17 : auto &cBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
3698 :
3699 17 : int InletNode = cBVAV.AirInNode; // Inlet node number for CBVAVNum
3700 17 : int OutletNode = cBVAV.AirOutNode; // Outlet node number for CBVAVNum
3701 17 : int MixerMixedAirNode = cBVAV.MixerMixedAirNode; // Mixed air node number in OA mixer
3702 17 : int MixerOutsideAirNode = cBVAV.MixerOutsideAirNode; // Outside air node number in OA mixer
3703 17 : int MixerReliefAirNode = cBVAV.MixerReliefAirNode; // Relief air node number in OA mixer
3704 17 : int MixerInletAirNode = cBVAV.MixerInletAirNode; // Inlet air node number in OA mixer
3705 :
3706 17 : Real64 SystemMassFlow = 0.0; // System mass flow rate required for all zones [kg/s]
3707 17 : Real64 CpSupplyAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(OutletNode).HumRat); // Specific heat of outlet air [J/kg-K]
3708 : // Determine zone air flow
3709 34 : for (int ZoneNum = 1; ZoneNum <= cBVAV.NumControlledZones; ++ZoneNum) {
3710 17 : int ZoneNodeNum = cBVAV.ControlledZoneNodeNum(ZoneNum);
3711 17 : int BoxOutletNodeNum = cBVAV.CBVAVBoxOutletNode(ZoneNum); // Zone supply air inlet node number
3712 17 : if ((cBVAV.ZoneSequenceCoolingNum(ZoneNum) > 0) && (cBVAV.ZoneSequenceHeatingNum(ZoneNum) > 0)) {
3713 17 : Real64 QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum))
3714 17 : .SequencedOutputRequiredToCoolingSP(cBVAV.ZoneSequenceCoolingNum(ZoneNum));
3715 17 : Real64 QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum))
3716 17 : .SequencedOutputRequiredToHeatingSP(cBVAV.ZoneSequenceHeatingNum(ZoneNum));
3717 17 : if (QToHeatSetPt > 0.0 && QToCoolSetPt > 0.0) {
3718 5 : ZoneLoad = QToHeatSetPt;
3719 12 : } else if (QToHeatSetPt < 0.0 && QToCoolSetPt < 0.0) {
3720 8 : ZoneLoad = QToCoolSetPt;
3721 4 : } else if (QToHeatSetPt <= 0.0 && QToCoolSetPt >= 0.0) {
3722 4 : ZoneLoad = 0.0;
3723 : }
3724 : } else {
3725 0 : ZoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum)).RemainingOutputRequired;
3726 : }
3727 17 : Real64 CpZoneAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(ZoneNodeNum).HumRat);
3728 17 : Real64 DeltaCpTemp = CpSupplyAir * state.dataLoopNodes->Node(OutletNode).Temp - CpZoneAir * state.dataLoopNodes->Node(ZoneNodeNum).Temp;
3729 :
3730 : // Need to check DeltaCpTemp and ensure that it is not zero
3731 17 : if (DeltaCpTemp != 0.0) { // .AND. .NOT. CurDeadBandOrSetback(ZoneNum))THEN
3732 16 : ZoneMassFlow = ZoneLoad / DeltaCpTemp;
3733 : } else {
3734 : // reset to 0 so we don't add in the last zone's mass flow rate
3735 1 : ZoneMassFlow = 0.0;
3736 : }
3737 17 : SystemMassFlow += max(state.dataLoopNodes->Node(BoxOutletNodeNum).MassFlowRateMin,
3738 17 : min(ZoneMassFlow, state.dataLoopNodes->Node(BoxOutletNodeNum).MassFlowRateMax));
3739 : }
3740 :
3741 17 : Real64 AverageUnitMassFlow = state.dataHVACUnitaryBypassVAV->CompOnMassFlow;
3742 17 : Real64 AverageOAMassFlow = state.dataHVACUnitaryBypassVAV->OACompOnMassFlow;
3743 17 : state.dataHVACUnitaryBypassVAV->FanSpeedRatio = state.dataHVACUnitaryBypassVAV->CompOnFlowRatio;
3744 :
3745 17 : state.dataLoopNodes->Node(MixerInletAirNode) = state.dataLoopNodes->Node(InletNode);
3746 :
3747 17 : state.dataLoopNodes->Node(MixerMixedAirNode).MassFlowRateMin = 0.0;
3748 :
3749 17 : if (cBVAV.availSched->getCurrentVal() == 0.0 || AverageUnitMassFlow == 0.0) {
3750 1 : state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
3751 1 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRate = 0.0;
3752 1 : state.dataLoopNodes->Node(MixerReliefAirNode).MassFlowRate = 0.0;
3753 1 : OnOffAirFlowRatio = 0.0;
3754 1 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction = 0.0;
3755 : } else {
3756 16 : state.dataLoopNodes->Node(MixerInletAirNode).MassFlowRate = AverageUnitMassFlow;
3757 16 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRate = AverageOAMassFlow;
3758 16 : state.dataLoopNodes->Node(MixerReliefAirNode).MassFlowRate = AverageOAMassFlow;
3759 16 : OnOffAirFlowRatio = 1.0;
3760 16 : Real64 boxOutletNodeFlow = 0.0;
3761 32 : for (int i = 1; i <= cBVAV.NumControlledZones; ++i) {
3762 16 : boxOutletNodeFlow += state.dataLoopNodes->Node(cBVAV.CBVAVBoxOutletNode(i)).MassFlowRate;
3763 : }
3764 16 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction = max(0.0, 1.0 - (boxOutletNodeFlow / AverageUnitMassFlow));
3765 : }
3766 17 : }
3767 :
3768 0 : void ReportCBVAV(EnergyPlusData &state, int const CBVAVNum) // Index of the current CBVAV unit being simulated
3769 : {
3770 :
3771 : // SUBROUTINE INFORMATION:
3772 : // AUTHOR Richard Raustad
3773 : // DATE WRITTEN July 2006
3774 :
3775 : // PURPOSE OF THIS SUBROUTINE:
3776 : // Fills some of the report variables for the changeover-bypass VAV system
3777 :
3778 0 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
3779 :
3780 0 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
3781 :
3782 0 : thisCBVAV.TotCoolEnergy = thisCBVAV.TotCoolEnergyRate * ReportingConstant;
3783 0 : thisCBVAV.TotHeatEnergy = thisCBVAV.TotHeatEnergyRate * ReportingConstant;
3784 0 : thisCBVAV.SensCoolEnergy = thisCBVAV.SensCoolEnergyRate * ReportingConstant;
3785 0 : thisCBVAV.SensHeatEnergy = thisCBVAV.SensHeatEnergyRate * ReportingConstant;
3786 0 : thisCBVAV.LatCoolEnergy = thisCBVAV.LatCoolEnergyRate * ReportingConstant;
3787 0 : thisCBVAV.LatHeatEnergy = thisCBVAV.LatHeatEnergyRate * ReportingConstant;
3788 0 : thisCBVAV.ElecConsumption = thisCBVAV.ElecPower * ReportingConstant;
3789 :
3790 0 : if (thisCBVAV.FirstPass) {
3791 0 : if (!state.dataGlobal->SysSizingCalc) {
3792 0 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, state.dataSize->CurSysNum, thisCBVAV.FirstPass);
3793 : }
3794 : }
3795 :
3796 : // reset to 1 in case blow through fan configuration (fan resets to 1, but for blow thru fans coil sets back down < 1)
3797 0 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
3798 0 : }
3799 :
3800 28 : void CalcNonDXHeatingCoils(EnergyPlusData &state,
3801 : int const CBVAVNum, // Changeover bypass VAV unit index
3802 : bool const FirstHVACIteration, // flag for first HVAC iteration in the time step
3803 : Real64 &HeatCoilLoad, // heating coil load to be met (Watts)
3804 : HVAC::FanOp const fanOp, // fan operation mode
3805 : Real64 &HeatCoilLoadmet // coil heating load met
3806 : )
3807 : {
3808 :
3809 : // SUBROUTINE INFORMATION:
3810 : // AUTHOR Bereket Nigusse, FSEC/UCF
3811 : // DATE WRITTEN January 2012
3812 :
3813 : // PURPOSE OF THIS SUBROUTINE:
3814 : // This subroutine simulates the four non dx heating coil types: Gas, Electric, hot water and steam.
3815 :
3816 : // METHODOLOGY EMPLOYED:
3817 : // Simply calls the different heating coil component. The hot water flow rate matching the coil load
3818 : // is calculated iteratively.
3819 :
3820 : // SUBROUTINE PARAMETER DEFINITIONS:
3821 28 : Real64 constexpr ErrTolerance = 0.001; // convergence limit for hotwater coil
3822 28 : int constexpr SolveMaxIter = 50;
3823 :
3824 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3825 : Real64 mdot; // heating coil steam or hot water mass flow rate
3826 : Real64 MinWaterFlow; // minimum water mass flow rate
3827 : Real64 MaxHotWaterFlow; // maximum hot water mass flow rate, kg/s
3828 : Real64 HotWaterMdot; // actual hot water mass flow rate
3829 :
3830 28 : Real64 QCoilActual = 0.0; // actual heating load met
3831 :
3832 28 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
3833 :
3834 28 : if (HeatCoilLoad > HVAC::SmallLoad) {
3835 5 : switch (thisCBVAV.HeatCoilType) {
3836 5 : case HVAC::CoilType::HeatingGasOrOtherFuel:
3837 : case HVAC::CoilType::HeatingElectric: {
3838 20 : HeatingCoils::SimulateHeatingCoilComponents(
3839 15 : state, thisCBVAV.HeatCoilName, FirstHVACIteration, HeatCoilLoad, thisCBVAV.HeatCoilIndex, QCoilActual, false, fanOp);
3840 5 : } break;
3841 0 : case HVAC::CoilType::HeatingWater: {
3842 : // simulate the heating coil at maximum hot water flow rate
3843 0 : MaxHotWaterFlow = thisCBVAV.MaxHeatCoilFluidFlow;
3844 0 : PlantUtilities::SetComponentFlowRate(state, MaxHotWaterFlow, thisCBVAV.CoilControlNode, thisCBVAV.CoilOutletNode, thisCBVAV.plantLoc);
3845 0 : WaterCoils::SimulateWaterCoilComponents(
3846 0 : state, thisCBVAV.HeatCoilName, FirstHVACIteration, thisCBVAV.HeatCoilIndex, QCoilActual, fanOp);
3847 0 : if (QCoilActual > (HeatCoilLoad + HVAC::SmallLoad)) {
3848 : // control water flow to obtain output matching HeatCoilLoad
3849 0 : int SolFlag = 0;
3850 0 : MinWaterFlow = 0.0;
3851 0 : auto f = [&state, CBVAVNum, FirstHVACIteration, HeatCoilLoad](Real64 const HWFlow) {
3852 0 : auto &thiscBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
3853 0 : Real64 QCoilActual = HeatCoilLoad;
3854 0 : Real64 mdot = HWFlow;
3855 0 : PlantUtilities::SetComponentFlowRate(state, mdot, thiscBVAV.CoilControlNode, thiscBVAV.CoilOutletNode, thiscBVAV.plantLoc);
3856 : // simulate the hot water supplemental heating coil
3857 0 : WaterCoils::SimulateWaterCoilComponents(
3858 0 : state, thiscBVAV.HeatCoilName, FirstHVACIteration, thiscBVAV.HeatCoilIndex, QCoilActual, thiscBVAV.fanOp);
3859 0 : if (HeatCoilLoad != 0.0) {
3860 0 : return (QCoilActual - HeatCoilLoad) / HeatCoilLoad;
3861 : } else { // Autodesk:Return Condition added to assure return value is set
3862 0 : return 0.0;
3863 : }
3864 0 : };
3865 0 : General::SolveRoot(state, ErrTolerance, SolveMaxIter, SolFlag, HotWaterMdot, f, MinWaterFlow, MaxHotWaterFlow);
3866 0 : if (SolFlag == -1) {
3867 0 : if (thisCBVAV.HotWaterCoilMaxIterIndex == 0) {
3868 0 : ShowWarningMessage(
3869 : state,
3870 0 : format("CalcNonDXHeatingCoils: Hot water coil control failed for {}=\"{}\"", thisCBVAV.UnitType, thisCBVAV.Name));
3871 0 : ShowContinueErrorTimeStamp(state, "");
3872 0 : ShowContinueError(state, format(" Iteration limit [{}] exceeded in calculating hot water mass flow rate", SolveMaxIter));
3873 : }
3874 0 : ShowRecurringWarningErrorAtEnd(
3875 : state,
3876 0 : format("CalcNonDXHeatingCoils: Hot water coil control failed (iteration limit [{}]) for {}=\"{}",
3877 : SolveMaxIter,
3878 0 : thisCBVAV.UnitType,
3879 0 : thisCBVAV.Name),
3880 0 : thisCBVAV.HotWaterCoilMaxIterIndex);
3881 0 : } else if (SolFlag == -2) {
3882 0 : if (thisCBVAV.HotWaterCoilMaxIterIndex2 == 0) {
3883 0 : ShowWarningMessage(state,
3884 0 : format("CalcNonDXHeatingCoils: Hot water coil control failed (maximum flow limits) for {}=\"{}\"",
3885 0 : thisCBVAV.UnitType,
3886 0 : thisCBVAV.Name));
3887 0 : ShowContinueErrorTimeStamp(state, "");
3888 0 : ShowContinueError(state, "...Bad hot water maximum flow rate limits");
3889 0 : ShowContinueError(state, format("...Given minimum water flow rate={:.3R} kg/s", MinWaterFlow));
3890 0 : ShowContinueError(state, format("...Given maximum water flow rate={:.3R} kg/s", MaxHotWaterFlow));
3891 : }
3892 0 : ShowRecurringWarningErrorAtEnd(state,
3893 0 : "CalcNonDXHeatingCoils: Hot water coil control failed (flow limits) for " +
3894 0 : thisCBVAV.UnitType + "=\"" + thisCBVAV.Name + "\"",
3895 0 : thisCBVAV.HotWaterCoilMaxIterIndex2,
3896 : MaxHotWaterFlow,
3897 : MinWaterFlow,
3898 : _,
3899 : "[kg/s]",
3900 : "[kg/s]");
3901 : }
3902 : // simulate the hot water heating coil
3903 0 : QCoilActual = HeatCoilLoad;
3904 : // simulate the hot water heating coil
3905 0 : WaterCoils::SimulateWaterCoilComponents(
3906 0 : state, thisCBVAV.HeatCoilName, FirstHVACIteration, thisCBVAV.HeatCoilIndex, QCoilActual, fanOp);
3907 : }
3908 0 : } break;
3909 0 : case HVAC::CoilType::HeatingSteam: {
3910 0 : mdot = thisCBVAV.MaxHeatCoilFluidFlow;
3911 0 : PlantUtilities::SetComponentFlowRate(state, mdot, thisCBVAV.CoilControlNode, thisCBVAV.CoilOutletNode, thisCBVAV.plantLoc);
3912 :
3913 : // simulate the steam heating coil
3914 0 : SteamCoils::SimulateSteamCoilComponents(
3915 0 : state, thisCBVAV.HeatCoilName, FirstHVACIteration, thisCBVAV.HeatCoilIndex, HeatCoilLoad, QCoilActual, fanOp);
3916 0 : } break;
3917 0 : default:
3918 0 : break;
3919 : }
3920 : } else {
3921 23 : switch (thisCBVAV.HeatCoilType) {
3922 23 : case HVAC::CoilType::HeatingGasOrOtherFuel:
3923 : case HVAC::CoilType::HeatingElectric: {
3924 92 : HeatingCoils::SimulateHeatingCoilComponents(
3925 69 : state, thisCBVAV.HeatCoilName, FirstHVACIteration, HeatCoilLoad, thisCBVAV.HeatCoilIndex, QCoilActual, false, fanOp);
3926 23 : } break;
3927 0 : case HVAC::CoilType::HeatingWater: {
3928 0 : mdot = 0.0;
3929 0 : PlantUtilities::SetComponentFlowRate(state, mdot, thisCBVAV.CoilControlNode, thisCBVAV.CoilOutletNode, thisCBVAV.plantLoc);
3930 0 : QCoilActual = HeatCoilLoad;
3931 : // simulate the hot water heating coil
3932 0 : WaterCoils::SimulateWaterCoilComponents(
3933 0 : state, thisCBVAV.HeatCoilName, FirstHVACIteration, thisCBVAV.HeatCoilIndex, QCoilActual, fanOp);
3934 0 : } break;
3935 0 : case HVAC::CoilType::HeatingSteam: {
3936 0 : mdot = 0.0;
3937 0 : PlantUtilities::SetComponentFlowRate(state, mdot, thisCBVAV.CoilControlNode, thisCBVAV.CoilOutletNode, thisCBVAV.plantLoc);
3938 : // simulate the steam heating coil
3939 0 : SteamCoils::SimulateSteamCoilComponents(
3940 0 : state, thisCBVAV.HeatCoilName, FirstHVACIteration, thisCBVAV.HeatCoilIndex, HeatCoilLoad, QCoilActual, fanOp);
3941 0 : } break;
3942 0 : default:
3943 0 : break;
3944 : }
3945 : }
3946 28 : HeatCoilLoadmet = QCoilActual;
3947 28 : }
3948 :
3949 : } // namespace HVACUnitaryBypassVAV
3950 :
3951 : } // namespace EnergyPlus
|