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