Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2024, The Board of Trustees of the University of Illinois,
2 : // The Regents of the University of California, through Lawrence Berkeley National Laboratory
3 : // (subject to receipt of any required approvals from the U.S. Dept. of Energy), Oak Ridge
4 : // National Laboratory, managed by UT-Battelle, Alliance for Sustainable Energy, LLC, and other
5 : // contributors. All rights reserved.
6 : //
7 : // NOTICE: This Software was developed under funding from the U.S. Department of Energy and the
8 : // U.S. Government consequently retains certain rights. As such, the U.S. Government has been
9 : // granted for itself and others acting on its behalf a paid-up, nonexclusive, irrevocable,
10 : // worldwide license in the Software to reproduce, distribute copies to the public, prepare
11 : // derivative works, and perform publicly and display publicly, and to permit others to do so.
12 : //
13 : // Redistribution and use in source and binary forms, with or without modification, are permitted
14 : // provided that the following conditions are met:
15 : //
16 : // (1) Redistributions of source code must retain the above copyright notice, this list of
17 : // conditions and the following disclaimer.
18 : //
19 : // (2) Redistributions in binary form must reproduce the above copyright notice, this list of
20 : // conditions and the following disclaimer in the documentation and/or other materials
21 : // provided with the distribution.
22 : //
23 : // (3) Neither the name of the University of California, Lawrence Berkeley National Laboratory,
24 : // the University of Illinois, U.S. Dept. of Energy nor the names of its contributors may be
25 : // used to endorse or promote products derived from this software without specific prior
26 : // written permission.
27 : //
28 : // (4) Use of EnergyPlus(TM) Name. If Licensee (i) distributes the software in stand-alone form
29 : // without changes from the version obtained under this License, or (ii) Licensee makes a
30 : // reference solely to the software portion of its product, Licensee must refer to the
31 : // software as "EnergyPlus version X" software, where "X" is the version number Licensee
32 : // obtained under this License and may not use a different name for the software. Except as
33 : // specifically required in this Section (4), Licensee shall not use in a company name, a
34 : // product name, in advertising, publicity, or other promotional activities any name, trade
35 : // name, trademark, logo, or other designation of "EnergyPlus", "E+", "e+" or confusingly
36 : // similar designation, without the U.S. Department of Energy's prior written consent.
37 : //
38 : // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR
39 : // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
40 : // AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
41 : // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
42 : // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
43 : // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
44 : // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
45 : // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
46 : // POSSIBILITY OF SUCH DAMAGE.
47 :
48 : // C++ Headers
49 : #include <cmath>
50 :
51 : // ObjexxFCL Headers
52 : #include <ObjexxFCL/Array.functions.hh>
53 : #include <ObjexxFCL/Fmath.hh>
54 :
55 : // EnergyPlus Headers
56 : #include <EnergyPlus/Autosizing/HeatingCapacitySizing.hh>
57 : #include <EnergyPlus/BranchNodeConnections.hh>
58 : #include <EnergyPlus/Data/EnergyPlusData.hh>
59 : #include <EnergyPlus/DataEnvironment.hh>
60 : #include <EnergyPlus/DataHVACGlobals.hh>
61 : #include <EnergyPlus/DataHeatBalFanSys.hh>
62 : #include <EnergyPlus/DataHeatBalSurface.hh>
63 : #include <EnergyPlus/DataHeatBalance.hh>
64 : #include <EnergyPlus/DataIPShortCuts.hh>
65 : #include <EnergyPlus/DataLoopNode.hh>
66 : #include <EnergyPlus/DataSurfaces.hh>
67 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
68 : #include <EnergyPlus/DataZoneEquipment.hh>
69 : #include <EnergyPlus/FluidProperties.hh>
70 : #include <EnergyPlus/General.hh>
71 : #include <EnergyPlus/GeneralRoutines.hh>
72 : #include <EnergyPlus/GlobalNames.hh>
73 : #include <EnergyPlus/HWBaseboardRadiator.hh>
74 : #include <EnergyPlus/HeatBalanceIntRadExchange.hh>
75 : #include <EnergyPlus/HeatBalanceSurfaceManager.hh>
76 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
77 : #include <EnergyPlus/NodeInputManager.hh>
78 : #include <EnergyPlus/OutputProcessor.hh>
79 : #include <EnergyPlus/Plant/DataPlant.hh>
80 : #include <EnergyPlus/PlantUtilities.hh>
81 : #include <EnergyPlus/Psychrometrics.hh>
82 : #include <EnergyPlus/ScheduleManager.hh>
83 : #include <EnergyPlus/UtilityRoutines.hh>
84 :
85 : namespace EnergyPlus {
86 :
87 : namespace HWBaseboardRadiator {
88 :
89 : // Module -- (ref: Object: ZoneHVAC:Baseboard:RadiantConvective:Water)
90 :
91 : // Module containing the routines dealing with the hot water baseboard heaters
92 :
93 : // MODULE INFORMATION:
94 : // AUTHOR Daeho Kang
95 : // DATE WRITTEN Aug 2007
96 :
97 : // PURPOSE OF THIS MODULE:
98 : // The purpose of this module is to simulate hot water baseboard heaters.
99 :
100 : // REFERENCES:
101 : // 1. I=B=R Ratings for Baseboards, Baseboard Radiation,
102 : // Finned Tube (Commercial) Radiation, and Indirect Fired Water Heaters, January 2007 Edition
103 : // 2. Incropera and DeWitt, Fundamentals of Heat and Mass Transfer, Chapter 11.3 and 11.4,
104 : // eq. 11.15, 11.17, and 11.33
105 :
106 : std::string const cCMO_BBRadiator_Water("ZoneHVAC:Baseboard:RadiantConvective:Water");
107 : std::string const cCMO_BBRadiator_Water_Design("ZoneHVAC:Baseboard:RadiantConvective:Water:Design");
108 :
109 88831 : void SimHWBaseboard(EnergyPlusData &state,
110 : std::string const &EquipName,
111 : int const ControlledZoneNum,
112 : bool const FirstHVACIteration,
113 : Real64 &PowerMet,
114 : int &CompIndex)
115 : {
116 :
117 : // SUBROUTINE INFORMATION:
118 : // AUTHOR Russ Taylor
119 : // DATE WRITTEN Nov 1997
120 :
121 : // PURPOSE OF THIS SUBROUTINE:
122 : // This subroutine simulates the Baseboard Radiators.
123 :
124 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
125 : int BaseboardNum; // Index of unit in baseboard array
126 : Real64 QZnReq; // Zone load not yet satisfied
127 : Real64 MaxWaterFlow;
128 : Real64 MinWaterFlow;
129 :
130 88831 : if (state.dataHWBaseboardRad->GetInputFlag) {
131 7 : GetHWBaseboardInput(state);
132 7 : state.dataHWBaseboardRad->GetInputFlag = false;
133 : }
134 :
135 88831 : int const NumHWBaseboards = state.dataHWBaseboardRad->NumHWBaseboards;
136 :
137 : // Find the correct Baseboard Equipment
138 88831 : if (CompIndex == 0) {
139 17 : BaseboardNum = Util::FindItemInList(EquipName, state.dataHWBaseboardRad->HWBaseboard, &HWBaseboardParams::Name);
140 17 : if (BaseboardNum == 0) {
141 0 : ShowFatalError(state, format("SimHWBaseboard: Unit not found={}", EquipName));
142 : }
143 17 : CompIndex = BaseboardNum;
144 : } else {
145 88814 : BaseboardNum = CompIndex;
146 88814 : if (BaseboardNum > NumHWBaseboards || BaseboardNum < 1) {
147 0 : ShowFatalError(state,
148 0 : format("SimHWBaseboard: Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
149 : BaseboardNum,
150 : NumHWBaseboards,
151 : EquipName));
152 : }
153 88814 : if (state.dataHWBaseboardRad->CheckEquipName(BaseboardNum)) {
154 17 : if (EquipName != state.dataHWBaseboardRad->HWBaseboard(BaseboardNum).Name) {
155 0 : ShowFatalError(state,
156 0 : format("SimHWBaseboard: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
157 : BaseboardNum,
158 : EquipName,
159 0 : state.dataHWBaseboardRad->HWBaseboard(BaseboardNum).Name));
160 : }
161 17 : state.dataHWBaseboardRad->CheckEquipName(BaseboardNum) = false;
162 : }
163 : }
164 :
165 88831 : if (CompIndex > 0) {
166 88831 : auto &HWBaseboard = state.dataHWBaseboardRad->HWBaseboard(BaseboardNum);
167 :
168 88831 : HWBaseboardDesignData const &HWBaseboardDesignDataObject = state.dataHWBaseboardRad->HWBaseboardDesignObject(
169 : HWBaseboard.DesignObjectPtr); // Contains the data for variable flow hydronic systems
170 :
171 88831 : InitHWBaseboard(state, BaseboardNum, ControlledZoneNum, FirstHVACIteration);
172 :
173 88831 : QZnReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToHeatSP;
174 :
175 : // On the first HVAC iteration the system values are given to the controller, but after that
176 : // the demand limits are in place and there needs to be feedback to the Zone Equipment
177 88831 : if (FirstHVACIteration) {
178 42272 : MaxWaterFlow = HWBaseboard.WaterMassFlowRateMax;
179 42272 : MinWaterFlow = 0.0;
180 : } else {
181 46559 : MaxWaterFlow = state.dataLoopNodes->Node(HWBaseboard.WaterInletNode).MassFlowRateMaxAvail;
182 46559 : MinWaterFlow = state.dataLoopNodes->Node(HWBaseboard.WaterInletNode).MassFlowRateMinAvail;
183 : }
184 :
185 88831 : switch (HWBaseboard.EquipType) {
186 88831 : case DataPlant::PlantEquipmentType::Baseboard_Rad_Conv_Water: { // 'ZoneHVAC:Baseboard:RadiantConvective:Water'
187 266493 : ControlCompOutput(state,
188 88831 : HWBaseboard.Name,
189 : cCMO_BBRadiator_Water,
190 : BaseboardNum,
191 : FirstHVACIteration,
192 : QZnReq,
193 : HWBaseboard.WaterInletNode,
194 : MaxWaterFlow,
195 : MinWaterFlow,
196 88831 : HWBaseboardDesignDataObject.Offset,
197 88831 : HWBaseboard.ControlCompTypeNum,
198 88831 : HWBaseboard.CompErrIndex,
199 : _,
200 : _,
201 : _,
202 : _,
203 : _,
204 88831 : HWBaseboard.plantLoc);
205 88831 : } break;
206 0 : default: {
207 0 : ShowSevereError(state, format("SimBaseboard: Errors in Baseboard={}", HWBaseboard.Name));
208 0 : ShowContinueError(state, format("Invalid or unimplemented equipment type={}", HWBaseboard.EquipType));
209 0 : ShowFatalError(state, "Preceding condition causes termination.");
210 0 : } break;
211 : }
212 :
213 88831 : PowerMet = HWBaseboard.TotPower;
214 :
215 88831 : UpdateHWBaseboard(state, BaseboardNum);
216 :
217 88831 : ReportHWBaseboard(state, BaseboardNum);
218 :
219 : } else {
220 0 : ShowFatalError(state, format("SimHWBaseboard: Unit not found={}", EquipName));
221 : }
222 88831 : }
223 :
224 7 : void GetHWBaseboardInput(EnergyPlusData &state)
225 : {
226 :
227 : // SUBROUTINE INFORMATION:
228 : // AUTHOR Daeho Kang
229 : // DATE WRITTEN Aug 2007
230 :
231 : // PURPOSE OF THIS SUBROUTINE:
232 : // This subroutine gets the input for the baseboard units.
233 :
234 : // METHODOLOGY EMPLOYED:
235 : // Standard input processor calls.
236 :
237 : // SUBROUTINE PARAMETER DEFINITIONS:
238 : static constexpr std::string_view RoutineName("GetHWBaseboardInput:");
239 7 : Real64 constexpr MaxFraction(1.0);
240 7 : Real64 constexpr MinFraction(0.0);
241 7 : Real64 constexpr MaxWaterTempAvg(150.0); // Maximum limit of average water temperature in degree C
242 7 : Real64 constexpr MinWaterTempAvg(20.0); // Minimum limit of average water temperature in degree C
243 7 : Real64 constexpr HighWaterMassFlowRate(10.0); // Maximum limit of water mass flow rate in kg/s
244 7 : Real64 constexpr LowWaterMassFlowRate(0.00001); // Minimum limit of water mass flow rate in kg/s
245 7 : Real64 constexpr MaxWaterFlowRate(10.0); // Maximum limit of water volume flow rate in m3/s
246 7 : Real64 constexpr MinWaterFlowRate(0.00001); // Minimum limit of water volume flow rate in m3/s
247 7 : Real64 constexpr WaterMassFlowDefault(0.063); // Default water mass flow rate in kg/s
248 7 : int constexpr MinDistribSurfaces(1); // Minimum number of surfaces that a baseboard heater can radiate to
249 7 : int constexpr iHeatCAPMAlphaNum(2); // get input index to HW baseboard heating capacity sizing method
250 7 : int constexpr iHeatDesignCapacityNumericNum(3); // get input index to HW baseboard heating capacity
251 7 : int constexpr iHeatCapacityPerFloorAreaNumericNum(1); // get input index to HW baseboard heating capacity per floor area sizing
252 7 : int constexpr iHeatFracOfAutosizedCapacityNumericNum(
253 : 2); // get input index to HW baseboard heating capacity sizing as fraction of autozized heating capacity
254 :
255 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
256 : int BaseboardNum; // Baseboard number
257 : int BaseboardDesignNum;
258 : int NumAlphas; // Number of Alphas for each GetobjectItem call
259 : int NumNumbers; // Number of Numbers for each GetobjectItem call
260 : int SurfNum; // Surface number Do loop counter
261 : int IOStat;
262 7 : bool ErrorsFound(false); // If errors detected in input
263 :
264 : // Update Nums in state and make local convenience copies
265 14 : int NumHWBaseboards = state.dataHWBaseboardRad->NumHWBaseboards =
266 7 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCMO_BBRadiator_Water);
267 14 : int NumHWBaseboardDesignObjs = state.dataHWBaseboardRad->NumHWBaseboardDesignObjs =
268 7 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCMO_BBRadiator_Water_Design);
269 :
270 : // Count total number of baseboard units
271 :
272 7 : state.dataHWBaseboardRad->HWBaseboard.allocate(NumHWBaseboards);
273 7 : state.dataHWBaseboardRad->HWBaseboardDesignObject.allocate(NumHWBaseboardDesignObjs);
274 7 : state.dataHWBaseboardRad->CheckEquipName.allocate(NumHWBaseboards);
275 7 : state.dataHWBaseboardRad->HWBaseboardNumericFields.allocate(NumHWBaseboards);
276 7 : Array1D_string HWBaseboardDesignNames;
277 7 : HWBaseboardDesignNames.allocate(NumHWBaseboardDesignObjs);
278 7 : state.dataHWBaseboardRad->CheckEquipName = true;
279 :
280 : // Get the data from the user input related to design data for baseboard heaters
281 18 : for (BaseboardDesignNum = 1; BaseboardDesignNum <= NumHWBaseboardDesignObjs; ++BaseboardDesignNum) {
282 11 : auto &thisHWBaseboardDesign = state.dataHWBaseboardRad->HWBaseboardDesignObject(BaseboardDesignNum);
283 :
284 22 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
285 : cCMO_BBRadiator_Water_Design,
286 : BaseboardDesignNum,
287 11 : state.dataIPShortCut->cAlphaArgs,
288 : NumAlphas,
289 11 : state.dataIPShortCut->rNumericArgs,
290 : NumNumbers,
291 : IOStat,
292 11 : state.dataIPShortCut->lNumericFieldBlanks,
293 11 : state.dataIPShortCut->lAlphaFieldBlanks,
294 11 : state.dataIPShortCut->cAlphaFieldNames,
295 11 : state.dataIPShortCut->cNumericFieldNames);
296 :
297 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
298 11 : GlobalNames::VerifyUniqueBaseboardName(
299 22 : state, cCMO_BBRadiator_Water_Design, state.dataIPShortCut->cAlphaArgs(1), ErrorsFound, cCMO_BBRadiator_Water_Design + " Name");
300 :
301 11 : thisHWBaseboardDesign.designName = state.dataIPShortCut->cAlphaArgs(1); // Name of this baseboard design object
302 11 : HWBaseboardDesignNames(BaseboardDesignNum) = thisHWBaseboardDesign.designName;
303 :
304 : // Determine HW radiant baseboard heating design capacity sizing method
305 11 : thisHWBaseboardDesign.HeatingCapMethod = static_cast<DataSizing::DesignSizingType>(
306 11 : getEnumValue(DataSizing::DesignSizingTypeNamesUC, state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
307 11 : if (thisHWBaseboardDesign.HeatingCapMethod == DataSizing::DesignSizingType::CapacityPerFloorArea) {
308 0 : if (!state.dataIPShortCut->lNumericFieldBlanks(iHeatCapacityPerFloorAreaNumericNum)) {
309 0 : thisHWBaseboardDesign.ScaledHeatingCapacity = state.dataIPShortCut->rNumericArgs(iHeatCapacityPerFloorAreaNumericNum);
310 0 : if (thisHWBaseboardDesign.ScaledHeatingCapacity <= 0.0) {
311 0 : ShowSevereError(state, format("{} = {}", state.dataIPShortCut->cCurrentModuleObject, thisHWBaseboardDesign.designName));
312 0 : ShowContinueError(state,
313 0 : format("Input for {} = {}",
314 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
315 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
316 0 : ShowContinueError(state,
317 0 : format("Illegal {} = {:.7T}",
318 0 : state.dataIPShortCut->cNumericFieldNames(iHeatCapacityPerFloorAreaNumericNum),
319 0 : state.dataIPShortCut->rNumericArgs(iHeatCapacityPerFloorAreaNumericNum)));
320 0 : ErrorsFound = true;
321 0 : } else if (thisHWBaseboardDesign.ScaledHeatingCapacity == DataSizing::AutoSize) {
322 0 : ShowSevereError(state, format("{} = {}", state.dataIPShortCut->cCurrentModuleObject, thisHWBaseboardDesign.designName));
323 0 : ShowContinueError(state,
324 0 : format("Input for {} = {}",
325 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
326 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
327 0 : ShowContinueError(
328 0 : state, format("Illegal {} = Autosize", state.dataIPShortCut->cNumericFieldNames(iHeatCapacityPerFloorAreaNumericNum)));
329 0 : ErrorsFound = true;
330 : }
331 : } else {
332 0 : ShowSevereError(state, format("{} = {}", state.dataIPShortCut->cCurrentModuleObject, thisHWBaseboardDesign.designName));
333 0 : ShowContinueError(state,
334 0 : format("Input for {} = {}",
335 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
336 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
337 0 : ShowContinueError(
338 : state,
339 0 : format("Blank field not allowed for {}", state.dataIPShortCut->cNumericFieldNames(iHeatCapacityPerFloorAreaNumericNum)));
340 0 : ErrorsFound = true;
341 : }
342 11 : } else if (thisHWBaseboardDesign.HeatingCapMethod == DataSizing::DesignSizingType::FractionOfAutosizedHeatingCapacity) {
343 0 : if (!state.dataIPShortCut->lNumericFieldBlanks(iHeatFracOfAutosizedCapacityNumericNum)) {
344 0 : thisHWBaseboardDesign.ScaledHeatingCapacity = state.dataIPShortCut->rNumericArgs(iHeatFracOfAutosizedCapacityNumericNum);
345 0 : if (thisHWBaseboardDesign.ScaledHeatingCapacity < 0.0) {
346 0 : ShowSevereError(state, format("{} = {}", state.dataIPShortCut->cCurrentModuleObject, thisHWBaseboardDesign.designName));
347 0 : ShowContinueError(state,
348 0 : format("Illegal {} = {:.7T}",
349 0 : state.dataIPShortCut->cNumericFieldNames(iHeatFracOfAutosizedCapacityNumericNum),
350 0 : state.dataIPShortCut->rNumericArgs(iHeatFracOfAutosizedCapacityNumericNum)));
351 0 : ErrorsFound = true;
352 : }
353 : } else {
354 0 : ShowSevereError(state, format("{} = {}", state.dataIPShortCut->cCurrentModuleObject, thisHWBaseboardDesign.designName));
355 0 : ShowContinueError(state,
356 0 : format("Input for {} = {}",
357 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
358 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
359 0 : ShowContinueError(
360 : state,
361 0 : format("Blank field not allowed for {}", state.dataIPShortCut->cNumericFieldNames(iHeatFracOfAutosizedCapacityNumericNum)));
362 0 : ErrorsFound = true;
363 : }
364 : }
365 :
366 11 : thisHWBaseboardDesign.Offset = state.dataIPShortCut->rNumericArgs(3);
367 : // Set default convergence tolerance
368 11 : if (thisHWBaseboardDesign.Offset <= 0.0) {
369 0 : ShowWarningError(state,
370 0 : format("{}{}=\"{}\", {} was less than the allowable minimum.",
371 : RoutineName,
372 : cCMO_BBRadiator_Water_Design,
373 0 : thisHWBaseboardDesign.designName,
374 0 : state.dataIPShortCut->cNumericFieldNames(3)));
375 0 : ShowContinueError(state, format("...reset to a default value=[{:.2R}].", MaxFraction));
376 0 : thisHWBaseboardDesign.Offset = 0.001;
377 : }
378 :
379 11 : thisHWBaseboardDesign.FracRadiant = state.dataIPShortCut->rNumericArgs(4);
380 11 : if (thisHWBaseboardDesign.FracRadiant < MinFraction) {
381 0 : ShowWarningError(state,
382 0 : format("{}{}=\"{}\", {} was lower than the allowable minimum.",
383 : RoutineName,
384 : cCMO_BBRadiator_Water,
385 0 : thisHWBaseboardDesign.designName,
386 0 : state.dataIPShortCut->cNumericFieldNames(4)));
387 0 : ShowContinueError(state, format("...reset to minimum value=[{:.2R}].", MinFraction));
388 0 : thisHWBaseboardDesign.FracRadiant = MinFraction;
389 : }
390 11 : if (thisHWBaseboardDesign.FracRadiant > MaxFraction) {
391 0 : ShowWarningError(state,
392 0 : format("{}{}=\"{}\", {} was higher than the allowable maximum.",
393 : RoutineName,
394 : cCMO_BBRadiator_Water,
395 0 : thisHWBaseboardDesign.designName,
396 0 : state.dataIPShortCut->cNumericFieldNames(4)));
397 0 : ShowContinueError(state, format("...reset to maximum value=[{:.2R}].", MaxFraction));
398 0 : thisHWBaseboardDesign.FracRadiant = MaxFraction;
399 : }
400 :
401 11 : thisHWBaseboardDesign.FracDistribPerson = state.dataIPShortCut->rNumericArgs(5);
402 11 : if (thisHWBaseboardDesign.FracDistribPerson < MinFraction) {
403 0 : ShowWarningError(state,
404 0 : format("{}{}=\"{}\", {} was lower than the allowable minimum.",
405 : RoutineName,
406 : cCMO_BBRadiator_Water,
407 0 : thisHWBaseboardDesign.designName,
408 0 : state.dataIPShortCut->cNumericFieldNames(5)));
409 0 : ShowContinueError(state, format("...reset to minimum value=[{:.3R}].", MinFraction));
410 0 : thisHWBaseboardDesign.FracDistribPerson = MinFraction;
411 : }
412 11 : if (thisHWBaseboardDesign.FracDistribPerson > MaxFraction) {
413 0 : ShowWarningError(state,
414 0 : format("{}{}=\"{}\", {} was higher than the allowable maximum.",
415 : RoutineName,
416 : cCMO_BBRadiator_Water,
417 0 : thisHWBaseboardDesign.designName,
418 0 : state.dataIPShortCut->cNumericFieldNames(5)));
419 0 : ShowContinueError(state, format("...reset to maximum value=[{:.3R}].", MaxFraction));
420 0 : thisHWBaseboardDesign.FracDistribPerson = MaxFraction;
421 : }
422 : }
423 :
424 : // Get the data from the user input related to baseboard heaters
425 24 : for (BaseboardNum = 1; BaseboardNum <= NumHWBaseboards; ++BaseboardNum) {
426 17 : auto &thisHWBaseboard = state.dataHWBaseboardRad->HWBaseboard(BaseboardNum);
427 17 : auto &HWBaseboardNumericFields = state.dataHWBaseboardRad->HWBaseboardNumericFields(BaseboardNum);
428 :
429 34 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
430 : cCMO_BBRadiator_Water,
431 : BaseboardNum,
432 17 : state.dataIPShortCut->cAlphaArgs,
433 : NumAlphas,
434 17 : state.dataIPShortCut->rNumericArgs,
435 : NumNumbers,
436 : IOStat,
437 17 : state.dataIPShortCut->lNumericFieldBlanks,
438 17 : state.dataIPShortCut->lAlphaFieldBlanks,
439 17 : state.dataIPShortCut->cAlphaFieldNames,
440 17 : state.dataIPShortCut->cNumericFieldNames);
441 :
442 17 : HWBaseboardNumericFields.FieldNames.allocate(NumNumbers);
443 17 : HWBaseboardNumericFields.FieldNames = state.dataIPShortCut->cNumericFieldNames;
444 :
445 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
446 17 : GlobalNames::VerifyUniqueBaseboardName(
447 34 : state, cCMO_BBRadiator_Water, state.dataIPShortCut->cAlphaArgs(1), ErrorsFound, cCMO_BBRadiator_Water + " Name");
448 :
449 17 : thisHWBaseboard.Name = state.dataIPShortCut->cAlphaArgs(1); // Name of this baseboard
450 17 : thisHWBaseboard.EquipType = DataPlant::PlantEquipmentType::Baseboard_Rad_Conv_Water; //'ZoneHVAC:Baseboard:RadiantConvective:Water'
451 :
452 17 : thisHWBaseboard.designObjectName = state.dataIPShortCut->cAlphaArgs(2); // Name of the design object for this baseboard
453 17 : thisHWBaseboard.DesignObjectPtr = Util::FindItemInList(thisHWBaseboard.designObjectName, HWBaseboardDesignNames);
454 : HWBaseboardDesignData &HWBaseboardDesignDataObject =
455 17 : state.dataHWBaseboardRad->HWBaseboardDesignObject(thisHWBaseboard.DesignObjectPtr); // Contains the data for the design object
456 :
457 : // Get schedule
458 17 : if (state.dataIPShortCut->lAlphaFieldBlanks(3)) {
459 5 : thisHWBaseboard.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
460 : } else {
461 12 : thisHWBaseboard.SchedPtr = ScheduleManager::GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(3));
462 12 : if (thisHWBaseboard.SchedPtr == 0) {
463 0 : ShowSevereError(state,
464 0 : format("{}{}=\"{}\", {}=\"{}\" not found.",
465 : RoutineName,
466 : cCMO_BBRadiator_Water,
467 0 : state.dataIPShortCut->cAlphaArgs(1),
468 0 : state.dataIPShortCut->cAlphaFieldNames(3),
469 0 : state.dataIPShortCut->cAlphaArgs(3)));
470 0 : ErrorsFound = true;
471 : }
472 : }
473 :
474 : // Get inlet node number
475 17 : thisHWBaseboard.WaterInletNode = GetOnlySingleNode(state,
476 17 : state.dataIPShortCut->cAlphaArgs(4),
477 : ErrorsFound,
478 : DataLoopNode::ConnectionObjectType::ZoneHVACBaseboardRadiantConvectiveWater,
479 17 : state.dataIPShortCut->cAlphaArgs(1),
480 : DataLoopNode::NodeFluidType::Water,
481 : DataLoopNode::ConnectionType::Inlet,
482 : NodeInputManager::CompFluidStream::Primary,
483 : DataLoopNode::ObjectIsNotParent);
484 :
485 : // Get outlet node number
486 17 : thisHWBaseboard.WaterOutletNode = GetOnlySingleNode(state,
487 17 : state.dataIPShortCut->cAlphaArgs(5),
488 : ErrorsFound,
489 : DataLoopNode::ConnectionObjectType::ZoneHVACBaseboardRadiantConvectiveWater,
490 17 : state.dataIPShortCut->cAlphaArgs(1),
491 : DataLoopNode::NodeFluidType::Water,
492 : DataLoopNode::ConnectionType::Outlet,
493 : NodeInputManager::CompFluidStream::Primary,
494 : DataLoopNode::ObjectIsNotParent);
495 34 : BranchNodeConnections::TestCompSet(state,
496 : cCMO_BBRadiator_Water,
497 17 : state.dataIPShortCut->cAlphaArgs(1),
498 17 : state.dataIPShortCut->cAlphaArgs(4),
499 17 : state.dataIPShortCut->cAlphaArgs(5),
500 : "Hot Water Nodes");
501 :
502 17 : thisHWBaseboard.WaterTempAvg = state.dataIPShortCut->rNumericArgs(1);
503 17 : if (thisHWBaseboard.WaterTempAvg > MaxWaterTempAvg + 0.001) {
504 0 : ShowWarningError(state,
505 0 : format("{}{}=\"{}\", {} was higher than the allowable maximum.",
506 : RoutineName,
507 : cCMO_BBRadiator_Water,
508 0 : state.dataIPShortCut->cAlphaArgs(1),
509 0 : state.dataIPShortCut->cNumericFieldNames(1)));
510 0 : ShowContinueError(state, format("...reset to maximum value=[{:.2R}].", MaxWaterTempAvg));
511 0 : thisHWBaseboard.WaterTempAvg = MaxWaterTempAvg;
512 17 : } else if (thisHWBaseboard.WaterTempAvg < MinWaterTempAvg - 0.001) {
513 0 : ShowWarningError(state,
514 0 : format("{}{}=\"{}\", {} was lower than the allowable minimum.",
515 : RoutineName,
516 : cCMO_BBRadiator_Water,
517 0 : state.dataIPShortCut->cAlphaArgs(1),
518 0 : state.dataIPShortCut->cNumericFieldNames(1)));
519 0 : ShowContinueError(state, format("...reset to minimum value=[{:.2R}].", MinWaterTempAvg));
520 0 : thisHWBaseboard.WaterTempAvg = MinWaterTempAvg;
521 : }
522 :
523 17 : thisHWBaseboard.WaterMassFlowRateStd = state.dataIPShortCut->rNumericArgs(2);
524 17 : if (thisHWBaseboard.WaterMassFlowRateStd < LowWaterMassFlowRate - 0.0001 ||
525 17 : thisHWBaseboard.WaterMassFlowRateStd > HighWaterMassFlowRate + 0.0001) {
526 0 : ShowWarningError(state,
527 0 : format("{}{}=\"{}\", {} is an invalid Standard Water mass flow rate.",
528 : RoutineName,
529 : cCMO_BBRadiator_Water,
530 0 : state.dataIPShortCut->cAlphaArgs(1),
531 0 : state.dataIPShortCut->cNumericFieldNames(2)));
532 0 : ShowContinueError(state, format("...reset to a default value=[{:.1R}].", WaterMassFlowDefault));
533 0 : thisHWBaseboard.WaterMassFlowRateStd = WaterMassFlowDefault;
534 : }
535 :
536 : // Determine HW radiant baseboard heating design capacity sizing method
537 17 : thisHWBaseboard.HeatingCapMethod = static_cast<int>(HWBaseboardDesignDataObject.HeatingCapMethod);
538 17 : if (thisHWBaseboard.HeatingCapMethod == DataSizing::HeatingDesignCapacity) {
539 17 : if (!state.dataIPShortCut->lNumericFieldBlanks(iHeatDesignCapacityNumericNum)) {
540 17 : thisHWBaseboard.ScaledHeatingCapacity = state.dataIPShortCut->rNumericArgs(iHeatDesignCapacityNumericNum);
541 17 : if (thisHWBaseboard.ScaledHeatingCapacity < 0.0 && thisHWBaseboard.ScaledHeatingCapacity != DataSizing::AutoSize) {
542 0 : ShowSevereError(state, format("{} = {}", state.dataIPShortCut->cCurrentModuleObject, thisHWBaseboard.Name));
543 0 : ShowContinueError(state,
544 0 : format("Illegal {} = {:.7T}",
545 0 : state.dataIPShortCut->cNumericFieldNames(iHeatDesignCapacityNumericNum),
546 0 : state.dataIPShortCut->rNumericArgs(iHeatDesignCapacityNumericNum)));
547 0 : ErrorsFound = true;
548 : }
549 : } else {
550 0 : ShowSevereError(state, format("{} = {}", state.dataIPShortCut->cCurrentModuleObject, thisHWBaseboard.Name));
551 0 : ShowContinueError(state,
552 0 : format("Input for {} = {}",
553 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
554 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
555 0 : ShowContinueError(
556 0 : state, format("Blank field not allowed for {}", state.dataIPShortCut->cNumericFieldNames(iHeatDesignCapacityNumericNum)));
557 0 : ErrorsFound = true;
558 : }
559 0 : } else if (thisHWBaseboard.HeatingCapMethod == DataSizing::CapacityPerFloorArea) {
560 0 : thisHWBaseboard.ScaledHeatingCapacity = HWBaseboardDesignDataObject.ScaledHeatingCapacity;
561 :
562 0 : } else if (thisHWBaseboard.HeatingCapMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
563 0 : thisHWBaseboard.ScaledHeatingCapacity = HWBaseboardDesignDataObject.ScaledHeatingCapacity;
564 :
565 : } else {
566 0 : ShowSevereError(state, format("{} = {}", state.dataIPShortCut->cCurrentModuleObject, thisHWBaseboard.Name));
567 0 : ShowContinueError(state,
568 0 : format("Illegal {} = {}",
569 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
570 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
571 0 : ErrorsFound = true;
572 : }
573 :
574 17 : thisHWBaseboard.WaterVolFlowRateMax = state.dataIPShortCut->rNumericArgs(4);
575 17 : if (std::abs(thisHWBaseboard.WaterVolFlowRateMax) <= MinWaterFlowRate) {
576 0 : ShowWarningError(state,
577 0 : format("{}{}=\"{}\", {} was less than the allowable minimum.",
578 : RoutineName,
579 : cCMO_BBRadiator_Water,
580 0 : state.dataIPShortCut->cAlphaArgs(1),
581 0 : state.dataIPShortCut->cNumericFieldNames(4)));
582 0 : ShowContinueError(state, format("...reset to minimum value=[{:.2R}].", MinWaterFlowRate));
583 0 : thisHWBaseboard.WaterVolFlowRateMax = MinWaterFlowRate;
584 17 : } else if (thisHWBaseboard.WaterVolFlowRateMax > MaxWaterFlowRate) {
585 0 : ShowWarningError(state,
586 0 : format("{}{}=\"{}\", {} was higher than the allowable maximum.",
587 : RoutineName,
588 : cCMO_BBRadiator_Water,
589 0 : state.dataIPShortCut->cAlphaArgs(1),
590 0 : state.dataIPShortCut->cNumericFieldNames(4)));
591 0 : ShowContinueError(state, format("...reset to maximum value=[{:.2R}].", MaxWaterFlowRate));
592 0 : thisHWBaseboard.WaterVolFlowRateMax = MaxWaterFlowRate;
593 : }
594 :
595 : // Remaining fraction is added to the zone as convective heat transfer
596 17 : if (HWBaseboardDesignDataObject.FracRadiant > MaxFraction) {
597 0 : ShowWarningError(state,
598 0 : format("{}{}=\"{}\", Fraction Radiant was higher than the allowable maximum.",
599 : RoutineName,
600 : cCMO_BBRadiator_Water,
601 0 : state.dataIPShortCut->cAlphaArgs(1)));
602 0 : HWBaseboardDesignDataObject.FracRadiant = MaxFraction;
603 0 : thisHWBaseboard.FracConvect = 0.0;
604 : } else {
605 17 : thisHWBaseboard.FracConvect = 1.0 - HWBaseboardDesignDataObject.FracRadiant;
606 : }
607 :
608 17 : thisHWBaseboard.TotSurfToDistrib = NumNumbers - 4;
609 : // IF (thisHWBaseboard%TotSurfToDistrib > MaxDistribSurfaces) THEN
610 : // CALL ShowWarningError(state, RoutineName//cCMO_BBRadiator_Water//'="'//TRIM(state.dataIPShortCut->cAlphaArgs(1))// &
611 : // '", the number of surface/radiant fraction groups entered was higher than the allowable maximum.')
612 : // CALL ShowContinueError(state, '...only the maximum value=['//TRIM(RoundSigDigits(MaxDistribSurfaces))// &
613 : // '] will be processed.')
614 : // thisHWBaseboard%TotSurfToDistrib = MaxDistribSurfaces
615 : // END IF
616 17 : if ((thisHWBaseboard.TotSurfToDistrib < MinDistribSurfaces) && (HWBaseboardDesignDataObject.FracRadiant > MinFraction)) {
617 0 : ShowSevereError(state,
618 0 : std::string{RoutineName} + cCMO_BBRadiator_Water + "=\"" + state.dataIPShortCut->cAlphaArgs(1) +
619 : "\", the number of surface/radiant fraction groups entered was less than the allowable minimum.");
620 0 : ShowContinueError(state, format("...the minimum that must be entered=[{}].", MinDistribSurfaces));
621 0 : ErrorsFound = true;
622 0 : thisHWBaseboard.TotSurfToDistrib = 0; // error
623 : }
624 :
625 17 : thisHWBaseboard.SurfacePtr.allocate(thisHWBaseboard.TotSurfToDistrib);
626 17 : thisHWBaseboard.SurfacePtr = 0;
627 17 : thisHWBaseboard.FracDistribToSurf.allocate(thisHWBaseboard.TotSurfToDistrib);
628 17 : thisHWBaseboard.FracDistribToSurf = 0.0;
629 :
630 17 : thisHWBaseboard.ZonePtr =
631 17 : DataZoneEquipment::GetZoneEquipControlledZoneNum(state, DataZoneEquipment::ZoneEquipType::BaseboardWater, thisHWBaseboard.Name);
632 :
633 17 : Real64 AllFracsSummed = HWBaseboardDesignDataObject.FracDistribPerson;
634 53 : for (SurfNum = 1; SurfNum <= thisHWBaseboard.TotSurfToDistrib; ++SurfNum) {
635 72 : thisHWBaseboard.SurfacePtr(SurfNum) =
636 36 : HeatBalanceIntRadExchange::GetRadiantSystemSurface(state,
637 : cCMO_BBRadiator_Water,
638 36 : thisHWBaseboard.Name,
639 : thisHWBaseboard.ZonePtr,
640 36 : state.dataIPShortCut->cAlphaArgs(SurfNum + 5),
641 : ErrorsFound);
642 36 : thisHWBaseboard.FracDistribToSurf(SurfNum) = state.dataIPShortCut->rNumericArgs(SurfNum + 4);
643 36 : if (thisHWBaseboard.FracDistribToSurf(SurfNum) > MaxFraction) {
644 0 : ShowWarningError(state,
645 0 : format("{}{}=\"{}\", {}was greater than the allowable maximum.",
646 : RoutineName,
647 : cCMO_BBRadiator_Water,
648 0 : state.dataIPShortCut->cAlphaArgs(1),
649 0 : state.dataIPShortCut->cNumericFieldNames(SurfNum + 4)));
650 0 : ShowContinueError(state, format("...reset to maximum value=[{:.2R}].", MaxFraction));
651 0 : thisHWBaseboard.TotSurfToDistrib = MaxFraction;
652 : }
653 36 : if (thisHWBaseboard.FracDistribToSurf(SurfNum) < MinFraction) {
654 0 : ShowWarningError(state,
655 0 : format("{}{}=\"{}\", {}was less than the allowable minimum.",
656 : RoutineName,
657 : cCMO_BBRadiator_Water,
658 0 : state.dataIPShortCut->cAlphaArgs(1),
659 0 : state.dataIPShortCut->cNumericFieldNames(SurfNum + 4)));
660 0 : ShowContinueError(state, format("...reset to maximum value=[{:.2R}].", MinFraction));
661 0 : thisHWBaseboard.TotSurfToDistrib = MinFraction;
662 : }
663 36 : if (thisHWBaseboard.SurfacePtr(SurfNum) != 0) {
664 36 : state.dataSurface->surfIntConv(thisHWBaseboard.SurfacePtr(SurfNum)).getsRadiantHeat = true;
665 36 : state.dataSurface->allGetsRadiantHeatSurfaceList.emplace_back(thisHWBaseboard.SurfacePtr(SurfNum));
666 : }
667 :
668 36 : AllFracsSummed += thisHWBaseboard.FracDistribToSurf(SurfNum);
669 : } // Surfaces
670 :
671 17 : if (AllFracsSummed > (MaxFraction + 0.01)) {
672 0 : ShowSevereError(state,
673 0 : format("{}{}=\"{}\", Summed radiant fractions for people + surface groups > 1.0",
674 : RoutineName,
675 : cCMO_BBRadiator_Water,
676 0 : state.dataIPShortCut->cAlphaArgs(1)));
677 0 : ErrorsFound = true;
678 : }
679 17 : if ((AllFracsSummed < (MaxFraction - 0.01)) &&
680 5 : (HWBaseboardDesignDataObject.FracRadiant >
681 : MinFraction)) { // User didn't distribute all of the | radiation warn that some will be lost
682 0 : ShowWarningError(state,
683 0 : format("{}{}=\"{}\", Summed radiant fractions for people + surface groups < 1.0",
684 : RoutineName,
685 : cCMO_BBRadiator_Water,
686 0 : state.dataIPShortCut->cAlphaArgs(1)));
687 0 : ShowContinueError(state, "The rest of the radiant energy delivered by the baseboard heater will be lost");
688 : }
689 : }
690 :
691 7 : if (ErrorsFound) {
692 0 : ShowFatalError(state, format("{}{}Errors found getting input. Program terminates.", RoutineName, cCMO_BBRadiator_Water));
693 : }
694 :
695 : // Setup Report variables for the Coils
696 24 : for (BaseboardNum = 1; BaseboardNum <= NumHWBaseboards; ++BaseboardNum) {
697 : // CurrentModuleObject='ZoneHVAC:Baseboard:RadiantConvective:Water'
698 17 : auto &thisHWBaseboard = state.dataHWBaseboardRad->HWBaseboard(BaseboardNum);
699 34 : SetupOutputVariable(state,
700 : "Baseboard Total Heating Rate",
701 : Constant::Units::W,
702 17 : thisHWBaseboard.TotPower,
703 : OutputProcessor::TimeStepType::System,
704 : OutputProcessor::StoreType::Average,
705 17 : thisHWBaseboard.Name);
706 :
707 34 : SetupOutputVariable(state,
708 : "Baseboard Convective Heating Rate",
709 : Constant::Units::W,
710 17 : thisHWBaseboard.ConvPower,
711 : OutputProcessor::TimeStepType::System,
712 : OutputProcessor::StoreType::Average,
713 17 : thisHWBaseboard.Name);
714 34 : SetupOutputVariable(state,
715 : "Baseboard Radiant Heating Rate",
716 : Constant::Units::W,
717 17 : thisHWBaseboard.RadPower,
718 : OutputProcessor::TimeStepType::System,
719 : OutputProcessor::StoreType::Average,
720 17 : thisHWBaseboard.Name);
721 34 : SetupOutputVariable(state,
722 : "Baseboard Total Heating Energy",
723 : Constant::Units::J,
724 17 : thisHWBaseboard.TotEnergy,
725 : OutputProcessor::TimeStepType::System,
726 : OutputProcessor::StoreType::Sum,
727 17 : thisHWBaseboard.Name,
728 : Constant::eResource::EnergyTransfer,
729 : OutputProcessor::Group::HVAC,
730 : OutputProcessor::EndUseCat::Baseboard);
731 :
732 34 : SetupOutputVariable(state,
733 : "Baseboard Convective Heating Energy",
734 : Constant::Units::J,
735 17 : thisHWBaseboard.ConvEnergy,
736 : OutputProcessor::TimeStepType::System,
737 : OutputProcessor::StoreType::Sum,
738 17 : thisHWBaseboard.Name);
739 34 : SetupOutputVariable(state,
740 : "Baseboard Radiant Heating Energy",
741 : Constant::Units::J,
742 17 : thisHWBaseboard.RadEnergy,
743 : OutputProcessor::TimeStepType::System,
744 : OutputProcessor::StoreType::Sum,
745 17 : thisHWBaseboard.Name);
746 34 : SetupOutputVariable(state,
747 : "Baseboard Hot Water Energy",
748 : Constant::Units::J,
749 17 : thisHWBaseboard.Energy,
750 : OutputProcessor::TimeStepType::System,
751 : OutputProcessor::StoreType::Sum,
752 17 : thisHWBaseboard.Name,
753 : Constant::eResource::PlantLoopHeatingDemand,
754 : OutputProcessor::Group::HVAC,
755 : OutputProcessor::EndUseCat::Baseboard);
756 34 : SetupOutputVariable(state,
757 : "Baseboard Hot Water Mass Flow Rate",
758 : Constant::Units::kg_s,
759 17 : thisHWBaseboard.WaterMassFlowRate,
760 : OutputProcessor::TimeStepType::System,
761 : OutputProcessor::StoreType::Average,
762 17 : thisHWBaseboard.Name);
763 34 : SetupOutputVariable(state,
764 : "Baseboard Air Mass Flow Rate",
765 : Constant::Units::kg_s,
766 17 : thisHWBaseboard.AirMassFlowRate,
767 : OutputProcessor::TimeStepType::System,
768 : OutputProcessor::StoreType::Average,
769 17 : thisHWBaseboard.Name);
770 34 : SetupOutputVariable(state,
771 : "Baseboard Air Inlet Temperature",
772 : Constant::Units::C,
773 17 : thisHWBaseboard.AirInletTemp,
774 : OutputProcessor::TimeStepType::System,
775 : OutputProcessor::StoreType::Average,
776 17 : thisHWBaseboard.Name);
777 34 : SetupOutputVariable(state,
778 : "Baseboard Air Outlet Temperature",
779 : Constant::Units::C,
780 17 : thisHWBaseboard.AirOutletTemp,
781 : OutputProcessor::TimeStepType::System,
782 : OutputProcessor::StoreType::Average,
783 17 : thisHWBaseboard.Name);
784 34 : SetupOutputVariable(state,
785 : "Baseboard Water Inlet Temperature",
786 : Constant::Units::C,
787 17 : thisHWBaseboard.WaterInletTemp,
788 : OutputProcessor::TimeStepType::System,
789 : OutputProcessor::StoreType::Average,
790 17 : thisHWBaseboard.Name);
791 34 : SetupOutputVariable(state,
792 : "Baseboard Water Outlet Temperature",
793 : Constant::Units::C,
794 17 : thisHWBaseboard.WaterOutletTemp,
795 : OutputProcessor::TimeStepType::System,
796 : OutputProcessor::StoreType::Average,
797 17 : thisHWBaseboard.Name);
798 : }
799 7 : }
800 :
801 88831 : void InitHWBaseboard(EnergyPlusData &state, int const BaseboardNum, int const ControlledZoneNum, bool const FirstHVACIteration)
802 : {
803 :
804 : // SUBROUTINE INFORMATION:
805 : // AUTHOR Russ Taylor
806 : // Rick Strand
807 : // DATE WRITTEN Nov 1997
808 : // Feb 2001
809 : // MODIFIED Aug 2007 Daeho Kang (Add radiant component)
810 : // Sept 2010 Brent Griffith (plant interactions)
811 :
812 : // PURPOSE OF THIS SUBROUTINE:
813 : // This subroutine initializes the baseboard units, and determines the UA values during simulation.
814 :
815 : // METHODOLOGY EMPLOYED:
816 : // The initialization subrotines both in high temperature radiant radiator
817 : // and convective only baseboard radiator are combined and modified. In addition,
818 : // an UA value calculation by LMTD method is added.
819 : // The heater is assumed to be crossflow with both fluids unmixed.
820 :
821 : // REFERENCES:
822 : // 1. Incropera and DeWitt, Fundamentals of Heat and Mass Transfer
823 : // Chapter 11.3, p. 510, eq. 11.15 and 11.17
824 : // 2. I=B=R Ratings for Baseboards, Baseboard Radiation, Finned Tube (Commercial) Radiation,
825 : // and Indirect Fired Water Heaters, January 2007 Edition
826 :
827 88831 : Real64 constexpr Constant(0.0062); // Constant of linear equation for air mass flow rate
828 88831 : Real64 constexpr Coeff(0.0000275); // Correlation coefficient to capacity
829 : static constexpr std::string_view RoutineName("BaseboardRadiatorWater:InitHWBaseboard");
830 :
831 : int WaterInletNode;
832 : Real64 rho; // local fluid density
833 : Real64 Cp; // local fluid specific heat
834 :
835 88831 : int NumHWBaseboards = state.dataHWBaseboardRad->NumHWBaseboards;
836 88831 : auto &HWBaseboard = state.dataHWBaseboardRad->HWBaseboard(BaseboardNum);
837 :
838 : // Do the one time initializations
839 88831 : if (state.dataHWBaseboardRad->MyOneTimeFlag) {
840 :
841 : // Initialize the environment and sizing flags
842 7 : state.dataHWBaseboardRad->MyEnvrnFlag.dimension(NumHWBaseboards, true);
843 7 : state.dataHWBaseboardRad->MySizeFlag.dimension(NumHWBaseboards, true);
844 7 : state.dataHWBaseboardRad->SetLoopIndexFlag.dimension(NumHWBaseboards, true);
845 7 : state.dataHWBaseboardRad->MyOneTimeFlag = false;
846 :
847 24 : for (auto &hWBB : state.dataHWBaseboardRad->HWBaseboard) {
848 : // Air mass flow rate is obtained from the following linear equation (reset if autosize is used)
849 : // m_dot = 0.0062 + 2.75e-05*q
850 17 : hWBB.ZeroBBSourceSumHATsurf = 0.0;
851 17 : hWBB.QBBRadSource = 0.0;
852 17 : hWBB.QBBRadSrcAvg = 0.0;
853 17 : hWBB.LastQBBRadSrc = 0.0;
854 17 : hWBB.LastSysTimeElapsed = 0.0;
855 17 : hWBB.LastTimeStepSys = 0.0;
856 17 : hWBB.AirMassFlowRateStd = Constant + Coeff * hWBB.RatedCapacity;
857 : }
858 : }
859 :
860 88831 : if (state.dataHWBaseboardRad->SetLoopIndexFlag(BaseboardNum)) {
861 17 : if (allocated(state.dataPlnt->PlantLoop)) {
862 17 : bool errFlag = false;
863 17 : PlantUtilities::ScanPlantLoopsForObject(state, HWBaseboard.Name, HWBaseboard.EquipType, HWBaseboard.plantLoc, errFlag, _, _, _, _, _);
864 17 : if (errFlag) {
865 0 : ShowFatalError(state, "InitHWBaseboard: Program terminated for previous conditions.");
866 : }
867 17 : state.dataHWBaseboardRad->SetLoopIndexFlag(BaseboardNum) = false;
868 : }
869 : }
870 :
871 88848 : if (!state.dataGlobal->SysSizingCalc && state.dataHWBaseboardRad->MySizeFlag(BaseboardNum) &&
872 17 : !state.dataHWBaseboardRad->SetLoopIndexFlag(BaseboardNum)) {
873 : // For each coil, do the sizing once
874 17 : SizeHWBaseboard(state, BaseboardNum);
875 17 : state.dataHWBaseboardRad->MySizeFlag(BaseboardNum) = false;
876 : }
877 :
878 : // Do the Begin Environment initializations
879 88831 : if (state.dataGlobal->BeginEnvrnFlag && state.dataHWBaseboardRad->MyEnvrnFlag(BaseboardNum)) {
880 : // Initialize
881 102 : WaterInletNode = HWBaseboard.WaterInletNode;
882 :
883 102 : rho = FluidProperties::GetDensityGlycol(state,
884 102 : state.dataPlnt->PlantLoop(HWBaseboard.plantLoc.loopNum).FluidName,
885 : Constant::HWInitConvTemp,
886 102 : state.dataPlnt->PlantLoop(HWBaseboard.plantLoc.loopNum).FluidIndex,
887 : RoutineName);
888 :
889 102 : HWBaseboard.WaterMassFlowRateMax = rho * HWBaseboard.WaterVolFlowRateMax;
890 :
891 102 : PlantUtilities::InitComponentNodes(state, 0.0, HWBaseboard.WaterMassFlowRateMax, HWBaseboard.WaterInletNode, HWBaseboard.WaterOutletNode);
892 :
893 102 : state.dataLoopNodes->Node(WaterInletNode).Temp = 60.0;
894 :
895 102 : Cp = FluidProperties::GetSpecificHeatGlycol(state,
896 102 : state.dataPlnt->PlantLoop(HWBaseboard.plantLoc.loopNum).FluidName,
897 102 : state.dataLoopNodes->Node(WaterInletNode).Temp,
898 102 : state.dataPlnt->PlantLoop(HWBaseboard.plantLoc.loopNum).FluidIndex,
899 : RoutineName);
900 :
901 102 : state.dataLoopNodes->Node(WaterInletNode).Enthalpy = Cp * state.dataLoopNodes->Node(WaterInletNode).Temp;
902 102 : state.dataLoopNodes->Node(WaterInletNode).Quality = 0.0;
903 102 : state.dataLoopNodes->Node(WaterInletNode).Press = 0.0;
904 102 : state.dataLoopNodes->Node(WaterInletNode).HumRat = 0.0;
905 :
906 102 : HWBaseboard.ZeroBBSourceSumHATsurf = 0.0;
907 102 : HWBaseboard.QBBRadSource = 0.0;
908 102 : HWBaseboard.QBBRadSrcAvg = 0.0;
909 102 : HWBaseboard.LastQBBRadSrc = 0.0;
910 102 : HWBaseboard.LastSysTimeElapsed = 0.0;
911 102 : HWBaseboard.LastTimeStepSys = 0.0;
912 :
913 102 : state.dataHWBaseboardRad->MyEnvrnFlag(BaseboardNum) = false;
914 : }
915 :
916 88831 : if (!state.dataGlobal->BeginEnvrnFlag) {
917 88297 : state.dataHWBaseboardRad->MyEnvrnFlag(BaseboardNum) = true;
918 : }
919 :
920 88831 : if (state.dataGlobal->BeginTimeStepFlag && FirstHVACIteration) {
921 31094 : int ZoneNum = HWBaseboard.ZonePtr;
922 31094 : HWBaseboard.ZeroBBSourceSumHATsurf = state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state);
923 31094 : HWBaseboard.QBBRadSrcAvg = 0.0;
924 31094 : HWBaseboard.LastQBBRadSrc = 0.0;
925 31094 : HWBaseboard.LastSysTimeElapsed = 0.0;
926 31094 : HWBaseboard.LastTimeStepSys = 0.0;
927 : }
928 :
929 : // Do the every time step initializations
930 88831 : WaterInletNode = HWBaseboard.WaterInletNode;
931 88831 : int ZoneNode = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
932 88831 : HWBaseboard.WaterMassFlowRate = state.dataLoopNodes->Node(WaterInletNode).MassFlowRate;
933 88831 : HWBaseboard.WaterInletTemp = state.dataLoopNodes->Node(WaterInletNode).Temp;
934 88831 : HWBaseboard.WaterInletEnthalpy = state.dataLoopNodes->Node(WaterInletNode).Enthalpy;
935 88831 : HWBaseboard.AirInletTemp = state.dataLoopNodes->Node(ZoneNode).Temp;
936 88831 : HWBaseboard.AirInletHumRat = state.dataLoopNodes->Node(ZoneNode).HumRat;
937 :
938 88831 : HWBaseboard.TotPower = 0.0;
939 88831 : HWBaseboard.Power = 0.0;
940 88831 : HWBaseboard.ConvPower = 0.0;
941 88831 : HWBaseboard.RadPower = 0.0;
942 88831 : HWBaseboard.TotEnergy = 0.0;
943 88831 : HWBaseboard.Energy = 0.0;
944 88831 : HWBaseboard.ConvEnergy = 0.0;
945 88831 : HWBaseboard.RadEnergy = 0.0;
946 88831 : }
947 :
948 17 : void SizeHWBaseboard(EnergyPlusData &state, int const BaseboardNum)
949 : {
950 :
951 : // SUBROUTINE INFORMATION:
952 : // AUTHOR Fred Buhl
953 : // DATE WRITTEN February 2002
954 : // MODIFIED August 2009 Daeho Kang (Add UA autosizing by LMTD)
955 : // Aug 2013 Daeho Kang, add component sizing table entries
956 : // July 2014, B.Nigusse, added scalable sizing
957 :
958 : // PURPOSE OF THIS SUBROUTINE:
959 : // This subroutine is for sizing hot water baseboard components
960 :
961 : // METHODOLOGY EMPLOYED:
962 : // Obtains flow rates from the zone sizing arrays and plant sizing data.
963 :
964 : // SUBROUTINE PARAMETER DEFINITIONS:
965 17 : Real64 constexpr AirInletTempStd(18.0); // I=B=R rating document
966 17 : Real64 constexpr CPAirStd(1005.0); // Average specific heat of air at between 25C and 40C in J/kg-k
967 17 : Real64 constexpr Constant(0.0062); // Constant of linear equation for air mass flow rate
968 17 : Real64 constexpr Coeff(0.0000275); // Correlation coefficient to capacity
969 : static constexpr std::string_view RoutineName("SizeHWBaseboard");
970 : static constexpr std::string_view RoutineNameFull("BaseboardRadiatorWater:SizeHWBaseboard");
971 :
972 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
973 : Real64 WaterInletTempStd;
974 : Real64 WaterOutletTempStd;
975 : Real64 AirOutletTempStd;
976 : Real64 DeltaT1;
977 : Real64 DeltaT2;
978 : Real64 LMTD;
979 : Real64 AirMassFlowRate;
980 : Real64 WaterMassFlowRateStd;
981 : Real64 rho; // local fluid density
982 : Real64 Cp; // local fluid specific heat
983 : Real64 TempSize; // autosized value of coil input field
984 :
985 17 : int PltSizHeatNum = 0;
986 17 : Real64 DesCoilLoad = 0.0;
987 17 : bool ErrorsFound = false;
988 17 : Real64 WaterVolFlowRateMaxDes = 0.0;
989 17 : Real64 WaterVolFlowRateMaxUser = 0.0;
990 17 : Real64 RatedCapacityDes = 0.0;
991 17 : state.dataSize->DataScalableCapSizingON = false;
992 :
993 17 : auto &hWBaseboard = state.dataHWBaseboardRad->HWBaseboard(BaseboardNum);
994 17 : if (state.dataSize->CurZoneEqNum > 0) {
995 17 : auto &zoneEqSizing = state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum);
996 :
997 17 : std::string CompType = cCMO_BBRadiator_Water;
998 17 : std::string CompName = hWBaseboard.Name;
999 17 : state.dataSize->DataHeatSizeRatio = 1.0;
1000 17 : state.dataSize->DataFracOfAutosizedHeatingCapacity = 1.0;
1001 17 : state.dataSize->DataZoneNumber = hWBaseboard.ZonePtr;
1002 17 : int SizingMethod = HVAC::HeatingCapacitySizing;
1003 17 : int FieldNum = 3; // IDD numeric field number where input field description is found
1004 17 : std::string SizingString = state.dataHWBaseboardRad->HWBaseboardNumericFields(BaseboardNum).FieldNames(FieldNum) + " [W]";
1005 17 : int CapSizingMethod = hWBaseboard.HeatingCapMethod;
1006 17 : zoneEqSizing.SizingMethod(SizingMethod) = CapSizingMethod;
1007 17 : if (CapSizingMethod == DataSizing::HeatingDesignCapacity || CapSizingMethod == DataSizing::CapacityPerFloorArea ||
1008 : CapSizingMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
1009 17 : if (CapSizingMethod == DataSizing::HeatingDesignCapacity) {
1010 17 : if (hWBaseboard.ScaledHeatingCapacity == DataSizing::AutoSize) {
1011 17 : CheckZoneSizing(state, CompType, CompName);
1012 17 : zoneEqSizing.HeatingCapacity = true;
1013 17 : zoneEqSizing.DesHeatingLoad = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesHeatLoad;
1014 : }
1015 17 : TempSize = hWBaseboard.ScaledHeatingCapacity;
1016 :
1017 0 : } else if (CapSizingMethod == DataSizing::CapacityPerFloorArea) {
1018 0 : zoneEqSizing.HeatingCapacity = true;
1019 0 : zoneEqSizing.DesHeatingLoad =
1020 0 : hWBaseboard.ScaledHeatingCapacity * state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
1021 0 : TempSize = zoneEqSizing.DesHeatingLoad;
1022 0 : state.dataSize->DataScalableCapSizingON = true;
1023 0 : } else if (CapSizingMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
1024 0 : CheckZoneSizing(state, CompType, CompName);
1025 0 : zoneEqSizing.HeatingCapacity = true;
1026 0 : state.dataSize->DataFracOfAutosizedHeatingCapacity = hWBaseboard.ScaledHeatingCapacity;
1027 0 : zoneEqSizing.DesHeatingLoad = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesHeatLoad;
1028 0 : TempSize = DataSizing::AutoSize;
1029 0 : state.dataSize->DataScalableCapSizingON = true;
1030 : } else {
1031 0 : TempSize = hWBaseboard.ScaledHeatingCapacity;
1032 : }
1033 17 : bool PrintFlag = false;
1034 17 : bool errorsFound = false;
1035 17 : HeatingCapacitySizer sizerHeatingCapacity;
1036 17 : sizerHeatingCapacity.overrideSizingString(SizingString);
1037 17 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
1038 17 : TempSize = sizerHeatingCapacity.size(state, TempSize, errorsFound);
1039 17 : if (hWBaseboard.ScaledHeatingCapacity == DataSizing::AutoSize) {
1040 17 : hWBaseboard.RatedCapacity = DataSizing::AutoSize;
1041 : } else {
1042 0 : hWBaseboard.RatedCapacity = TempSize;
1043 : }
1044 17 : RatedCapacityDes = TempSize;
1045 17 : state.dataSize->DataScalableCapSizingON = false;
1046 17 : }
1047 17 : }
1048 :
1049 : // find the appropriate heating Plant Sizing object
1050 17 : PltSizHeatNum = state.dataPlnt->PlantLoop(hWBaseboard.plantLoc.loopNum).PlantSizNum;
1051 :
1052 17 : if (PltSizHeatNum > 0) {
1053 17 : if (state.dataSize->CurZoneEqNum > 0) {
1054 17 : bool FlowAutoSize = false;
1055 :
1056 17 : if (hWBaseboard.WaterVolFlowRateMax == DataSizing::AutoSize) {
1057 17 : FlowAutoSize = true;
1058 : }
1059 17 : if (!FlowAutoSize && !state.dataSize->ZoneSizingRunDone) { // Simulation continue
1060 0 : if (hWBaseboard.WaterVolFlowRateMax > 0.0) {
1061 0 : BaseSizer::reportSizerOutput(state,
1062 : cCMO_BBRadiator_Water,
1063 : hWBaseboard.Name,
1064 : "User-Specified Maximum Water Flow Rate [m3/s]",
1065 : hWBaseboard.WaterVolFlowRateMax);
1066 : }
1067 : } else {
1068 17 : CheckZoneSizing(state, cCMO_BBRadiator_Water, hWBaseboard.Name);
1069 17 : DesCoilLoad = RatedCapacityDes;
1070 17 : if (DesCoilLoad >= HVAC::SmallLoad) {
1071 17 : Cp = FluidProperties::GetSpecificHeatGlycol(state,
1072 17 : state.dataPlnt->PlantLoop(hWBaseboard.plantLoc.loopNum).FluidName,
1073 : Constant::HWInitConvTemp,
1074 17 : state.dataPlnt->PlantLoop(hWBaseboard.plantLoc.loopNum).FluidIndex,
1075 : RoutineName);
1076 17 : rho = FluidProperties::GetDensityGlycol(state,
1077 17 : state.dataPlnt->PlantLoop(hWBaseboard.plantLoc.loopNum).FluidName,
1078 : Constant::HWInitConvTemp,
1079 17 : state.dataPlnt->PlantLoop(hWBaseboard.plantLoc.loopNum).FluidIndex,
1080 : RoutineName);
1081 17 : WaterVolFlowRateMaxDes = DesCoilLoad / (state.dataSize->PlantSizData(PltSizHeatNum).DeltaT * Cp * rho);
1082 : } else {
1083 0 : WaterVolFlowRateMaxDes = 0.0;
1084 : }
1085 :
1086 17 : if (FlowAutoSize) {
1087 17 : hWBaseboard.WaterVolFlowRateMax = WaterVolFlowRateMaxDes;
1088 17 : BaseSizer::reportSizerOutput(
1089 : state, cCMO_BBRadiator_Water, hWBaseboard.Name, "Design Size Maximum Water Flow Rate [m3/s]", WaterVolFlowRateMaxDes);
1090 : } else { // Hard-sized with sizing data
1091 0 : if (hWBaseboard.WaterVolFlowRateMax > 0.0 && WaterVolFlowRateMaxDes > 0.0) {
1092 0 : WaterVolFlowRateMaxUser = hWBaseboard.WaterVolFlowRateMax;
1093 0 : BaseSizer::reportSizerOutput(state,
1094 : cCMO_BBRadiator_Water,
1095 : hWBaseboard.Name,
1096 : "Design Size Maximum Water Flow Rate [m3/s]",
1097 : WaterVolFlowRateMaxDes,
1098 : "User-Specified Maximum Water Flow Rate [m3/s]",
1099 : WaterVolFlowRateMaxUser);
1100 0 : if (state.dataGlobal->DisplayExtraWarnings) {
1101 0 : if ((std::abs(WaterVolFlowRateMaxDes - WaterVolFlowRateMaxUser) / WaterVolFlowRateMaxUser) >
1102 0 : state.dataSize->AutoVsHardSizingThreshold) {
1103 0 : ShowMessage(state,
1104 0 : format("SizeHWBaseboard: Potential issue with equipment sizing for "
1105 : "ZoneHVAC:Baseboard:RadiantConvective:Water=\"{}\".",
1106 0 : hWBaseboard.Name));
1107 0 : ShowContinueError(state,
1108 0 : format("User-Specified Maximum Water Flow Rate of {:.5R} [m3/s]", WaterVolFlowRateMaxUser));
1109 0 : ShowContinueError(
1110 0 : state, format("differs from Design Size Maximum Water Flow Rate of {:.5R} [m3/s]", WaterVolFlowRateMaxDes));
1111 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1112 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1113 : }
1114 : }
1115 : }
1116 : }
1117 : }
1118 17 : if (hWBaseboard.WaterTempAvg > 0.0 && hWBaseboard.WaterMassFlowRateStd > 0.0 && hWBaseboard.RatedCapacity > 0.0) {
1119 0 : DesCoilLoad = hWBaseboard.RatedCapacity;
1120 0 : WaterMassFlowRateStd = hWBaseboard.WaterMassFlowRateStd;
1121 17 : } else if (hWBaseboard.RatedCapacity == DataSizing::AutoSize || hWBaseboard.RatedCapacity == 0.0) {
1122 17 : DesCoilLoad = RatedCapacityDes;
1123 17 : rho = FluidProperties::GetDensityGlycol(state,
1124 17 : state.dataPlnt->PlantLoop(hWBaseboard.plantLoc.loopNum).FluidName,
1125 : Constant::HWInitConvTemp,
1126 17 : state.dataPlnt->PlantLoop(hWBaseboard.plantLoc.loopNum).FluidIndex,
1127 : RoutineNameFull);
1128 17 : WaterMassFlowRateStd = hWBaseboard.WaterVolFlowRateMax * rho;
1129 : }
1130 17 : if (DesCoilLoad >= HVAC::SmallLoad) {
1131 : // Calculate UA value
1132 : // Air mass flow rate is obtained from the following linear equation
1133 : // m_dot = 0.0062 + 2.75e-05*q
1134 17 : AirMassFlowRate = Constant + Coeff * DesCoilLoad;
1135 17 : Cp = FluidProperties::GetSpecificHeatGlycol(state,
1136 17 : state.dataPlnt->PlantLoop(hWBaseboard.plantLoc.loopNum).FluidName,
1137 : hWBaseboard.WaterTempAvg,
1138 17 : state.dataPlnt->PlantLoop(hWBaseboard.plantLoc.loopNum).FluidIndex,
1139 : RoutineName);
1140 17 : WaterInletTempStd = (DesCoilLoad / (2.0 * WaterMassFlowRateStd * Cp)) + hWBaseboard.WaterTempAvg;
1141 17 : WaterOutletTempStd = std::abs((2.0 * hWBaseboard.WaterTempAvg) - WaterInletTempStd);
1142 17 : AirOutletTempStd = (DesCoilLoad / (AirMassFlowRate * CPAirStd)) + AirInletTempStd;
1143 17 : hWBaseboard.AirMassFlowRateStd = AirMassFlowRate;
1144 : // Check Ta,out < Tw,in
1145 17 : if (AirOutletTempStd >= WaterInletTempStd) {
1146 0 : ShowSevereError(state, format("SizeHWBaseboard: ZoneHVAC:Baseboard:RadiantConvective:Water=\"{}\".", hWBaseboard.Name));
1147 0 : ShowContinueError(state, "...Air Outlet temperature must be below the Water Inlet temperature");
1148 0 : ShowContinueError(
1149 : state,
1150 0 : format("...Air Outlet Temperature=[{:.2R}], Water Inlet Temperature=[{:.2R}].", AirOutletTempStd, WaterInletTempStd));
1151 0 : AirOutletTempStd = WaterInletTempStd - 0.01;
1152 0 : ShowContinueError(state, format("...Air Outlet Temperature set to [{:.2R}].", AirOutletTempStd));
1153 : }
1154 : // Check Tw,out < Ta,in
1155 17 : if (AirInletTempStd >= WaterOutletTempStd) {
1156 0 : ShowSevereError(state, format("SizeHWBaseboard: ZoneHVAC:Baseboard:RadiantConvective:Water=\"{}\".", hWBaseboard.Name));
1157 0 : ShowContinueError(state, "...Water Outlet temperature must be below the Air Inlet temperature");
1158 0 : ShowContinueError(
1159 : state,
1160 0 : format("...Air Inlet Temperature=[{:.2R}], Water Outlet Temperature=[{:.2R}].", AirInletTempStd, WaterOutletTempStd));
1161 0 : WaterOutletTempStd = AirInletTempStd + 0.01;
1162 0 : ShowContinueError(state, format("...Water Outlet Temperature set to [{:.2R}].", WaterOutletTempStd));
1163 : }
1164 : // LMTD calculation
1165 17 : DeltaT1 = WaterInletTempStd - AirOutletTempStd;
1166 17 : DeltaT2 = WaterOutletTempStd - AirInletTempStd;
1167 17 : LMTD = (DeltaT1 - DeltaT2) / (std::log(DeltaT1 / DeltaT2));
1168 17 : hWBaseboard.UA = DesCoilLoad / LMTD;
1169 : } else {
1170 0 : hWBaseboard.UA = 0.0;
1171 : }
1172 : // Report an UA value
1173 17 : BaseSizer::reportSizerOutput(state, cCMO_BBRadiator_Water, hWBaseboard.Name, "U-Factor times Area [W/C]", hWBaseboard.UA);
1174 : }
1175 : } else {
1176 : // if there is no heating Sizing:Plant object and autosizng was requested, issue an error message
1177 0 : if (hWBaseboard.WaterVolFlowRateMax == DataSizing::AutoSize || hWBaseboard.RatedCapacity == DataSizing::AutoSize ||
1178 0 : hWBaseboard.RatedCapacity == 0.0) {
1179 0 : ShowSevereError(state, "Autosizing of hot water baseboard requires a heating loop Sizing:Plant object");
1180 0 : ShowContinueError(state, format("Occurs in Hot Water Baseboard Heater={}", hWBaseboard.Name));
1181 0 : ErrorsFound = true;
1182 : }
1183 : // calculate UA from rated capacities
1184 0 : hWBaseboard.RatedCapacity = RatedCapacityDes;
1185 0 : DesCoilLoad = RatedCapacityDes;
1186 :
1187 0 : if (DesCoilLoad >= HVAC::SmallLoad) {
1188 0 : WaterMassFlowRateStd = hWBaseboard.WaterMassFlowRateStd;
1189 : // m_dot = 0.0062 + 2.75e-05*q
1190 0 : AirMassFlowRate = Constant + Coeff * DesCoilLoad;
1191 0 : Cp = FluidProperties::GetSpecificHeatGlycol(state,
1192 0 : state.dataPlnt->PlantLoop(hWBaseboard.plantLoc.loopNum).FluidName,
1193 : hWBaseboard.WaterTempAvg,
1194 0 : state.dataPlnt->PlantLoop(hWBaseboard.plantLoc.loopNum).FluidIndex,
1195 : RoutineName);
1196 0 : WaterInletTempStd = (DesCoilLoad / (2.0 * WaterMassFlowRateStd * Cp)) + hWBaseboard.WaterTempAvg;
1197 0 : WaterOutletTempStd = std::abs((2.0 * hWBaseboard.WaterTempAvg) - WaterInletTempStd);
1198 0 : AirOutletTempStd = (DesCoilLoad / (AirMassFlowRate * CPAirStd)) + AirInletTempStd;
1199 0 : hWBaseboard.AirMassFlowRateStd = AirMassFlowRate;
1200 :
1201 : // Check Ta,out < Tw,in
1202 0 : if (AirOutletTempStd >= WaterInletTempStd) {
1203 0 : ShowSevereError(state, format("SizeHWBaseboard: ZoneHVAC:Baseboard:RadiantConvective:Water=\"{}\".", hWBaseboard.Name));
1204 0 : ShowContinueError(state, "...Air Outlet temperature must be below the Water Inlet temperature");
1205 0 : ShowContinueError(
1206 0 : state, format("...Air Outlet Temperature=[{:.2R}], Water Inlet Temperature=[{:.2R}].", AirOutletTempStd, WaterInletTempStd));
1207 0 : AirOutletTempStd = WaterInletTempStd - 0.01;
1208 0 : ShowContinueError(state, format("...Air Outlet Temperature set to [{:.2R}].", AirOutletTempStd));
1209 : }
1210 : // Check Tw,out < Ta,in
1211 0 : if (AirInletTempStd >= WaterOutletTempStd) {
1212 0 : ShowSevereError(state, format("SizeHWBaseboard: ZoneHVAC:Baseboard:RadiantConvective:Water=\"{}\".", hWBaseboard.Name));
1213 0 : ShowContinueError(state, "...Water Outlet temperature must be below the Air Inlet temperature");
1214 0 : ShowContinueError(
1215 0 : state, format("...Air Inlet Temperature=[{:.2R}], Water Outlet Temperature=[{:.2R}].", AirInletTempStd, WaterOutletTempStd));
1216 0 : WaterOutletTempStd = AirInletTempStd + 0.01;
1217 0 : ShowContinueError(state, format("...Water Outlet Temperature set to [{:.2R}].", WaterOutletTempStd));
1218 : }
1219 : // LMTD calculation
1220 0 : DeltaT1 = WaterInletTempStd - AirOutletTempStd;
1221 0 : DeltaT2 = WaterOutletTempStd - AirInletTempStd;
1222 0 : LMTD = (DeltaT1 - DeltaT2) / (std::log(DeltaT1 / DeltaT2));
1223 0 : hWBaseboard.UA = DesCoilLoad / LMTD;
1224 : } else {
1225 0 : hWBaseboard.UA = 0.0;
1226 : }
1227 : // Report an UA value
1228 0 : BaseSizer::reportSizerOutput(state, cCMO_BBRadiator_Water, hWBaseboard.Name, "U-Factor times Area [W/C]", hWBaseboard.UA);
1229 : }
1230 : // save the design water flow rate for use by the water loop sizing algorithms
1231 17 : PlantUtilities::RegisterPlantCompDesignFlow(state, hWBaseboard.WaterInletNode, hWBaseboard.WaterVolFlowRateMax);
1232 :
1233 17 : if (ErrorsFound) {
1234 0 : ShowFatalError(state, "Preceding sizing errors cause program termination");
1235 : }
1236 17 : }
1237 :
1238 160405 : void CalcHWBaseboard(EnergyPlusData &state, int &BaseboardNum, Real64 &LoadMet)
1239 : {
1240 : // SUBROUTINE INFORMATION:
1241 : // AUTHOR Russ Taylor
1242 : // DATE WRITTEN Nov 1997
1243 : // MODIFIED May 2000 Fred Buhl
1244 : // Aug 2007 Daeho Kang (Add the calculation of radiant heat source)
1245 : // Sep 2011 LKL/BG - resimulate only zones needing it for Radiant systems
1246 :
1247 : // PURPOSE OF THIS SUBROUTINE:
1248 : // This subroutine calculates both the convective and radiant heat transfer rate
1249 : // in a hot water baseboard heater. The heater is assumed to be crossflowwith
1250 : // both fluids unmixed. The air flow is buoyancy driven and a constant airflow
1251 : // and a constant airflow velocity of 0.5m/s is assumed.
1252 :
1253 : // REFERENCES:
1254 : // Incropera and DeWitt, Fundamentals of Heat and Mass Transfer
1255 : // Chapter 11.4, p. 523, eq. 11.33
1256 :
1257 : // SUBROUTINE PARAMETER DEFINITIONS:
1258 160405 : Real64 constexpr MinFrac(0.0005); // Minimum fraction that delivers radiant heats to surfaces
1259 : static constexpr std::string_view RoutineName("CalcHWBaseboard");
1260 :
1261 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1262 : Real64 RadHeat;
1263 : Real64 BBHeat;
1264 : Real64 AirOutletTemp;
1265 : Real64 WaterOutletTemp;
1266 : Real64 AirMassFlowRate;
1267 : Real64 CapacitanceAir;
1268 : Real64 CapacitanceWater;
1269 : Real64 CapacitanceMax;
1270 : Real64 CapacitanceMin;
1271 : Real64 CapacityRatio;
1272 : Real64 NTU;
1273 : Real64 Effectiveness;
1274 : Real64 AA;
1275 : Real64 BB;
1276 : Real64 CC;
1277 : Real64 Cp;
1278 :
1279 160405 : auto &hWBaseboard = state.dataHWBaseboardRad->HWBaseboard(BaseboardNum);
1280 :
1281 160405 : int const ZoneNum = hWBaseboard.ZonePtr;
1282 160405 : Real64 QZnReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ZoneNum).RemainingOutputReqToHeatSP;
1283 160405 : Real64 AirInletTemp = hWBaseboard.AirInletTemp;
1284 160405 : Real64 WaterInletTemp = hWBaseboard.WaterInletTemp;
1285 160405 : Real64 WaterMassFlowRate = state.dataLoopNodes->Node(hWBaseboard.WaterInletNode).MassFlowRate;
1286 :
1287 74955 : if (QZnReq > HVAC::SmallLoad && !state.dataZoneEnergyDemand->CurDeadBandOrSetback(ZoneNum) &&
1288 235360 : (ScheduleManager::GetCurrentScheduleValue(state, hWBaseboard.SchedPtr) > 0) && (WaterMassFlowRate > 0.0)) {
1289 :
1290 : HWBaseboardDesignData const &HWBaseboardDesignDataObject{
1291 68797 : state.dataHWBaseboardRad->HWBaseboardDesignObject(hWBaseboard.DesignObjectPtr)}; // Contains the data for the design object
1292 :
1293 : // Calculate air mass flow rate
1294 68797 : AirMassFlowRate = hWBaseboard.AirMassFlowRateStd * (WaterMassFlowRate / hWBaseboard.WaterMassFlowRateMax);
1295 68797 : CapacitanceAir = Psychrometrics::PsyCpAirFnW(hWBaseboard.AirInletHumRat) * AirMassFlowRate;
1296 68797 : Cp = FluidProperties::GetSpecificHeatGlycol(state,
1297 68797 : state.dataPlnt->PlantLoop(hWBaseboard.plantLoc.loopNum).FluidName,
1298 : WaterInletTemp,
1299 68797 : state.dataPlnt->PlantLoop(hWBaseboard.plantLoc.loopNum).FluidIndex,
1300 : RoutineName);
1301 :
1302 68797 : CapacitanceWater = Cp * WaterMassFlowRate;
1303 68797 : CapacitanceMax = max(CapacitanceAir, CapacitanceWater);
1304 68797 : CapacitanceMin = min(CapacitanceAir, CapacitanceWater);
1305 68797 : CapacityRatio = CapacitanceMin / CapacitanceMax;
1306 68797 : NTU = hWBaseboard.UA / CapacitanceMin;
1307 :
1308 : // The effectiveness is given by the following formula:
1309 : // Effectiveness = 1. - EXP((1./CapacityRatio)*(NTU)**0.22*(EXP(-CapacityRatio*(NTU)**0.78)-1.))
1310 : // To prevent possible underflows (numbers smaller than the computer can handle) we must break
1311 : // the calculation up into steps and check the size of the exponential arguments.
1312 68797 : AA = -CapacityRatio * std::pow(NTU, 0.78);
1313 68797 : if (AA < -20.0) {
1314 66 : BB = 0.0;
1315 : } else {
1316 68731 : BB = std::exp(AA);
1317 : }
1318 68797 : CC = (1.0 / CapacityRatio) * std::pow(NTU, 0.22) * (BB - 1.0);
1319 68797 : if (CC < -20.0) {
1320 11 : Effectiveness = 1.0;
1321 : } else {
1322 68786 : Effectiveness = 1.0 - std::exp(CC);
1323 : }
1324 :
1325 68797 : AirOutletTemp = AirInletTemp + Effectiveness * CapacitanceMin * (WaterInletTemp - AirInletTemp) / CapacitanceAir;
1326 68797 : WaterOutletTemp = WaterInletTemp - CapacitanceAir * (AirOutletTemp - AirInletTemp) / CapacitanceWater;
1327 68797 : BBHeat = CapacitanceWater * (WaterInletTemp - WaterOutletTemp);
1328 68797 : RadHeat = BBHeat * HWBaseboardDesignDataObject.FracRadiant;
1329 68797 : hWBaseboard.QBBRadSource = RadHeat;
1330 :
1331 68797 : if (HWBaseboardDesignDataObject.FracRadiant <= MinFrac) {
1332 31186 : LoadMet = BBHeat;
1333 : } else {
1334 :
1335 : // Now, distribute the radiant energy of all systems to the appropriate surfaces, to people, and the air
1336 37611 : DistributeBBRadGains(state);
1337 : // Now "simulate" the system by recalculating the heat balances
1338 37611 : HeatBalanceSurfaceManager::CalcHeatBalanceOutsideSurf(state, ZoneNum);
1339 :
1340 37611 : HeatBalanceSurfaceManager::CalcHeatBalanceInsideSurf(state, ZoneNum);
1341 :
1342 : // Here an assumption is made regarding radiant heat transfer to people.
1343 : // While the radiant heat transfer to people array will be used by the thermal comfort
1344 : // routines, the energy transfer to people would get lost from the perspective
1345 : // of the heat balance. So, to avoid this net loss of energy which clearly
1346 : // gets added to the zones, we must account for it somehow. This assumption
1347 : // that all energy radiated to people is converted to convective energy is
1348 : // not very precise, but at least it conserves energy. The system impact to heat balance
1349 : // should include this.
1350 :
1351 37611 : LoadMet = (state.dataHeatBal->Zone(ZoneNum).sumHATsurf(state) - hWBaseboard.ZeroBBSourceSumHATsurf) +
1352 37611 : (BBHeat * hWBaseboard.FracConvect) + (RadHeat * HWBaseboardDesignDataObject.FracDistribPerson);
1353 : }
1354 68797 : hWBaseboard.WaterOutletEnthalpy = hWBaseboard.WaterInletEnthalpy - BBHeat / WaterMassFlowRate;
1355 : } else {
1356 91608 : CapacitanceWater = 0.0;
1357 91608 : CapacitanceMax = 0.0;
1358 91608 : CapacitanceMin = 0.0;
1359 91608 : NTU = 0.0;
1360 91608 : Effectiveness = 0.0;
1361 91608 : AirOutletTemp = AirInletTemp;
1362 91608 : WaterOutletTemp = WaterInletTemp;
1363 91608 : BBHeat = 0.0;
1364 91608 : LoadMet = 0.0;
1365 91608 : RadHeat = 0.0;
1366 91608 : WaterMassFlowRate = 0.0;
1367 91608 : AirMassFlowRate = 0.0;
1368 91608 : hWBaseboard.QBBRadSource = 0.0;
1369 91608 : hWBaseboard.WaterOutletEnthalpy = hWBaseboard.WaterInletEnthalpy;
1370 91608 : PlantUtilities::SetActuatedBranchFlowRate(state, WaterMassFlowRate, hWBaseboard.WaterInletNode, hWBaseboard.plantLoc, false);
1371 : }
1372 :
1373 160405 : hWBaseboard.WaterOutletTemp = WaterOutletTemp;
1374 160405 : hWBaseboard.AirOutletTemp = AirOutletTemp;
1375 160405 : hWBaseboard.WaterMassFlowRate = WaterMassFlowRate;
1376 160405 : hWBaseboard.AirMassFlowRate = AirMassFlowRate;
1377 160405 : hWBaseboard.TotPower = LoadMet;
1378 160405 : hWBaseboard.Power = BBHeat;
1379 160405 : hWBaseboard.ConvPower = BBHeat - RadHeat;
1380 160405 : hWBaseboard.RadPower = RadHeat;
1381 160405 : }
1382 :
1383 88831 : void UpdateHWBaseboard(EnergyPlusData &state, int const BaseboardNum)
1384 : {
1385 :
1386 : // SUBROUTINE INFORMATION:
1387 : // AUTHOR Russ Taylor
1388 : // Rick Strand
1389 : // DATE WRITTEN Nov 1997
1390 : // February 2001
1391 : // MODIFIED Aug 2007 Daeho Kang (Add the update of radiant source)
1392 :
1393 : // METHODOLOGY EMPLOYED:
1394 : // The update subrotines both in high temperature radiant radiator
1395 : // and convective only baseboard radiator are combined and modified.
1396 :
1397 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1398 : int WaterInletNode;
1399 : int WaterOutletNode;
1400 88831 : auto &thisHWBB = state.dataHWBaseboardRad->HWBaseboard(BaseboardNum);
1401 :
1402 88831 : if (state.dataGlobal->BeginEnvrnFlag && state.dataHWBaseboardRad->MyEnvrnFlag2) {
1403 42 : state.dataHWBaseboardRad->Iter = 0;
1404 42 : state.dataHWBaseboardRad->MyEnvrnFlag2 = false;
1405 : }
1406 88831 : if (!state.dataGlobal->BeginEnvrnFlag) {
1407 88297 : state.dataHWBaseboardRad->MyEnvrnFlag2 = true;
1408 : }
1409 :
1410 : // First, update the running average if necessary...
1411 88831 : if (thisHWBB.LastSysTimeElapsed == state.dataHVACGlobal->SysTimeElapsed) {
1412 82517 : thisHWBB.QBBRadSrcAvg -= thisHWBB.LastQBBRadSrc * thisHWBB.LastTimeStepSys / state.dataGlobal->TimeStepZone;
1413 : }
1414 : // Update the running average and the "last" values with the current values of the appropriate variables
1415 88831 : thisHWBB.QBBRadSrcAvg += thisHWBB.QBBRadSource * state.dataHVACGlobal->TimeStepSys / state.dataGlobal->TimeStepZone;
1416 :
1417 88831 : thisHWBB.LastQBBRadSrc = thisHWBB.QBBRadSource;
1418 88831 : thisHWBB.LastSysTimeElapsed = state.dataHVACGlobal->SysTimeElapsed;
1419 88831 : thisHWBB.LastTimeStepSys = state.dataHVACGlobal->TimeStepSys;
1420 :
1421 88831 : WaterInletNode = thisHWBB.WaterInletNode;
1422 88831 : WaterOutletNode = thisHWBB.WaterOutletNode;
1423 :
1424 : // Set the outlet air nodes of the Baseboard
1425 : // Set the outlet water nodes for the Coil
1426 88831 : PlantUtilities::SafeCopyPlantNode(state, WaterInletNode, WaterOutletNode);
1427 88831 : state.dataLoopNodes->Node(WaterOutletNode).Temp = thisHWBB.WaterOutletTemp;
1428 88831 : state.dataLoopNodes->Node(WaterOutletNode).Enthalpy = thisHWBB.WaterOutletEnthalpy;
1429 88831 : }
1430 :
1431 2804482 : void UpdateBBRadSourceValAvg(EnergyPlusData &state, bool &HWBaseboardSysOn) // .TRUE. if the radiant system has run this zone time step
1432 : {
1433 :
1434 : // SUBROUTINE INFORMATION:
1435 : // AUTHOR Rick Strand
1436 : // DATE WRITTEN February 2001
1437 : // MODIFIED Aug 2007 Daeho Kang (Modification only for baseboard)
1438 :
1439 : // PURPOSE OF THIS SUBROUTINE:
1440 : // To transfer the average value of the heat source over the entire
1441 : // zone time step back to the heat balance routines so that the heat
1442 : // balance algorithms can simulate one last time with the average source
1443 : // to maintain some reasonable amount of continuity and energy balance
1444 : // in the temperature and flux histories.
1445 :
1446 : // METHODOLOGY EMPLOYED:
1447 : // All of the record keeping for the average term is done in the Update
1448 : // routine so the only other thing that this subroutine does is check to
1449 : // see if the system was even on. If any average term is non-zero, then
1450 : // one or more of the radiant systems was running.
1451 :
1452 2804482 : HWBaseboardSysOn = false;
1453 :
1454 : // If there are no baseboards in this input file, just RETURN
1455 2804482 : if (state.dataHWBaseboardRad->NumHWBaseboards == 0) return;
1456 :
1457 : // If there are baseboards, then we have to check to see if this was running at all...
1458 44640 : for (auto &thisHWBaseboard : state.dataHWBaseboardRad->HWBaseboard) {
1459 31116 : thisHWBaseboard.QBBRadSource = thisHWBaseboard.QBBRadSrcAvg;
1460 31116 : if (thisHWBaseboard.QBBRadSrcAvg != 0.0) HWBaseboardSysOn = true;
1461 : }
1462 :
1463 13524 : DistributeBBRadGains(state); // QBBRadSource has been modified so we need to redistribute gains
1464 : }
1465 :
1466 51135 : void DistributeBBRadGains(EnergyPlusData &state)
1467 : {
1468 :
1469 : // SUBROUTINE INFORMATION:
1470 : // AUTHOR Rick Strand
1471 : // DATE WRITTEN February 2001
1472 : // MODIFIED Aug. 2007 Daeho Kang (Modification only for baseboard)
1473 : // April 2010 Brent Griffith, max limit to protect surface temperature calcs
1474 :
1475 : // PURPOSE OF THIS SUBROUTINE:
1476 : // To distribute the gains from the hot water basebaord heater
1477 : // as specified in the user input file. This includes distribution
1478 : // of long wavelength radiant gains to surfaces and "people."
1479 :
1480 : // METHODOLOGY EMPLOYED:
1481 : // We must cycle through all of the radiant systems because each
1482 : // surface could feel the effect of more than one radiant system.
1483 : // Note that the energy radiated to people is assumed to affect them
1484 : // but them it is assumed to be convected to the air.
1485 :
1486 : // SUBROUTINE PARAMETER DEFINITIONS:
1487 51135 : Real64 constexpr SmallestArea(0.001); // Smallest area in meters squared (to avoid a divide by zero)
1488 :
1489 : Real64 ThisSurfIntensity; // temporary for W/m2 term for rad on a surface
1490 :
1491 : // Initialize arrays
1492 157473 : for (auto &thisHWBB : state.dataHWBaseboardRad->HWBaseboard) {
1493 405012 : for (int radSurfNum = 1; radSurfNum <= thisHWBB.TotSurfToDistrib; ++radSurfNum) {
1494 298674 : int surfNum = thisHWBB.SurfacePtr(radSurfNum);
1495 298674 : state.dataHeatBalFanSys->surfQRadFromHVAC(surfNum).HWBaseboard = 0.0;
1496 : }
1497 : }
1498 51135 : state.dataHeatBalFanSys->ZoneQHWBaseboardToPerson = 0.0;
1499 :
1500 157473 : for (auto &thisHWBB : state.dataHWBaseboardRad->HWBaseboard) {
1501 : HWBaseboardDesignData const &HWBaseboardDesignDataObject =
1502 106338 : state.dataHWBaseboardRad->HWBaseboardDesignObject(thisHWBB.DesignObjectPtr); // Contains the data for the design object
1503 106338 : int ZoneNum = thisHWBB.ZonePtr;
1504 106338 : if (ZoneNum <= 0) continue;
1505 106338 : state.dataHeatBalFanSys->ZoneQHWBaseboardToPerson(ZoneNum) += thisHWBB.QBBRadSource * HWBaseboardDesignDataObject.FracDistribPerson;
1506 :
1507 405012 : for (int RadSurfNum = 1; RadSurfNum <= thisHWBB.TotSurfToDistrib; ++RadSurfNum) {
1508 298674 : int SurfNum = thisHWBB.SurfacePtr(RadSurfNum);
1509 298674 : if (state.dataSurface->Surface(SurfNum).Area > SmallestArea) {
1510 298674 : ThisSurfIntensity = (thisHWBB.QBBRadSource * thisHWBB.FracDistribToSurf(RadSurfNum) / state.dataSurface->Surface(SurfNum).Area);
1511 298674 : state.dataHeatBalFanSys->surfQRadFromHVAC(SurfNum).HWBaseboard += ThisSurfIntensity;
1512 : // CR 8074, trap for excessive intensity (throws off surface balance )
1513 298674 : if (ThisSurfIntensity > DataHeatBalFanSys::MaxRadHeatFlux) {
1514 0 : ShowSevereError(state, "DistributeBBRadGains: excessive thermal radiation heat flux intensity detected");
1515 0 : ShowContinueError(state, format("Surface = {}", state.dataSurface->Surface(SurfNum).Name));
1516 0 : ShowContinueError(state, format("Surface area = {:.3R} [m2]", state.dataSurface->Surface(SurfNum).Area));
1517 0 : ShowContinueError(state, format("Occurs in {} = {}", cCMO_BBRadiator_Water, thisHWBB.Name));
1518 0 : ShowContinueError(state, format("Radiation intensity = {:.2R} [W/m2]", ThisSurfIntensity));
1519 0 : ShowContinueError(state, format("Assign a larger surface area or more surfaces in {}", cCMO_BBRadiator_Water));
1520 0 : ShowFatalError(state, "DistributeBBRadGains: excessive thermal radiation heat flux intensity detected");
1521 : }
1522 : } else {
1523 0 : ShowSevereError(state, "DistributeBBRadGains: surface not large enough to receive thermal radiation heat flux");
1524 0 : ShowContinueError(state, format("Surface = {}", state.dataSurface->Surface(SurfNum).Name));
1525 0 : ShowContinueError(state, format("Surface area = {:.3R} [m2]", state.dataSurface->Surface(SurfNum).Area));
1526 0 : ShowContinueError(state, format("Occurs in {} = {}", cCMO_BBRadiator_Water, thisHWBB.Name));
1527 0 : ShowContinueError(state, format("Assign a larger surface area or more surfaces in {}", cCMO_BBRadiator_Water));
1528 0 : ShowFatalError(state, "DistributeBBRadGains: surface not large enough to receive thermal radiation heat flux");
1529 : }
1530 : }
1531 : }
1532 51135 : }
1533 :
1534 88831 : void ReportHWBaseboard(EnergyPlusData &state, int const BaseboardNum)
1535 : {
1536 :
1537 : // SUBROUTINE INFORMATION:
1538 : // AUTHOR Daeho Kang
1539 : // DATE WRITTEN Aug 2007
1540 :
1541 88831 : auto &thisHWBB = state.dataHWBaseboardRad->HWBaseboard(BaseboardNum);
1542 88831 : Real64 const timeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
1543 :
1544 88831 : thisHWBB.TotEnergy = thisHWBB.TotPower * timeStepSysSec;
1545 88831 : thisHWBB.Energy = thisHWBB.Power * timeStepSysSec;
1546 88831 : thisHWBB.ConvEnergy = thisHWBB.ConvPower * timeStepSysSec;
1547 88831 : thisHWBB.RadEnergy = thisHWBB.RadPower * timeStepSysSec;
1548 88831 : }
1549 :
1550 0 : void UpdateHWBaseboardPlantConnection(EnergyPlusData &state,
1551 : int const BaseboardTypeNum, // type index
1552 : std::string const &BaseboardName, // component name
1553 : [[maybe_unused]] int const EquipFlowCtrl, // Flow control mode for the equipment
1554 : [[maybe_unused]] int const LoopNum, // Plant loop index for where called from
1555 : [[maybe_unused]] const DataPlant::LoopSideLocation LoopSide, // Plant loop side index for where called from
1556 : int &CompIndex, // Chiller number pointer
1557 : [[maybe_unused]] bool const FirstHVACIteration,
1558 : bool &InitLoopEquip // If not zero, calculate the max load for operating conditions
1559 : )
1560 : {
1561 :
1562 : // SUBROUTINE INFORMATION:
1563 : // AUTHOR Brent Griffith
1564 : // DATE WRITTEN Sept. 2010
1565 :
1566 : // PURPOSE OF THIS SUBROUTINE:
1567 : // update sim routine called from plant
1568 :
1569 : // METHODOLOGY EMPLOYED:
1570 : // check input, provide comp index, call utility routines
1571 :
1572 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1573 0 : int const NumHWBaseboards = state.dataHWBaseboardRad->NumHWBaseboards;
1574 : int BaseboardNum;
1575 :
1576 : // Find the correct baseboard
1577 0 : if (CompIndex == 0) {
1578 0 : BaseboardNum = Util::FindItemInList(BaseboardName, state.dataHWBaseboardRad->HWBaseboard, &HWBaseboardParams::Name);
1579 0 : if (BaseboardNum == 0) {
1580 0 : ShowFatalError(state, format("UpdateHWBaseboardPlantConnection: Specified baseboard not valid ={}", BaseboardName));
1581 : }
1582 0 : CompIndex = BaseboardNum;
1583 : } else {
1584 0 : BaseboardNum = CompIndex;
1585 0 : if (BaseboardNum > NumHWBaseboards || BaseboardNum < 1) {
1586 0 : ShowFatalError(
1587 : state,
1588 0 : format("UpdateHWBaseboardPlantConnection: Invalid CompIndex passed={}, Number of baseboards={}, Entered baseboard name={}",
1589 : BaseboardNum,
1590 : NumHWBaseboards,
1591 : BaseboardName));
1592 : }
1593 0 : if (state.dataGlobal->KickOffSimulation) {
1594 0 : if (BaseboardName != state.dataHWBaseboardRad->HWBaseboard(BaseboardNum).Name) {
1595 0 : ShowFatalError(state,
1596 0 : format("UpdateHWBaseboardPlantConnection: Invalid CompIndex passed={}, baseboard name={}, stored baseboard Name "
1597 : "for that index={}",
1598 : BaseboardNum,
1599 : BaseboardName,
1600 0 : state.dataHWBaseboardRad->HWBaseboard(BaseboardNum).Name));
1601 : }
1602 0 : if (BaseboardTypeNum != static_cast<int>(DataPlant::PlantEquipmentType::Baseboard_Rad_Conv_Water)) {
1603 0 : ShowFatalError(state,
1604 0 : format("UpdateHWBaseboardPlantConnection: Invalid CompIndex passed={}, baseboard name={}, stored baseboard Name "
1605 : "for that index={}",
1606 : BaseboardNum,
1607 : BaseboardName,
1608 0 : DataPlant::PlantEquipTypeNames[BaseboardTypeNum]));
1609 : }
1610 : }
1611 : }
1612 :
1613 0 : if (InitLoopEquip) {
1614 0 : return;
1615 : }
1616 :
1617 0 : auto &thisHWBaseboard = state.dataHWBaseboardRad->HWBaseboard(BaseboardNum);
1618 0 : PlantUtilities::PullCompInterconnectTrigger(state,
1619 0 : thisHWBaseboard.plantLoc,
1620 0 : thisHWBaseboard.BBLoadReSimIndex,
1621 0 : thisHWBaseboard.plantLoc,
1622 : DataPlant::CriteriaType::HeatTransferRate,
1623 : thisHWBaseboard.Power);
1624 :
1625 0 : PlantUtilities::PullCompInterconnectTrigger(state,
1626 0 : thisHWBaseboard.plantLoc,
1627 0 : thisHWBaseboard.BBMassFlowReSimIndex,
1628 0 : thisHWBaseboard.plantLoc,
1629 : DataPlant::CriteriaType::MassFlowRate,
1630 : thisHWBaseboard.WaterMassFlowRate);
1631 :
1632 0 : PlantUtilities::PullCompInterconnectTrigger(state,
1633 0 : thisHWBaseboard.plantLoc,
1634 0 : thisHWBaseboard.BBInletTempFlowReSimIndex,
1635 0 : thisHWBaseboard.plantLoc,
1636 : DataPlant::CriteriaType::Temperature,
1637 : thisHWBaseboard.WaterOutletTemp);
1638 : }
1639 :
1640 : //*****************************************************************************************
1641 :
1642 : } // namespace HWBaseboardRadiator
1643 :
1644 : } // namespace EnergyPlus
|