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 :
50 : // EnergyPlus Headers
51 : #include <EnergyPlus/Autosizing/HeatingCapacitySizing.hh>
52 : #include <EnergyPlus/BaseboardElectric.hh>
53 : #include <EnergyPlus/Data/EnergyPlusData.hh>
54 : #include <EnergyPlus/DataHVACGlobals.hh>
55 : #include <EnergyPlus/DataHeatBalance.hh>
56 : #include <EnergyPlus/DataIPShortCuts.hh>
57 : #include <EnergyPlus/DataLoopNode.hh>
58 : #include <EnergyPlus/DataSizing.hh>
59 : #include <EnergyPlus/DataZoneEnergyDemands.hh>
60 : #include <EnergyPlus/DataZoneEquipment.hh>
61 : #include <EnergyPlus/GeneralRoutines.hh>
62 : #include <EnergyPlus/GlobalNames.hh>
63 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
64 : #include <EnergyPlus/OutputProcessor.hh>
65 : #include <EnergyPlus/Psychrometrics.hh>
66 : #include <EnergyPlus/ScheduleManager.hh>
67 : #include <EnergyPlus/UtilityRoutines.hh>
68 :
69 : namespace EnergyPlus {
70 :
71 : namespace BaseboardElectric {
72 : // Module containing the routines dealing with the BASEBOARD Electric HEATER
73 : // component(s).
74 :
75 : // MODULE INFORMATION: Richard Liesen
76 : // DATE WRITTEN Nov 2001
77 : // RE-ENGINEERED na
78 :
79 : // Use statements for access to subroutines in other modules
80 : using namespace ScheduleManager;
81 :
82 : // MODULE PARAMETER DEFINITIONS
83 : const char *cCMO_BBRadiator_Electric = "ZoneHVAC:Baseboard:Convective:Electric";
84 : constexpr Real64 SimpConvAirFlowSpeed(0.5); // m/s
85 :
86 316599 : void SimElectricBaseboard(EnergyPlusData &state, std::string const &EquipName, int const ControlledZoneNum, Real64 &PowerMet, int &CompIndex)
87 : {
88 :
89 : // SUBROUTINE INFORMATION:
90 : // AUTHOR Richard Liesen
91 : // DATE WRITTEN Nov 2001
92 : // MODIFIED na
93 : // RE-ENGINEERED na
94 :
95 : // PURPOSE OF THIS SUBROUTINE:
96 : // This subroutine simulates the Electric Baseboard units.
97 :
98 : int BaseboardNum; // index of unit in baseboard array
99 : Real64 QZnReq; // zone load not yet satisfied
100 :
101 316599 : if (state.dataBaseboardElectric->getInputFlag) {
102 14 : GetBaseboardInput(state);
103 14 : state.dataBaseboardElectric->getInputFlag = false;
104 : }
105 :
106 316599 : auto &baseboard = state.dataBaseboardElectric;
107 :
108 : // Find the correct Baseboard Equipment
109 316599 : if (CompIndex == 0) {
110 51 : BaseboardNum = UtilityRoutines::FindItemInList(EquipName, baseboard->baseboards, &BaseboardParams::EquipName);
111 51 : if (BaseboardNum == 0) {
112 0 : ShowFatalError(state, "SimElectricBaseboard: Unit not found=" + EquipName);
113 : }
114 51 : CompIndex = BaseboardNum;
115 : } else {
116 316548 : BaseboardNum = CompIndex;
117 316548 : int numBaseboards = (int)baseboard->baseboards.size();
118 316548 : if (BaseboardNum > numBaseboards || BaseboardNum < 1) {
119 0 : ShowFatalError(state,
120 0 : format("SimElectricBaseboard: Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
121 : BaseboardNum,
122 : numBaseboards,
123 0 : EquipName));
124 : }
125 316548 : if (baseboard->baseboards(BaseboardNum).CheckEquipName) {
126 51 : if (EquipName != baseboard->baseboards(BaseboardNum).EquipName) {
127 0 : ShowFatalError(state,
128 0 : format("SimElectricBaseboard: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
129 : BaseboardNum,
130 : EquipName,
131 0 : baseboard->baseboards(BaseboardNum).EquipName));
132 : }
133 51 : baseboard->baseboards(BaseboardNum).CheckEquipName = false;
134 : }
135 : }
136 :
137 316599 : InitBaseboard(state, BaseboardNum, ControlledZoneNum);
138 :
139 316599 : QZnReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToHeatSP;
140 :
141 : // Simulate baseboard
142 316599 : SimElectricConvective(state, BaseboardNum, QZnReq);
143 :
144 316599 : PowerMet = baseboard->baseboards(BaseboardNum).Power;
145 :
146 316599 : baseboard->baseboards(BaseboardNum).Energy =
147 316599 : baseboard->baseboards(BaseboardNum).Power * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
148 316599 : baseboard->baseboards(BaseboardNum).ElecUseLoad =
149 316599 : baseboard->baseboards(BaseboardNum).ElecUseRate * state.dataHVACGlobal->TimeStepSys * DataGlobalConstants::SecInHour;
150 316599 : }
151 :
152 14 : void GetBaseboardInput(EnergyPlusData &state)
153 : {
154 :
155 : // SUBROUTINE INFORMATION:
156 : // AUTHOR Richard Liesen
157 : // DATE WRITTEN Nov 2001
158 : // MODIFIED na
159 : // RE-ENGINEERED na
160 :
161 : // PURPOSE OF THIS SUBROUTINE:
162 : // This subroutine gets the input for the Baseboard units.
163 :
164 : // METHODOLOGY EMPLOYED:
165 : // Standard input processor calls.
166 :
167 : // Using/Aliasing
168 : using DataSizing::AutoSize;
169 : using DataSizing::CapacityPerFloorArea;
170 : using DataSizing::FractionOfAutosizedHeatingCapacity;
171 : using DataSizing::HeatingDesignCapacity;
172 : using GlobalNames::VerifyUniqueBaseboardName;
173 :
174 : // SUBROUTINE PARAMETER DEFINITIONS:
175 : static constexpr std::string_view RoutineName("GetBaseboardInput: "); // include trailing blank space
176 14 : int constexpr iHeatCAPMAlphaNum(3); // get input index to baseboard heating capacity sizing method
177 14 : int constexpr iHeatDesignCapacityNumericNum(1); // get input index to baseboard heating capacity
178 14 : int constexpr iHeatCapacityPerFloorAreaNumericNum(2); // get input index to baseboard heating capacity per floor area sizing
179 14 : int constexpr iHeatFracOfAutosizedCapacityNumericNum(
180 : 3); // get input index to baseboard heating capacity sizing as fraction of autozized heating capacity
181 :
182 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
183 : int BaseboardNum;
184 : int NumConvElecBaseboards;
185 : int ConvElecBBNum;
186 : int NumAlphas;
187 : int NumNums;
188 : int IOStat;
189 14 : bool ErrorsFound(false); // If errors detected in input
190 :
191 14 : auto &baseboard = state.dataBaseboardElectric;
192 14 : std::string_view cCurrentModuleObject = cCMO_BBRadiator_Electric;
193 :
194 14 : NumConvElecBaseboards = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
195 :
196 14 : baseboard->baseboards.allocate(NumConvElecBaseboards);
197 :
198 14 : if (NumConvElecBaseboards > 0) { // Get the data for cooling schemes
199 14 : BaseboardNum = 0;
200 65 : for (ConvElecBBNum = 1; ConvElecBBNum <= NumConvElecBaseboards; ++ConvElecBBNum) {
201 :
202 357 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
203 : cCurrentModuleObject,
204 : ConvElecBBNum,
205 51 : state.dataIPShortCut->cAlphaArgs,
206 : NumAlphas,
207 51 : state.dataIPShortCut->rNumericArgs,
208 : NumNums,
209 : IOStat,
210 51 : state.dataIPShortCut->lNumericFieldBlanks,
211 51 : state.dataIPShortCut->lAlphaFieldBlanks,
212 51 : state.dataIPShortCut->cAlphaFieldNames,
213 51 : state.dataIPShortCut->cNumericFieldNames);
214 :
215 51 : baseboard->baseboards(ConvElecBBNum).FieldNames.allocate(NumNums);
216 51 : baseboard->baseboards(ConvElecBBNum).FieldNames = "";
217 51 : baseboard->baseboards(ConvElecBBNum).FieldNames = state.dataIPShortCut->cNumericFieldNames;
218 :
219 51 : if (UtilityRoutines::IsNameEmpty(state, state.dataIPShortCut->cAlphaArgs(1), cCurrentModuleObject, ErrorsFound)) {
220 0 : continue;
221 : }
222 :
223 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
224 51 : VerifyUniqueBaseboardName(
225 102 : state, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1), ErrorsFound, format("{} Name", cCurrentModuleObject));
226 :
227 51 : ++BaseboardNum;
228 51 : auto &thisBaseboard = baseboard->baseboards(BaseboardNum);
229 51 : thisBaseboard.EquipName = state.dataIPShortCut->cAlphaArgs(1); // name of this baseboard
230 51 : thisBaseboard.EquipType = UtilityRoutines::MakeUPPERCase(cCurrentModuleObject); // the type of baseboard-rename change
231 51 : thisBaseboard.Schedule = state.dataIPShortCut->cAlphaArgs(2);
232 51 : if (state.dataIPShortCut->lAlphaFieldBlanks(2)) {
233 0 : thisBaseboard.SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
234 : } else {
235 51 : thisBaseboard.SchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(2));
236 51 : if (thisBaseboard.SchedPtr == 0) {
237 0 : ShowSevereError(state,
238 0 : format("{}{}: invalid {} entered ={} for {}= {}",
239 : RoutineName,
240 : cCurrentModuleObject,
241 0 : state.dataIPShortCut->cAlphaFieldNames(2),
242 0 : state.dataIPShortCut->cAlphaArgs(2),
243 0 : state.dataIPShortCut->cAlphaFieldNames(1),
244 0 : state.dataIPShortCut->cAlphaArgs(1)));
245 0 : ErrorsFound = true;
246 : }
247 : }
248 : // get inlet node number
249 51 : thisBaseboard.BaseboardEfficiency = state.dataIPShortCut->rNumericArgs(4);
250 :
251 : // Determine baseboard electric heating design capacity sizing method
252 51 : if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum), "HeatingDesignCapacity")) {
253 51 : thisBaseboard.HeatingCapMethod = HeatingDesignCapacity;
254 51 : if (!state.dataIPShortCut->lNumericFieldBlanks(iHeatDesignCapacityNumericNum)) {
255 51 : thisBaseboard.ScaledHeatingCapacity = state.dataIPShortCut->rNumericArgs(iHeatDesignCapacityNumericNum);
256 51 : if (thisBaseboard.ScaledHeatingCapacity < 0.0 && thisBaseboard.ScaledHeatingCapacity != AutoSize) {
257 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisBaseboard.EquipName));
258 0 : ShowContinueError(state,
259 0 : format("Illegal {} = {:.7T}",
260 0 : state.dataIPShortCut->cNumericFieldNames(iHeatDesignCapacityNumericNum),
261 0 : state.dataIPShortCut->rNumericArgs(iHeatDesignCapacityNumericNum)));
262 0 : ErrorsFound = true;
263 : }
264 : } else {
265 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisBaseboard.EquipName));
266 0 : ShowContinueError(state,
267 0 : format("Input for {} = {}",
268 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
269 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
270 0 : ShowContinueError(
271 0 : state, format("Blank field not allowed for {}", state.dataIPShortCut->cNumericFieldNames(iHeatDesignCapacityNumericNum)));
272 0 : ErrorsFound = true;
273 : }
274 0 : } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum), "CapacityPerFloorArea")) {
275 0 : thisBaseboard.HeatingCapMethod = CapacityPerFloorArea;
276 0 : if (!state.dataIPShortCut->lNumericFieldBlanks(iHeatCapacityPerFloorAreaNumericNum)) {
277 0 : thisBaseboard.ScaledHeatingCapacity = state.dataIPShortCut->rNumericArgs(iHeatCapacityPerFloorAreaNumericNum);
278 0 : if (thisBaseboard.ScaledHeatingCapacity <= 0.0) {
279 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisBaseboard.EquipName));
280 0 : ShowContinueError(state,
281 0 : format("Input for {} = {}",
282 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
283 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
284 0 : ShowContinueError(state,
285 0 : format("Illegal {} = {:.7T}",
286 0 : state.dataIPShortCut->cNumericFieldNames(iHeatCapacityPerFloorAreaNumericNum),
287 0 : state.dataIPShortCut->rNumericArgs(iHeatCapacityPerFloorAreaNumericNum)));
288 0 : ErrorsFound = true;
289 0 : } else if (thisBaseboard.ScaledHeatingCapacity == AutoSize) {
290 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisBaseboard.EquipName));
291 0 : ShowContinueError(state,
292 0 : format("Input for {} = {}",
293 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
294 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
295 0 : ShowContinueError(
296 : state,
297 0 : format("Illegal {} = AutoSize", state.dataIPShortCut->cNumericFieldNames(iHeatCapacityPerFloorAreaNumericNum)));
298 0 : ErrorsFound = true;
299 : }
300 : } else {
301 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisBaseboard.EquipName));
302 0 : ShowContinueError(state,
303 0 : format("Input for {} = {}",
304 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
305 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
306 0 : ShowContinueError(
307 : state,
308 0 : format("Blank field not allowed for {}", state.dataIPShortCut->cNumericFieldNames(iHeatCapacityPerFloorAreaNumericNum)));
309 0 : ErrorsFound = true;
310 : }
311 0 : } else if (UtilityRoutines::SameString(state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum), "FractionOfAutosizedHeatingCapacity")) {
312 0 : thisBaseboard.HeatingCapMethod = FractionOfAutosizedHeatingCapacity;
313 0 : if (!state.dataIPShortCut->lNumericFieldBlanks(iHeatFracOfAutosizedCapacityNumericNum)) {
314 0 : thisBaseboard.ScaledHeatingCapacity = state.dataIPShortCut->rNumericArgs(iHeatFracOfAutosizedCapacityNumericNum);
315 0 : if (thisBaseboard.ScaledHeatingCapacity < 0.0) {
316 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisBaseboard.EquipName));
317 0 : ShowContinueError(state,
318 0 : format("Illegal {} = {:.7T}",
319 0 : state.dataIPShortCut->cNumericFieldNames(iHeatFracOfAutosizedCapacityNumericNum),
320 0 : state.dataIPShortCut->rNumericArgs(iHeatFracOfAutosizedCapacityNumericNum)));
321 0 : ErrorsFound = true;
322 : }
323 : } else {
324 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisBaseboard.EquipName));
325 0 : ShowContinueError(state,
326 0 : format("Input for {} = {}",
327 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
328 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
329 0 : ShowContinueError(state,
330 0 : format("Blank field not allowed for {}",
331 0 : state.dataIPShortCut->cNumericFieldNames(iHeatFracOfAutosizedCapacityNumericNum)));
332 0 : ErrorsFound = true;
333 : }
334 : } else {
335 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisBaseboard.EquipName));
336 0 : ShowContinueError(state,
337 0 : format("Illegal {} = {}",
338 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
339 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
340 0 : ErrorsFound = true;
341 : }
342 :
343 51 : thisBaseboard.ZonePtr = DataZoneEquipment::GetZoneEquipControlledZoneNum(
344 : state, DataZoneEquipment::ZoneEquip::BBElectricConvective, thisBaseboard.EquipName);
345 : }
346 :
347 14 : if (ErrorsFound) {
348 0 : ShowFatalError(state, format("{} Errors found in getting input. Preceding condition(s) cause termination.", RoutineName));
349 : }
350 : }
351 :
352 65 : for (BaseboardNum = 1; BaseboardNum <= NumConvElecBaseboards; ++BaseboardNum) {
353 :
354 : // Setup Report variables for the Electric Baseboards
355 : // CurrentModuleObject='ZoneHVAC:Baseboard:Convective:Electric'
356 :
357 51 : auto &thisBaseboard = baseboard->baseboards(BaseboardNum);
358 102 : SetupOutputVariable(state,
359 : "Baseboard Total Heating Energy",
360 : OutputProcessor::Unit::J,
361 : thisBaseboard.Energy,
362 : OutputProcessor::SOVTimeStepType::System,
363 : OutputProcessor::SOVStoreType::Summed,
364 : thisBaseboard.EquipName,
365 : _,
366 : "ENERGYTRANSFER",
367 : "BASEBOARD",
368 : _,
369 51 : "System");
370 :
371 102 : SetupOutputVariable(state,
372 : "Baseboard Total Heating Rate",
373 : OutputProcessor::Unit::W,
374 : thisBaseboard.Power,
375 : OutputProcessor::SOVTimeStepType::System,
376 : OutputProcessor::SOVStoreType::Average,
377 51 : thisBaseboard.EquipName);
378 :
379 102 : SetupOutputVariable(state,
380 : "Baseboard Electricity Energy",
381 : OutputProcessor::Unit::J,
382 : thisBaseboard.ElecUseLoad,
383 : OutputProcessor::SOVTimeStepType::System,
384 : OutputProcessor::SOVStoreType::Summed,
385 : thisBaseboard.EquipName,
386 : _,
387 : "Electricity",
388 : "HEATING",
389 : _,
390 51 : "System");
391 :
392 102 : SetupOutputVariable(state,
393 : "Baseboard Electricity Rate",
394 : OutputProcessor::Unit::W,
395 : thisBaseboard.ElecUseRate,
396 : OutputProcessor::SOVTimeStepType::System,
397 : OutputProcessor::SOVStoreType::Average,
398 51 : thisBaseboard.EquipName);
399 : }
400 14 : }
401 :
402 316599 : void InitBaseboard(EnergyPlusData &state, int const BaseboardNum, int const ControlledZoneNum)
403 : {
404 :
405 : // SUBROUTINE INFORMATION:
406 : // AUTHOR Richard Liesen
407 : // DATE WRITTEN Nov 2001
408 :
409 : // PURPOSE OF THIS SUBROUTINE:
410 : // This subroutine initializes the Baseboard units during simulation.
411 :
412 316599 : auto &baseboard = state.dataBaseboardElectric;
413 :
414 316599 : if (!state.dataGlobal->SysSizingCalc && baseboard->baseboards(BaseboardNum).MySizeFlag) {
415 : // for each coil, do the sizing once.
416 51 : SizeElectricBaseboard(state, BaseboardNum);
417 51 : baseboard->baseboards(BaseboardNum).MySizeFlag = false;
418 : }
419 :
420 : // Set the reporting variables to zero at each timestep.
421 316599 : baseboard->baseboards(BaseboardNum).Energy = 0.0;
422 316599 : baseboard->baseboards(BaseboardNum).Power = 0.0;
423 316599 : baseboard->baseboards(BaseboardNum).ElecUseLoad = 0.0;
424 316599 : baseboard->baseboards(BaseboardNum).ElecUseRate = 0.0;
425 :
426 : // Do the every time step initializations
427 316599 : int ZoneNode = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
428 316599 : baseboard->baseboards(BaseboardNum).AirInletTemp = state.dataLoopNodes->Node(ZoneNode).Temp;
429 316599 : baseboard->baseboards(BaseboardNum).AirInletHumRat = state.dataLoopNodes->Node(ZoneNode).HumRat;
430 316599 : }
431 :
432 51 : void SizeElectricBaseboard(EnergyPlusData &state, int const BaseboardNum)
433 : {
434 :
435 : // SUBROUTINE INFORMATION:
436 : // AUTHOR Fred Buhl
437 : // DATE WRITTEN February 2002
438 : // MODIFIED August 2013 Daeho Kang, add component sizing table entries
439 : // July 2014, B. Nigusse, added scalable sizing
440 : // RE-ENGINEERED na
441 :
442 : // PURPOSE OF THIS SUBROUTINE:
443 : // This subroutine is for sizing electric baseboard components for which nominal capacities have not been
444 : // specified in the input.
445 :
446 : // METHODOLOGY EMPLOYED:
447 : // Obtains flow rates from the zone sizing arrays and plant sizing data. UAs are
448 : // calculated by numerically inverting the baseboard calculation routine.
449 :
450 : // Using/Aliasing
451 : using namespace DataSizing;
452 : using DataHVACGlobals::HeatingCapacitySizing;
453 :
454 : // SUBROUTINE PARAMETER DEFINITIONS:
455 : static constexpr std::string_view RoutineName("SizeElectricBaseboard");
456 :
457 51 : auto &baseboard = state.dataBaseboardElectric;
458 :
459 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
460 :
461 102 : std::string CompName; // component name
462 102 : std::string CompType; // component type
463 102 : std::string SizingString; // input field sizing description (e.g., Nominal Capacity)
464 : Real64 TempSize; // autosized value of coil input field
465 : int FieldNum; // IDD numeric field number where input field description is found
466 : int SizingMethod; // Integer representation of sizing method name (e.g., CoolingAirflowSizing, HeatingAirflowSizing, CoolingCapacitySizing,
467 : // HeatingCapacitySizing, etc.)
468 : bool PrintFlag; // TRUE when sizing information is reported in the eio file
469 : int CapSizingMethod; // capacity sizing methods (HeatingDesignCapacity, CapacityPerFloorArea, FractionOfAutosizedCoolingCapacity, and
470 : // FractionOfAutosizedHeatingCapacity )
471 :
472 51 : auto &ZoneEqSizing(state.dataSize->ZoneEqSizing);
473 :
474 51 : state.dataSize->DataScalableCapSizingON = false;
475 :
476 51 : if (state.dataSize->CurZoneEqNum > 0) {
477 :
478 51 : CompType = baseboard->baseboards(BaseboardNum).EquipType;
479 51 : CompName = baseboard->baseboards(BaseboardNum).EquipName;
480 51 : state.dataSize->DataFracOfAutosizedHeatingCapacity = 1.0;
481 51 : state.dataSize->DataZoneNumber = baseboard->baseboards(BaseboardNum).ZonePtr;
482 51 : SizingMethod = HeatingCapacitySizing;
483 51 : FieldNum = 1;
484 51 : PrintFlag = true;
485 51 : SizingString = baseboard->baseboards(BaseboardNum).FieldNames(FieldNum) + " [W]";
486 51 : CapSizingMethod = baseboard->baseboards(BaseboardNum).HeatingCapMethod;
487 51 : ZoneEqSizing(state.dataSize->CurZoneEqNum).SizingMethod(SizingMethod) = CapSizingMethod;
488 51 : if (CapSizingMethod == HeatingDesignCapacity || CapSizingMethod == CapacityPerFloorArea ||
489 : CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
490 51 : if (CapSizingMethod == HeatingDesignCapacity) {
491 51 : if (baseboard->baseboards(BaseboardNum).ScaledHeatingCapacity == AutoSize) {
492 39 : CheckZoneSizing(state, CompType, CompName);
493 39 : ZoneEqSizing(state.dataSize->CurZoneEqNum).HeatingCapacity = true;
494 39 : ZoneEqSizing(state.dataSize->CurZoneEqNum).DesHeatingLoad =
495 39 : state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesHeatLoad;
496 : }
497 51 : TempSize = baseboard->baseboards(BaseboardNum).ScaledHeatingCapacity;
498 0 : } else if (CapSizingMethod == CapacityPerFloorArea) {
499 0 : ZoneEqSizing(state.dataSize->CurZoneEqNum).HeatingCapacity = true;
500 0 : ZoneEqSizing(state.dataSize->CurZoneEqNum).DesHeatingLoad =
501 0 : baseboard->baseboards(BaseboardNum).ScaledHeatingCapacity * state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
502 0 : TempSize = ZoneEqSizing(state.dataSize->CurZoneEqNum).DesHeatingLoad;
503 0 : state.dataSize->DataScalableCapSizingON = true;
504 0 : } else if (CapSizingMethod == FractionOfAutosizedHeatingCapacity) {
505 0 : CheckZoneSizing(state, CompType, CompName);
506 0 : ZoneEqSizing(state.dataSize->CurZoneEqNum).HeatingCapacity = true;
507 0 : state.dataSize->DataFracOfAutosizedHeatingCapacity = baseboard->baseboards(BaseboardNum).ScaledHeatingCapacity;
508 0 : ZoneEqSizing(state.dataSize->CurZoneEqNum).DesHeatingLoad =
509 0 : state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesHeatLoad;
510 0 : TempSize = AutoSize;
511 0 : state.dataSize->DataScalableCapSizingON = true;
512 : } else {
513 0 : TempSize = baseboard->baseboards(BaseboardNum).ScaledHeatingCapacity;
514 : }
515 51 : bool errorsFound = false;
516 102 : HeatingCapacitySizer sizerHeatingCapacity;
517 51 : sizerHeatingCapacity.overrideSizingString(SizingString);
518 51 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
519 51 : baseboard->baseboards(BaseboardNum).NominalCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
520 51 : state.dataSize->DataScalableCapSizingON = false;
521 : }
522 : }
523 51 : }
524 :
525 316599 : void SimElectricConvective(EnergyPlusData &state, int const BaseboardNum, Real64 const LoadMet)
526 : {
527 : // SUBROUTINE INFORMATION:
528 : // AUTHOR Richard Liesen
529 : // DATE WRITTEN Nov 2001
530 : // RE-ENGINEERED na
531 :
532 : // PURPOSE OF THIS SUBROUTINE: This subroutine calculates the heat exchange rate
533 : // in a pure Electricconvective baseboard heater.
534 :
535 : // METHODOLOGY EMPLOYED:
536 : // Currently this is primarily modified from HW Convective baseboard which has connections to
537 : // a water loop and was necessary to calculate temps, flow rates and other things. This
538 : // model might be made more sophisticated and might use some of those data structures in the future
539 : // so they are left in place even though this model does not utilize them.
540 :
541 : // Using/Aliasing
542 : using DataHVACGlobals::SmallLoad;
543 : using Psychrometrics::PsyCpAirFnW;
544 :
545 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
546 : Real64 AirInletTemp;
547 : Real64 CpAir;
548 : Real64 AirMassFlowRate;
549 : Real64 CapacitanceAir;
550 : Real64 Effic;
551 : Real64 AirOutletTemp;
552 : Real64 QBBCap;
553 :
554 316599 : auto &baseboard = state.dataBaseboardElectric;
555 :
556 316599 : AirInletTemp = baseboard->baseboards(BaseboardNum).AirInletTemp;
557 316599 : CpAir = PsyCpAirFnW(baseboard->baseboards(BaseboardNum).AirInletHumRat);
558 316599 : AirMassFlowRate = SimpConvAirFlowSpeed;
559 316599 : CapacitanceAir = CpAir * AirMassFlowRate;
560 : // currently only the efficiency is used to calculate the electric consumption. There could be some
561 : // thermal loss that could be accounted for with this efficiency input.
562 316599 : Effic = baseboard->baseboards(BaseboardNum).BaseboardEfficiency;
563 :
564 316599 : if (GetCurrentScheduleValue(state, baseboard->baseboards(BaseboardNum).SchedPtr) > 0.0 && LoadMet >= SmallLoad) {
565 :
566 : // if the load exceeds the capacity than the capacity is set to the BB limit.
567 111055 : if (LoadMet > baseboard->baseboards(BaseboardNum).NominalCapacity) {
568 17893 : QBBCap = baseboard->baseboards(BaseboardNum).NominalCapacity;
569 : } else {
570 93162 : QBBCap = LoadMet;
571 : }
572 :
573 : // this could be utilized somehow or even reported so the data structures are left in place
574 111055 : AirOutletTemp = AirInletTemp + QBBCap / CapacitanceAir;
575 :
576 : // The Baseboard electric Load is calculated using the efficiency
577 111055 : baseboard->baseboards(BaseboardNum).ElecUseRate = QBBCap / Effic;
578 :
579 : } else {
580 : // if there is an off condition the BB does nothing.
581 205544 : AirOutletTemp = AirInletTemp;
582 205544 : QBBCap = 0.0;
583 205544 : baseboard->baseboards(BaseboardNum).ElecUseRate = 0.0;
584 : }
585 :
586 316599 : baseboard->baseboards(BaseboardNum).AirOutletTemp = AirOutletTemp;
587 316599 : baseboard->baseboards(BaseboardNum).Power = QBBCap;
588 316599 : }
589 :
590 : } // namespace BaseboardElectric
591 :
592 2313 : } // namespace EnergyPlus
|