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 2 : thisCBVAV.AirLoopNumber = AirLoopNum;
1087 : // Should EXIT here or do other checking?
1088 2 : break;
1089 : }
1090 : }
1091 : }
1092 :
1093 2 : if (thisCBVAV.AirLoopNumber > 0) {
1094 2 : thisCBVAV.NumControlledZones = state.dataAirLoop->AirToZoneNodeInfo(thisCBVAV.AirLoopNumber).NumZonesCooled;
1095 2 : thisCBVAV.ControlledZoneNum.allocate(thisCBVAV.NumControlledZones);
1096 2 : thisCBVAV.ControlledZoneNodeNum.allocate(thisCBVAV.NumControlledZones);
1097 2 : thisCBVAV.CBVAVBoxOutletNode.allocate(thisCBVAV.NumControlledZones);
1098 2 : thisCBVAV.ZoneSequenceCoolingNum.allocate(thisCBVAV.NumControlledZones);
1099 2 : thisCBVAV.ZoneSequenceHeatingNum.allocate(thisCBVAV.NumControlledZones);
1100 :
1101 2 : thisCBVAV.ControlledZoneNum = 0;
1102 4 : for (int AirLoopZoneNum = 1; AirLoopZoneNum <= state.dataAirLoop->AirToZoneNodeInfo(thisCBVAV.AirLoopNumber).NumZonesCooled;
1103 : ++AirLoopZoneNum) {
1104 4 : thisCBVAV.ControlledZoneNum(AirLoopZoneNum) =
1105 2 : state.dataAirLoop->AirToZoneNodeInfo(thisCBVAV.AirLoopNumber).CoolCtrlZoneNums(AirLoopZoneNum);
1106 2 : if (thisCBVAV.ControlledZoneNum(AirLoopZoneNum) > 0) {
1107 4 : thisCBVAV.ControlledZoneNodeNum(AirLoopZoneNum) =
1108 2 : state.dataZoneEquip->ZoneEquipConfig(thisCBVAV.ControlledZoneNum(AirLoopZoneNum)).ZoneNode;
1109 4 : thisCBVAV.CBVAVBoxOutletNode(AirLoopZoneNum) =
1110 2 : state.dataAirLoop->AirToZoneNodeInfo(thisCBVAV.AirLoopNumber).CoolZoneInletNodes(AirLoopZoneNum);
1111 : // check for thermostat in controlled zone
1112 2 : bool FoundTstatZone = false;
1113 2 : for (int TstatZoneNum = 1; TstatZoneNum <= state.dataZoneCtrls->NumTempControlledZones; ++TstatZoneNum) {
1114 0 : if (state.dataZoneCtrls->TempControlledZone(TstatZoneNum).ActualZoneNum != thisCBVAV.ControlledZoneNum(AirLoopZoneNum))
1115 0 : continue;
1116 0 : FoundTstatZone = true;
1117 : }
1118 2 : if (!FoundTstatZone) {
1119 2 : ShowWarningError(state, format("{} \"{}\"", CurrentModuleObject, thisCBVAV.Name));
1120 4 : ShowContinueError(state,
1121 4 : format("Thermostat not found in zone = {} and the simulation continues.",
1122 2 : state.dataZoneEquip->ZoneEquipConfig(thisCBVAV.ControlledZoneNum(AirLoopZoneNum)).ZoneName));
1123 6 : ShowContinueError(state, "This zone will not be controlled to a temperature setpoint.");
1124 : }
1125 2 : int zoneNum = thisCBVAV.ControlledZoneNum(AirLoopZoneNum);
1126 2 : int zoneInlet = thisCBVAV.CBVAVBoxOutletNode(AirLoopZoneNum);
1127 : // setup zone equipment sequence information based on finding matching air terminal
1128 2 : if (state.dataZoneEquip->ZoneEquipConfig(zoneNum).EquipListIndex > 0) {
1129 2 : int coolingPriority = 0;
1130 2 : int heatingPriority = 0;
1131 2 : state.dataZoneEquip->ZoneEquipList(state.dataZoneEquip->ZoneEquipConfig(zoneNum).EquipListIndex)
1132 2 : .getPrioritiesForInletNode(state, zoneInlet, coolingPriority, heatingPriority);
1133 2 : thisCBVAV.ZoneSequenceCoolingNum(AirLoopZoneNum) = coolingPriority;
1134 2 : thisCBVAV.ZoneSequenceHeatingNum(AirLoopZoneNum) = heatingPriority;
1135 : }
1136 2 : if (thisCBVAV.ZoneSequenceCoolingNum(AirLoopZoneNum) == 0 || thisCBVAV.ZoneSequenceHeatingNum(AirLoopZoneNum) == 0) {
1137 0 : ShowSevereError(
1138 : state,
1139 0 : format("AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass, \"{}\": Airloop air terminal in the zone equipment list for "
1140 : "zone = {} not found or is not allowed Zone Equipment Cooling or Heating Sequence = 0.",
1141 0 : thisCBVAV.Name,
1142 0 : state.dataZoneEquip->ZoneEquipConfig(zoneNum).ZoneName));
1143 0 : ErrorsFound = true;
1144 : }
1145 : } else {
1146 0 : ShowSevereError(state, "Controlled Zone node not found.");
1147 0 : ErrorsFound = true;
1148 : }
1149 : }
1150 : } else {
1151 : }
1152 :
1153 2 : } // CBVAVNum = 1,NumCBVAV
1154 :
1155 2 : if (ErrorsFound) {
1156 0 : ShowFatalError(state, format("GetCBVAV: Errors found in getting {} input.", CurrentModuleObject));
1157 : }
1158 :
1159 4 : for (int CBVAVNum = 1; CBVAVNum <= NumCBVAV; ++CBVAVNum) {
1160 : // Setup Report variables
1161 2 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
1162 4 : SetupOutputVariable(state,
1163 : "Unitary System Total Heating Rate",
1164 : Constant::Units::W,
1165 2 : thisCBVAV.TotHeatEnergyRate,
1166 : OutputProcessor::TimeStepType::System,
1167 : OutputProcessor::StoreType::Average,
1168 2 : thisCBVAV.Name);
1169 4 : SetupOutputVariable(state,
1170 : "Unitary System Total Heating Energy",
1171 : Constant::Units::J,
1172 2 : thisCBVAV.TotHeatEnergy,
1173 : OutputProcessor::TimeStepType::System,
1174 : OutputProcessor::StoreType::Sum,
1175 2 : thisCBVAV.Name);
1176 4 : SetupOutputVariable(state,
1177 : "Unitary System Total Cooling Rate",
1178 : Constant::Units::W,
1179 2 : thisCBVAV.TotCoolEnergyRate,
1180 : OutputProcessor::TimeStepType::System,
1181 : OutputProcessor::StoreType::Average,
1182 2 : thisCBVAV.Name);
1183 4 : SetupOutputVariable(state,
1184 : "Unitary System Total Cooling Energy",
1185 : Constant::Units::J,
1186 2 : thisCBVAV.TotCoolEnergy,
1187 : OutputProcessor::TimeStepType::System,
1188 : OutputProcessor::StoreType::Sum,
1189 2 : thisCBVAV.Name);
1190 4 : SetupOutputVariable(state,
1191 : "Unitary System Sensible Heating Rate",
1192 : Constant::Units::W,
1193 2 : thisCBVAV.SensHeatEnergyRate,
1194 : OutputProcessor::TimeStepType::System,
1195 : OutputProcessor::StoreType::Average,
1196 2 : thisCBVAV.Name);
1197 4 : SetupOutputVariable(state,
1198 : "Unitary System Sensible Heating Energy",
1199 : Constant::Units::J,
1200 2 : thisCBVAV.SensHeatEnergy,
1201 : OutputProcessor::TimeStepType::System,
1202 : OutputProcessor::StoreType::Sum,
1203 2 : thisCBVAV.Name);
1204 4 : SetupOutputVariable(state,
1205 : "Unitary System Sensible Cooling Rate",
1206 : Constant::Units::W,
1207 2 : thisCBVAV.SensCoolEnergyRate,
1208 : OutputProcessor::TimeStepType::System,
1209 : OutputProcessor::StoreType::Average,
1210 2 : thisCBVAV.Name);
1211 4 : SetupOutputVariable(state,
1212 : "Unitary System Sensible Cooling Energy",
1213 : Constant::Units::J,
1214 2 : thisCBVAV.SensCoolEnergy,
1215 : OutputProcessor::TimeStepType::System,
1216 : OutputProcessor::StoreType::Sum,
1217 2 : thisCBVAV.Name);
1218 4 : SetupOutputVariable(state,
1219 : "Unitary System Latent Heating Rate",
1220 : Constant::Units::W,
1221 2 : thisCBVAV.LatHeatEnergyRate,
1222 : OutputProcessor::TimeStepType::System,
1223 : OutputProcessor::StoreType::Average,
1224 2 : thisCBVAV.Name);
1225 4 : SetupOutputVariable(state,
1226 : "Unitary System Latent Heating Energy",
1227 : Constant::Units::J,
1228 2 : thisCBVAV.LatHeatEnergy,
1229 : OutputProcessor::TimeStepType::System,
1230 : OutputProcessor::StoreType::Sum,
1231 2 : thisCBVAV.Name);
1232 4 : SetupOutputVariable(state,
1233 : "Unitary System Latent Cooling Rate",
1234 : Constant::Units::W,
1235 2 : thisCBVAV.LatCoolEnergyRate,
1236 : OutputProcessor::TimeStepType::System,
1237 : OutputProcessor::StoreType::Average,
1238 2 : thisCBVAV.Name);
1239 4 : SetupOutputVariable(state,
1240 : "Unitary System Latent Cooling Energy",
1241 : Constant::Units::J,
1242 2 : thisCBVAV.LatCoolEnergy,
1243 : OutputProcessor::TimeStepType::System,
1244 : OutputProcessor::StoreType::Sum,
1245 2 : thisCBVAV.Name);
1246 4 : SetupOutputVariable(state,
1247 : "Unitary System Electricity Rate",
1248 : Constant::Units::W,
1249 2 : thisCBVAV.ElecPower,
1250 : OutputProcessor::TimeStepType::System,
1251 : OutputProcessor::StoreType::Average,
1252 2 : thisCBVAV.Name);
1253 4 : SetupOutputVariable(state,
1254 : "Unitary System Electricity Energy",
1255 : Constant::Units::J,
1256 2 : thisCBVAV.ElecConsumption,
1257 : OutputProcessor::TimeStepType::System,
1258 : OutputProcessor::StoreType::Sum,
1259 2 : thisCBVAV.Name);
1260 4 : SetupOutputVariable(state,
1261 : "Unitary System Fan Part Load Ratio",
1262 : Constant::Units::None,
1263 2 : thisCBVAV.FanPartLoadRatio,
1264 : OutputProcessor::TimeStepType::System,
1265 : OutputProcessor::StoreType::Average,
1266 2 : thisCBVAV.Name);
1267 4 : SetupOutputVariable(state,
1268 : "Unitary System Compressor Part Load Ratio",
1269 : Constant::Units::None,
1270 2 : thisCBVAV.CompPartLoadRatio,
1271 : OutputProcessor::TimeStepType::System,
1272 : OutputProcessor::StoreType::Average,
1273 2 : thisCBVAV.Name);
1274 4 : SetupOutputVariable(state,
1275 : "Unitary System Bypass Air Mass Flow Rate",
1276 : Constant::Units::kg_s,
1277 2 : thisCBVAV.BypassMassFlowRate,
1278 : OutputProcessor::TimeStepType::System,
1279 : OutputProcessor::StoreType::Average,
1280 2 : thisCBVAV.Name);
1281 4 : SetupOutputVariable(state,
1282 : "Unitary System Air Outlet Setpoint Temperature",
1283 : Constant::Units::C,
1284 2 : thisCBVAV.OutletTempSetPoint,
1285 : OutputProcessor::TimeStepType::System,
1286 : OutputProcessor::StoreType::Average,
1287 2 : thisCBVAV.Name);
1288 2 : SetupOutputVariable(state,
1289 : "Unitary System Operating Mode Index",
1290 : Constant::Units::None,
1291 2 : thisCBVAV.HeatCoolMode,
1292 : OutputProcessor::TimeStepType::System,
1293 : OutputProcessor::StoreType::Average,
1294 2 : thisCBVAV.Name);
1295 : }
1296 2 : }
1297 :
1298 17 : void InitCBVAV(EnergyPlusData &state,
1299 : int const CBVAVNum, // Index of the current CBVAV unit being simulated
1300 : bool const FirstHVACIteration, // TRUE if first HVAC iteration
1301 : int const AirLoopNum, // air loop index
1302 : Real64 &OnOffAirFlowRatio, // Ratio of compressor ON airflow to average airflow over timestep
1303 : bool const HXUnitOn // flag to enable heat exchanger
1304 : )
1305 : {
1306 :
1307 : // SUBROUTINE INFORMATION:
1308 : // AUTHOR Richard Raustad
1309 : // DATE WRITTEN July 2006
1310 : // MODIFIED B. Griffith, May 2009, EMS setpoint check
1311 :
1312 : // PURPOSE OF THIS SUBROUTINE:
1313 : // This subroutine is for initializations of the changeover-bypass VAV system components.
1314 :
1315 : // METHODOLOGY EMPLOYED:
1316 : // Uses the status flags to trigger initializations. The CBVAV system is simulated with no load (coils off) to
1317 : // determine the outlet temperature. A setpoint temperature is calculated on FirstHVACIteration = TRUE.
1318 : // Once the setpoint is calculated, the inlet mass flow rate on FirstHVACIteration = FALSE is used to
1319 : // determine the bypass fraction. The simulation converges quickly on mass flow rate. If the zone
1320 : // temperatures float in the deadband, additional iterations are required to converge on mass flow rate.
1321 :
1322 : // SUBROUTINE PARAMETER DEFINITIONS:
1323 : static constexpr std::string_view RoutineName("InitCBVAV");
1324 :
1325 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1326 : Real64 QSensUnitOut; // Output of CBVAV system with coils off
1327 : Real64 OutsideAirMultiplier; // Outside air multiplier schedule (= 1.0 if no schedule)
1328 : Real64 QCoilActual; // actual CBVAV steam heating coil load met (W)
1329 : bool ErrorFlag; // local error flag returned from data mining
1330 : Real64 mdot; // heating coil fluid mass flow rate, kg/s
1331 :
1332 17 : auto &cBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
1333 17 : int NumCBVAV = state.dataHVACUnitaryBypassVAV->NumCBVAV;
1334 :
1335 17 : int InNode = cBVAV.AirInNode;
1336 17 : int OutNode = cBVAV.AirOutNode;
1337 :
1338 : // Do the one time initializations
1339 17 : if (state.dataHVACUnitaryBypassVAV->MyOneTimeFlag) {
1340 :
1341 5 : state.dataHVACUnitaryBypassVAV->MyEnvrnFlag.allocate(NumCBVAV);
1342 5 : state.dataHVACUnitaryBypassVAV->MySizeFlag.allocate(NumCBVAV);
1343 5 : state.dataHVACUnitaryBypassVAV->MyPlantScanFlag.allocate(NumCBVAV);
1344 5 : state.dataHVACUnitaryBypassVAV->MyEnvrnFlag = true;
1345 5 : state.dataHVACUnitaryBypassVAV->MySizeFlag = true;
1346 5 : state.dataHVACUnitaryBypassVAV->MyPlantScanFlag = true;
1347 :
1348 5 : state.dataHVACUnitaryBypassVAV->MyOneTimeFlag = false;
1349 : // speed up test based on code from 16 years ago to correct cycling fan economizer defect
1350 : // see https://github.com/NREL/EnergyPlusArchive/commit/a2202f8a168fd0330bf3a45392833405e8bd08f2
1351 : // This test sets simple flag so air loop doesn't iterate twice each pass (reverts above change)
1352 : // AirLoopControlInfo(AirplantLoc.loopNum).Simple = true;
1353 : }
1354 :
1355 17 : if (state.dataHVACUnitaryBypassVAV->MyPlantScanFlag(CBVAVNum) && allocated(state.dataPlnt->PlantLoop)) {
1356 0 : if ((cBVAV.HeatCoilType == HVAC::CoilType::HeatingWater) || (cBVAV.HeatCoilType == HVAC::CoilType::HeatingSteam)) {
1357 0 : bool ErrorsFound = false; // Set to true if errors in input, fatal at end of routine
1358 0 : if (cBVAV.HeatCoilType == HVAC::CoilType::HeatingWater) {
1359 :
1360 0 : ErrorFlag = false;
1361 0 : PlantUtilities::ScanPlantLoopsForObject(
1362 0 : state, cBVAV.HeatCoilName, DataPlant::PlantEquipmentType::CoilWaterSimpleHeating, cBVAV.plantLoc, ErrorFlag, _, _, _, _, _);
1363 0 : if (ErrorFlag) {
1364 0 : ShowFatalError(state, "InitCBVAV: Program terminated for previous conditions.");
1365 : }
1366 :
1367 0 : cBVAV.MaxHeatCoilFluidFlow = WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", cBVAV.HeatCoilName, ErrorsFound);
1368 :
1369 0 : if (cBVAV.MaxHeatCoilFluidFlow > 0.0) {
1370 : Real64 FluidDensity =
1371 0 : state.dataPlnt->PlantLoop(cBVAV.plantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
1372 0 : cBVAV.MaxHeatCoilFluidFlow =
1373 0 : WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", cBVAV.HeatCoilName, ErrorsFound) * FluidDensity;
1374 : }
1375 :
1376 0 : } else if (cBVAV.HeatCoilType == HVAC::CoilType::HeatingSteam) {
1377 :
1378 0 : ErrorFlag = false;
1379 0 : PlantUtilities::ScanPlantLoopsForObject(
1380 0 : state, cBVAV.HeatCoilName, DataPlant::PlantEquipmentType::CoilSteamAirHeating, cBVAV.plantLoc, ErrorFlag, _, _, _, _, _);
1381 :
1382 0 : if (ErrorFlag) {
1383 0 : ShowFatalError(state, "InitCBVAV: Program terminated for previous conditions.");
1384 : }
1385 :
1386 0 : cBVAV.MaxHeatCoilFluidFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, cBVAV.HeatCoilIndex, ErrorsFound);
1387 :
1388 0 : if (cBVAV.MaxHeatCoilFluidFlow > 0.0) {
1389 : // Why is TempSteamIn a state variable of the entire module?
1390 : Real64 FluidDensity =
1391 0 : Fluid::GetSteam(state)->getSatDensity(state, state.dataHVACUnitaryBypassVAV->TempSteamIn, 1.0, RoutineName);
1392 :
1393 0 : cBVAV.MaxHeatCoilFluidFlow = SteamCoils::GetCoilMaxSteamFlowRate(state, cBVAV.HeatCoilIndex, ErrorsFound) * FluidDensity;
1394 : }
1395 : }
1396 :
1397 0 : if (ErrorsFound) {
1398 0 : ShowContinueError(state, format("Occurs in {} = {}", "AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass", cBVAV.Name));
1399 : }
1400 : // fill outlet node for heating coil
1401 0 : cBVAV.CoilOutletNode = DataPlant::CompData::getPlantComponent(state, cBVAV.plantLoc).NodeNumOut;
1402 0 : state.dataHVACUnitaryBypassVAV->MyPlantScanFlag(CBVAVNum) = false;
1403 :
1404 0 : } else { // CBVAV is not connected to plant
1405 0 : state.dataHVACUnitaryBypassVAV->MyPlantScanFlag(CBVAVNum) = false;
1406 : }
1407 17 : } else if (state.dataHVACUnitaryBypassVAV->MyPlantScanFlag(CBVAVNum) && !state.dataGlobal->AnyPlantInModel) {
1408 5 : state.dataHVACUnitaryBypassVAV->MyPlantScanFlag(CBVAVNum) = false;
1409 : }
1410 :
1411 17 : if (!state.dataGlobal->SysSizingCalc && state.dataHVACUnitaryBypassVAV->MySizeFlag(CBVAVNum)) {
1412 4 : SizeCBVAV(state, CBVAVNum);
1413 : // Pass the fan cycling schedule index up to the air loop. Set the air loop unitary system flag.
1414 4 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).cycFanSched = cBVAV.fanOpModeSched;
1415 : // Set UnitarySys flag to FALSE and let the heating coil autosize independently of the cooling coil
1416 4 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).UnitarySys = false;
1417 4 : state.dataAirLoop->AirLoopControlInfo(AirLoopNum).fanOp = cBVAV.fanOp;
1418 : // check for set point manager on outlet node of CBVAV
1419 4 : cBVAV.OutNodeSPMIndex = SetPointManager::GetSetPointManagerIndexByNode(state,
1420 : OutNode,
1421 : HVAC::CtrlVarType::Temp,
1422 : SetPointManager::SPMType::MixedAir,
1423 : true); // isRefNode
1424 4 : state.dataHVACUnitaryBypassVAV->MySizeFlag(CBVAVNum) = false;
1425 : }
1426 :
1427 : // Do the Begin Environment initializations
1428 17 : if (state.dataGlobal->BeginEnvrnFlag && state.dataHVACUnitaryBypassVAV->MyEnvrnFlag(CBVAVNum)) {
1429 1 : int MixerOutsideAirNode = cBVAV.MixerOutsideAirNode;
1430 1 : Real64 RhoAir = state.dataEnvrn->StdRhoAir;
1431 : // set the mass flow rates from the input volume flow rates
1432 1 : cBVAV.MaxCoolAirMassFlow = RhoAir * cBVAV.MaxCoolAirVolFlow;
1433 1 : cBVAV.CoolOutAirMassFlow = RhoAir * cBVAV.CoolOutAirVolFlow;
1434 1 : cBVAV.MaxHeatAirMassFlow = RhoAir * cBVAV.MaxHeatAirVolFlow;
1435 1 : cBVAV.HeatOutAirMassFlow = RhoAir * cBVAV.HeatOutAirVolFlow;
1436 1 : cBVAV.MaxNoCoolHeatAirMassFlow = RhoAir * cBVAV.MaxNoCoolHeatAirVolFlow;
1437 1 : cBVAV.NoCoolHeatOutAirMassFlow = RhoAir * cBVAV.NoCoolHeatOutAirVolFlow;
1438 : // set the node max and min mass flow rates
1439 1 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMax = max(cBVAV.CoolOutAirMassFlow, cBVAV.HeatOutAirMassFlow);
1440 1 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMaxAvail = max(cBVAV.CoolOutAirMassFlow, cBVAV.HeatOutAirMassFlow);
1441 1 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMin = 0.0;
1442 1 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMinAvail = 0.0;
1443 1 : state.dataLoopNodes->Node(InNode).MassFlowRateMax = max(cBVAV.MaxCoolAirMassFlow, cBVAV.MaxHeatAirMassFlow);
1444 1 : state.dataLoopNodes->Node(InNode).MassFlowRateMaxAvail = max(cBVAV.MaxCoolAirMassFlow, cBVAV.MaxHeatAirMassFlow);
1445 1 : state.dataLoopNodes->Node(InNode).MassFlowRateMin = 0.0;
1446 1 : state.dataLoopNodes->Node(InNode).MassFlowRateMinAvail = 0.0;
1447 1 : state.dataLoopNodes->Node(OutNode).Temp = state.dataLoopNodes->Node(InNode).Temp;
1448 1 : state.dataLoopNodes->Node(OutNode).HumRat = state.dataLoopNodes->Node(InNode).HumRat;
1449 1 : state.dataLoopNodes->Node(OutNode).Enthalpy = state.dataLoopNodes->Node(InNode).Enthalpy;
1450 1 : state.dataLoopNodes->Node(cBVAV.MixerReliefAirNode) = state.dataLoopNodes->Node(MixerOutsideAirNode);
1451 1 : state.dataHVACUnitaryBypassVAV->MyEnvrnFlag(CBVAVNum) = false;
1452 1 : cBVAV.LastMode = HeatingMode;
1453 1 : cBVAV.changeOverTimer = -1.0;
1454 : // set fluid-side hardware limits
1455 1 : if (cBVAV.CoilControlNode > 0) {
1456 : // If water coil max water flow rate is autosized, simulate once in order to mine max water flow rate
1457 0 : if (cBVAV.MaxHeatCoilFluidFlow == DataSizing::AutoSize) {
1458 0 : if (cBVAV.HeatCoilType == HVAC::CoilType::HeatingWater) {
1459 0 : WaterCoils::SimulateWaterCoilComponents(state, cBVAV.HeatCoilName, FirstHVACIteration, cBVAV.HeatCoilIndex);
1460 0 : ErrorFlag = false;
1461 0 : Real64 CoilMaxVolFlowRate = WaterCoils::GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", cBVAV.HeatCoilName, ErrorFlag);
1462 0 : if (ErrorFlag) {
1463 0 : ShowContinueError(state, format("Occurs in {} = {}", "AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass", cBVAV.Name));
1464 : }
1465 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
1466 : Real64 FluidDensity =
1467 0 : state.dataPlnt->PlantLoop(cBVAV.plantLoc.loopNum).glycol->getDensity(state, Constant::HWInitConvTemp, RoutineName);
1468 0 : cBVAV.MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * FluidDensity;
1469 : }
1470 : }
1471 0 : if (cBVAV.HeatCoilType == HVAC::CoilType::HeatingSteam) {
1472 0 : SteamCoils::SimulateSteamCoilComponents(state,
1473 : cBVAV.HeatCoilName,
1474 : FirstHVACIteration,
1475 0 : cBVAV.HeatCoilIndex,
1476 0 : 1.0,
1477 : QCoilActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
1478 0 : ErrorFlag = false;
1479 0 : Real64 CoilMaxVolFlowRate = SteamCoils::GetCoilMaxSteamFlowRate(state, cBVAV.HeatCoilIndex, ErrorFlag);
1480 0 : if (ErrorFlag) {
1481 0 : ShowContinueError(state, format("Occurs in {} = {}", "AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass", cBVAV.Name));
1482 : }
1483 0 : if (CoilMaxVolFlowRate != DataSizing::AutoSize) {
1484 : Real64 FluidDensity =
1485 0 : Fluid::GetSteam(state)->getSatDensity(state, state.dataHVACUnitaryBypassVAV->TempSteamIn, 1.0, RoutineName);
1486 0 : cBVAV.MaxHeatCoilFluidFlow = CoilMaxVolFlowRate * FluidDensity;
1487 : }
1488 : }
1489 : } // end of IF(cBVAV%MaxHeatCoilFluidFlow .EQ. DataSizing::AutoSize)THEN
1490 :
1491 0 : PlantUtilities::InitComponentNodes(state, 0.0, cBVAV.MaxHeatCoilFluidFlow, cBVAV.CoilControlNode, cBVAV.CoilOutletNode);
1492 :
1493 : } // end of IF(cBVAV%CoilControlNode .GT. 0)THEN
1494 : } // end one time inits
1495 :
1496 17 : if (!state.dataGlobal->BeginEnvrnFlag) {
1497 16 : state.dataHVACUnitaryBypassVAV->MyEnvrnFlag(CBVAVNum) = true;
1498 : }
1499 :
1500 : // IF CBVAV system was not autosized and the fan is autosized, check that fan volumetric flow rate is greater than CBVAV flow rates
1501 17 : if (cBVAV.CheckFanFlow) {
1502 :
1503 5 : if (!state.dataGlobal->DoingSizing && cBVAV.FanVolFlow != DataSizing::AutoSize) {
1504 4 : std::string CurrentModuleObject = "AirLoopHVAC:UnitaryHeatCool:VAVChangeoverBypass";
1505 : // Check fan versus system supply air flow rates
1506 4 : if (cBVAV.FanVolFlow < cBVAV.MaxCoolAirVolFlow) {
1507 0 : ShowWarningError(state,
1508 0 : format("{} - air flow rate = {:.7T} in fan object {} is less than the maximum CBVAV system air flow rate when "
1509 : "cooling is required ({:.7T}).",
1510 : CurrentModuleObject,
1511 0 : cBVAV.FanVolFlow,
1512 0 : cBVAV.FanName,
1513 0 : cBVAV.MaxCoolAirVolFlow));
1514 0 : ShowContinueError(
1515 : state, " The CBVAV system flow rate when cooling is required is reset to the fan flow rate and the simulation continues.");
1516 0 : ShowContinueError(state, format(" Occurs in Changeover-bypass VAV system = {}", cBVAV.Name));
1517 0 : cBVAV.MaxCoolAirVolFlow = cBVAV.FanVolFlow;
1518 : }
1519 4 : if (cBVAV.FanVolFlow < cBVAV.MaxHeatAirVolFlow) {
1520 0 : ShowWarningError(state,
1521 0 : format("{} - air flow rate = {:.7T} in fan object {} is less than the maximum CBVAV system air flow rate when "
1522 : "heating is required ({:.7T}).",
1523 : CurrentModuleObject,
1524 0 : cBVAV.FanVolFlow,
1525 0 : cBVAV.FanName,
1526 0 : cBVAV.MaxHeatAirVolFlow));
1527 0 : ShowContinueError(
1528 : state, " The CBVAV system flow rate when heating is required is reset to the fan flow rate and the simulation continues.");
1529 0 : ShowContinueError(state, format(" Occurs in Changeover-bypass VAV system = {}", cBVAV.Name));
1530 0 : cBVAV.MaxHeatAirVolFlow = cBVAV.FanVolFlow;
1531 : }
1532 4 : if (cBVAV.FanVolFlow < cBVAV.MaxNoCoolHeatAirVolFlow && cBVAV.MaxNoCoolHeatAirVolFlow != 0.0) {
1533 0 : ShowWarningError(state,
1534 0 : format("{} - air flow rate = {:.7T} in fan object {} is less than the maximum CBVAV system air flow rate when "
1535 : "no heating or cooling is needed ({:.7T}).",
1536 : CurrentModuleObject,
1537 0 : cBVAV.FanVolFlow,
1538 0 : cBVAV.FanName,
1539 0 : cBVAV.MaxNoCoolHeatAirVolFlow));
1540 0 : ShowContinueError(state,
1541 : " The CBVAV system flow rate when no heating or cooling is needed is reset to the fan flow rate and the "
1542 : "simulation continues.");
1543 0 : ShowContinueError(state, format(" Occurs in Changeover-bypass VAV system = {}", cBVAV.Name));
1544 0 : cBVAV.MaxNoCoolHeatAirVolFlow = cBVAV.FanVolFlow;
1545 : }
1546 : // Check fan versus outdoor air flow rates
1547 4 : if (cBVAV.FanVolFlow < cBVAV.CoolOutAirVolFlow) {
1548 0 : ShowWarningError(state,
1549 0 : format("{} - air flow rate = {:.7T} in fan object {} is less than the maximum CBVAV outdoor air flow rate when "
1550 : "cooling is required ({:.7T}).",
1551 : CurrentModuleObject,
1552 0 : cBVAV.FanVolFlow,
1553 0 : cBVAV.FanName,
1554 0 : cBVAV.CoolOutAirVolFlow));
1555 0 : ShowContinueError(
1556 : state, " The CBVAV outdoor flow rate when cooling is required is reset to the fan flow rate and the simulation continues.");
1557 0 : ShowContinueError(state, format(" Occurs in Changeover-bypass VAV system = {}", cBVAV.Name));
1558 0 : cBVAV.CoolOutAirVolFlow = cBVAV.FanVolFlow;
1559 : }
1560 4 : if (cBVAV.FanVolFlow < cBVAV.HeatOutAirVolFlow) {
1561 0 : ShowWarningError(state,
1562 0 : format("{} - air flow rate = {:.7T} in fan object {} is less than the maximum CBVAV outdoor air flow rate when "
1563 : "heating is required ({:.7T}).",
1564 : CurrentModuleObject,
1565 0 : cBVAV.FanVolFlow,
1566 0 : cBVAV.FanName,
1567 0 : cBVAV.HeatOutAirVolFlow));
1568 0 : ShowContinueError(
1569 : state, " The CBVAV outdoor flow rate when heating is required is reset to the fan flow rate and the simulation continues.");
1570 0 : ShowContinueError(state, format(" Occurs in Changeover-bypass VAV system = {}", cBVAV.Name));
1571 0 : cBVAV.HeatOutAirVolFlow = cBVAV.FanVolFlow;
1572 : }
1573 4 : if (cBVAV.FanVolFlow < cBVAV.NoCoolHeatOutAirVolFlow) {
1574 0 : ShowWarningError(state,
1575 0 : format("{} - air flow rate = {:.7T} in fan object {} is less than the maximum CBVAV outdoor air flow rate when "
1576 : "no heating or cooling is needed ({:.7T}).",
1577 : CurrentModuleObject,
1578 0 : cBVAV.FanVolFlow,
1579 0 : cBVAV.FanName,
1580 0 : cBVAV.NoCoolHeatOutAirVolFlow));
1581 0 : ShowContinueError(state,
1582 : " The CBVAV outdoor flow rate when no heating or cooling is needed is reset to the fan flow rate and the "
1583 : "simulation continues.");
1584 0 : ShowContinueError(state, format(" Occurs in Changeover-bypass VAV system = {}", cBVAV.Name));
1585 0 : cBVAV.NoCoolHeatOutAirVolFlow = cBVAV.FanVolFlow;
1586 : }
1587 4 : int MixerOutsideAirNode = cBVAV.MixerOutsideAirNode;
1588 4 : Real64 RhoAir = state.dataEnvrn->StdRhoAir;
1589 : // set the mass flow rates from the reset volume flow rates
1590 4 : cBVAV.MaxCoolAirMassFlow = RhoAir * cBVAV.MaxCoolAirVolFlow;
1591 4 : cBVAV.CoolOutAirMassFlow = RhoAir * cBVAV.CoolOutAirVolFlow;
1592 4 : cBVAV.MaxHeatAirMassFlow = RhoAir * cBVAV.MaxHeatAirVolFlow;
1593 4 : cBVAV.HeatOutAirMassFlow = RhoAir * cBVAV.HeatOutAirVolFlow;
1594 4 : cBVAV.MaxNoCoolHeatAirMassFlow = RhoAir * cBVAV.MaxNoCoolHeatAirVolFlow;
1595 4 : cBVAV.NoCoolHeatOutAirMassFlow = RhoAir * cBVAV.NoCoolHeatOutAirVolFlow;
1596 : // set the node max and min mass flow rates based on reset volume flow rates
1597 4 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMax = max(cBVAV.CoolOutAirMassFlow, cBVAV.HeatOutAirMassFlow);
1598 4 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMaxAvail = max(cBVAV.CoolOutAirMassFlow, cBVAV.HeatOutAirMassFlow);
1599 4 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMin = 0.0;
1600 4 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRateMinAvail = 0.0;
1601 4 : state.dataLoopNodes->Node(InNode).MassFlowRateMax = max(cBVAV.MaxCoolAirMassFlow, cBVAV.MaxHeatAirMassFlow);
1602 4 : state.dataLoopNodes->Node(InNode).MassFlowRateMaxAvail = max(cBVAV.MaxCoolAirMassFlow, cBVAV.MaxHeatAirMassFlow);
1603 4 : state.dataLoopNodes->Node(InNode).MassFlowRateMin = 0.0;
1604 4 : state.dataLoopNodes->Node(InNode).MassFlowRateMinAvail = 0.0;
1605 4 : state.dataLoopNodes->Node(OutNode).Temp = state.dataLoopNodes->Node(InNode).Temp;
1606 4 : state.dataLoopNodes->Node(OutNode).HumRat = state.dataLoopNodes->Node(InNode).HumRat;
1607 4 : state.dataLoopNodes->Node(OutNode).Enthalpy = state.dataLoopNodes->Node(InNode).Enthalpy;
1608 4 : state.dataLoopNodes->Node(cBVAV.MixerReliefAirNode) = state.dataLoopNodes->Node(MixerOutsideAirNode);
1609 4 : cBVAV.CheckFanFlow = false;
1610 4 : if (cBVAV.FanVolFlow > 0.0) {
1611 4 : cBVAV.HeatingSpeedRatio = cBVAV.MaxHeatAirVolFlow / cBVAV.FanVolFlow;
1612 4 : cBVAV.CoolingSpeedRatio = cBVAV.MaxCoolAirVolFlow / cBVAV.FanVolFlow;
1613 4 : cBVAV.NoHeatCoolSpeedRatio = cBVAV.MaxNoCoolHeatAirVolFlow / cBVAV.FanVolFlow;
1614 : }
1615 4 : }
1616 : }
1617 :
1618 17 : if (cBVAV.fanOpModeSched != nullptr) {
1619 0 : cBVAV.fanOp = (cBVAV.fanOpModeSched->getCurrentVal() == 0.0) ? HVAC::FanOp::Cycling : HVAC::FanOp::Continuous;
1620 : }
1621 :
1622 : // Returns load only for zones requesting cooling (heating). If in deadband, Qzoneload = 0.
1623 17 : if (FirstHVACIteration) cBVAV.modeChanged = false;
1624 17 : GetZoneLoads(state, CBVAVNum);
1625 :
1626 17 : OutsideAirMultiplier = (cBVAV.outAirSched != nullptr) ? cBVAV.outAirSched->getCurrentVal() : 1.0;
1627 :
1628 : // Set the inlet node mass flow rate
1629 17 : if (cBVAV.fanOp == HVAC::FanOp::Continuous) {
1630 : // constant fan mode
1631 1 : if (cBVAV.HeatCoolMode == HeatingMode) {
1632 1 : state.dataHVACUnitaryBypassVAV->CompOnMassFlow = cBVAV.MaxHeatAirMassFlow;
1633 1 : state.dataHVACUnitaryBypassVAV->CompOnFlowRatio = cBVAV.HeatingSpeedRatio;
1634 1 : state.dataHVACUnitaryBypassVAV->OACompOnMassFlow = cBVAV.HeatOutAirMassFlow * OutsideAirMultiplier;
1635 0 : } else if (cBVAV.HeatCoolMode == CoolingMode) {
1636 0 : state.dataHVACUnitaryBypassVAV->CompOnMassFlow = cBVAV.MaxCoolAirMassFlow;
1637 0 : state.dataHVACUnitaryBypassVAV->CompOnFlowRatio = cBVAV.CoolingSpeedRatio;
1638 0 : state.dataHVACUnitaryBypassVAV->OACompOnMassFlow = cBVAV.CoolOutAirMassFlow * OutsideAirMultiplier;
1639 : } else {
1640 0 : state.dataHVACUnitaryBypassVAV->CompOnMassFlow = cBVAV.MaxNoCoolHeatAirMassFlow;
1641 0 : state.dataHVACUnitaryBypassVAV->CompOnFlowRatio = cBVAV.NoHeatCoolSpeedRatio;
1642 0 : state.dataHVACUnitaryBypassVAV->OACompOnMassFlow = cBVAV.NoCoolHeatOutAirMassFlow * OutsideAirMultiplier;
1643 : }
1644 :
1645 1 : if (cBVAV.AirFlowControl == AirFlowCtrlMode::UseCompressorOnFlow) {
1646 1 : if (cBVAV.LastMode == HeatingMode) {
1647 1 : state.dataHVACUnitaryBypassVAV->CompOffMassFlow = cBVAV.MaxHeatAirMassFlow;
1648 1 : state.dataHVACUnitaryBypassVAV->CompOffFlowRatio = cBVAV.HeatingSpeedRatio;
1649 1 : state.dataHVACUnitaryBypassVAV->OACompOffMassFlow = cBVAV.HeatOutAirMassFlow * OutsideAirMultiplier;
1650 : } else {
1651 0 : state.dataHVACUnitaryBypassVAV->CompOffMassFlow = cBVAV.MaxCoolAirMassFlow;
1652 0 : state.dataHVACUnitaryBypassVAV->CompOffFlowRatio = cBVAV.CoolingSpeedRatio;
1653 0 : state.dataHVACUnitaryBypassVAV->OACompOffMassFlow = cBVAV.CoolOutAirMassFlow * OutsideAirMultiplier;
1654 : }
1655 : } else {
1656 0 : state.dataHVACUnitaryBypassVAV->CompOffMassFlow = cBVAV.MaxNoCoolHeatAirMassFlow;
1657 0 : state.dataHVACUnitaryBypassVAV->CompOffFlowRatio = cBVAV.NoHeatCoolSpeedRatio;
1658 0 : state.dataHVACUnitaryBypassVAV->OACompOffMassFlow = cBVAV.NoCoolHeatOutAirMassFlow * OutsideAirMultiplier;
1659 : }
1660 : } else {
1661 : // cycling fan mode
1662 16 : if (cBVAV.HeatCoolMode == HeatingMode) {
1663 4 : state.dataHVACUnitaryBypassVAV->CompOnMassFlow = cBVAV.MaxHeatAirMassFlow;
1664 4 : state.dataHVACUnitaryBypassVAV->CompOnFlowRatio = cBVAV.HeatingSpeedRatio;
1665 4 : state.dataHVACUnitaryBypassVAV->OACompOnMassFlow = cBVAV.HeatOutAirMassFlow * OutsideAirMultiplier;
1666 12 : } else if (cBVAV.HeatCoolMode == CoolingMode) {
1667 8 : state.dataHVACUnitaryBypassVAV->CompOnMassFlow = cBVAV.MaxCoolAirMassFlow;
1668 8 : state.dataHVACUnitaryBypassVAV->CompOnFlowRatio = cBVAV.CoolingSpeedRatio;
1669 8 : state.dataHVACUnitaryBypassVAV->OACompOnMassFlow = cBVAV.CoolOutAirMassFlow * OutsideAirMultiplier;
1670 : } else {
1671 4 : state.dataHVACUnitaryBypassVAV->CompOnMassFlow = cBVAV.MaxCoolAirMassFlow;
1672 4 : state.dataHVACUnitaryBypassVAV->CompOnFlowRatio = cBVAV.CoolingSpeedRatio;
1673 4 : state.dataHVACUnitaryBypassVAV->OACompOnMassFlow = cBVAV.CoolOutAirMassFlow * OutsideAirMultiplier;
1674 : }
1675 16 : state.dataHVACUnitaryBypassVAV->CompOffMassFlow = 0.0;
1676 16 : state.dataHVACUnitaryBypassVAV->CompOffFlowRatio = 0.0;
1677 16 : state.dataHVACUnitaryBypassVAV->OACompOffMassFlow = 0.0;
1678 : }
1679 :
1680 : // Check for correct control node at outlet of unit
1681 17 : if (cBVAV.HumRatMaxCheck) {
1682 5 : if (cBVAV.DehumidControlType != DehumidControl::None) {
1683 0 : if (state.dataLoopNodes->Node(OutNode).HumRatMax == DataLoopNode::SensedNodeFlagValue) {
1684 0 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
1685 0 : ShowWarningError(state, format("Unitary System:VAV:ChangeOverBypass = {}", cBVAV.Name));
1686 0 : ShowContinueError(state,
1687 : "Use SetpointManager:SingleZone:Humidity:Maximum to place a humidity setpoint at the air outlet node of "
1688 : "the unitary system.");
1689 0 : ShowContinueError(state, "Setting Dehumidification Control Type to None and simulation continues.");
1690 0 : cBVAV.DehumidControlType = DehumidControl::None;
1691 : } else {
1692 : // need call to EMS to check node
1693 0 : bool EMSSetPointCheck = false;
1694 0 : EMSManager::CheckIfNodeSetPointManagedByEMS(state, OutNode, HVAC::CtrlVarType::MaxHumRat, EMSSetPointCheck);
1695 0 : state.dataLoopNodes->NodeSetpointCheck(OutNode).needsSetpointChecking = false;
1696 0 : if (EMSSetPointCheck) {
1697 : // There is no plugin anyways, so we now we have a bad condition.
1698 0 : ShowWarningError(state, format("Unitary System:VAV:ChangeOverBypass = {}", cBVAV.Name));
1699 0 : ShowContinueError(state,
1700 : "Use SetpointManager:SingleZone:Humidity:Maximum to place a humidity setpoint at the air outlet node "
1701 : "of the unitary system.");
1702 0 : ShowContinueError(
1703 : state, "Or use an EMS Actuator to place a maximum humidity setpoint at the air outlet node of the unitary system.");
1704 0 : ShowContinueError(state, "Setting Dehumidification Control Type to None and simulation continues.");
1705 0 : cBVAV.DehumidControlType = DehumidControl::None;
1706 : }
1707 : }
1708 : }
1709 0 : cBVAV.HumRatMaxCheck = false;
1710 : } else {
1711 5 : cBVAV.HumRatMaxCheck = false;
1712 : }
1713 : }
1714 :
1715 : // Set the inlet node mass flow rate
1716 17 : if (cBVAV.availSched->getCurrentVal() > 0.0 && state.dataHVACUnitaryBypassVAV->CompOnMassFlow != 0.0) {
1717 16 : OnOffAirFlowRatio = 1.0;
1718 16 : if (FirstHVACIteration) {
1719 13 : state.dataLoopNodes->Node(cBVAV.AirInNode).MassFlowRate = state.dataHVACUnitaryBypassVAV->CompOnMassFlow;
1720 13 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate = state.dataHVACUnitaryBypassVAV->CompOnMassFlow;
1721 13 : state.dataLoopNodes->Node(cBVAV.MixerOutsideAirNode).MassFlowRate = state.dataHVACUnitaryBypassVAV->OACompOnMassFlow;
1722 13 : state.dataLoopNodes->Node(cBVAV.MixerReliefAirNode).MassFlowRate = state.dataHVACUnitaryBypassVAV->OACompOnMassFlow;
1723 13 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction = 0.0;
1724 13 : state.dataHVACUnitaryBypassVAV->PartLoadFrac = 0.0;
1725 : } else {
1726 3 : if (cBVAV.HeatCoolMode != 0) {
1727 3 : state.dataHVACUnitaryBypassVAV->PartLoadFrac = 1.0;
1728 : } else {
1729 0 : state.dataHVACUnitaryBypassVAV->PartLoadFrac = 0.0;
1730 : }
1731 3 : if (cBVAV.fanOp == HVAC::FanOp::Cycling) {
1732 3 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction = 0.0;
1733 : } else {
1734 0 : if (cBVAV.PlenumMixerInletAirNode == 0) {
1735 0 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction = max(
1736 0 : 0.0, 1.0 - (state.dataLoopNodes->Node(cBVAV.AirInNode).MassFlowRate / state.dataHVACUnitaryBypassVAV->CompOnMassFlow));
1737 : }
1738 : }
1739 : }
1740 : } else {
1741 1 : state.dataHVACUnitaryBypassVAV->PartLoadFrac = 0.0;
1742 1 : state.dataLoopNodes->Node(cBVAV.AirInNode).MassFlowRate = 0.0;
1743 1 : state.dataLoopNodes->Node(cBVAV.AirOutNode).MassFlowRate = 0.0;
1744 1 : state.dataLoopNodes->Node(cBVAV.AirOutNode).MassFlowRateMaxAvail = 0.0;
1745 :
1746 1 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate = 0.0;
1747 1 : state.dataLoopNodes->Node(cBVAV.MixerOutsideAirNode).MassFlowRate = 0.0;
1748 1 : state.dataLoopNodes->Node(cBVAV.MixerReliefAirNode).MassFlowRate = 0.0;
1749 :
1750 1 : OnOffAirFlowRatio = 1.0;
1751 1 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction = 0.0;
1752 : }
1753 :
1754 17 : CalcCBVAV(state, CBVAVNum, FirstHVACIteration, state.dataHVACUnitaryBypassVAV->PartLoadFrac, QSensUnitOut, OnOffAirFlowRatio, HXUnitOn);
1755 :
1756 : // If unit is scheduled OFF, setpoint is equal to inlet node temperature.
1757 17 : if (cBVAV.availSched->getCurrentVal() == 0.0) {
1758 0 : cBVAV.OutletTempSetPoint = state.dataLoopNodes->Node(InNode).Temp;
1759 0 : return;
1760 : }
1761 :
1762 17 : SetAverageAirFlow(state, CBVAVNum, OnOffAirFlowRatio);
1763 :
1764 17 : if (FirstHVACIteration) cBVAV.OutletTempSetPoint = CalcSetPointTempTarget(state, CBVAVNum);
1765 :
1766 : // The setpoint is used to control the DX coils at their respective outlet nodes (not the unit outlet), correct
1767 : // for fan heat for draw thru units only (fan heat is included at the outlet of each coil when blowthru is used)
1768 17 : cBVAV.CoilTempSetPoint = cBVAV.OutletTempSetPoint;
1769 17 : if (cBVAV.fanPlace == HVAC::FanPlace::DrawThru) {
1770 0 : cBVAV.CoilTempSetPoint -= (state.dataLoopNodes->Node(cBVAV.AirOutNode).Temp - state.dataLoopNodes->Node(cBVAV.FanInletNodeNum).Temp);
1771 : }
1772 :
1773 17 : if (FirstHVACIteration) {
1774 14 : if (cBVAV.HeatCoilType == HVAC::CoilType::HeatingWater) {
1775 0 : WaterCoils::SimulateWaterCoilComponents(state, cBVAV.HeatCoilName, FirstHVACIteration, cBVAV.HeatCoilIndex);
1776 :
1777 : // set air-side and steam-side mass flow rates
1778 0 : state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).MassFlowRate = state.dataHVACUnitaryBypassVAV->CompOnMassFlow;
1779 0 : mdot = cBVAV.MaxHeatCoilFluidFlow;
1780 0 : PlantUtilities::SetComponentFlowRate(state, mdot, cBVAV.CoilControlNode, cBVAV.CoilOutletNode, cBVAV.plantLoc);
1781 :
1782 : // simulate water coil to find operating capacity
1783 0 : WaterCoils::SimulateWaterCoilComponents(state, cBVAV.HeatCoilName, FirstHVACIteration, cBVAV.HeatCoilIndex, QCoilActual);
1784 0 : cBVAV.DesignSuppHeatingCapacity = QCoilActual;
1785 :
1786 : } // from IF(MSHeatPump(MSHeatPumpNum)%SuppHeatCoilType == HVAC::Coil_HeatingWater) THEN
1787 :
1788 14 : if (cBVAV.HeatCoilType == HVAC::CoilType::HeatingSteam) {
1789 :
1790 : // set air-side and steam-side mass flow rates
1791 0 : state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).MassFlowRate = state.dataHVACUnitaryBypassVAV->CompOnMassFlow;
1792 0 : mdot = cBVAV.MaxHeatCoilFluidFlow;
1793 0 : PlantUtilities::SetComponentFlowRate(state, mdot, cBVAV.CoilControlNode, cBVAV.CoilOutletNode, cBVAV.plantLoc);
1794 :
1795 : // simulate steam coil to find operating capacity
1796 0 : SteamCoils::SimulateSteamCoilComponents(state,
1797 : cBVAV.HeatCoilName,
1798 : FirstHVACIteration,
1799 0 : cBVAV.HeatCoilIndex,
1800 0 : 1.0,
1801 : QCoilActual); // QCoilReq, simulate any load > 0 to get max capacity of steam coil
1802 0 : cBVAV.DesignSuppHeatingCapacity = QCoilActual;
1803 :
1804 : } // from IF(cBVAV%HeatCoilType == HVAC::Coil_HeatingSteam) THEN
1805 : } // from IF( FirstHVACIteration ) THEN
1806 :
1807 17 : if ((cBVAV.HeatCoolMode == 0 && cBVAV.fanOp == HVAC::FanOp::Cycling) || state.dataHVACUnitaryBypassVAV->CompOnMassFlow == 0.0) {
1808 4 : state.dataHVACUnitaryBypassVAV->PartLoadFrac = 0.0;
1809 4 : state.dataLoopNodes->Node(cBVAV.AirInNode).MassFlowRate = 0.0;
1810 4 : state.dataLoopNodes->Node(cBVAV.AirOutNode).MassFlowRateMaxAvail = 0.0;
1811 4 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate = 0.0;
1812 4 : state.dataLoopNodes->Node(cBVAV.MixerOutsideAirNode).MassFlowRate = 0.0;
1813 4 : state.dataLoopNodes->Node(cBVAV.MixerReliefAirNode).MassFlowRate = 0.0;
1814 : }
1815 : }
1816 :
1817 4 : void SizeCBVAV(EnergyPlusData &state, int const CBVAVNum) // Index to CBVAV system
1818 : {
1819 :
1820 : // SUBROUTINE INFORMATION:
1821 : // AUTHOR Richard Raustad
1822 : // DATE WRITTEN July 2006
1823 :
1824 : // PURPOSE OF THIS SUBROUTINE:
1825 : // This subroutine is for sizing changeover-bypass VAV components.
1826 :
1827 : // METHODOLOGY EMPLOYED:
1828 : // Obtains flow rates from the zone sizing arrays.
1829 :
1830 4 : int curSysNum = state.dataSize->CurSysNum;
1831 4 : int curOASysNum = state.dataSize->CurOASysNum;
1832 :
1833 4 : auto &cBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
1834 :
1835 4 : if (curSysNum > 0 && curOASysNum == 0) {
1836 4 : state.dataAirSystemsData->PrimaryAirSystems(curSysNum).supFanNum = cBVAV.FanIndex;
1837 4 : state.dataAirSystemsData->PrimaryAirSystems(curSysNum).supFanType = cBVAV.fanType;
1838 4 : state.dataAirSystemsData->PrimaryAirSystems(curSysNum).supFanPlace = cBVAV.fanPlace;
1839 : }
1840 :
1841 4 : if (cBVAV.MaxCoolAirVolFlow == DataSizing::AutoSize) {
1842 :
1843 1 : if (curSysNum > 0) {
1844 :
1845 1 : CheckSysSizing(state, cBVAV.UnitType, cBVAV.Name);
1846 1 : cBVAV.MaxCoolAirVolFlow = state.dataSize->FinalSysSizing(curSysNum).DesMainVolFlow;
1847 1 : if (cBVAV.FanVolFlow < cBVAV.MaxCoolAirVolFlow && cBVAV.FanVolFlow != DataSizing::AutoSize) {
1848 0 : cBVAV.MaxCoolAirVolFlow = cBVAV.FanVolFlow;
1849 0 : ShowWarningError(state, format("{} \"{}\"", cBVAV.UnitType, cBVAV.Name));
1850 0 : ShowContinueError(state,
1851 : "The CBVAV system supply air fan air flow rate is less than the autosized value for the maximum air flow rate "
1852 : "in cooling mode. Consider autosizing the fan for this simulation.");
1853 0 : ShowContinueError(
1854 : state, "The maximum air flow rate in cooling mode is reset to the supply air fan flow rate and the simulation continues.");
1855 : }
1856 1 : if (cBVAV.MaxCoolAirVolFlow < HVAC::SmallAirVolFlow) {
1857 0 : cBVAV.MaxCoolAirVolFlow = 0.0;
1858 : }
1859 1 : BaseSizer::reportSizerOutput(state, cBVAV.UnitType, cBVAV.Name, "maximum cooling air flow rate [m3/s]", cBVAV.MaxCoolAirVolFlow);
1860 : }
1861 : }
1862 :
1863 4 : if (cBVAV.MaxHeatAirVolFlow == DataSizing::AutoSize) {
1864 :
1865 1 : if (curSysNum > 0) {
1866 :
1867 1 : CheckSysSizing(state, cBVAV.UnitType, cBVAV.Name);
1868 1 : cBVAV.MaxHeatAirVolFlow = state.dataSize->FinalSysSizing(curSysNum).DesMainVolFlow;
1869 1 : if (cBVAV.FanVolFlow < cBVAV.MaxHeatAirVolFlow && cBVAV.FanVolFlow != DataSizing::AutoSize) {
1870 0 : cBVAV.MaxHeatAirVolFlow = cBVAV.FanVolFlow;
1871 0 : ShowWarningError(state, format("{} \"{}\"", cBVAV.UnitType, cBVAV.Name));
1872 0 : ShowContinueError(state,
1873 : "The CBVAV system supply air fan air flow rate is less than the autosized value for the maximum air flow rate "
1874 : "in heating mode. Consider autosizing the fan for this simulation.");
1875 0 : ShowContinueError(
1876 : state, "The maximum air flow rate in heating mode is reset to the supply air fan flow rate and the simulation continues.");
1877 : }
1878 1 : if (cBVAV.MaxHeatAirVolFlow < HVAC::SmallAirVolFlow) {
1879 0 : cBVAV.MaxHeatAirVolFlow = 0.0;
1880 : }
1881 1 : BaseSizer::reportSizerOutput(state, cBVAV.UnitType, cBVAV.Name, "maximum heating air flow rate [m3/s]", cBVAV.MaxHeatAirVolFlow);
1882 : }
1883 : }
1884 :
1885 4 : if (cBVAV.MaxNoCoolHeatAirVolFlow == DataSizing::AutoSize) {
1886 :
1887 1 : if (curSysNum > 0) {
1888 :
1889 1 : CheckSysSizing(state, cBVAV.UnitType, cBVAV.Name);
1890 1 : cBVAV.MaxNoCoolHeatAirVolFlow = state.dataSize->FinalSysSizing(curSysNum).DesMainVolFlow;
1891 1 : if (cBVAV.FanVolFlow < cBVAV.MaxNoCoolHeatAirVolFlow && cBVAV.FanVolFlow != DataSizing::AutoSize) {
1892 0 : cBVAV.MaxNoCoolHeatAirVolFlow = cBVAV.FanVolFlow;
1893 0 : ShowWarningError(state, format("{} \"{}\"", cBVAV.UnitType, cBVAV.Name));
1894 0 : ShowContinueError(state,
1895 : "The CBVAV system supply air fan air flow rate is less than the autosized value for the maximum air flow rate "
1896 : "when no heating or cooling is needed. Consider autosizing the fan for this simulation.");
1897 0 : ShowContinueError(state,
1898 : "The maximum air flow rate when no heating or cooling is needed is reset to the supply air fan flow rate and "
1899 : "the simulation continues.");
1900 : }
1901 1 : if (cBVAV.MaxNoCoolHeatAirVolFlow < HVAC::SmallAirVolFlow) {
1902 0 : cBVAV.MaxNoCoolHeatAirVolFlow = 0.0;
1903 : }
1904 :
1905 1 : BaseSizer::reportSizerOutput(
1906 : state, cBVAV.UnitType, cBVAV.Name, "maximum air flow rate when compressor/coil is off [m3/s]", cBVAV.MaxNoCoolHeatAirVolFlow);
1907 : }
1908 : }
1909 :
1910 4 : if (cBVAV.CoolOutAirVolFlow == DataSizing::AutoSize) {
1911 :
1912 1 : if (curSysNum > 0) {
1913 :
1914 1 : CheckSysSizing(state, cBVAV.UnitType, cBVAV.Name);
1915 1 : cBVAV.CoolOutAirVolFlow = state.dataSize->FinalSysSizing(curSysNum).DesOutAirVolFlow;
1916 1 : if (cBVAV.FanVolFlow < cBVAV.CoolOutAirVolFlow && cBVAV.FanVolFlow != DataSizing::AutoSize) {
1917 0 : cBVAV.CoolOutAirVolFlow = cBVAV.FanVolFlow;
1918 0 : ShowWarningError(state, format("{} \"{}\"", cBVAV.UnitType, cBVAV.Name));
1919 0 : ShowContinueError(state,
1920 : "The CBVAV system supply air fan air flow rate is less than the autosized value for the outdoor air flow rate "
1921 : "in cooling mode. Consider autosizing the fan for this simulation.");
1922 0 : ShowContinueError(
1923 : state, "The outdoor air flow rate in cooling mode is reset to the supply air fan flow rate and the simulation continues.");
1924 : }
1925 1 : if (cBVAV.CoolOutAirVolFlow < HVAC::SmallAirVolFlow) {
1926 0 : cBVAV.CoolOutAirVolFlow = 0.0;
1927 : }
1928 1 : BaseSizer::reportSizerOutput(
1929 : state, cBVAV.UnitType, cBVAV.Name, "maximum outside air flow rate in cooling [m3/s]", cBVAV.CoolOutAirVolFlow);
1930 : }
1931 : }
1932 :
1933 4 : if (cBVAV.HeatOutAirVolFlow == DataSizing::AutoSize) {
1934 :
1935 1 : if (curSysNum > 0) {
1936 :
1937 1 : CheckSysSizing(state, cBVAV.UnitType, cBVAV.Name);
1938 1 : cBVAV.HeatOutAirVolFlow = state.dataSize->FinalSysSizing(curSysNum).DesOutAirVolFlow;
1939 1 : if (cBVAV.FanVolFlow < cBVAV.HeatOutAirVolFlow && cBVAV.FanVolFlow != DataSizing::AutoSize) {
1940 0 : cBVAV.HeatOutAirVolFlow = cBVAV.FanVolFlow;
1941 0 : ShowContinueError(state,
1942 : "The CBVAV system supply air fan air flow rate is less than the autosized value for the outdoor air flow rate "
1943 : "in heating mode. Consider autosizing the fan for this simulation.");
1944 0 : ShowContinueError(
1945 : state, "The outdoor air flow rate in heating mode is reset to the supply air fan flow rate and the simulation continues.");
1946 : }
1947 1 : if (cBVAV.HeatOutAirVolFlow < HVAC::SmallAirVolFlow) {
1948 0 : cBVAV.HeatOutAirVolFlow = 0.0;
1949 : }
1950 1 : BaseSizer::reportSizerOutput(
1951 : state, cBVAV.UnitType, cBVAV.Name, "maximum outdoor air flow rate in heating [m3/s]", cBVAV.CoolOutAirVolFlow);
1952 : }
1953 : }
1954 :
1955 4 : if (cBVAV.NoCoolHeatOutAirVolFlow == DataSizing::AutoSize) {
1956 :
1957 1 : if (curSysNum > 0) {
1958 :
1959 1 : CheckSysSizing(state, cBVAV.UnitType, cBVAV.Name);
1960 1 : cBVAV.NoCoolHeatOutAirVolFlow = state.dataSize->FinalSysSizing(curSysNum).DesOutAirVolFlow;
1961 1 : if (cBVAV.FanVolFlow < cBVAV.NoCoolHeatOutAirVolFlow && cBVAV.FanVolFlow != DataSizing::AutoSize) {
1962 0 : cBVAV.NoCoolHeatOutAirVolFlow = cBVAV.FanVolFlow;
1963 0 : ShowContinueError(state,
1964 : "The CBVAV system supply air fan air flow rate is less than the autosized value for the outdoor air flow rate "
1965 : "when no heating or cooling is needed. Consider autosizing the fan for this simulation.");
1966 0 : ShowContinueError(state,
1967 : "The outdoor air flow rate when no heating or cooling is needed is reset to the supply air fan flow rate and "
1968 : "the simulation continues.");
1969 : }
1970 1 : if (cBVAV.NoCoolHeatOutAirVolFlow < HVAC::SmallAirVolFlow) {
1971 0 : cBVAV.NoCoolHeatOutAirVolFlow = 0.0;
1972 : }
1973 1 : BaseSizer::reportSizerOutput(
1974 : state, cBVAV.UnitType, cBVAV.Name, "maximum outdoor air flow rate when compressor is off [m3/s]", cBVAV.NoCoolHeatOutAirVolFlow);
1975 : }
1976 : }
1977 4 : }
1978 :
1979 7 : void ControlCBVAVOutput(EnergyPlusData &state,
1980 : int const CBVAVNum, // Index to CBVAV system
1981 : bool const FirstHVACIteration, // Flag for 1st HVAC iteration
1982 : Real64 &PartLoadFrac, // Unit part load fraction
1983 : Real64 &OnOffAirFlowRatio, // Ratio of compressor ON airflow to AVERAGE airflow over timestep
1984 : bool const HXUnitOn // flag to enable heat exchanger
1985 : )
1986 : {
1987 :
1988 : // SUBROUTINE INFORMATION:
1989 : // AUTHOR Richard Raustad
1990 : // DATE WRITTEN July 2006
1991 :
1992 : // PURPOSE OF THIS SUBROUTINE:
1993 : // Determine the part load fraction of the CBVAV system for this time step.
1994 :
1995 : // METHODOLOGY EMPLOYED:
1996 : // Use RegulaFalsi technique to iterate on part-load ratio until convergence is achieved.
1997 :
1998 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1999 7 : Real64 FullOutput = 0; // Unit full output when compressor is operating [W]
2000 7 : PartLoadFrac = 0.0;
2001 :
2002 7 : auto &cBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2003 :
2004 7 : if (cBVAV.availSched->getCurrentVal() == 0.0) return;
2005 :
2006 : // Get operating result
2007 7 : PartLoadFrac = 1.0;
2008 7 : CalcCBVAV(state, CBVAVNum, FirstHVACIteration, PartLoadFrac, FullOutput, OnOffAirFlowRatio, HXUnitOn);
2009 :
2010 11 : if ((state.dataLoopNodes->Node(cBVAV.AirOutNode).Temp - cBVAV.OutletTempSetPoint) > HVAC::SmallTempDiff && cBVAV.HeatCoolMode > 0 &&
2011 4 : PartLoadFrac < 1.0) {
2012 0 : CalcCBVAV(state, CBVAVNum, FirstHVACIteration, PartLoadFrac, FullOutput, OnOffAirFlowRatio, HXUnitOn);
2013 : }
2014 : }
2015 :
2016 30 : void CalcCBVAV(EnergyPlusData &state,
2017 : int const CBVAVNum, // Unit index in fan coil array
2018 : bool const FirstHVACIteration, // Flag for 1st HVAC iteration
2019 : Real64 &PartLoadFrac, // Compressor part load fraction
2020 : Real64 &LoadMet, // Load met by unit (W)
2021 : Real64 &OnOffAirFlowRatio, // Ratio of compressor ON airflow to AVERAGE airflow over timestep
2022 : bool const HXUnitOn // flag to enable heat exchanger
2023 : )
2024 : {
2025 :
2026 : // SUBROUTINE INFORMATION:
2027 : // AUTHOR Richard Raustad
2028 : // DATE WRITTEN July 2006
2029 :
2030 : // PURPOSE OF THIS SUBROUTINE:
2031 : // Simulate the components making up the changeover-bypass VAV system.
2032 :
2033 : // METHODOLOGY EMPLOYED:
2034 : // Simulates the unit components sequentially in the air flow direction.
2035 :
2036 : // SUBROUTINE PARAMETER DEFINITIONS:
2037 30 : int constexpr MaxIte(500); // Maximum number of iterations
2038 :
2039 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2040 : Real64 MinHumRat; // Minimum humidity ratio for sensible capacity calculation (kg/kg)
2041 : int SolFla; // Flag of RegulaFalsi solver
2042 : Real64 QHeater; // Load to be met by heater [W]
2043 : Real64 QHeaterActual; // actual heating load met [W]
2044 : Real64 CpAir; // Specific heat of air [J/kg-K]
2045 : Real64 ApproachTemp;
2046 : Real64 DesiredDewPoint;
2047 : Real64 OutdoorDryBulbTemp; // Dry-bulb temperature at outdoor condenser
2048 : Real64 OutdoorBaroPress; // Barometric pressure at outdoor condenser
2049 :
2050 30 : auto &cBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2051 :
2052 30 : int OutletNode = cBVAV.AirOutNode;
2053 30 : int InletNode = cBVAV.AirInNode;
2054 30 : if (cBVAV.CondenserNodeNum > 0) {
2055 0 : OutdoorDryBulbTemp = state.dataLoopNodes->Node(cBVAV.CondenserNodeNum).Temp;
2056 0 : OutdoorBaroPress = state.dataLoopNodes->Node(cBVAV.CondenserNodeNum).Press;
2057 : } else {
2058 30 : OutdoorDryBulbTemp = state.dataEnvrn->OutDryBulbTemp;
2059 30 : OutdoorBaroPress = state.dataEnvrn->OutBaroPress;
2060 : }
2061 :
2062 30 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = 0.0;
2063 :
2064 : // Bypass excess system air through bypass duct and calculate new mixed air conditions at OA mixer inlet node
2065 30 : if (cBVAV.plenumIndex > 0 || cBVAV.mixerIndex > 0) {
2066 13 : Real64 saveMixerInletAirNodeFlow = state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate;
2067 13 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode) = state.dataLoopNodes->Node(InletNode);
2068 13 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate = saveMixerInletAirNodeFlow;
2069 13 : } else {
2070 17 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).Temp =
2071 17 : (1.0 - state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction) * state.dataLoopNodes->Node(InletNode).Temp +
2072 17 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction * state.dataLoopNodes->Node(OutletNode).Temp;
2073 17 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).HumRat =
2074 17 : (1.0 - state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction) * state.dataLoopNodes->Node(InletNode).HumRat +
2075 17 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction * state.dataLoopNodes->Node(OutletNode).HumRat;
2076 17 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).Enthalpy = Psychrometrics::PsyHFnTdbW(
2077 17 : state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).Temp, state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).HumRat);
2078 : }
2079 30 : MixedAir::SimOAMixer(state, cBVAV.OAMixName, cBVAV.OAMixIndex);
2080 :
2081 30 : if (cBVAV.fanPlace == HVAC::FanPlace::BlowThru) {
2082 2 : state.dataFans->fans(cBVAV.FanIndex)
2083 2 : ->simulate(state, FirstHVACIteration, state.dataHVACUnitaryBypassVAV->FanSpeedRatio, _, 1.0 / OnOffAirFlowRatio);
2084 : }
2085 : // Simulate cooling coil if zone load is negative (cooling load)
2086 30 : if (cBVAV.HeatCoolMode == CoolingMode) {
2087 16 : if (OutdoorDryBulbTemp >= cBVAV.MinOATCompressor) {
2088 16 : switch (cBVAV.CoolCoilType) {
2089 0 : case HVAC::CoilType::DXCoolingHXAssisted: {
2090 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
2091 : cBVAV.DXCoolCoilName,
2092 : FirstHVACIteration,
2093 : HVAC::CompressorOp::On,
2094 : PartLoadFrac,
2095 0 : cBVAV.CoolCoilCompIndex,
2096 : HVAC::FanOp::Continuous,
2097 : HXUnitOn);
2098 0 : if (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp <= cBVAV.CoilTempSetPoint) {
2099 : // If coil inlet temp is already below the setpoint, simulated with coil off
2100 0 : PartLoadFrac = 0.0;
2101 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
2102 : cBVAV.DXCoolCoilName,
2103 : FirstHVACIteration,
2104 : HVAC::CompressorOp::Off,
2105 : PartLoadFrac,
2106 0 : cBVAV.CoolCoilCompIndex,
2107 : HVAC::FanOp::Continuous,
2108 : HXUnitOn);
2109 0 : } else if (state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp < cBVAV.CoilTempSetPoint) {
2110 0 : auto f = [&state, CBVAVNum, FirstHVACIteration, HXUnitOn](Real64 const PartLoadFrac) {
2111 0 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2112 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
2113 : thisCBVAV.DXCoolCoilName,
2114 : FirstHVACIteration,
2115 : HVAC::CompressorOp::On,
2116 : PartLoadFrac,
2117 0 : thisCBVAV.CoolCoilCompIndex,
2118 : HVAC::FanOp::Continuous,
2119 0 : HXUnitOn);
2120 :
2121 0 : Real64 OutletAirTemp = state.dataLoopNodes->Node(thisCBVAV.DXCoilOutletNode).Temp;
2122 0 : return thisCBVAV.CoilTempSetPoint - OutletAirTemp;
2123 0 : };
2124 0 : General::SolveRoot(state, HVAC::SmallTempDiff, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
2125 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
2126 : cBVAV.DXCoolCoilName,
2127 : FirstHVACIteration,
2128 : HVAC::CompressorOp::On,
2129 : PartLoadFrac,
2130 0 : cBVAV.CoolCoilCompIndex,
2131 : HVAC::FanOp::Continuous,
2132 : HXUnitOn);
2133 0 : if (SolFla == -1 && !state.dataGlobal->WarmupFlag) {
2134 0 : if (cBVAV.HXDXIterationExceeded < 1) {
2135 0 : ++cBVAV.HXDXIterationExceeded;
2136 0 : ShowWarningError(state,
2137 0 : format("Iteration limit exceeded calculating HX assisted DX unit part-load ratio, for unit = {}",
2138 0 : cBVAV.DXCoolCoilName));
2139 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
2140 0 : ShowContinueErrorTimeStamp(
2141 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
2142 : } else {
2143 0 : ShowRecurringWarningErrorAtEnd(
2144 : state,
2145 0 : cBVAV.Name + ", Iteration limit exceeded for HX assisted DX unit part-load ratio error continues.",
2146 0 : cBVAV.HXDXIterationExceededIndex,
2147 : PartLoadFrac,
2148 : PartLoadFrac);
2149 : }
2150 0 : } else if (SolFla == -2 && !state.dataGlobal->WarmupFlag) {
2151 0 : PartLoadFrac = max(0.0,
2152 : min(1.0,
2153 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp - cBVAV.CoilTempSetPoint) /
2154 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp -
2155 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp)));
2156 0 : if (cBVAV.HXDXIterationFailed < 1) {
2157 0 : ++cBVAV.HXDXIterationFailed;
2158 0 : ShowSevereError(
2159 : state,
2160 0 : format("HX assisted DX unit part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
2161 0 : cBVAV.DXCoolCoilName));
2162 0 : ShowContinueErrorTimeStamp(
2163 : state,
2164 0 : format("An estimated part-load ratio of {:.3R}will be used and the simulation continues. Occurrence info:",
2165 : PartLoadFrac));
2166 : } else {
2167 0 : ShowRecurringWarningErrorAtEnd(state,
2168 0 : cBVAV.Name +
2169 : ", Part-load ratio calculation failed for HX assisted DX unit error continues.",
2170 0 : cBVAV.HXDXIterationFailedIndex,
2171 : PartLoadFrac,
2172 : PartLoadFrac);
2173 : }
2174 : }
2175 : }
2176 0 : } break;
2177 16 : case HVAC::CoilType::DXCoolingSingleSpeed: {
2178 32 : DXCoils::SimDXCoil(state,
2179 : cBVAV.DXCoolCoilName,
2180 : HVAC::CompressorOp::On,
2181 : FirstHVACIteration,
2182 16 : cBVAV.CoolCoilCompIndex,
2183 : HVAC::FanOp::Continuous,
2184 : PartLoadFrac,
2185 : OnOffAirFlowRatio);
2186 16 : if (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp <= cBVAV.CoilTempSetPoint) {
2187 : // If coil inlet temp is already below the setpoint, simulated with coil off
2188 1 : PartLoadFrac = 0.0;
2189 2 : DXCoils::SimDXCoil(state,
2190 : cBVAV.DXCoolCoilName,
2191 : HVAC::CompressorOp::On,
2192 : FirstHVACIteration,
2193 1 : cBVAV.CoolCoilCompIndex,
2194 : HVAC::FanOp::Continuous,
2195 : PartLoadFrac,
2196 : OnOffAirFlowRatio);
2197 15 : } else if (state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp < cBVAV.CoilTempSetPoint) {
2198 25 : auto f = [&state, CBVAVNum, OnOffAirFlowRatio](Real64 const PartLoadFrac) {
2199 20 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2200 40 : DXCoils::CalcDoe2DXCoil(state,
2201 : thisCBVAV.CoolCoilCompIndex,
2202 : HVAC::CompressorOp::On,
2203 : false,
2204 : PartLoadFrac,
2205 : HVAC::FanOp::Continuous,
2206 : _,
2207 20 : OnOffAirFlowRatio);
2208 20 : Real64 OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(thisCBVAV.CoolCoilCompIndex);
2209 20 : return thisCBVAV.CoilTempSetPoint - OutletAirTemp;
2210 5 : };
2211 5 : General::SolveRoot(state, HVAC::SmallTempDiff, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
2212 10 : DXCoils::SimDXCoil(state,
2213 : cBVAV.DXCoolCoilName,
2214 : HVAC::CompressorOp::On,
2215 : FirstHVACIteration,
2216 5 : cBVAV.CoolCoilCompIndex,
2217 : HVAC::FanOp::Continuous,
2218 : PartLoadFrac,
2219 : OnOffAirFlowRatio);
2220 5 : if (SolFla == -1 && !state.dataGlobal->WarmupFlag) {
2221 0 : if (cBVAV.DXIterationExceeded < 1) {
2222 0 : ++cBVAV.DXIterationExceeded;
2223 0 : ShowWarningError(
2224 : state,
2225 0 : format("Iteration limit exceeded calculating DX unit part-load ratio, for unit = {}", cBVAV.DXCoolCoilName));
2226 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
2227 0 : ShowContinueErrorTimeStamp(
2228 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
2229 : } else {
2230 0 : ShowRecurringWarningErrorAtEnd(
2231 : state,
2232 0 : cBVAV.Name + ", Iteration limit exceeded for DX unit part-load ratio calculation error continues.",
2233 0 : cBVAV.DXIterationExceededIndex,
2234 : PartLoadFrac,
2235 : PartLoadFrac);
2236 : }
2237 5 : } else if (SolFla == -2 && !state.dataGlobal->WarmupFlag) {
2238 0 : PartLoadFrac = max(0.0,
2239 : min(1.0,
2240 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp - cBVAV.CoilTempSetPoint) /
2241 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp -
2242 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp)));
2243 0 : if (cBVAV.DXIterationFailed < 1) {
2244 0 : ++cBVAV.DXIterationFailed;
2245 0 : ShowSevereError(state,
2246 0 : format("DX unit part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
2247 0 : cBVAV.DXCoolCoilName));
2248 0 : ShowContinueErrorTimeStamp(
2249 : state,
2250 0 : format("An estimated part-load ratio of {:.3R}will be used and the simulation continues. Occurrence info:",
2251 : PartLoadFrac));
2252 : } else {
2253 0 : ShowRecurringWarningErrorAtEnd(state,
2254 0 : cBVAV.Name + ", Part-load ratio calculation failed for DX unit error continues.",
2255 0 : cBVAV.DXIterationFailedIndex,
2256 : PartLoadFrac,
2257 : PartLoadFrac);
2258 : }
2259 : }
2260 : }
2261 16 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(cBVAV.DXCoolCoilIndexNum);
2262 16 : } break;
2263 0 : case HVAC::CoilType::CoolingAirToAirVariableSpeed: {
2264 0 : Real64 QZnReq(0.0); // Zone load (W), input to variable-speed DX coil
2265 0 : Real64 QLatReq(0.0); // Zone latent load, input to variable-speed DX coil
2266 0 : Real64 LocalOnOffAirFlowRatio(1.0); // ratio of compressor on flow to average flow over time step
2267 0 : Real64 LocalPartLoadFrac(0.0);
2268 0 : Real64 SpeedRatio(0.0);
2269 0 : int SpeedNum(1);
2270 0 : bool errorFlag(false);
2271 0 : int maxNumSpeeds = VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, cBVAV.DXCoolCoilName, errorFlag);
2272 0 : Real64 DesOutTemp = cBVAV.CoilTempSetPoint;
2273 : // Get no load result
2274 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2275 : cBVAV.DXCoolCoilName,
2276 0 : cBVAV.CoolCoilCompIndex,
2277 : HVAC::FanOp::Continuous,
2278 : HVAC::CompressorOp::Off,
2279 : LocalPartLoadFrac,
2280 : SpeedNum,
2281 : SpeedRatio,
2282 : QZnReq,
2283 : QLatReq);
2284 :
2285 0 : Real64 NoOutput = state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).MassFlowRate *
2286 0 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp,
2287 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat) -
2288 0 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp,
2289 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat));
2290 :
2291 : // Get full load result
2292 0 : LocalPartLoadFrac = 1.0;
2293 0 : SpeedNum = maxNumSpeeds;
2294 0 : SpeedRatio = 1.0;
2295 0 : QZnReq = 0.001; // to indicate the coil is running
2296 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2297 : cBVAV.DXCoolCoilName,
2298 0 : cBVAV.CoolCoilCompIndex,
2299 : HVAC::FanOp::Continuous,
2300 : HVAC::CompressorOp::On,
2301 : LocalPartLoadFrac,
2302 : SpeedNum,
2303 : SpeedRatio,
2304 : QZnReq,
2305 : QLatReq);
2306 :
2307 0 : Real64 FullOutput = state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).MassFlowRate *
2308 0 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp,
2309 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat) -
2310 0 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp,
2311 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat));
2312 0 : Real64 ReqOutput = state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).MassFlowRate *
2313 0 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat) -
2314 0 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp,
2315 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat));
2316 :
2317 0 : Real64 loadAccuracy(0.001); // Watts, power
2318 0 : Real64 tempAccuracy(0.001); // delta C, temperature
2319 0 : if ((NoOutput - ReqOutput) < loadAccuracy) { // IF NoOutput is lower than (more cooling than required) or very near
2320 : // the ReqOutput, do not run the compressor
2321 0 : LocalPartLoadFrac = 0.0;
2322 0 : SpeedNum = 1;
2323 0 : SpeedRatio = 0.0;
2324 0 : QZnReq = 0.0;
2325 : // Get no load result
2326 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2327 : cBVAV.DXCoolCoilName,
2328 0 : cBVAV.CoolCoilCompIndex,
2329 : HVAC::FanOp::Continuous,
2330 : HVAC::CompressorOp::Off,
2331 : LocalPartLoadFrac,
2332 : SpeedNum,
2333 : SpeedRatio,
2334 : QZnReq,
2335 : QLatReq);
2336 :
2337 0 : } else if ((FullOutput - ReqOutput) > loadAccuracy) {
2338 : // If the FullOutput is greater than (insufficient cooling) or very near the ReqOutput,
2339 : // run the compressor at LocalPartLoadFrac = 1.
2340 0 : LocalPartLoadFrac = 1.0;
2341 0 : SpeedNum = maxNumSpeeds;
2342 0 : SpeedRatio = 1.0;
2343 : // Else find the PLR to meet the load
2344 : } else {
2345 : // OutletTempDXCoil is the full capacity outlet temperature at LocalPartLoadFrac = 1 from the CALL above. If this
2346 : // temp is greater than the desired outlet temp, then run the compressor at LocalPartLoadFrac = 1, otherwise find
2347 : // the operating PLR.
2348 0 : Real64 OutletTempDXCoil = state.dataVariableSpeedCoils->VarSpeedCoil(cBVAV.CoolCoilCompIndex).OutletAirDBTemp;
2349 0 : if (OutletTempDXCoil > DesOutTemp) {
2350 0 : LocalPartLoadFrac = 1.0;
2351 0 : SpeedNum = maxNumSpeeds;
2352 0 : SpeedRatio = 1.0;
2353 : } else {
2354 : // run at lowest speed
2355 0 : LocalPartLoadFrac = 1.0;
2356 0 : SpeedNum = 1;
2357 0 : SpeedRatio = 1.0;
2358 0 : QZnReq = 0.001; // to indicate the coil is running
2359 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2360 : cBVAV.DXCoolCoilName,
2361 0 : cBVAV.CoolCoilCompIndex,
2362 : HVAC::FanOp::Continuous,
2363 : HVAC::CompressorOp::On,
2364 : LocalPartLoadFrac,
2365 : SpeedNum,
2366 : SpeedRatio,
2367 : QZnReq,
2368 : QLatReq,
2369 : LocalOnOffAirFlowRatio);
2370 :
2371 0 : Real64 TempSpeedOut = state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).MassFlowRate *
2372 0 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp,
2373 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat) -
2374 0 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp,
2375 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat));
2376 : Real64 TempSpeedReqst =
2377 0 : state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).MassFlowRate *
2378 0 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat) -
2379 0 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp,
2380 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat));
2381 :
2382 0 : if ((TempSpeedOut - TempSpeedReqst) > tempAccuracy) {
2383 : // Check to see which speed to meet the load
2384 0 : LocalPartLoadFrac = 1.0;
2385 0 : SpeedRatio = 1.0;
2386 0 : for (int I = 2; I <= maxNumSpeeds; ++I) {
2387 0 : SpeedNum = I;
2388 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2389 : cBVAV.DXCoolCoilName,
2390 0 : cBVAV.CoolCoilCompIndex,
2391 : HVAC::FanOp::Continuous,
2392 : HVAC::CompressorOp::On,
2393 : LocalPartLoadFrac,
2394 : SpeedNum,
2395 : SpeedRatio,
2396 : QZnReq,
2397 : QLatReq,
2398 : LocalOnOffAirFlowRatio);
2399 :
2400 0 : TempSpeedOut = state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).MassFlowRate *
2401 0 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp,
2402 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat) -
2403 0 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp,
2404 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat));
2405 0 : TempSpeedReqst =
2406 0 : state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).MassFlowRate *
2407 0 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat) -
2408 0 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp,
2409 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat));
2410 :
2411 0 : if ((TempSpeedOut - TempSpeedReqst) < tempAccuracy) {
2412 0 : SpeedNum = I;
2413 0 : break;
2414 : }
2415 : }
2416 : // now find the speed ratio for the found speednum
2417 0 : auto f = [&state, CBVAVNum, SpeedNum, DesOutTemp](Real64 const SpeedRatio) {
2418 0 : auto const &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2419 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2420 : Real64 OutletAirTemp; // outlet air temperature [C]
2421 0 : Real64 QZnReqCycling = 0.001;
2422 0 : Real64 QLatReqCycling = 0.0;
2423 0 : Real64 OnOffAirFlowRatioCycling = 1.0;
2424 0 : Real64 partLoadRatio = 1.0;
2425 0 : int CoilIndex = thisCBVAV.CoolCoilCompIndex;
2426 0 : HVAC::FanOp fanOp = HVAC::FanOp::Continuous;
2427 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2428 : "",
2429 : CoilIndex,
2430 : fanOp,
2431 : HVAC::CompressorOp::On,
2432 : partLoadRatio,
2433 : SpeedNum,
2434 : SpeedRatio,
2435 : QZnReqCycling,
2436 : QLatReqCycling,
2437 : OnOffAirFlowRatioCycling);
2438 :
2439 0 : OutletAirTemp = state.dataVariableSpeedCoils->VarSpeedCoil(CoilIndex).OutletAirDBTemp;
2440 0 : return DesOutTemp - OutletAirTemp;
2441 0 : };
2442 0 : General::SolveRoot(state, tempAccuracy, MaxIte, SolFla, SpeedRatio, f, 1.0e-10, 1.0);
2443 :
2444 0 : if (SolFla == -1) {
2445 0 : if (!state.dataGlobal->WarmupFlag) {
2446 0 : if (cBVAV.DXIterationExceeded < 4) {
2447 0 : ++cBVAV.DXIterationExceeded;
2448 0 : ShowWarningError(state,
2449 0 : format("{} - Iteration limit exceeded calculating VS DX coil speed ratio for coil named "
2450 : "{}, in Unitary system named{}",
2451 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2452 0 : cBVAV.DXCoolCoilName,
2453 0 : cBVAV.Name));
2454 0 : ShowContinueError(state, format("Calculated speed ratio = {:.4R}", SpeedRatio));
2455 0 : ShowContinueErrorTimeStamp(
2456 : state, "The calculated speed ratio will be used and the simulation continues. Occurrence info:");
2457 : }
2458 0 : ShowRecurringWarningErrorAtEnd(state,
2459 0 : format("{} \"{}\" - Iteration limit exceeded calculating speed ratio error "
2460 : "continues. Speed Ratio statistics follow.",
2461 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2462 0 : cBVAV.DXCoolCoilName),
2463 0 : cBVAV.DXIterationExceededIndex,
2464 : LocalPartLoadFrac,
2465 : LocalPartLoadFrac);
2466 : }
2467 0 : } else if (SolFla == -2) {
2468 0 : if (!state.dataGlobal->WarmupFlag) {
2469 0 : if (cBVAV.DXIterationFailed < 4) {
2470 0 : ++cBVAV.DXIterationFailed;
2471 0 : ShowWarningError(state,
2472 0 : format("{} - DX unit speed ratio calculation failed: solver limits exceeded, for coil "
2473 : "named {}, in Unitary system named{}",
2474 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2475 0 : cBVAV.DXCoolCoilName,
2476 0 : cBVAV.Name));
2477 0 : ShowContinueError(state, format("Estimated speed ratio = {:.3R}", TempSpeedReqst / TempSpeedOut));
2478 0 : ShowContinueErrorTimeStamp(
2479 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
2480 : }
2481 0 : ShowRecurringWarningErrorAtEnd(
2482 : state,
2483 0 : format(
2484 : "{} \"{}\" - DX unit speed ratio calculation failed error continues. speed ratio statistics follow.",
2485 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2486 0 : cBVAV.DXCoolCoilName),
2487 0 : cBVAV.DXIterationFailedIndex,
2488 : SpeedRatio,
2489 : SpeedRatio);
2490 : }
2491 0 : SpeedRatio = TempSpeedReqst / TempSpeedOut;
2492 : }
2493 : } else {
2494 : // cycling compressor at lowest speed number, find part load fraction
2495 0 : auto f = [&state, CBVAVNum, DesOutTemp](Real64 const PartLoadRatio) {
2496 0 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2497 0 : int speedNum = 1;
2498 0 : Real64 speedRatio = 0.0;
2499 0 : Real64 QZnReqCycling = 0.001;
2500 0 : Real64 QLatReqCycling = 0.0;
2501 0 : Real64 OnOffAirFlowRatioCycling = 1.0;
2502 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2503 : "",
2504 0 : thisCBVAV.CoolCoilCompIndex,
2505 : HVAC::FanOp::Continuous,
2506 : HVAC::CompressorOp::On,
2507 : PartLoadRatio,
2508 : speedNum,
2509 : speedRatio,
2510 : QZnReqCycling,
2511 : QLatReqCycling,
2512 : OnOffAirFlowRatioCycling);
2513 :
2514 0 : Real64 OutletAirTemp = state.dataVariableSpeedCoils->VarSpeedCoil(thisCBVAV.CoolCoilCompIndex).OutletAirDBTemp;
2515 0 : return DesOutTemp - OutletAirTemp;
2516 0 : };
2517 0 : General::SolveRoot(state, tempAccuracy, MaxIte, SolFla, LocalPartLoadFrac, f, 1.0e-10, 1.0);
2518 0 : if (SolFla == -1) {
2519 0 : if (!state.dataGlobal->WarmupFlag) {
2520 0 : if (cBVAV.DXCyclingIterationExceeded < 4) {
2521 0 : ++cBVAV.DXCyclingIterationExceeded;
2522 0 : ShowWarningError(state,
2523 0 : format("{} - Iteration limit exceeded calculating VS DX unit low speed cycling ratio, "
2524 : "for coil named {}, in Unitary system named{}",
2525 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2526 0 : cBVAV.DXCoolCoilName,
2527 0 : cBVAV.Name));
2528 0 : ShowContinueError(state, format("Estimated cycling ratio = {:.3R}", (TempSpeedReqst / TempSpeedOut)));
2529 0 : ShowContinueError(state, format("Calculated cycling ratio = {:.3R}", LocalPartLoadFrac));
2530 0 : ShowContinueErrorTimeStamp(
2531 : state, "The calculated cycling ratio will be used and the simulation continues. Occurrence info:");
2532 : }
2533 0 : ShowRecurringWarningErrorAtEnd(
2534 : state,
2535 0 : format(" {} \"{}\" - Iteration limit exceeded calculating low speed cycling ratio "
2536 : "error continues. Sensible PLR statistics follow.",
2537 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2538 0 : cBVAV.DXCoolCoilName),
2539 0 : cBVAV.DXCyclingIterationExceededIndex,
2540 : LocalPartLoadFrac,
2541 : LocalPartLoadFrac);
2542 : }
2543 0 : } else if (SolFla == -2) {
2544 :
2545 0 : if (!state.dataGlobal->WarmupFlag) {
2546 0 : if (cBVAV.DXCyclingIterationFailed < 4) {
2547 0 : ++cBVAV.DXCyclingIterationFailed;
2548 0 : ShowWarningError(
2549 : state,
2550 0 : format("{} - DX unit low speed cycling ratio calculation failed: limits exceeded, for unit = {}",
2551 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2552 0 : cBVAV.Name));
2553 0 : ShowContinueError(state,
2554 0 : format("Estimated low speed cycling ratio = {:.3R}", TempSpeedReqst / TempSpeedOut));
2555 0 : ShowContinueErrorTimeStamp(state,
2556 : "The estimated low speed cycling ratio will be used and the simulation "
2557 : "continues. Occurrence info:");
2558 : }
2559 0 : ShowRecurringWarningErrorAtEnd(state,
2560 0 : format("{} \"{}\" - DX unit low speed cycling ratio calculation failed error "
2561 : "continues. cycling ratio statistics follow.",
2562 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)],
2563 0 : cBVAV.DXCoolCoilName),
2564 0 : cBVAV.DXCyclingIterationFailedIndex,
2565 : LocalPartLoadFrac,
2566 : LocalPartLoadFrac);
2567 : }
2568 0 : LocalPartLoadFrac = TempSpeedReqst / TempSpeedOut;
2569 : }
2570 : }
2571 : }
2572 : }
2573 :
2574 0 : if (LocalPartLoadFrac > 1.0) {
2575 0 : LocalPartLoadFrac = 1.0;
2576 0 : } else if (LocalPartLoadFrac < 0.0) {
2577 0 : LocalPartLoadFrac = 0.0;
2578 : }
2579 0 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = VariableSpeedCoils::getVarSpeedPartLoadRatio(state, cBVAV.CoolCoilCompIndex);
2580 : // variable-speed air-to-air cooling coil, end -------------------------
2581 0 : } break;
2582 0 : case HVAC::CoilType::DXCoolingTwoStageWHumControl: {
2583 : // Coil:Cooling:DX:TwoStageWithHumidityControlMode
2584 : // formerly (v3 and beyond) Coil:DX:MultiMode:CoolingEmpirical
2585 :
2586 : // If DXCoolingSystem runs with a cooling load then set PartLoadFrac on Cooling System and the Mass Flow
2587 : // Multimode coil will switch to enhanced dehumidification if available and needed, but it
2588 : // still runs to meet the sensible load
2589 :
2590 : // Determine required part load for normal mode
2591 :
2592 : // Get full load result
2593 0 : HVAC::CoilMode DehumidMode = HVAC::CoilMode::Normal; // Dehumidification mode (0=normal, 1=enhanced)
2594 0 : cBVAV.DehumidificationMode = DehumidMode;
2595 0 : DXCoils::SimDXCoilMultiMode(state,
2596 : cBVAV.DXCoolCoilName,
2597 : HVAC::CompressorOp::On,
2598 : FirstHVACIteration,
2599 : PartLoadFrac,
2600 : DehumidMode,
2601 0 : cBVAV.CoolCoilCompIndex,
2602 : HVAC::FanOp::Continuous);
2603 0 : if (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp <= cBVAV.CoilTempSetPoint) {
2604 0 : PartLoadFrac = 0.0;
2605 0 : DXCoils::SimDXCoilMultiMode(state,
2606 : cBVAV.DXCoolCoilName,
2607 : HVAC::CompressorOp::On,
2608 : FirstHVACIteration,
2609 : PartLoadFrac,
2610 : DehumidMode,
2611 0 : cBVAV.CoolCoilCompIndex,
2612 : HVAC::FanOp::Continuous);
2613 0 : } else if (state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp > cBVAV.CoilTempSetPoint) {
2614 0 : PartLoadFrac = 1.0;
2615 : } else {
2616 0 : auto f = [&state, CBVAVNum, DehumidMode](Real64 const PartLoadRatio) {
2617 0 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2618 0 : DXCoils::SimDXCoilMultiMode(state,
2619 : "",
2620 : HVAC::CompressorOp::On,
2621 : false,
2622 : PartLoadRatio,
2623 : DehumidMode,
2624 0 : thisCBVAV.CoolCoilCompIndex,
2625 : HVAC::FanOp::Continuous);
2626 0 : return thisCBVAV.CoilTempSetPoint - state.dataDXCoils->DXCoilOutletTemp(thisCBVAV.CoolCoilCompIndex);
2627 0 : };
2628 0 : General::SolveRoot(state, HVAC::SmallTempDiff, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
2629 0 : if (SolFla == -1) {
2630 0 : if (cBVAV.MMDXIterationExceeded < 1) {
2631 0 : ++cBVAV.MMDXIterationExceeded;
2632 0 : ShowWarningError(state,
2633 0 : format("Iteration limit exceeded calculating DX unit part-load ratio, for unit={}", cBVAV.Name));
2634 0 : ShowContinueErrorTimeStamp(state, format("Part-load ratio returned = {:.2R}", PartLoadFrac));
2635 0 : ShowContinueErrorTimeStamp(
2636 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
2637 : } else {
2638 0 : ShowRecurringWarningErrorAtEnd(state,
2639 0 : cBVAV.Name +
2640 : ", Iteration limit exceeded calculating DX unit part-load ratio error continues.",
2641 0 : cBVAV.MMDXIterationExceededIndex,
2642 : PartLoadFrac,
2643 : PartLoadFrac);
2644 : }
2645 0 : } else if (SolFla == -2) {
2646 0 : PartLoadFrac = max(0.0,
2647 : min(1.0,
2648 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp - cBVAV.CoilTempSetPoint) /
2649 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp -
2650 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp)));
2651 0 : if (cBVAV.MMDXIterationFailed < 1) {
2652 0 : ++cBVAV.MMDXIterationFailed;
2653 0 : ShowSevereError(
2654 : state,
2655 0 : format("DX unit part-load ratio calculation failed: part-load ratio limits exceeded, for unit={}", cBVAV.Name));
2656 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
2657 0 : ShowContinueErrorTimeStamp(
2658 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
2659 : } else {
2660 0 : ShowRecurringWarningErrorAtEnd(state,
2661 0 : cBVAV.Name + ", Part-load ratio calculation failed for DX unit error continues.",
2662 0 : cBVAV.MMDXIterationFailedIndex,
2663 : PartLoadFrac,
2664 : PartLoadFrac);
2665 : }
2666 : }
2667 : }
2668 :
2669 : // If humidity setpoint is not satisfied and humidity control type is Multimode,
2670 : // then turn on enhanced dehumidification mode 1
2671 :
2672 0 : if ((state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat > state.dataLoopNodes->Node(OutletNode).HumRatMax) &&
2673 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).HumRat > state.dataLoopNodes->Node(OutletNode).HumRatMax) &&
2674 0 : (cBVAV.DehumidControlType == DehumidControl::Multimode) && state.dataLoopNodes->Node(OutletNode).HumRatMax > 0.0) {
2675 :
2676 : // Determine required part load for enhanced dehumidification mode 1
2677 :
2678 : // Get full load result
2679 0 : PartLoadFrac = 1.0;
2680 0 : DehumidMode = HVAC::CoilMode::Enhanced;
2681 0 : cBVAV.DehumidificationMode = DehumidMode;
2682 0 : DXCoils::SimDXCoilMultiMode(state,
2683 : cBVAV.DXCoolCoilName,
2684 : HVAC::CompressorOp::On,
2685 : FirstHVACIteration,
2686 : PartLoadFrac,
2687 : DehumidMode,
2688 0 : cBVAV.CoolCoilCompIndex,
2689 : HVAC::FanOp::Continuous);
2690 0 : if (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp <= cBVAV.CoilTempSetPoint) {
2691 0 : PartLoadFrac = 0.0;
2692 0 : } else if (state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp > cBVAV.CoilTempSetPoint) {
2693 0 : PartLoadFrac = 1.0;
2694 : } else {
2695 0 : auto f = [&state, CBVAVNum, DehumidMode](Real64 const PartLoadRatio) {
2696 0 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2697 0 : DXCoils::SimDXCoilMultiMode(state,
2698 : "",
2699 : HVAC::CompressorOp::On,
2700 : false,
2701 : PartLoadRatio,
2702 : DehumidMode,
2703 0 : thisCBVAV.CoolCoilCompIndex,
2704 : HVAC::FanOp::Continuous);
2705 0 : return thisCBVAV.CoilTempSetPoint - state.dataDXCoils->DXCoilOutletTemp(thisCBVAV.CoolCoilCompIndex);
2706 0 : };
2707 0 : General::SolveRoot(state, HVAC::SmallTempDiff, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
2708 0 : if (SolFla == -1) {
2709 0 : if (cBVAV.DMDXIterationExceeded < 1) {
2710 0 : ++cBVAV.DMDXIterationExceeded;
2711 0 : ShowWarningError(
2712 : state,
2713 0 : format("Iteration limit exceeded calculating DX unit dehumidifying part-load ratio, for unit = {}",
2714 0 : cBVAV.Name));
2715 0 : ShowContinueErrorTimeStamp(state, format("Part-load ratio returned={:.2R}", PartLoadFrac));
2716 0 : ShowContinueErrorTimeStamp(
2717 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
2718 : } else {
2719 0 : ShowRecurringWarningErrorAtEnd(
2720 : state,
2721 0 : cBVAV.Name + ", Iteration limit exceeded calculating DX unit dehumidifying part-load ratio error continues.",
2722 0 : cBVAV.DMDXIterationExceededIndex,
2723 : PartLoadFrac,
2724 : PartLoadFrac);
2725 : }
2726 0 : } else if (SolFla == -2) {
2727 0 : PartLoadFrac = max(0.0,
2728 : min(1.0,
2729 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp - cBVAV.CoilTempSetPoint) /
2730 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp -
2731 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp)));
2732 0 : if (cBVAV.DMDXIterationFailed < 1) {
2733 0 : ++cBVAV.DMDXIterationFailed;
2734 0 : ShowSevereError(state,
2735 0 : format("DX unit dehumidifying part-load ratio calculation failed: part-load ratio limits "
2736 : "exceeded, for unit = {}",
2737 0 : cBVAV.Name));
2738 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
2739 0 : ShowContinueErrorTimeStamp(
2740 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
2741 : } else {
2742 0 : ShowRecurringWarningErrorAtEnd(
2743 : state,
2744 0 : cBVAV.Name + ", Dehumidifying part-load ratio calculation failed for DX unit error continues.",
2745 0 : cBVAV.DMDXIterationFailedIndex,
2746 : PartLoadFrac,
2747 : PartLoadFrac);
2748 : }
2749 : }
2750 : }
2751 : } // End if humidity ratio setpoint not met - multimode humidity control
2752 :
2753 : // If humidity setpoint is not satisfied and humidity control type is CoolReheat,
2754 : // then run to meet latent load
2755 :
2756 0 : if ((state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).HumRat > state.dataLoopNodes->Node(OutletNode).HumRatMax) &&
2757 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).HumRat > state.dataLoopNodes->Node(OutletNode).HumRatMax) &&
2758 0 : (cBVAV.DehumidControlType == DehumidControl::CoolReheat) && state.dataLoopNodes->Node(OutletNode).HumRatMax > 0.0) {
2759 :
2760 : // Determine revised desired outlet temperature - use approach temperature control strategy
2761 : // based on CONTROLLER:SIMPLE TEMPANDHUMRAT control type.
2762 :
2763 : // Calculate the approach temperature (difference between SA dry-bulb temp and SA dew point temp)
2764 0 : ApproachTemp = state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp -
2765 0 : Psychrometrics::PsyTdpFnWPb(state, state.dataLoopNodes->Node(OutletNode).HumRat, OutdoorBaroPress);
2766 : // Calculate the dew point temperature at the SA humidity ratio setpoint
2767 0 : DesiredDewPoint = Psychrometrics::PsyTdpFnWPb(state, state.dataLoopNodes->Node(OutletNode).HumRatMax, OutdoorBaroPress);
2768 : // Adjust the calculated dew point temperature by the approach temp
2769 0 : cBVAV.CoilTempSetPoint = min(cBVAV.CoilTempSetPoint, (DesiredDewPoint + ApproachTemp));
2770 :
2771 : // Determine required part load for cool reheat at adjusted DesiredOutletTemp
2772 :
2773 : // Get full load result
2774 0 : PartLoadFrac = 1.0;
2775 0 : DehumidMode = HVAC::CoilMode::Normal;
2776 0 : cBVAV.DehumidificationMode = DehumidMode;
2777 0 : DXCoils::SimDXCoilMultiMode(state,
2778 : cBVAV.DXCoolCoilName,
2779 : HVAC::CompressorOp::On,
2780 : FirstHVACIteration,
2781 : PartLoadFrac,
2782 : DehumidMode,
2783 0 : cBVAV.CoolCoilCompIndex,
2784 : HVAC::FanOp::Continuous);
2785 0 : if (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp <= cBVAV.CoilTempSetPoint) {
2786 0 : PartLoadFrac = 0.0;
2787 0 : } else if (state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp > cBVAV.CoilTempSetPoint) {
2788 0 : PartLoadFrac = 1.0;
2789 : } else {
2790 0 : auto f = [&state, CBVAVNum, DehumidMode](Real64 const PartLoadRatio) {
2791 0 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2792 0 : DXCoils::SimDXCoilMultiMode(state,
2793 : "",
2794 : HVAC::CompressorOp::On,
2795 : false,
2796 : PartLoadRatio,
2797 : DehumidMode,
2798 0 : thisCBVAV.CoolCoilCompIndex,
2799 : HVAC::FanOp::Continuous);
2800 0 : return thisCBVAV.CoilTempSetPoint - state.dataDXCoils->DXCoilOutletTemp(thisCBVAV.CoolCoilCompIndex);
2801 0 : };
2802 0 : General::SolveRoot(state, HVAC::SmallTempDiff, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
2803 0 : if (SolFla == -1) {
2804 0 : if (cBVAV.CRDXIterationExceeded < 1) {
2805 0 : ++cBVAV.CRDXIterationExceeded;
2806 0 : ShowWarningError(state,
2807 0 : format("Iteration limit exceeded calculating DX unit cool reheat part-load ratio, for unit = {}",
2808 0 : cBVAV.Name));
2809 0 : ShowContinueErrorTimeStamp(state, format("Part-load ratio returned = {:.2R}", PartLoadFrac));
2810 0 : ShowContinueErrorTimeStamp(
2811 : state, "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
2812 : } else {
2813 0 : ShowRecurringWarningErrorAtEnd(
2814 : state,
2815 0 : cBVAV.Name + ", Iteration limit exceeded calculating cool reheat part-load ratio DX unit error continues.",
2816 0 : cBVAV.CRDXIterationExceededIndex,
2817 : PartLoadFrac,
2818 : PartLoadFrac);
2819 : }
2820 0 : } else if (SolFla == -2) {
2821 0 : PartLoadFrac = max(0.0,
2822 : min(1.0,
2823 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp - cBVAV.CoilTempSetPoint) /
2824 0 : (state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp -
2825 0 : state.dataLoopNodes->Node(cBVAV.DXCoilOutletNode).Temp)));
2826 0 : if (cBVAV.CRDXIterationFailed < 1) {
2827 0 : ++cBVAV.CRDXIterationFailed;
2828 0 : ShowSevereError(
2829 : state,
2830 0 : format(
2831 : "DX unit cool reheat part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
2832 0 : cBVAV.Name));
2833 0 : ShowContinueError(state, format("Estimated part-load ratio = {:.3R}", PartLoadFrac));
2834 0 : ShowContinueErrorTimeStamp(
2835 : state, "The estimated part-load ratio will be used and the simulation continues. Occurrence info:");
2836 : } else {
2837 0 : ShowRecurringWarningErrorAtEnd(
2838 : state,
2839 0 : cBVAV.Name + ", Dehumidifying part-load ratio calculation failed for DX unit error continues.",
2840 0 : cBVAV.DMDXIterationFailedIndex,
2841 : PartLoadFrac,
2842 : PartLoadFrac);
2843 : }
2844 : }
2845 : }
2846 : } // End if humidity ratio setpoint not met - CoolReheat humidity control
2847 :
2848 0 : if (PartLoadFrac > 1.0) {
2849 0 : PartLoadFrac = 1.0;
2850 0 : } else if (PartLoadFrac < 0.0) {
2851 0 : PartLoadFrac = 0.0;
2852 : }
2853 0 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(cBVAV.DXCoolCoilIndexNum);
2854 0 : } break;
2855 0 : default: {
2856 0 : ShowFatalError(
2857 0 : state, format("SimCBVAV System: Invalid DX Cooling Coil={}", HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.CoolCoilType)]));
2858 0 : } break;
2859 : }
2860 : } else { // IF(OutdoorDryBulbTemp .GE. cBVAV%MinOATCompressor)THEN
2861 : // Simulate DX cooling coil with compressor off
2862 0 : if (cBVAV.CoolCoilType == HVAC::CoilType::DXCoolingHXAssisted) {
2863 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
2864 : cBVAV.DXCoolCoilName,
2865 : FirstHVACIteration,
2866 : HVAC::CompressorOp::Off,
2867 : 0.0,
2868 0 : cBVAV.CoolCoilCompIndex,
2869 : HVAC::FanOp::Continuous,
2870 : HXUnitOn);
2871 0 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(cBVAV.DXCoolCoilIndexNum);
2872 0 : } else if (cBVAV.CoolCoilType == HVAC::CoilType::DXCoolingSingleSpeed) {
2873 0 : DXCoils::SimDXCoil(state,
2874 : cBVAV.DXCoolCoilName,
2875 : HVAC::CompressorOp::Off,
2876 : FirstHVACIteration,
2877 0 : cBVAV.CoolCoilCompIndex,
2878 : HVAC::FanOp::Continuous,
2879 0 : 0.0,
2880 : OnOffAirFlowRatio);
2881 0 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(cBVAV.DXCoolCoilIndexNum);
2882 0 : } else if (cBVAV.CoolCoilType == HVAC::CoilType::DXCoolingTwoStageWHumControl) {
2883 0 : DXCoils::SimDXCoilMultiMode(state,
2884 : cBVAV.DXCoolCoilName,
2885 : HVAC::CompressorOp::Off,
2886 : FirstHVACIteration,
2887 : 0.0,
2888 : HVAC::CoilMode::Normal,
2889 0 : cBVAV.CoolCoilCompIndex,
2890 : HVAC::FanOp::Continuous);
2891 0 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(cBVAV.DXCoolCoilIndexNum);
2892 0 : } else if (cBVAV.CoolCoilType == HVAC::CoilType::CoolingAirToAirVariableSpeed) {
2893 : // Real64 PartLoadFrac(0.0);
2894 0 : Real64 LocalPartLoadFrac = 0.0;
2895 0 : Real64 QZnReq = 0.0; // Zone load (W), input to variable-speed DX coil
2896 0 : Real64 QLatReq = 0.0; // Zone latent load, input to variable-speed DX coil
2897 0 : Real64 SpeedRatio = 0.0;
2898 0 : int SpeedNum = 1;
2899 : // Get no load result
2900 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2901 : cBVAV.DXCoolCoilName,
2902 0 : cBVAV.CoolCoilCompIndex,
2903 : HVAC::FanOp::Continuous,
2904 : HVAC::CompressorOp::Off,
2905 : LocalPartLoadFrac,
2906 : SpeedNum,
2907 : SpeedRatio,
2908 : QZnReq,
2909 : QLatReq);
2910 0 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = VariableSpeedCoils::getVarSpeedPartLoadRatio(state, cBVAV.CoolCoilCompIndex);
2911 : }
2912 : }
2913 :
2914 : // Simulate cooling coil with compressor off if zone requires heating
2915 : } else { // HeatCoolMode == HeatingMode and no cooling is required, set PLR to 0
2916 14 : if (cBVAV.CoolCoilType == HVAC::CoilType::DXCoolingHXAssisted) {
2917 0 : HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil(state,
2918 : cBVAV.DXCoolCoilName,
2919 : FirstHVACIteration,
2920 : HVAC::CompressorOp::Off,
2921 : 0.0,
2922 0 : cBVAV.CoolCoilCompIndex,
2923 : HVAC::FanOp::Continuous,
2924 : HXUnitOn);
2925 14 : } else if (cBVAV.CoolCoilType == HVAC::CoilType::DXCoolingSingleSpeed) {
2926 36 : DXCoils::SimDXCoil(state,
2927 : cBVAV.DXCoolCoilName,
2928 : HVAC::CompressorOp::Off,
2929 : FirstHVACIteration,
2930 12 : cBVAV.CoolCoilCompIndex,
2931 : HVAC::FanOp::Continuous,
2932 24 : 0.0,
2933 : OnOffAirFlowRatio);
2934 2 : } else if (cBVAV.CoolCoilType == HVAC::CoilType::CoolingAirToAirVariableSpeed) {
2935 2 : Real64 QZnReq = 0.0; // Zone load (W), input to variable-speed DX coil
2936 2 : Real64 QLatReq = 0.0; // Zone latent load, input to variable-speed DX coil
2937 2 : Real64 LocalPartLoadFrac = 0.0;
2938 2 : Real64 SpeedRatio = 0.0;
2939 2 : int SpeedNum = 1;
2940 : // run model with no load
2941 2 : VariableSpeedCoils::SimVariableSpeedCoils(state,
2942 : cBVAV.DXCoolCoilName,
2943 2 : cBVAV.CoolCoilCompIndex,
2944 : HVAC::FanOp::Continuous,
2945 : HVAC::CompressorOp::Off,
2946 : LocalPartLoadFrac,
2947 : SpeedNum,
2948 : SpeedRatio,
2949 : QZnReq,
2950 : QLatReq);
2951 :
2952 0 : } else if (cBVAV.CoolCoilType == HVAC::CoilType::DXCoolingTwoStageWHumControl) {
2953 0 : DXCoils::SimDXCoilMultiMode(state,
2954 : cBVAV.DXCoolCoilName,
2955 : HVAC::CompressorOp::Off,
2956 : FirstHVACIteration,
2957 : 0.0,
2958 : HVAC::CoilMode::Normal,
2959 0 : cBVAV.CoolCoilCompIndex,
2960 : HVAC::FanOp::Continuous);
2961 : }
2962 : }
2963 :
2964 : // Simulate the heating coil based on coil type
2965 30 : switch (cBVAV.HeatCoilType) {
2966 0 : case HVAC::CoilType::DXHeatingEmpirical: {
2967 : // Simulate DX heating coil if zone load is positive (heating load)
2968 0 : if (cBVAV.HeatCoolMode == HeatingMode) {
2969 0 : if (OutdoorDryBulbTemp > cBVAV.MinOATCompressor) {
2970 : // simulate the DX heating coil
2971 : // vs coil issue
2972 :
2973 0 : DXCoils::SimDXCoil(state,
2974 : cBVAV.HeatCoilName,
2975 : HVAC::CompressorOp::On,
2976 : FirstHVACIteration,
2977 0 : cBVAV.HeatCoilIndex,
2978 : HVAC::FanOp::Continuous,
2979 : PartLoadFrac,
2980 : OnOffAirFlowRatio);
2981 0 : if (state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).Temp > cBVAV.CoilTempSetPoint &&
2982 0 : state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).Temp < cBVAV.CoilTempSetPoint) {
2983 : // iterate to find PLR at CoilTempSetPoint
2984 0 : auto f = [&state, CBVAVNum, OnOffAirFlowRatio](Real64 const PartLoadFrac) {
2985 0 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
2986 0 : DXCoils::CalcDXHeatingCoil(state, thisCBVAV.HeatCoilIndex, PartLoadFrac, HVAC::FanOp::Continuous, OnOffAirFlowRatio);
2987 0 : Real64 OutletAirTemp = state.dataDXCoils->DXCoilOutletTemp(thisCBVAV.HeatCoilIndex);
2988 0 : Real64 par2 = min(thisCBVAV.CoilTempSetPoint, thisCBVAV.MaxLATHeating);
2989 0 : return par2 - OutletAirTemp;
2990 0 : };
2991 0 : General::SolveRoot(state, HVAC::SmallTempDiff, MaxIte, SolFla, PartLoadFrac, f, 0.0, 1.0);
2992 0 : DXCoils::SimDXCoil(state,
2993 : cBVAV.HeatCoilName,
2994 : HVAC::CompressorOp::On,
2995 : FirstHVACIteration,
2996 0 : cBVAV.HeatCoilIndex,
2997 : HVAC::FanOp::Continuous,
2998 : PartLoadFrac,
2999 : OnOffAirFlowRatio);
3000 0 : if (SolFla == -1 && !state.dataGlobal->WarmupFlag) {
3001 0 : ShowWarningError(
3002 0 : state, format("Iteration limit exceeded calculating DX unit part-load ratio, for unit = {}", cBVAV.HeatCoilName));
3003 0 : ShowContinueError(state, format("Calculated part-load ratio = {:.3R}", PartLoadFrac));
3004 0 : ShowContinueErrorTimeStamp(state,
3005 : "The calculated part-load ratio will be used and the simulation continues. Occurrence info:");
3006 0 : } else if (SolFla == -2 && !state.dataGlobal->WarmupFlag) {
3007 0 : ShowSevereError(state,
3008 0 : format("DX unit part-load ratio calculation failed: part-load ratio limits exceeded, for unit = {}",
3009 0 : cBVAV.HeatCoilName));
3010 0 : ShowContinueErrorTimeStamp(
3011 : state,
3012 0 : format("A part-load ratio of {:.3R}will be used and the simulation continues. Occurrence info:", PartLoadFrac));
3013 0 : ShowContinueError(state, "Please send this information to the EnergyPlus support group.");
3014 : }
3015 : }
3016 : } else { // OAT .LT. MinOATCompressor
3017 : // simulate DX heating coil with compressor off
3018 0 : DXCoils::SimDXCoil(state,
3019 : cBVAV.HeatCoilName,
3020 : HVAC::CompressorOp::Off,
3021 : FirstHVACIteration,
3022 0 : cBVAV.HeatCoilIndex,
3023 : HVAC::FanOp::Continuous,
3024 0 : 0.0,
3025 : OnOffAirFlowRatio);
3026 : }
3027 0 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = state.dataDXCoils->DXCoilPartLoadRatio(cBVAV.DXHeatCoilIndexNum);
3028 : } else { // HeatCoolMode = CoolingMode
3029 : // simulate DX heating coil with compressor off when cooling load is required
3030 0 : DXCoils::SimDXCoil(state,
3031 : cBVAV.HeatCoilName,
3032 : HVAC::CompressorOp::Off,
3033 : FirstHVACIteration,
3034 0 : cBVAV.HeatCoilIndex,
3035 : HVAC::FanOp::Continuous,
3036 0 : 0.0,
3037 : OnOffAirFlowRatio);
3038 : }
3039 0 : } break;
3040 2 : case HVAC::CoilType::HeatingAirToAirVariableSpeed: {
3041 2 : Real64 QZnReq = 0.0; // Zone load (W), input to variable-speed DX coil
3042 2 : Real64 QLatReq = 0.0; // Zone latent load, input to variable-speed DX coil
3043 2 : Real64 LocalOnOffAirFlowRatio = 1.0; // ratio of compressor on flow to average flow over time step
3044 2 : Real64 LocalPartLoadFrac = 0.0;
3045 2 : Real64 SpeedRatio = 0.0;
3046 2 : int SpeedNum = 1;
3047 2 : bool errorFlag = false;
3048 2 : int maxNumSpeeds = VariableSpeedCoils::GetVSCoilNumOfSpeeds(state, cBVAV.HeatCoilName, errorFlag);
3049 2 : Real64 DesOutTemp = cBVAV.CoilTempSetPoint;
3050 : // Get no load result
3051 2 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3052 : cBVAV.HeatCoilName,
3053 2 : cBVAV.DXHeatCoilIndexNum,
3054 : HVAC::FanOp::Continuous,
3055 : HVAC::CompressorOp::Off,
3056 : LocalPartLoadFrac,
3057 : SpeedNum,
3058 : SpeedRatio,
3059 : QZnReq,
3060 : QLatReq);
3061 :
3062 2 : Real64 NoOutput = state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).MassFlowRate *
3063 2 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).Temp,
3064 2 : state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).HumRat) -
3065 2 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).Temp,
3066 2 : state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).HumRat));
3067 2 : Real64 TempNoOutput = state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).Temp;
3068 : // Real64 NoLoadHumRatOut = VariableSpeedCoils::VarSpeedCoil( CBVAV( CBVAVNum ).CoolCoilCompIndex ).OutletAirHumRat;
3069 :
3070 : // Get full load result
3071 2 : LocalPartLoadFrac = 1.0;
3072 2 : SpeedNum = maxNumSpeeds;
3073 2 : SpeedRatio = 1.0;
3074 2 : QZnReq = 0.001; // to indicate the coil is running
3075 2 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3076 : cBVAV.HeatCoilName,
3077 2 : cBVAV.DXHeatCoilIndexNum,
3078 : HVAC::FanOp::Continuous,
3079 : HVAC::CompressorOp::On,
3080 : LocalPartLoadFrac,
3081 : SpeedNum,
3082 : SpeedRatio,
3083 : QZnReq,
3084 : QLatReq);
3085 :
3086 : // Real64 FullLoadHumRatOut = VariableSpeedCoils::VarSpeedCoil( CBVAV( CBVAVNum ).CoolCoilCompIndex ).OutletAirHumRat;
3087 2 : Real64 FullOutput = state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).MassFlowRate *
3088 2 : (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).Temp,
3089 2 : state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).HumRat) -
3090 2 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).Temp,
3091 2 : state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).HumRat));
3092 2 : Real64 ReqOutput = state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).MassFlowRate *
3093 2 : (Psychrometrics::PsyHFnTdbW(DesOutTemp, state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).HumRat) -
3094 2 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).Temp,
3095 2 : state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).HumRat));
3096 :
3097 2 : Real64 loadAccuracy = 0.001; // Watts, power
3098 2 : Real64 tempAccuracy = 0.001; // delta C, temperature
3099 2 : if ((NoOutput - ReqOutput) > -loadAccuracy) { // IF NoOutput is higher than (more heating than required) or very near the
3100 : // ReqOutput, do not run the compressor
3101 1 : LocalPartLoadFrac = 0.0;
3102 1 : SpeedNum = 1;
3103 1 : SpeedRatio = 0.0;
3104 1 : QZnReq = 0.0;
3105 : // call again with coil off
3106 1 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3107 : cBVAV.HeatCoilName,
3108 1 : cBVAV.DXHeatCoilIndexNum,
3109 : HVAC::FanOp::Continuous,
3110 : HVAC::CompressorOp::Off,
3111 : LocalPartLoadFrac,
3112 : SpeedNum,
3113 : SpeedRatio,
3114 : QZnReq,
3115 : QLatReq);
3116 :
3117 1 : } else if ((FullOutput - ReqOutput) < loadAccuracy) { // If the FullOutput is less than (insufficient cooling) or very near
3118 : // the ReqOutput, run the compressor at LocalPartLoadFrac = 1.
3119 : // which we just did so nothing to be done
3120 :
3121 : } 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
3122 : // OutletTempDXCoil is the full capacity outlet temperature at LocalPartLoadFrac = 1 from the CALL above. If this temp is
3123 : // greater than the desired outlet temp, then run the compressor at LocalPartLoadFrac = 1, otherwise find the operating PLR.
3124 1 : Real64 OutletTempDXCoil = state.dataVariableSpeedCoils->VarSpeedCoil(cBVAV.DXHeatCoilIndexNum).OutletAirDBTemp;
3125 1 : if (OutletTempDXCoil < DesOutTemp) {
3126 0 : LocalPartLoadFrac = 1.0;
3127 0 : SpeedNum = maxNumSpeeds;
3128 0 : SpeedRatio = 1.0;
3129 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3130 : cBVAV.HeatCoilName,
3131 0 : cBVAV.DXHeatCoilIndexNum,
3132 : HVAC::FanOp::Continuous,
3133 : HVAC::CompressorOp::On,
3134 : LocalPartLoadFrac,
3135 : SpeedNum,
3136 : SpeedRatio,
3137 : QZnReq,
3138 : QLatReq,
3139 : LocalOnOffAirFlowRatio);
3140 : } else {
3141 : // run at lowest speed
3142 1 : LocalPartLoadFrac = 1.0;
3143 1 : SpeedNum = 1;
3144 1 : SpeedRatio = 1.0;
3145 1 : QZnReq = 0.001; // to indicate the coil is running
3146 1 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3147 : cBVAV.HeatCoilName,
3148 1 : cBVAV.DXHeatCoilIndexNum,
3149 : HVAC::FanOp::Continuous,
3150 : HVAC::CompressorOp::On,
3151 : LocalPartLoadFrac,
3152 : SpeedNum,
3153 : SpeedRatio,
3154 : QZnReq,
3155 : QLatReq,
3156 : LocalOnOffAirFlowRatio);
3157 :
3158 1 : Real64 TempSpeedOut = state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).Temp;
3159 1 : Real64 TempSpeedOutSpeed1 = TempSpeedOut;
3160 :
3161 1 : if ((TempSpeedOut - DesOutTemp) < tempAccuracy) {
3162 : // Check to see which speed to meet the load
3163 0 : LocalPartLoadFrac = 1.0;
3164 0 : SpeedRatio = 1.0;
3165 0 : for (int I = 2; I <= maxNumSpeeds; ++I) {
3166 0 : SpeedNum = I;
3167 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3168 : cBVAV.HeatCoilName,
3169 0 : cBVAV.DXHeatCoilIndexNum,
3170 : HVAC::FanOp::Continuous,
3171 : HVAC::CompressorOp::On,
3172 : LocalPartLoadFrac,
3173 : SpeedNum,
3174 : SpeedRatio,
3175 : QZnReq,
3176 : QLatReq,
3177 : LocalOnOffAirFlowRatio);
3178 :
3179 0 : TempSpeedOut = state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).Temp;
3180 :
3181 0 : if ((TempSpeedOut - DesOutTemp) > tempAccuracy) {
3182 0 : SpeedNum = I;
3183 0 : break;
3184 : }
3185 : }
3186 : // now find the speed ratio for the found speednum
3187 0 : int const vsCoilIndex = cBVAV.DXHeatCoilIndexNum;
3188 0 : auto f = [&state, vsCoilIndex, DesOutTemp, SpeedNum](Real64 const x) {
3189 0 : return HVACDXHeatPumpSystem::VSCoilSpeedResidual(state, x, vsCoilIndex, DesOutTemp, SpeedNum, HVAC::FanOp::Continuous);
3190 0 : };
3191 0 : General::SolveRoot(state, tempAccuracy, MaxIte, SolFla, SpeedRatio, f, 1.0e-10, 1.0);
3192 :
3193 0 : if (SolFla == -1) {
3194 0 : if (!state.dataGlobal->WarmupFlag) {
3195 0 : if (cBVAV.DXHeatIterationExceeded < 4) {
3196 0 : ++cBVAV.DXHeatIterationExceeded;
3197 0 : ShowWarningError(state,
3198 0 : format("{} - Iteration limit exceeded calculating VS DX coil speed ratio for coil named {}, in "
3199 : "Unitary system named{}",
3200 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3201 0 : cBVAV.HeatCoilName,
3202 0 : cBVAV.Name));
3203 0 : ShowContinueError(state, format("Calculated speed ratio = {:.4R}", SpeedRatio));
3204 0 : ShowContinueErrorTimeStamp(
3205 : state, "The calculated speed ratio will be used and the simulation continues. Occurrence info:");
3206 : }
3207 0 : ShowRecurringWarningErrorAtEnd(state,
3208 0 : format("{} \"{}\" - Iteration limit exceeded calculating speed ratio error continues. "
3209 : "Speed Ratio statistics follow.",
3210 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3211 0 : cBVAV.HeatCoilName),
3212 0 : cBVAV.DXHeatIterationExceededIndex,
3213 : LocalPartLoadFrac,
3214 : LocalPartLoadFrac);
3215 : }
3216 0 : } else if (SolFla == -2) {
3217 :
3218 0 : if (!state.dataGlobal->WarmupFlag) {
3219 0 : if (cBVAV.DXHeatIterationFailed < 4) {
3220 0 : ++cBVAV.DXHeatIterationFailed;
3221 0 : ShowWarningError(state,
3222 0 : format("{} - DX unit speed ratio calculation failed: solver limits exceeded, for coil named {}, "
3223 : "in Unitary system named{}",
3224 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3225 0 : cBVAV.HeatCoilName,
3226 0 : cBVAV.Name));
3227 0 : ShowContinueErrorTimeStamp(state,
3228 : " Speed ratio will be set to 0.5, and the simulation continues. Occurrence info:");
3229 : }
3230 0 : ShowRecurringWarningErrorAtEnd(
3231 : state,
3232 0 : format("{} \"{}\" - DX unit speed ratio calculation failed error continues. speed ratio statistics follow.",
3233 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3234 0 : cBVAV.HeatCoilName),
3235 0 : cBVAV.DXHeatIterationFailedIndex,
3236 : SpeedRatio,
3237 : SpeedRatio);
3238 : }
3239 0 : SpeedRatio = 0.5;
3240 : }
3241 0 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3242 : cBVAV.HeatCoilName,
3243 0 : cBVAV.DXHeatCoilIndexNum,
3244 : HVAC::FanOp::Continuous,
3245 : HVAC::CompressorOp::On,
3246 : LocalPartLoadFrac,
3247 : SpeedNum,
3248 : SpeedRatio,
3249 : QZnReq,
3250 : QLatReq,
3251 : LocalOnOffAirFlowRatio);
3252 : } else {
3253 : // cycling compressor at lowest speed number, find part load fraction
3254 1 : int VSCoilIndex = cBVAV.DXHeatCoilIndexNum;
3255 3 : auto f = [&state, VSCoilIndex, DesOutTemp](Real64 const x) {
3256 3 : return HVACDXHeatPumpSystem::VSCoilCyclingResidual(state, x, VSCoilIndex, DesOutTemp, HVAC::FanOp::Continuous);
3257 1 : };
3258 1 : General::SolveRoot(state, tempAccuracy, MaxIte, SolFla, LocalPartLoadFrac, f, 1.0e-10, 1.0);
3259 1 : if (SolFla == -1) {
3260 0 : if (!state.dataGlobal->WarmupFlag) {
3261 0 : if (cBVAV.DXHeatCyclingIterationExceeded < 4) {
3262 0 : ++cBVAV.DXHeatCyclingIterationExceeded;
3263 0 : ShowWarningError(state,
3264 0 : format("{} - Iteration limit exceeded calculating VS DX unit low speed cycling ratio, for coil "
3265 : "named {}, in Unitary system named{}",
3266 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3267 0 : cBVAV.HeatCoilName,
3268 0 : cBVAV.Name));
3269 0 : ShowContinueError(state, format("Estimated cycling ratio = {:.3R}", (DesOutTemp / TempSpeedOut)));
3270 0 : ShowContinueError(state, format("Calculated cycling ratio = {:.3R}", LocalPartLoadFrac));
3271 0 : ShowContinueErrorTimeStamp(
3272 : state, "The calculated cycling ratio will be used and the simulation continues. Occurrence info:");
3273 : }
3274 0 : ShowRecurringWarningErrorAtEnd(state,
3275 0 : format("{} \"{}\" - Iteration limit exceeded calculating low speed cycling ratio "
3276 : "error continues. Sensible PLR statistics follow.",
3277 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3278 0 : cBVAV.HeatCoilName),
3279 0 : cBVAV.DXHeatCyclingIterationExceededIndex,
3280 : LocalPartLoadFrac,
3281 : LocalPartLoadFrac);
3282 : }
3283 1 : } else if (SolFla == -2) {
3284 :
3285 0 : if (!state.dataGlobal->WarmupFlag) {
3286 0 : if (cBVAV.DXHeatCyclingIterationFailed < 4) {
3287 0 : ++cBVAV.DXHeatCyclingIterationFailed;
3288 0 : ShowWarningError(state,
3289 0 : format("{} - DX unit low speed cycling ratio calculation failed: limits exceeded, for unit = {}",
3290 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3291 0 : cBVAV.Name));
3292 0 : ShowContinueError(state,
3293 0 : format("Estimated low speed cycling ratio = {:.3R}",
3294 0 : (DesOutTemp - TempNoOutput) / (TempSpeedOutSpeed1 - TempNoOutput)));
3295 0 : ShowContinueErrorTimeStamp(
3296 : state, "The estimated low speed cycling ratio will be used and the simulation continues. Occurrence info:");
3297 : }
3298 0 : ShowRecurringWarningErrorAtEnd(state,
3299 0 : format("{} \"{}\" - DX unit low speed cycling ratio calculation failed error "
3300 : "continues. cycling ratio statistics follow.",
3301 0 : HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)],
3302 0 : cBVAV.HeatCoilName),
3303 0 : cBVAV.DXHeatCyclingIterationFailedIndex,
3304 : LocalPartLoadFrac,
3305 : LocalPartLoadFrac);
3306 : }
3307 0 : LocalPartLoadFrac = (DesOutTemp - TempNoOutput) / (TempSpeedOutSpeed1 - TempNoOutput);
3308 : }
3309 1 : VariableSpeedCoils::SimVariableSpeedCoils(state,
3310 : cBVAV.HeatCoilName,
3311 1 : cBVAV.DXHeatCoilIndexNum,
3312 : HVAC::FanOp::Continuous,
3313 : HVAC::CompressorOp::On,
3314 : LocalPartLoadFrac,
3315 : SpeedNum,
3316 : SpeedRatio,
3317 : QZnReq,
3318 : QLatReq,
3319 : LocalOnOffAirFlowRatio);
3320 : }
3321 : }
3322 : }
3323 :
3324 2 : if (LocalPartLoadFrac > 1.0) {
3325 0 : LocalPartLoadFrac = 1.0;
3326 2 : } else if (LocalPartLoadFrac < 0.0) {
3327 0 : LocalPartLoadFrac = 0.0;
3328 : }
3329 2 : state.dataHVACUnitaryBypassVAV->SaveCompressorPLR = VariableSpeedCoils::getVarSpeedPartLoadRatio(state, cBVAV.DXHeatCoilIndexNum);
3330 2 : } break;
3331 28 : case HVAC::CoilType::HeatingGasOrOtherFuel:
3332 : case HVAC::CoilType::HeatingElectric:
3333 : case HVAC::CoilType::HeatingWater:
3334 : case HVAC::CoilType::HeatingSteam: { // not a DX heating coil
3335 28 : if (cBVAV.HeatCoolMode == HeatingMode) {
3336 8 : CpAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).HumRat);
3337 8 : QHeater = state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).MassFlowRate * CpAir *
3338 8 : (cBVAV.CoilTempSetPoint - state.dataLoopNodes->Node(cBVAV.HeatingCoilInletNode).Temp);
3339 : } else {
3340 20 : QHeater = 0.0;
3341 : }
3342 : // Added None DX heating coils calling point
3343 28 : state.dataLoopNodes->Node(cBVAV.HeatingCoilOutletNode).TempSetPoint = cBVAV.CoilTempSetPoint;
3344 28 : CalcNonDXHeatingCoils(state, CBVAVNum, FirstHVACIteration, QHeater, cBVAV.fanOp, QHeaterActual);
3345 28 : } break;
3346 0 : default: {
3347 0 : ShowFatalError(state, format("SimCBVAV System: Invalid Heating Coil={}", HVAC::coilTypeNamesUC[static_cast<int>(cBVAV.HeatCoilType)]));
3348 0 : } break;
3349 : }
3350 :
3351 30 : if (cBVAV.fanPlace == HVAC::FanPlace::DrawThru) {
3352 0 : state.dataFans->fans(cBVAV.FanIndex)
3353 0 : ->simulate(state, FirstHVACIteration, state.dataHVACUnitaryBypassVAV->FanSpeedRatio, _, 1.0 / OnOffAirFlowRatio, _);
3354 : }
3355 30 : int splitterOutNode = cBVAV.SplitterOutletAirNode;
3356 30 : state.dataLoopNodes->Node(splitterOutNode).MassFlowRateSetPoint = state.dataLoopNodes->Node(OutletNode).MassFlowRateSetPoint;
3357 30 : state.dataLoopNodes->Node(OutletNode) = state.dataLoopNodes->Node(splitterOutNode);
3358 30 : state.dataLoopNodes->Node(OutletNode).TempSetPoint = cBVAV.OutletTempSetPoint;
3359 30 : state.dataLoopNodes->Node(OutletNode).MassFlowRate =
3360 30 : (1.0 - state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction) * state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate;
3361 : // report variable
3362 30 : cBVAV.BypassMassFlowRate =
3363 30 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction * state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate;
3364 : // initialize bypass duct connected to mixer or plenum with flow rate and conditions
3365 30 : if (cBVAV.plenumIndex > 0 || cBVAV.mixerIndex > 0) {
3366 13 : int plenumOrMixerInletNode = cBVAV.PlenumMixerInletAirNode;
3367 13 : state.dataLoopNodes->Node(plenumOrMixerInletNode) = state.dataLoopNodes->Node(splitterOutNode);
3368 13 : state.dataLoopNodes->Node(plenumOrMixerInletNode).MassFlowRate =
3369 13 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction * state.dataLoopNodes->Node(cBVAV.MixerInletAirNode).MassFlowRate;
3370 13 : state.dataLoopNodes->Node(plenumOrMixerInletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(plenumOrMixerInletNode).MassFlowRate;
3371 13 : state.dataAirLoop->AirLoopFlow(cBVAV.AirLoopNumber).BypassMassFlow = state.dataLoopNodes->Node(plenumOrMixerInletNode).MassFlowRate;
3372 : }
3373 :
3374 : // calculate sensible load met using delta enthalpy at a constant (minimum) humidity ratio)
3375 30 : MinHumRat = min(state.dataLoopNodes->Node(InletNode).HumRat, state.dataLoopNodes->Node(OutletNode).HumRat);
3376 30 : LoadMet =
3377 30 : state.dataLoopNodes->Node(OutletNode).MassFlowRate * (Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, MinHumRat) -
3378 30 : Psychrometrics::PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, MinHumRat));
3379 :
3380 : // calculate OA fraction used for zone OA volume flow rate calc
3381 30 : state.dataAirLoop->AirLoopFlow(cBVAV.AirLoopNumber).OAFrac = 0.0;
3382 30 : if (state.dataLoopNodes->Node(cBVAV.AirOutNode).MassFlowRate > 0.0) {
3383 28 : state.dataAirLoop->AirLoopFlow(cBVAV.AirLoopNumber).OAFrac =
3384 28 : state.dataLoopNodes->Node(cBVAV.MixerOutsideAirNode).MassFlowRate / state.dataLoopNodes->Node(cBVAV.AirOutNode).MassFlowRate;
3385 : }
3386 30 : }
3387 :
3388 18 : void GetZoneLoads(EnergyPlusData &state,
3389 : int const CBVAVNum // Index to CBVAV unit being simulated
3390 : )
3391 : {
3392 :
3393 : // SUBROUTINE INFORMATION:
3394 : // AUTHOR Richard Raustad
3395 : // DATE WRITTEN July 2006
3396 :
3397 : // PURPOSE OF THIS SUBROUTINE:
3398 : // This subroutine is used to poll the thermostats in each zone and determine the
3399 : // mode of operation, either cooling, heating, or none.
3400 :
3401 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3402 18 : Real64 ZoneLoad = 0.0; // Total load in controlled zone [W]
3403 18 : int lastDayOfSim(0); // used during warmup to reset changeOverTimer since need to do same thing next warmup day
3404 :
3405 18 : auto &cBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
3406 :
3407 18 : int dayOfSim = state.dataGlobal->DayOfSim; // DayOfSim increments during Warmup when it actually simulates the same day
3408 18 : if (state.dataGlobal->WarmupFlag) {
3409 : // when warmupday increments then reset timer
3410 0 : if (lastDayOfSim != dayOfSim) cBVAV.changeOverTimer = -1.0; // reset to default (thisTime always > -1)
3411 0 : lastDayOfSim = dayOfSim;
3412 0 : dayOfSim = 1; // reset so that thisTime is <= 24 during warmup
3413 : }
3414 18 : Real64 thisTime = (dayOfSim - 1) * 24 + state.dataGlobal->HourOfDay - 1 + (state.dataGlobal->TimeStep - 1) * state.dataGlobal->TimeStepZone +
3415 18 : state.dataHVACGlobal->SysTimeElapsed;
3416 :
3417 18 : if (thisTime <= cBVAV.changeOverTimer) {
3418 5 : cBVAV.modeChanged = true;
3419 5 : return;
3420 : }
3421 :
3422 13 : Real64 QZoneReqCool = 0.0; // Total cooling load in all controlled zones [W]
3423 13 : Real64 QZoneReqHeat = 0.0; // Total heating load in all controlled zones [W]
3424 13 : cBVAV.NumZonesCooled = 0;
3425 13 : cBVAV.NumZonesHeated = 0;
3426 13 : cBVAV.HeatCoolMode = 0;
3427 :
3428 26 : for (int ZoneNum = 1; ZoneNum <= cBVAV.NumControlledZones; ++ZoneNum) {
3429 13 : int actualZoneNum = cBVAV.ControlledZoneNum(ZoneNum);
3430 13 : int coolSeqNum = cBVAV.ZoneSequenceCoolingNum(ZoneNum);
3431 13 : int heatSeqNum = cBVAV.ZoneSequenceHeatingNum(ZoneNum);
3432 13 : if (coolSeqNum > 0 && heatSeqNum > 0) {
3433 : Real64 ZoneLoadToCoolSPSequenced =
3434 13 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(actualZoneNum).SequencedOutputRequiredToCoolingSP(coolSeqNum);
3435 : Real64 ZoneLoadToHeatSPSequenced =
3436 13 : state.dataZoneEnergyDemand->ZoneSysEnergyDemand(actualZoneNum).SequencedOutputRequiredToHeatingSP(heatSeqNum);
3437 13 : if (ZoneLoadToHeatSPSequenced > 0.0 && ZoneLoadToCoolSPSequenced > 0.0) {
3438 4 : ZoneLoad = ZoneLoadToHeatSPSequenced;
3439 9 : } else if (ZoneLoadToHeatSPSequenced < 0.0 && ZoneLoadToCoolSPSequenced < 0.0) {
3440 5 : ZoneLoad = ZoneLoadToCoolSPSequenced;
3441 4 : } else if (ZoneLoadToHeatSPSequenced <= 0.0 && ZoneLoadToCoolSPSequenced >= 0.0) {
3442 4 : ZoneLoad = 0.0;
3443 : }
3444 13 : } else {
3445 0 : ZoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(actualZoneNum).RemainingOutputRequired;
3446 : }
3447 :
3448 13 : if (!state.dataZoneEnergyDemand->CurDeadBandOrSetback(actualZoneNum)) {
3449 13 : if (ZoneLoad > HVAC::SmallLoad) {
3450 4 : QZoneReqHeat += ZoneLoad;
3451 4 : ++cBVAV.NumZonesHeated;
3452 9 : } else if (ZoneLoad < -HVAC::SmallLoad) {
3453 5 : QZoneReqCool += ZoneLoad;
3454 5 : ++cBVAV.NumZonesCooled;
3455 : }
3456 : }
3457 : }
3458 :
3459 13 : switch (cBVAV.PriorityControl) {
3460 7 : case PriorityCtrlMode::CoolingPriority: {
3461 7 : if (QZoneReqCool < 0.0) {
3462 4 : cBVAV.HeatCoolMode = CoolingMode;
3463 3 : } else if (QZoneReqHeat > 0.0) {
3464 3 : cBVAV.HeatCoolMode = HeatingMode;
3465 : }
3466 7 : } break;
3467 1 : case PriorityCtrlMode::HeatingPriority: {
3468 1 : if (QZoneReqHeat > 0.0) {
3469 1 : cBVAV.HeatCoolMode = HeatingMode;
3470 0 : } else if (QZoneReqCool < 0.0) {
3471 0 : cBVAV.HeatCoolMode = CoolingMode;
3472 : }
3473 1 : } break;
3474 1 : case PriorityCtrlMode::ZonePriority: {
3475 1 : if (cBVAV.NumZonesHeated > cBVAV.NumZonesCooled) {
3476 0 : if (QZoneReqHeat > 0.0) {
3477 0 : cBVAV.HeatCoolMode = HeatingMode;
3478 0 : } else if (QZoneReqCool < 0.0) {
3479 0 : cBVAV.HeatCoolMode = CoolingMode;
3480 : }
3481 1 : } else if (cBVAV.NumZonesCooled > cBVAV.NumZonesHeated) {
3482 1 : if (QZoneReqCool < 0.0) {
3483 1 : cBVAV.HeatCoolMode = CoolingMode;
3484 0 : } else if (QZoneReqHeat > 0.0) {
3485 0 : cBVAV.HeatCoolMode = HeatingMode;
3486 : }
3487 : } else {
3488 0 : if (std::abs(QZoneReqCool) > std::abs(QZoneReqHeat) && QZoneReqCool != 0.0) {
3489 0 : cBVAV.HeatCoolMode = CoolingMode;
3490 0 : } else if (std::abs(QZoneReqCool) < std::abs(QZoneReqHeat) && QZoneReqHeat != 0.0) {
3491 0 : cBVAV.HeatCoolMode = HeatingMode;
3492 0 : } else if (std::abs(QZoneReqCool) == std::abs(QZoneReqHeat) && QZoneReqCool != 0.0) {
3493 0 : cBVAV.HeatCoolMode = CoolingMode;
3494 : }
3495 : }
3496 1 : } break;
3497 0 : case PriorityCtrlMode::LoadPriority: {
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 (cBVAV.NumZonesHeated > cBVAV.NumZonesCooled) {
3503 0 : if (QZoneReqHeat > 0.0) {
3504 0 : cBVAV.HeatCoolMode = HeatingMode;
3505 0 : } else if (QZoneReqCool < 0.0) {
3506 0 : cBVAV.HeatCoolMode = CoolingMode;
3507 : }
3508 0 : } else if (cBVAV.NumZonesHeated < cBVAV.NumZonesCooled) {
3509 0 : if (QZoneReqCool < 0.0) {
3510 0 : cBVAV.HeatCoolMode = CoolingMode;
3511 0 : } else if (QZoneReqHeat > 0.0) {
3512 0 : cBVAV.HeatCoolMode = HeatingMode;
3513 : }
3514 : } else {
3515 0 : if (QZoneReqCool < 0.0) {
3516 0 : cBVAV.HeatCoolMode = CoolingMode;
3517 0 : } else if (QZoneReqHeat > 0.0) {
3518 0 : cBVAV.HeatCoolMode = HeatingMode;
3519 : }
3520 : }
3521 0 : break;
3522 4 : default:
3523 4 : break;
3524 : }
3525 : }
3526 :
3527 13 : if (cBVAV.LastMode != cBVAV.HeatCoolMode) {
3528 7 : cBVAV.changeOverTimer = thisTime + cBVAV.minModeChangeTime;
3529 7 : cBVAV.LastMode = cBVAV.HeatCoolMode;
3530 7 : cBVAV.modeChanged = true;
3531 : }
3532 : }
3533 :
3534 14 : Real64 CalcSetPointTempTarget(EnergyPlusData &state, int const CBVAVNumber) // Index to changeover-bypass VAV system
3535 : {
3536 :
3537 : // FUNCTION INFORMATION:
3538 : // AUTHOR Richard Raustad
3539 : // DATE WRITTEN August 2006
3540 :
3541 : // PURPOSE OF THIS FUNCTION:
3542 : // Calculate outlet air node temperature setpoint
3543 :
3544 : // METHODOLOGY EMPLOYED:
3545 : // Calculate an outlet temperature to satisfy zone loads. This temperature is calculated
3546 : // based on 1 zone's VAV box fully opened. The other VAV boxes are partially open (modulated).
3547 :
3548 : // Return value
3549 : Real64 CalcSetPointTempTarget;
3550 :
3551 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3552 : Real64 ZoneLoad; // Zone load sensed by thermostat [W]
3553 : Real64 QToCoolSetPt; // Zone load to cooling setpoint [W]
3554 : Real64 QToHeatSetPt; // Zone load to heating setpoint [W]
3555 : Real64 SupplyAirTemp; // Supply air temperature required to meet load [C]
3556 : Real64 SupplyAirTempToHeatSetPt; // Supply air temperature required to reach the heating setpoint [C]
3557 : Real64 SupplyAirTempToCoolSetPt; // Supply air temperature required to reach the cooling setpoint [C]
3558 :
3559 14 : auto &cBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNumber);
3560 :
3561 14 : Real64 DXCoolCoilInletTemp = state.dataLoopNodes->Node(cBVAV.DXCoilInletNode).Temp;
3562 14 : Real64 OutAirTemp = state.dataLoopNodes->Node(cBVAV.AirOutNode).Temp;
3563 14 : Real64 OutAirHumRat = state.dataLoopNodes->Node(cBVAV.AirOutNode).HumRat;
3564 :
3565 14 : if (cBVAV.HeatCoolMode == CoolingMode) { // Cooling required
3566 6 : CalcSetPointTempTarget = 99999.0;
3567 8 : } else if (cBVAV.HeatCoolMode == HeatingMode) { // Heating required
3568 4 : CalcSetPointTempTarget = -99999.0;
3569 : }
3570 14 : Real64 TSupplyToHeatSetPtMax = -99999.0; // Maximum of the supply air temperatures required to reach the heating setpoint [C]
3571 14 : Real64 TSupplyToCoolSetPtMin = 99999.0; // Minimum of the supply air temperatures required to reach the cooling setpoint [C]
3572 :
3573 28 : for (int ZoneNum = 1; ZoneNum <= cBVAV.NumControlledZones; ++ZoneNum) {
3574 14 : int ZoneNodeNum = cBVAV.ControlledZoneNodeNum(ZoneNum);
3575 14 : int BoxOutletNodeNum = cBVAV.CBVAVBoxOutletNode(ZoneNum);
3576 14 : if ((cBVAV.ZoneSequenceCoolingNum(ZoneNum) > 0) && (cBVAV.ZoneSequenceHeatingNum(ZoneNum) > 0)) {
3577 14 : QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum))
3578 14 : .SequencedOutputRequiredToCoolingSP(cBVAV.ZoneSequenceCoolingNum(ZoneNum));
3579 14 : QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum))
3580 14 : .SequencedOutputRequiredToHeatingSP(cBVAV.ZoneSequenceHeatingNum(ZoneNum));
3581 14 : if (QToHeatSetPt > 0.0 && QToCoolSetPt > 0.0) {
3582 4 : ZoneLoad = QToHeatSetPt;
3583 10 : } else if (QToHeatSetPt < 0.0 && QToCoolSetPt < 0.0) {
3584 6 : ZoneLoad = QToCoolSetPt;
3585 4 : } else if (QToHeatSetPt <= 0.0 && QToCoolSetPt >= 0.0) {
3586 4 : ZoneLoad = 0.0;
3587 : }
3588 : } else {
3589 0 : ZoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum)).RemainingOutputRequired;
3590 0 : QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum)).OutputRequiredToCoolingSP;
3591 0 : QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum)).OutputRequiredToHeatingSP;
3592 : }
3593 :
3594 14 : Real64 CpSupplyAir = Psychrometrics::PsyCpAirFnW(OutAirHumRat);
3595 :
3596 : // Find the supply air temperature that will force the box to full flow
3597 14 : if (BoxOutletNodeNum > 0) {
3598 14 : if (state.dataLoopNodes->Node(BoxOutletNodeNum).MassFlowRateMax == 0.0) {
3599 0 : SupplyAirTemp = state.dataLoopNodes->Node(ZoneNodeNum).Temp;
3600 : } else {
3601 : // The target supply air temperature is based on current zone temp and load and max box flow rate
3602 14 : SupplyAirTemp = state.dataLoopNodes->Node(ZoneNodeNum).Temp +
3603 14 : ZoneLoad / (CpSupplyAir * state.dataLoopNodes->Node(BoxOutletNodeNum).MassFlowRateMax);
3604 : }
3605 : } else {
3606 0 : SupplyAirTemp = state.dataLoopNodes->Node(ZoneNodeNum).Temp;
3607 : }
3608 :
3609 : // Save the MIN (cooling) or MAX (heating) temperature for coil control
3610 : // One box will always operate at maximum damper position minimizing overall system energy use
3611 14 : if (cBVAV.HeatCoolMode == CoolingMode) {
3612 6 : CalcSetPointTempTarget = min(SupplyAirTemp, CalcSetPointTempTarget);
3613 8 : } else if (cBVAV.HeatCoolMode == HeatingMode) {
3614 4 : CalcSetPointTempTarget = max(SupplyAirTemp, CalcSetPointTempTarget);
3615 : } else {
3616 : // Should use CpAirAtCoolSetPoint or CpAirAtHeatSetPoint here?
3617 : // If so, use ZoneThermostatSetPointLo(ZoneNum) and ZoneThermostatSetPointHi(ZoneNum)
3618 : // along with the zone humidity ratio
3619 4 : if (state.dataLoopNodes->Node(BoxOutletNodeNum).MassFlowRateMax == 0.0) {
3620 0 : SupplyAirTempToHeatSetPt = state.dataLoopNodes->Node(ZoneNodeNum).Temp;
3621 0 : SupplyAirTempToCoolSetPt = state.dataLoopNodes->Node(ZoneNodeNum).Temp;
3622 : } else {
3623 4 : SupplyAirTempToHeatSetPt = state.dataLoopNodes->Node(ZoneNodeNum).Temp +
3624 4 : QToHeatSetPt / (CpSupplyAir * state.dataLoopNodes->Node(BoxOutletNodeNum).MassFlowRateMax);
3625 4 : SupplyAirTempToCoolSetPt = state.dataLoopNodes->Node(ZoneNodeNum).Temp +
3626 4 : QToCoolSetPt / (CpSupplyAir * state.dataLoopNodes->Node(BoxOutletNodeNum).MassFlowRateMax);
3627 : }
3628 4 : TSupplyToHeatSetPtMax = max(SupplyAirTempToHeatSetPt, TSupplyToHeatSetPtMax);
3629 4 : TSupplyToCoolSetPtMin = min(SupplyAirTempToCoolSetPt, TSupplyToCoolSetPtMin);
3630 : }
3631 : }
3632 :
3633 : // Account for floating condition where cooling/heating is required to avoid overshooting setpoint
3634 14 : if (cBVAV.HeatCoolMode == 0) {
3635 4 : if (cBVAV.fanOp == HVAC::FanOp::Continuous) {
3636 0 : if (OutAirTemp > TSupplyToCoolSetPtMin) {
3637 0 : CalcSetPointTempTarget = TSupplyToCoolSetPtMin;
3638 0 : } else if (OutAirTemp < TSupplyToHeatSetPtMax) {
3639 0 : CalcSetPointTempTarget = TSupplyToHeatSetPtMax;
3640 : } else {
3641 0 : CalcSetPointTempTarget = OutAirTemp;
3642 : }
3643 : } else { // Reset setpoint to inlet air temp if unit is OFF and in cycling fan mode
3644 4 : CalcSetPointTempTarget = state.dataLoopNodes->Node(cBVAV.AirInNode).Temp;
3645 : }
3646 : // Reset cooling/heating mode to OFF if mixed air inlet temperature is below/above setpoint temperature.
3647 : // HeatCoolMode = 0 for OFF, 1 for cooling, 2 for heating
3648 10 : } else if (cBVAV.HeatCoolMode == CoolingMode) {
3649 6 : if (DXCoolCoilInletTemp < CalcSetPointTempTarget) CalcSetPointTempTarget = DXCoolCoilInletTemp;
3650 4 : } else if (cBVAV.HeatCoolMode == HeatingMode) {
3651 4 : if (DXCoolCoilInletTemp > CalcSetPointTempTarget) CalcSetPointTempTarget = DXCoolCoilInletTemp;
3652 : }
3653 :
3654 : // Limit outlet node temperature to MAX/MIN specified in input
3655 14 : if (CalcSetPointTempTarget < cBVAV.MinLATCooling) CalcSetPointTempTarget = cBVAV.MinLATCooling;
3656 14 : if (CalcSetPointTempTarget > cBVAV.MaxLATHeating) CalcSetPointTempTarget = cBVAV.MaxLATHeating;
3657 :
3658 14 : return CalcSetPointTempTarget;
3659 : }
3660 :
3661 17 : void SetAverageAirFlow(EnergyPlusData &state,
3662 : int const CBVAVNum, // Index to CBVAV system
3663 : Real64 &OnOffAirFlowRatio // Ratio of compressor ON airflow to average airflow over timestep
3664 : )
3665 : {
3666 :
3667 : // SUBROUTINE INFORMATION:
3668 : // AUTHOR Richard Raustad
3669 : // DATE WRITTEN July 2006
3670 :
3671 : // PURPOSE OF THIS SUBROUTINE:
3672 : // Set the average air mass flow rates for this time step
3673 : // Set OnOffAirFlowRatio to be used by DX coils
3674 :
3675 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3676 : Real64 ZoneMassFlow; // Zone mass flow rate required to meet zone load [kg/s]
3677 : Real64 ZoneLoad; // Zone load calculated by ZoneTempPredictor [W]
3678 :
3679 17 : auto &cBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
3680 :
3681 17 : int InletNode = cBVAV.AirInNode; // Inlet node number for CBVAVNum
3682 17 : int OutletNode = cBVAV.AirOutNode; // Outlet node number for CBVAVNum
3683 17 : int MixerMixedAirNode = cBVAV.MixerMixedAirNode; // Mixed air node number in OA mixer
3684 17 : int MixerOutsideAirNode = cBVAV.MixerOutsideAirNode; // Outside air node number in OA mixer
3685 17 : int MixerReliefAirNode = cBVAV.MixerReliefAirNode; // Relief air node number in OA mixer
3686 17 : int MixerInletAirNode = cBVAV.MixerInletAirNode; // Inlet air node number in OA mixer
3687 :
3688 17 : Real64 SystemMassFlow = 0.0; // System mass flow rate required for all zones [kg/s]
3689 17 : Real64 CpSupplyAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(OutletNode).HumRat); // Specific heat of outlet air [J/kg-K]
3690 : // Determine zone air flow
3691 34 : for (int ZoneNum = 1; ZoneNum <= cBVAV.NumControlledZones; ++ZoneNum) {
3692 17 : int ZoneNodeNum = cBVAV.ControlledZoneNodeNum(ZoneNum);
3693 17 : int BoxOutletNodeNum = cBVAV.CBVAVBoxOutletNode(ZoneNum); // Zone supply air inlet node number
3694 17 : if ((cBVAV.ZoneSequenceCoolingNum(ZoneNum) > 0) && (cBVAV.ZoneSequenceHeatingNum(ZoneNum) > 0)) {
3695 17 : Real64 QToCoolSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum))
3696 17 : .SequencedOutputRequiredToCoolingSP(cBVAV.ZoneSequenceCoolingNum(ZoneNum));
3697 17 : Real64 QToHeatSetPt = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum))
3698 17 : .SequencedOutputRequiredToHeatingSP(cBVAV.ZoneSequenceHeatingNum(ZoneNum));
3699 17 : if (QToHeatSetPt > 0.0 && QToCoolSetPt > 0.0) {
3700 5 : ZoneLoad = QToHeatSetPt;
3701 12 : } else if (QToHeatSetPt < 0.0 && QToCoolSetPt < 0.0) {
3702 8 : ZoneLoad = QToCoolSetPt;
3703 4 : } else if (QToHeatSetPt <= 0.0 && QToCoolSetPt >= 0.0) {
3704 4 : ZoneLoad = 0.0;
3705 : }
3706 : } else {
3707 0 : ZoneLoad = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(cBVAV.ControlledZoneNum(ZoneNum)).RemainingOutputRequired;
3708 : }
3709 17 : Real64 CpZoneAir = Psychrometrics::PsyCpAirFnW(state.dataLoopNodes->Node(ZoneNodeNum).HumRat);
3710 17 : Real64 DeltaCpTemp = CpSupplyAir * state.dataLoopNodes->Node(OutletNode).Temp - CpZoneAir * state.dataLoopNodes->Node(ZoneNodeNum).Temp;
3711 :
3712 : // Need to check DeltaCpTemp and ensure that it is not zero
3713 17 : if (DeltaCpTemp != 0.0) { // .AND. .NOT. CurDeadBandOrSetback(ZoneNum))THEN
3714 16 : ZoneMassFlow = ZoneLoad / DeltaCpTemp;
3715 : } else {
3716 : // reset to 0 so we don't add in the last zone's mass flow rate
3717 1 : ZoneMassFlow = 0.0;
3718 : }
3719 17 : SystemMassFlow += max(state.dataLoopNodes->Node(BoxOutletNodeNum).MassFlowRateMin,
3720 17 : min(ZoneMassFlow, state.dataLoopNodes->Node(BoxOutletNodeNum).MassFlowRateMax));
3721 : }
3722 :
3723 17 : Real64 AverageUnitMassFlow = state.dataHVACUnitaryBypassVAV->CompOnMassFlow;
3724 17 : Real64 AverageOAMassFlow = state.dataHVACUnitaryBypassVAV->OACompOnMassFlow;
3725 17 : state.dataHVACUnitaryBypassVAV->FanSpeedRatio = state.dataHVACUnitaryBypassVAV->CompOnFlowRatio;
3726 :
3727 17 : state.dataLoopNodes->Node(MixerInletAirNode) = state.dataLoopNodes->Node(InletNode);
3728 :
3729 17 : state.dataLoopNodes->Node(MixerMixedAirNode).MassFlowRateMin = 0.0;
3730 :
3731 17 : if (cBVAV.availSched->getCurrentVal() == 0.0 || AverageUnitMassFlow == 0.0) {
3732 1 : state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
3733 1 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRate = 0.0;
3734 1 : state.dataLoopNodes->Node(MixerReliefAirNode).MassFlowRate = 0.0;
3735 1 : OnOffAirFlowRatio = 0.0;
3736 1 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction = 0.0;
3737 : } else {
3738 16 : state.dataLoopNodes->Node(MixerInletAirNode).MassFlowRate = AverageUnitMassFlow;
3739 16 : state.dataLoopNodes->Node(MixerOutsideAirNode).MassFlowRate = AverageOAMassFlow;
3740 16 : state.dataLoopNodes->Node(MixerReliefAirNode).MassFlowRate = AverageOAMassFlow;
3741 16 : OnOffAirFlowRatio = 1.0;
3742 16 : Real64 boxOutletNodeFlow = 0.0;
3743 32 : for (int i = 1; i <= cBVAV.NumControlledZones; ++i) {
3744 16 : boxOutletNodeFlow += state.dataLoopNodes->Node(cBVAV.CBVAVBoxOutletNode(i)).MassFlowRate;
3745 : }
3746 16 : state.dataHVACUnitaryBypassVAV->BypassDuctFlowFraction = max(0.0, 1.0 - (boxOutletNodeFlow / AverageUnitMassFlow));
3747 : }
3748 17 : }
3749 :
3750 0 : void ReportCBVAV(EnergyPlusData &state, int const CBVAVNum) // Index of the current CBVAV unit being simulated
3751 : {
3752 :
3753 : // SUBROUTINE INFORMATION:
3754 : // AUTHOR Richard Raustad
3755 : // DATE WRITTEN July 2006
3756 :
3757 : // PURPOSE OF THIS SUBROUTINE:
3758 : // Fills some of the report variables for the changeover-bypass VAV system
3759 :
3760 0 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
3761 :
3762 0 : Real64 ReportingConstant = state.dataHVACGlobal->TimeStepSysSec;
3763 :
3764 0 : thisCBVAV.TotCoolEnergy = thisCBVAV.TotCoolEnergyRate * ReportingConstant;
3765 0 : thisCBVAV.TotHeatEnergy = thisCBVAV.TotHeatEnergyRate * ReportingConstant;
3766 0 : thisCBVAV.SensCoolEnergy = thisCBVAV.SensCoolEnergyRate * ReportingConstant;
3767 0 : thisCBVAV.SensHeatEnergy = thisCBVAV.SensHeatEnergyRate * ReportingConstant;
3768 0 : thisCBVAV.LatCoolEnergy = thisCBVAV.LatCoolEnergyRate * ReportingConstant;
3769 0 : thisCBVAV.LatHeatEnergy = thisCBVAV.LatHeatEnergyRate * ReportingConstant;
3770 0 : thisCBVAV.ElecConsumption = thisCBVAV.ElecPower * ReportingConstant;
3771 :
3772 0 : if (thisCBVAV.FirstPass) {
3773 0 : if (!state.dataGlobal->SysSizingCalc) {
3774 0 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, state.dataSize->CurSysNum, thisCBVAV.FirstPass);
3775 : }
3776 : }
3777 :
3778 : // reset to 1 in case blow through fan configuration (fan resets to 1, but for blow thru fans coil sets back down < 1)
3779 0 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
3780 0 : }
3781 :
3782 28 : void CalcNonDXHeatingCoils(EnergyPlusData &state,
3783 : int const CBVAVNum, // Changeover bypass VAV unit index
3784 : bool const FirstHVACIteration, // flag for first HVAC iteration in the time step
3785 : Real64 &HeatCoilLoad, // heating coil load to be met (Watts)
3786 : HVAC::FanOp const fanOp, // fan operation mode
3787 : Real64 &HeatCoilLoadmet // coil heating load met
3788 : )
3789 : {
3790 :
3791 : // SUBROUTINE INFORMATION:
3792 : // AUTHOR Bereket Nigusse, FSEC/UCF
3793 : // DATE WRITTEN January 2012
3794 :
3795 : // PURPOSE OF THIS SUBROUTINE:
3796 : // This subroutine simulates the four non dx heating coil types: Gas, Electric, hot water and steam.
3797 :
3798 : // METHODOLOGY EMPLOYED:
3799 : // Simply calls the different heating coil component. The hot water flow rate matching the coil load
3800 : // is calculated iteratively.
3801 :
3802 : // SUBROUTINE PARAMETER DEFINITIONS:
3803 28 : Real64 constexpr ErrTolerance = 0.001; // convergence limit for hotwater coil
3804 28 : int constexpr SolveMaxIter = 50;
3805 :
3806 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3807 : Real64 mdot; // heating coil steam or hot water mass flow rate
3808 : Real64 MinWaterFlow; // minimum water mass flow rate
3809 : Real64 MaxHotWaterFlow; // maximum hot water mass flow rate, kg/s
3810 : Real64 HotWaterMdot; // actual hot water mass flow rate
3811 :
3812 28 : Real64 QCoilActual = 0.0; // actual heating load met
3813 :
3814 28 : auto &thisCBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
3815 :
3816 28 : if (HeatCoilLoad > HVAC::SmallLoad) {
3817 5 : switch (thisCBVAV.HeatCoilType) {
3818 5 : case HVAC::CoilType::HeatingGasOrOtherFuel:
3819 : case HVAC::CoilType::HeatingElectric: {
3820 20 : HeatingCoils::SimulateHeatingCoilComponents(
3821 15 : state, thisCBVAV.HeatCoilName, FirstHVACIteration, HeatCoilLoad, thisCBVAV.HeatCoilIndex, QCoilActual, false, fanOp);
3822 5 : } break;
3823 0 : case HVAC::CoilType::HeatingWater: {
3824 : // simulate the heating coil at maximum hot water flow rate
3825 0 : MaxHotWaterFlow = thisCBVAV.MaxHeatCoilFluidFlow;
3826 0 : PlantUtilities::SetComponentFlowRate(state, MaxHotWaterFlow, thisCBVAV.CoilControlNode, thisCBVAV.CoilOutletNode, thisCBVAV.plantLoc);
3827 0 : WaterCoils::SimulateWaterCoilComponents(
3828 0 : state, thisCBVAV.HeatCoilName, FirstHVACIteration, thisCBVAV.HeatCoilIndex, QCoilActual, fanOp);
3829 0 : if (QCoilActual > (HeatCoilLoad + HVAC::SmallLoad)) {
3830 : // control water flow to obtain output matching HeatCoilLoad
3831 0 : int SolFlag = 0;
3832 0 : MinWaterFlow = 0.0;
3833 0 : auto f = [&state, CBVAVNum, FirstHVACIteration, HeatCoilLoad](Real64 const HWFlow) {
3834 0 : auto &thiscBVAV = state.dataHVACUnitaryBypassVAV->CBVAV(CBVAVNum);
3835 0 : Real64 QCoilActual = HeatCoilLoad;
3836 0 : Real64 mdot = HWFlow;
3837 0 : PlantUtilities::SetComponentFlowRate(state, mdot, thiscBVAV.CoilControlNode, thiscBVAV.CoilOutletNode, thiscBVAV.plantLoc);
3838 : // simulate the hot water supplemental heating coil
3839 0 : WaterCoils::SimulateWaterCoilComponents(
3840 0 : state, thiscBVAV.HeatCoilName, FirstHVACIteration, thiscBVAV.HeatCoilIndex, QCoilActual, thiscBVAV.fanOp);
3841 0 : if (HeatCoilLoad != 0.0) {
3842 0 : return (QCoilActual - HeatCoilLoad) / HeatCoilLoad;
3843 : } else { // Autodesk:Return Condition added to assure return value is set
3844 0 : return 0.0;
3845 : }
3846 0 : };
3847 0 : General::SolveRoot(state, ErrTolerance, SolveMaxIter, SolFlag, HotWaterMdot, f, MinWaterFlow, MaxHotWaterFlow);
3848 0 : if (SolFlag == -1) {
3849 0 : if (thisCBVAV.HotWaterCoilMaxIterIndex == 0) {
3850 0 : ShowWarningMessage(
3851 : state,
3852 0 : format("CalcNonDXHeatingCoils: Hot water coil control failed for {}=\"{}\"", thisCBVAV.UnitType, thisCBVAV.Name));
3853 0 : ShowContinueErrorTimeStamp(state, "");
3854 0 : ShowContinueError(state, format(" Iteration limit [{}] exceeded in calculating hot water mass flow rate", SolveMaxIter));
3855 : }
3856 0 : ShowRecurringWarningErrorAtEnd(
3857 : state,
3858 0 : format("CalcNonDXHeatingCoils: Hot water coil control failed (iteration limit [{}]) for {}=\"{}",
3859 : SolveMaxIter,
3860 0 : thisCBVAV.UnitType,
3861 0 : thisCBVAV.Name),
3862 0 : thisCBVAV.HotWaterCoilMaxIterIndex);
3863 0 : } else if (SolFlag == -2) {
3864 0 : if (thisCBVAV.HotWaterCoilMaxIterIndex2 == 0) {
3865 0 : ShowWarningMessage(state,
3866 0 : format("CalcNonDXHeatingCoils: Hot water coil control failed (maximum flow limits) for {}=\"{}\"",
3867 0 : thisCBVAV.UnitType,
3868 0 : thisCBVAV.Name));
3869 0 : ShowContinueErrorTimeStamp(state, "");
3870 0 : ShowContinueError(state, "...Bad hot water maximum flow rate limits");
3871 0 : ShowContinueError(state, format("...Given minimum water flow rate={:.3R} kg/s", MinWaterFlow));
3872 0 : ShowContinueError(state, format("...Given maximum water flow rate={:.3R} kg/s", MaxHotWaterFlow));
3873 : }
3874 0 : ShowRecurringWarningErrorAtEnd(state,
3875 0 : "CalcNonDXHeatingCoils: Hot water coil control failed (flow limits) for " +
3876 0 : thisCBVAV.UnitType + "=\"" + thisCBVAV.Name + "\"",
3877 0 : thisCBVAV.HotWaterCoilMaxIterIndex2,
3878 : MaxHotWaterFlow,
3879 : MinWaterFlow,
3880 : _,
3881 : "[kg/s]",
3882 : "[kg/s]");
3883 : }
3884 : // simulate the hot water heating coil
3885 0 : QCoilActual = HeatCoilLoad;
3886 : // simulate the hot water heating coil
3887 0 : WaterCoils::SimulateWaterCoilComponents(
3888 0 : state, thisCBVAV.HeatCoilName, FirstHVACIteration, thisCBVAV.HeatCoilIndex, QCoilActual, fanOp);
3889 : }
3890 0 : } break;
3891 0 : case HVAC::CoilType::HeatingSteam: {
3892 0 : mdot = thisCBVAV.MaxHeatCoilFluidFlow;
3893 0 : PlantUtilities::SetComponentFlowRate(state, mdot, thisCBVAV.CoilControlNode, thisCBVAV.CoilOutletNode, thisCBVAV.plantLoc);
3894 :
3895 : // simulate the steam heating coil
3896 0 : SteamCoils::SimulateSteamCoilComponents(
3897 0 : state, thisCBVAV.HeatCoilName, FirstHVACIteration, thisCBVAV.HeatCoilIndex, HeatCoilLoad, QCoilActual, fanOp);
3898 0 : } break;
3899 0 : default:
3900 0 : break;
3901 : }
3902 : } else {
3903 23 : switch (thisCBVAV.HeatCoilType) {
3904 23 : case HVAC::CoilType::HeatingGasOrOtherFuel:
3905 : case HVAC::CoilType::HeatingElectric: {
3906 92 : HeatingCoils::SimulateHeatingCoilComponents(
3907 69 : state, thisCBVAV.HeatCoilName, FirstHVACIteration, HeatCoilLoad, thisCBVAV.HeatCoilIndex, QCoilActual, false, fanOp);
3908 23 : } break;
3909 0 : case HVAC::CoilType::HeatingWater: {
3910 0 : mdot = 0.0;
3911 0 : PlantUtilities::SetComponentFlowRate(state, mdot, thisCBVAV.CoilControlNode, thisCBVAV.CoilOutletNode, thisCBVAV.plantLoc);
3912 0 : QCoilActual = HeatCoilLoad;
3913 : // simulate the hot water heating coil
3914 0 : WaterCoils::SimulateWaterCoilComponents(
3915 0 : state, thisCBVAV.HeatCoilName, FirstHVACIteration, thisCBVAV.HeatCoilIndex, QCoilActual, fanOp);
3916 0 : } break;
3917 0 : case HVAC::CoilType::HeatingSteam: {
3918 0 : mdot = 0.0;
3919 0 : PlantUtilities::SetComponentFlowRate(state, mdot, thisCBVAV.CoilControlNode, thisCBVAV.CoilOutletNode, thisCBVAV.plantLoc);
3920 : // simulate the steam heating coil
3921 0 : SteamCoils::SimulateSteamCoilComponents(
3922 0 : state, thisCBVAV.HeatCoilName, FirstHVACIteration, thisCBVAV.HeatCoilIndex, HeatCoilLoad, QCoilActual, fanOp);
3923 0 : } break;
3924 0 : default:
3925 0 : break;
3926 : }
3927 : }
3928 28 : HeatCoilLoadmet = QCoilActual;
3929 28 : }
3930 :
3931 : } // namespace HVACUnitaryBypassVAV
3932 :
3933 : } // namespace EnergyPlus
|