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/CoolingAirFlowSizing.hh>
57 : #include <EnergyPlus/Autosizing/CoolingCapacitySizing.hh>
58 : #include <EnergyPlus/Autosizing/HeatingAirFlowSizing.hh>
59 : #include <EnergyPlus/Autosizing/HeatingCapacitySizing.hh>
60 : #include <EnergyPlus/Autosizing/SystemAirFlowSizing.hh>
61 : #include <EnergyPlus/BranchNodeConnections.hh>
62 : #include <EnergyPlus/Construction.hh>
63 : #include <EnergyPlus/Data/EnergyPlusData.hh>
64 : #include <EnergyPlus/DataAirSystems.hh>
65 : #include <EnergyPlus/DataEnvironment.hh>
66 : #include <EnergyPlus/DataHVACGlobals.hh>
67 : #include <EnergyPlus/DataHeatBalFanSys.hh>
68 : #include <EnergyPlus/DataHeatBalSurface.hh>
69 : #include <EnergyPlus/DataHeatBalance.hh>
70 : #include <EnergyPlus/DataIPShortCuts.hh>
71 : #include <EnergyPlus/DataLoopNode.hh>
72 : #include <EnergyPlus/DataSizing.hh>
73 : #include <EnergyPlus/DataSurfaceLists.hh>
74 : #include <EnergyPlus/DataSurfaces.hh>
75 : #include <EnergyPlus/DataZoneEquipment.hh>
76 : #include <EnergyPlus/Fans.hh>
77 : #include <EnergyPlus/FluidProperties.hh>
78 : #include <EnergyPlus/General.hh>
79 : #include <EnergyPlus/GeneralRoutines.hh>
80 : #include <EnergyPlus/HVACFan.hh>
81 : #include <EnergyPlus/HVACHXAssistedCoolingCoil.hh>
82 : #include <EnergyPlus/HeatBalanceSurfaceManager.hh>
83 : #include <EnergyPlus/HeatingCoils.hh>
84 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
85 : #include <EnergyPlus/NodeInputManager.hh>
86 : #include <EnergyPlus/OutAirNodeManager.hh>
87 : #include <EnergyPlus/OutputProcessor.hh>
88 : #include <EnergyPlus/PlantUtilities.hh>
89 : #include <EnergyPlus/Psychrometrics.hh>
90 : #include <EnergyPlus/ScheduleManager.hh>
91 : #include <EnergyPlus/SteamCoils.hh>
92 : #include <EnergyPlus/UtilityRoutines.hh>
93 : #include <EnergyPlus/VentilatedSlab.hh>
94 : #include <EnergyPlus/WaterCoils.hh>
95 : #include <EnergyPlus/ZoneTempPredictorCorrector.hh>
96 :
97 : namespace EnergyPlus {
98 :
99 : namespace VentilatedSlab {
100 :
101 : // Module containing the routines dealing with the Ventilated Slab
102 :
103 : // MODULE INFORMATION:
104 : // AUTHOR Young Tae Chae, Rick Strand
105 : // DATE WRITTEN June 2008
106 : // MODIFIED
107 : // RE-ENGINEERED na
108 :
109 : // PURPOSE OF THIS MODULE:
110 : // Simulate Ventilated Slab Systems.
111 :
112 : // METHODOLOGY EMPLOYED:
113 : // Systems are modeled as a collection of components: radiant panel, outside air mixer,
114 : // fan, heating coil and/or cooling coil plus an integrated control
115 : // algorithm that adjusts the hot or cold water flow to meet the setpoint
116 : // condition. Outside air mixing is handled locally as either fixed percent
117 : // or as attempting to meet a prescribed mixed air temperature.
118 :
119 : // REFERENCES:
120 : // ASHRAE Systems and Equipment Handbook (SI), 1996. pp. 31.1-31.3
121 : // Fred Buhl's fan coil module (FanCoilUnits.cc)
122 :
123 : // Using/Aliasing
124 : using namespace DataLoopNode;
125 : using DataHVACGlobals::ContFanCycCoil;
126 : using DataHVACGlobals::SmallAirVolFlow;
127 : using namespace ScheduleManager;
128 : using namespace Psychrometrics;
129 : using namespace FluidProperties;
130 :
131 771 : static std::string const fluidNameSteam("STEAM");
132 771 : static std::string const fluidNameWater("WATER");
133 771 : std::string const cMO_VentilatedSlab = "ZoneHVAC:VentilatedSlab";
134 :
135 : // int constexpr NotOperating = 0; // Parameter for use with OperatingMode variable, set for no heating/cooling
136 : int constexpr HeatingMode = 1; // Parameter for use with OperatingMode variable, set for heating
137 : int constexpr CoolingMode = 2; // Parameter for use with OperatingMode variable, set for cooling
138 :
139 106951 : void SimVentilatedSlab(EnergyPlusData &state,
140 : std::string const &CompName, // name of the fan coil unit
141 : int const ZoneNum, // number of zone being served
142 : bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
143 : Real64 &PowerMet, // Sensible power supplied (W)
144 : Real64 &LatOutputProvided, // Latent add/removal supplied by window AC (kg/s), dehumid = negative
145 : int &CompIndex)
146 : {
147 :
148 : // SUBROUTINE INFORMATION:
149 : // AUTHOR Rick Strand
150 : // DATE WRITTEN May 2000
151 : // MODIFIED Don Shirey, Aug 2009 (LatOutputProvided)
152 : // RE-ENGINEERED
153 : // This is re-engineered by Rick Strand and Young T. Chae for Ventilated Slab (June, 2008)
154 :
155 : // PURPOSE OF THIS SUBROUTINE:
156 : // This is the main driver subroutine for the Ventilated Slab simulation.
157 :
158 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
159 : int Item; // index of ventilated slab being simulated
160 :
161 106951 : if (state.dataVentilatedSlab->GetInputFlag) {
162 2 : GetVentilatedSlabInput(state);
163 2 : state.dataVentilatedSlab->GetInputFlag = false;
164 : }
165 :
166 : // Find the correct VentilatedSlabInput
167 106951 : if (CompIndex == 0) {
168 7 : Item = UtilityRoutines::FindItemInList(CompName, state.dataVentilatedSlab->VentSlab);
169 7 : if (Item == 0) {
170 0 : ShowFatalError(state, "SimVentilatedSlab: system not found=" + CompName);
171 : }
172 7 : CompIndex = Item;
173 : } else {
174 106944 : Item = CompIndex;
175 106944 : if (Item > state.dataVentilatedSlab->NumOfVentSlabs || Item < 1) {
176 0 : ShowFatalError(state,
177 0 : format("SimVentilatedSlab: Invalid CompIndex passed={}, Number of Systems={}, Entered System name={}",
178 : Item,
179 0 : state.dataVentilatedSlab->NumOfVentSlabs,
180 0 : CompName));
181 : }
182 106944 : if (state.dataVentilatedSlab->CheckEquipName(Item)) {
183 7 : if (CompName != state.dataVentilatedSlab->VentSlab(Item).Name) {
184 0 : ShowFatalError(state,
185 0 : format("SimVentilatedSlab: Invalid CompIndex passed={}, System name={}, stored System Name for that index={}",
186 : Item,
187 : CompName,
188 0 : state.dataVentilatedSlab->VentSlab(Item).Name));
189 : }
190 7 : state.dataVentilatedSlab->CheckEquipName(Item) = false;
191 : }
192 : }
193 :
194 106951 : state.dataSize->ZoneEqVentedSlab = true;
195 :
196 106951 : InitVentilatedSlab(state, Item, ZoneNum, FirstHVACIteration);
197 :
198 106951 : CalcVentilatedSlab(state, Item, ZoneNum, FirstHVACIteration, PowerMet, LatOutputProvided);
199 :
200 106951 : UpdateVentilatedSlab(state, Item, FirstHVACIteration);
201 :
202 106951 : ReportVentilatedSlab(state, Item);
203 :
204 106951 : state.dataSize->ZoneEqVentedSlab = false;
205 106951 : }
206 :
207 2 : void GetVentilatedSlabInput(EnergyPlusData &state)
208 : {
209 :
210 : // SUBROUTINE INFORMATION:
211 : // AUTHOR Young Tae Chae, Rick Strand
212 : // DATE WRITTEN June 2008
213 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
214 : // RE-ENGINEERED na
215 :
216 : // PURPOSE OF THIS SUBROUTINE:
217 : // This subroutine obtains the input for ventilated slab and sets
218 : // up the appropriate derived type.
219 :
220 : // METHODOLOGY EMPLOYED:
221 : // Standard EnergyPlus methodology.
222 :
223 : // REFERENCES:
224 : // Fred Buhl's fan coil module (FanCoilUnits.cc)
225 : // Kwang Ho Lee's Unit Ventilator Module (UnitVentilator.cc)
226 : // Rick Strand's Low temperature Radiant system (RadiantSystemLowTemp.cc)
227 :
228 : // Using/Aliasing
229 : using BranchNodeConnections::SetUpCompSets;
230 : using NodeInputManager::GetOnlySingleNode;
231 2 : auto &GetWaterCoilMaxFlowRate(WaterCoils::GetCoilMaxWaterFlowRate);
232 2 : auto &GetSteamCoilMaxFlowRate(SteamCoils::GetCoilMaxWaterFlowRate);
233 2 : auto &GetHXAssistedCoilFlowRate(HVACHXAssistedCoolingCoil::GetCoilMaxWaterFlowRate);
234 : using HVACHXAssistedCoolingCoil::GetHXCoilTypeAndName;
235 : using ScheduleManager::GetScheduleIndex;
236 : using namespace DataLoopNode;
237 : using namespace DataSurfaceLists;
238 :
239 : using FluidProperties::FindRefrigerant;
240 : using OutAirNodeManager::CheckAndAddAirNodeNumber;
241 :
242 : // SUBROUTINE PARAMETER DEFINITIONS:
243 :
244 2 : constexpr std::array<std::string_view, static_cast<int>(VentilatedSlabConfig::Num)> VentilatedSlabConfigNamesUC{
245 : "SLABONLY", "SLABANDZONE", "SERIESSLABS"};
246 :
247 2 : constexpr std::array<std::string_view, static_cast<int>(ControlType::Num)> ControlTypeNamesUC{
248 : "MEANAIRTEMPERATURE",
249 : "MEANRADIANTTEMPERATURE",
250 : "OPERATIVETEMPERATURE",
251 : "OUTDOORDRYBULBTEMPERATURE",
252 : "OUTDOORWETBULBTEMPERATURE",
253 : "SURFACETEMPERATURE",
254 : "ZONEAIRDEWPOINTTEMPERATURE",
255 : };
256 :
257 2 : static std::string const CurrentModuleObject("ZoneHVAC:VentilatedSlab");
258 :
259 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
260 2 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
261 : int IOStatus; // Used in GetObjectItem
262 : bool IsNotOK; // TRUE if there was a problem with a list name
263 : int NumAlphas; // Number of Alphas for each GetObjectItem call
264 : int NumArgs; // Unused variable that is part of a subroutine call
265 : int NumNumbers; // Number of Numbers for each GetObjectItem call
266 : int Item; // Item to be "gotten"
267 : int BaseNum; // Temporary number for creating RadiantSystemTypes structure
268 : bool errFlag; // interim error flag
269 : int SurfListNum; // Index within the SurfList derived type for a surface list name
270 : int SurfNum; // DO loop counter for surfaces
271 : bool IsValid; // Set for outside air node check
272 4 : Array1D_string cAlphaArgs; // Alpha input items for object
273 4 : Array1D_string cAlphaFields; // Alpha field names
274 4 : Array1D_string cNumericFields; // Numeric field names
275 4 : Array1D<Real64> rNumericArgs; // Numeric input items for object
276 4 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
277 4 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
278 : bool SteamMessageNeeded;
279 :
280 2 : constexpr std::array<std::string_view, static_cast<int>(OutsideAirControlType::Num)> OutsideAirControlTypeNamesUC{
281 : "VARIABLEPERCENT", "FIXEDTEMPERATURE", "FIXEDAMOUNT"};
282 2 : constexpr std::array<std::string_view, static_cast<int>(CoilType::Num)> CoilTypeNamesUC{"NONE", "HEATING", "COOLING", "HEATINGANDCOOLING"};
283 :
284 2 : constexpr std::array<std::string_view, static_cast<int>(HeatingCoilType::Num)> HeatingCoilTypeNamesUC{
285 : "COIL:HEATING:ELECTRIC", "COIL:HEATING:FUEL", "COIL:HEATING:WATER", "COIL:HEATING:STEAM"};
286 2 : constexpr std::array<std::string_view, static_cast<int>(CoolingCoilType::Num)> CoolingCoilTypeNamesUC{
287 : "COIL:COOLING:WATER", "COIL:COOLING:WATER:DETAILEDGEOMETRY", "COILSYSTEM:COOLING:WATER:HEATEXCHANGERASSISTED"};
288 :
289 : // Figure out how many Ventilated Slab Systems there are in the input file
290 :
291 2 : SteamMessageNeeded = true;
292 2 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, NumArgs, NumAlphas, NumNumbers);
293 2 : cAlphaArgs.allocate(NumAlphas);
294 2 : cAlphaFields.allocate(NumAlphas);
295 2 : cNumericFields.allocate(NumNumbers);
296 2 : rNumericArgs.dimension(NumNumbers, 0.0);
297 2 : lAlphaBlanks.dimension(NumAlphas, true);
298 2 : lNumericBlanks.dimension(NumNumbers, true);
299 :
300 : // make sure data is gotten for surface lists
301 2 : BaseNum = GetNumberOfSurfListVentSlab(state);
302 :
303 2 : state.dataVentilatedSlab->NumOfVentSlabs = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
304 : // Allocate the local derived type and do one-time initializations for all parts of it
305 :
306 2 : state.dataVentilatedSlab->VentSlab.allocate(state.dataVentilatedSlab->NumOfVentSlabs);
307 2 : state.dataVentilatedSlab->CheckEquipName.dimension(state.dataVentilatedSlab->NumOfVentSlabs, true);
308 2 : state.dataVentilatedSlab->VentSlabNumericFields.allocate(state.dataVentilatedSlab->NumOfVentSlabs);
309 :
310 9 : for (Item = 1; Item <= state.dataVentilatedSlab->NumOfVentSlabs;
311 : ++Item) { // Begin looping over the entire ventilated slab systems found in the input file...
312 :
313 21 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
314 : CurrentModuleObject,
315 : Item,
316 7 : state.dataIPShortCut->cAlphaArgs,
317 : NumAlphas,
318 7 : state.dataIPShortCut->rNumericArgs,
319 : NumNumbers,
320 : IOStatus,
321 : lNumericBlanks,
322 : lAlphaBlanks,
323 : cAlphaFields,
324 : cNumericFields);
325 :
326 7 : state.dataVentilatedSlab->VentSlabNumericFields(Item).FieldNames.allocate(NumNumbers);
327 7 : state.dataVentilatedSlab->VentSlabNumericFields(Item).FieldNames = cNumericFields;
328 7 : UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), CurrentModuleObject, ErrorsFound);
329 7 : auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
330 :
331 7 : ventSlab.Name = state.dataIPShortCut->cAlphaArgs(1);
332 7 : if (lAlphaBlanks(2)) {
333 0 : ventSlab.SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
334 7 : } else if ((ventSlab.SchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(2))) == 0) { // convert schedule name to pointer
335 0 : ShowSevereError(state,
336 0 : format(R"({}="{}" invalid {}="{}" not found.)",
337 : CurrentModuleObject,
338 : ventSlab.Name,
339 : cAlphaFields(2),
340 0 : state.dataIPShortCut->cAlphaArgs(2)));
341 0 : ErrorsFound = true;
342 : }
343 :
344 7 : ventSlab.ZonePtr = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(3), state.dataHeatBal->Zone);
345 7 : if (ventSlab.ZonePtr == 0) {
346 0 : if (lAlphaBlanks(3)) {
347 0 : ShowSevereError(
348 0 : state, format(R"({}="{}" invalid {} is required but input is blank.)", CurrentModuleObject, ventSlab.Name, cAlphaFields(3)));
349 : } else {
350 0 : ShowSevereError(state,
351 0 : format(R"({}="{}" invalid {}="{}" not found.)",
352 : CurrentModuleObject,
353 : ventSlab.Name,
354 : cAlphaFields(3),
355 0 : state.dataIPShortCut->cAlphaArgs(3)));
356 : }
357 0 : ErrorsFound = true;
358 : }
359 :
360 7 : ventSlab.SurfListName = state.dataIPShortCut->cAlphaArgs(4);
361 7 : SurfListNum = 0;
362 : // IF (NumOfSlabLists > 0) SurfListNum = UtilityRoutines::FindItemInList(VentSlab(Item)%SurfListName, SlabList%Name, NumOfSlabLists)
363 7 : if (state.dataSurfLists->NumOfSurfListVentSlab > 0)
364 2 : SurfListNum = UtilityRoutines::FindItemInList(ventSlab.SurfListName, state.dataSurfLists->SlabList);
365 7 : if (SurfListNum > 0) { // Found a valid surface list
366 2 : ventSlab.NumOfSurfaces = state.dataSurfLists->SlabList(SurfListNum).NumOfSurfaces;
367 2 : ventSlab.ZName.allocate(ventSlab.NumOfSurfaces);
368 2 : ventSlab.ZPtr.allocate(ventSlab.NumOfSurfaces);
369 2 : ventSlab.SurfaceName.allocate(ventSlab.NumOfSurfaces);
370 2 : ventSlab.SurfacePtr.allocate(ventSlab.NumOfSurfaces);
371 2 : ventSlab.CDiameter.allocate(ventSlab.NumOfSurfaces);
372 2 : ventSlab.CLength.allocate(ventSlab.NumOfSurfaces);
373 2 : ventSlab.CNumbers.allocate(ventSlab.NumOfSurfaces);
374 2 : ventSlab.SlabIn.allocate(ventSlab.NumOfSurfaces);
375 2 : ventSlab.SlabOut.allocate(ventSlab.NumOfSurfaces);
376 :
377 2 : state.dataVentilatedSlab->MaxCloNumOfSurfaces = max(state.dataVentilatedSlab->MaxCloNumOfSurfaces, ventSlab.NumOfSurfaces);
378 7 : for (SurfNum = 1; SurfNum <= state.dataSurfLists->SlabList(SurfListNum).NumOfSurfaces; ++SurfNum) {
379 5 : ventSlab.ZName(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).ZoneName(SurfNum);
380 5 : ventSlab.ZPtr(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).ZonePtr(SurfNum);
381 5 : ventSlab.SurfaceName(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).SurfName(SurfNum);
382 5 : ventSlab.SurfacePtr(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).SurfPtr(SurfNum);
383 5 : ventSlab.CDiameter(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).CoreDiameter(SurfNum);
384 5 : ventSlab.CLength(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).CoreLength(SurfNum);
385 5 : ventSlab.CNumbers(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).CoreNumbers(SurfNum);
386 5 : ventSlab.SlabIn(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).SlabInNodeName(SurfNum);
387 5 : ventSlab.SlabOut(SurfNum) = state.dataSurfLists->SlabList(SurfListNum).SlabOutNodeName(SurfNum);
388 5 : if (ventSlab.SurfacePtr(SurfNum) != 0) {
389 5 : state.dataSurface->SurfIntConvSurfHasActiveInIt(ventSlab.SurfacePtr(SurfNum)) = true;
390 : }
391 : }
392 :
393 : } else { // User entered a single surface name rather than a surface list
394 5 : ventSlab.NumOfSurfaces = 1;
395 5 : ventSlab.SurfacePtr.allocate(ventSlab.NumOfSurfaces);
396 5 : ventSlab.SurfaceName.allocate(ventSlab.NumOfSurfaces);
397 5 : ventSlab.SurfaceFlowFrac.allocate(ventSlab.NumOfSurfaces);
398 5 : state.dataVentilatedSlab->MaxCloNumOfSurfaces = max(state.dataVentilatedSlab->MaxCloNumOfSurfaces, ventSlab.NumOfSurfaces);
399 5 : ventSlab.SurfaceName(1) = ventSlab.SurfListName;
400 5 : ventSlab.SurfacePtr(1) = UtilityRoutines::FindItemInList(ventSlab.SurfaceName(1), state.dataSurface->Surface);
401 5 : ventSlab.SurfaceFlowFrac(1) = 1.0;
402 : // Error checking for single surfaces
403 5 : if (ventSlab.SurfacePtr(1) == 0) {
404 0 : ShowSevereError(state,
405 0 : format(R"({}="{}" invalid {}="{}" not found.)",
406 : CurrentModuleObject,
407 : ventSlab.Name,
408 : cAlphaFields(4),
409 0 : state.dataIPShortCut->cAlphaArgs(4)));
410 0 : ErrorsFound = true;
411 5 : } else if (state.dataSurface->SurfIsRadSurfOrVentSlabOrPool(ventSlab.SurfacePtr(1))) {
412 0 : ShowSevereError(state, CurrentModuleObject + "=\"" + ventSlab.Name + "\", invalid Surface");
413 0 : ShowContinueError(state,
414 0 : cAlphaFields(4) + "=\"" + state.dataIPShortCut->cAlphaArgs(4) +
415 : "\" has been used in another radiant system or ventilated slab.");
416 0 : ErrorsFound = true;
417 : }
418 5 : if (ventSlab.SurfacePtr(1) != 0) {
419 5 : state.dataSurface->SurfIntConvSurfHasActiveInIt(ventSlab.SurfacePtr(1)) = true;
420 5 : state.dataSurface->SurfIsRadSurfOrVentSlabOrPool(ventSlab.SurfacePtr(1)) = true;
421 : }
422 : }
423 :
424 : // Error checking for zones and construction information
425 :
426 7 : if (SurfListNum > 0) {
427 :
428 7 : for (SurfNum = 1; SurfNum <= ventSlab.NumOfSurfaces; ++SurfNum) {
429 :
430 5 : if (ventSlab.SurfacePtr(SurfNum) == 0) continue; // invalid surface -- detected earlier
431 5 : if (ventSlab.ZPtr(SurfNum) == 0) continue; // invalid zone -- detected earlier
432 5 : if (state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Construction == 0)
433 0 : continue; // invalid construction, detected earlier
434 5 : if (!state.dataConstruction->Construct(state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Construction).SourceSinkPresent) {
435 0 : ShowSevereError(state,
436 0 : CurrentModuleObject + "=\"" + ventSlab.Name + "\" invalid surface=\"" +
437 0 : state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Name + "\".");
438 0 : ShowContinueError(
439 : state,
440 0 : "Surface Construction does not have a source/sink, Construction name= \"" +
441 0 : state.dataConstruction->Construct(state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Construction).Name +
442 : "\".");
443 0 : ErrorsFound = true;
444 : }
445 : }
446 : } else {
447 10 : for (SurfNum = 1; SurfNum <= ventSlab.NumOfSurfaces; ++SurfNum) {
448 5 : if (ventSlab.SurfacePtr(SurfNum) == 0) continue; // invalid surface -- detected earlier
449 5 : if (ventSlab.ZonePtr == 0) continue; // invalid zone -- detected earlier
450 5 : if (state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Zone != ventSlab.ZonePtr) {
451 0 : ShowSevereError(state,
452 0 : CurrentModuleObject + "=\"" + ventSlab.Name + "\" invalid surface=\"" +
453 0 : state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Name + "\".");
454 0 : ShowContinueError(
455 : state,
456 0 : "Surface in Zone=" + state.dataHeatBal->Zone(state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Zone).Name + ' ' +
457 0 : CurrentModuleObject + " in Zone=" + state.dataIPShortCut->cAlphaArgs(3));
458 0 : ErrorsFound = true;
459 : }
460 5 : if (state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Construction == 0)
461 0 : continue; // invalid construction, detected earlier
462 5 : if (!state.dataConstruction->Construct(state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Construction).SourceSinkPresent) {
463 0 : ShowSevereError(state,
464 0 : CurrentModuleObject + "=\"" + ventSlab.Name + "\" invalid surface=\"" +
465 0 : state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Name + "\".");
466 0 : ShowContinueError(
467 : state,
468 0 : "Surface Construction does not have a source/sink, Construction name= \"" +
469 0 : state.dataConstruction->Construct(state.dataSurface->Surface(ventSlab.SurfacePtr(SurfNum)).Construction).Name +
470 : "\".");
471 0 : ErrorsFound = true;
472 : }
473 : }
474 : }
475 :
476 7 : ventSlab.MaxAirVolFlow = state.dataIPShortCut->rNumericArgs(1);
477 :
478 : // Outside air information:
479 7 : ventSlab.MinOutAirVolFlow = state.dataIPShortCut->rNumericArgs(2);
480 7 : ventSlab.OutAirVolFlow = state.dataIPShortCut->rNumericArgs(3);
481 :
482 7 : ventSlab.outsideAirControlType = static_cast<OutsideAirControlType>(
483 14 : getEnumerationValue(OutsideAirControlTypeNamesUC, UtilityRoutines::MakeUPPERCase(state.dataIPShortCut->cAlphaArgs(5))));
484 :
485 7 : switch (ventSlab.outsideAirControlType) {
486 7 : case OutsideAirControlType::VariablePercent: {
487 7 : ventSlab.MaxOASchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(7)); // convert schedule name to pointer
488 7 : if (ventSlab.MaxOASchedPtr == 0) {
489 0 : ShowSevereError(state,
490 0 : format(R"({}="{}" invalid {}="{}" not found.)",
491 : CurrentModuleObject,
492 : ventSlab.Name,
493 : cAlphaFields(7),
494 0 : state.dataIPShortCut->cAlphaArgs(7)));
495 0 : ErrorsFound = true;
496 7 : } else if (!CheckScheduleValueMinMax(state, ventSlab.MaxOASchedPtr, ">=0", 0.0, "<=", 1.0)) {
497 0 : ShowSevereError(state,
498 0 : CurrentModuleObject + "=\"" + ventSlab.Name + "\" invalid " + cAlphaFields(7) + "=\"" +
499 0 : state.dataIPShortCut->cAlphaArgs(7) + "\" values out of range [0,1].");
500 0 : ErrorsFound = true;
501 : }
502 7 : break;
503 : }
504 0 : case OutsideAirControlType::FixedOAControl: {
505 0 : ventSlab.MaxOASchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(7)); // convert schedule name to pointer
506 0 : if (ventSlab.MaxOASchedPtr == 0) {
507 0 : ShowSevereError(state,
508 0 : format(R"({}="{}" invalid {}="{}" not found.)",
509 : CurrentModuleObject,
510 : ventSlab.Name,
511 : cAlphaFields(7),
512 0 : state.dataIPShortCut->cAlphaArgs(7)));
513 0 : ErrorsFound = true;
514 0 : } else if (!CheckScheduleValueMinMax(state, ventSlab.MaxOASchedPtr, ">=0", 0.0)) {
515 0 : ShowSevereError(state,
516 0 : CurrentModuleObject + "=\"" + ventSlab.Name + "\" invalid " + cAlphaFields(7) + "=\"" +
517 0 : state.dataIPShortCut->cAlphaArgs(7) + "\" values out of range (must be >=0).");
518 0 : ErrorsFound = true;
519 : }
520 0 : break;
521 : }
522 0 : case OutsideAirControlType::FixedTemperature: {
523 0 : ventSlab.TempSchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(7)); // convert schedule name to pointer
524 0 : if (ventSlab.TempSchedPtr == 0) {
525 0 : ShowSevereError(state,
526 0 : format(R"({}="{}" invalid {}="{}" not found.)",
527 : CurrentModuleObject,
528 : ventSlab.Name,
529 : cAlphaFields(7),
530 0 : state.dataIPShortCut->cAlphaArgs(7)));
531 0 : ErrorsFound = true;
532 : }
533 0 : break;
534 : }
535 0 : default: {
536 0 : ShowSevereError(
537 : state,
538 0 : format(R"({}="{}" invalid {}="{}".)", CurrentModuleObject, ventSlab.Name, cAlphaFields(5), state.dataIPShortCut->cAlphaArgs(5)));
539 : }
540 : }
541 :
542 7 : ventSlab.MinOASchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(6)); // convert schedule name to pointer
543 7 : if (ventSlab.MinOASchedPtr == 0) {
544 0 : ShowSevereError(state,
545 0 : format(R"({}="{}" invalid {}="{}" not found.)",
546 : CurrentModuleObject,
547 : ventSlab.Name,
548 : cAlphaFields(6),
549 0 : state.dataIPShortCut->cAlphaArgs(6)));
550 0 : ErrorsFound = true;
551 : }
552 :
553 : // System Configuration:
554 7 : ventSlab.SysConfg = static_cast<VentilatedSlabConfig>(
555 14 : getEnumerationValue(VentilatedSlabConfigNamesUC, UtilityRoutines::MakeUPPERCase(state.dataIPShortCut->cAlphaArgs(8))));
556 :
557 7 : if (ventSlab.SysConfg == VentilatedSlabConfig::Invalid) {
558 0 : ShowSevereError(
559 : state,
560 0 : format(R"({}="{}" invalid {}="{}".)", CurrentModuleObject, ventSlab.Name, cAlphaFields(8), state.dataIPShortCut->cAlphaArgs(8)));
561 0 : ShowContinueError(state, "Control reset to SLAB ONLY Configuration.");
562 0 : ventSlab.SysConfg = VentilatedSlabConfig::SlabOnly;
563 : }
564 :
565 : // Hollow Core information :
566 7 : ventSlab.CoreDiameter = state.dataIPShortCut->rNumericArgs(4);
567 7 : ventSlab.CoreLength = state.dataIPShortCut->rNumericArgs(5);
568 7 : ventSlab.CoreNumbers = state.dataIPShortCut->rNumericArgs(6);
569 :
570 7 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(8), "SurfaceListNames")) {
571 0 : if (!lNumericBlanks(4)) {
572 0 : ShowWarningError(state,
573 0 : CurrentModuleObject + "=\"" + ventSlab.Name +
574 : "\" Core Diameter is not needed for the series slabs configuration- ignored.");
575 0 : ShowContinueError(state, "...It has been assigned on SlabGroup.");
576 : }
577 : }
578 :
579 7 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(8), "SurfaceListNames")) {
580 0 : if (!lNumericBlanks(5)) {
581 0 : ShowWarningError(state,
582 0 : CurrentModuleObject + "=\"" + ventSlab.Name +
583 : "\" Core Length is not needed for the series slabs configuration- ignored.");
584 0 : ShowContinueError(state, "...It has been assigned on SlabGroup.");
585 : }
586 : }
587 :
588 7 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(8), "SurfaceListNames")) {
589 0 : if (!lNumericBlanks(6)) {
590 0 : ShowWarningError(state,
591 0 : CurrentModuleObject + "=\"" + ventSlab.Name +
592 : "\" Core Numbers is not needed for the series slabs configuration- ignored.");
593 0 : ShowContinueError(state, "...It has been assigned on SlabGroup.");
594 : }
595 : }
596 :
597 : // Process the temperature control type
598 7 : ventSlab.controlType = static_cast<ControlType>(
599 14 : getEnumerationValue(ControlTypeNamesUC, UtilityRoutines::MakeUPPERCase(state.dataIPShortCut->cAlphaArgs(9))));
600 :
601 7 : if (ventSlab.controlType == ControlType::Invalid) {
602 0 : ShowSevereError(
603 : state,
604 0 : format(R"({}="{}" invalid {}="{}".)", CurrentModuleObject, ventSlab.Name, cAlphaFields(9), state.dataIPShortCut->cAlphaArgs(9)));
605 0 : ShowContinueError(state, "Control reset to ODB control.");
606 0 : ventSlab.controlType = ControlType::OutdoorDryBulbTemp;
607 : }
608 :
609 : // Heating User Input Data For Ventilated Slab Control :
610 :
611 : // High Air Temp :
612 7 : ventSlab.HotAirHiTempSchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(10));
613 7 : if ((ventSlab.HotAirHiTempSchedPtr == 0) && (!lAlphaBlanks(10))) {
614 0 : ShowSevereError(state,
615 0 : format(R"({}="{}" invalid {}="{}" not found.)",
616 : CurrentModuleObject,
617 : ventSlab.Name,
618 : cAlphaFields(10),
619 0 : state.dataIPShortCut->cAlphaArgs(10)));
620 0 : ErrorsFound = true;
621 : }
622 :
623 : // Low Air Temp :
624 :
625 7 : ventSlab.HotAirLoTempSchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(11));
626 7 : if ((ventSlab.HotAirLoTempSchedPtr == 0) && (!lAlphaBlanks(11))) {
627 0 : ShowSevereError(state,
628 0 : format(R"({}="{}" invalid {}="{}" not found.)",
629 : CurrentModuleObject,
630 : ventSlab.Name,
631 : cAlphaFields(11),
632 0 : state.dataIPShortCut->cAlphaArgs(11)));
633 0 : ErrorsFound = true;
634 : }
635 :
636 7 : ventSlab.HotCtrlHiTempSchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(12));
637 7 : if ((ventSlab.HotCtrlHiTempSchedPtr == 0) && (!lAlphaBlanks(12))) {
638 0 : ShowSevereError(state,
639 0 : format(R"({}="{}" invalid {}="{}" not found.)",
640 : CurrentModuleObject,
641 : ventSlab.Name,
642 : cAlphaFields(12),
643 0 : state.dataIPShortCut->cAlphaArgs(12)));
644 0 : ErrorsFound = true;
645 : }
646 :
647 7 : ventSlab.HotCtrlLoTempSchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(13));
648 7 : if ((ventSlab.HotCtrlLoTempSchedPtr == 0) && (!lAlphaBlanks(13))) {
649 0 : ShowSevereError(state,
650 0 : format(R"({}="{}" invalid {}="{}" not found.)",
651 : CurrentModuleObject,
652 : ventSlab.Name,
653 : cAlphaFields(13),
654 0 : state.dataIPShortCut->cAlphaArgs(13)));
655 0 : ErrorsFound = true;
656 : }
657 :
658 : // Cooling User Input Data For Ventilated Slab Control :
659 : // Cooling High Temp Sch.
660 7 : ventSlab.ColdAirHiTempSchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(14));
661 7 : if ((ventSlab.ColdAirHiTempSchedPtr == 0) && (!lAlphaBlanks(14))) {
662 0 : ShowSevereError(state,
663 0 : format(R"({}="{}" invalid {}="{}" not found.)",
664 : CurrentModuleObject,
665 : ventSlab.Name,
666 : cAlphaFields(14),
667 0 : state.dataIPShortCut->cAlphaArgs(14)));
668 0 : ErrorsFound = true;
669 : }
670 :
671 : // Cooling Low Temp Sch.
672 :
673 7 : ventSlab.ColdAirLoTempSchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(15));
674 7 : if ((ventSlab.ColdAirLoTempSchedPtr == 0) && (!lAlphaBlanks(15))) {
675 0 : ShowSevereError(state,
676 0 : format(R"({}="{}" invalid {}="{}" not found.)",
677 : CurrentModuleObject,
678 : ventSlab.Name,
679 : cAlphaFields(15),
680 0 : state.dataIPShortCut->cAlphaArgs(15)));
681 0 : ErrorsFound = true;
682 : }
683 :
684 : // Cooling Control High Sch.
685 :
686 7 : ventSlab.ColdCtrlHiTempSchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(16));
687 7 : if ((ventSlab.ColdCtrlHiTempSchedPtr == 0) && (!lAlphaBlanks(16))) {
688 0 : ShowSevereError(state,
689 0 : format(R"({}="{}" invalid {}="{}" not found.)",
690 : CurrentModuleObject,
691 : ventSlab.Name,
692 : cAlphaFields(16),
693 0 : state.dataIPShortCut->cAlphaArgs(16)));
694 0 : ErrorsFound = true;
695 : }
696 :
697 : // Cooling Control Low Sch.
698 :
699 7 : ventSlab.ColdCtrlLoTempSchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(17));
700 7 : if ((ventSlab.ColdCtrlLoTempSchedPtr == 0) && (!lAlphaBlanks(17))) {
701 0 : ShowSevereError(state,
702 0 : format(R"({}="{}" invalid {}="{}" not found.)",
703 : CurrentModuleObject,
704 : ventSlab.Name,
705 : cAlphaFields(17),
706 0 : state.dataIPShortCut->cAlphaArgs(17)));
707 0 : ErrorsFound = true;
708 : }
709 :
710 : // Main air nodes (except outside air node):
711 : // Refer the Unit Ventilator Air Node note
712 :
713 : // MJW CR7903 - Ventilated slab was not drawing properly in HVAC Diagram svg output
714 : // This object is structured differently from other zone equipment in that it functions
715 : // as both a parent and non-parent, and it has an implicit OA mixer. This makes it difficult
716 : // to register the nodes in a way that HVAC Diagram can understand and in a way that satisfies
717 : // node connection tests. Here's an explanation of the changes made for this CR:
718 : // In general, nodes associated with the ventilated slab system (the overall parent object)
719 : // are registered with "-SYSTEM" appended to the object type and object name
720 : // This same suffix is also added later when SetUpCompSets is called, for the same reason
721 : // In general, nodes associated with the implicit OA mixer object
722 : // are registered with "-OA MIXER" appended to the object type and object name
723 : // %ReturnAirNode is one inlet to the implicit oa mixer
724 : // For SlabOnly and SeriesSlab this node does nothing,
725 : // so DataLoopNode::NodeConnectionType::Internal,ObjectIsNotParent, -OA MIXER
726 : // For SlabandZone, this node extracts air from the zone,
727 : // so DataLoopNode::NodeConnectionType::Inlet,ObjectIsNotParent, -OA MIXER
728 : // For SlabandZone, this node is also used to associate the whole system with a pair of zone inlet/exhaust nodes,
729 : // so it is registered again as DataLoopNode::NodeConnectionType::Inlet,1,ObjectIsParent, -SYSTEM
730 : // %RadInNode is the ultimate air inlet to the slab or series of slabs
731 : // For all types of ventilated slab, this is DataLoopNode::NodeConnectionType::Inlet,ObjectIsNotParent
732 : // %OAMixerOutNode is the outlet from the implicit OA mixer
733 : // For all types of ventilated slab, this is DataLoopNode::NodeConnectionType::Outlet,ObjectIsNotParent
734 : // %FanOutletNode is the outlet from the explicit fan child object (redundant input, should mine from child)
735 : // For all types of ventilated slab, this is DataLoopNode::NodeConnectionType::Internal,ObjectIsParent
736 : // %ZoneAirInNode is applicable only to SlabandZone configuration. It is the node that flows into the zone,
737 : // and it is also the outlet from the ventilated slab section, so it must be registered twice
738 : // First for the overall system, DataLoopNode::NodeConnectionType::Outlet,ObjectIsParent, -SYSTEM
739 : // Second as the slab outlet, DataLoopNode::NodeConnectionType::Outlet,ObjectIsNotParent
740 : // %OutsideAirNode is the outdoor air inlet to the OA mixer
741 : // For all types of ventilated slab, this is DataLoopNode::NodeConnectionType::Inlet,ObjectIsNotParent, -OA MIXER
742 :
743 7 : if (ventSlab.SysConfg == VentilatedSlabConfig::SlabOnly) {
744 :
745 4 : ventSlab.ReturnAirNode = GetOnlySingleNode(state,
746 2 : state.dataIPShortCut->cAlphaArgs(18),
747 : ErrorsFound,
748 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
749 4 : ventSlab.Name + "-OA MIXER",
750 : DataLoopNode::NodeFluidType::Air,
751 : DataLoopNode::ConnectionType::Internal,
752 : NodeInputManager::CompFluidStream::Primary,
753 2 : ObjectIsNotParent);
754 4 : ventSlab.RadInNode = GetOnlySingleNode(state,
755 2 : state.dataIPShortCut->cAlphaArgs(19),
756 : ErrorsFound,
757 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
758 : ventSlab.Name,
759 : DataLoopNode::NodeFluidType::Air,
760 : DataLoopNode::ConnectionType::Inlet,
761 : NodeInputManager::CompFluidStream::Primary,
762 2 : ObjectIsNotParent);
763 :
764 4 : ventSlab.OAMixerOutNode = GetOnlySingleNode(state,
765 2 : state.dataIPShortCut->cAlphaArgs(23),
766 : ErrorsFound,
767 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
768 4 : ventSlab.Name + "-OA MIXER",
769 : DataLoopNode::NodeFluidType::Air,
770 : DataLoopNode::ConnectionType::Outlet,
771 : NodeInputManager::CompFluidStream::Primary,
772 2 : ObjectIsNotParent);
773 4 : ventSlab.FanOutletNode = GetOnlySingleNode(state,
774 2 : state.dataIPShortCut->cAlphaArgs(24),
775 : ErrorsFound,
776 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
777 : ventSlab.Name,
778 : DataLoopNode::NodeFluidType::Air,
779 : DataLoopNode::ConnectionType::Internal,
780 : NodeInputManager::CompFluidStream::Primary,
781 2 : ObjectIsParent);
782 :
783 5 : } else if (ventSlab.SysConfg == VentilatedSlabConfig::SeriesSlabs) {
784 :
785 4 : ventSlab.ReturnAirNode = GetOnlySingleNode(state,
786 2 : state.dataIPShortCut->cAlphaArgs(18),
787 : ErrorsFound,
788 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
789 4 : ventSlab.Name + "-OA MIXER",
790 : DataLoopNode::NodeFluidType::Air,
791 : DataLoopNode::ConnectionType::Internal,
792 : NodeInputManager::CompFluidStream::Primary,
793 2 : ObjectIsNotParent);
794 4 : ventSlab.RadInNode = GetOnlySingleNode(state,
795 2 : state.dataIPShortCut->cAlphaArgs(19),
796 : ErrorsFound,
797 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
798 : ventSlab.Name,
799 : DataLoopNode::NodeFluidType::Air,
800 : DataLoopNode::ConnectionType::Inlet,
801 : NodeInputManager::CompFluidStream::Primary,
802 2 : ObjectIsNotParent);
803 :
804 4 : ventSlab.OAMixerOutNode = GetOnlySingleNode(state,
805 2 : state.dataIPShortCut->cAlphaArgs(23),
806 : ErrorsFound,
807 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
808 4 : ventSlab.Name + "-OA MIXER",
809 : DataLoopNode::NodeFluidType::Air,
810 : DataLoopNode::ConnectionType::Outlet,
811 : NodeInputManager::CompFluidStream::Primary,
812 2 : ObjectIsNotParent);
813 4 : ventSlab.FanOutletNode = GetOnlySingleNode(state,
814 2 : state.dataIPShortCut->cAlphaArgs(24),
815 : ErrorsFound,
816 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
817 : ventSlab.Name,
818 : DataLoopNode::NodeFluidType::Air,
819 : DataLoopNode::ConnectionType::Internal,
820 : NodeInputManager::CompFluidStream::Primary,
821 2 : ObjectIsParent);
822 :
823 3 : } else if (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone) {
824 :
825 6 : ventSlab.ReturnAirNode = GetOnlySingleNode(state,
826 3 : state.dataIPShortCut->cAlphaArgs(18),
827 : ErrorsFound,
828 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
829 6 : ventSlab.Name + "-SYSTEM",
830 : DataLoopNode::NodeFluidType::Air,
831 : DataLoopNode::ConnectionType::Inlet,
832 : NodeInputManager::CompFluidStream::Primary,
833 3 : ObjectIsParent);
834 6 : ventSlab.ReturnAirNode = GetOnlySingleNode(state,
835 3 : state.dataIPShortCut->cAlphaArgs(18),
836 : ErrorsFound,
837 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
838 6 : ventSlab.Name + "-OA MIXER",
839 : DataLoopNode::NodeFluidType::Air,
840 : DataLoopNode::ConnectionType::Inlet,
841 : NodeInputManager::CompFluidStream::Primary,
842 3 : ObjectIsNotParent);
843 6 : ventSlab.RadInNode = GetOnlySingleNode(state,
844 3 : state.dataIPShortCut->cAlphaArgs(19),
845 : ErrorsFound,
846 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
847 : ventSlab.Name,
848 : DataLoopNode::NodeFluidType::Air,
849 : DataLoopNode::ConnectionType::Inlet,
850 : NodeInputManager::CompFluidStream::Primary,
851 3 : ObjectIsNotParent);
852 6 : ventSlab.OAMixerOutNode = GetOnlySingleNode(state,
853 3 : state.dataIPShortCut->cAlphaArgs(23),
854 : ErrorsFound,
855 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
856 6 : ventSlab.Name + "-OA MIXER",
857 : DataLoopNode::NodeFluidType::Air,
858 : DataLoopNode::ConnectionType::Outlet,
859 : NodeInputManager::CompFluidStream::Primary,
860 3 : ObjectIsNotParent);
861 6 : ventSlab.FanOutletNode = GetOnlySingleNode(state,
862 3 : state.dataIPShortCut->cAlphaArgs(24),
863 : ErrorsFound,
864 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
865 : ventSlab.Name,
866 : DataLoopNode::NodeFluidType::Air,
867 : DataLoopNode::ConnectionType::Internal,
868 : NodeInputManager::CompFluidStream::Primary,
869 3 : ObjectIsParent);
870 : }
871 :
872 7 : if (ventSlab.SysConfg == VentilatedSlabConfig::SlabOnly) {
873 2 : if (!lAlphaBlanks(20)) {
874 0 : ShowWarningError(state,
875 0 : CurrentModuleObject + "=\"" + ventSlab.Name + "\" " + cAlphaFields(20) + "=\"" +
876 0 : state.dataIPShortCut->cAlphaArgs(20) + "\" not needed - ignored.");
877 0 : ShowContinueError(state, "It is used for \"SlabAndZone\" only");
878 : }
879 :
880 5 : } else if (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone) {
881 3 : if (lAlphaBlanks(20)) {
882 0 : ShowSevereError(
883 0 : state, CurrentModuleObject + "=\"" + ventSlab.Name + "\" invalid " + cAlphaFields(20) + " is blank and must be entered.");
884 0 : ErrorsFound = true;
885 : }
886 :
887 6 : ventSlab.ZoneAirInNode = GetOnlySingleNode(state,
888 3 : state.dataIPShortCut->cAlphaArgs(20),
889 : ErrorsFound,
890 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
891 6 : ventSlab.Name + "-SYSTEM",
892 : DataLoopNode::NodeFluidType::Air,
893 : DataLoopNode::ConnectionType::Outlet,
894 : NodeInputManager::CompFluidStream::Primary,
895 3 : ObjectIsParent);
896 :
897 6 : ventSlab.ZoneAirInNode = GetOnlySingleNode(state,
898 3 : state.dataIPShortCut->cAlphaArgs(20),
899 : ErrorsFound,
900 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
901 : ventSlab.Name,
902 : DataLoopNode::NodeFluidType::Air,
903 : DataLoopNode::ConnectionType::Outlet,
904 : NodeInputManager::CompFluidStream::Primary,
905 3 : ObjectIsNotParent);
906 : }
907 :
908 : // Set connection type to 'Inlet', because it now uses an OA node
909 14 : ventSlab.OutsideAirNode = GetOnlySingleNode(state,
910 7 : state.dataIPShortCut->cAlphaArgs(21),
911 : ErrorsFound,
912 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
913 14 : ventSlab.Name + "-OA MIXER",
914 : DataLoopNode::NodeFluidType::Air,
915 : DataLoopNode::ConnectionType::Inlet,
916 : NodeInputManager::CompFluidStream::Primary,
917 7 : ObjectIsNotParent);
918 :
919 7 : if (!lAlphaBlanks(21)) {
920 7 : CheckAndAddAirNodeNumber(state, ventSlab.OutsideAirNode, IsValid);
921 7 : if (!IsValid) {
922 0 : ShowWarningError(
923 0 : state, CurrentModuleObject + "=\"" + ventSlab.Name + "\", Adding OutdoorAir:Node=" + state.dataIPShortCut->cAlphaArgs(21));
924 : }
925 : }
926 :
927 14 : ventSlab.AirReliefNode = GetOnlySingleNode(state,
928 7 : state.dataIPShortCut->cAlphaArgs(22),
929 : ErrorsFound,
930 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
931 14 : ventSlab.Name + "-OA MIXER",
932 : DataLoopNode::NodeFluidType::Air,
933 : DataLoopNode::ConnectionType::ReliefAir,
934 : NodeInputManager::CompFluidStream::Primary,
935 7 : ObjectIsNotParent);
936 :
937 : // Fan information:
938 7 : ventSlab.FanName = state.dataIPShortCut->cAlphaArgs(25);
939 :
940 7 : if (HVACFan::checkIfFanNameIsAFanSystem(state, ventSlab.FanName)) {
941 5 : ventSlab.FanType_Num = DataHVACGlobals::FanType_SystemModelObject;
942 5 : state.dataHVACFan->fanObjs.emplace_back(new HVACFan::FanSystem(state, ventSlab.FanName));
943 5 : ventSlab.Fan_Index = HVACFan::getFanObjectVectorIndex(state, ventSlab.FanName);
944 : } else {
945 2 : bool isNotOkay(false);
946 2 : ValidateComponent(state, "FAN:CONSTANTVOLUME", ventSlab.FanName, isNotOkay, "GetPIUs");
947 2 : if (isNotOkay) {
948 0 : ShowContinueError(state, "In " + CurrentModuleObject + " = " + ventSlab.Name);
949 0 : ErrorsFound = true;
950 : }
951 2 : ventSlab.FanType_Num = DataHVACGlobals::FanType_SimpleConstVolume;
952 : }
953 :
954 7 : if (ventSlab.outsideAirControlType == OutsideAirControlType::FixedOAControl) {
955 0 : ventSlab.OutAirVolFlow = ventSlab.MinOutAirVolFlow;
956 0 : ventSlab.MaxOASchedPtr = ventSlab.MinOASchedPtr;
957 : }
958 :
959 : // Add fan to component sets array
960 35 : SetUpCompSets(state,
961 : CurrentModuleObject,
962 14 : ventSlab.Name + "-SYSTEM",
963 : "UNDEFINED",
964 7 : state.dataIPShortCut->cAlphaArgs(25),
965 7 : state.dataIPShortCut->cAlphaArgs(23),
966 14 : state.dataIPShortCut->cAlphaArgs(24));
967 :
968 : // Coil options assign
969 :
970 7 : ventSlab.coilOption =
971 14 : static_cast<CoilType>(getEnumerationValue(CoilTypeNamesUC, UtilityRoutines::MakeUPPERCase(state.dataIPShortCut->cAlphaArgs(26))));
972 :
973 7 : if (ventSlab.coilOption == CoilType::Invalid) {
974 0 : ShowSevereError(
975 : state,
976 0 : format(
977 0 : R"({}="{}" invalid {}="{}".)", CurrentModuleObject, ventSlab.Name, cAlphaFields(26), state.dataIPShortCut->cAlphaArgs(26)));
978 0 : ErrorsFound = true;
979 : }
980 :
981 7 : if (ventSlab.coilOption == CoilType::Both || ventSlab.coilOption == CoilType::Heating) {
982 : // Heating coil information:
983 : // A27, \field Heating Coil Object Type
984 : // \type choice
985 : // \key Coil:Heating:Water
986 : // \key Coil:Heating:Electric
987 : // \key Coil:Heating:Fuel
988 : // \key Coil:Heating:Steam
989 : // A28, \field Heating Coil Name
990 : // \type object-list
991 : // \object-list HeatingCoilName
992 :
993 : // Heating coil information:
994 7 : if (!lAlphaBlanks(28)) {
995 7 : ventSlab.heatingCoilPresent = true;
996 7 : ventSlab.heatingCoilTypeCh = state.dataIPShortCut->cAlphaArgs(27);
997 7 : errFlag = false;
998 :
999 7 : ventSlab.hCoilType = static_cast<HeatingCoilType>(
1000 14 : getEnumerationValue(HeatingCoilTypeNamesUC, UtilityRoutines::MakeUPPERCase(state.dataIPShortCut->cAlphaArgs(27))));
1001 :
1002 7 : switch (ventSlab.hCoilType) {
1003 :
1004 4 : case HeatingCoilType::Water: {
1005 4 : ventSlab.heatingCoilType = DataPlant::PlantEquipmentType::CoilWaterSimpleHeating;
1006 4 : break;
1007 : }
1008 0 : case HeatingCoilType::Steam: {
1009 0 : ventSlab.heatingCoilType = DataPlant::PlantEquipmentType::CoilSteamAirHeating;
1010 0 : ventSlab.heatingCoil_FluidIndex = FindRefrigerant(state, "Steam");
1011 0 : if (ventSlab.heatingCoil_FluidIndex == 0) {
1012 0 : ShowSevereError(state, CurrentModuleObject + "=\"" + ventSlab.Name + "Steam Properties not found.");
1013 0 : if (SteamMessageNeeded) ShowContinueError(state, "Steam Fluid Properties should have been included in the input file.");
1014 0 : ErrorsFound = true;
1015 0 : SteamMessageNeeded = false;
1016 : }
1017 0 : break;
1018 : }
1019 3 : case HeatingCoilType::Electric:
1020 : case HeatingCoilType::Gas:
1021 3 : break;
1022 0 : default: {
1023 0 : ShowSevereError(state,
1024 0 : format(R"({}="{}" invalid {}="{}".)",
1025 : CurrentModuleObject,
1026 : ventSlab.Name,
1027 : cAlphaFields(27),
1028 0 : state.dataIPShortCut->cAlphaArgs(27)));
1029 0 : ErrorsFound = true;
1030 0 : errFlag = true;
1031 0 : break;
1032 : }
1033 : }
1034 7 : if (!errFlag) {
1035 7 : ventSlab.heatingCoilName = state.dataIPShortCut->cAlphaArgs(28);
1036 7 : ValidateComponent(state, state.dataIPShortCut->cAlphaArgs(27), ventSlab.heatingCoilName, IsNotOK, CurrentModuleObject);
1037 7 : if (IsNotOK) {
1038 0 : ShowContinueError(state,
1039 0 : CurrentModuleObject + "=\"" + ventSlab.Name + "\" invalid " + cAlphaFields(28) + "=\"" +
1040 0 : state.dataIPShortCut->cAlphaArgs(28) + "\".");
1041 0 : ShowContinueError(state, "... not valid for " + cAlphaFields(27) + "=\"" + state.dataIPShortCut->cAlphaArgs(27) + "\".");
1042 0 : ErrorsFound = true;
1043 : }
1044 : }
1045 :
1046 7 : ventSlab.MinVolHotWaterFlow = 0.0;
1047 7 : ventSlab.MinVolHotSteamFlow = 0.0;
1048 :
1049 : // The heating coil control node is necessary for a hot water coil, but not necessary for an
1050 : // electric or gas coil.
1051 7 : if (ventSlab.hCoilType == HeatingCoilType::Gas || ventSlab.hCoilType == HeatingCoilType::Electric) {
1052 6 : if (!lAlphaBlanks(29)) {
1053 0 : ShowWarningError(state,
1054 0 : CurrentModuleObject + "=\"" + ventSlab.Name + "\" " + cAlphaFields(29) + "=\"" +
1055 0 : state.dataIPShortCut->cAlphaArgs(29) + "\" not needed - ignored.");
1056 0 : ShowContinueError(state, "..It is used for hot water coils only.");
1057 : }
1058 : } else {
1059 4 : if (lAlphaBlanks(29)) {
1060 0 : ShowSevereError(state,
1061 0 : CurrentModuleObject + "=\"" + ventSlab.Name + "\" invalid " + cAlphaFields(29) +
1062 : " is blank and must be entered.");
1063 0 : ErrorsFound = true;
1064 : }
1065 8 : ventSlab.HotControlNode = GetOnlySingleNode(state,
1066 4 : state.dataIPShortCut->cAlphaArgs(29),
1067 : ErrorsFound,
1068 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
1069 : ventSlab.Name,
1070 : DataLoopNode::NodeFluidType::Water,
1071 : DataLoopNode::ConnectionType::Actuator,
1072 : NodeInputManager::CompFluidStream::Primary,
1073 4 : ObjectIsParent);
1074 : }
1075 7 : ventSlab.HotControlOffset = 0.001;
1076 :
1077 7 : if (ventSlab.hCoilType == HeatingCoilType::Water) {
1078 4 : ventSlab.MaxVolHotWaterFlow = GetWaterCoilMaxFlowRate(state, "Coil:Heating:Water", ventSlab.heatingCoilName, ErrorsFound);
1079 4 : ventSlab.MaxVolHotSteamFlow = GetWaterCoilMaxFlowRate(state, "Coil:Heating:Water", ventSlab.heatingCoilName, ErrorsFound);
1080 3 : } else if (ventSlab.hCoilType == HeatingCoilType::Steam) {
1081 0 : ventSlab.MaxVolHotWaterFlow = GetSteamCoilMaxFlowRate(state, "Coil:Heating:Steam", ventSlab.heatingCoilName, ErrorsFound);
1082 0 : ventSlab.MaxVolHotSteamFlow = GetSteamCoilMaxFlowRate(state, "Coil:Heating:Steam", ventSlab.heatingCoilName, ErrorsFound);
1083 : }
1084 :
1085 : } else { // no heating coil
1086 0 : ShowSevereError(state, CurrentModuleObject + "=\"" + ventSlab.Name + "\" missing heating coil.");
1087 0 : ShowContinueError(state,
1088 0 : "a heating coil is required for " + cAlphaFields(26) + "=\"" + state.dataIPShortCut->cAlphaArgs(26) + "\".");
1089 0 : ErrorsFound = true;
1090 : }
1091 : }
1092 :
1093 7 : if (ventSlab.coilOption == CoilType::Both || ventSlab.coilOption == CoilType::Cooling) {
1094 : // Cooling coil information (if one is present):
1095 : // A30, \field Cooling Coil Object Type
1096 : // \type choice
1097 : // \key Coil:Cooling:Water
1098 : // \key Coil:Cooling:Water:DetailedGeometry
1099 : // \key CoilSystem:Cooling:Water:HeatExchangerAssisted
1100 : // A31, \field Cooling Coil Name
1101 : // \type object-list
1102 : // \object-list CoolingCoilsWater
1103 : // Cooling coil information (if one is present):
1104 4 : if (!lAlphaBlanks(31)) {
1105 4 : ventSlab.coolingCoilPresent = true;
1106 4 : ventSlab.coolingCoilTypeCh = state.dataIPShortCut->cAlphaArgs(30);
1107 4 : errFlag = false;
1108 :
1109 4 : ventSlab.cCoilType = static_cast<CoolingCoilType>(
1110 8 : getEnumerationValue(CoolingCoilTypeNamesUC, UtilityRoutines::MakeUPPERCase(state.dataIPShortCut->cAlphaArgs(30))));
1111 :
1112 4 : switch (ventSlab.cCoilType) {
1113 4 : case CoolingCoilType::WaterCooling: {
1114 4 : ventSlab.coolingCoilType = DataPlant::PlantEquipmentType::CoilWaterCooling;
1115 4 : ventSlab.coolingCoilPlantName = state.dataIPShortCut->cAlphaArgs(31);
1116 4 : break;
1117 : }
1118 0 : case CoolingCoilType::DetailedCooling: {
1119 0 : ventSlab.coolingCoilType = DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling;
1120 0 : ventSlab.coolingCoilPlantName = state.dataIPShortCut->cAlphaArgs(31);
1121 0 : break;
1122 : }
1123 0 : case CoolingCoilType::HXAssisted: {
1124 0 : GetHXCoilTypeAndName(state,
1125 0 : state.dataIPShortCut->cAlphaArgs(30),
1126 0 : state.dataIPShortCut->cAlphaArgs(31),
1127 : ErrorsFound,
1128 : ventSlab.coolingCoilPlantType,
1129 : ventSlab.coolingCoilPlantName);
1130 0 : if (UtilityRoutines::SameString(ventSlab.coolingCoilPlantType, "Coil:Cooling:Water")) {
1131 0 : ventSlab.coolingCoilType = DataPlant::PlantEquipmentType::CoilWaterCooling;
1132 0 : } else if (UtilityRoutines::SameString(ventSlab.coolingCoilPlantType, "Coil:Cooling:Water:DetailedGeometry")) {
1133 0 : ventSlab.coolingCoilType = DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling;
1134 : } else {
1135 0 : ShowSevereError(state, "GetVentilatedSlabInput: " + CurrentModuleObject + "=\"" + ventSlab.Name + "\", invalid");
1136 0 : ShowContinueError(state, "For: " + cAlphaFields(30) + "=\"" + state.dataIPShortCut->cAlphaArgs(30) + "\".");
1137 0 : ShowContinueError(state,
1138 0 : "Invalid Coil Type=" + ventSlab.coolingCoilPlantType + ", Name=" + ventSlab.coolingCoilPlantName);
1139 0 : ShowContinueError(state, R"(must be "Coil:Cooling:Water" or "Coil:Cooling:Water:DetailedGeometry")");
1140 0 : ErrorsFound = true;
1141 : }
1142 0 : break;
1143 : }
1144 0 : default: {
1145 0 : ShowSevereError(state,
1146 0 : format(R"({}="{}" invalid {}="{}".)",
1147 : CurrentModuleObject,
1148 : ventSlab.Name,
1149 : cAlphaFields(29),
1150 0 : state.dataIPShortCut->cAlphaArgs(29)));
1151 0 : ErrorsFound = true;
1152 0 : errFlag = true;
1153 0 : break;
1154 : }
1155 : }
1156 :
1157 4 : if (!errFlag) {
1158 4 : ventSlab.coolingCoilName = state.dataIPShortCut->cAlphaArgs(31);
1159 4 : ValidateComponent(state, state.dataIPShortCut->cAlphaArgs(30), ventSlab.coolingCoilName, IsNotOK, "ZoneHVAC:VentilatedSlab ");
1160 4 : if (IsNotOK) {
1161 0 : ShowContinueError(state,
1162 0 : CurrentModuleObject + "=\"" + ventSlab.Name + "\" invalid " + cAlphaFields(31) + "=\"" +
1163 0 : state.dataIPShortCut->cAlphaArgs(31) + "\".");
1164 0 : ShowContinueError(state, "... not valid for " + cAlphaFields(30) + "=\"" + state.dataIPShortCut->cAlphaArgs(30) + "\".");
1165 0 : ErrorsFound = true;
1166 : }
1167 : }
1168 :
1169 4 : ventSlab.MinVolColdWaterFlow = 0.0;
1170 :
1171 8 : ventSlab.ColdControlNode = GetOnlySingleNode(state,
1172 4 : state.dataIPShortCut->cAlphaArgs(32),
1173 : ErrorsFound,
1174 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
1175 : ventSlab.Name,
1176 : DataLoopNode::NodeFluidType::Water,
1177 : DataLoopNode::ConnectionType::Actuator,
1178 : NodeInputManager::CompFluidStream::Primary,
1179 4 : ObjectIsParent);
1180 :
1181 4 : if (lAlphaBlanks(32)) {
1182 0 : ShowSevereError(
1183 0 : state, CurrentModuleObject + "=\"" + ventSlab.Name + "\" invalid " + cAlphaFields(32) + " is blank and must be entered.");
1184 0 : ErrorsFound = true;
1185 : }
1186 :
1187 4 : ventSlab.ColdControlOffset = 0.001;
1188 :
1189 4 : if (ventSlab.cCoilType == CoolingCoilType::WaterCooling) {
1190 4 : ventSlab.MaxVolColdWaterFlow = GetWaterCoilMaxFlowRate(state, "Coil:Cooling:Water", ventSlab.coolingCoilName, ErrorsFound);
1191 0 : } else if (ventSlab.cCoilType == CoolingCoilType::DetailedCooling) {
1192 0 : ventSlab.MaxVolColdWaterFlow =
1193 0 : GetWaterCoilMaxFlowRate(state, "Coil:Cooling:Water:DetailedGeometry", ventSlab.coolingCoilName, ErrorsFound);
1194 0 : } else if (ventSlab.cCoilType == CoolingCoilType::HXAssisted) {
1195 0 : ventSlab.MaxVolColdWaterFlow =
1196 0 : GetHXAssistedCoilFlowRate(state, "CoilSystem:Cooling:Water:HeatExchangerAssisted", ventSlab.coolingCoilName, ErrorsFound);
1197 : }
1198 :
1199 : } else { // No Cooling Coil
1200 0 : ShowSevereError(state, CurrentModuleObject + "=\"" + ventSlab.Name + "\" missing cooling coil.");
1201 0 : ShowContinueError(state,
1202 0 : "a cooling coil is required for " + cAlphaFields(26) + "=\"" + state.dataIPShortCut->cAlphaArgs(26) + "\".");
1203 0 : ErrorsFound = true;
1204 : }
1205 : }
1206 :
1207 7 : ventSlab.HVACSizingIndex = 0;
1208 7 : if (!lAlphaBlanks(34)) {
1209 0 : ventSlab.HVACSizingIndex = UtilityRoutines::FindItemInList(state.dataIPShortCut->cAlphaArgs(34), state.dataSize->ZoneHVACSizing);
1210 0 : if (ventSlab.HVACSizingIndex == 0) {
1211 0 : ShowSevereError(state, cAlphaFields(34) + " = " + state.dataIPShortCut->cAlphaArgs(34) + " not found.");
1212 0 : ShowContinueError(state, "Occurs in " + cMO_VentilatedSlab + " = " + ventSlab.Name);
1213 0 : ErrorsFound = true;
1214 : }
1215 : }
1216 :
1217 7 : switch (ventSlab.coilOption) {
1218 4 : case CoilType::Both: { // 'HeatingAndCooling'
1219 : // Add cooling coil to component sets array when present
1220 20 : SetUpCompSets(state,
1221 : CurrentModuleObject,
1222 8 : ventSlab.Name + "-SYSTEM",
1223 4 : state.dataIPShortCut->cAlphaArgs(30),
1224 4 : state.dataIPShortCut->cAlphaArgs(31),
1225 4 : state.dataIPShortCut->cAlphaArgs(24),
1226 4 : "UNDEFINED");
1227 :
1228 : // Add heating coil to component sets array when cooling coil present
1229 20 : SetUpCompSets(state,
1230 : CurrentModuleObject,
1231 8 : ventSlab.Name + "-SYSTEM",
1232 4 : state.dataIPShortCut->cAlphaArgs(27),
1233 4 : state.dataIPShortCut->cAlphaArgs(28),
1234 : "UNDEFINED",
1235 8 : state.dataIPShortCut->cAlphaArgs(19));
1236 4 : break;
1237 : }
1238 3 : case CoilType::Heating: { // 'Heating'
1239 : // Add heating coil to component sets array when no cooling coil present
1240 18 : SetUpCompSets(state,
1241 : CurrentModuleObject,
1242 6 : ventSlab.Name + "-SYSTEM",
1243 3 : state.dataIPShortCut->cAlphaArgs(27),
1244 3 : state.dataIPShortCut->cAlphaArgs(28),
1245 3 : state.dataIPShortCut->cAlphaArgs(24),
1246 3 : state.dataIPShortCut->cAlphaArgs(19));
1247 3 : break;
1248 : }
1249 0 : case CoilType::Cooling: { // 'Cooling'
1250 : // Add cooling coil to component sets array when no heating coil present
1251 0 : SetUpCompSets(state,
1252 : CurrentModuleObject,
1253 0 : ventSlab.Name + "-SYSTEM",
1254 0 : state.dataIPShortCut->cAlphaArgs(30),
1255 0 : state.dataIPShortCut->cAlphaArgs(31),
1256 0 : state.dataIPShortCut->cAlphaArgs(24),
1257 0 : state.dataIPShortCut->cAlphaArgs(19));
1258 0 : break;
1259 : }
1260 0 : case CoilType::None:
1261 : default:
1262 0 : break;
1263 : }
1264 :
1265 : } // ...loop over all of the ventilated slab found in the input file
1266 :
1267 2 : cAlphaArgs.deallocate();
1268 2 : cAlphaFields.deallocate();
1269 2 : cNumericFields.deallocate();
1270 2 : rNumericArgs.deallocate();
1271 2 : lAlphaBlanks.deallocate();
1272 2 : lNumericBlanks.deallocate();
1273 :
1274 2 : if (ErrorsFound) ShowFatalError(state, CurrentModuleObject + " errors occurred in input. Program terminates.");
1275 :
1276 : // Setup Report variables for the VENTILATED SLAB
1277 9 : for (Item = 1; Item <= state.dataVentilatedSlab->NumOfVentSlabs; ++Item) {
1278 : // CALL SetupOutputVariable(state, 'Ventilated Slab Direct Heat Loss Rate [W]', &
1279 : // VentSlab(Item)%DirectHeatLossRate,'System', &
1280 : // 'Average', VentSlab(Item)%Name)
1281 : // CALL SetupOutputVariable(state, 'Ventilated Slab Direct Heat Loss [W]', &
1282 : // VentSlab(Item)%DirectHeatLoss,'System', &
1283 : // 'Sum', VentSlab(Item)%Name)
1284 : // CALL SetupOutputVariable(state, 'Ventilated Slab Direct Heat Gain Rate [W]', &
1285 : // VentSlab(Item)%DirectHeatGainRate,'System', &
1286 : // 'Average', VentSlab(Item)%Name)
1287 : // CALL SetupOutputVariable(state, 'Ventilated Slab Direct Heat Gain [J]', &
1288 : // VentSlab(Item)%DirectHeatGain,'System', &
1289 : // 'Sum', VentSlab(Item)%Name)
1290 7 : auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
1291 14 : SetupOutputVariable(state,
1292 : "Zone Ventilated Slab Radiant Heating Rate",
1293 : OutputProcessor::Unit::W,
1294 : ventSlab.RadHeatingPower,
1295 : OutputProcessor::SOVTimeStepType::System,
1296 : OutputProcessor::SOVStoreType::Average,
1297 7 : ventSlab.Name);
1298 14 : SetupOutputVariable(state,
1299 : "Zone Ventilated Slab Radiant Heating Energy",
1300 : OutputProcessor::Unit::J,
1301 : ventSlab.RadHeatingEnergy,
1302 : OutputProcessor::SOVTimeStepType::System,
1303 : OutputProcessor::SOVStoreType::Summed,
1304 7 : ventSlab.Name);
1305 14 : SetupOutputVariable(state,
1306 : "Zone Ventilated Slab Radiant Cooling Rate",
1307 : OutputProcessor::Unit::W,
1308 : ventSlab.RadCoolingPower,
1309 : OutputProcessor::SOVTimeStepType::System,
1310 : OutputProcessor::SOVStoreType::Average,
1311 7 : ventSlab.Name);
1312 14 : SetupOutputVariable(state,
1313 : "Zone Ventilated Slab Radiant Cooling Energy",
1314 : OutputProcessor::Unit::J,
1315 : ventSlab.RadCoolingEnergy,
1316 : OutputProcessor::SOVTimeStepType::System,
1317 : OutputProcessor::SOVStoreType::Summed,
1318 7 : ventSlab.Name);
1319 14 : SetupOutputVariable(state,
1320 : "Zone Ventilated Slab Coil Heating Rate",
1321 : OutputProcessor::Unit::W,
1322 : ventSlab.HeatCoilPower,
1323 : OutputProcessor::SOVTimeStepType::System,
1324 : OutputProcessor::SOVStoreType::Average,
1325 7 : ventSlab.Name);
1326 14 : SetupOutputVariable(state,
1327 : "Zone Ventilated Slab Coil Heating Energy",
1328 : OutputProcessor::Unit::J,
1329 : ventSlab.HeatCoilEnergy,
1330 : OutputProcessor::SOVTimeStepType::System,
1331 : OutputProcessor::SOVStoreType::Summed,
1332 7 : ventSlab.Name);
1333 14 : SetupOutputVariable(state,
1334 : "Zone Ventilated Slab Coil Total Cooling Rate",
1335 : OutputProcessor::Unit::W,
1336 : ventSlab.TotCoolCoilPower,
1337 : OutputProcessor::SOVTimeStepType::System,
1338 : OutputProcessor::SOVStoreType::Average,
1339 7 : ventSlab.Name);
1340 14 : SetupOutputVariable(state,
1341 : "Zone Ventilated Slab Coil Total Cooling Energy",
1342 : OutputProcessor::Unit::J,
1343 : ventSlab.TotCoolCoilEnergy,
1344 : OutputProcessor::SOVTimeStepType::System,
1345 : OutputProcessor::SOVStoreType::Summed,
1346 7 : ventSlab.Name);
1347 14 : SetupOutputVariable(state,
1348 : "Zone Ventilated Slab Coil Sensible Cooling Rate",
1349 : OutputProcessor::Unit::W,
1350 : ventSlab.SensCoolCoilPower,
1351 : OutputProcessor::SOVTimeStepType::System,
1352 : OutputProcessor::SOVStoreType::Average,
1353 7 : ventSlab.Name);
1354 14 : SetupOutputVariable(state,
1355 : "Zone Ventilated Slab Coil Sensible Cooling Energy",
1356 : OutputProcessor::Unit::J,
1357 : ventSlab.SensCoolCoilEnergy,
1358 : OutputProcessor::SOVTimeStepType::System,
1359 : OutputProcessor::SOVStoreType::Summed,
1360 7 : ventSlab.Name);
1361 14 : SetupOutputVariable(state,
1362 : "Zone Ventilated Slab Coil Latent Cooling Rate",
1363 : OutputProcessor::Unit::W,
1364 : ventSlab.LateCoolCoilPower,
1365 : OutputProcessor::SOVTimeStepType::System,
1366 : OutputProcessor::SOVStoreType::Average,
1367 7 : ventSlab.Name);
1368 14 : SetupOutputVariable(state,
1369 : "Zone Ventilated Slab Coil Latent Cooling Energy",
1370 : OutputProcessor::Unit::J,
1371 : ventSlab.LateCoolCoilEnergy,
1372 : OutputProcessor::SOVTimeStepType::System,
1373 : OutputProcessor::SOVStoreType::Summed,
1374 7 : ventSlab.Name);
1375 14 : SetupOutputVariable(state,
1376 : "Zone Ventilated Slab Air Mass Flow Rate",
1377 : OutputProcessor::Unit::kg_s,
1378 : ventSlab.AirMassFlowRate,
1379 : OutputProcessor::SOVTimeStepType::System,
1380 : OutputProcessor::SOVStoreType::Average,
1381 7 : ventSlab.Name);
1382 14 : SetupOutputVariable(state,
1383 : "Zone Ventilated Slab Fan Electricity Rate",
1384 : OutputProcessor::Unit::W,
1385 : ventSlab.ElecFanPower,
1386 : OutputProcessor::SOVTimeStepType::System,
1387 : OutputProcessor::SOVStoreType::Average,
1388 7 : ventSlab.Name);
1389 : //! Note that the ventilated slab fan electric is NOT metered because this value is already metered through the fan component
1390 14 : SetupOutputVariable(state,
1391 : "Zone Ventilated Slab Fan Electricity Energy",
1392 : OutputProcessor::Unit::J,
1393 : ventSlab.ElecFanEnergy,
1394 : OutputProcessor::SOVTimeStepType::System,
1395 : OutputProcessor::SOVStoreType::Summed,
1396 7 : ventSlab.Name);
1397 14 : SetupOutputVariable(state,
1398 : "Zone Ventilated Slab Inlet Air Temperature",
1399 : OutputProcessor::Unit::C,
1400 : ventSlab.SlabInTemp,
1401 : OutputProcessor::SOVTimeStepType::System,
1402 : OutputProcessor::SOVStoreType::Average,
1403 7 : ventSlab.Name);
1404 14 : SetupOutputVariable(state,
1405 : "Zone Ventilated Slab Outlet Air Temperature",
1406 : OutputProcessor::Unit::C,
1407 : ventSlab.SlabOutTemp,
1408 : OutputProcessor::SOVTimeStepType::System,
1409 : OutputProcessor::SOVStoreType::Average,
1410 7 : ventSlab.Name);
1411 14 : SetupOutputVariable(state,
1412 : "Zone Ventilated Slab Zone Inlet Air Temperature",
1413 : OutputProcessor::Unit::C,
1414 : ventSlab.ZoneInletTemp,
1415 : OutputProcessor::SOVTimeStepType::System,
1416 : OutputProcessor::SOVStoreType::Average,
1417 7 : ventSlab.Name);
1418 14 : SetupOutputVariable(state,
1419 : "Zone Ventilated Slab Return Air Temperature",
1420 : OutputProcessor::Unit::C,
1421 : ventSlab.ReturnAirTemp,
1422 : OutputProcessor::SOVTimeStepType::System,
1423 : OutputProcessor::SOVStoreType::Average,
1424 7 : ventSlab.Name);
1425 14 : SetupOutputVariable(state,
1426 : "Zone Ventilated Slab Fan Outlet Air Temperature",
1427 : OutputProcessor::Unit::C,
1428 : ventSlab.FanOutletTemp,
1429 : OutputProcessor::SOVTimeStepType::System,
1430 : OutputProcessor::SOVStoreType::Average,
1431 7 : ventSlab.Name);
1432 14 : SetupOutputVariable(state,
1433 : "Zone Ventilated Slab Fan Availability Status",
1434 : OutputProcessor::Unit::None,
1435 : ventSlab.AvailStatus,
1436 : OutputProcessor::SOVTimeStepType::System,
1437 : OutputProcessor::SOVStoreType::Average,
1438 7 : ventSlab.Name);
1439 : }
1440 2 : }
1441 :
1442 106951 : void InitVentilatedSlab(EnergyPlusData &state,
1443 : int const Item, // index for the current ventilated slab
1444 : int const VentSlabZoneNum, // number of zone being served
1445 : bool const FirstHVACIteration // TRUE if 1st HVAC simulation of system timestep
1446 : )
1447 : {
1448 :
1449 : // SUBROUTINE INFORMATION:
1450 : // AUTHOR Young Tae Chae, Rick Strand
1451 : // DATE WRITTEN June 2008
1452 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
1453 : // RE-ENGINEERED na
1454 :
1455 : // PURPOSE OF THIS SUBROUTINE:
1456 : // This subroutine initializes all of the data elements which are necessary
1457 : // to simulate a Ventilated Slab.
1458 :
1459 : // METHODOLOGY EMPLOYED:
1460 : // Uses the status flags to trigger initializations.
1461 :
1462 : // REFERENCES:
1463 : // na
1464 :
1465 : // Using/Aliasing
1466 106951 : auto &ZoneComp = state.dataHVACGlobal->ZoneComp;
1467 106951 : auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
1468 :
1469 : using DataZoneEquipment::CheckZoneEquipmentList;
1470 : using FluidProperties::GetDensityGlycol;
1471 : using PlantUtilities::InitComponentNodes;
1472 : using PlantUtilities::ScanPlantLoopsForObject;
1473 : using ScheduleManager::GetCurrentScheduleValue;
1474 :
1475 : // Locals
1476 : // SUBROUTINE ARGUMENT DEFINITIONS:
1477 :
1478 : // SUBROUTINE PARAMETER DEFINITIONS:
1479 : static constexpr std::string_view RoutineName("InitVentilatedSlab");
1480 :
1481 : // INTERFACE BLOCK SPECIFICATIONS
1482 : // na
1483 :
1484 : // DERIVED TYPE DEFINITIONS
1485 : // na
1486 :
1487 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1488 : int RadNum; // Number of the radiant system (DO loop counter)
1489 : int RadSurfNum; // Number of the radiant system surface (DO loop counter)
1490 : int SurfNum; // Intermediate variable for keeping track of the surface number
1491 : int ZoneNum; // Intermediate variable for keeping track of the zone number
1492 : int AirRelNode; // relief air node number in Ventilated Slab loop
1493 : int ColdConNode; // cold water control node number in Ventilated Slab loop
1494 : int HotConNode; // hot water control node number in Ventilated Slab loop
1495 : int InNode; // inlet node number in Ventilated Slab loop
1496 : int OutNode; // outlet node number in Ventilated Slab loop
1497 : int OutsideAirNode; // outside air node number in Ventilated Slab loop
1498 : Real64 RhoAir; // air density at InNode
1499 : Real64 TempSteamIn;
1500 : Real64 SteamDensity;
1501 : int ZoneAirInNode;
1502 : int MixOut;
1503 : Real64 rho;
1504 : bool errFlag;
1505 :
1506 : // Do the one time initializations
1507 :
1508 106951 : if (state.dataVentilatedSlab->MyOneTimeFlag) {
1509 2 : state.dataVentilatedSlab->MyEnvrnFlag.allocate(state.dataVentilatedSlab->NumOfVentSlabs);
1510 2 : state.dataVentilatedSlab->MySizeFlag.allocate(state.dataVentilatedSlab->NumOfVentSlabs);
1511 2 : state.dataVentilatedSlab->MyPlantScanFlag.allocate(state.dataVentilatedSlab->NumOfVentSlabs);
1512 2 : state.dataVentilatedSlab->MyZoneEqFlag.allocate(state.dataVentilatedSlab->NumOfVentSlabs);
1513 2 : state.dataVentilatedSlab->ZeroSourceSumHATsurf.dimension(state.dataGlobal->NumOfZones, 0.0);
1514 2 : state.dataVentilatedSlab->QRadSysSrcAvg.dimension(state.dataSurface->TotSurfaces, 0.0);
1515 2 : state.dataVentilatedSlab->LastQRadSysSrc.dimension(state.dataSurface->TotSurfaces, 0.0);
1516 2 : state.dataVentilatedSlab->LastSysTimeElapsed.dimension(state.dataSurface->TotSurfaces, 0.0);
1517 2 : state.dataVentilatedSlab->LastTimeStepSys.dimension(state.dataSurface->TotSurfaces, 0.0);
1518 :
1519 : // Initialize total areas for all radiant systems
1520 9 : for (RadNum = 1; RadNum <= state.dataVentilatedSlab->NumOfVentSlabs; ++RadNum) {
1521 7 : state.dataVentilatedSlab->VentSlab(RadNum).TotalSurfaceArea = 0.0;
1522 17 : for (SurfNum = 1; SurfNum <= state.dataVentilatedSlab->VentSlab(RadNum).NumOfSurfaces; ++SurfNum) {
1523 10 : state.dataVentilatedSlab->VentSlab(RadNum).TotalSurfaceArea +=
1524 10 : state.dataSurface->Surface(state.dataVentilatedSlab->VentSlab(RadNum).SurfacePtr(SurfNum)).Area;
1525 : }
1526 : }
1527 2 : state.dataVentilatedSlab->MyEnvrnFlag = true;
1528 2 : state.dataVentilatedSlab->MySizeFlag = true;
1529 2 : state.dataVentilatedSlab->MyPlantScanFlag = true;
1530 2 : state.dataVentilatedSlab->MyZoneEqFlag = true;
1531 2 : state.dataVentilatedSlab->MyOneTimeFlag = false;
1532 : }
1533 :
1534 106951 : if (allocated(ZoneComp)) {
1535 106951 : if (state.dataVentilatedSlab->MyZoneEqFlag(Item)) { // initialize the name of each availability manager list and zone number
1536 7 : ZoneComp(DataZoneEquipment::ZoneEquip::VentilatedSlab).ZoneCompAvailMgrs(Item).AvailManagerListName = ventSlab.AvailManagerListName;
1537 7 : ZoneComp(DataZoneEquipment::ZoneEquip::VentilatedSlab).ZoneCompAvailMgrs(Item).ZoneNum = VentSlabZoneNum;
1538 7 : state.dataVentilatedSlab->MyZoneEqFlag(Item) = false;
1539 : }
1540 106951 : ventSlab.AvailStatus = ZoneComp(DataZoneEquipment::ZoneEquip::VentilatedSlab).ZoneCompAvailMgrs(Item).AvailStatus;
1541 : }
1542 :
1543 106951 : if (state.dataVentilatedSlab->MyPlantScanFlag(Item) && allocated(state.dataPlnt->PlantLoop)) {
1544 10 : if ((ventSlab.heatingCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating) ||
1545 3 : (ventSlab.heatingCoilType == DataPlant::PlantEquipmentType::CoilSteamAirHeating)) {
1546 4 : errFlag = false;
1547 4 : ScanPlantLoopsForObject(state, ventSlab.heatingCoilName, ventSlab.heatingCoilType, ventSlab.HWPlantLoc, errFlag, _, _, _, _, _);
1548 4 : if (errFlag) {
1549 0 : ShowContinueError(state, "Reference Unit=\"" + ventSlab.Name + "\", type=ZoneHVAC:VentilatedSlab");
1550 0 : ShowFatalError(state, "InitVentilatedSlab: Program terminated due to previous condition(s).");
1551 : }
1552 :
1553 4 : ventSlab.HotCoilOutNodeNum = DataPlant::CompData::getPlantComponent(state, ventSlab.HWPlantLoc).NodeNumOut;
1554 : }
1555 10 : if ((ventSlab.coolingCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling) ||
1556 3 : (ventSlab.coolingCoilType == DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling)) {
1557 4 : errFlag = false;
1558 4 : ScanPlantLoopsForObject(state, ventSlab.coolingCoilPlantName, ventSlab.coolingCoilType, ventSlab.CWPlantLoc, errFlag);
1559 4 : if (errFlag) {
1560 0 : ShowContinueError(state, "Reference Unit=\"" + ventSlab.Name + "\", type=ZoneHVAC:VentilatedSlab");
1561 0 : ShowFatalError(state, "InitVentilatedSlab: Program terminated due to previous condition(s).");
1562 : }
1563 4 : ventSlab.ColdCoilOutNodeNum = DataPlant::CompData::getPlantComponent(state, ventSlab.CWPlantLoc).NodeNumOut;
1564 : } else {
1565 3 : if (ventSlab.coolingCoilPresent)
1566 0 : ShowFatalError(state, "InitVentilatedSlab: Unit=" + ventSlab.Name + ", invalid cooling coil type. Program terminated.");
1567 : }
1568 7 : state.dataVentilatedSlab->MyPlantScanFlag(Item) = false;
1569 106944 : } else if (state.dataVentilatedSlab->MyPlantScanFlag(Item) && !state.dataGlobal->AnyPlantInModel) {
1570 0 : state.dataVentilatedSlab->MyPlantScanFlag(Item) = false;
1571 : }
1572 :
1573 : // need to check all Ventilated Slab units to see if they are on Zone Equipment List or issue warning
1574 106951 : if (!state.dataVentilatedSlab->ZoneEquipmentListChecked && state.dataZoneEquip->ZoneEquipInputsFilled) {
1575 2 : state.dataVentilatedSlab->ZoneEquipmentListChecked = true;
1576 9 : for (RadNum = 1; RadNum <= state.dataVentilatedSlab->NumOfVentSlabs; ++RadNum) {
1577 7 : if (CheckZoneEquipmentList(state, cMO_VentilatedSlab, state.dataVentilatedSlab->VentSlab(RadNum).Name)) continue;
1578 0 : ShowSevereError(state,
1579 0 : "InitVentilatedSlab: Ventilated Slab Unit=[" + cMO_VentilatedSlab + ',' +
1580 0 : state.dataVentilatedSlab->VentSlab(RadNum).Name +
1581 : "] is not on any ZoneHVAC:EquipmentList. It will not be simulated.");
1582 : }
1583 : }
1584 :
1585 106951 : if (!state.dataGlobal->SysSizingCalc && state.dataVentilatedSlab->MySizeFlag(Item) && !state.dataVentilatedSlab->MyPlantScanFlag(Item)) {
1586 :
1587 7 : SizeVentilatedSlab(state, Item);
1588 :
1589 7 : state.dataVentilatedSlab->MySizeFlag(Item) = false;
1590 : }
1591 :
1592 : // Do the one time initializations
1593 106951 : if (state.dataGlobal->BeginEnvrnFlag && state.dataVentilatedSlab->MyEnvrnFlag(Item) && !state.dataVentilatedSlab->MyPlantScanFlag(Item)) {
1594 :
1595 : // Coil Part
1596 35 : InNode = ventSlab.ReturnAirNode;
1597 35 : OutNode = ventSlab.RadInNode;
1598 35 : HotConNode = ventSlab.HotControlNode;
1599 35 : ColdConNode = ventSlab.ColdControlNode;
1600 35 : OutsideAirNode = ventSlab.OutsideAirNode;
1601 35 : RhoAir = state.dataEnvrn->StdRhoAir;
1602 :
1603 : // Radiation Panel Part
1604 35 : state.dataVentilatedSlab->ZeroSourceSumHATsurf = 0.0;
1605 35 : state.dataVentilatedSlab->QRadSysSrcAvg = 0.0;
1606 35 : state.dataVentilatedSlab->LastQRadSysSrc = 0.0;
1607 35 : state.dataVentilatedSlab->LastSysTimeElapsed = 0.0;
1608 35 : state.dataVentilatedSlab->LastTimeStepSys = 0.0;
1609 35 : if (state.dataVentilatedSlab->NumOfVentSlabs > 0) {
1610 180 : for (auto &e : state.dataVentilatedSlab->VentSlab) {
1611 145 : e.RadHeatingPower = 0.0;
1612 145 : e.RadHeatingEnergy = 0.0;
1613 145 : e.RadCoolingPower = 0.0;
1614 145 : e.RadCoolingEnergy = 0.0;
1615 : }
1616 : }
1617 :
1618 : // set the initial Temperature of Return Air
1619 :
1620 : // set the mass flow rates from the input volume flow rates
1621 35 : ventSlab.MaxAirMassFlow = RhoAir * ventSlab.MaxAirVolFlow;
1622 35 : ventSlab.OutAirMassFlow = RhoAir * ventSlab.OutAirVolFlow;
1623 35 : ventSlab.MinOutAirMassFlow = RhoAir * ventSlab.MinOutAirVolFlow;
1624 35 : if (ventSlab.OutAirMassFlow > ventSlab.MaxAirMassFlow) {
1625 0 : ventSlab.OutAirMassFlow = ventSlab.MaxAirMassFlow;
1626 0 : ventSlab.MinOutAirMassFlow = ventSlab.OutAirMassFlow * (ventSlab.MinOutAirVolFlow / ventSlab.OutAirVolFlow);
1627 0 : ShowWarningError(state, "Outdoor air mass flow rate higher than unit flow rate, reset to unit flow rate for " + ventSlab.Name);
1628 : }
1629 :
1630 : // set the node max and min mass flow rates
1631 35 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMax = ventSlab.OutAirMassFlow;
1632 35 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMin = 0.0;
1633 :
1634 35 : state.dataLoopNodes->Node(OutNode).MassFlowRateMax = ventSlab.MaxAirMassFlow;
1635 35 : state.dataLoopNodes->Node(OutNode).MassFlowRateMin = 0.0;
1636 :
1637 35 : state.dataLoopNodes->Node(InNode).MassFlowRateMax = ventSlab.MaxAirMassFlow;
1638 35 : state.dataLoopNodes->Node(InNode).MassFlowRateMin = 0.0;
1639 :
1640 35 : if (ventSlab.heatingCoilPresent) { // Only initialize these if a heating coil is actually present
1641 :
1642 55 : if (ventSlab.heatingCoilType == DataPlant::PlantEquipmentType::CoilWaterSimpleHeating &&
1643 20 : !state.dataVentilatedSlab->MyPlantScanFlag(Item)) {
1644 40 : rho = GetDensityGlycol(state,
1645 20 : state.dataPlnt->PlantLoop(ventSlab.HWPlantLoc.loopNum).FluidName,
1646 : DataGlobalConstants::HWInitConvTemp,
1647 20 : state.dataPlnt->PlantLoop(ventSlab.HWPlantLoc.loopNum).FluidIndex,
1648 : RoutineName);
1649 :
1650 20 : ventSlab.MaxHotWaterFlow = rho * ventSlab.MaxVolHotWaterFlow;
1651 20 : ventSlab.MinHotWaterFlow = rho * ventSlab.MinVolHotWaterFlow;
1652 :
1653 20 : InitComponentNodes(
1654 : state, ventSlab.MinHotWaterFlow, ventSlab.MaxHotWaterFlow, ventSlab.HotControlNode, ventSlab.HotCoilOutNodeNum);
1655 : }
1656 35 : if (ventSlab.heatingCoilType == DataPlant::PlantEquipmentType::CoilSteamAirHeating &&
1657 0 : !state.dataVentilatedSlab->MyPlantScanFlag(Item)) {
1658 0 : TempSteamIn = 100.00;
1659 0 : SteamDensity = GetSatDensityRefrig(state, fluidNameSteam, TempSteamIn, 1.0, ventSlab.heatingCoil_FluidIndex, RoutineName);
1660 0 : ventSlab.MaxHotSteamFlow = SteamDensity * ventSlab.MaxVolHotSteamFlow;
1661 0 : ventSlab.MinHotSteamFlow = SteamDensity * ventSlab.MinVolHotSteamFlow;
1662 :
1663 0 : InitComponentNodes(
1664 : state, ventSlab.MinHotSteamFlow, ventSlab.MaxHotSteamFlow, ventSlab.HotControlNode, ventSlab.HotCoilOutNodeNum);
1665 : }
1666 : } //(VentSlab(Item)%HCoilPresent)
1667 :
1668 35 : if (ventSlab.coolingCoilPresent && !state.dataVentilatedSlab->MyPlantScanFlag(Item)) {
1669 : // Only initialize these if a cooling coil is actually present
1670 20 : if ((ventSlab.coolingCoilType == DataPlant::PlantEquipmentType::CoilWaterCooling) ||
1671 0 : (ventSlab.coolingCoilType == DataPlant::PlantEquipmentType::CoilWaterDetailedFlatCooling)) {
1672 40 : rho = GetDensityGlycol(state,
1673 20 : state.dataPlnt->PlantLoop(ventSlab.CWPlantLoc.loopNum).FluidName,
1674 : DataGlobalConstants::CWInitConvTemp,
1675 20 : state.dataPlnt->PlantLoop(ventSlab.CWPlantLoc.loopNum).FluidIndex,
1676 : RoutineName);
1677 20 : ventSlab.MaxColdWaterFlow = rho * ventSlab.MaxVolColdWaterFlow;
1678 20 : ventSlab.MinColdWaterFlow = rho * ventSlab.MinVolColdWaterFlow;
1679 20 : InitComponentNodes(
1680 : state, ventSlab.MinColdWaterFlow, ventSlab.MaxColdWaterFlow, ventSlab.ColdControlNode, ventSlab.ColdCoilOutNodeNum);
1681 : }
1682 : }
1683 :
1684 35 : state.dataVentilatedSlab->MyEnvrnFlag(Item) = false;
1685 :
1686 : } // ...end start of environment inits
1687 :
1688 106951 : if (!state.dataGlobal->BeginEnvrnFlag) {
1689 :
1690 106744 : state.dataVentilatedSlab->MyEnvrnFlag(Item) = true;
1691 : }
1692 :
1693 : // These initializations are done every iteration...
1694 106951 : InNode = ventSlab.ReturnAirNode;
1695 106951 : OutNode = ventSlab.RadInNode;
1696 106951 : OutsideAirNode = ventSlab.OutsideAirNode;
1697 106951 : AirRelNode = ventSlab.AirReliefNode;
1698 106951 : ZoneAirInNode = ventSlab.ZoneAirInNode;
1699 106951 : MixOut = ventSlab.OAMixerOutNode;
1700 :
1701 : // First, set the flow conditions up so that there is flow through the ventilated
1702 : // slab system(this will be shut down if the system is not available or there
1703 : // is no load
1704 106951 : state.dataLoopNodes->Node(InNode).MassFlowRate = ventSlab.MaxAirMassFlow;
1705 106951 : state.dataLoopNodes->Node(InNode).MassFlowRateMaxAvail = ventSlab.MaxAirMassFlow;
1706 106951 : state.dataLoopNodes->Node(InNode).MassFlowRateMinAvail = ventSlab.MaxAirMassFlow;
1707 106951 : state.dataLoopNodes->Node(OutNode).MassFlowRate = ventSlab.MaxAirMassFlow;
1708 106951 : state.dataLoopNodes->Node(OutNode).MassFlowRateMaxAvail = ventSlab.MaxAirMassFlow;
1709 106951 : state.dataLoopNodes->Node(OutNode).MassFlowRateMinAvail = ventSlab.MaxAirMassFlow;
1710 106951 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = ventSlab.OutAirMassFlow;
1711 106951 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMaxAvail = ventSlab.OutAirMassFlow;
1712 106951 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMinAvail = ventSlab.OutAirMassFlow;
1713 106951 : state.dataLoopNodes->Node(AirRelNode).MassFlowRate = ventSlab.OutAirMassFlow;
1714 106951 : state.dataLoopNodes->Node(AirRelNode).MassFlowRateMaxAvail = ventSlab.OutAirMassFlow;
1715 106951 : state.dataLoopNodes->Node(AirRelNode).MassFlowRateMinAvail = ventSlab.OutAirMassFlow;
1716 :
1717 : // Initialize the relief air (same as inlet conditions to the Ventilated Slab ..
1718 : // Note that mass flow rates will be taken care of later.
1719 106951 : state.dataLoopNodes->Node(AirRelNode) = state.dataLoopNodes->Node(InNode);
1720 106951 : state.dataVentilatedSlab->OAMassFlowRate = 0.0;
1721 :
1722 : // Just in case the system is off and conditions do not get sent through
1723 : // the system for some reason, set the outlet conditions equal to the inlet
1724 : // conditions of the ventilated slab mixer
1725 106951 : state.dataLoopNodes->Node(OutNode).Temp = state.dataLoopNodes->Node(InNode).Temp;
1726 106951 : state.dataLoopNodes->Node(OutNode).Press = state.dataLoopNodes->Node(InNode).Press;
1727 106951 : state.dataLoopNodes->Node(OutNode).HumRat = state.dataLoopNodes->Node(InNode).HumRat;
1728 106951 : state.dataLoopNodes->Node(OutNode).Enthalpy = state.dataLoopNodes->Node(InNode).Enthalpy;
1729 :
1730 : // These initializations only need to be done once at the start of the iterations...
1731 106951 : if (state.dataGlobal->BeginTimeStepFlag && FirstHVACIteration) {
1732 : // Initialize the outside air conditions...
1733 14168 : state.dataLoopNodes->Node(OutsideAirNode).Temp = state.dataLoopNodes->Node(OutsideAirNode).OutAirDryBulb;
1734 14168 : state.dataLoopNodes->Node(OutsideAirNode).HumRat = state.dataEnvrn->OutHumRat;
1735 14168 : state.dataLoopNodes->Node(OutsideAirNode).Press = state.dataEnvrn->OutBaroPress;
1736 :
1737 : // The first pass through in a particular time step
1738 14168 : ZoneNum = ventSlab.ZonePtr;
1739 14168 : state.dataVentilatedSlab->ZeroSourceSumHATsurf(ZoneNum) =
1740 14168 : state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state); // Set this to figure what part of the load the radiant system meets
1741 34408 : for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
1742 20240 : SurfNum = ventSlab.SurfacePtr(RadSurfNum);
1743 20240 : state.dataVentilatedSlab->QRadSysSrcAvg(SurfNum) = 0.0; // Initialize this variable to zero (radiant system defaults to off)
1744 20240 : state.dataVentilatedSlab->LastQRadSysSrc(SurfNum) =
1745 : 0.0; // At the start of a time step, reset to zero so average calculation can begin again
1746 20240 : state.dataVentilatedSlab->LastSysTimeElapsed(SurfNum) =
1747 : 0.0; // At the start of a time step, reset to zero so average calculation can begin again
1748 20240 : state.dataVentilatedSlab->LastTimeStepSys(SurfNum) =
1749 : 0.0; // At the start of a time step, reset to zero so average calculation can begin again
1750 : }
1751 : }
1752 106951 : }
1753 :
1754 7 : void SizeVentilatedSlab(EnergyPlusData &state, int const Item)
1755 : {
1756 :
1757 : // SUBROUTINE INFORMATION:
1758 : // AUTHOR Young Tae Chae, Rick Strand
1759 : // DATE WRITTEN June 2008
1760 : // MODIFIED July 2013 Daeho Kang, add component sizing table entries
1761 : // July 2014, B. Nigusse, added scalable sizing
1762 : // RE-ENGINEERED na
1763 :
1764 : // PURPOSE OF THIS SUBROUTINE:
1765 : // This subroutine is for sizing Ventilated Slab components for which flow rates have not been
1766 : // specified in the input.
1767 :
1768 : // METHODOLOGY EMPLOYED:
1769 : // Obtains flow rates from the zone sizing arrays and plant sizing data.
1770 :
1771 : // Using/Aliasing
1772 : using namespace DataSizing;
1773 : using DataHVACGlobals::CoolingCapacitySizing;
1774 : using DataHVACGlobals::HeatingAirflowSizing;
1775 : using DataHVACGlobals::HeatingCapacitySizing;
1776 : using FluidProperties::GetDensityGlycol;
1777 : using FluidProperties::GetSpecificHeatGlycol;
1778 : using HVACHXAssistedCoolingCoil::GetHXCoilType;
1779 : using HVACHXAssistedCoolingCoil::GetHXDXCoilName;
1780 : using PlantUtilities::MyPlantSizingIndex;
1781 : using SteamCoils::GetCoilSteamInletNode;
1782 : using SteamCoils::GetCoilSteamOutletNode;
1783 :
1784 : // SUBROUTINE PARAMETER DEFINITIONS:
1785 : static constexpr std::string_view RoutineName("SizeVentilatedSlab");
1786 :
1787 7 : auto &ZoneEqSizing(state.dataSize->ZoneEqSizing);
1788 7 : auto &CurZoneEqNum(state.dataSize->CurZoneEqNum);
1789 7 : auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
1790 :
1791 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1792 : int PltSizHeatNum; // index of plant sizing object for 1st heating loop
1793 : int PltSizCoolNum; // index of plant sizing object for 1st cooling loop
1794 : bool ErrorsFound;
1795 : Real64 DesCoilLoad;
1796 : Real64 TempSteamIn;
1797 : Real64 EnthSteamInDry;
1798 : Real64 EnthSteamOutWet;
1799 : Real64 LatentHeatSteam;
1800 : Real64 SteamDensity;
1801 7 : int CoilWaterInletNode(0);
1802 7 : int CoilWaterOutletNode(0);
1803 7 : int CoilSteamInletNode(0);
1804 7 : int CoilSteamOutletNode(0);
1805 14 : std::string CoolingCoilName;
1806 14 : std::string CoolingCoilType;
1807 : Real64 rho;
1808 : Real64 Cp;
1809 7 : int DummyWaterIndex(1);
1810 : bool IsAutoSize; // Indicator to autosize
1811 : Real64 MaxAirVolFlowDes; // Autosized maximum air flow for reporting
1812 : Real64 MaxAirVolFlowUser; // Hardsized maximum air flow for reporting
1813 : Real64 OutAirVolFlowDes; // Autosized outdoor air flow for reporting
1814 : Real64 OutAirVolFlowUser; // Hardsized outdoor air flow for reporting
1815 : Real64 MinOutAirVolFlowDes; // Autosized minimum outdoor air flow for reporting
1816 : Real64 MinOutAirVolFlowUser; // Hardsized minimum outdoor air flow for reporting
1817 : Real64 MaxVolHotWaterFlowDes; // Autosized maximum hot water flow for reporting
1818 : Real64 MaxVolHotWaterFlowUser; // Hardsized maximum hot water flow for reporting
1819 : Real64 MaxVolHotSteamFlowDes; // Autosized maximum hot steam flow for reporting
1820 : Real64 MaxVolHotSteamFlowUser; // Hardsized maximum hot steam flow for reporting
1821 : Real64 MaxVolColdWaterFlowDes; // Autosized maximum cold water flow for reporting
1822 : Real64 MaxVolColdWaterFlowUser; // Hardsized maximum cold water flow for reporting
1823 14 : std::string CompName; // component name
1824 14 : std::string CompType; // component type
1825 14 : std::string SizingString; // input field sizing description (e.g., Nominal Capacity)
1826 : Real64 TempSize; // autosized value of coil input field
1827 7 : int FieldNum = 2; // IDD numeric field number where input field description is found
1828 : int SizingMethod; // Integer representation of sizing method name (e.g., CoolingAirflowSizing, HeatingAirflowSizing, CoolingCapacitySizing,
1829 : // HeatingCapacitySizing, etc.)
1830 : bool PrintFlag; // TRUE when sizing information is reported in the eio file
1831 : int zoneHVACIndex; // index of zoneHVAC equipment sizing specification
1832 7 : int SAFMethod(0); // supply air flow rate sizing method (SupplyAirFlowRate, FlowPerFloorArea, FractionOfAutosizedCoolingAirflow,
1833 : // FractionOfAutosizedHeatingAirflow ...)
1834 7 : int CapSizingMethod(0); // capacity sizing methods (HeatingDesignCapacity, CapacityPerFloorArea, FractionOfAutosizedCoolingCapacity, and
1835 : // FractionOfAutosizedHeatingCapacity )
1836 : Real64 CoolingAirVolFlowScalable; // cooling airvolume for rate determined using scalable sizing method
1837 : Real64 HeatingAirVolFlowScalable; // heating airvolume for rate determined using scalable sizing method
1838 7 : bool DoWaterCoilSizing = false; // if TRUE do water coil sizing calculation
1839 : Real64 WaterCoilSizDeltaT; // water coil deltaT for design water flow rate autosizing
1840 : int CoilNum; // index of water coil object
1841 :
1842 7 : DoWaterCoilSizing = false;
1843 7 : WaterCoilSizDeltaT = 0.0;
1844 7 : CoilNum = 0;
1845 7 : PltSizCoolNum = 0;
1846 7 : PltSizHeatNum = 0;
1847 7 : ErrorsFound = false;
1848 7 : IsAutoSize = false;
1849 7 : MaxAirVolFlowDes = 0.0;
1850 7 : MaxAirVolFlowUser = 0.0;
1851 7 : OutAirVolFlowDes = 0.0;
1852 7 : OutAirVolFlowUser = 0.0;
1853 7 : MinOutAirVolFlowDes = 0.0;
1854 7 : MinOutAirVolFlowUser = 0.0;
1855 7 : MaxVolHotWaterFlowDes = 0.0;
1856 7 : MaxVolHotWaterFlowUser = 0.0;
1857 7 : MaxVolHotSteamFlowDes = 0.0;
1858 7 : MaxVolHotSteamFlowUser = 0.0;
1859 7 : MaxVolColdWaterFlowDes = 0.0;
1860 7 : MaxVolColdWaterFlowUser = 0.0;
1861 7 : CoolingAirVolFlowScalable = 0.0;
1862 7 : HeatingAirVolFlowScalable = 0.0;
1863 7 : state.dataSize->DataScalableSizingON = false;
1864 7 : state.dataSize->DataScalableCapSizingON = false;
1865 7 : CompType = cMO_VentilatedSlab;
1866 7 : CompName = ventSlab.Name;
1867 7 : state.dataSize->DataZoneNumber = ventSlab.ZonePtr;
1868 7 : if (ventSlab.FanType_Num == DataHVACGlobals::FanType_SystemModelObject) {
1869 5 : state.dataSize->DataFanEnumType = DataAirSystems::ObjectVectorOOFanSystemModel;
1870 : } else {
1871 2 : state.dataSize->DataFanEnumType = DataAirSystems::StructArrayLegacyFanModels;
1872 : }
1873 7 : state.dataSize->DataFanIndex = ventSlab.Fan_Index;
1874 : // ventilated slab unit is always blow thru
1875 7 : state.dataSize->DataFanPlacement = DataSizing::ZoneFanPlacement::BlowThru;
1876 :
1877 7 : if (ventSlab.HVACSizingIndex > 0) {
1878 0 : zoneHVACIndex = ventSlab.HVACSizingIndex;
1879 : // N1 , \field Maximum Supply Air Flow Rate
1880 0 : FieldNum = 1;
1881 0 : PrintFlag = true;
1882 0 : SizingString = state.dataVentilatedSlab->VentSlabNumericFields(Item).FieldNames(FieldNum) + " [m3/s]";
1883 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingSAFMethod > 0) {
1884 0 : SizingMethod = DataHVACGlobals::CoolingAirflowSizing;
1885 0 : SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingSAFMethod;
1886 0 : ZoneEqSizing(CurZoneEqNum).SizingMethod(SizingMethod) = SAFMethod;
1887 0 : if (SAFMethod == None || SAFMethod == SupplyAirFlowRate || SAFMethod == FlowPerFloorArea ||
1888 : SAFMethod == FractionOfAutosizedCoolingAirflow) {
1889 0 : if (SAFMethod == SupplyAirFlowRate) {
1890 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow > 0.0) {
1891 0 : ZoneEqSizing(CurZoneEqNum).AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
1892 0 : ZoneEqSizing(CurZoneEqNum).SystemAirFlow = true;
1893 : }
1894 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
1895 0 : } else if (SAFMethod == FlowPerFloorArea) {
1896 0 : ZoneEqSizing(CurZoneEqNum).SystemAirFlow = true;
1897 0 : ZoneEqSizing(CurZoneEqNum).AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow *
1898 0 : state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
1899 0 : TempSize = ZoneEqSizing(CurZoneEqNum).AirVolFlow;
1900 0 : state.dataSize->DataScalableSizingON = true;
1901 0 : } else if (SAFMethod == FractionOfAutosizedCoolingAirflow) {
1902 0 : state.dataSize->DataFracOfAutosizedCoolingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
1903 0 : TempSize = AutoSize;
1904 0 : state.dataSize->DataScalableSizingON = true;
1905 : } else {
1906 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
1907 : }
1908 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
1909 0 : std::string stringOverride = "Maximum Air Flow Rate [m3/s]";
1910 0 : if (state.dataGlobal->isEpJSON) stringOverride = "maximum_air_flow_rate [m3/s]";
1911 0 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
1912 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
1913 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1914 0 : CoolingAirVolFlowScalable = sizingCoolingAirFlow.size(state, TempSize, ErrorsFound);
1915 :
1916 0 : } else if (SAFMethod == FlowPerCoolingCapacity) {
1917 0 : SizingMethod = CoolingCapacitySizing;
1918 0 : TempSize = AutoSize;
1919 0 : PrintFlag = false;
1920 0 : state.dataSize->DataScalableSizingON = true;
1921 0 : state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesCoolVolFlow;
1922 0 : CoolingCapacitySizer sizerCoolingCapacity;
1923 0 : sizerCoolingCapacity.overrideSizingString(SizingString);
1924 0 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1925 0 : state.dataSize->DataAutosizedCoolingCapacity = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
1926 0 : state.dataSize->DataFlowPerCoolingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxCoolAirVolFlow;
1927 0 : PrintFlag = true;
1928 0 : TempSize = AutoSize;
1929 0 : CoolingAirFlowSizer sizingCoolingAirFlow;
1930 0 : std::string stringOverride = "Maximum Air Flow Rate [m3/s]";
1931 0 : if (state.dataGlobal->isEpJSON) stringOverride = "maximum_air_flow_rate [m3/s]";
1932 0 : sizingCoolingAirFlow.overrideSizingString(stringOverride);
1933 : // sizingCoolingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
1934 0 : sizingCoolingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1935 0 : CoolingAirVolFlowScalable = sizingCoolingAirFlow.size(state, TempSize, ErrorsFound);
1936 : }
1937 : }
1938 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingSAFMethod > 0) {
1939 0 : SizingMethod = HeatingAirflowSizing;
1940 0 : SAFMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingSAFMethod;
1941 0 : ZoneEqSizing(CurZoneEqNum).SizingMethod(SizingMethod) = SAFMethod;
1942 0 : if (SAFMethod == None || SAFMethod == SupplyAirFlowRate || SAFMethod == FlowPerFloorArea ||
1943 : SAFMethod == FractionOfAutosizedHeatingAirflow) {
1944 0 : if (SAFMethod == SupplyAirFlowRate) {
1945 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow > 0.0) {
1946 0 : ZoneEqSizing(CurZoneEqNum).AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
1947 0 : ZoneEqSizing(CurZoneEqNum).SystemAirFlow = true;
1948 : }
1949 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
1950 0 : } else if (SAFMethod == FlowPerFloorArea) {
1951 0 : ZoneEqSizing(CurZoneEqNum).SystemAirFlow = true;
1952 0 : ZoneEqSizing(CurZoneEqNum).AirVolFlow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow *
1953 0 : state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
1954 0 : TempSize = ZoneEqSizing(CurZoneEqNum).AirVolFlow;
1955 0 : state.dataSize->DataScalableSizingON = true;
1956 0 : } else if (SAFMethod == FractionOfAutosizedHeatingAirflow) {
1957 0 : state.dataSize->DataFracOfAutosizedHeatingAirflow = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
1958 0 : TempSize = AutoSize;
1959 0 : state.dataSize->DataScalableSizingON = true;
1960 : } else {
1961 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
1962 : }
1963 0 : HeatingAirFlowSizer sizingHeatingAirFlow;
1964 0 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1965 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
1966 0 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1967 0 : HeatingAirVolFlowScalable = sizingHeatingAirFlow.size(state, TempSize, ErrorsFound);
1968 0 : } else if (SAFMethod == FlowPerHeatingCapacity) {
1969 0 : SizingMethod = HeatingCapacitySizing;
1970 0 : TempSize = AutoSize;
1971 0 : PrintFlag = false;
1972 0 : state.dataSize->DataScalableSizingON = true;
1973 0 : state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesHeatVolFlow;
1974 0 : HeatingCapacitySizer sizerHeatingCapacity;
1975 0 : sizerHeatingCapacity.overrideSizingString(SizingString);
1976 0 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1977 0 : state.dataSize->DataAutosizedHeatingCapacity = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
1978 0 : state.dataSize->DataFlowPerHeatingCapacity = state.dataSize->ZoneHVACSizing(zoneHVACIndex).MaxHeatAirVolFlow;
1979 0 : SizingMethod = HeatingAirflowSizing;
1980 0 : PrintFlag = true;
1981 0 : TempSize = AutoSize;
1982 0 : HeatingAirFlowSizer sizingHeatingAirFlow;
1983 0 : sizingHeatingAirFlow.overrideSizingString(SizingString);
1984 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
1985 0 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1986 0 : HeatingAirVolFlowScalable = sizingHeatingAirFlow.size(state, TempSize, ErrorsFound);
1987 : }
1988 : }
1989 : // DataScalableSizingON = false;
1990 0 : ventSlab.MaxAirVolFlow = max(CoolingAirVolFlowScalable, HeatingAirVolFlowScalable);
1991 : } else {
1992 : // no scalble sizing method has been specified. Sizing proceeds using the method
1993 : // specified in the zoneHVAC object
1994 : // N1 , \field Maximum Supply Air Flow Rate
1995 7 : FieldNum = 1;
1996 7 : PrintFlag = true;
1997 7 : SizingString = state.dataVentilatedSlab->VentSlabNumericFields(Item).FieldNames(FieldNum) + " [m3/s]";
1998 7 : TempSize = ventSlab.MaxAirVolFlow;
1999 14 : SystemAirFlowSizer sizerSystemAirFlow;
2000 7 : sizerSystemAirFlow.overrideSizingString(SizingString);
2001 : // sizerSystemAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
2002 7 : sizerSystemAirFlow.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2003 7 : ventSlab.MaxAirVolFlow = sizerSystemAirFlow.size(state, TempSize, ErrorsFound);
2004 : }
2005 :
2006 7 : IsAutoSize = false;
2007 7 : if (ventSlab.OutAirVolFlow == AutoSize) {
2008 0 : IsAutoSize = true;
2009 : }
2010 7 : if (CurZoneEqNum > 0) {
2011 7 : if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
2012 7 : if (ventSlab.OutAirVolFlow > 0.0) {
2013 14 : BaseSizer::reportSizerOutput(
2014 7 : state, cMO_VentilatedSlab, ventSlab.Name, "User-Specified Maximum Outdoor Air Flow Rate [m3/s]", ventSlab.OutAirVolFlow);
2015 : }
2016 : } else { // Autosize or hard-size with sizing run
2017 0 : CheckZoneSizing(state, cMO_VentilatedSlab, ventSlab.Name);
2018 0 : OutAirVolFlowDes = ventSlab.MaxAirVolFlow;
2019 0 : if (IsAutoSize) {
2020 0 : ventSlab.OutAirVolFlow = OutAirVolFlowDes;
2021 0 : BaseSizer::reportSizerOutput(
2022 0 : state, cMO_VentilatedSlab, ventSlab.Name, "Design Size Maximum Outdoor Air Flow Rate [m3/s]", OutAirVolFlowDes);
2023 : } else {
2024 0 : if (ventSlab.OutAirVolFlow > 0.0 && OutAirVolFlowDes > 0.0) {
2025 0 : OutAirVolFlowUser = ventSlab.OutAirVolFlow;
2026 0 : BaseSizer::reportSizerOutput(state,
2027 : cMO_VentilatedSlab,
2028 : ventSlab.Name,
2029 : "Design Size Maximum Outdoor Air Flow Rate [m3/s]",
2030 : OutAirVolFlowDes,
2031 : "User-Specified Maximum Outdoor Air Flow Rate [m3/s]",
2032 0 : OutAirVolFlowUser);
2033 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2034 0 : if ((std::abs(OutAirVolFlowDes - OutAirVolFlowUser) / OutAirVolFlowUser) > state.dataSize->AutoVsHardSizingThreshold) {
2035 0 : ShowMessage(state,
2036 0 : "SizeVentilatedSlab: Potential issue with equipment sizing for ZoneHVAC:VentilatedSlab = \"" +
2037 0 : ventSlab.Name + "\".");
2038 0 : ShowContinueError(state, format("User-Specified Maximum Outdoor Air Flow Rate of {:.5R} [m3/s]", OutAirVolFlowUser));
2039 0 : ShowContinueError(
2040 0 : state, format("differs from Design Size Maximum Outdoor Air Flow Rate of {:.5R} [m3/s]", OutAirVolFlowDes));
2041 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2042 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2043 : }
2044 : }
2045 : }
2046 : }
2047 : }
2048 : }
2049 :
2050 7 : IsAutoSize = false;
2051 7 : if (ventSlab.MinOutAirVolFlow == AutoSize) {
2052 0 : IsAutoSize = true;
2053 : }
2054 7 : if (CurZoneEqNum > 0) {
2055 7 : if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
2056 7 : if (ventSlab.MinOutAirVolFlow > 0.0) {
2057 14 : BaseSizer::reportSizerOutput(
2058 7 : state, cMO_VentilatedSlab, ventSlab.Name, "User-Specified Minimum Outdoor Air Flow Rate [m3/s]", ventSlab.MinOutAirVolFlow);
2059 : }
2060 : } else {
2061 0 : CheckZoneSizing(state, cMO_VentilatedSlab, ventSlab.Name);
2062 0 : MinOutAirVolFlowDes = min(state.dataSize->FinalZoneSizing(CurZoneEqNum).MinOA, ventSlab.MaxAirVolFlow);
2063 0 : if (MinOutAirVolFlowDes < SmallAirVolFlow) {
2064 0 : MinOutAirVolFlowDes = 0.0;
2065 : }
2066 0 : if (IsAutoSize) {
2067 0 : ventSlab.MinOutAirVolFlow = MinOutAirVolFlowDes;
2068 0 : BaseSizer::reportSizerOutput(
2069 0 : state, cMO_VentilatedSlab, ventSlab.Name, "Design Size Minimum Outdoor Air Flow Rate [m3/s]", MinOutAirVolFlowDes);
2070 : } else { // Hard-size with sizing data
2071 0 : if (ventSlab.MinOutAirVolFlow > 0.0 && MinOutAirVolFlowDes > 0.0) {
2072 0 : MinOutAirVolFlowUser = ventSlab.MinOutAirVolFlow;
2073 0 : BaseSizer::reportSizerOutput(state,
2074 : cMO_VentilatedSlab,
2075 : ventSlab.Name,
2076 : "Design Size Minimum Outdoor Air Flow Rate [m3/s]",
2077 : MinOutAirVolFlowDes,
2078 : "User-Specified Minimum Outdoor Air Flow Rate [m3/s]",
2079 0 : MinOutAirVolFlowUser);
2080 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2081 0 : if ((std::abs(MinOutAirVolFlowDes - MinOutAirVolFlowUser) / MinOutAirVolFlowUser) >
2082 0 : state.dataSize->AutoVsHardSizingThreshold) {
2083 0 : ShowMessage(state,
2084 0 : "SizeVentilatedSlab: Potential issue with equipment sizing for ZoneHVAC:VentilatedSlab = \"" +
2085 0 : ventSlab.Name + "\".");
2086 0 : ShowContinueError(state,
2087 0 : format("User-Specified Minimum Outdoor Air Flow Rate of {:.5R} [m3/s]", MinOutAirVolFlowUser));
2088 0 : ShowContinueError(
2089 0 : state, format("differs from Design Size Minimum Outdoor Air Flow Rate of {:.5R} [m3/s]", MinOutAirVolFlowDes));
2090 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2091 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2092 : }
2093 : }
2094 : }
2095 : }
2096 : }
2097 : }
2098 :
2099 7 : IsAutoSize = false;
2100 7 : if (ventSlab.MaxVolHotWaterFlow == AutoSize) {
2101 0 : IsAutoSize = true;
2102 : }
2103 7 : if (ventSlab.hCoilType == HeatingCoilType::Water) {
2104 :
2105 4 : if (CurZoneEqNum > 0) {
2106 4 : if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
2107 4 : if (ventSlab.MaxVolHotWaterFlow > 0.0) {
2108 8 : BaseSizer::reportSizerOutput(
2109 4 : state, cMO_VentilatedSlab, ventSlab.Name, "User-Specified Maximum Hot Water Flow [m3/s]", ventSlab.MaxVolHotWaterFlow);
2110 : }
2111 : } else { // Autosize or hard-size with sizing run
2112 0 : CheckZoneSizing(state, cMO_VentilatedSlab, ventSlab.Name);
2113 :
2114 0 : CoilWaterInletNode = WaterCoils::GetCoilWaterInletNode(state, "Coil:Heating:Water", ventSlab.heatingCoilName, ErrorsFound);
2115 0 : CoilWaterOutletNode = WaterCoils::GetCoilWaterOutletNode(state, "Coil:Heating:Water", ventSlab.heatingCoilName, ErrorsFound);
2116 0 : if (IsAutoSize) {
2117 0 : PltSizHeatNum = MyPlantSizingIndex(
2118 : state, "Coil:Heating:Water", ventSlab.heatingCoilName, CoilWaterInletNode, CoilWaterOutletNode, ErrorsFound);
2119 0 : CoilNum = WaterCoils::GetWaterCoilIndex(state, "COIL:HEATING:WATER", ventSlab.heatingCoilName, ErrorsFound);
2120 0 : if (state.dataWaterCoils->WaterCoil(CoilNum).UseDesignWaterDeltaTemp) {
2121 0 : WaterCoilSizDeltaT = state.dataWaterCoils->WaterCoil(CoilNum).DesignWaterDeltaTemp;
2122 0 : DoWaterCoilSizing = true;
2123 : } else {
2124 0 : if (PltSizHeatNum > 0) {
2125 0 : WaterCoilSizDeltaT = state.dataSize->PlantSizData(PltSizHeatNum).DeltaT;
2126 0 : DoWaterCoilSizing = true;
2127 : } else {
2128 0 : DoWaterCoilSizing = false;
2129 : // If there is no heating Plant Sizing object and autosizing was requested, issue fatal error message
2130 0 : ShowSevereError(state, "Autosizing of water flow requires a heating loop Sizing:Plant object");
2131 0 : ShowContinueError(state, "Occurs in " + cMO_VentilatedSlab + " Object=" + ventSlab.Name);
2132 0 : ErrorsFound = true;
2133 : }
2134 : }
2135 0 : if (DoWaterCoilSizing) {
2136 0 : if (state.dataSize->FinalZoneSizing(CurZoneEqNum).DesHeatMassFlow >= SmallAirVolFlow) {
2137 0 : SizingMethod = HeatingCapacitySizing;
2138 0 : if (ventSlab.HVACSizingIndex > 0) {
2139 0 : zoneHVACIndex = ventSlab.HVACSizingIndex;
2140 0 : CapSizingMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingCapMethod;
2141 0 : ZoneEqSizing(CurZoneEqNum).SizingMethod(SizingMethod) = CapSizingMethod;
2142 0 : if (CapSizingMethod == HeatingDesignCapacity || CapSizingMethod == CapacityPerFloorArea ||
2143 : CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
2144 0 : if (CapSizingMethod == HeatingDesignCapacity) {
2145 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity > 0.0) {
2146 0 : ZoneEqSizing(CurZoneEqNum).HeatingCapacity = true;
2147 0 : ZoneEqSizing(CurZoneEqNum).DesHeatingLoad =
2148 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
2149 : } else {
2150 0 : state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesHeatVolFlow;
2151 : }
2152 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
2153 0 : } else if (CapSizingMethod == CapacityPerFloorArea) {
2154 0 : ZoneEqSizing(CurZoneEqNum).HeatingCapacity = true;
2155 0 : ZoneEqSizing(CurZoneEqNum).DesHeatingLoad =
2156 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity *
2157 0 : state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
2158 0 : state.dataSize->DataScalableCapSizingON = true;
2159 0 : } else if (CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
2160 0 : state.dataSize->DataFracOfAutosizedHeatingCapacity =
2161 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
2162 0 : state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesHeatVolFlow;
2163 0 : TempSize = AutoSize;
2164 0 : state.dataSize->DataScalableCapSizingON = true;
2165 : }
2166 : }
2167 0 : SizingString = "";
2168 0 : PrintFlag = false;
2169 0 : HeatingCapacitySizer sizerHeatingCapacity;
2170 0 : sizerHeatingCapacity.overrideSizingString(SizingString);
2171 0 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2172 0 : DesCoilLoad = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
2173 0 : state.dataSize->DataScalableCapSizingON = false;
2174 : } else {
2175 0 : SizingString = "";
2176 0 : PrintFlag = false;
2177 0 : TempSize = AutoSize;
2178 0 : HeatingCapacitySizer sizerHeatingCapacity;
2179 0 : sizerHeatingCapacity.overrideSizingString(SizingString);
2180 0 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2181 0 : DesCoilLoad = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
2182 : }
2183 0 : rho = GetDensityGlycol(state,
2184 0 : state.dataPlnt->PlantLoop(ventSlab.HWPlantLoc.loopNum).FluidName,
2185 : DataGlobalConstants::HWInitConvTemp,
2186 0 : state.dataPlnt->PlantLoop(ventSlab.HWPlantLoc.loopNum).FluidIndex,
2187 : RoutineName);
2188 0 : Cp = GetSpecificHeatGlycol(state,
2189 0 : state.dataPlnt->PlantLoop(ventSlab.HWPlantLoc.loopNum).FluidName,
2190 : DataGlobalConstants::HWInitConvTemp,
2191 0 : state.dataPlnt->PlantLoop(ventSlab.HWPlantLoc.loopNum).FluidIndex,
2192 : RoutineName);
2193 0 : MaxVolHotWaterFlowDes = DesCoilLoad / (WaterCoilSizDeltaT * Cp * rho);
2194 : } else {
2195 0 : MaxVolHotWaterFlowDes = 0.0;
2196 : }
2197 : }
2198 : }
2199 :
2200 0 : if (IsAutoSize) {
2201 0 : ventSlab.MaxVolHotWaterFlow = MaxVolHotWaterFlowDes;
2202 0 : BaseSizer::reportSizerOutput(
2203 0 : state, cMO_VentilatedSlab, ventSlab.Name, "Design Size Maximum Hot Water Flow [m3/s]", MaxVolHotWaterFlowDes);
2204 : } else { // Hard-size with sizing data
2205 0 : if (ventSlab.MaxVolHotWaterFlow > 0.0 && MaxVolHotWaterFlowDes > 0.0) {
2206 0 : MaxVolHotWaterFlowUser = ventSlab.MaxVolHotWaterFlow;
2207 0 : BaseSizer::reportSizerOutput(state,
2208 : cMO_VentilatedSlab,
2209 : ventSlab.Name,
2210 : "Design Size Maximum Hot Water Flow [m3/s]",
2211 : MaxVolHotWaterFlowDes,
2212 : "User-Specified Maximum Hot Water Flow [m3/s]",
2213 0 : MaxVolHotWaterFlowUser);
2214 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2215 0 : if ((std::abs(MaxVolHotWaterFlowDes - MaxVolHotWaterFlowUser) / MaxVolHotWaterFlowUser) >
2216 0 : state.dataSize->AutoVsHardSizingThreshold) {
2217 0 : ShowMessage(state,
2218 0 : "SizeVentilatedSlab: Potential issue with equipment sizing for ZoneHVAC:VentilatedSlab = \"" +
2219 0 : ventSlab.Name + "\".");
2220 0 : ShowContinueError(state,
2221 0 : format("User-Specified Maximum Hot Water Flow of {:.5R} [m3/s]", MaxVolHotWaterFlowUser));
2222 0 : ShowContinueError(
2223 0 : state, format("differs from Design Size Maximum Hot Water Flow of {:.5R} [m3/s]", MaxVolHotWaterFlowDes));
2224 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2225 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2226 : }
2227 : }
2228 : }
2229 : }
2230 : }
2231 : }
2232 : } else {
2233 3 : ventSlab.MaxVolHotWaterFlow = 0.0;
2234 : }
2235 :
2236 7 : IsAutoSize = false;
2237 7 : if (ventSlab.MaxVolHotSteamFlow == AutoSize) {
2238 0 : IsAutoSize = true;
2239 : }
2240 7 : if (ventSlab.hCoilType == HeatingCoilType::Steam) {
2241 :
2242 0 : if (CurZoneEqNum > 0) {
2243 0 : if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
2244 0 : if (ventSlab.MaxVolHotSteamFlow > 0.0) {
2245 0 : BaseSizer::reportSizerOutput(
2246 0 : state, cMO_VentilatedSlab, ventSlab.Name, "User-Specified Maximum Steam Flow [m3/s]", ventSlab.MaxVolHotSteamFlow);
2247 : }
2248 : } else { // Autosize or hard-size with sizing run
2249 0 : CheckZoneSizing(state, "ZoneHVAC:VentilatedSlab", ventSlab.Name);
2250 :
2251 0 : CoilSteamInletNode = GetCoilSteamInletNode(state, "Coil:Heating:Steam", ventSlab.heatingCoilName, ErrorsFound);
2252 0 : CoilSteamOutletNode = GetCoilSteamOutletNode(state, "Coil:Heating:Steam", ventSlab.heatingCoilName, ErrorsFound);
2253 0 : if (IsAutoSize) {
2254 0 : PltSizHeatNum = MyPlantSizingIndex(
2255 : state, "Coil:Heating:Steam", ventSlab.heatingCoilName, CoilSteamInletNode, CoilSteamOutletNode, ErrorsFound);
2256 0 : if (PltSizHeatNum > 0) {
2257 0 : if (state.dataSize->FinalZoneSizing(CurZoneEqNum).DesHeatMassFlow >= SmallAirVolFlow) {
2258 0 : SizingMethod = HeatingCapacitySizing;
2259 0 : if (ventSlab.HVACSizingIndex > 0) {
2260 0 : zoneHVACIndex = ventSlab.HVACSizingIndex;
2261 0 : CapSizingMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).HeatingCapMethod;
2262 0 : ZoneEqSizing(CurZoneEqNum).SizingMethod(SizingMethod) = CapSizingMethod;
2263 0 : if (CapSizingMethod == HeatingDesignCapacity || CapSizingMethod == CapacityPerFloorArea ||
2264 : CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
2265 0 : if (CapSizingMethod == HeatingDesignCapacity) {
2266 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity > 0.0) {
2267 0 : ZoneEqSizing(CurZoneEqNum).HeatingCapacity = true;
2268 0 : ZoneEqSizing(CurZoneEqNum).DesHeatingLoad =
2269 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
2270 : } else {
2271 0 : state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesHeatVolFlow;
2272 : }
2273 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
2274 0 : } else if (CapSizingMethod == CapacityPerFloorArea) {
2275 0 : ZoneEqSizing(CurZoneEqNum).HeatingCapacity = true;
2276 0 : ZoneEqSizing(CurZoneEqNum).DesHeatingLoad =
2277 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity *
2278 0 : state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
2279 0 : state.dataSize->DataScalableCapSizingON = true;
2280 0 : } else if (CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
2281 0 : state.dataSize->DataFracOfAutosizedHeatingCapacity =
2282 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledHeatingCapacity;
2283 0 : state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesHeatVolFlow;
2284 0 : TempSize = AutoSize;
2285 0 : state.dataSize->DataScalableCapSizingON = true;
2286 : }
2287 : }
2288 0 : SizingString = "";
2289 0 : PrintFlag = false;
2290 0 : HeatingCapacitySizer sizerHeatingCapacity;
2291 0 : sizerHeatingCapacity.overrideSizingString(SizingString);
2292 0 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2293 0 : DesCoilLoad = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
2294 0 : state.dataSize->DataScalableCapSizingON = false;
2295 : } else {
2296 0 : SizingString = "";
2297 0 : PrintFlag = false;
2298 0 : TempSize = AutoSize;
2299 0 : HeatingCapacitySizer sizerHeatingCapacity;
2300 0 : sizerHeatingCapacity.overrideSizingString(SizingString);
2301 0 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2302 0 : DesCoilLoad = sizerHeatingCapacity.size(state, TempSize, ErrorsFound);
2303 : }
2304 0 : TempSteamIn = 100.00;
2305 0 : EnthSteamInDry =
2306 0 : GetSatEnthalpyRefrig(state, fluidNameSteam, TempSteamIn, 1.0, ventSlab.heatingCoil_FluidIndex, RoutineName);
2307 0 : EnthSteamOutWet =
2308 0 : GetSatEnthalpyRefrig(state, fluidNameSteam, TempSteamIn, 0.0, ventSlab.heatingCoil_FluidIndex, RoutineName);
2309 0 : LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet;
2310 0 : SteamDensity =
2311 0 : GetSatDensityRefrig(state, fluidNameSteam, TempSteamIn, 1.0, ventSlab.heatingCoil_FluidIndex, RoutineName);
2312 0 : Cp = GetSpecificHeatGlycol(state, fluidNameWater, DataGlobalConstants::HWInitConvTemp, DummyWaterIndex, RoutineName);
2313 0 : rho = GetDensityGlycol(state, fluidNameWater, DataGlobalConstants::HWInitConvTemp, DummyWaterIndex, RoutineName);
2314 0 : MaxVolHotSteamFlowDes =
2315 0 : DesCoilLoad / ((state.dataSize->PlantSizData(PltSizHeatNum).DeltaT * Cp * rho) + SteamDensity * LatentHeatSteam);
2316 : } else {
2317 0 : MaxVolHotSteamFlowDes = 0.0;
2318 : }
2319 : } else {
2320 0 : ShowSevereError(state, "Autosizing of Steam flow requires a heating loop Sizing:Plant object");
2321 0 : ShowContinueError(state, "Occurs in ZoneHVAC:VentilatedSlab Object=" + ventSlab.Name);
2322 0 : ErrorsFound = true;
2323 : }
2324 : }
2325 0 : if (IsAutoSize) {
2326 0 : ventSlab.MaxVolHotSteamFlow = MaxVolHotSteamFlowDes;
2327 0 : BaseSizer::reportSizerOutput(
2328 0 : state, cMO_VentilatedSlab, ventSlab.Name, "Design Size Maximum Steam Flow [m3/s]", MaxVolHotSteamFlowDes);
2329 : } else {
2330 0 : if (ventSlab.MaxVolHotSteamFlow > 0.0 && MaxVolHotSteamFlowDes > 0.0) {
2331 0 : MaxVolHotSteamFlowUser = ventSlab.MaxVolHotSteamFlow;
2332 0 : BaseSizer::reportSizerOutput(state,
2333 : cMO_VentilatedSlab,
2334 : ventSlab.Name,
2335 : "Design Size Maximum Steam Flow [m3/s]",
2336 : MaxVolHotSteamFlowDes,
2337 : "User-Specified Maximum Steam Flow [m3/s]",
2338 0 : MaxVolHotSteamFlowUser);
2339 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2340 0 : if ((std::abs(MaxVolHotSteamFlowDes - MaxVolHotSteamFlowUser) / MaxVolHotSteamFlowUser) >
2341 0 : state.dataSize->AutoVsHardSizingThreshold) {
2342 0 : ShowMessage(state,
2343 0 : "SizeVentilatedSlab: Potential issue with equipment sizing for ZoneHVAC:VentilatedSlab = \"" +
2344 0 : ventSlab.Name + "\".");
2345 0 : ShowContinueError(state, format("User-Specified Maximum Steam Flow of {:.5R} [m3/s]", MaxVolHotSteamFlowUser));
2346 0 : ShowContinueError(state,
2347 0 : format("differs from Design Size Maximum Steam Flow of {:.5R} [m3/s]", MaxVolHotSteamFlowDes));
2348 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2349 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2350 : }
2351 : }
2352 : }
2353 : }
2354 : }
2355 : }
2356 : } else {
2357 7 : ventSlab.MaxVolHotSteamFlow = 0.0;
2358 : }
2359 :
2360 7 : IsAutoSize = false;
2361 7 : if (ventSlab.MaxVolColdWaterFlow == AutoSize) {
2362 0 : IsAutoSize = true;
2363 : }
2364 7 : if (CurZoneEqNum > 0) {
2365 7 : if (!IsAutoSize && !state.dataSize->ZoneSizingRunDone) {
2366 7 : if (ventSlab.MaxVolColdWaterFlow > 0.0) {
2367 8 : BaseSizer::reportSizerOutput(
2368 4 : state, cMO_VentilatedSlab, ventSlab.Name, "User-Specified Maximum Cold Water Flow [m3/s]", ventSlab.MaxVolColdWaterFlow);
2369 : }
2370 : } else {
2371 0 : CheckZoneSizing(state, cMO_VentilatedSlab, ventSlab.Name);
2372 0 : if (ventSlab.cCoilType == CoolingCoilType::HXAssisted) {
2373 0 : CoolingCoilName = GetHXDXCoilName(state, ventSlab.coolingCoilTypeCh, ventSlab.coolingCoilName, ErrorsFound);
2374 0 : CoolingCoilType = GetHXCoilType(state, ventSlab.coolingCoilTypeCh, ventSlab.coolingCoilName, ErrorsFound);
2375 : } else {
2376 0 : CoolingCoilName = ventSlab.coolingCoilName;
2377 0 : CoolingCoilType = ventSlab.coolingCoilTypeCh;
2378 : }
2379 0 : CoilWaterInletNode = WaterCoils::GetCoilWaterInletNode(state, CoolingCoilType, CoolingCoilName, ErrorsFound);
2380 0 : CoilWaterOutletNode = WaterCoils::GetCoilWaterOutletNode(state, CoolingCoilType, CoolingCoilName, ErrorsFound);
2381 0 : if (IsAutoSize) {
2382 0 : PltSizCoolNum = MyPlantSizingIndex(state, CoolingCoilType, CoolingCoilName, CoilWaterInletNode, CoilWaterOutletNode, ErrorsFound);
2383 0 : CoilNum = WaterCoils::GetWaterCoilIndex(state, CoolingCoilType, CoolingCoilName, ErrorsFound);
2384 0 : if (state.dataWaterCoils->WaterCoil(CoilNum).UseDesignWaterDeltaTemp) {
2385 0 : WaterCoilSizDeltaT = state.dataWaterCoils->WaterCoil(CoilNum).DesignWaterDeltaTemp;
2386 0 : DoWaterCoilSizing = true;
2387 : } else {
2388 0 : if (PltSizCoolNum > 0) {
2389 0 : WaterCoilSizDeltaT = state.dataSize->PlantSizData(PltSizCoolNum).DeltaT;
2390 0 : DoWaterCoilSizing = true;
2391 : } else {
2392 0 : DoWaterCoilSizing = false;
2393 : // If there is no cooling Plant Sizing object and autosizing was requested, issue fatal error message
2394 0 : ShowSevereError(state, "Autosizing of water flow requires a cooling loop Sizing:Plant object");
2395 0 : ShowContinueError(state, "Occurs in " + cMO_VentilatedSlab + " Object=" + ventSlab.Name);
2396 0 : ErrorsFound = true;
2397 : }
2398 : }
2399 0 : if (DoWaterCoilSizing) {
2400 0 : if (state.dataSize->FinalZoneSizing(CurZoneEqNum).DesCoolMassFlow >= SmallAirVolFlow) {
2401 0 : SizingMethod = CoolingCapacitySizing;
2402 0 : if (ventSlab.HVACSizingIndex > 0) {
2403 0 : zoneHVACIndex = ventSlab.HVACSizingIndex;
2404 0 : CapSizingMethod = state.dataSize->ZoneHVACSizing(zoneHVACIndex).CoolingCapMethod;
2405 0 : ZoneEqSizing(CurZoneEqNum).SizingMethod(SizingMethod) = CapSizingMethod;
2406 0 : if (CapSizingMethod == CoolingDesignCapacity || CapSizingMethod == CapacityPerFloorArea ||
2407 : CapSizingMethod == FractionOfAutosizedCoolingCapacity) {
2408 0 : if (CapSizingMethod == CoolingDesignCapacity) {
2409 0 : if (state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity > 0.0) {
2410 0 : ZoneEqSizing(CurZoneEqNum).CoolingCapacity = true;
2411 0 : ZoneEqSizing(CurZoneEqNum).DesCoolingLoad =
2412 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity;
2413 : } else {
2414 0 : state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesCoolVolFlow;
2415 : }
2416 0 : TempSize = state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity;
2417 0 : } else if (CapSizingMethod == CapacityPerFloorArea) {
2418 0 : ZoneEqSizing(CurZoneEqNum).CoolingCapacity = true;
2419 0 : ZoneEqSizing(CurZoneEqNum).DesCoolingLoad =
2420 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity *
2421 0 : state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
2422 0 : state.dataSize->DataScalableCapSizingON = true;
2423 0 : } else if (CapSizingMethod == FractionOfAutosizedCoolingCapacity) {
2424 0 : state.dataSize->DataFracOfAutosizedHeatingCapacity =
2425 0 : state.dataSize->ZoneHVACSizing(zoneHVACIndex).ScaledCoolingCapacity;
2426 0 : state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesCoolVolFlow;
2427 0 : TempSize = AutoSize;
2428 0 : state.dataSize->DataScalableCapSizingON = true;
2429 : }
2430 : }
2431 0 : SizingString = "";
2432 0 : PrintFlag = false;
2433 0 : CoolingCapacitySizer sizerCoolingCapacity;
2434 0 : sizerCoolingCapacity.overrideSizingString(SizingString);
2435 0 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2436 0 : DesCoilLoad = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
2437 0 : state.dataSize->DataScalableCapSizingON = false;
2438 : } else {
2439 0 : SizingString = "";
2440 0 : PrintFlag = false;
2441 0 : TempSize = AutoSize;
2442 0 : state.dataSize->DataFlowUsedForSizing = state.dataSize->FinalZoneSizing(CurZoneEqNum).DesCoolVolFlow;
2443 0 : CoolingCapacitySizer sizerCoolingCapacity;
2444 0 : sizerCoolingCapacity.overrideSizingString(SizingString);
2445 0 : sizerCoolingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
2446 0 : DesCoilLoad = sizerCoolingCapacity.size(state, TempSize, ErrorsFound);
2447 : }
2448 0 : rho = GetDensityGlycol(state,
2449 0 : state.dataPlnt->PlantLoop(ventSlab.CWPlantLoc.loopNum).FluidName,
2450 : 5.,
2451 0 : state.dataPlnt->PlantLoop(ventSlab.CWPlantLoc.loopNum).FluidIndex,
2452 : RoutineName);
2453 0 : Cp = GetSpecificHeatGlycol(state,
2454 0 : state.dataPlnt->PlantLoop(ventSlab.CWPlantLoc.loopNum).FluidName,
2455 : 5.,
2456 0 : state.dataPlnt->PlantLoop(ventSlab.CWPlantLoc.loopNum).FluidIndex,
2457 : RoutineName);
2458 0 : MaxVolColdWaterFlowDes = DesCoilLoad / (WaterCoilSizDeltaT * Cp * rho);
2459 : } else {
2460 0 : MaxVolColdWaterFlowDes = 0.0;
2461 : }
2462 : }
2463 : }
2464 0 : if (IsAutoSize) {
2465 0 : ventSlab.MaxVolColdWaterFlow = MaxVolColdWaterFlowDes;
2466 0 : BaseSizer::reportSizerOutput(
2467 0 : state, cMO_VentilatedSlab, ventSlab.Name, "Design Size Maximum Cold Water Flow [m3/s]", MaxVolColdWaterFlowDes);
2468 : } else {
2469 0 : if (ventSlab.MaxVolColdWaterFlow > 0.0 && MaxVolColdWaterFlowDes > 0.0) {
2470 0 : MaxVolColdWaterFlowUser = ventSlab.MaxVolColdWaterFlow;
2471 0 : BaseSizer::reportSizerOutput(state,
2472 : cMO_VentilatedSlab,
2473 : ventSlab.Name,
2474 : "Design Size Maximum Cold Water Flow [m3/s]",
2475 : MaxVolColdWaterFlowDes,
2476 : "User-Specified Maximum Cold Water Flow [m3/s]",
2477 0 : MaxVolColdWaterFlowUser);
2478 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2479 0 : if ((std::abs(MaxVolColdWaterFlowDes - MaxVolColdWaterFlowUser) / MaxVolColdWaterFlowUser) >
2480 0 : state.dataSize->AutoVsHardSizingThreshold) {
2481 0 : ShowMessage(state,
2482 0 : "SizeVentilatedSlab: Potential issue with equipment sizing for ZoneHVAC:VentilatedSlab = \"" +
2483 0 : ventSlab.Name + "\".");
2484 0 : ShowContinueError(state, format("User-Specified Maximum Cold Water Flow of {:.5R} [m3/s]", MaxVolColdWaterFlowUser));
2485 0 : ShowContinueError(
2486 0 : state, format("differs from Design Size Maximum Cold Water Flow of {:.5R} [m3/s]", MaxVolColdWaterFlowDes));
2487 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2488 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2489 : }
2490 : }
2491 : }
2492 : }
2493 : }
2494 : }
2495 :
2496 7 : if (ventSlab.cCoilType == CoolingCoilType::HXAssisted) {
2497 0 : CoolingCoilName = GetHXDXCoilName(state, ventSlab.coolingCoilTypeCh, ventSlab.coolingCoilName, ErrorsFound);
2498 0 : CoolingCoilType = GetHXCoilType(state, ventSlab.coolingCoilTypeCh, ventSlab.coolingCoilName, ErrorsFound);
2499 : } else {
2500 7 : CoolingCoilName = ventSlab.coolingCoilName;
2501 7 : CoolingCoilType = ventSlab.coolingCoilTypeCh;
2502 : }
2503 7 : WaterCoils::SetCoilDesFlow(state, CoolingCoilType, CoolingCoilName, ventSlab.MaxAirVolFlow, ErrorsFound);
2504 7 : WaterCoils::SetCoilDesFlow(state, ventSlab.heatingCoilTypeCh, ventSlab.heatingCoilName, ventSlab.MaxAirVolFlow, ErrorsFound);
2505 :
2506 7 : if (CurZoneEqNum > 0) {
2507 7 : ZoneEqSizing(CurZoneEqNum).MaxHWVolFlow = ventSlab.MaxVolHotWaterFlow;
2508 7 : ZoneEqSizing(CurZoneEqNum).MaxCWVolFlow = ventSlab.MaxVolColdWaterFlow;
2509 : }
2510 :
2511 7 : if (ErrorsFound) {
2512 0 : ShowFatalError(state, "Preceding sizing errors cause program termination");
2513 : }
2514 7 : }
2515 :
2516 106951 : void CalcVentilatedSlab(EnergyPlusData &state,
2517 : int &Item, // number of the current ventilated slab being simulated
2518 : int const ZoneNum, // number of zone being served
2519 : bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
2520 : Real64 &PowerMet, // power supplied (W)
2521 : Real64 &LatOutputProvided // latent capacity supplied (kg/s)
2522 : )
2523 : {
2524 :
2525 : // SUBROUTINE INFORMATION:
2526 : // AUTHOR Young Tae Chae, Rick Strand
2527 : // DATE WRITTEN June 2008
2528 : // MODIFIED Don Shirey, Aug 2009 (LatOutputProvided)
2529 : // July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
2530 : // RE-ENGINEERED na
2531 :
2532 : // PURPOSE OF THIS SUBROUTINE:
2533 : // This subroutine mainly controls the action of the Ventilated Slab
2534 : // (or more exactly, it controls the amount of outside air brought in)
2535 : // based on the user input for controls and the defined controls
2536 : // algorithms.
2537 :
2538 : // METHODOLOGY EMPLOYED:
2539 : // Ventilated slab is controlled based on user input and what is happening in the
2540 : // simulation. There are various cases to consider:
2541 : // 1. OFF: Unit is schedule off or there is no load on it. All flow
2542 : // rates are set to zero and the temperatures are set to zone conditions
2543 : // (except for the outside air inlet).
2544 : // 2. HEATING/VARIABLE PERCENT: The unit is on, there is a heating load,
2545 : // and variable percent control is specified. The outside air fraction
2546 : // is set to the minimum outside air fraction (schedule based) and the
2547 : // heating coil is activated.
2548 : // 3. HEATING/FIXED TEMPERATURE: The unit is on, there is a heating load,
2549 : // and fixed temperature control is specified. The outside air fraction
2550 : // is varied in an attempt to obtain a mixed air temperature equal to
2551 : // the user specified temperature (schedule based). The heating coil
2552 : // is activated, if necessary.
2553 : // 4. COOLING/NO COIL: The unit is on, there is a cooling load, and no
2554 : // coil is present or it has been scheduled off. Set the amount of
2555 : // outside air based on the control type. Simulate the "mixing box".
2556 : // 5. COOLING/WITH COIL: The unit is on, there is a cooling load, and
2557 : // a cooling coil is present and scheduled on. Tries to use outside
2558 : // air as best as possible and then calls a cooling coil
2559 : // Note: controls are strictly temperature based and do not factor
2560 : // humidity into the equation (not an enthalpy economy cycle but rather
2561 : // a simple return air economy cycle). In addition, temperature predictions
2562 : // are not strict energy balances here in the control routine though
2563 : // in the mixing routine an energy balance is preserved.
2564 :
2565 : // REFERENCES:
2566 : // ASHRAE Systems and Equipment Handbook (SI), 1996. page 31.3
2567 :
2568 : // USE STATEMENTS:
2569 :
2570 : // Using/Aliasing
2571 106951 : auto &ZoneCompTurnFansOff = state.dataHVACGlobal->ZoneCompTurnFansOff;
2572 106951 : auto &ZoneCompTurnFansOn = state.dataHVACGlobal->ZoneCompTurnFansOn;
2573 106951 : auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
2574 :
2575 : using HeatingCoils::CheckHeatingCoilSchedule;
2576 : using HVACHXAssistedCoolingCoil::CheckHXAssistedCoolingCoilSchedule;
2577 : using NodeInputManager::GetOnlySingleNode;
2578 : using ScheduleManager::GetCurrentScheduleValue;
2579 : using SteamCoils::CheckSteamCoilSchedule;
2580 : using WaterCoils::CheckWaterCoilSchedule;
2581 :
2582 : // Locals
2583 : Real64 QZnReq;
2584 :
2585 : // SUBROUTINE ARGUMENT DEFINITIONS:
2586 :
2587 : // SUBROUTINE PARAMETER DEFINITIONS:
2588 :
2589 106951 : Real64 constexpr LowTempDiff(0.1); // Smallest allowed temperature difference for comparisons
2590 : // (below this value the temperatures are assumed equal)
2591 106951 : Real64 constexpr LowOAFracDiff(0.01); // Smallest allowed outside air fraction difference for comparison
2592 : // (below this value the fractions are assumed equal)
2593 :
2594 : // INTERFACE BLOCK SPECIFICATIONS
2595 :
2596 : // DERIVED TYPE DEFINITIONS
2597 : // na
2598 :
2599 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2600 : Real64 AirMassFlow; // air mass flow rate [kg/sec]
2601 : int AirRelNode; // outside air relief node
2602 : int ControlNode; // the hot water or cold water inlet node
2603 : int InletNode; // system air inlet node
2604 : int FanOutletNode; // system fan outlet node
2605 : int ZoneAirInNode; // zone supply air node
2606 : Real64 MaxOAFrac; // maximum possible outside air fraction
2607 : Real64 MaxWaterFlow; // maximum water flow for heating or cooling [kg/sec]
2608 : Real64 MinOAFrac; // minimum possible outside air fraction
2609 : Real64 MinWaterFlow; // minimum water flow for heating or cooling [kg/sec]
2610 : int OutletNode; // air outlet node
2611 : int OutsideAirNode; // outside air node
2612 : int MixoutNode; // oa mixer outlet node
2613 : int ReturnAirNode; // return air node
2614 : Real64 QUnitOut; // heating or sens. cooling provided by fan coil unit [watts]
2615 : Real64 LatentOutput; // Latent (moisture) add/removal rate, negative is dehumidification [kg/s]
2616 : Real64 Tdesired; // desired temperature after mixing inlet and outdoor air [degrees C]
2617 : Real64 Tinlet; // temperature of air coming into the ventilated slab [degrees C]
2618 : Real64 Toutdoor; // temperature of outdoor air being introduced into the ventilated slab [degrees C]
2619 : Real64 MaxSteamFlow;
2620 : Real64 MinSteamFlow;
2621 : Real64 RadInTemp; // "Desired" radiant system air inlet temperature [Celsius]**setpoint
2622 : Real64 SetPointTemp; // temperature that will be used to control the radiant system [Celsius]
2623 : Real64 SetPointTempHi; // Current high point in setpoint temperature range
2624 : Real64 SetPointTempLo; // Current low point in setpoint temperature range
2625 : Real64 AirTempHi; // Current high point in water temperature range
2626 : Real64 AirTempLo; // Current low point in water temperature range
2627 : Real64 AirTempHeatHi; // Current high point in water temperature range
2628 : Real64 AirTempCoolLo; // Current low point in water temperature range
2629 : Real64 CpFan; // Intermediate calculational variable for specific heat of air <<NOV9 Updated
2630 : Real64 ZoneRadNum; // number of zone being served *********************
2631 : int RadSurfNum; // DO loop counter for the surfaces that comprise a particular radiant system
2632 213902 : std::string MSlabIn;
2633 213902 : std::string MSlabOut;
2634 213902 : std::string SlabName;
2635 : int MSlabInletNode;
2636 : int MSlabOutletNode;
2637 106951 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
2638 106951 : static std::string const CurrentModuleObject("ZoneHVAC:VentilatedSlab");
2639 :
2640 106951 : switch (ventSlab.coilOption) {
2641 57316 : case CoilType::Both: {
2642 :
2643 57316 : switch (ventSlab.hCoilType) {
2644 28658 : case HeatingCoilType::Water: {
2645 28658 : CheckWaterCoilSchedule(state, ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
2646 28658 : break;
2647 : }
2648 0 : case HeatingCoilType::Steam: {
2649 0 : CheckSteamCoilSchedule(
2650 : state, "Coil:Heating:Steam", ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
2651 0 : break;
2652 : }
2653 28658 : case HeatingCoilType::Electric: {
2654 28658 : CheckHeatingCoilSchedule(
2655 : state, "Coil:Heating:Electric", ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
2656 28658 : break;
2657 : }
2658 0 : case HeatingCoilType::Gas: {
2659 0 : CheckHeatingCoilSchedule(
2660 : state, "Coil:Heating:Fuel", ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
2661 0 : break;
2662 : }
2663 0 : default:
2664 0 : break;
2665 : }
2666 :
2667 57316 : switch (ventSlab.cCoilType) {
2668 57316 : case CoolingCoilType::WaterCooling:
2669 : case CoolingCoilType::DetailedCooling: {
2670 57316 : CheckWaterCoilSchedule(state, ventSlab.coolingCoilName, ventSlab.coolingCoilSchedValue, ventSlab.coolingCoil_Index);
2671 57316 : break;
2672 : }
2673 0 : case CoolingCoilType::HXAssisted: {
2674 0 : CheckHXAssistedCoolingCoilSchedule(state,
2675 : "CoilSystem:Cooling:Water:HeatExchangerAssisted",
2676 : ventSlab.coolingCoilName,
2677 : ventSlab.coolingCoilSchedValue,
2678 : ventSlab.coolingCoil_Index);
2679 0 : break;
2680 : }
2681 0 : default:
2682 0 : break;
2683 : }
2684 57316 : break;
2685 : }
2686 49635 : case CoilType::Heating: {
2687 :
2688 49635 : switch (ventSlab.hCoilType) {
2689 33090 : case HeatingCoilType::Water: {
2690 33090 : CheckWaterCoilSchedule(state, ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
2691 33090 : break;
2692 : }
2693 0 : case HeatingCoilType::Steam: {
2694 0 : CheckSteamCoilSchedule(
2695 : state, "Coil:Heating:Steam", ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
2696 0 : break;
2697 : }
2698 0 : case HeatingCoilType::Electric: {
2699 0 : CheckHeatingCoilSchedule(
2700 : state, "Coil:Heating:Electric", ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
2701 0 : break;
2702 : }
2703 16545 : case HeatingCoilType::Gas: {
2704 16545 : CheckHeatingCoilSchedule(
2705 : state, "Coil:Heating:Fuel", ventSlab.heatingCoilName, ventSlab.heatingCoilSchedValue, ventSlab.heatingCoil_Index);
2706 16545 : break;
2707 : }
2708 0 : default:
2709 0 : break;
2710 : }
2711 49635 : break;
2712 : }
2713 0 : case CoilType::Cooling: {
2714 :
2715 0 : switch (ventSlab.cCoilType) {
2716 0 : case CoolingCoilType::WaterCooling:
2717 : case CoolingCoilType::DetailedCooling: {
2718 0 : CheckWaterCoilSchedule(state, ventSlab.coolingCoilName, ventSlab.coolingCoilSchedValue, ventSlab.coolingCoil_Index);
2719 0 : break;
2720 : }
2721 0 : case CoolingCoilType::HXAssisted: {
2722 0 : CheckHXAssistedCoolingCoilSchedule(state,
2723 : "CoilSystem:Cooling:Water:HeatExchangerAssisted",
2724 : ventSlab.coolingCoilName,
2725 : ventSlab.coolingCoilSchedValue,
2726 : ventSlab.coolingCoil_Index);
2727 0 : break;
2728 : }
2729 0 : default:
2730 0 : break;
2731 : }
2732 : }
2733 : case CoilType::None:
2734 : default:
2735 0 : break;
2736 : }
2737 :
2738 : // initialize local variables
2739 106951 : ControlNode = 0;
2740 106951 : QUnitOut = 0.0;
2741 106951 : LatentOutput = 0.0;
2742 106951 : MaxWaterFlow = 0.0;
2743 106951 : MinWaterFlow = 0.0;
2744 106951 : AirMassFlow = 0.0;
2745 106951 : InletNode = ventSlab.ReturnAirNode;
2746 106951 : OutletNode = ventSlab.RadInNode;
2747 106951 : FanOutletNode = ventSlab.FanOutletNode;
2748 106951 : ZoneAirInNode = ventSlab.ZoneAirInNode;
2749 106951 : OutsideAirNode = ventSlab.OutsideAirNode;
2750 106951 : AirRelNode = ventSlab.AirReliefNode;
2751 106951 : MixoutNode = ventSlab.OAMixerOutNode;
2752 106951 : ReturnAirNode = ventSlab.ReturnAirNode;
2753 106951 : ZoneRadNum = ventSlab.ZonePtr;
2754 106951 : RadSurfNum = ventSlab.NumOfSurfaces;
2755 106951 : Tinlet = state.dataLoopNodes->Node(InletNode).Temp;
2756 106951 : Toutdoor = state.dataLoopNodes->Node(OutsideAirNode).Temp;
2757 106951 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
2758 :
2759 : // Control Type Check
2760 106951 : switch (ventSlab.controlType) {
2761 45203 : case ControlType::MeanAirTemp: {
2762 45203 : SetPointTemp = thisZoneHB.MAT;
2763 45203 : break;
2764 : }
2765 16545 : case ControlType::MeanRadTemp: {
2766 16545 : SetPointTemp = state.dataHeatBal->ZoneMRT(ZoneNum);
2767 16545 : break;
2768 : }
2769 16545 : case ControlType::OperativeTemp: {
2770 16545 : SetPointTemp = 0.5 * (thisZoneHB.MAT + state.dataHeatBal->ZoneMRT(ZoneNum));
2771 16545 : break;
2772 : }
2773 28658 : case ControlType::OutdoorDryBulbTemp: {
2774 28658 : SetPointTemp = state.dataEnvrn->OutDryBulbTemp;
2775 28658 : break;
2776 : }
2777 0 : case ControlType::OutdoorWetBulbTemp: {
2778 0 : SetPointTemp = state.dataEnvrn->OutWetBulbTemp;
2779 0 : break;
2780 : }
2781 0 : case ControlType::SurfaceTemp: {
2782 0 : SetPointTemp = state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(RadSurfNum));
2783 0 : break;
2784 : }
2785 0 : case ControlType::DewPointTemp: {
2786 0 : SetPointTemp = PsyTdpFnWPb(
2787 0 : state, state.dataZoneTempPredictorCorrector->zoneHeatBalance(ventSlab.ZonePtr).ZoneAirHumRat, state.dataEnvrn->OutBaroPress);
2788 0 : break;
2789 : }
2790 0 : default: { // Should never get here
2791 0 : SetPointTemp = 0.0; // Suppress uninitialized warning
2792 0 : ShowSevereError(state, "Illegal control type in low temperature radiant system: " + ventSlab.Name);
2793 0 : ShowFatalError(state, "Preceding condition causes termination.");
2794 : }
2795 : }
2796 :
2797 : // Load Check
2798 :
2799 106951 : AirTempHeatHi = GetCurrentScheduleValue(state, ventSlab.HotCtrlHiTempSchedPtr);
2800 106951 : AirTempCoolLo = GetCurrentScheduleValue(state, ventSlab.ColdCtrlLoTempSchedPtr);
2801 :
2802 106951 : if (((SetPointTemp >= AirTempHeatHi) && (SetPointTemp <= AirTempCoolLo)) || (GetCurrentScheduleValue(state, ventSlab.SchedPtr) <= 0)) {
2803 :
2804 : // System is off or has no load upon it; set the flow rates to zero and then
2805 : // simulate the components with the no flow conditions
2806 29165 : state.dataLoopNodes->Node(InletNode).MassFlowRate = 0.0;
2807 29165 : state.dataLoopNodes->Node(InletNode).MassFlowRateMaxAvail = 0.0;
2808 29165 : state.dataLoopNodes->Node(InletNode).MassFlowRateMinAvail = 0.0;
2809 29165 : state.dataLoopNodes->Node(OutletNode).MassFlowRate = 0.0;
2810 29165 : state.dataLoopNodes->Node(OutletNode).MassFlowRateMaxAvail = 0.0;
2811 29165 : state.dataLoopNodes->Node(OutletNode).MassFlowRateMinAvail = 0.0;
2812 29165 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = 0.0;
2813 29165 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMaxAvail = 0.0;
2814 29165 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMinAvail = 0.0;
2815 29165 : state.dataLoopNodes->Node(AirRelNode).MassFlowRate = 0.0;
2816 29165 : state.dataLoopNodes->Node(AirRelNode).MassFlowRateMaxAvail = 0.0;
2817 29165 : state.dataLoopNodes->Node(AirRelNode).MassFlowRateMinAvail = 0.0;
2818 29165 : state.dataLoopNodes->Node(ReturnAirNode).MassFlowRate = 0.0;
2819 29165 : state.dataLoopNodes->Node(ReturnAirNode).MassFlowRateMaxAvail = 0.0;
2820 29165 : state.dataLoopNodes->Node(ReturnAirNode).MassFlowRateMinAvail = 0.0;
2821 29165 : state.dataLoopNodes->Node(MixoutNode).MassFlowRate = 0.0;
2822 29165 : state.dataLoopNodes->Node(MixoutNode).MassFlowRateMaxAvail = 0.0;
2823 29165 : state.dataLoopNodes->Node(MixoutNode).MassFlowRateMinAvail = 0.0;
2824 29165 : state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = 0.0;
2825 29165 : state.dataLoopNodes->Node(FanOutletNode).MassFlowRateMaxAvail = 0.0;
2826 29165 : state.dataLoopNodes->Node(FanOutletNode).MassFlowRateMinAvail = 0.0;
2827 29165 : AirMassFlow = 0.0;
2828 29165 : state.dataVentilatedSlab->HCoilOn = false;
2829 :
2830 : // Node condition
2831 29165 : state.dataLoopNodes->Node(InletNode).Temp = state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(1));
2832 29165 : state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(InletNode).Temp;
2833 29165 : state.dataLoopNodes->Node(OutletNode).Temp = state.dataLoopNodes->Node(FanOutletNode).Temp;
2834 :
2835 : // Node condition
2836 29165 : if (ventSlab.SysConfg == VentilatedSlabConfig::SeriesSlabs) {
2837 9580 : for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
2838 7185 : SlabName = ventSlab.SurfaceName(RadSurfNum);
2839 7185 : MSlabIn = ventSlab.SlabIn(RadSurfNum);
2840 7185 : MSlabOut = ventSlab.SlabOut(RadSurfNum);
2841 7185 : ventSlab.MSlabInNode = GetOnlySingleNode(state,
2842 : MSlabIn,
2843 : ErrorsFound,
2844 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
2845 : SlabName,
2846 : DataLoopNode::NodeFluidType::Air,
2847 : DataLoopNode::ConnectionType::Internal,
2848 : NodeInputManager::CompFluidStream::Primary,
2849 7185 : ObjectIsNotParent);
2850 7185 : ventSlab.MSlabOutNode = GetOnlySingleNode(state,
2851 : MSlabOut,
2852 : ErrorsFound,
2853 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
2854 : SlabName,
2855 : DataLoopNode::NodeFluidType::Air,
2856 : DataLoopNode::ConnectionType::Internal,
2857 : NodeInputManager::CompFluidStream::Primary,
2858 7185 : ObjectIsNotParent);
2859 7185 : MSlabInletNode = ventSlab.MSlabInNode;
2860 7185 : MSlabOutletNode = ventSlab.MSlabOutNode;
2861 :
2862 7185 : state.dataLoopNodes->Node(MSlabInletNode).Temp = state.dataLoopNodes->Node(InletNode).Temp;
2863 7185 : state.dataLoopNodes->Node(MSlabOutletNode).Temp = state.dataLoopNodes->Node(MSlabInletNode).Temp;
2864 : }
2865 : }
2866 :
2867 29165 : CalcVentilatedSlabComps(state, Item, FirstHVACIteration, QUnitOut);
2868 :
2869 : } else { // System On
2870 :
2871 77786 : if (SetPointTemp < AirTempHeatHi) { // HEATING MODE
2872 47732 : state.dataVentilatedSlab->OperatingMode = HeatingMode;
2873 :
2874 : // Check the setpoint and temperature span
2875 47732 : SetPointTempHi = GetCurrentScheduleValue(state, ventSlab.HotCtrlHiTempSchedPtr);
2876 47732 : SetPointTempLo = GetCurrentScheduleValue(state, ventSlab.HotCtrlLoTempSchedPtr);
2877 47732 : if (SetPointTempHi < SetPointTempLo) {
2878 0 : ShowSevereError(state, "Heating setpoint temperature mismatch in" + ventSlab.Name);
2879 0 : ShowContinueError(state, "High setpoint temperature is less than low setpoint temperature--check your schedule input");
2880 0 : ShowFatalError(state, "Preceding condition causes termination.");
2881 : }
2882 47732 : AirTempHi = GetCurrentScheduleValue(state, ventSlab.HotAirHiTempSchedPtr);
2883 47732 : AirTempLo = GetCurrentScheduleValue(state, ventSlab.HotAirLoTempSchedPtr);
2884 :
2885 47732 : if (AirTempHi < AirTempLo) {
2886 0 : ShowSevereError(state, "Heating Air temperature mismatch in" + ventSlab.Name);
2887 0 : ShowContinueError(state, "High Air temperature is less than low Air temperature--check your schedule input");
2888 0 : ShowFatalError(state, "Preceding condition causes termination.");
2889 : }
2890 :
2891 47732 : if (SetPointTemp >= SetPointTempHi) {
2892 : // System is above high heating setpoint so we should be able to turn the system off
2893 0 : RadInTemp = AirTempLo;
2894 :
2895 47732 : } else if (SetPointTemp <= SetPointTempLo) {
2896 : // System is running with its highest inlet temperature
2897 27637 : RadInTemp = AirTempHi;
2898 : } else {
2899 : // Interpolate to obtain the current radiant system inlet temperature
2900 20095 : RadInTemp = AirTempHi - (AirTempHi - AirTempLo) * (SetPointTemp - SetPointTempLo) / (SetPointTempHi - SetPointTempLo);
2901 : }
2902 :
2903 47732 : state.dataLoopNodes->Node(ventSlab.RadInNode).Temp = RadInTemp;
2904 :
2905 47732 : ControlNode = ventSlab.HotControlNode;
2906 47732 : MaxWaterFlow = ventSlab.MaxHotWaterFlow;
2907 47732 : MinWaterFlow = ventSlab.MinHotWaterFlow;
2908 47732 : MaxSteamFlow = ventSlab.MaxHotSteamFlow;
2909 47732 : MinSteamFlow = ventSlab.MinHotSteamFlow;
2910 :
2911 : // On the first HVAC iteration the system values are given to the controller, but after that
2912 : // the demand limits are in place and there needs to be feedback to the Zone Equipment
2913 :
2914 47732 : if (!FirstHVACIteration && ventSlab.hCoilType == HeatingCoilType::Water) {
2915 14411 : MaxWaterFlow = state.dataLoopNodes->Node(ControlNode).MassFlowRateMaxAvail;
2916 14411 : MinWaterFlow = state.dataLoopNodes->Node(ControlNode).MassFlowRateMinAvail;
2917 : }
2918 :
2919 47732 : if (!FirstHVACIteration && ventSlab.hCoilType == HeatingCoilType::Steam) {
2920 0 : MaxSteamFlow = state.dataLoopNodes->Node(ControlNode).MassFlowRateMaxAvail;
2921 0 : MinSteamFlow = state.dataLoopNodes->Node(ControlNode).MassFlowRateMinAvail;
2922 : }
2923 :
2924 47732 : state.dataVentilatedSlab->HCoilOn = true;
2925 :
2926 47732 : if (state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate > 0.0) {
2927 95464 : MinOAFrac = GetCurrentScheduleValue(state, ventSlab.MinOASchedPtr) *
2928 47732 : (ventSlab.MinOutAirMassFlow / state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate);
2929 : } else {
2930 0 : MinOAFrac = 0.0;
2931 : }
2932 :
2933 47732 : MinOAFrac = min(1.0, max(0.0, MinOAFrac));
2934 :
2935 47732 : if ((!ventSlab.heatingCoilPresent) || (ventSlab.heatingCoilSchedValue <= 0.0)) {
2936 : // In heating mode, but there is no coil to provide heating. This is handled
2937 : // differently than if there was a heating coil present. Fixed temperature
2938 : // will still try to vary the amount of outside air to meet the desired
2939 : // mixed air temperature, while variable percent will go to full ventilation
2940 : // when it is most advantageous.
2941 :
2942 : // If there are no coil, Slab In Node is assumed to be Fan Outlet Node
2943 :
2944 0 : OutletNode = FanOutletNode;
2945 :
2946 0 : switch (ventSlab.outsideAirControlType) {
2947 0 : case OutsideAirControlType::FixedOAControl: {
2948 : // In this control type, the outdoor air flow rate is fixed to the maximum value
2949 : // which is equal to the minimum value, regardless of all the other conditions.
2950 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
2951 0 : break;
2952 : }
2953 0 : case OutsideAirControlType::VariablePercent: {
2954 : // This algorithm is probably a bit simplistic in that it just bounces
2955 : // back and forth between the maximum outside air and the minimum. In
2956 : // reality, a system *might* vary between the two based on the load in
2957 : // the zone. This simple flow control might cause some overcooling but
2958 : // chances are that if there is a cooling load and the zone temperature
2959 : // gets above the outside temperature that overcooling won't be significant.
2960 0 : Tinlet = state.dataLoopNodes->Node(InletNode).Temp;
2961 0 : Toutdoor = state.dataLoopNodes->Node(OutsideAirNode).Temp;
2962 :
2963 0 : if (Tinlet >= Toutdoor) {
2964 :
2965 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
2966 :
2967 : } else { // Tinlet < Toutdoor
2968 :
2969 0 : MaxOAFrac = GetCurrentScheduleValue(state, ventSlab.MaxOASchedPtr);
2970 0 : state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
2971 : }
2972 0 : break;
2973 : }
2974 0 : case OutsideAirControlType::FixedTemperature: {
2975 : // This is basically the same algorithm as for the heating case...
2976 0 : Tdesired = GetCurrentScheduleValue(state, ventSlab.TempSchedPtr);
2977 0 : MaxOAFrac = 1.0;
2978 :
2979 0 : if (std::abs(Tinlet - Toutdoor) <= LowTempDiff) { // no difference in indoor and outdoor conditions-->set OA to minimum
2980 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
2981 0 : } else if (std::abs(MaxOAFrac - MinOAFrac) <= LowOAFracDiff) { // no difference in outside air fractions
2982 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
2983 0 : } else if (((Tdesired <= Tinlet) && (Tdesired >= Toutdoor)) || ((Tdesired >= Tinlet) && (Tdesired <= Toutdoor))) {
2984 : // Desired temperature is between the inlet and outdoor temperatures
2985 : // so vary the flow rate between no outside air and no recirculation air
2986 : // then applying the maximum and minimum limits the user has scheduled
2987 : // to make sure too much/little outside air is being introduced
2988 0 : state.dataVentilatedSlab->OAMassFlowRate =
2989 0 : ((Tdesired - Tinlet) / (Toutdoor - Tinlet)) * state.dataLoopNodes->Node(InletNode).MassFlowRate;
2990 0 : state.dataVentilatedSlab->OAMassFlowRate =
2991 0 : max(state.dataVentilatedSlab->OAMassFlowRate, (MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
2992 0 : state.dataVentilatedSlab->OAMassFlowRate =
2993 0 : min(state.dataVentilatedSlab->OAMassFlowRate, (MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
2994 0 : } else if ((Tdesired < Tinlet) && (Tdesired < Toutdoor)) {
2995 : // Desired temperature is below both the inlet and outdoor temperatures
2996 : // so use whichever flow rate (max or min) that will get closer
2997 0 : if (Tinlet < Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
2998 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
2999 : } else { // Toutdoor closer to Tdesired so use maximum outside air
3000 0 : state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3001 : }
3002 0 : } else if ((Tdesired > Tinlet) && (Tdesired > Toutdoor)) {
3003 : // Desired temperature is above both the inlet and outdoor temperatures
3004 : // so use whichever flow rate (max or min) that will get closer
3005 0 : if (Tinlet > Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
3006 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3007 : } else { // Toutdoor closer to Tdesired so use maximum outside air
3008 0 : state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3009 : }
3010 : } else {
3011 : // It should NEVER get to this point, but just in case...
3012 0 : ShowFatalError(state, "Ventilated Slab simulation control: illogical condition for " + ventSlab.Name);
3013 : }
3014 0 : break;
3015 : }
3016 0 : default:
3017 0 : break;
3018 : }
3019 :
3020 0 : CalcVentilatedSlabComps(state, Item, FirstHVACIteration, QUnitOut);
3021 :
3022 : } else { // Heating Coil present
3023 :
3024 47732 : switch (ventSlab.outsideAirControlType) {
3025 0 : case OutsideAirControlType::FixedOAControl: {
3026 : // In this control type, the outdoor air flow rate is fixed to the maximum value
3027 : // which is equal to the minimum value, regardless of all the other conditions.
3028 0 : if (state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate > 0.0) {
3029 0 : MaxOAFrac = GetCurrentScheduleValue(state, ventSlab.MaxOASchedPtr);
3030 : } else {
3031 0 : MaxOAFrac = 0.0;
3032 : }
3033 0 : MaxOAFrac = min(1.0, max(0.0, MinOAFrac));
3034 0 : state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3035 0 : break;
3036 : }
3037 47732 : case OutsideAirControlType::VariablePercent: {
3038 : // In heating mode, the ouside air for "variable percent" control
3039 : // is set to the minimum value
3040 :
3041 47732 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3042 47732 : break;
3043 : }
3044 0 : case OutsideAirControlType::FixedTemperature: {
3045 : // This is basically the same algorithm as for the heating case...
3046 0 : Tdesired = GetCurrentScheduleValue(state, ventSlab.TempSchedPtr);
3047 0 : MaxOAFrac = 1.0;
3048 :
3049 0 : if (std::abs(Tinlet - Toutdoor) <= LowTempDiff) { // no difference in indoor and outdoor conditions-->set OA to minimum
3050 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3051 0 : } else if (std::abs(MaxOAFrac - MinOAFrac) <= LowOAFracDiff) { // no difference in outside air fractions
3052 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3053 0 : } else if (((Tdesired <= Tinlet) && (Tdesired >= Toutdoor)) || ((Tdesired >= Tinlet) && (Tdesired <= Toutdoor))) {
3054 : // Desired temperature is between the inlet and outdoor temperatures
3055 : // so vary the flow rate between no outside air and no recirculation air
3056 : // then applying the maximum and minimum limits the user has scheduled
3057 : // to make sure too much/little outside air is being introduced
3058 0 : state.dataVentilatedSlab->OAMassFlowRate =
3059 0 : ((Tdesired - Tinlet) / (Toutdoor - Tinlet)) * state.dataLoopNodes->Node(InletNode).MassFlowRate;
3060 0 : state.dataVentilatedSlab->OAMassFlowRate =
3061 0 : max(state.dataVentilatedSlab->OAMassFlowRate, (MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
3062 0 : state.dataVentilatedSlab->OAMassFlowRate =
3063 0 : min(state.dataVentilatedSlab->OAMassFlowRate, (MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
3064 0 : } else if ((Tdesired < Tinlet) && (Tdesired < Toutdoor)) {
3065 : // Desired temperature is below both the inlet and outdoor temperatures
3066 : // so use whichever flow rate (max or min) that will get closer
3067 0 : if (Tinlet < Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
3068 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3069 : } else { // Toutdoor closer to Tdesired so use maximum outside air
3070 0 : state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3071 : }
3072 0 : } else if ((Tdesired > Tinlet) && (Tdesired > Toutdoor)) {
3073 : // Desired temperature is above both the inlet and outdoor temperatures
3074 : // so use whichever flow rate (max or min) that will get closer
3075 0 : if (Tinlet > Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
3076 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3077 : } else { // Toutdoor closer to Tdesired so use maximum outside air
3078 0 : state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3079 : }
3080 : } else {
3081 : // It should NEVER get to this point, but just in case...
3082 0 : ShowFatalError(state, "Ventilated Slab simulation control: illogical condition for " + ventSlab.Name);
3083 : }
3084 0 : break;
3085 : }
3086 0 : default:
3087 0 : break;
3088 : }
3089 :
3090 47732 : SimVentSlabOAMixer(state, Item);
3091 :
3092 47732 : if (ventSlab.FanType_Num == DataHVACGlobals::FanType_SystemModelObject) {
3093 38138 : state.dataHVACFan->fanObjs[ventSlab.Fan_Index]->simulate(state, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _);
3094 9594 : } else if (ventSlab.FanType_Num == DataHVACGlobals::FanType_SimpleConstVolume) {
3095 9594 : Fans::SimulateFanComponents(
3096 : state, ventSlab.FanName, FirstHVACIteration, ventSlab.Fan_Index, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff);
3097 : }
3098 :
3099 47732 : CpFan = PsyCpAirFnW(state.dataLoopNodes->Node(FanOutletNode).HumRat);
3100 47732 : QZnReq =
3101 47732 : (state.dataLoopNodes->Node(OutletNode).MassFlowRate) * CpFan * (RadInTemp - state.dataLoopNodes->Node(FanOutletNode).Temp);
3102 :
3103 : // Setup the coil configuration
3104 47732 : switch (ventSlab.hCoilType) {
3105 :
3106 29038 : case HeatingCoilType::Water: {
3107 : // control water flow to obtain output matching QZnReq
3108 :
3109 29038 : ControlCompOutput(state,
3110 : ventSlab.Name,
3111 : cMO_VentilatedSlab,
3112 : Item,
3113 : FirstHVACIteration,
3114 : QZnReq,
3115 : ControlNode,
3116 : MaxWaterFlow,
3117 : MinWaterFlow,
3118 : 0.001,
3119 : ventSlab.ControlCompTypeNum,
3120 : ventSlab.CompErrIndex,
3121 : _,
3122 : _,
3123 : _,
3124 : _,
3125 : _,
3126 : ventSlab.HWPlantLoc);
3127 29038 : break;
3128 : }
3129 18694 : case HeatingCoilType::Gas:
3130 : case HeatingCoilType::Electric:
3131 : case HeatingCoilType::Steam: {
3132 :
3133 18694 : CalcVentilatedSlabComps(state, Item, FirstHVACIteration, QUnitOut);
3134 18694 : break;
3135 : }
3136 0 : default:
3137 0 : break;
3138 : }
3139 :
3140 : } // Coil/no coil block
3141 :
3142 30054 : } else if (SetPointTemp > AirTempCoolLo) { // Cooling Mode
3143 :
3144 30054 : state.dataVentilatedSlab->OperatingMode = CoolingMode;
3145 :
3146 30054 : SetPointTempHi = GetCurrentScheduleValue(state, ventSlab.ColdCtrlHiTempSchedPtr);
3147 30054 : SetPointTempLo = GetCurrentScheduleValue(state, ventSlab.ColdCtrlLoTempSchedPtr);
3148 30054 : if (SetPointTempHi < SetPointTempLo) {
3149 0 : ShowSevereError(state, "Cooling setpoint temperature mismatch in" + ventSlab.Name);
3150 0 : ShowContinueError(state, "High setpoint temperature is less than low setpoint temperature--check your schedule input");
3151 0 : ShowFatalError(state, "Preceding condition causes termination.");
3152 : }
3153 :
3154 30054 : AirTempHi = GetCurrentScheduleValue(state, ventSlab.ColdAirHiTempSchedPtr);
3155 30054 : AirTempLo = GetCurrentScheduleValue(state, ventSlab.ColdAirLoTempSchedPtr);
3156 30054 : if (AirTempHi < AirTempLo) {
3157 0 : ShowSevereError(state, "Cooling Air temperature mismatch in" + ventSlab.Name);
3158 0 : ShowContinueError(state, "High Air temperature is less than low Air temperature--check your schedule input");
3159 0 : ShowFatalError(state, "Preceding condition causes termination.");
3160 : }
3161 :
3162 30054 : if (SetPointTemp <= SetPointTempLo) {
3163 : // System is below low cooling setpoint so we should be able to turn the system off
3164 0 : RadInTemp = AirTempHi;
3165 30054 : } else if (SetPointTemp >= SetPointTempHi) {
3166 : // System is running with its lowest inlet temperature
3167 16708 : RadInTemp = AirTempLo;
3168 : } else {
3169 : // Interpolate to obtain the current radiant system inlet temperature
3170 13346 : RadInTemp = AirTempHi - (AirTempHi - AirTempLo) * (SetPointTemp - SetPointTempLo) / (SetPointTempHi - SetPointTempLo);
3171 : }
3172 :
3173 30054 : ControlNode = ventSlab.ColdControlNode;
3174 30054 : MaxWaterFlow = ventSlab.MaxColdWaterFlow;
3175 30054 : MinWaterFlow = ventSlab.MinColdWaterFlow;
3176 :
3177 : // On the first HVAC iteration the system values are given to the controller, but after that
3178 : // the demand limits are in place and there needs to be feedback to the Zone Equipment
3179 30054 : if ((!FirstHVACIteration) && (ControlNode > 0) && (ventSlab.coolingCoilPresent)) {
3180 10497 : MaxWaterFlow = state.dataLoopNodes->Node(ControlNode).MassFlowRateMaxAvail;
3181 10497 : MinWaterFlow = state.dataLoopNodes->Node(ControlNode).MassFlowRateMinAvail;
3182 : }
3183 30054 : state.dataVentilatedSlab->HCoilOn = false;
3184 :
3185 30054 : if (state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate > 0.0) {
3186 60108 : MinOAFrac = GetCurrentScheduleValue(state, ventSlab.MinOASchedPtr) *
3187 30054 : (ventSlab.MinOutAirMassFlow / state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate);
3188 : } else {
3189 0 : MinOAFrac = 0.0;
3190 : }
3191 30054 : MinOAFrac = min(1.0, max(0.0, MinOAFrac));
3192 :
3193 30054 : if ((!ventSlab.coolingCoilPresent) || (ventSlab.coolingCoilSchedValue <= 0.0)) {
3194 : // In cooling mode, but there is no coil to provide cooling. This is handled
3195 : // differently than if there was a cooling coil present. Fixed temperature
3196 : // will still try to vary the amount of outside air to meet the desired
3197 : // mixed air temperature, while variable percent will go to full ventilation
3198 : // when it is most advantageous.
3199 :
3200 : // If there are no coil, Slab In Node is assumed to be Fan Outlet Node
3201 22190 : OutletNode = FanOutletNode;
3202 :
3203 22190 : switch (ventSlab.outsideAirControlType) {
3204 :
3205 0 : case OutsideAirControlType::FixedOAControl: {
3206 : // In this control type, the outdoor air flow rate is fixed to the maximum value
3207 : // which is equal to the minimum value, regardless of all the other conditions.
3208 0 : if (state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate > 0.0) {
3209 0 : MaxOAFrac = GetCurrentScheduleValue(state, ventSlab.MaxOASchedPtr);
3210 : } else {
3211 0 : MaxOAFrac = 0.0;
3212 : }
3213 0 : MaxOAFrac = min(1.0, max(0.0, MinOAFrac));
3214 0 : state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3215 0 : break;
3216 : }
3217 22190 : case OutsideAirControlType::VariablePercent: {
3218 : // This algorithm is probably a bit simplistic in that it just bounces
3219 : // back and forth between the maximum outside air and the minimum. In
3220 : // reality, a system *might* vary between the two based on the load in
3221 : // the zone. This simple flow control might cause some overcooling but
3222 : // chances are that if there is a cooling load and the zone temperature
3223 : // gets above the outside temperature that overcooling won't be significant.
3224 :
3225 22190 : Tinlet = state.dataLoopNodes->Node(InletNode).Temp;
3226 22190 : Toutdoor = state.dataLoopNodes->Node(OutsideAirNode).Temp;
3227 :
3228 22190 : if (Tinlet <= Toutdoor) {
3229 :
3230 1130 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3231 :
3232 : } else { // Tinlet > Toutdoor
3233 :
3234 21060 : MaxOAFrac = GetCurrentScheduleValue(state, ventSlab.MaxOASchedPtr);
3235 21060 : state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3236 : }
3237 22190 : break;
3238 : }
3239 0 : case OutsideAirControlType::FixedTemperature: {
3240 : // This is basically the same algorithm as for the heating case...
3241 0 : Tdesired = GetCurrentScheduleValue(state, ventSlab.TempSchedPtr);
3242 0 : MaxOAFrac = 1.0;
3243 :
3244 0 : if (std::abs(Tinlet - Toutdoor) <= LowTempDiff) { // no difference in indoor and outdoor conditions-->set OA to minimum
3245 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3246 0 : } else if (std::abs(MaxOAFrac - MinOAFrac) <= LowOAFracDiff) { // no difference in outside air fractions
3247 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3248 0 : } else if (((Tdesired <= Tinlet) && (Tdesired >= Toutdoor)) || ((Tdesired >= Tinlet) && (Tdesired <= Toutdoor))) {
3249 : // Desired temperature is between the inlet and outdoor temperatures
3250 : // so vary the flow rate between no outside air and no recirculation air
3251 : // then applying the maximum and minimum limits the user has scheduled
3252 : // to make sure too much/little outside air is being introduced
3253 0 : state.dataVentilatedSlab->OAMassFlowRate =
3254 0 : ((Tdesired - Tinlet) / (Toutdoor - Tinlet)) * state.dataLoopNodes->Node(InletNode).MassFlowRate;
3255 0 : state.dataVentilatedSlab->OAMassFlowRate =
3256 0 : max(state.dataVentilatedSlab->OAMassFlowRate, (MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
3257 0 : state.dataVentilatedSlab->OAMassFlowRate =
3258 0 : min(state.dataVentilatedSlab->OAMassFlowRate, (MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
3259 0 : } else if ((Tdesired < Tinlet) && (Tdesired < Toutdoor)) {
3260 : // Desired temperature is below both the inlet and outdoor temperatures
3261 : // so use whichever flow rate (max or min) that will get closer
3262 0 : if (Tinlet < Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
3263 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3264 : } else { // Toutdoor closer to Tdesired so use maximum outside air
3265 0 : state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3266 : }
3267 0 : } else if ((Tdesired > Tinlet) && (Tdesired > Toutdoor)) {
3268 : // Desired temperature is above both the inlet and outdoor temperatures
3269 : // so use whichever flow rate (max or min) that will get closer
3270 0 : if (Tinlet > Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
3271 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3272 : } else { // Toutdoor closer to Tdesired so use maximum outside air
3273 0 : state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3274 : }
3275 : } else {
3276 : // It should NEVER get to this point, but just in case...
3277 0 : ShowFatalError(state, cMO_VentilatedSlab + " simulation control: illogical condition for " + ventSlab.Name);
3278 : }
3279 0 : break;
3280 : }
3281 0 : default:
3282 0 : break;
3283 : }
3284 :
3285 22190 : CalcVentilatedSlabComps(state, Item, FirstHVACIteration, QUnitOut);
3286 :
3287 : } else {
3288 : // There is a cooling load and there is a cooling coil present (presumably).
3289 : // Variable percent will throttle outside air back to the minimum while
3290 : // fixed temperature will still try to vary the outside air amount to meet
3291 : // the desired mixed air temperature.
3292 :
3293 7864 : switch (ventSlab.outsideAirControlType) {
3294 :
3295 0 : case OutsideAirControlType::FixedOAControl: {
3296 : // In this control type, the outdoor air flow rate is fixed to the maximum value
3297 : // which is equal to the minimum value, regardless of all the other conditions.
3298 0 : if (state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate > 0.0) {
3299 0 : MaxOAFrac = GetCurrentScheduleValue(state, ventSlab.MaxOASchedPtr);
3300 : } else {
3301 0 : MaxOAFrac = 0.0;
3302 : }
3303 0 : MaxOAFrac = min(1.0, max(0.0, MinOAFrac));
3304 0 : state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3305 0 : break;
3306 : }
3307 7864 : case OutsideAirControlType::VariablePercent: {
3308 : // A cooling coil is present so let it try to do the cooling...
3309 7864 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3310 7864 : break;
3311 : }
3312 0 : case OutsideAirControlType::FixedTemperature: {
3313 : // This is basically the same algorithm as for the heating case...
3314 0 : Tdesired = GetCurrentScheduleValue(state, ventSlab.TempSchedPtr);
3315 :
3316 0 : MaxOAFrac = 1.0;
3317 :
3318 0 : if (std::abs(Tinlet - Toutdoor) <= LowTempDiff) { // no difference in indoor and outdoor conditions-->set OA to minimum
3319 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3320 0 : } else if (std::abs(MaxOAFrac - MinOAFrac) <= LowOAFracDiff) { // no difference in outside air fractions
3321 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3322 0 : } else if (((Tdesired <= Tinlet) && (Tdesired >= Toutdoor)) || ((Tdesired >= Tinlet) && (Tdesired <= Toutdoor))) {
3323 : // Desired temperature is between the inlet and outdoor temperatures
3324 : // so vary the flow rate between no outside air and no recirculation air
3325 : // then applying the maximum and minimum limits the user has scheduled
3326 : // to make sure too much/little outside air is being introduced
3327 0 : state.dataVentilatedSlab->OAMassFlowRate =
3328 0 : ((Tdesired - Tinlet) / (Toutdoor - Tinlet)) * state.dataLoopNodes->Node(InletNode).MassFlowRate;
3329 0 : state.dataVentilatedSlab->OAMassFlowRate =
3330 0 : max(state.dataVentilatedSlab->OAMassFlowRate, (MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
3331 0 : state.dataVentilatedSlab->OAMassFlowRate =
3332 0 : min(state.dataVentilatedSlab->OAMassFlowRate, (MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate));
3333 0 : } else if ((Tdesired < Tinlet) && (Tdesired < Toutdoor)) {
3334 : // Desired temperature is below both the inlet and outdoor temperatures
3335 : // so use whichever flow rate (max or min) that will get closer
3336 0 : if (Tinlet < Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
3337 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3338 : } else { // Toutdoor closer to Tdesired so use maximum outside air
3339 0 : state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3340 : }
3341 0 : } else if ((Tdesired > Tinlet) && (Tdesired > Toutdoor)) {
3342 : // Desired temperature is above both the inlet and outdoor temperatures
3343 : // so use whichever flow rate (max or min) that will get closer
3344 0 : if (Tinlet > Toutdoor) { // Tinlet closer to Tdesired so use minimum outside air
3345 0 : state.dataVentilatedSlab->OAMassFlowRate = MinOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3346 : } else { // Toutdoor closer to Tdesired so use maximum outside air
3347 0 : state.dataVentilatedSlab->OAMassFlowRate = MaxOAFrac * state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate;
3348 : }
3349 : } else {
3350 : // It should NEVER get to this point, but just in case...
3351 0 : ShowFatalError(state, cMO_VentilatedSlab + " simulation control: illogical condition for " + ventSlab.Name);
3352 : }
3353 0 : break;
3354 : }
3355 0 : default:
3356 0 : break;
3357 : }
3358 :
3359 : // control water flow to obtain output matching Low Setpoint Temperateure
3360 7864 : state.dataVentilatedSlab->HCoilOn = false;
3361 :
3362 7864 : SimVentSlabOAMixer(state, Item);
3363 7864 : if (ventSlab.FanType_Num == DataHVACGlobals::FanType_SystemModelObject) {
3364 2886 : state.dataHVACFan->fanObjs[ventSlab.Fan_Index]->simulate(state, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _);
3365 4978 : } else if (ventSlab.FanType_Num == DataHVACGlobals::FanType_SimpleConstVolume) {
3366 4978 : Fans::SimulateFanComponents(
3367 : state, ventSlab.FanName, FirstHVACIteration, ventSlab.Fan_Index, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff);
3368 : }
3369 :
3370 7864 : CpFan = PsyCpAirFnW(state.dataLoopNodes->Node(FanOutletNode).HumRat);
3371 7864 : QZnReq =
3372 7864 : (state.dataLoopNodes->Node(OutletNode).MassFlowRate) * CpFan * (RadInTemp - state.dataLoopNodes->Node(FanOutletNode).Temp);
3373 :
3374 7864 : ControlCompOutput(state,
3375 : ventSlab.Name,
3376 : cMO_VentilatedSlab,
3377 : Item,
3378 : FirstHVACIteration,
3379 : QZnReq,
3380 : ControlNode,
3381 : MaxWaterFlow,
3382 : MinWaterFlow,
3383 : 0.001,
3384 : ventSlab.ControlCompTypeNum,
3385 : ventSlab.CompErrIndex,
3386 : _,
3387 : _,
3388 : _,
3389 : _,
3390 : _,
3391 : ventSlab.CWPlantLoc);
3392 : }
3393 :
3394 : } // ...end of HEATING/COOLING IF-THEN block
3395 :
3396 77786 : CalcVentilatedSlabRadComps(state, Item, FirstHVACIteration);
3397 :
3398 : } // ...end of system ON/OFF IF-THEN block
3399 :
3400 : // Resimulate fans if AirMassFlow is zero and FanElecPower is > 0, indicating that load or condensation controls shut off the ventilated slab
3401 : // in CalcVentilatedSlabRadComps
3402 106951 : AirMassFlow = state.dataLoopNodes->Node(OutletNode).MassFlowRate;
3403 106951 : Real64 locFanElecPower = 0.0;
3404 106951 : if (ventSlab.FanType_Num == DataHVACGlobals::FanType_SystemModelObject) {
3405 82725 : locFanElecPower = state.dataHVACFan->fanObjs[ventSlab.Fan_Index]->fanPower();
3406 : } else {
3407 24226 : locFanElecPower = Fans::GetFanPower(state, ventSlab.Fan_Index);
3408 : }
3409 106951 : if ((AirMassFlow <= 0.0) && (locFanElecPower > 0.0)) {
3410 7705 : state.dataLoopNodes->Node(MixoutNode).MassFlowRate = 0.0;
3411 7705 : state.dataLoopNodes->Node(MixoutNode).MassFlowRateMaxAvail = 0.0;
3412 7705 : state.dataLoopNodes->Node(MixoutNode).MassFlowRateMinAvail = 0.0;
3413 7705 : state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = 0.0;
3414 7705 : state.dataLoopNodes->Node(FanOutletNode).MassFlowRateMaxAvail = 0.0;
3415 7705 : state.dataLoopNodes->Node(FanOutletNode).MassFlowRateMinAvail = 0.0;
3416 7705 : if (ventSlab.FanType_Num == DataHVACGlobals::FanType_SystemModelObject) {
3417 4836 : state.dataHVACFan->fanObjs[ventSlab.Fan_Index]->simulate(state, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _);
3418 2869 : } else if (ventSlab.FanType_Num == DataHVACGlobals::FanType_SimpleConstVolume) {
3419 2869 : Fans::SimulateFanComponents(
3420 : state, ventSlab.FanName, FirstHVACIteration, ventSlab.Fan_Index, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff);
3421 : }
3422 : }
3423 :
3424 106951 : CalcVentilatedSlabCoilOutput(state, Item, PowerMet, LatOutputProvided);
3425 106951 : }
3426 :
3427 501620 : void CalcVentilatedSlabComps(EnergyPlusData &state,
3428 : int const Item, // system index in ventilated slab array
3429 : bool const FirstHVACIteration, // flag for 1st HVAV iteration in the time step
3430 : Real64 &LoadMet // load met by the system (watts)
3431 : )
3432 : {
3433 :
3434 : // SUBROUTINE INFORMATION:
3435 : // AUTHOR Young Tae Chae, Rick Strand
3436 : // DATE WRITTEN June 2008
3437 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
3438 : // RE-ENGINEERED na
3439 :
3440 : // PURPOSE OF THIS SUBROUTINE:
3441 : // This subroutine launches the individual component simulations.
3442 : // This is called either when the system is off to carry null conditions
3443 : // through the system or during control iterations to continue updating
3444 : // what is going on within the unit.
3445 :
3446 : // METHODOLOGY EMPLOYED:
3447 : // Simply calls the different components in order. Only slight wrinkles
3448 : // here are that the ventilated slab system has it's own outside air mixed and
3449 : // that a cooling coil must be present in order to call a cooling coil
3450 : // simulation. Other than that, the subroutine is very straightforward.
3451 :
3452 : // Using/Aliasing
3453 501620 : auto &ZoneCompTurnFansOff = state.dataHVACGlobal->ZoneCompTurnFansOff;
3454 501620 : auto &ZoneCompTurnFansOn = state.dataHVACGlobal->ZoneCompTurnFansOn;
3455 501620 : auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
3456 : using HeatingCoils::SimulateHeatingCoilComponents;
3457 : using HVACHXAssistedCoolingCoil::SimHXAssistedCoolingCoil;
3458 : using SteamCoils::SimulateSteamCoilComponents;
3459 : using WaterCoils::SimulateWaterCoilComponents;
3460 :
3461 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3462 : Real64 AirMassFlow; // total mass flow through the system
3463 : Real64 CpAirZn; // specific heat of dry air at zone conditions (zone conditions same as system inlet)
3464 : int HCoilInAirNode; // inlet node number for fan exit/coil inlet
3465 : int InletNode; // system air inlet node
3466 : int OutletNode; // system air outlet node
3467 : // unused0309 INTEGER :: HCoilOutAirNode
3468 : Real64 QCoilReq; // Heat addition required from an electric/gas heating coil
3469 : Real64 HCoilOutAirTemp;
3470 : Real64 HCoilInAirTemp;
3471 : // unused1208 REAL(r64) :: RadInTemp ! Set temperature for "Slab In Node"
3472 :
3473 501620 : SimVentSlabOAMixer(state, Item);
3474 501620 : if (ventSlab.FanType_Num == DataHVACGlobals::FanType_SystemModelObject) {
3475 393327 : state.dataHVACFan->fanObjs[ventSlab.Fan_Index]->simulate(state, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff, _);
3476 108293 : } else if (ventSlab.FanType_Num == DataHVACGlobals::FanType_SimpleConstVolume) {
3477 108293 : Fans::SimulateFanComponents(state, ventSlab.FanName, FirstHVACIteration, ventSlab.Fan_Index, _, ZoneCompTurnFansOn, ZoneCompTurnFansOff);
3478 : }
3479 501620 : if ((ventSlab.coolingCoilPresent) && (ventSlab.coolingCoilSchedValue >= 0.0)) {
3480 269279 : if (ventSlab.cCoilType == CoolingCoilType::HXAssisted) {
3481 0 : SimHXAssistedCoolingCoil(state,
3482 : ventSlab.coolingCoilName,
3483 : FirstHVACIteration,
3484 : DataHVACGlobals::CompressorOperation::On,
3485 : 0.0,
3486 : ventSlab.coolingCoil_Index,
3487 : ContFanCycCoil);
3488 : } else {
3489 269279 : SimulateWaterCoilComponents(state, ventSlab.coolingCoilName, FirstHVACIteration, ventSlab.coolingCoil_Index);
3490 : }
3491 : }
3492 :
3493 501620 : if ((ventSlab.heatingCoilPresent) && (ventSlab.heatingCoilSchedValue >= 0.0)) {
3494 :
3495 501620 : switch (ventSlab.hCoilType) {
3496 :
3497 404706 : case HeatingCoilType::Water: {
3498 :
3499 404706 : SimulateWaterCoilComponents(state, ventSlab.heatingCoilName, FirstHVACIteration, ventSlab.heatingCoil_Index);
3500 404706 : break;
3501 : }
3502 0 : case HeatingCoilType::Steam: {
3503 :
3504 0 : if (!state.dataVentilatedSlab->HCoilOn) {
3505 0 : QCoilReq = 0.0;
3506 : } else {
3507 0 : HCoilInAirNode = ventSlab.FanOutletNode;
3508 0 : CpAirZn = PsyCpAirFnW(state.dataLoopNodes->Node(HCoilInAirNode).HumRat);
3509 0 : QCoilReq =
3510 0 : state.dataLoopNodes->Node(HCoilInAirNode).MassFlowRate * CpAirZn * (state.dataLoopNodes->Node(ventSlab.RadInNode).Temp) -
3511 0 : (state.dataLoopNodes->Node(HCoilInAirNode).Temp);
3512 : }
3513 :
3514 0 : if (QCoilReq < 0.0) QCoilReq = 0.0; // a heating coil can only heat, not cool
3515 :
3516 0 : SimulateSteamCoilComponents(state, ventSlab.heatingCoilName, FirstHVACIteration, ventSlab.heatingCoil_Index, QCoilReq);
3517 0 : break;
3518 : }
3519 96914 : case HeatingCoilType::Electric:
3520 : case HeatingCoilType::Gas: {
3521 :
3522 96914 : if (!state.dataVentilatedSlab->HCoilOn) {
3523 78220 : QCoilReq = 0.0;
3524 : } else {
3525 18694 : HCoilInAirTemp = state.dataLoopNodes->Node(ventSlab.FanOutletNode).Temp;
3526 18694 : HCoilOutAirTemp = state.dataLoopNodes->Node(ventSlab.RadInNode).Temp;
3527 18694 : CpAirZn = PsyCpAirFnW(state.dataLoopNodes->Node(ventSlab.RadInNode).HumRat);
3528 18694 : QCoilReq = state.dataLoopNodes->Node(ventSlab.FanOutletNode).MassFlowRate * CpAirZn * (HCoilOutAirTemp - HCoilInAirTemp);
3529 : }
3530 :
3531 96914 : if (QCoilReq < 0.0) QCoilReq = 0.0; // a heating coil can only heat, not cool
3532 :
3533 96914 : SimulateHeatingCoilComponents(state, ventSlab.heatingCoilName, FirstHVACIteration, QCoilReq, ventSlab.heatingCoil_Index);
3534 96914 : break;
3535 : }
3536 0 : default:
3537 0 : break;
3538 : }
3539 : }
3540 :
3541 501620 : InletNode = ventSlab.FanOutletNode;
3542 501620 : OutletNode = ventSlab.RadInNode;
3543 501620 : AirMassFlow = state.dataLoopNodes->Node(OutletNode).MassFlowRate;
3544 :
3545 1003240 : LoadMet = AirMassFlow * (PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, state.dataLoopNodes->Node(InletNode).HumRat) -
3546 501620 : PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(InletNode).HumRat));
3547 501620 : }
3548 :
3549 106951 : void CalcVentilatedSlabCoilOutput(EnergyPlusData &state,
3550 : int const Item, // system index in ventilated slab array
3551 : Real64 &PowerMet, // power supplied (W)
3552 : Real64 &LatOutputProvided // latent capacity supplied (kg/s)
3553 : )
3554 : {
3555 :
3556 : // SUBROUTINE INFORMATION:
3557 : // AUTHOR Young Tae Chae, Rick Strand
3558 : // DATE WRITTEN June 2008
3559 : // MODIFIED July 2012, Chandan Sharma - FSEC: Added zone sys avail managers
3560 : // RE-ENGINEERED July 2015, M.J. Witte, Refactored coil output calcs in to this new routine
3561 :
3562 : // PURPOSE OF THIS SUBROUTINE:
3563 : // This subroutine calculates the output from the coils
3564 :
3565 : // METHODOLOGY EMPLOYED:
3566 : // Calculates the sensible and total enthalpy change from the fan outlet node to the slab inlet node.
3567 :
3568 : // USING/ALIASING:
3569 106951 : auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
3570 :
3571 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3572 : Real64 AirMassFlow; // total mass flow through the system
3573 : int FanOutletNode; // system fan outlet node
3574 : int OutletNode; // air outlet node
3575 : Real64 SpecHumOut; // Specific humidity ratio of outlet air (kg moisture / kg moist air)
3576 : Real64 SpecHumIn; // Specific humidity ratio of inlet air (kg moisture / kg moist air)
3577 : Real64 QTotUnitOut; // total unit output [watts]
3578 : Real64 QUnitOut; // heating or sens. cooling provided by fan coil unit [watts]
3579 :
3580 106951 : OutletNode = ventSlab.RadInNode;
3581 106951 : FanOutletNode = ventSlab.FanOutletNode;
3582 106951 : AirMassFlow = state.dataLoopNodes->Node(OutletNode).MassFlowRate;
3583 :
3584 : // QTotUnitOut = AirMassFlow * ( Node( OutletNode ).Enthalpy - Node( FanOutletNode ).Enthalpy );
3585 213902 : QTotUnitOut = AirMassFlow * (PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, state.dataLoopNodes->Node(OutletNode).HumRat) -
3586 106951 : PsyHFnTdbW(state.dataLoopNodes->Node(FanOutletNode).Temp, state.dataLoopNodes->Node(FanOutletNode).HumRat));
3587 213902 : QUnitOut = AirMassFlow * (PsyHFnTdbW(state.dataLoopNodes->Node(OutletNode).Temp, state.dataLoopNodes->Node(FanOutletNode).HumRat) -
3588 106951 : PsyHFnTdbW(state.dataLoopNodes->Node(FanOutletNode).Temp, state.dataLoopNodes->Node(FanOutletNode).HumRat));
3589 : // Limit sensible <= total when cooling (which is negative, so use max)
3590 106951 : QUnitOut = max(QUnitOut, QTotUnitOut);
3591 :
3592 : // Report variables...
3593 106951 : ventSlab.HeatCoilPower = max(0.0, QUnitOut);
3594 106951 : ventSlab.SensCoolCoilPower = std::abs(min(0.0, QUnitOut));
3595 106951 : ventSlab.TotCoolCoilPower = std::abs(min(0.0, QTotUnitOut));
3596 106951 : ventSlab.LateCoolCoilPower = ventSlab.TotCoolCoilPower - ventSlab.SensCoolCoilPower;
3597 106951 : if (ventSlab.FanType_Num == DataHVACGlobals::FanType_SystemModelObject) {
3598 82725 : ventSlab.ElecFanPower = state.dataHVACFan->fanObjs[ventSlab.Fan_Index]->fanPower();
3599 : } else {
3600 24226 : ventSlab.ElecFanPower = Fans::GetFanPower(state, ventSlab.Fan_Index);
3601 : }
3602 106951 : ventSlab.AirMassFlowRate = AirMassFlow;
3603 :
3604 106951 : SpecHumOut = state.dataLoopNodes->Node(OutletNode).HumRat;
3605 106951 : SpecHumIn = state.dataLoopNodes->Node(FanOutletNode).HumRat;
3606 106951 : LatOutputProvided = AirMassFlow * (SpecHumOut - SpecHumIn); // Latent rate (kg/s), dehumid = negative
3607 106951 : PowerMet = QUnitOut;
3608 106951 : }
3609 :
3610 77786 : void CalcVentilatedSlabRadComps(EnergyPlusData &state,
3611 : int const Item, // System index in ventilated slab array
3612 : [[maybe_unused]] bool const FirstHVACIteration // flag for 1st HVAV iteration in the time step !unused1208
3613 : )
3614 : {
3615 :
3616 : // SUBROUTINE INFORMATION:
3617 : // AUTHOR Young Tae Chae, Rick Strand
3618 : // DATE WRITTEN June 2008
3619 : // MODIFIED Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
3620 : // RE-ENGINEERED na
3621 :
3622 : // PURPOSE OF THIS SUBROUTINE:
3623 : // This subroutine launches the individual component simulations.
3624 : // This is called either when the system is off to carry null conditions
3625 : // through the system or during control iterations to continue updating
3626 : // what is going on within the system.
3627 :
3628 : // METHODOLOGY EMPLOYED:
3629 : // Simply calls the different components in order. Only slight wrinkles
3630 : // here are that the Ventilated Slab has it's own outside air mixed and
3631 : // that a cooling coil must be present in order to call a cooling coil
3632 : // simulation. Other than that, the subroutine is very straightforward.
3633 :
3634 : // Using/Aliasing
3635 : using HeatingCoils::SimulateHeatingCoilComponents;
3636 : using NodeInputManager::GetOnlySingleNode;
3637 : using SteamCoils::SimulateSteamCoilComponents;
3638 : using WaterCoils::SimulateWaterCoilComponents;
3639 77786 : auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
3640 :
3641 : // SUBROUTINE PARAMETER DEFINITIONS:
3642 77786 : Real64 constexpr CondDeltaTemp(0.001); // How close the surface temperatures can get to the dewpoint temperature
3643 : // of a space before the radiant cooling system shuts off the flow.
3644 77786 : Real64 constexpr ZeroSystemResp(0.1); // Response below which the system response is really zero
3645 77786 : Real64 constexpr TempCheckLimit(0.1); // Maximum allowed temperature difference between outlet temperature calculations
3646 77786 : static std::string const CurrentModuleObject("ZoneHVAC:VentilatedSlab");
3647 :
3648 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3649 : int ConstrNum; // Index for construction number in Construct derived type
3650 : Real64 CpAirZn; // Intermediate calculational variable for specific heat of air
3651 : Real64 DewPointTemp; // Dew-point temperature based on the zone air conditions
3652 : Real64 EpsMdotCpAirZn; // Epsilon (heat exchanger terminology) times water mass flow rate times water specific heat
3653 : Real64 Mdot; // Intermediate calculation variable for mass flow rate in a surface within the radiant system
3654 : int RadSurfNum; // DO loop counter for the surfaces that comprise a particular radiant system
3655 : int RadSurfNum2; // DO loop counter for the surfaces that comprise a particular radiant system
3656 : int RadSurfNum3; // DO loop counter for the surfaces that comprise a particular radiant system
3657 : // unused0309 INTEGER :: RadSurfNum4 ! DO loop counter for the surfaces that comprise a particular radiant system
3658 :
3659 : int SurfNum; // Index for radiant surface in Surface derived type
3660 : int SurfNum2; // Index for radiant surface in Surface derived type
3661 : // unused0309 INTEGER :: RadSurfNumNum
3662 : Real64 TotalVentSlabRadPower; // Total heat source/sink to radiant system
3663 : Real64 AirMassFlow; // air mass flow rate in the radiant system, kg/s
3664 : int SlabInNode; // Node number of the air entering the radiant system
3665 : Real64 AirOutletTempCheck; // Radiant system air outlet temperature (calculated from mixing all outlet streams together)
3666 : Real64 AirTempIn; // Temperature of the air entering the radiant system, in C
3667 : int ZoneNum; // number of zone being served
3668 : Real64 ZoneMult; // Zone multiplier for this system
3669 : Real64 Ca; // Coefficients to relate the inlet air temperature to the heat source
3670 : Real64 Cb;
3671 : Real64 Cc;
3672 : Real64 Cd;
3673 : Real64 Ce;
3674 : Real64 Cf;
3675 : Real64 Cg;
3676 : Real64 Ch;
3677 : Real64 Ci;
3678 : Real64 Cj;
3679 : Real64 Ck;
3680 : Real64 Cl;
3681 : // For more info on Ca through Cl, refer Constant Flow Radiant System
3682 : int FanOutletNode; // unit air outlet node
3683 : int OAInletNode; // unit air outlet node
3684 : int MixoutNode; // unit air outlet node
3685 : int ReturnAirNode; // description
3686 : int ZoneAirInNode; // supply air node
3687 : // For Phase 3
3688 : Real64 CNumDS;
3689 : Real64 CLengDS;
3690 : Real64 CDiaDS;
3691 : Real64 FlowFrac;
3692 : Real64 MSlabAirInTemp;
3693 77786 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
3694 155572 : std::string MSlabIn;
3695 155572 : std::string MSlabOut;
3696 155572 : std::string SlabName;
3697 : int MSlabInletNode;
3698 : int MSlabOutletNode;
3699 :
3700 77786 : if (state.dataVentilatedSlab->FirstTimeFlag) {
3701 2 : state.dataVentilatedSlab->AirTempOut.allocate(state.dataVentilatedSlab->MaxCloNumOfSurfaces);
3702 2 : state.dataVentilatedSlab->FirstTimeFlag = false;
3703 : }
3704 :
3705 77786 : SlabInNode = ventSlab.RadInNode;
3706 77786 : FanOutletNode = ventSlab.FanOutletNode;
3707 77786 : OAInletNode = ventSlab.OutsideAirNode;
3708 77786 : MixoutNode = ventSlab.OAMixerOutNode;
3709 77786 : ReturnAirNode = ventSlab.ReturnAirNode;
3710 77786 : ZoneAirInNode = ventSlab.ZoneAirInNode;
3711 :
3712 : // Set the conditions on the air side inlet
3713 77786 : ZoneNum = ventSlab.ZonePtr;
3714 77786 : ZoneMult = double(state.dataHeatBal->Zone(ZoneNum).Multiplier * state.dataHeatBal->Zone(ZoneNum).ListMultiplier);
3715 77786 : AirMassFlow = state.dataLoopNodes->Node(ventSlab.RadInNode).MassFlowRate / ZoneMult;
3716 77786 : auto &thisZoneHB = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum);
3717 :
3718 77786 : if (state.dataVentilatedSlab->OperatingMode == HeatingMode) {
3719 :
3720 47732 : if ((!ventSlab.heatingCoilPresent) || (ventSlab.heatingCoilSchedValue <= 0.0)) {
3721 :
3722 0 : AirTempIn = state.dataLoopNodes->Node(FanOutletNode).Temp;
3723 0 : state.dataLoopNodes->Node(SlabInNode).Temp =
3724 0 : state.dataLoopNodes->Node(FanOutletNode).Temp; // If coil not available or running, then coil in and out temps same
3725 :
3726 : } else {
3727 :
3728 47732 : AirTempIn = state.dataLoopNodes->Node(SlabInNode).Temp;
3729 : }
3730 : }
3731 :
3732 77786 : if (state.dataVentilatedSlab->OperatingMode == CoolingMode) {
3733 :
3734 30054 : if ((!ventSlab.coolingCoilPresent) || (ventSlab.coolingCoilSchedValue <= 0.0)) {
3735 :
3736 22190 : AirTempIn = state.dataLoopNodes->Node(FanOutletNode).Temp;
3737 22190 : state.dataLoopNodes->Node(SlabInNode).Temp =
3738 22190 : state.dataLoopNodes->Node(FanOutletNode).Temp; // If coil not available or running, then coil in and out temps same
3739 :
3740 : } else {
3741 :
3742 7864 : AirTempIn = state.dataLoopNodes->Node(SlabInNode).Temp;
3743 : }
3744 : }
3745 :
3746 77786 : if (AirMassFlow <= 0.0) {
3747 : // No flow or below minimum allowed so there is no heat source/sink
3748 : // This is possible with a mismatch between system and plant operation
3749 : // or a slight mismatch between zone and system controls. This is not
3750 : // necessarily a "problem" so this exception is necessary in the code.
3751 :
3752 0 : for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
3753 0 : SurfNum = ventSlab.SurfacePtr(RadSurfNum);
3754 0 : state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
3755 0 : if (state.dataSurface->Surface(SurfNum).ExtBoundCond > 0 && state.dataSurface->Surface(SurfNum).ExtBoundCond != SurfNum)
3756 0 : state.dataHeatBalFanSys->QRadSysSource(state.dataSurface->Surface(SurfNum).ExtBoundCond) =
3757 : 0.0; // Also zero the other side of an interzone
3758 : }
3759 :
3760 0 : ventSlab.SlabOutTemp = ventSlab.SlabInTemp;
3761 :
3762 : // zero out node flows
3763 0 : state.dataLoopNodes->Node(SlabInNode).MassFlowRate = 0.0;
3764 0 : state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = 0.0;
3765 0 : state.dataLoopNodes->Node(OAInletNode).MassFlowRate = 0.0;
3766 0 : state.dataLoopNodes->Node(MixoutNode).MassFlowRate = 0.0;
3767 0 : state.dataLoopNodes->Node(ReturnAirNode).MassFlowRate = 0.0;
3768 0 : state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
3769 0 : AirMassFlow = 0.0;
3770 : }
3771 :
3772 77786 : if (AirMassFlow > 0.0) {
3773 :
3774 77786 : if ((ventSlab.SysConfg == VentilatedSlabConfig::SlabOnly) || (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone)) {
3775 :
3776 107084 : for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
3777 55955 : SurfNum = ventSlab.SurfacePtr(RadSurfNum);
3778 : // Determine the heat exchanger "effectiveness" term
3779 111910 : EpsMdotCpAirZn = CalcVentSlabHXEffectTerm(state,
3780 : Item,
3781 : AirTempIn,
3782 : AirMassFlow,
3783 55955 : ventSlab.SurfaceFlowFrac(RadSurfNum),
3784 : ventSlab.CoreLength,
3785 : ventSlab.CoreDiameter,
3786 : ventSlab.CoreNumbers);
3787 :
3788 : // Obtain the heat balance coefficients and calculate the intermediate coefficients
3789 : // linking the inlet air temperature to the heat source/sink to the radiant system.
3790 : // The coefficients are based on the Constant Flow Radiation System.
3791 :
3792 55955 : ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
3793 :
3794 55955 : Ca = state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum);
3795 55955 : Cb = state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum);
3796 55955 : Cc = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum);
3797 :
3798 55955 : Cd = state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum);
3799 55955 : Ce = state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum);
3800 55955 : Cf = state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum);
3801 :
3802 55955 : Cg = state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum);
3803 55955 : Ch = double(state.dataConstruction->Construct(ConstrNum).CTFTSourceQ(0));
3804 55955 : Ci = double(state.dataConstruction->Construct(ConstrNum).CTFTSourceIn(0));
3805 55955 : Cj = double(state.dataConstruction->Construct(ConstrNum).CTFTSourceOut(0));
3806 :
3807 55955 : Ck = Cg + ((Ci * (Ca + Cb * Cd) + Cj * (Cd + Ce * Ca)) / (1.0 - Ce * Cb));
3808 55955 : Cl = Ch + ((Ci * (Cc + Cb * Cf) + Cj * (Cf + Ce * Cc)) / (1.0 - Ce * Cb));
3809 :
3810 55955 : Mdot = AirMassFlow * ventSlab.SurfaceFlowFrac(RadSurfNum);
3811 55955 : CpAirZn = PsyCpAirFnW(state.dataLoopNodes->Node(ventSlab.RadInNode).HumRat);
3812 :
3813 111910 : state.dataHeatBalFanSys->QRadSysSource(SurfNum) = ventSlab.CoreNumbers * EpsMdotCpAirZn * (AirTempIn - Ck) /
3814 55955 : (1.0 + (EpsMdotCpAirZn * Cl / state.dataSurface->Surface(SurfNum).Area));
3815 :
3816 55955 : if (state.dataSurface->Surface(SurfNum).ExtBoundCond > 0 && state.dataSurface->Surface(SurfNum).ExtBoundCond != SurfNum)
3817 38111 : state.dataHeatBalFanSys->QRadSysSource(state.dataSurface->Surface(SurfNum).ExtBoundCond) =
3818 38111 : state.dataHeatBalFanSys->QRadSysSource(SurfNum);
3819 : // Also set the other side of an interzone!
3820 55955 : state.dataVentilatedSlab->AirTempOut(RadSurfNum) =
3821 55955 : AirTempIn - (state.dataHeatBalFanSys->QRadSysSource(SurfNum) / (Mdot * CpAirZn));
3822 :
3823 : // "Temperature Comparison" Cut-off:
3824 : // Check to see whether or not the system should really be running. If
3825 : // QRadSysSource is negative when we are in heating mode or QRadSysSource
3826 : // is positive when we are in cooling mode, then the radiant system will
3827 : // be doing the opposite of its intention. In this case, the flow rate
3828 : // is set to zero to avoid heating in cooling mode or cooling in heating
3829 : // mode.
3830 :
3831 116734 : if (((state.dataVentilatedSlab->OperatingMode == HeatingMode) && (state.dataHeatBalFanSys->QRadSysSource(SurfNum) <= 0.0)) ||
3832 73770 : ((state.dataVentilatedSlab->OperatingMode == CoolingMode) && (state.dataHeatBalFanSys->QRadSysSource(SurfNum) >= 0.0))) {
3833 :
3834 : // IF (.not. WarmupFlag) THEN
3835 : // TempComparisonErrorCount = TempComparisonErrorCount + 1
3836 : // IF (TempComparisonErrorCount <= NumOfVentSlabs) THEN
3837 : // CALL ShowWarningError(state, 'Radaint Heat exchange is negative in Heating Mode or posive in Cooling Mode')
3838 : // CALL ShowContinueError(state, 'Flow to the following ventilated slab will be shut-off to avoid heating in cooling mode
3839 : // or cooling &
3840 : // in heating mode')
3841 : // CALL ShowContinueError(state, 'Ventilated Slab Name = '//TRIM(VentSlab(Item)%Name))
3842 : // CALL ShowContinueError(state, 'All node temperature are reseted at the ventilated slab surface temperature = '// &
3843 : // RoundSigDigits(TH(VentSlab(Item)%SurfacePtr(RadSurfNum),1,2),2))
3844 : // CALL ShowContinueErrorTimeStamp(state, ' ')
3845 : // ELSE
3846 : // CALL ShowRecurringWarningErrorAtEnd(state, 'Ventilated Slab ['//TRIM(VentSlab(Item)%Name)// &
3847 : // '] Temperature Comparison Error shut-off occurrence continues.', &
3848 : // VentSlab(Item)%CondErrCount)
3849 : // END IF
3850 : // END IF
3851 :
3852 4826 : state.dataLoopNodes->Node(SlabInNode).MassFlowRate = 0.0;
3853 4826 : state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = 0.0;
3854 4826 : state.dataLoopNodes->Node(OAInletNode).MassFlowRate = 0.0;
3855 4826 : state.dataLoopNodes->Node(MixoutNode).MassFlowRate = 0.0;
3856 4826 : state.dataLoopNodes->Node(ReturnAirNode).MassFlowRate = 0.0;
3857 4826 : AirMassFlow = 0.0;
3858 :
3859 9652 : for (RadSurfNum2 = 1; RadSurfNum2 <= ventSlab.NumOfSurfaces; ++RadSurfNum2) {
3860 4826 : SurfNum2 = ventSlab.SurfacePtr(RadSurfNum2);
3861 4826 : state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
3862 8720 : if (state.dataSurface->Surface(SurfNum2).ExtBoundCond > 0 &&
3863 3894 : state.dataSurface->Surface(SurfNum2).ExtBoundCond != SurfNum2)
3864 3894 : state.dataHeatBalFanSys->QRadSysSource(state.dataSurface->Surface(SurfNum2).ExtBoundCond) =
3865 : 0.0; // Also zero the other side of an interzone
3866 :
3867 4826 : if (ventSlab.SysConfg == VentilatedSlabConfig::SlabOnly) {
3868 : // state.dataLoopNodes->Node(Returnairnode)%Temp = MAT(Zonenum)
3869 2174 : state.dataLoopNodes->Node(ReturnAirNode).Temp =
3870 2174 : state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(RadSurfNum));
3871 2174 : state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(ReturnAirNode).Temp;
3872 2174 : state.dataLoopNodes->Node(SlabInNode).Temp = state.dataLoopNodes->Node(FanOutletNode).Temp;
3873 2652 : } else if (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone) {
3874 2652 : state.dataLoopNodes->Node(ReturnAirNode).Temp = thisZoneHB.MAT;
3875 2652 : state.dataLoopNodes->Node(SlabInNode).Temp = state.dataLoopNodes->Node(ReturnAirNode).Temp;
3876 2652 : state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
3877 2652 : state.dataLoopNodes->Node(ZoneAirInNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
3878 : }
3879 : }
3880 4826 : break; // outer do loop
3881 : }
3882 :
3883 : // Condensation Cut-off:
3884 : // Check to see whether there are any surface temperatures within the radiant system that have
3885 : // dropped below the dew-point temperature. If so, we need to shut off this radiant system.
3886 : // A safety parameter is added (hardwired parameter) to avoid getting too close to condensation
3887 : // conditions.
3888 :
3889 51129 : if (state.dataVentilatedSlab->OperatingMode == CoolingMode) {
3890 12993 : DewPointTemp = PsyTdpFnWPb(state, thisZoneHB.ZoneAirHumRat, state.dataEnvrn->OutBaroPress);
3891 25976 : for (RadSurfNum2 = 1; RadSurfNum2 <= ventSlab.NumOfSurfaces; ++RadSurfNum2) {
3892 12993 : if (state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(RadSurfNum2)) < (DewPointTemp + CondDeltaTemp)) {
3893 : // Condensation warning--must shut off radiant system
3894 10 : state.dataLoopNodes->Node(SlabInNode).MassFlowRate = 0.0;
3895 10 : state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = 0.0;
3896 10 : state.dataLoopNodes->Node(OAInletNode).MassFlowRate = 0.0;
3897 10 : state.dataLoopNodes->Node(MixoutNode).MassFlowRate = 0.0;
3898 10 : state.dataLoopNodes->Node(ReturnAirNode).MassFlowRate = 0.0;
3899 10 : state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
3900 10 : AirMassFlow = 0.0;
3901 20 : for (RadSurfNum3 = 1; RadSurfNum3 <= ventSlab.NumOfSurfaces; ++RadSurfNum3) {
3902 10 : SurfNum2 = ventSlab.SurfacePtr(RadSurfNum3);
3903 10 : state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
3904 20 : if (state.dataSurface->Surface(SurfNum2).ExtBoundCond > 0 &&
3905 10 : state.dataSurface->Surface(SurfNum2).ExtBoundCond != SurfNum2)
3906 10 : state.dataHeatBalFanSys->QRadSysSource(state.dataSurface->Surface(SurfNum2).ExtBoundCond) =
3907 : 0.0; // Also zero the other side of an interzone
3908 : }
3909 : // Produce a warning message so that user knows the system was shut-off due to potential for condensation
3910 10 : if (!state.dataGlobal->WarmupFlag) {
3911 2 : ++state.dataVentilatedSlab->CondensationErrorCount;
3912 :
3913 2 : if (ventSlab.CondErrIndex == 0) {
3914 1 : ShowWarningMessage(state, cMO_VentilatedSlab + " [" + ventSlab.Name + ']');
3915 3 : ShowContinueError(state,
3916 2 : "Surface [" + state.dataSurface->Surface(ventSlab.SurfacePtr(RadSurfNum2)).Name +
3917 : "] temperature below dew-point temperature--potential for condensation exists");
3918 1 : ShowContinueError(state, "Flow to the ventilated slab system will be shut-off to avoid condensation");
3919 3 : ShowContinueError(state,
3920 4 : format("Predicted radiant system surface temperature = {:.2R}",
3921 3 : state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(RadSurfNum2))));
3922 3 : ShowContinueError(
3923 2 : state, format("Zone dew-point temperature + safety factor delta= {:.2R}", DewPointTemp + CondDeltaTemp));
3924 1 : ShowContinueErrorTimeStamp(state, "");
3925 : }
3926 2 : if (state.dataVentilatedSlab->CondensationErrorCount == 1) {
3927 3 : ShowContinueError(
3928 2 : state, format("Note that there is a {:.4R} C safety built-in to the shut-off criteria", CondDeltaTemp));
3929 1 : ShowContinueError(state, "Note also that this affects all surfaces that are part of this system");
3930 : }
3931 6 : ShowRecurringWarningErrorAtEnd(state,
3932 4 : cMO_VentilatedSlab + " [" + ventSlab.Name +
3933 : "] condensation shut-off occurrence continues.",
3934 : ventSlab.CondErrIndex,
3935 : DewPointTemp,
3936 : DewPointTemp,
3937 : _,
3938 : "C",
3939 : "C");
3940 : }
3941 10 : break; // outer do loop
3942 : }
3943 : }
3944 : }
3945 : }
3946 :
3947 : // Total Radiant Power
3948 55955 : AirOutletTempCheck = 0.0;
3949 55955 : TotalVentSlabRadPower = 0.0;
3950 111910 : for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
3951 55955 : SurfNum = ventSlab.SurfacePtr(RadSurfNum);
3952 55955 : TotalVentSlabRadPower += state.dataHeatBalFanSys->QRadSysSource(SurfNum);
3953 55955 : AirOutletTempCheck += (ventSlab.SurfaceFlowFrac(RadSurfNum) * state.dataVentilatedSlab->AirTempOut(RadSurfNum));
3954 : }
3955 55955 : TotalVentSlabRadPower *= ZoneMult;
3956 :
3957 : // Return Air temp Check
3958 55955 : if (ventSlab.SysConfg == VentilatedSlabConfig::SlabOnly) {
3959 29261 : if (AirMassFlow > 0.0) {
3960 27077 : CpAirZn = PsyCpAirFnW(state.dataLoopNodes->Node(ventSlab.RadInNode).HumRat);
3961 27077 : state.dataLoopNodes->Node(ReturnAirNode).Temp =
3962 27077 : state.dataLoopNodes->Node(SlabInNode).Temp - (TotalVentSlabRadPower / (AirMassFlow * CpAirZn));
3963 27077 : if ((std::abs(state.dataLoopNodes->Node(ReturnAirNode).Temp - AirOutletTempCheck) > TempCheckLimit) &&
3964 0 : (std::abs(TotalVentSlabRadPower) > ZeroSystemResp)) {
3965 :
3966 0 : if (!state.dataGlobal->WarmupFlag) {
3967 0 : ++state.dataVentilatedSlab->EnergyImbalanceErrorCount;
3968 0 : if (ventSlab.EnrgyImbalErrIndex == 0) {
3969 0 : ShowWarningMessage(state, cMO_VentilatedSlab + " [" + ventSlab.Name + ']');
3970 0 : ShowContinueError(state, "Ventilated Slab (slab only type) air outlet temperature calculation mismatch.");
3971 0 : ShowContinueError(state,
3972 : "This should not happen as it indicates a potential energy imbalance in the calculations.");
3973 0 : ShowContinueError(state, "However, it could also result from improper input for the ventilated slab or");
3974 0 : ShowContinueError(state, "illogical control temperatures. Check your input for this ventilated slab and");
3975 0 : ShowContinueError(state, "also look at the internal data shown below.");
3976 0 : ShowContinueError(state,
3977 0 : format("Predicted return air temperature [C] from the overall energy balance = {:.4R}",
3978 0 : state.dataLoopNodes->Node(ReturnAirNode).Temp));
3979 0 : ShowContinueError(state,
3980 0 : format("Predicted return air temperature [C] from the slab section energy balances = {:.4R}",
3981 0 : AirOutletTempCheck));
3982 0 : ShowContinueError(state,
3983 0 : format("Total energy rate (power) [W] added to the slab = {:.4R}", TotalVentSlabRadPower));
3984 0 : ShowContinueErrorTimeStamp(state, "");
3985 : }
3986 0 : ShowRecurringWarningErrorAtEnd(state,
3987 0 : cMO_VentilatedSlab + " [" + ventSlab.Name +
3988 : "] temperature calculation mismatch occurrence continues.",
3989 : ventSlab.EnrgyImbalErrIndex);
3990 : }
3991 : }
3992 : } else {
3993 2184 : state.dataLoopNodes->Node(ReturnAirNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
3994 : }
3995 : }
3996 :
3997 55955 : if (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone) {
3998 26694 : if (AirMassFlow > 0.0) {
3999 24042 : state.dataLoopNodes->Node(ZoneAirInNode).Temp =
4000 24042 : state.dataLoopNodes->Node(SlabInNode).Temp - (TotalVentSlabRadPower / (AirMassFlow * CpAirZn));
4001 24042 : if ((std::abs(state.dataLoopNodes->Node(ZoneAirInNode).Temp - AirOutletTempCheck) > TempCheckLimit) &&
4002 0 : (std::abs(TotalVentSlabRadPower) > ZeroSystemResp)) {
4003 :
4004 0 : if (!state.dataGlobal->WarmupFlag) {
4005 0 : ++state.dataVentilatedSlab->EnergyImbalanceErrorCount;
4006 0 : if (ventSlab.EnrgyImbalErrIndex == 0) {
4007 0 : ShowWarningMessage(state, cMO_VentilatedSlab + " [" + ventSlab.Name + ']');
4008 0 : ShowContinueError(state, "Ventilated Slab (slab only type) air outlet temperature calculation mismatch.");
4009 0 : ShowContinueError(state,
4010 : "This should not happen as it indicates a potential energy imbalance in the calculations.");
4011 0 : ShowContinueError(state, "However, it could also result from improper input for the ventilated slab or");
4012 0 : ShowContinueError(state, "illogical control temperatures. Check your input for this ventilated slab and");
4013 0 : ShowContinueError(state, "also look at the internal data shown below.");
4014 0 : ShowContinueError(state,
4015 0 : format("Predicted return air temperature [C] from the overall energy balance = {:.4R}",
4016 0 : state.dataLoopNodes->Node(ReturnAirNode).Temp));
4017 0 : ShowContinueError(state,
4018 0 : format("Predicted return air temperature [C] from the slab section energy balances = {:.4R}",
4019 0 : AirOutletTempCheck));
4020 0 : ShowContinueError(state,
4021 0 : format("Total energy rate (power) [W] added to the slab = {:.4R}", TotalVentSlabRadPower));
4022 0 : ShowContinueErrorTimeStamp(state, "");
4023 : }
4024 0 : ShowRecurringWarningErrorAtEnd(state,
4025 0 : cMO_VentilatedSlab + " [" + ventSlab.Name +
4026 : "] temperature calculation mismatch occurrence continues.",
4027 : ventSlab.EnrgyImbalErrIndex);
4028 : }
4029 : }
4030 : // IF ((.NOT. FirstHVACIteration) .AND. &
4031 : // (ABS(Node(ReturnAirNode)%Temp-MAT(Zonenum)) > VentSlabAirTempToler))THEN
4032 : // NeedtoIterate = .TRUE.
4033 : // END IF
4034 : // state.dataLoopNodes->Node(ReturnAirNode)%Temp = MAT(Zonenum)
4035 : } else {
4036 2652 : state.dataLoopNodes->Node(ZoneAirInNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
4037 2652 : state.dataLoopNodes->Node(ReturnAirNode).Temp = thisZoneHB.MAT;
4038 : }
4039 : }
4040 :
4041 : // Now that we have the source/sink term, we must redo the heat balances to obtain
4042 : // the new SumHATsurf value for the zone. Note that the difference between the new
4043 : // SumHATsurf and the value originally calculated by the heat balance with a zero
4044 : // source for all radiant systems in the zone is the load met by the system (approximately).
4045 55955 : HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum);
4046 55955 : HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum);
4047 :
4048 : } // SYSCONFIG. SLABONLY&SLABANDZONE
4049 :
4050 77786 : if (ventSlab.SysConfg == VentilatedSlabConfig::SeriesSlabs) {
4051 :
4052 67889 : for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
4053 :
4054 48927 : CNumDS = ventSlab.CNumbers(RadSurfNum);
4055 48927 : CLengDS = ventSlab.CLength(RadSurfNum); // for check
4056 48927 : CDiaDS = ventSlab.CDiameter(RadSurfNum); // for check
4057 48927 : FlowFrac = 1.0;
4058 :
4059 48927 : SurfNum = ventSlab.SurfacePtr(RadSurfNum);
4060 :
4061 : // Determine the heat exchanger "effectiveness" term
4062 48927 : EpsMdotCpAirZn = CalcVentSlabHXEffectTerm(state, Item, AirTempIn, AirMassFlow, FlowFrac, CLengDS, CDiaDS, CNumDS);
4063 :
4064 : // Obtain the heat balance coefficients and calculate the intermediate coefficients
4065 : // linking the inlet air temperature to the heat source/sink to the radiant system.
4066 : // The coefficients are based on the Constant Flow Radiation System.
4067 :
4068 48927 : ConstrNum = state.dataSurface->Surface(SurfNum).Construction;
4069 :
4070 48927 : Ca = state.dataHeatBalFanSys->RadSysTiHBConstCoef(SurfNum);
4071 48927 : Cb = state.dataHeatBalFanSys->RadSysTiHBToutCoef(SurfNum);
4072 48927 : Cc = state.dataHeatBalFanSys->RadSysTiHBQsrcCoef(SurfNum);
4073 :
4074 48927 : Cd = state.dataHeatBalFanSys->RadSysToHBConstCoef(SurfNum);
4075 48927 : Ce = state.dataHeatBalFanSys->RadSysToHBTinCoef(SurfNum);
4076 48927 : Cf = state.dataHeatBalFanSys->RadSysToHBQsrcCoef(SurfNum);
4077 :
4078 48927 : Cg = state.dataHeatBalFanSys->CTFTsrcConstPart(SurfNum);
4079 48927 : Ch = double(state.dataConstruction->Construct(ConstrNum).CTFTSourceQ(0));
4080 48927 : Ci = double(state.dataConstruction->Construct(ConstrNum).CTFTSourceIn(0));
4081 48927 : Cj = double(state.dataConstruction->Construct(ConstrNum).CTFTSourceOut(0));
4082 :
4083 48927 : Ck = Cg + ((Ci * (Ca + Cb * Cd) + Cj * (Cd + Ce * Ca)) / (1.0 - Ce * Cb));
4084 48927 : Cl = Ch + ((Ci * (Cc + Cb * Cf) + Cj * (Cf + Ce * Cc)) / (1.0 - Ce * Cb));
4085 :
4086 48927 : Mdot = AirMassFlow * FlowFrac;
4087 48927 : CpAirZn = PsyCpAirFnW(state.dataLoopNodes->Node(ventSlab.RadInNode).HumRat);
4088 :
4089 48927 : state.dataHeatBalFanSys->QRadSysSource(SurfNum) =
4090 48927 : CNumDS * EpsMdotCpAirZn * (AirTempIn - Ck) / (1.0 + (EpsMdotCpAirZn * Cl / state.dataSurface->Surface(SurfNum).Area));
4091 :
4092 48927 : if (state.dataSurface->Surface(SurfNum).ExtBoundCond > 0 && state.dataSurface->Surface(SurfNum).ExtBoundCond != SurfNum)
4093 48927 : state.dataHeatBalFanSys->QRadSysSource(state.dataSurface->Surface(SurfNum).ExtBoundCond) =
4094 48927 : state.dataHeatBalFanSys->QRadSysSource(SurfNum);
4095 : // Also set the other side of an interzone!
4096 :
4097 48927 : state.dataVentilatedSlab->AirTempOut(RadSurfNum) =
4098 48927 : AirTempIn - (state.dataHeatBalFanSys->QRadSysSource(SurfNum) / (Mdot * CpAirZn));
4099 48927 : AirTempIn = state.dataVentilatedSlab->AirTempOut(RadSurfNum);
4100 : // "Temperature Comparison" Cut-off:
4101 : // Check to see whether or not the system should really be running. If
4102 : // QRadSysSource is negative when we are in heating mode or QRadSysSource
4103 : // is positive when we are in cooling mode, then the radiant system will
4104 : // be doing the opposite of its intention. In this case, the flow rate
4105 : // is set to zero to avoid heating in cooling mode or cooling in heating
4106 : // mode.
4107 :
4108 48927 : if (RadSurfNum == 1) {
4109 46531 : if (((state.dataVentilatedSlab->OperatingMode == HeatingMode) && (state.dataHeatBalFanSys->QRadSysSource(SurfNum) <= 0.0)) ||
4110 34068 : ((state.dataVentilatedSlab->OperatingMode == CoolingMode) && (state.dataHeatBalFanSys->QRadSysSource(SurfNum) >= 0.0))) {
4111 2869 : state.dataLoopNodes->Node(SlabInNode).MassFlowRate = 0.0;
4112 2869 : state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = 0.0;
4113 2869 : state.dataLoopNodes->Node(OAInletNode).MassFlowRate = 0.0;
4114 2869 : state.dataLoopNodes->Node(MixoutNode).MassFlowRate = 0.0;
4115 2869 : state.dataLoopNodes->Node(ReturnAirNode).MassFlowRate = 0.0;
4116 2869 : AirMassFlow = 0.0;
4117 :
4118 10191 : for (RadSurfNum2 = 1; RadSurfNum2 <= ventSlab.NumOfSurfaces; ++RadSurfNum2) {
4119 7322 : SurfNum2 = ventSlab.SurfacePtr(RadSurfNum2);
4120 7322 : state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
4121 14644 : if (state.dataSurface->Surface(SurfNum2).ExtBoundCond > 0 &&
4122 7322 : state.dataSurface->Surface(SurfNum2).ExtBoundCond != SurfNum2)
4123 7322 : state.dataHeatBalFanSys->QRadSysSource(state.dataSurface->Surface(SurfNum2).ExtBoundCond) =
4124 : 0.0; // Also zero the other side of an interzone
4125 : }
4126 2869 : state.dataLoopNodes->Node(ReturnAirNode).Temp = state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(1));
4127 2869 : state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(ReturnAirNode).Temp;
4128 2869 : state.dataLoopNodes->Node(SlabInNode).Temp = state.dataLoopNodes->Node(FanOutletNode).Temp;
4129 : // Each Internal node is reseted at the surface temperature
4130 :
4131 2869 : break; // outer do loop
4132 : }
4133 : }
4134 : // Condensation Cut-off:
4135 : // Check to see whether there are any surface temperatures within the radiant system that have
4136 : // dropped below the dew-point temperature. If so, we need to shut off this radiant system.
4137 : // A safety parameter is added (hardwired parameter) to avoid getting too close to condensation
4138 : // conditions.
4139 :
4140 46058 : if (state.dataVentilatedSlab->OperatingMode == CoolingMode) {
4141 46336 : DewPointTemp = PsyTdpFnWPb(state,
4142 23168 : state.dataZoneTempPredictorCorrector->zoneHeatBalance(ventSlab.ZPtr(RadSurfNum)).ZoneAirHumRat,
4143 23168 : state.dataEnvrn->OutBaroPress);
4144 82800 : for (RadSurfNum2 = 1; RadSurfNum2 <= ventSlab.NumOfSurfaces; ++RadSurfNum2) {
4145 59632 : if (state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(RadSurfNum2)) < (DewPointTemp + CondDeltaTemp)) {
4146 : // Condensation warning--must shut off radiant system
4147 0 : state.dataLoopNodes->Node(SlabInNode).MassFlowRate = 0.0;
4148 0 : state.dataLoopNodes->Node(FanOutletNode).MassFlowRate = 0.0;
4149 0 : state.dataLoopNodes->Node(OAInletNode).MassFlowRate = 0.0;
4150 0 : state.dataLoopNodes->Node(MixoutNode).MassFlowRate = 0.0;
4151 0 : state.dataLoopNodes->Node(ReturnAirNode).MassFlowRate = 0.0;
4152 0 : state.dataLoopNodes->Node(FanOutletNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
4153 0 : AirMassFlow = 0.0;
4154 0 : for (RadSurfNum3 = 1; RadSurfNum3 <= ventSlab.NumOfSurfaces; ++RadSurfNum3) {
4155 0 : SurfNum2 = ventSlab.SurfacePtr(RadSurfNum3);
4156 0 : state.dataHeatBalFanSys->QRadSysSource(SurfNum2) = 0.0;
4157 0 : if (state.dataSurface->Surface(SurfNum2).ExtBoundCond > 0 &&
4158 0 : state.dataSurface->Surface(SurfNum2).ExtBoundCond != SurfNum2)
4159 0 : state.dataHeatBalFanSys->QRadSysSource(state.dataSurface->Surface(SurfNum2).ExtBoundCond) =
4160 : 0.0; // Also zero the other side of an interzone
4161 : }
4162 : // Produce a warning message so that user knows the system was shut-off due to potential for condensation
4163 0 : if (!state.dataGlobal->WarmupFlag) {
4164 0 : ++state.dataVentilatedSlab->CondensationErrorCount;
4165 0 : if (ventSlab.CondErrIndex == 0) {
4166 0 : ShowWarningMessage(state, cMO_VentilatedSlab + " [" + ventSlab.Name + ']');
4167 0 : ShowContinueError(state,
4168 0 : "Surface [" + state.dataSurface->Surface(ventSlab.SurfacePtr(RadSurfNum2)).Name +
4169 : "] temperature below dew-point temperature--potential for condensation exists");
4170 0 : ShowContinueError(state, "Flow to the ventilated slab system will be shut-off to avoid condensation");
4171 0 : ShowContinueError(state,
4172 0 : format("Predicted radiant system surface temperature = {:.2R}",
4173 0 : state.dataHeatBalSurf->SurfInsideTempHist(1)(ventSlab.SurfacePtr(RadSurfNum2))));
4174 0 : ShowContinueError(
4175 0 : state, format("Zone dew-point temperature + safety factor delta= {:.2R}", DewPointTemp + CondDeltaTemp));
4176 0 : ShowContinueErrorTimeStamp(state, "");
4177 : }
4178 0 : if (state.dataVentilatedSlab->CondensationErrorCount == 1) {
4179 0 : ShowContinueError(
4180 0 : state, format("Note that there is a {:.4R} C safety built-in to the shut-off criteria", CondDeltaTemp));
4181 0 : ShowContinueError(state, "Note also that this affects all surfaces that are part of this system");
4182 : }
4183 0 : ShowRecurringWarningErrorAtEnd(state,
4184 0 : cMO_VentilatedSlab + " [" + ventSlab.Name +
4185 : "] condensation shut-off occurrence continues.",
4186 : ventSlab.CondErrIndex,
4187 : DewPointTemp,
4188 : DewPointTemp,
4189 : _,
4190 : "C",
4191 : "C");
4192 : }
4193 0 : break; // outer do loop
4194 : }
4195 : }
4196 : }
4197 : }
4198 :
4199 : // Total Radiant Power
4200 21831 : AirOutletTempCheck = 0.0;
4201 21831 : TotalVentSlabRadPower = 0.0;
4202 75211 : for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
4203 53380 : SurfNum = ventSlab.SurfacePtr(RadSurfNum);
4204 53380 : TotalVentSlabRadPower += state.dataHeatBalFanSys->QRadSysSource(SurfNum);
4205 53380 : AirOutletTempCheck = state.dataVentilatedSlab->AirTempOut(RadSurfNum);
4206 : }
4207 21831 : TotalVentSlabRadPower *= ZoneMult;
4208 :
4209 : // Internal Node Temperature Check
4210 :
4211 21831 : MSlabAirInTemp = state.dataLoopNodes->Node(SlabInNode).Temp;
4212 :
4213 75211 : for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
4214 53380 : SlabName = ventSlab.SurfaceName(RadSurfNum);
4215 53380 : MSlabIn = ventSlab.SlabIn(RadSurfNum);
4216 53380 : MSlabOut = ventSlab.SlabOut(RadSurfNum);
4217 53380 : ventSlab.MSlabInNode = GetOnlySingleNode(state,
4218 : MSlabIn,
4219 : ErrorsFound,
4220 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
4221 : SlabName,
4222 : DataLoopNode::NodeFluidType::Air,
4223 : DataLoopNode::ConnectionType::Internal,
4224 : NodeInputManager::CompFluidStream::Primary,
4225 53380 : ObjectIsNotParent);
4226 53380 : ventSlab.MSlabOutNode = GetOnlySingleNode(state,
4227 : MSlabOut,
4228 : ErrorsFound,
4229 : DataLoopNode::ConnectionObjectType::ZoneHVACVentilatedSlab,
4230 : SlabName,
4231 : DataLoopNode::NodeFluidType::Air,
4232 : DataLoopNode::ConnectionType::Internal,
4233 : NodeInputManager::CompFluidStream::Primary,
4234 53380 : ObjectIsNotParent);
4235 53380 : MSlabInletNode = ventSlab.MSlabInNode;
4236 53380 : MSlabOutletNode = ventSlab.MSlabOutNode;
4237 53380 : SurfNum = ventSlab.SurfacePtr(RadSurfNum);
4238 :
4239 53380 : if (AirMassFlow > 0.0) {
4240 :
4241 46058 : CpAirZn = PsyCpAirFnW(state.dataLoopNodes->Node(ventSlab.RadInNode).HumRat);
4242 :
4243 46058 : state.dataLoopNodes->Node(MSlabInletNode).Temp = MSlabAirInTemp;
4244 92116 : state.dataLoopNodes->Node(MSlabOutletNode).Temp = state.dataLoopNodes->Node(MSlabInletNode).Temp -
4245 46058 : (state.dataHeatBalFanSys->QRadSysSource(SurfNum) / (AirMassFlow * CpAirZn));
4246 46058 : MSlabAirInTemp = state.dataLoopNodes->Node(MSlabOutletNode).Temp;
4247 : } else {
4248 7322 : state.dataLoopNodes->Node(MSlabInletNode).Temp = state.dataLoopNodes->Node(ReturnAirNode).Temp;
4249 7322 : state.dataLoopNodes->Node(MSlabOutletNode).Temp = state.dataLoopNodes->Node(MSlabInletNode).Temp;
4250 : }
4251 : }
4252 :
4253 : // Return Air temp Check
4254 21831 : if (AirMassFlow > 0.0) {
4255 :
4256 18962 : CpAirZn = PsyCpAirFnW(state.dataLoopNodes->Node(ventSlab.RadInNode).HumRat);
4257 18962 : state.dataLoopNodes->Node(ReturnAirNode).Temp =
4258 18962 : state.dataLoopNodes->Node(SlabInNode).Temp - (TotalVentSlabRadPower / (AirMassFlow * CpAirZn));
4259 :
4260 18962 : if ((std::abs(state.dataLoopNodes->Node(ReturnAirNode).Temp - AirOutletTempCheck) > TempCheckLimit) &&
4261 0 : (std::abs(TotalVentSlabRadPower) > ZeroSystemResp)) { // Return air temperature check did not match calculated temp
4262 :
4263 0 : if (!state.dataGlobal->WarmupFlag) {
4264 0 : ++state.dataVentilatedSlab->EnergyImbalanceErrorCount;
4265 0 : if (ventSlab.EnrgyImbalErrIndex == 0) {
4266 0 : ShowWarningMessage(state, cMO_VentilatedSlab + " [" + ventSlab.Name + ']');
4267 0 : ShowContinueError(state, "Ventilated Slab (slab only type) air outlet temperature calculation mismatch.");
4268 0 : ShowContinueError(state, "This should not happen as it indicates a potential energy imbalance in the calculations.");
4269 0 : ShowContinueError(state, "However, it could also result from improper input for the ventilated slab or");
4270 0 : ShowContinueError(state, "illogical control temperatures. Check your input for this ventilated slab and");
4271 0 : ShowContinueError(state, "also look at the internal data shown below.");
4272 0 : ShowContinueError(state,
4273 0 : format("Predicted return air temperature [C] from the overall energy balance = {:.4R}",
4274 0 : state.dataLoopNodes->Node(ReturnAirNode).Temp));
4275 0 : ShowContinueError(state,
4276 0 : format("Predicted return air temperature [C] from the slab section energy balances = {:.4R}",
4277 0 : AirOutletTempCheck));
4278 0 : ShowContinueError(state, format("Total energy rate (power) [W] added to the slab = {:.4R}", TotalVentSlabRadPower));
4279 0 : ShowContinueErrorTimeStamp(state, "");
4280 : }
4281 0 : ShowRecurringWarningErrorAtEnd(state,
4282 0 : cMO_VentilatedSlab + " [" + ventSlab.Name +
4283 : "] temperature calculation mismatch occurrence continues.",
4284 : ventSlab.EnrgyImbalErrIndex);
4285 : }
4286 : }
4287 :
4288 : } else {
4289 2869 : state.dataLoopNodes->Node(ReturnAirNode).Temp = state.dataLoopNodes->Node(SlabInNode).Temp;
4290 : }
4291 :
4292 : // Now that we have the source/sink term, we must redo the heat balances to obtain
4293 : // the new SumHATsurf value for the zone. Note that the difference between the new
4294 : // SumHATsurf and the value originally calculated by the heat balance with a zero
4295 : // source for all radiant systems in the zone is the load met by the system (approximately).
4296 :
4297 21831 : HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state);
4298 21831 : HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state);
4299 :
4300 : } // SeriesSlabs
4301 :
4302 : } //(AirMassFlow > 0.0d0)
4303 77786 : }
4304 :
4305 557216 : void SimVentSlabOAMixer(EnergyPlusData &state, int const Item) // System index in Ventilated Slab array
4306 : {
4307 :
4308 : // SUBROUTINE INFORMATION:
4309 : // AUTHOR Rick Strand
4310 : // DATE WRITTEN May 2000
4311 : // MODIFIED na
4312 : // RE-ENGINEERED na
4313 :
4314 : // PURPOSE OF THIS SUBROUTINE:
4315 : // This responsibility of this subroutine is to set the air flow rates
4316 : // through the mixing box portion of the Ventilated Slab and then perform
4317 : // an energy balance to arrive at outlet conditions which then would
4318 : // serve as inlet conditions to the coils (or outlet conditions for
4319 : // the device). There is some question as to whether this needs to be
4320 : // called every time the coils and fan are called since how the fans and
4321 : // coil operate won't presumable change how the mixer operates. The
4322 : // method in which this routine is called is slightly cleaner though
4323 : // from a code readability standpoint though less efficient.
4324 :
4325 : // METHODOLOGY EMPLOYED:
4326 : // The OAMassFlowRate has already been calculated in the main control
4327 : // algorithm. Use this flow rate to establish all of the other flow
4328 : // rates and perform an energy balance on the mixing of the return and
4329 : // outdoor air streams.
4330 :
4331 : // Using/Aliasing
4332 557216 : auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
4333 :
4334 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4335 : int AirRelNode; // relief air node number in ventilated slab loop
4336 : int InletNode; // inlet node number for ventilated slab loop
4337 : Real64 OAFraction; // Outside air fraction of inlet air
4338 : int OAMixOutNode; // outside air mixer outlet node for ventilated slab loop
4339 : int OutsideAirNode; // outside air node number in ventilated slab loop
4340 :
4341 557216 : AirRelNode = ventSlab.AirReliefNode;
4342 557216 : InletNode = ventSlab.ReturnAirNode;
4343 557216 : OAMixOutNode = ventSlab.OAMixerOutNode;
4344 557216 : OutsideAirNode = ventSlab.OutsideAirNode;
4345 :
4346 : // "Resolve" the air flow rates...
4347 :
4348 557216 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate = state.dataVentilatedSlab->OAMassFlowRate;
4349 557216 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMinAvail = state.dataVentilatedSlab->OAMassFlowRate;
4350 557216 : state.dataLoopNodes->Node(OutsideAirNode).MassFlowRateMaxAvail = state.dataVentilatedSlab->OAMassFlowRate;
4351 :
4352 557216 : state.dataLoopNodes->Node(AirRelNode).MassFlowRate = state.dataVentilatedSlab->OAMassFlowRate;
4353 557216 : state.dataLoopNodes->Node(AirRelNode).MassFlowRateMinAvail = state.dataVentilatedSlab->OAMassFlowRate;
4354 557216 : state.dataLoopNodes->Node(AirRelNode).MassFlowRateMaxAvail = state.dataVentilatedSlab->OAMassFlowRate;
4355 :
4356 557216 : state.dataLoopNodes->Node(OAMixOutNode).MassFlowRate = state.dataLoopNodes->Node(InletNode).MassFlowRate;
4357 557216 : state.dataLoopNodes->Node(OAMixOutNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(InletNode).MassFlowRate;
4358 557216 : state.dataLoopNodes->Node(OAMixOutNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(InletNode).MassFlowRate;
4359 :
4360 : // "Inlet" conditions for InletNode and OutsideAirNode have already
4361 : // been set elsewhere so we just need to set the "outlet" conditions
4362 557216 : state.dataLoopNodes->Node(AirRelNode).Temp = state.dataLoopNodes->Node(InletNode).Temp;
4363 557216 : state.dataLoopNodes->Node(AirRelNode).Press = state.dataLoopNodes->Node(InletNode).Press;
4364 557216 : state.dataLoopNodes->Node(AirRelNode).HumRat = state.dataLoopNodes->Node(InletNode).HumRat;
4365 557216 : state.dataLoopNodes->Node(AirRelNode).Enthalpy = state.dataLoopNodes->Node(InletNode).Enthalpy;
4366 :
4367 557216 : if (state.dataLoopNodes->Node(InletNode).MassFlowRate > 0.0) {
4368 :
4369 528051 : OAFraction = state.dataLoopNodes->Node(OutsideAirNode).MassFlowRate / state.dataLoopNodes->Node(InletNode).MassFlowRate;
4370 :
4371 : } else {
4372 29165 : OAFraction = 0.0;
4373 : }
4374 :
4375 557216 : state.dataLoopNodes->Node(InletNode).Enthalpy =
4376 557216 : PsyHFnTdbW(state.dataLoopNodes->Node(InletNode).Temp, state.dataLoopNodes->Node(InletNode).HumRat);
4377 :
4378 : // Perform an energy and moisture mass balance on the mixing portion of the OA Mixer of the ventilated slab
4379 557216 : state.dataLoopNodes->Node(OAMixOutNode).Enthalpy =
4380 557216 : OAFraction * state.dataLoopNodes->Node(OutsideAirNode).Enthalpy + (1.0 - OAFraction) * state.dataLoopNodes->Node(InletNode).Enthalpy;
4381 557216 : state.dataLoopNodes->Node(OAMixOutNode).HumRat =
4382 557216 : OAFraction * state.dataLoopNodes->Node(OutsideAirNode).HumRat + (1.0 - OAFraction) * state.dataLoopNodes->Node(InletNode).HumRat;
4383 :
4384 : // Find the other key state points based on calculated conditions
4385 557216 : state.dataLoopNodes->Node(OAMixOutNode).Temp =
4386 557216 : PsyTdbFnHW(state.dataLoopNodes->Node(OAMixOutNode).Enthalpy, state.dataLoopNodes->Node(OAMixOutNode).HumRat);
4387 557216 : state.dataLoopNodes->Node(OAMixOutNode).Press = state.dataLoopNodes->Node(InletNode).Press;
4388 557216 : }
4389 :
4390 106951 : void UpdateVentilatedSlab(EnergyPlusData &state,
4391 : int const Item, // Index for the ventilated slab under consideration within the derived types
4392 : [[maybe_unused]] bool const FirstHVACIteration // TRUE if 1st HVAC simulation of system timestep !unused1208
4393 : )
4394 : {
4395 :
4396 : // SUBROUTINE INFORMATION:
4397 : // AUTHOR Young Tae Chae, Rick Strand
4398 : // DATE WRITTEN November 2000
4399 : // MODIFIED na
4400 : // RE-ENGINEERED na
4401 :
4402 : // PURPOSE OF THIS SUBROUTINE:
4403 : // This subroutine does any updating that needs to be done for low
4404 : // temperature radiant heating and cooling systems. One of the most
4405 : // important functions of this routine is to update the average heat
4406 : // source/sink for a particular system over the various system time
4407 : // steps that make up the zone time step. For hydronic systems,
4408 : // this routine must also set the outlet water conditions.
4409 :
4410 : // METHODOLOGY EMPLOYED:
4411 : // For the source/sink average update, if the system time step elapsed
4412 : // is still what it used to be, then either we are still iterating or
4413 : // we had to go back and shorten the time step. As a result, we have
4414 : // to subtract out the previous value that we added. If the system
4415 : // time step elapsed is different, then we just need to add the new
4416 : // values to the running average.
4417 :
4418 : // Using/Aliasing
4419 106951 : auto &SysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
4420 106951 : auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys;
4421 106951 : auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
4422 :
4423 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4424 : Real64 CpAppAir; // Specific heat of air
4425 : int RadSurfNum; // DO loop counter for radiant surfaces in the ventilated slab
4426 : int SurfNum; // Surface index number for the current ventilated slab
4427 : int AirInletNode; // Node number for the air side inlet of the ventilated slab
4428 : Real64 TotalHeatSource; // Total heat source or sink for a particular system (sum of all surface source/sinks)
4429 : int TotRadSurfaces; // Total number of radiant surfaces in this system
4430 : Real64 AirMassFlow; // Flow rate of water in the radiant system
4431 : int AirOutletNode; // Node number for the water side outlet of the radiant system
4432 : int FanOutNode; // Node number for the water side outlet of the radiant system
4433 : Real64 ZoneMult; // Zone multiplier
4434 : int ZoneNum; // Zone for this ventilated slab
4435 : int MixOutNode; // Node number for the water side outlet of the radiant system
4436 : int OANode; // Node number for the water side outlet of the radiant system
4437 : Real64 OAFraction; // Outside air fraction of inlet air
4438 : int ZoneInletNode; // Node number for the air side inlet of the ventilated slab
4439 :
4440 106951 : ZoneNum = ventSlab.ZonePtr;
4441 106951 : TotRadSurfaces = ventSlab.NumOfSurfaces;
4442 106951 : MixOutNode = ventSlab.OAMixerOutNode;
4443 106951 : OANode = ventSlab.OutsideAirNode;
4444 106951 : AirOutletNode = ventSlab.RadInNode;
4445 106951 : FanOutNode = ventSlab.FanOutletNode;
4446 106951 : AirMassFlow = state.dataLoopNodes->Node(AirOutletNode).MassFlowRate;
4447 106951 : ZoneInletNode = ventSlab.ZoneAirInNode;
4448 106951 : CpAppAir = PsyCpAirFnW(state.dataLoopNodes->Node(AirOutletNode).HumRat);
4449 106951 : AirInletNode = ventSlab.ReturnAirNode;
4450 :
4451 250241 : for (RadSurfNum = 1; RadSurfNum <= TotRadSurfaces; ++RadSurfNum) {
4452 :
4453 143290 : SurfNum = ventSlab.SurfacePtr(RadSurfNum);
4454 :
4455 143290 : if (state.dataVentilatedSlab->LastSysTimeElapsed(SurfNum) == SysTimeElapsed) {
4456 : // Still iterating or reducing system time step, so subtract old values which were
4457 : // not valid
4458 312690 : state.dataVentilatedSlab->QRadSysSrcAvg(SurfNum) -= state.dataVentilatedSlab->LastQRadSysSrc(SurfNum) *
4459 208460 : state.dataVentilatedSlab->LastTimeStepSys(SurfNum) /
4460 104230 : state.dataGlobal->TimeStepZone;
4461 : }
4462 :
4463 : // Update the running average and the "last" values with the current values of the appropriate variables
4464 143290 : state.dataVentilatedSlab->QRadSysSrcAvg(SurfNum) +=
4465 143290 : state.dataHeatBalFanSys->QRadSysSource(SurfNum) * TimeStepSys / state.dataGlobal->TimeStepZone;
4466 :
4467 143290 : state.dataVentilatedSlab->LastQRadSysSrc(SurfNum) = state.dataHeatBalFanSys->QRadSysSource(SurfNum);
4468 143290 : state.dataVentilatedSlab->LastSysTimeElapsed(SurfNum) = SysTimeElapsed;
4469 143290 : state.dataVentilatedSlab->LastTimeStepSys(SurfNum) = TimeStepSys;
4470 : }
4471 :
4472 : // First sum up all of the heat sources/sinks associated with this system
4473 106951 : TotalHeatSource = 0.0;
4474 250241 : for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
4475 143290 : SurfNum = ventSlab.SurfacePtr(RadSurfNum);
4476 143290 : TotalHeatSource += state.dataHeatBalFanSys->QRadSysSource(SurfNum);
4477 : }
4478 106951 : ZoneNum = ventSlab.ZonePtr;
4479 106951 : ZoneMult = double(state.dataHeatBal->Zone(ZoneNum).Multiplier * state.dataHeatBal->Zone(ZoneNum).ListMultiplier);
4480 106951 : TotalHeatSource *= ZoneMult;
4481 :
4482 : // Update the heating side of things
4483 :
4484 106951 : if ((CpAppAir > 0.0) && (AirMassFlow > 0.0)) {
4485 :
4486 140162 : if ((ventSlab.SysConfg == VentilatedSlabConfig::SlabOnly) || (ventSlab.SysConfg == VentilatedSlabConfig::SeriesSlabs)) {
4487 46039 : state.dataLoopNodes->Node(AirInletNode) = state.dataLoopNodes->Node(AirInletNode);
4488 46039 : state.dataLoopNodes->Node(AirInletNode).Temp =
4489 46039 : state.dataLoopNodes->Node(AirOutletNode).Temp - TotalHeatSource / AirMassFlow / CpAppAir;
4490 46039 : state.dataLoopNodes->Node(AirInletNode).MassFlowRate = state.dataLoopNodes->Node(AirOutletNode).MassFlowRate;
4491 46039 : state.dataLoopNodes->Node(AirInletNode).HumRat = state.dataLoopNodes->Node(AirOutletNode).HumRat;
4492 :
4493 24042 : } else if (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone) {
4494 24042 : state.dataLoopNodes->Node(ZoneInletNode) = state.dataLoopNodes->Node(ZoneInletNode);
4495 24042 : state.dataLoopNodes->Node(ZoneInletNode).Temp =
4496 24042 : state.dataLoopNodes->Node(AirOutletNode).Temp - TotalHeatSource / AirMassFlow / CpAppAir;
4497 24042 : state.dataLoopNodes->Node(ZoneInletNode).MassFlowRate = state.dataLoopNodes->Node(AirOutletNode).MassFlowRate;
4498 24042 : state.dataLoopNodes->Node(ZoneInletNode).HumRat = state.dataLoopNodes->Node(AirOutletNode).HumRat;
4499 24042 : state.dataLoopNodes->Node(ventSlab.ReturnAirNode).Temp = state.dataZoneTempPredictorCorrector->zoneHeatBalance(ZoneNum).MAT;
4500 : }
4501 :
4502 : } else {
4503 36870 : if ((ventSlab.SysConfg == VentilatedSlabConfig::SlabOnly) || (ventSlab.SysConfg == VentilatedSlabConfig::SeriesSlabs)) {
4504 11277 : state.dataLoopNodes->Node(FanOutNode) = state.dataLoopNodes->Node(AirOutletNode);
4505 11277 : state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
4506 :
4507 25593 : } else if (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone) {
4508 25593 : state.dataLoopNodes->Node(ZoneInletNode) = state.dataLoopNodes->Node(AirInletNode);
4509 25593 : state.dataLoopNodes->Node(FanOutNode) = state.dataLoopNodes->Node(AirOutletNode); // Fan Resolve
4510 25593 : state.dataHeatBalFanSys->QRadSysSource(SurfNum) = 0.0;
4511 : }
4512 : }
4513 :
4514 : // Resolve mixouttemp
4515 :
4516 106951 : if (state.dataLoopNodes->Node(AirInletNode).MassFlowRate > 0.0) {
4517 :
4518 70081 : OAFraction = state.dataLoopNodes->Node(OANode).MassFlowRate / state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
4519 :
4520 : } else {
4521 36870 : OAFraction = 0.0;
4522 : }
4523 :
4524 106951 : if (OAFraction <= 0.0) {
4525 :
4526 92622 : state.dataLoopNodes->Node(MixOutNode).HumRat = state.dataLoopNodes->Node(AirInletNode).HumRat;
4527 92622 : state.dataLoopNodes->Node(MixOutNode).Temp = state.dataLoopNodes->Node(AirInletNode).Temp;
4528 :
4529 : } else {
4530 :
4531 14329 : state.dataLoopNodes->Node(MixOutNode).Enthalpy =
4532 14329 : OAFraction * state.dataLoopNodes->Node(OANode).Enthalpy + (1.0 - OAFraction) * state.dataLoopNodes->Node(AirInletNode).Enthalpy;
4533 14329 : state.dataLoopNodes->Node(MixOutNode).HumRat =
4534 14329 : OAFraction * state.dataLoopNodes->Node(OANode).HumRat + (1.0 - OAFraction) * state.dataLoopNodes->Node(AirInletNode).HumRat;
4535 :
4536 14329 : state.dataLoopNodes->Node(MixOutNode).Temp =
4537 14329 : PsyTdbFnHW(state.dataLoopNodes->Node(MixOutNode).Enthalpy, state.dataLoopNodes->Node(MixOutNode).HumRat);
4538 : }
4539 106951 : }
4540 :
4541 104882 : Real64 CalcVentSlabHXEffectTerm(EnergyPlusData &state,
4542 : int const Item, // Index number of radiant system under consideration
4543 : Real64 const Temperature, // Temperature of air entering the radiant system, in C
4544 : Real64 const AirMassFlow, // Mass flow rate of water in the radiant system, in kg/s
4545 : Real64 const FlowFraction, // Mass flow rate fraction for this surface in the radiant system
4546 : Real64 const CoreLength, // Length of tubing in the radiant system, in m
4547 : Real64 const CoreDiameter, // Inside diameter of the tubing in the radiant system, in m
4548 : Real64 const CoreNumbers)
4549 : {
4550 :
4551 : // SUBROUTINE INFORMATION:
4552 : // AUTHOR Rick Strand
4553 : // DATE WRITTEN December 2000
4554 : // MODIFIED June 2008 (air properties)
4555 : // RE-ENGINEERED na
4556 :
4557 : // PURPOSE OF THIS SUBROUTINE:
4558 : // This subroutine calculates the radiant system "heat exchanger"
4559 : // effectiveness term. This is equal to the mass flow rate of water
4560 : // times the specific heat of water times the effectiveness of
4561 : // the heat exchanger (radiant system "coil").
4562 :
4563 : // METHODOLOGY EMPLOYED:
4564 : // Assumes that the only real heat transfer term that we have to
4565 : // deal with is the convection from the water to the tube. The
4566 : // other assumptions are that the tube inside surface temperature
4567 : // is equal to the "source location temperature" and that it is
4568 : // a CONSTANT throughout the radiant system. This is to make
4569 : // the problem more tractable and to fit with other system assumptions
4570 : // that were made elsewhere in the radiant system model.
4571 :
4572 : // REFERENCES:
4573 : // Property data for air shown below as parameters taken from
4574 : // Mills, Heat Transfer, Table A.7.
4575 : // Heat exchanger information also from Incropera and DeWitt.
4576 : // Code based loosely on code from IBLAST program (research version)
4577 :
4578 : // Using/Aliasing
4579 104882 : auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
4580 :
4581 : // Return value
4582 : Real64 CalcVentSlabHXEffectTerm;
4583 :
4584 104882 : Real64 constexpr MaxLaminarRe(2300.0); // Maximum Reynolds number for laminar flow
4585 104882 : int constexpr NumOfPropDivisions(13);
4586 104882 : Real64 constexpr MaxExpPower(50.0); // Maximum power after which EXP argument would be zero for DP variables
4587 : static constexpr std::array<Real64, NumOfPropDivisions> Temps = {
4588 : 1.85, 6.85, 11.85, 16.85, 21.85, 26.85, 31.85, 36.85, 41.85, 46.85, 51.85, 56.85, 61.85}; // Temperature, in C
4589 : static constexpr std::array<Real64, NumOfPropDivisions> Mu = {0.0000088,
4590 : 0.0000176,
4591 : 0.00001781,
4592 : 0.00001802,
4593 : 0.000018225,
4594 : 0.00001843,
4595 : 0.00001865,
4596 : 0.00001887,
4597 : 0.00001908,
4598 : 0.00001929,
4599 : 0.0000195,
4600 : 0.00001971,
4601 : 0.00001992}; // Viscosity, in Ns/m2
4602 :
4603 : static constexpr std::array<Real64, NumOfPropDivisions> Conductivity = {
4604 : 0.01275, 0.0255, 0.0258, 0.0261, 0.0264, 0.0267, 0.02705, 0.0274, 0.02775, 0.0281, 0.0284, 0.0287, 0.01435}; // Conductivity, in W/mK
4605 : static constexpr std::array<Real64, NumOfPropDivisions> Pr = {
4606 : 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69, 0.69}; // Prandtl number (dimensionless)
4607 :
4608 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
4609 : int Index;
4610 : Real64 InterpFrac;
4611 : Real64 NuD;
4612 : Real64 ReD;
4613 : Real64 NTU;
4614 : Real64 CpAppAir;
4615 : Real64 Kactual;
4616 : Real64 MUactual;
4617 : Real64 PRactual;
4618 : Real64 SysAirMassFlow; // Specific heat of air
4619 :
4620 : // First find out where we are in the range of temperatures
4621 104882 : Index = 0;
4622 1093328 : while (Index < NumOfPropDivisions) {
4623 599105 : if (Temperature < Temps[Index]) break; // DO loop
4624 494223 : ++Index;
4625 : }
4626 :
4627 : // Initialize thermal properties of Air
4628 104882 : if (Index == 0) {
4629 5617 : MUactual = Mu[Index];
4630 5617 : Kactual = Conductivity[Index];
4631 5617 : PRactual = Pr[Index];
4632 99265 : } else if (Index > NumOfPropDivisions - 1) {
4633 0 : Index = NumOfPropDivisions - 1;
4634 0 : MUactual = Mu[Index];
4635 0 : Kactual = Conductivity[Index];
4636 0 : PRactual = Pr[Index];
4637 : } else {
4638 99265 : InterpFrac = (Temperature - Temps[Index - 1]) / (Temps[Index] - Temps[Index - 1]);
4639 99265 : MUactual = Mu[Index - 1] + InterpFrac * (Mu[Index] - Mu[Index - 1]);
4640 99265 : Kactual = Conductivity[Index - 1] + InterpFrac * (Conductivity[Index] - Conductivity[Index - 1]);
4641 99265 : PRactual = Pr[Index - 1] + InterpFrac * (Pr[Index] - Pr[Index - 1]);
4642 : }
4643 : // arguments are glycol name, temperature, and concentration
4644 104882 : CpAppAir = PsyCpAirFnW(state.dataLoopNodes->Node(ventSlab.RadInNode).HumRat);
4645 104882 : SysAirMassFlow = AirMassFlow / CoreNumbers;
4646 :
4647 : // Calculate the Reynold's number from RE=(4*Mdot)/(Pi*Mu*Diameter)
4648 104882 : ReD = 4.0 * SysAirMassFlow * FlowFraction / (DataGlobalConstants::Pi * MUactual * CoreDiameter);
4649 :
4650 : // Calculate the Nusselt number based on what flow regime one is in
4651 104882 : if (ReD >= MaxLaminarRe) { // Turbulent flow --> use Colburn equation
4652 :
4653 104882 : NuD = 0.023 * std::pow(ReD, 0.8) * std::pow(PRactual, 1.0 / 3.0);
4654 :
4655 : } else { // Laminar flow --> use constant surface temperature relation
4656 :
4657 0 : NuD = 3.66;
4658 : }
4659 :
4660 : // Calculate the NTU parameter
4661 : // NTU = UA/[(Mdot*Cp)min]
4662 : // where: U = h (convection coefficient) and h = (k)(Nu)/D
4663 : // A = Pi*D*TubeLength
4664 104882 : NTU = DataGlobalConstants::Pi * Kactual * NuD * CoreLength / (SysAirMassFlow * CpAppAir); // FlowFraction cancels out here
4665 :
4666 : // Calculate Epsilon*MassFlowRate*Cp
4667 104882 : if (NTU > MaxExpPower) {
4668 0 : CalcVentSlabHXEffectTerm = FlowFraction * SysAirMassFlow * CpAppAir;
4669 : } else {
4670 104882 : CalcVentSlabHXEffectTerm = (1.0 - std::exp(-NTU)) * FlowFraction * SysAirMassFlow * CpAppAir;
4671 : }
4672 :
4673 104882 : return CalcVentSlabHXEffectTerm;
4674 : }
4675 :
4676 106951 : void ReportVentilatedSlab(EnergyPlusData &state, int const Item) // Index for the ventilated slab under consideration within the derived types
4677 : {
4678 :
4679 : // SUBROUTINE INFORMATION:
4680 : // AUTHOR Rick Strand
4681 : // DATE WRITTEN November 2000
4682 : // MODIFIED na
4683 : // RE-ENGINEERED na
4684 :
4685 : // PURPOSE OF THIS SUBROUTINE:
4686 : // This subroutine simply produces output for the low temperature radiant system.
4687 :
4688 : // METHODOLOGY EMPLOYED:
4689 : // Standard EnergyPlus methodology.
4690 :
4691 : // Using/Aliasing
4692 106951 : auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys;
4693 106951 : auto &ventSlab = state.dataVentilatedSlab->VentSlab(Item);
4694 :
4695 : int RadSurfNum; // DO loop counter for radiant surfaces in the system
4696 : int SurfNum; // Surface number (index) in Surface derived type
4697 : Real64 TotalVentSlabRadPower; // Total source/sink power for the radiant system (sum of all surfaces of the system)
4698 : Real64 ZoneMult; // Total zone multiplier to apply to the system level variables
4699 :
4700 : // Slab Part
4701 106951 : TotalVentSlabRadPower = 0.0;
4702 106951 : ZoneMult = 1.0;
4703 :
4704 250241 : for (RadSurfNum = 1; RadSurfNum <= ventSlab.NumOfSurfaces; ++RadSurfNum) {
4705 143290 : SurfNum = ventSlab.SurfacePtr(RadSurfNum);
4706 143290 : TotalVentSlabRadPower += state.dataHeatBalFanSys->QRadSysSource(SurfNum);
4707 : }
4708 106951 : ZoneMult = double(state.dataHeatBal->Zone(ventSlab.ZonePtr).Multiplier * state.dataHeatBal->Zone(ventSlab.ZonePtr).ListMultiplier);
4709 106951 : TotalVentSlabRadPower *= ZoneMult;
4710 106951 : ventSlab.RadHeatingPower = 0.0;
4711 106951 : ventSlab.RadCoolingPower = 0.0;
4712 :
4713 106951 : if (TotalVentSlabRadPower >= 0.01) {
4714 :
4715 48010 : ventSlab.RadHeatingPower = +TotalVentSlabRadPower;
4716 : } else {
4717 :
4718 58941 : ventSlab.RadCoolingPower = -TotalVentSlabRadPower;
4719 : }
4720 :
4721 106951 : ventSlab.RadHeatingEnergy = ventSlab.RadHeatingPower * TimeStepSys * DataGlobalConstants::SecInHour;
4722 106951 : ventSlab.RadCoolingEnergy = ventSlab.RadCoolingPower * TimeStepSys * DataGlobalConstants::SecInHour;
4723 :
4724 : // Coil Part
4725 106951 : ventSlab.HeatCoilEnergy = ventSlab.HeatCoilPower * TimeStepSys * DataGlobalConstants::SecInHour;
4726 106951 : ventSlab.SensCoolCoilEnergy = ventSlab.SensCoolCoilPower * TimeStepSys * DataGlobalConstants::SecInHour;
4727 106951 : ventSlab.LateCoolCoilEnergy = ventSlab.LateCoolCoilPower * TimeStepSys * DataGlobalConstants::SecInHour;
4728 106951 : ventSlab.TotCoolCoilEnergy = ventSlab.TotCoolCoilPower * TimeStepSys * DataGlobalConstants::SecInHour;
4729 106951 : ventSlab.ElecFanEnergy = ventSlab.ElecFanPower * TimeStepSys * DataGlobalConstants::SecInHour;
4730 :
4731 106951 : if ((ventSlab.SysConfg == VentilatedSlabConfig::SlabOnly) || (ventSlab.SysConfg == VentilatedSlabConfig::SeriesSlabs)) {
4732 57316 : ventSlab.SlabInTemp = state.dataLoopNodes->Node(ventSlab.RadInNode).Temp;
4733 57316 : ventSlab.SlabOutTemp = state.dataLoopNodes->Node(ventSlab.ReturnAirNode).Temp;
4734 :
4735 49635 : } else if (ventSlab.SysConfg == VentilatedSlabConfig::SlabAndZone) {
4736 49635 : ventSlab.SlabInTemp = state.dataLoopNodes->Node(ventSlab.RadInNode).Temp;
4737 49635 : ventSlab.ZoneInletTemp = state.dataLoopNodes->Node(ventSlab.ZoneAirInNode).Temp;
4738 49635 : ventSlab.SlabOutTemp = state.dataLoopNodes->Node(ventSlab.ReturnAirNode).Temp;
4739 : }
4740 :
4741 106951 : ventSlab.ReturnAirTemp = state.dataLoopNodes->Node(ventSlab.ReturnAirNode).Temp;
4742 106951 : ventSlab.FanOutletTemp = state.dataLoopNodes->Node(ventSlab.FanOutletNode).Temp;
4743 :
4744 106951 : if (ventSlab.FirstPass) { // reset sizing flags so other zone equipment can size normally
4745 7 : if (!state.dataGlobal->SysSizingCalc) {
4746 7 : DataSizing::resetHVACSizingGlobals(state, state.dataSize->CurZoneEqNum, 0, ventSlab.FirstPass);
4747 : }
4748 : }
4749 106951 : }
4750 :
4751 : //*****************************************************************************************
4752 :
4753 : } // namespace VentilatedSlab
4754 :
4755 2313 : } // namespace EnergyPlus
|