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