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 :
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 327006 : 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 327006 : if (state.dataBaseboardElectric->getInputFlag) {
102 15 : GetBaseboardInput(state);
103 15 : state.dataBaseboardElectric->getInputFlag = false;
104 : }
105 :
106 327006 : auto &baseboard = state.dataBaseboardElectric;
107 :
108 : // Find the correct Baseboard Equipment
109 327006 : if (CompIndex == 0) {
110 61 : BaseboardNum = Util::FindItemInList(EquipName, baseboard->baseboards, &BaseboardParams::EquipName);
111 61 : if (BaseboardNum == 0) {
112 0 : ShowFatalError(state, format("SimElectricBaseboard: Unit not found={}", EquipName));
113 : }
114 61 : CompIndex = BaseboardNum;
115 : } else {
116 326945 : BaseboardNum = CompIndex;
117 326945 : int numBaseboards = (int)baseboard->baseboards.size();
118 326945 : 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 : EquipName));
124 : }
125 326945 : if (baseboard->baseboards(BaseboardNum).CheckEquipName) {
126 61 : 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 61 : baseboard->baseboards(BaseboardNum).CheckEquipName = false;
134 : }
135 : }
136 :
137 327006 : InitBaseboard(state, BaseboardNum, ControlledZoneNum);
138 :
139 327006 : QZnReq = state.dataZoneEnergyDemand->ZoneSysEnergyDemand(ControlledZoneNum).RemainingOutputReqToHeatSP;
140 :
141 : // Simulate baseboard
142 327006 : SimElectricConvective(state, BaseboardNum, QZnReq);
143 :
144 327006 : PowerMet = baseboard->baseboards(BaseboardNum).Power;
145 :
146 327006 : baseboard->baseboards(BaseboardNum).Energy = baseboard->baseboards(BaseboardNum).Power * state.dataHVACGlobal->TimeStepSysSec;
147 327006 : baseboard->baseboards(BaseboardNum).ElecUseLoad = baseboard->baseboards(BaseboardNum).ElecUseRate * state.dataHVACGlobal->TimeStepSysSec;
148 327006 : }
149 :
150 15 : void GetBaseboardInput(EnergyPlusData &state)
151 : {
152 :
153 : // SUBROUTINE INFORMATION:
154 : // AUTHOR Richard Liesen
155 : // DATE WRITTEN Nov 2001
156 : // MODIFIED na
157 : // RE-ENGINEERED na
158 :
159 : // PURPOSE OF THIS SUBROUTINE:
160 : // This subroutine gets the input for the Baseboard units.
161 :
162 : // METHODOLOGY EMPLOYED:
163 : // Standard input processor calls.
164 :
165 : // Using/Aliasing
166 : using DataSizing::AutoSize;
167 : using DataSizing::CapacityPerFloorArea;
168 : using DataSizing::FractionOfAutosizedHeatingCapacity;
169 : using DataSizing::HeatingDesignCapacity;
170 : using GlobalNames::VerifyUniqueBaseboardName;
171 :
172 : // SUBROUTINE PARAMETER DEFINITIONS:
173 : static constexpr std::string_view RoutineName("GetBaseboardInput: "); // include trailing blank space
174 15 : int constexpr iHeatCAPMAlphaNum(3); // get input index to baseboard heating capacity sizing method
175 15 : int constexpr iHeatDesignCapacityNumericNum(1); // get input index to baseboard heating capacity
176 15 : int constexpr iHeatCapacityPerFloorAreaNumericNum(2); // get input index to baseboard heating capacity per floor area sizing
177 15 : int constexpr iHeatFracOfAutosizedCapacityNumericNum(
178 : 3); // get input index to baseboard heating capacity sizing as fraction of autosized heating capacity
179 :
180 15 : auto &baseboard = state.dataBaseboardElectric;
181 15 : std::string_view cCurrentModuleObject = cCMO_BBRadiator_Electric;
182 :
183 15 : int NumConvElecBaseboards = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, cCurrentModuleObject);
184 :
185 15 : baseboard->baseboards.allocate(NumConvElecBaseboards);
186 :
187 15 : if (NumConvElecBaseboards > 0) { // Get the data for cooling schemes
188 15 : bool ErrorsFound(false); // If errors detected in input
189 15 : int NumAlphas = 0;
190 15 : int NumNums = 0;
191 15 : int IOStat = 0;
192 15 : int BaseboardNum = 0;
193 76 : for (int ConvElecBBNum = 1; ConvElecBBNum <= NumConvElecBaseboards; ++ConvElecBBNum) {
194 :
195 122 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
196 : cCurrentModuleObject,
197 : ConvElecBBNum,
198 61 : state.dataIPShortCut->cAlphaArgs,
199 : NumAlphas,
200 61 : state.dataIPShortCut->rNumericArgs,
201 : NumNums,
202 : IOStat,
203 61 : state.dataIPShortCut->lNumericFieldBlanks,
204 61 : state.dataIPShortCut->lAlphaFieldBlanks,
205 61 : state.dataIPShortCut->cAlphaFieldNames,
206 61 : state.dataIPShortCut->cNumericFieldNames);
207 :
208 61 : baseboard->baseboards(ConvElecBBNum).FieldNames.allocate(NumNums);
209 61 : baseboard->baseboards(ConvElecBBNum).FieldNames = "";
210 61 : baseboard->baseboards(ConvElecBBNum).FieldNames = state.dataIPShortCut->cNumericFieldNames;
211 :
212 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
213 61 : VerifyUniqueBaseboardName(
214 61 : state, cCurrentModuleObject, state.dataIPShortCut->cAlphaArgs(1), ErrorsFound, format("{} Name", cCurrentModuleObject));
215 :
216 61 : ++BaseboardNum;
217 61 : auto &thisBaseboard = baseboard->baseboards(BaseboardNum);
218 61 : thisBaseboard.EquipName = state.dataIPShortCut->cAlphaArgs(1); // name of this baseboard
219 61 : thisBaseboard.EquipType = Util::makeUPPER(cCurrentModuleObject); // the type of baseboard-rename change
220 61 : thisBaseboard.Schedule = state.dataIPShortCut->cAlphaArgs(2);
221 61 : if (state.dataIPShortCut->lAlphaFieldBlanks(2)) {
222 0 : thisBaseboard.SchedPtr = ScheduleManager::ScheduleAlwaysOn;
223 : } else {
224 61 : thisBaseboard.SchedPtr = GetScheduleIndex(state, state.dataIPShortCut->cAlphaArgs(2));
225 61 : if (thisBaseboard.SchedPtr == 0) {
226 0 : ShowSevereError(state,
227 0 : format("{}{}: invalid {} entered ={} for {}= {}",
228 : RoutineName,
229 : cCurrentModuleObject,
230 0 : state.dataIPShortCut->cAlphaFieldNames(2),
231 0 : state.dataIPShortCut->cAlphaArgs(2),
232 0 : state.dataIPShortCut->cAlphaFieldNames(1),
233 0 : state.dataIPShortCut->cAlphaArgs(1)));
234 0 : ErrorsFound = true;
235 : }
236 : }
237 : // get inlet node number
238 61 : thisBaseboard.BaseboardEfficiency = state.dataIPShortCut->rNumericArgs(4);
239 :
240 : // Determine baseboard electric heating design capacity sizing method
241 61 : if (Util::SameString(state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum), "HeatingDesignCapacity")) {
242 61 : thisBaseboard.HeatingCapMethod = HeatingDesignCapacity;
243 61 : if (!state.dataIPShortCut->lNumericFieldBlanks(iHeatDesignCapacityNumericNum)) {
244 61 : thisBaseboard.ScaledHeatingCapacity = state.dataIPShortCut->rNumericArgs(iHeatDesignCapacityNumericNum);
245 61 : if (thisBaseboard.ScaledHeatingCapacity < 0.0 && thisBaseboard.ScaledHeatingCapacity != AutoSize) {
246 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisBaseboard.EquipName));
247 0 : ShowContinueError(state,
248 0 : format("Illegal {} = {:.7T}",
249 0 : state.dataIPShortCut->cNumericFieldNames(iHeatDesignCapacityNumericNum),
250 0 : state.dataIPShortCut->rNumericArgs(iHeatDesignCapacityNumericNum)));
251 0 : ErrorsFound = true;
252 : }
253 : } else {
254 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisBaseboard.EquipName));
255 0 : ShowContinueError(state,
256 0 : format("Input for {} = {}",
257 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
258 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
259 0 : ShowContinueError(
260 0 : state, format("Blank field not allowed for {}", state.dataIPShortCut->cNumericFieldNames(iHeatDesignCapacityNumericNum)));
261 0 : ErrorsFound = true;
262 : }
263 0 : } else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum), "CapacityPerFloorArea")) {
264 0 : thisBaseboard.HeatingCapMethod = CapacityPerFloorArea;
265 0 : if (!state.dataIPShortCut->lNumericFieldBlanks(iHeatCapacityPerFloorAreaNumericNum)) {
266 0 : thisBaseboard.ScaledHeatingCapacity = state.dataIPShortCut->rNumericArgs(iHeatCapacityPerFloorAreaNumericNum);
267 0 : if (thisBaseboard.ScaledHeatingCapacity <= 0.0) {
268 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisBaseboard.EquipName));
269 0 : ShowContinueError(state,
270 0 : format("Input for {} = {}",
271 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
272 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
273 0 : ShowContinueError(state,
274 0 : format("Illegal {} = {:.7T}",
275 0 : state.dataIPShortCut->cNumericFieldNames(iHeatCapacityPerFloorAreaNumericNum),
276 0 : state.dataIPShortCut->rNumericArgs(iHeatCapacityPerFloorAreaNumericNum)));
277 0 : ErrorsFound = true;
278 0 : } else if (thisBaseboard.ScaledHeatingCapacity == AutoSize) {
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(
285 : state,
286 0 : format("Illegal {} = AutoSize", state.dataIPShortCut->cNumericFieldNames(iHeatCapacityPerFloorAreaNumericNum)));
287 0 : ErrorsFound = true;
288 : }
289 : } else {
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("Blank field not allowed for {}", state.dataIPShortCut->cNumericFieldNames(iHeatCapacityPerFloorAreaNumericNum)));
298 0 : ErrorsFound = true;
299 : }
300 0 : } else if (Util::SameString(state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum), "FractionOfAutosizedHeatingCapacity")) {
301 0 : thisBaseboard.HeatingCapMethod = FractionOfAutosizedHeatingCapacity;
302 0 : if (!state.dataIPShortCut->lNumericFieldBlanks(iHeatFracOfAutosizedCapacityNumericNum)) {
303 0 : thisBaseboard.ScaledHeatingCapacity = state.dataIPShortCut->rNumericArgs(iHeatFracOfAutosizedCapacityNumericNum);
304 0 : if (thisBaseboard.ScaledHeatingCapacity < 0.0) {
305 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisBaseboard.EquipName));
306 0 : ShowContinueError(state,
307 0 : format("Illegal {} = {:.7T}",
308 0 : state.dataIPShortCut->cNumericFieldNames(iHeatFracOfAutosizedCapacityNumericNum),
309 0 : state.dataIPShortCut->rNumericArgs(iHeatFracOfAutosizedCapacityNumericNum)));
310 0 : ErrorsFound = true;
311 : }
312 : } else {
313 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisBaseboard.EquipName));
314 0 : ShowContinueError(state,
315 0 : format("Input for {} = {}",
316 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
317 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
318 0 : ShowContinueError(state,
319 0 : format("Blank field not allowed for {}",
320 0 : state.dataIPShortCut->cNumericFieldNames(iHeatFracOfAutosizedCapacityNumericNum)));
321 0 : ErrorsFound = true;
322 : }
323 : } else {
324 0 : ShowSevereError(state, format("{} = {}", cCurrentModuleObject, thisBaseboard.EquipName));
325 0 : ShowContinueError(state,
326 0 : format("Illegal {} = {}",
327 0 : state.dataIPShortCut->cAlphaFieldNames(iHeatCAPMAlphaNum),
328 0 : state.dataIPShortCut->cAlphaArgs(iHeatCAPMAlphaNum)));
329 0 : ErrorsFound = true;
330 : }
331 :
332 61 : thisBaseboard.ZonePtr = DataZoneEquipment::GetZoneEquipControlledZoneNum(
333 61 : state, DataZoneEquipment::ZoneEquipType::BaseboardConvectiveElectric, thisBaseboard.EquipName);
334 : }
335 :
336 15 : if (ErrorsFound) {
337 0 : ShowFatalError(state, format("{} Errors found in getting input. Preceding condition(s) cause termination.", RoutineName));
338 : }
339 : }
340 :
341 76 : for (int BaseboardNum = 1; BaseboardNum <= NumConvElecBaseboards; ++BaseboardNum) {
342 :
343 : // Setup Report variables for the Electric Baseboards
344 : // CurrentModuleObject='ZoneHVAC:Baseboard:Convective:Electric'
345 :
346 61 : auto &thisBaseboard = baseboard->baseboards(BaseboardNum);
347 122 : SetupOutputVariable(state,
348 : "Baseboard Total Heating Energy",
349 : Constant::Units::J,
350 61 : thisBaseboard.Energy,
351 : OutputProcessor::TimeStepType::System,
352 : OutputProcessor::StoreType::Sum,
353 61 : thisBaseboard.EquipName,
354 : Constant::eResource::EnergyTransfer,
355 : OutputProcessor::Group::HVAC,
356 : OutputProcessor::EndUseCat::Baseboard);
357 :
358 122 : SetupOutputVariable(state,
359 : "Baseboard Total Heating Rate",
360 : Constant::Units::W,
361 61 : thisBaseboard.Power,
362 : OutputProcessor::TimeStepType::System,
363 : OutputProcessor::StoreType::Average,
364 61 : thisBaseboard.EquipName);
365 :
366 122 : SetupOutputVariable(state,
367 : "Baseboard Electricity Energy",
368 : Constant::Units::J,
369 61 : thisBaseboard.ElecUseLoad,
370 : OutputProcessor::TimeStepType::System,
371 : OutputProcessor::StoreType::Sum,
372 61 : thisBaseboard.EquipName,
373 : Constant::eResource::Electricity,
374 : OutputProcessor::Group::HVAC,
375 : OutputProcessor::EndUseCat::Heating);
376 :
377 122 : SetupOutputVariable(state,
378 : "Baseboard Electricity Rate",
379 : Constant::Units::W,
380 61 : thisBaseboard.ElecUseRate,
381 : OutputProcessor::TimeStepType::System,
382 : OutputProcessor::StoreType::Average,
383 61 : thisBaseboard.EquipName);
384 : }
385 15 : }
386 :
387 327006 : void InitBaseboard(EnergyPlusData &state, int const BaseboardNum, int const ControlledZoneNum)
388 : {
389 :
390 : // SUBROUTINE INFORMATION:
391 : // AUTHOR Richard Liesen
392 : // DATE WRITTEN Nov 2001
393 :
394 : // PURPOSE OF THIS SUBROUTINE:
395 : // This subroutine initializes the Baseboard units during simulation.
396 :
397 327006 : auto &baseboard = state.dataBaseboardElectric;
398 :
399 327006 : if (!state.dataGlobal->SysSizingCalc && baseboard->baseboards(BaseboardNum).MySizeFlag) {
400 : // for each coil, do the sizing once.
401 61 : SizeElectricBaseboard(state, BaseboardNum);
402 61 : baseboard->baseboards(BaseboardNum).MySizeFlag = false;
403 : }
404 :
405 : // Set the reporting variables to zero at each timestep.
406 327006 : baseboard->baseboards(BaseboardNum).Energy = 0.0;
407 327006 : baseboard->baseboards(BaseboardNum).Power = 0.0;
408 327006 : baseboard->baseboards(BaseboardNum).ElecUseLoad = 0.0;
409 327006 : baseboard->baseboards(BaseboardNum).ElecUseRate = 0.0;
410 :
411 : // Do the every time step initializations
412 327006 : int ZoneNode = state.dataZoneEquip->ZoneEquipConfig(ControlledZoneNum).ZoneNode;
413 327006 : baseboard->baseboards(BaseboardNum).AirInletTemp = state.dataLoopNodes->Node(ZoneNode).Temp;
414 327006 : baseboard->baseboards(BaseboardNum).AirInletHumRat = state.dataLoopNodes->Node(ZoneNode).HumRat;
415 327006 : }
416 :
417 61 : void SizeElectricBaseboard(EnergyPlusData &state, int const BaseboardNum)
418 : {
419 :
420 : // SUBROUTINE INFORMATION:
421 : // AUTHOR Fred Buhl
422 : // DATE WRITTEN February 2002
423 : // MODIFIED August 2013 Daeho Kang, add component sizing table entries
424 : // July 2014, B. Nigusse, added scalable sizing
425 :
426 : // PURPOSE OF THIS SUBROUTINE:
427 : // This subroutine is for sizing electric baseboard components for which nominal capacities have not been
428 : // specified in the input.
429 :
430 : // METHODOLOGY EMPLOYED:
431 : // Obtains flow rates from the zone sizing arrays and plant sizing data. UAs are
432 : // calculated by numerically inverting the baseboard calculation routine.
433 :
434 : // SUBROUTINE PARAMETER DEFINITIONS:
435 : static constexpr std::string_view RoutineName("SizeElectricBaseboard");
436 :
437 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
438 : Real64 TempSize; // autosized value of coil input field
439 61 : state.dataSize->DataScalableCapSizingON = false;
440 :
441 61 : if (state.dataSize->CurZoneEqNum > 0) {
442 61 : auto &ZoneEqSizing = state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum);
443 61 : auto &baseboard = state.dataBaseboardElectric->baseboards(BaseboardNum);
444 :
445 61 : std::string_view const CompType = baseboard.EquipType;
446 61 : std::string_view const CompName = baseboard.EquipName;
447 61 : state.dataSize->DataFracOfAutosizedHeatingCapacity = 1.0;
448 61 : state.dataSize->DataZoneNumber = baseboard.ZonePtr;
449 61 : int SizingMethod = HVAC::HeatingCapacitySizing;
450 61 : int FieldNum = 1;
451 61 : std::string const SizingString = format("{} [W]", baseboard.FieldNames(FieldNum));
452 61 : int CapSizingMethod = baseboard.HeatingCapMethod;
453 61 : ZoneEqSizing.SizingMethod(SizingMethod) = CapSizingMethod;
454 61 : if (CapSizingMethod == DataSizing::HeatingDesignCapacity || CapSizingMethod == DataSizing::CapacityPerFloorArea ||
455 : CapSizingMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
456 61 : if (CapSizingMethod == DataSizing::HeatingDesignCapacity) {
457 61 : if (baseboard.ScaledHeatingCapacity == DataSizing::AutoSize) {
458 49 : CheckZoneSizing(state, CompType, CompName);
459 49 : ZoneEqSizing.HeatingCapacity = true;
460 49 : ZoneEqSizing.DesHeatingLoad = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesHeatLoad;
461 : }
462 61 : TempSize = baseboard.ScaledHeatingCapacity;
463 0 : } else if (CapSizingMethod == DataSizing::CapacityPerFloorArea) {
464 0 : ZoneEqSizing.HeatingCapacity = true;
465 0 : ZoneEqSizing.DesHeatingLoad = baseboard.ScaledHeatingCapacity * state.dataHeatBal->Zone(state.dataSize->DataZoneNumber).FloorArea;
466 0 : TempSize = ZoneEqSizing.DesHeatingLoad;
467 0 : state.dataSize->DataScalableCapSizingON = true;
468 0 : } else if (CapSizingMethod == DataSizing::FractionOfAutosizedHeatingCapacity) {
469 0 : CheckZoneSizing(state, CompType, CompName);
470 0 : ZoneEqSizing.HeatingCapacity = true;
471 0 : state.dataSize->DataFracOfAutosizedHeatingCapacity = baseboard.ScaledHeatingCapacity;
472 0 : ZoneEqSizing.DesHeatingLoad = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).NonAirSysDesHeatLoad;
473 0 : TempSize = DataSizing::AutoSize;
474 0 : state.dataSize->DataScalableCapSizingON = true;
475 : } else {
476 0 : TempSize = baseboard.ScaledHeatingCapacity;
477 : }
478 61 : bool PrintFlag = true; // TRUE when sizing information is reported in the eio file
479 61 : bool errorsFound = false;
480 61 : HeatingCapacitySizer sizerHeatingCapacity;
481 61 : sizerHeatingCapacity.overrideSizingString(SizingString);
482 61 : sizerHeatingCapacity.initializeWithinEP(state, CompType, CompName, PrintFlag, RoutineName);
483 61 : baseboard.NominalCapacity = sizerHeatingCapacity.size(state, TempSize, errorsFound);
484 61 : state.dataSize->DataScalableCapSizingON = false;
485 61 : }
486 61 : }
487 61 : }
488 :
489 327006 : void SimElectricConvective(EnergyPlusData &state, int const BaseboardNum, Real64 const LoadMet)
490 : {
491 : // SUBROUTINE INFORMATION:
492 : // AUTHOR Richard Liesen
493 : // DATE WRITTEN Nov 2001
494 :
495 : // PURPOSE OF THIS SUBROUTINE: This subroutine calculates the heat exchange rate
496 : // in a pure Electricconvective baseboard heater.
497 :
498 : // METHODOLOGY EMPLOYED:
499 : // Currently this is primarily modified from HW Convective baseboard which has connections to
500 : // a water loop and was necessary to calculate temps, flow rates and other things. This
501 : // model might be made more sophisticated and might use some of those data structures in the future
502 : // so they are left in place even though this model does not utilize them.
503 :
504 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
505 : Real64 AirOutletTemp;
506 : Real64 QBBCap;
507 :
508 327006 : auto &baseboard = state.dataBaseboardElectric->baseboards(BaseboardNum);
509 :
510 327006 : Real64 AirInletTemp = baseboard.AirInletTemp;
511 327006 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(baseboard.AirInletHumRat);
512 327006 : Real64 AirMassFlowRate = SimpConvAirFlowSpeed;
513 327006 : Real64 CapacitanceAir = CpAir * AirMassFlowRate;
514 : // currently only the efficiency is used to calculate the electric consumption. There could be some
515 : // thermal loss that could be accounted for with this efficiency input.
516 327006 : Real64 Effic = baseboard.BaseboardEfficiency;
517 :
518 327006 : if (GetCurrentScheduleValue(state, baseboard.SchedPtr) > 0.0 && LoadMet >= HVAC::SmallLoad) {
519 :
520 : // if the load exceeds the capacity than the capacity is set to the BB limit.
521 131025 : if (LoadMet > baseboard.NominalCapacity) {
522 17896 : QBBCap = baseboard.NominalCapacity;
523 : } else {
524 113129 : QBBCap = LoadMet;
525 : }
526 :
527 : // this could be utilized somehow or even reported so the data structures are left in place
528 131025 : AirOutletTemp = AirInletTemp + QBBCap / CapacitanceAir;
529 :
530 : // The Baseboard electric Load is calculated using the efficiency
531 131025 : baseboard.ElecUseRate = QBBCap / Effic;
532 :
533 : } else {
534 : // if there is an off condition the BB does nothing.
535 195981 : AirOutletTemp = AirInletTemp;
536 195981 : QBBCap = 0.0;
537 195981 : baseboard.ElecUseRate = 0.0;
538 : }
539 :
540 327006 : baseboard.AirOutletTemp = AirOutletTemp;
541 327006 : baseboard.Power = QBBCap;
542 327006 : }
543 :
544 : } // namespace BaseboardElectric
545 :
546 : } // namespace EnergyPlus
|