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/All_Simple_Sizing.hh>
57 : #include <EnergyPlus/Autosizing/HeatingAirFlowSizing.hh>
58 : #include <EnergyPlus/BranchNodeConnections.hh>
59 : #include <EnergyPlus/Data/EnergyPlusData.hh>
60 : #include <EnergyPlus/DataContaminantBalance.hh>
61 : #include <EnergyPlus/DataEnvironment.hh>
62 : #include <EnergyPlus/DataHVACGlobals.hh>
63 : #include <EnergyPlus/DataLoopNode.hh>
64 : #include <EnergyPlus/DataSizing.hh>
65 : #include <EnergyPlus/Fans.hh>
66 : #include <EnergyPlus/FaultsManager.hh>
67 : #include <EnergyPlus/FluidProperties.hh>
68 : #include <EnergyPlus/GeneralRoutines.hh>
69 : #include <EnergyPlus/GlobalNames.hh>
70 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
71 : #include <EnergyPlus/NodeInputManager.hh>
72 : #include <EnergyPlus/OutputProcessor.hh>
73 : #include <EnergyPlus/Plant/DataPlant.hh>
74 : #include <EnergyPlus/PlantUtilities.hh>
75 : #include <EnergyPlus/Psychrometrics.hh>
76 : #include <EnergyPlus/ReportCoilSelection.hh>
77 : #include <EnergyPlus/ScheduleManager.hh>
78 : #include <EnergyPlus/SteamCoils.hh>
79 : #include <EnergyPlus/UtilityRoutines.hh>
80 :
81 : namespace EnergyPlus {
82 :
83 : namespace SteamCoils {
84 :
85 : // Module containing the SteamCoil simulation routines
86 :
87 : // MODULE INFORMATION:
88 : // AUTHOR Rahul Chillar
89 : // DATE WRITTEN Jan 2005
90 : // MODIFIED na
91 : // RE-ENGINEERED na
92 :
93 : // PURPOSE OF THIS MODULE:
94 : // To encapsulate the data and algorithms required to
95 : // manage the SteamCoil System Component.
96 :
97 : using namespace DataLoopNode;
98 : using namespace Psychrometrics;
99 :
100 : using PlantUtilities::MyPlantSizingIndex;
101 : using PlantUtilities::ScanPlantLoopsForObject;
102 : using namespace ScheduleManager;
103 :
104 : static constexpr std::string_view fluidNameSteam("STEAM");
105 : constexpr std::array<std::string_view, static_cast<int>(CoilControlType::Num)> coilControlTypeNames = {"TEMPERATURESETPOINTCONTROL",
106 : "ZONELOADCONTROL"};
107 :
108 227370 : void SimulateSteamCoilComponents(EnergyPlusData &state,
109 : std::string_view CompName,
110 : bool const FirstHVACIteration,
111 : int &CompIndex,
112 : ObjexxFCL::Optional<Real64 const> QCoilReq, // coil load to be met
113 : ObjexxFCL::Optional<Real64> QCoilActual, // coil load actually delivered returned to calling component
114 : ObjexxFCL::Optional<HVAC::FanOp const> fanOpMode,
115 : ObjexxFCL::Optional<Real64 const> PartLoadRatio)
116 : {
117 :
118 : // SUBROUTINE INFORMATION:
119 : // AUTHOR Rahul Chillar
120 : // DATE WRITTEN Jan 2005
121 : // MODIFIED na
122 : // RE-ENGINEERED na
123 :
124 : // PURPOSE OF THIS SUBROUTINE:
125 : // This subroutine manages SteamCoil component simulation.
126 :
127 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
128 : Real64 QCoilActualTemp; // coil load actually delivered returned to calling component
129 : int CoilNum; // The SteamCoil that you are currently loading input into
130 : HVAC::FanOp fanOp; // fan operating mode
131 : Real64 PartLoadFrac; // part-load fraction of heating coil
132 : Real64 QCoilReqLocal; // local required heating load optional
133 :
134 : // Obtains and Allocates SteamCoil related parameters from input file
135 227370 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
136 0 : GetSteamCoilInput(state);
137 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
138 : }
139 :
140 : // Find the correct SteamCoilNumber with the Coil Name
141 227370 : if (CompIndex == 0) {
142 16 : CoilNum = Util::FindItemInList(CompName, state.dataSteamCoils->SteamCoil);
143 16 : if (CoilNum == 0) {
144 0 : ShowFatalError(state, format("SimulateSteamCoilComponents: Coil not found={}", CompName));
145 : }
146 16 : CompIndex = CoilNum;
147 : } else {
148 227354 : CoilNum = CompIndex;
149 227354 : if (CoilNum > state.dataSteamCoils->NumSteamCoils || CoilNum < 1) {
150 0 : ShowFatalError(state,
151 0 : format("SimulateSteamCoilComponents: Invalid CompIndex passed={}, Number of Steam Coils={}, Coil name={}",
152 : CoilNum,
153 0 : state.dataSteamCoils->NumSteamCoils,
154 : CompName));
155 : }
156 227354 : if (state.dataSteamCoils->CheckEquipName(CoilNum)) {
157 20 : if (CompName != state.dataSteamCoils->SteamCoil(CoilNum).Name) {
158 0 : ShowFatalError(
159 : state,
160 0 : format("SimulateSteamCoilComponents: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
161 : CoilNum,
162 : CompName,
163 0 : state.dataSteamCoils->SteamCoil(CoilNum).Name));
164 : }
165 20 : state.dataSteamCoils->CheckEquipName(CoilNum) = false;
166 : }
167 : }
168 :
169 : // With the correct CoilNum Initialize
170 227370 : InitSteamCoil(state, CoilNum, FirstHVACIteration); // Initialize all SteamCoil related parameters
171 :
172 227370 : if (present(fanOpMode)) {
173 123623 : fanOp = fanOpMode;
174 : } else {
175 103747 : fanOp = HVAC::FanOp::Continuous;
176 : }
177 227370 : if (present(PartLoadRatio)) {
178 123623 : PartLoadFrac = PartLoadRatio;
179 : } else {
180 103747 : PartLoadFrac = 1.0;
181 : }
182 227370 : if (present(QCoilReq)) {
183 227370 : QCoilReqLocal = QCoilReq;
184 : } else {
185 0 : QCoilReqLocal = 0.0;
186 : }
187 :
188 227370 : CalcSteamAirCoil(
189 : state, CoilNum, QCoilReqLocal, QCoilActualTemp, fanOp, PartLoadFrac); // Autodesk:OPTIONAL QCoilReq used without PRESENT check
190 227370 : if (present(QCoilActual)) QCoilActual = QCoilActualTemp;
191 :
192 : // Update the current SteamCoil to the outlet nodes
193 227370 : UpdateSteamCoil(state, CoilNum);
194 :
195 : // Report the current SteamCoil
196 227370 : ReportSteamCoil(state, CoilNum);
197 227370 : }
198 :
199 : // Get Input Section of the Module
200 :
201 7 : void GetSteamCoilInput(EnergyPlusData &state)
202 : {
203 : // SUBROUTINE INFORMATION:
204 : // AUTHOR Rahul Chillar
205 : // DATE WRITTEN Jan 2005
206 : // MODIFIED na
207 : // RE-ENGINEERED na
208 :
209 : // PURPOSE OF THIS SUBROUTINE:
210 : // Obtains input data for coils and stores it in coil data structures
211 :
212 : // METHODOLOGY EMPLOYED:
213 : // Uses "Get" routines to read in data.
214 :
215 : // Using/Aliasing
216 : using BranchNodeConnections::TestCompSet;
217 : using GlobalNames::VerifyUniqueCoilName;
218 : using NodeInputManager::GetOnlySingleNode;
219 :
220 : // SUBROUTINE PARAMETER DEFINITIONS:
221 : static constexpr std::string_view RoutineName("GetSteamCoilInput: "); // include trailing blank space
222 :
223 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
224 : int CoilNum; // The SteamCoil that you are currently loading input into
225 : int NumStmHeat;
226 : int StmHeatNum;
227 : int NumAlphas;
228 : int NumNums;
229 : int IOStat;
230 7 : bool ErrorsFound(false); // If errors detected in input
231 7 : std::string CurrentModuleObject; // for ease in getting objects
232 7 : Array1D_string AlphArray; // Alpha input items for object
233 7 : Array1D_string cAlphaFields; // Alpha field names
234 7 : Array1D_string cNumericFields; // Numeric field names
235 7 : Array1D<Real64> NumArray; // Numeric input items for object
236 7 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
237 7 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
238 7 : int TotalArgs(0); // Total number of alpha and numeric arguments (max) for a
239 : // certain object in the input file
240 :
241 7 : CurrentModuleObject = "Coil:Heating:Steam";
242 7 : NumStmHeat = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, CurrentModuleObject);
243 7 : state.dataSteamCoils->NumSteamCoils = NumStmHeat;
244 7 : if (state.dataSteamCoils->NumSteamCoils > 0) {
245 7 : state.dataSteamCoils->SteamCoil.allocate(state.dataSteamCoils->NumSteamCoils);
246 7 : state.dataSteamCoils->CheckEquipName.dimension(state.dataSteamCoils->NumSteamCoils, true);
247 : }
248 :
249 7 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, CurrentModuleObject, TotalArgs, NumAlphas, NumNums);
250 7 : AlphArray.allocate(NumAlphas);
251 7 : cAlphaFields.allocate(NumAlphas);
252 7 : cNumericFields.allocate(NumNums);
253 7 : NumArray.dimension(NumNums, 0.0);
254 7 : lAlphaBlanks.dimension(NumAlphas, true);
255 7 : lNumericBlanks.dimension(NumNums, true);
256 :
257 : // Get the data for steam heating coils
258 27 : for (StmHeatNum = 1; StmHeatNum <= NumStmHeat; ++StmHeatNum) {
259 :
260 20 : CoilNum = StmHeatNum;
261 :
262 20 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
263 : CurrentModuleObject,
264 : StmHeatNum,
265 : AlphArray,
266 : NumAlphas,
267 : NumArray,
268 : NumNums,
269 : IOStat,
270 : lNumericBlanks,
271 : lAlphaBlanks,
272 : cAlphaFields,
273 : cNumericFields);
274 20 : Util::IsNameEmpty(state, AlphArray(1), CurrentModuleObject, ErrorsFound);
275 :
276 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
277 20 : VerifyUniqueCoilName(state, CurrentModuleObject, AlphArray(1), ErrorsFound, CurrentModuleObject + " Name");
278 :
279 20 : state.dataSteamCoils->SteamCoil(CoilNum).Name = AlphArray(1);
280 20 : state.dataSteamCoils->SteamCoil(CoilNum).Schedule = AlphArray(2);
281 20 : if (lAlphaBlanks(2)) {
282 0 : state.dataSteamCoils->SteamCoil(CoilNum).SchedPtr = ScheduleManager::ScheduleAlwaysOn;
283 : } else {
284 20 : state.dataSteamCoils->SteamCoil(CoilNum).SchedPtr = GetScheduleIndex(state, AlphArray(2));
285 20 : if (state.dataSteamCoils->SteamCoil(CoilNum).SchedPtr == 0) {
286 0 : ShowSevereError(state, format("{}{}=\"{}\", invalid data.", RoutineName, CurrentModuleObject, AlphArray(1)));
287 0 : ShowContinueError(state, format("{} not found={}", cAlphaFields(2), AlphArray(2)));
288 0 : ErrorsFound = true;
289 : }
290 : }
291 :
292 20 : state.dataSteamCoils->SteamCoil(CoilNum).SteamCoilTypeA = "Heating";
293 20 : state.dataSteamCoils->SteamCoil(CoilNum).CoilType = DataPlant::PlantEquipmentType::CoilSteamAirHeating;
294 20 : state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate = NumArray(1);
295 20 : state.dataSteamCoils->SteamCoil(CoilNum).DegOfSubcooling = NumArray(2);
296 20 : state.dataSteamCoils->SteamCoil(CoilNum).LoopSubcoolReturn = NumArray(3);
297 :
298 40 : state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum = GetOnlySingleNode(state,
299 20 : AlphArray(3),
300 : ErrorsFound,
301 : DataLoopNode::ConnectionObjectType::CoilHeatingSteam,
302 20 : AlphArray(1),
303 : DataLoopNode::NodeFluidType::Steam,
304 : DataLoopNode::ConnectionType::Inlet,
305 : NodeInputManager::CompFluidStream::Secondary,
306 : ObjectIsNotParent);
307 40 : state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum = GetOnlySingleNode(state,
308 20 : AlphArray(4),
309 : ErrorsFound,
310 : DataLoopNode::ConnectionObjectType::CoilHeatingSteam,
311 20 : AlphArray(1),
312 : DataLoopNode::NodeFluidType::Steam,
313 : DataLoopNode::ConnectionType::Outlet,
314 : NodeInputManager::CompFluidStream::Secondary,
315 : ObjectIsNotParent);
316 40 : state.dataSteamCoils->SteamCoil(CoilNum).AirInletNodeNum = GetOnlySingleNode(state,
317 20 : AlphArray(5),
318 : ErrorsFound,
319 : DataLoopNode::ConnectionObjectType::CoilHeatingSteam,
320 20 : AlphArray(1),
321 : DataLoopNode::NodeFluidType::Air,
322 : DataLoopNode::ConnectionType::Inlet,
323 : NodeInputManager::CompFluidStream::Primary,
324 : ObjectIsNotParent);
325 40 : state.dataSteamCoils->SteamCoil(CoilNum).AirOutletNodeNum = GetOnlySingleNode(state,
326 20 : AlphArray(6),
327 : ErrorsFound,
328 : DataLoopNode::ConnectionObjectType::CoilHeatingSteam,
329 20 : AlphArray(1),
330 : DataLoopNode::NodeFluidType::Air,
331 : DataLoopNode::ConnectionType::Outlet,
332 : NodeInputManager::CompFluidStream::Primary,
333 : ObjectIsNotParent);
334 :
335 20 : std::string controlMode = Util::makeUPPER(AlphArray(7));
336 20 : state.dataSteamCoils->SteamCoil(CoilNum).TypeOfCoil = static_cast<CoilControlType>(getEnumValue(coilControlTypeNames, controlMode));
337 :
338 20 : switch (state.dataSteamCoils->SteamCoil(CoilNum).TypeOfCoil) {
339 3 : case CoilControlType::TemperatureSetPoint:
340 6 : state.dataSteamCoils->SteamCoil(CoilNum).TempSetPointNodeNum = GetOnlySingleNode(state,
341 3 : AlphArray(8),
342 : ErrorsFound,
343 : DataLoopNode::ConnectionObjectType::CoilHeatingSteam,
344 3 : AlphArray(1),
345 : DataLoopNode::NodeFluidType::Air,
346 : DataLoopNode::ConnectionType::Sensor,
347 : NodeInputManager::CompFluidStream::Primary,
348 : ObjectIsNotParent);
349 3 : if (state.dataSteamCoils->SteamCoil(CoilNum).TempSetPointNodeNum == 0) {
350 0 : ShowSevereError(state, format("{}{} not found for {} = {}", RoutineName, cAlphaFields(8), CurrentModuleObject, AlphArray(1)));
351 0 : ShowContinueError(state, "..required for Temperature Setpoint Controlled Coils.");
352 0 : ErrorsFound = true;
353 : }
354 3 : break;
355 17 : case CoilControlType::ZoneLoadControl:
356 17 : if (!lAlphaBlanks(8)) {
357 0 : ShowWarningError(state, format("{}ZoneLoad Controlled Coil, so {} not needed", RoutineName, cAlphaFields(8)));
358 0 : ShowContinueError(state, format("for {} = {}", CurrentModuleObject, AlphArray(1)));
359 0 : state.dataSteamCoils->SteamCoil(CoilNum).TempSetPointNodeNum = 0;
360 : }
361 17 : break;
362 0 : default:
363 0 : ShowSevereError(
364 : state,
365 0 : format("{}Invalid {} [{}] specified for {} = {}", RoutineName, cAlphaFields(7), AlphArray(7), CurrentModuleObject, AlphArray(1)));
366 0 : ErrorsFound = true;
367 : }
368 :
369 20 : TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(3), AlphArray(4), "Steam Nodes");
370 20 : TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(5), AlphArray(6), "Air Nodes");
371 :
372 20 : if (state.dataSteamCoils->SteamIndex == 0 && CoilNum == 1) {
373 7 : state.dataSteamCoils->SteamIndex = FluidProperties::GetRefrigNum(state, "STEAM");
374 7 : if (state.dataSteamCoils->SteamIndex == 0) {
375 0 : ShowSevereError(state, format("{}Steam Properties for {} not found.", RoutineName, AlphArray(1)));
376 0 : ShowContinueError(state, "Steam Fluid Properties should have been included in the input file.");
377 0 : ErrorsFound = true;
378 : }
379 : }
380 :
381 20 : state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex = state.dataSteamCoils->SteamIndex;
382 20 : }
383 :
384 27 : for (CoilNum = 1; CoilNum <= NumStmHeat; ++CoilNum) {
385 :
386 : // Setup the Simple Heating Coil reporting variables
387 : // CurrentModuleObject = "Coil:Heating:Steam"
388 40 : SetupOutputVariable(state,
389 : "Heating Coil Heating Energy",
390 : Constant::Units::J,
391 20 : state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilEnergy,
392 : OutputProcessor::TimeStepType::System,
393 : OutputProcessor::StoreType::Sum,
394 20 : state.dataSteamCoils->SteamCoil(CoilNum).Name,
395 : Constant::eResource::EnergyTransfer,
396 : OutputProcessor::Group::HVAC,
397 : OutputProcessor::EndUseCat::HeatingCoils);
398 40 : SetupOutputVariable(state,
399 : "Heating Coil Heating Rate",
400 : Constant::Units::W,
401 20 : state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilRate,
402 : OutputProcessor::TimeStepType::System,
403 : OutputProcessor::StoreType::Average,
404 20 : state.dataSteamCoils->SteamCoil(CoilNum).Name);
405 40 : SetupOutputVariable(state,
406 : "Heating Coil Steam Mass Flow Rate",
407 : Constant::Units::kg_s,
408 20 : state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate,
409 : OutputProcessor::TimeStepType::System,
410 : OutputProcessor::StoreType::Average,
411 20 : state.dataSteamCoils->SteamCoil(CoilNum).Name);
412 40 : SetupOutputVariable(state,
413 : "Heating Coil Steam Inlet Temperature",
414 : Constant::Units::C,
415 20 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamTemp,
416 : OutputProcessor::TimeStepType::System,
417 : OutputProcessor::StoreType::Average,
418 20 : state.dataSteamCoils->SteamCoil(CoilNum).Name);
419 40 : SetupOutputVariable(state,
420 : "Heating Coil Steam Outlet Temperature",
421 : Constant::Units::C,
422 20 : state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamTemp,
423 : OutputProcessor::TimeStepType::System,
424 : OutputProcessor::StoreType::Average,
425 20 : state.dataSteamCoils->SteamCoil(CoilNum).Name);
426 40 : SetupOutputVariable(state,
427 : "Heating Coil Steam Trap Loss Rate",
428 : Constant::Units::W,
429 20 : state.dataSteamCoils->SteamCoil(CoilNum).LoopLoss,
430 : OutputProcessor::TimeStepType::System,
431 : OutputProcessor::StoreType::Average,
432 20 : state.dataSteamCoils->SteamCoil(CoilNum).Name);
433 : }
434 :
435 7 : if (ErrorsFound) {
436 0 : ShowFatalError(state, format("{}Errors found in getting input.", RoutineName));
437 : }
438 :
439 7 : AlphArray.deallocate();
440 7 : cAlphaFields.deallocate();
441 7 : cNumericFields.deallocate();
442 7 : NumArray.deallocate();
443 7 : lAlphaBlanks.deallocate();
444 7 : lNumericBlanks.deallocate();
445 7 : }
446 :
447 : // End of Get Input subroutines for the HB Module
448 :
449 : // Beginning Initialization Section of the Module
450 :
451 227370 : void InitSteamCoil(EnergyPlusData &state, int const CoilNum, bool const FirstHVACIteration)
452 : {
453 : // SUBROUTINE INFORMATION:
454 : // AUTHOR Rahul Chillar
455 : // DATE WRITTEN Jan 2005
456 : // MODIFIED na
457 : // RE-ENGINEERED na
458 :
459 : // PURPOSE OF THIS SUBROUTINE:
460 : // This subroutine is for initializations of the SteamCoil Components.
461 :
462 : // METHODOLOGY EMPLOYED:
463 : // Uses the status flags to trigger initializations.
464 :
465 : // REFERENCES:
466 : // na
467 :
468 : // Using/Aliasing
469 : using FluidProperties::GetSatDensityRefrig;
470 : using FluidProperties::GetSatEnthalpyRefrig;
471 : using PlantUtilities::InitComponentNodes;
472 :
473 : // Locals
474 : // SUBROUTINE ARGUMENT DEFINITIONS:
475 :
476 : // SUBROUTINE PARAMETER DEFINITIONS:
477 : static constexpr std::string_view RoutineName("InitSteamCoil");
478 :
479 : // INTERFACE BLOCK SPECIFICATIONS
480 : // na
481 :
482 : // DERIVED TYPE DEFINITIONS
483 : // na
484 :
485 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
486 : int AirInletNode;
487 : int SteamInletNode;
488 : int ControlNode;
489 : int AirOutletNode;
490 : Real64 SteamDensity;
491 : Real64 StartEnthSteam;
492 : bool errFlag;
493 :
494 227370 : if (state.dataSteamCoils->MyOneTimeFlag) {
495 : // initialize the environment and sizing flags
496 7 : state.dataSteamCoils->MyEnvrnFlag.dimension(state.dataSteamCoils->NumSteamCoils, true);
497 7 : state.dataSteamCoils->MySizeFlag.dimension(state.dataSteamCoils->NumSteamCoils, true);
498 7 : state.dataSteamCoils->CoilWarningOnceFlag.dimension(state.dataSteamCoils->NumSteamCoils, true);
499 7 : state.dataSteamCoils->MyPlantScanFlag.dimension(state.dataSteamCoils->NumSteamCoils, true);
500 7 : state.dataSteamCoils->MyOneTimeFlag = false;
501 : }
502 :
503 227370 : if (state.dataSteamCoils->MyPlantScanFlag(CoilNum) && allocated(state.dataPlnt->PlantLoop)) {
504 20 : errFlag = false;
505 40 : ScanPlantLoopsForObject(state,
506 20 : state.dataSteamCoils->SteamCoil(CoilNum).Name,
507 20 : state.dataSteamCoils->SteamCoil(CoilNum).CoilType,
508 20 : state.dataSteamCoils->SteamCoil(CoilNum).plantLoc,
509 : errFlag,
510 : _,
511 : _,
512 : _,
513 : _,
514 : _);
515 20 : if (errFlag) {
516 0 : ShowFatalError(state, "InitSteamCoil: Program terminated for previous conditions.");
517 : }
518 20 : state.dataSteamCoils->MyPlantScanFlag(CoilNum) = false;
519 : }
520 :
521 227370 : if (!state.dataGlobal->SysSizingCalc && state.dataSteamCoils->MySizeFlag(CoilNum)) {
522 : // for each coil, do the sizing once.
523 20 : SizeSteamCoil(state, CoilNum);
524 20 : state.dataSteamCoils->MySizeFlag(CoilNum) = false;
525 : }
526 :
527 : // Do the Begin Environment initializations
528 227370 : if (state.dataGlobal->BeginEnvrnFlag && state.dataSteamCoils->MyEnvrnFlag(CoilNum)) {
529 : // Initialize all report variables to a known state at beginning of simulation
530 120 : state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilEnergy = 0.0;
531 120 : state.dataSteamCoils->SteamCoil(CoilNum).TotSteamCoolingCoilEnergy = 0.0;
532 120 : state.dataSteamCoils->SteamCoil(CoilNum).SenSteamCoolingCoilEnergy = 0.0;
533 120 : state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilRate = 0.0;
534 120 : state.dataSteamCoils->SteamCoil(CoilNum).TotSteamCoolingCoilRate = 0.0;
535 120 : state.dataSteamCoils->SteamCoil(CoilNum).SenSteamCoolingCoilRate = 0.0;
536 : // Initialize other module level variables
537 120 : state.dataSteamCoils->SteamCoil(CoilNum).InletAirMassFlowRate = 0.0;
538 120 : state.dataSteamCoils->SteamCoil(CoilNum).OutletAirMassFlowRate = 0.0;
539 120 : state.dataSteamCoils->SteamCoil(CoilNum).InletAirTemp = 0.0;
540 120 : state.dataSteamCoils->SteamCoil(CoilNum).OutletAirTemp = 0.0;
541 120 : state.dataSteamCoils->SteamCoil(CoilNum).InletAirHumRat = 0.0;
542 120 : state.dataSteamCoils->SteamCoil(CoilNum).OutletAirHumRat = 0.0;
543 120 : state.dataSteamCoils->SteamCoil(CoilNum).InletAirEnthalpy = 0.0;
544 120 : state.dataSteamCoils->SteamCoil(CoilNum).OutletAirEnthalpy = 0.0;
545 120 : state.dataSteamCoils->SteamCoil(CoilNum).TotSteamCoilLoad = 0.0;
546 120 : state.dataSteamCoils->SteamCoil(CoilNum).SenSteamCoilLoad = 0.0;
547 120 : state.dataSteamCoils->SteamCoil(CoilNum).LoopLoss = 0.0;
548 120 : state.dataSteamCoils->SteamCoil(CoilNum).LeavingRelHum = 0.0;
549 120 : state.dataSteamCoils->SteamCoil(CoilNum).DesiredOutletTemp = 0.0;
550 120 : state.dataSteamCoils->SteamCoil(CoilNum).DesiredOutletHumRat = 0.0;
551 120 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamTemp = 0.0;
552 120 : state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamTemp = 0.0;
553 120 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate = 0.0;
554 120 : state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate = 0.0;
555 120 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamEnthalpy = 0.0;
556 120 : state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy = 0.0;
557 120 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamPress = 0.0;
558 120 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamQuality = 0.0;
559 120 : state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamQuality = 0.0;
560 :
561 : // More Environment initializations
562 120 : AirInletNode = state.dataSteamCoils->SteamCoil(CoilNum).AirInletNodeNum;
563 120 : SteamInletNode = state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum;
564 120 : ControlNode = state.dataSteamCoils->SteamCoil(CoilNum).TempSetPointNodeNum;
565 120 : AirOutletNode = state.dataSteamCoils->SteamCoil(CoilNum).AirOutletNodeNum;
566 :
567 120 : state.dataLoopNodes->Node(SteamInletNode).Temp = 100.0;
568 120 : state.dataLoopNodes->Node(SteamInletNode).Press = 101325.0;
569 240 : SteamDensity = GetSatDensityRefrig(state,
570 : fluidNameSteam,
571 120 : state.dataLoopNodes->Node(SteamInletNode).Temp,
572 : 1.0,
573 120 : state.dataLoopNodes->Node(SteamInletNode).FluidIndex,
574 : RoutineName);
575 240 : StartEnthSteam = GetSatEnthalpyRefrig(state,
576 : fluidNameSteam,
577 120 : state.dataLoopNodes->Node(SteamInletNode).Temp,
578 : 1.0,
579 120 : state.dataLoopNodes->Node(SteamInletNode).FluidIndex,
580 : RoutineName);
581 120 : state.dataLoopNodes->Node(SteamInletNode).Enthalpy = StartEnthSteam;
582 120 : state.dataLoopNodes->Node(SteamInletNode).Quality = 1.0;
583 120 : state.dataLoopNodes->Node(SteamInletNode).HumRat = 0.0;
584 120 : state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamMassFlowRate =
585 120 : SteamDensity * state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate;
586 : // Node(SteamInletNode)%MassFlowRate = SteamCoil(CoilNum)%MaxSteamMassFlowRate
587 : // Node(SteamInletNode)%MassFlowRateMinAvail = 0.0
588 : // Node(SteamInletNode)%MassFlowRateMaxAvail = SteamCoil(CoilNum)%MaxSteamMassFlowRate
589 360 : InitComponentNodes(state,
590 : 0.0,
591 120 : state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamMassFlowRate,
592 120 : state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
593 120 : state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum);
594 120 : state.dataSteamCoils->MyEnvrnFlag(CoilNum) = false;
595 : } // End If for the Begin Environment initializations
596 :
597 227370 : if (!state.dataGlobal->BeginEnvrnFlag) {
598 226092 : state.dataSteamCoils->MyEnvrnFlag(CoilNum) = true;
599 : }
600 :
601 : // Do the Begin Day initializations
602 : // NONE
603 :
604 : // Do the begin HVAC time step initializations
605 : // NONE
606 :
607 : // Do the following initializations (every time step): This should be the info from
608 : // the previous components outlets or the node data in this section.
609 :
610 227370 : AirInletNode = state.dataSteamCoils->SteamCoil(CoilNum).AirInletNodeNum;
611 227370 : SteamInletNode = state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum;
612 227370 : ControlNode = state.dataSteamCoils->SteamCoil(CoilNum).TempSetPointNodeNum;
613 227370 : AirOutletNode = state.dataSteamCoils->SteamCoil(CoilNum).AirOutletNodeNum;
614 :
615 : // First set the conditions for the air into the coil model
616 :
617 : // If a temperature setpoint controlled coil must set the desired outlet temp everytime
618 227370 : if (ControlNode == 0) {
619 177701 : state.dataSteamCoils->SteamCoil(CoilNum).DesiredOutletTemp = 0.0;
620 49669 : } else if (ControlNode == AirOutletNode) {
621 49669 : state.dataSteamCoils->SteamCoil(CoilNum).DesiredOutletTemp = state.dataLoopNodes->Node(ControlNode).TempSetPoint;
622 : } else {
623 0 : state.dataSteamCoils->SteamCoil(CoilNum).DesiredOutletTemp =
624 0 : state.dataLoopNodes->Node(ControlNode).TempSetPoint -
625 0 : (state.dataLoopNodes->Node(ControlNode).Temp - state.dataLoopNodes->Node(AirOutletNode).Temp);
626 : }
627 :
628 227370 : state.dataSteamCoils->SteamCoil(CoilNum).InletAirMassFlowRate = state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
629 227370 : state.dataSteamCoils->SteamCoil(CoilNum).InletAirTemp = state.dataLoopNodes->Node(AirInletNode).Temp;
630 227370 : state.dataSteamCoils->SteamCoil(CoilNum).InletAirHumRat = state.dataLoopNodes->Node(AirInletNode).HumRat;
631 227370 : state.dataSteamCoils->SteamCoil(CoilNum).InletAirEnthalpy = state.dataLoopNodes->Node(AirInletNode).Enthalpy;
632 227370 : if (FirstHVACIteration) {
633 111499 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate = state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamMassFlowRate;
634 : } else {
635 115871 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate = state.dataLoopNodes->Node(SteamInletNode).MassFlowRate;
636 : }
637 227370 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamTemp = state.dataLoopNodes->Node(SteamInletNode).Temp;
638 227370 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamEnthalpy = state.dataLoopNodes->Node(SteamInletNode).Enthalpy;
639 227370 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamPress = state.dataLoopNodes->Node(SteamInletNode).Press;
640 227370 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamQuality = state.dataLoopNodes->Node(SteamInletNode).Quality;
641 227370 : state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilRate = 0.0;
642 227370 : state.dataSteamCoils->SteamCoil(CoilNum).TotSteamCoolingCoilRate = 0.0;
643 227370 : state.dataSteamCoils->SteamCoil(CoilNum).SenSteamCoolingCoilRate = 0.0;
644 : // Node(SteamInletNode)%MassFlowRateMaxAvail = MIN(Node(SteamInletNode)%MassFlowRateMaxAvail,&
645 : // SteamCoil(CoilNum)%MaxSteamMassFlowRate)
646 227370 : }
647 :
648 20 : void SizeSteamCoil(EnergyPlusData &state, int const CoilNum)
649 : {
650 : // SUBROUTINE INFORMATION:
651 : // AUTHOR Rahul Chillar
652 : // DATE WRITTEN Jan 2005
653 : // MODIFIED na
654 : // RE-ENGINEERED na
655 :
656 : // PURPOSE OF THIS SUBROUTINE:
657 : // This subroutine is for sizing Steam Coil Components for which flow rates have not been
658 : // specified in the input.
659 :
660 : // METHODOLOGY EMPLOYED:
661 : // Obtains flow rates from the zone or system sizing arrays and plant sizing data.
662 :
663 : // Using/Aliasing
664 : using namespace DataSizing;
665 : using FluidProperties::GetSatDensityRefrig;
666 : using FluidProperties::GetSatEnthalpyRefrig;
667 : using PlantUtilities::RegisterPlantCompDesignFlow;
668 :
669 : // SUBROUTINE PARAMETER DEFINITIONS:
670 : static constexpr std::string_view RoutineName("SizeSteamCoil");
671 :
672 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
673 : int PltSizNum; // do loop index for plant sizing
674 : int PltSizSteamNum; // index of plant sizing object for 1st steam loop
675 : bool ErrorsFound; // If errors detected in input
676 : Real64 CoilInTemp;
677 : Real64 CoilOutTemp;
678 : Real64 CoilOutHumRat;
679 : Real64 CoilInHumRat;
680 : Real64 DesCoilLoad;
681 : Real64 DesMassFlow;
682 : Real64 DesVolFlow;
683 : Real64 MinFlowFrac;
684 : Real64 OutAirFrac;
685 20 : Real64 TempSteamIn(100.0);
686 : Real64 EnthSteamInDry;
687 : Real64 EnthSteamOutWet;
688 : Real64 LatentHeatSteam;
689 : Real64 SteamDensity;
690 : Real64 RhoAirStd; // density of air at standard conditions
691 : Real64 CpAirStd; // specific heat of air at std conditions
692 : Real64 CpWater; // specific heat of water (condensed steam)
693 :
694 20 : std::string CompName; // component name
695 20 : std::string CompType; // component type
696 20 : std::string SizingString; // input field sizing description (e.g., Nominal Capacity)
697 20 : bool bPRINT = false; // TRUE if sizing is reported to output (eio)
698 : Real64 TempSize; // autosized value
699 :
700 20 : ErrorsFound = false;
701 20 : PltSizSteamNum = 0;
702 20 : PltSizNum = 0;
703 20 : CoilInTemp = 0.0;
704 20 : CoilInHumRat = 0.0;
705 20 : CoilOutTemp = 0.0;
706 20 : DesCoilLoad = 0.0;
707 20 : MinFlowFrac = 0.0;
708 20 : DesMassFlow = 0.0;
709 20 : DesVolFlow = 0.0;
710 20 : CpWater = 0.0;
711 20 : RhoAirStd = PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, 20.0, 0.0);
712 20 : CpAirStd = PsyCpAirFnW(0.0);
713 20 : bool coilWasAutosized(false); // coil report
714 :
715 20 : auto &OASysEqSizing = state.dataSize->OASysEqSizing;
716 20 : auto &TermUnitSizing = state.dataSize->TermUnitSizing;
717 :
718 : // If this is a steam coil
719 : // Find the appropriate steam Plant Sizing object
720 20 : if (state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate == AutoSize) {
721 18 : coilWasAutosized = true; // coil report
722 18 : PltSizSteamNum = MyPlantSizingIndex(state,
723 : "steam heating coil",
724 18 : state.dataSteamCoils->SteamCoil(CoilNum).Name,
725 18 : state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
726 18 : state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
727 : ErrorsFound);
728 : }
729 :
730 20 : if (PltSizSteamNum > 0) {
731 : // If this is a central air system heating coil
732 18 : if (state.dataSize->CurSysNum > 0) {
733 3 : auto &finalSysSizing = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum);
734 :
735 : // If the coil water volume flow rate needs autosizing, then do it
736 3 : if (state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate == AutoSize) {
737 3 : CheckSysSizing(state, "Coil:Heating:Steam", state.dataSteamCoils->SteamCoil(CoilNum).Name);
738 :
739 3 : if (state.dataSteamCoils->SteamCoil(CoilNum).DesiccantRegenerationCoil) {
740 :
741 0 : state.dataSize->DataDesicRegCoil = true;
742 0 : state.dataSize->DataDesicDehumNum = state.dataSteamCoils->SteamCoil(CoilNum).DesiccantDehumNum;
743 0 : CompType = state.dataSteamCoils->SteamCoil(CoilNum).SteamCoilType; // this is casting an int to a string
744 0 : CompName = state.dataSteamCoils->SteamCoil(CoilNum).Name;
745 0 : bPRINT = false;
746 0 : HeatingCoilDesAirInletTempSizer sizerHeatingDesInletTemp;
747 0 : bool ErrorsFound = false;
748 0 : sizerHeatingDesInletTemp.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
749 0 : state.dataSize->DataDesInletAirTemp = sizerHeatingDesInletTemp.size(state, DataSizing::AutoSize, ErrorsFound);
750 :
751 0 : HeatingCoilDesAirOutletTempSizer sizerHeatingDesOutletTemp;
752 0 : ErrorsFound = false;
753 0 : sizerHeatingDesOutletTemp.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
754 0 : state.dataSize->DataDesOutletAirTemp = sizerHeatingDesOutletTemp.size(state, DataSizing::AutoSize, ErrorsFound);
755 :
756 0 : if (state.dataSize->CurOASysNum > 0) {
757 0 : OASysEqSizing(state.dataSize->CurOASysNum).AirFlow = true;
758 0 : OASysEqSizing(state.dataSize->CurOASysNum).AirVolFlow = finalSysSizing.DesOutAirVolFlow;
759 : }
760 0 : TempSize = AutoSize; // reset back
761 0 : }
762 :
763 : // Set the duct flow rate
764 3 : switch (state.dataSize->CurDuctType) {
765 3 : case HVAC::AirDuctType::Main:
766 3 : DesVolFlow = finalSysSizing.SysAirMinFlowRat * finalSysSizing.DesMainVolFlow;
767 3 : break;
768 0 : case HVAC::AirDuctType::Cooling:
769 0 : DesVolFlow = finalSysSizing.SysAirMinFlowRat * finalSysSizing.DesCoolVolFlow;
770 0 : break;
771 0 : case HVAC::AirDuctType::Heating:
772 0 : DesVolFlow = finalSysSizing.DesHeatVolFlow;
773 0 : break;
774 0 : case HVAC::AirDuctType::Other:
775 0 : DesVolFlow = finalSysSizing.DesMainVolFlow;
776 0 : break;
777 0 : default:
778 0 : DesVolFlow = finalSysSizing.DesMainVolFlow;
779 : }
780 3 : if (state.dataSize->DataDesicRegCoil) {
781 0 : bPRINT = false;
782 0 : TempSize = AutoSize;
783 0 : bool errorsFound = false;
784 0 : HeatingAirFlowSizer sizingHeatingAirFlow;
785 0 : sizingHeatingAirFlow.overrideSizingString(SizingString);
786 : // sizingHeatingAirFlow.setHVACSizingIndexData(FanCoil(FanCoilNum).HVACSizingIndex);
787 0 : sizingHeatingAirFlow.initializeWithinEP(state, CompType, CompName, bPRINT, RoutineName);
788 0 : DesVolFlow = sizingHeatingAirFlow.size(state, TempSize, errorsFound);
789 0 : }
790 3 : DesMassFlow = RhoAirStd * DesVolFlow;
791 : // get the outside air fraction
792 3 : if (finalSysSizing.HeatOAOption == DataSizing::OAControl::MinOA) {
793 3 : if (DesVolFlow > 0.0) {
794 3 : OutAirFrac = finalSysSizing.DesOutAirVolFlow / DesVolFlow;
795 : } else {
796 0 : OutAirFrac = 1.0;
797 : }
798 3 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
799 : } else {
800 0 : OutAirFrac = 1.0;
801 : }
802 :
803 3 : if (state.dataSize->DataDesicRegCoil) {
804 0 : DesCoilLoad = CpAirStd * DesMassFlow * (state.dataSize->DataDesOutletAirTemp - state.dataSize->DataDesInletAirTemp);
805 : } else {
806 : // mixed air temp
807 3 : CoilInTemp = OutAirFrac * finalSysSizing.HeatOutTemp + (1.0 - OutAirFrac) * finalSysSizing.HeatRetTemp;
808 : // coil load
809 3 : DesCoilLoad = CpAirStd * DesMassFlow * (finalSysSizing.HeatSupTemp - CoilInTemp);
810 : }
811 : // AUTOSTEAMCOIL
812 3 : if (DesCoilLoad >= HVAC::SmallLoad) {
813 : // TempSteamIn=SteamCoil(CoilNum)%InletSteamTemp
814 : // TempSteamIn=PlantSizData(PltSizSteamNum)%ExitTemp
815 3 : TempSteamIn = 100.0; // Should be from the PlantSizing object (ExitTemp) instead of hardwired to 100?
816 : // RefrigIndex is set during GetInput for this module
817 6 : EnthSteamInDry = GetSatEnthalpyRefrig(
818 3 : state, fluidNameSteam, TempSteamIn, 1.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
819 6 : EnthSteamOutWet = GetSatEnthalpyRefrig(
820 3 : state, fluidNameSteam, TempSteamIn, 0.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
821 3 : LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet;
822 6 : SteamDensity = GetSatDensityRefrig(
823 3 : state, fluidNameSteam, TempSteamIn, 1.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
824 : // SteamCoil(CoilNum)%MaxSteamVolFlowRate = DesCoilLoad/(SteamDensity * LatentHeatSteam)
825 : // CpWater = GetSpecificHeatGlycol('WATER', &
826 : // TempSteamIn, &
827 : // PlantLoop(SteamCoil(CoilNum)%LoopNum)%FluidIndex, &
828 : // 'SizeSteamCoil')
829 6 : CpWater = FluidProperties::GetSatSpecificHeatRefrig(
830 3 : state, fluidNameSteam, TempSteamIn, 0.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
831 :
832 3 : state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate =
833 3 : DesCoilLoad / (SteamDensity * (LatentHeatSteam + state.dataSteamCoils->SteamCoil(CoilNum).DegOfSubcooling * CpWater));
834 : // PlantSizData(PltSizSteamNum)%DeltaT*CPHW(PlantSizData(PltSizSteamNum)%ExitTemp)))
835 : } else {
836 0 : state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate = 0.0;
837 0 : ShowWarningError(
838 0 : state, format("The design coil load is zero for COIL:Heating:Steam {}", state.dataSteamCoils->SteamCoil(CoilNum).Name));
839 : }
840 6 : BaseSizer::reportSizerOutput(state,
841 : "Coil:Heating:Steam",
842 3 : state.dataSteamCoils->SteamCoil(CoilNum).Name,
843 : "Maximum Steam Flow Rate [m3/s]",
844 3 : state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate);
845 : }
846 3 : state.dataSize->DataDesicRegCoil = false; // reset all globals to 0 to ensure correct sizing for other child components
847 : // Coil report, set fan info for airloopnum
848 :
849 3 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanNum > 0) {
850 9 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilSupplyFanInfo(
851 : state,
852 3 : state.dataSteamCoils->SteamCoil(CoilNum).Name,
853 : "Coil:Heating:Steam",
854 3 : state.dataFans->fans(state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanNum)->Name,
855 3 : state.dataFans->fans(state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanNum)->type,
856 3 : state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanNum);
857 : }
858 :
859 : // if this is a zone coil
860 15 : } else if (state.dataSize->CurZoneEqNum > 0) {
861 15 : CheckZoneSizing(state, "Coil:Heating:Steam", state.dataSteamCoils->SteamCoil(CoilNum).Name);
862 : // autosize the coil steam volume flow rate if needed
863 15 : if (state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate == AutoSize) {
864 : // if coil is part of a terminal unit just use the terminal unit value
865 15 : if (state.dataSize->TermUnitSingDuct || state.dataSize->TermUnitPIU || state.dataSize->TermUnitIU) {
866 13 : if (state.dataSize->CurTermUnitSizingNum > 0) {
867 13 : state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate =
868 13 : TermUnitSizing(state.dataSize->CurTermUnitSizingNum).MaxSTVolFlow;
869 : } else {
870 0 : state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate = 0.0;
871 : }
872 : // if coil is part of a zonal unit, calc coil load to get hot Steam flow rate
873 13 : DesCoilLoad = TermUnitSizing(state.dataSize->CurTermUnitSizingNum).DesHeatingLoad; // coil report
874 13 : DesVolFlow = TermUnitSizing(state.dataSize->CurTermUnitSizingNum).AirVolFlow *
875 13 : TermUnitSizing(state.dataSize->CurTermUnitSizingNum).ReheatAirFlowMult; // coil report
876 : } else {
877 2 : CoilInTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInTemp;
878 2 : CoilOutTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).HeatDesTemp;
879 2 : CoilOutHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).HeatDesHumRat;
880 2 : DesMassFlow = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatMassFlow;
881 2 : DesVolFlow = DesMassFlow / RhoAirStd;
882 2 : DesCoilLoad = PsyCpAirFnW(CoilOutHumRat) * DesMassFlow * (CoilOutTemp - CoilInTemp);
883 2 : if (DesCoilLoad >= HVAC::SmallLoad) {
884 2 : TempSteamIn = 100.0;
885 : // RefrigIndex is set during GetInput for this module
886 4 : EnthSteamInDry = GetSatEnthalpyRefrig(
887 2 : state, fluidNameSteam, TempSteamIn, 1.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
888 4 : EnthSteamOutWet = GetSatEnthalpyRefrig(
889 2 : state, fluidNameSteam, TempSteamIn, 0.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
890 2 : LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet;
891 4 : SteamDensity = GetSatDensityRefrig(
892 2 : state, fluidNameSteam, TempSteamIn, 1.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
893 : // SteamCoil(CoilNum)%MaxSteamVolFlowRate = DesCoilLoad/(SteamDensity * LatentHeatSteam)
894 : // CpWater = GetSpecificHeatGlycol('WATER', &
895 : // TempSteamIn, &
896 : // PlantLoop(SteamCoil(CoilNum)%LoopNum)%FluidIndex, &
897 : // 'SizeSteamCoil')
898 4 : CpWater = FluidProperties::GetSatSpecificHeatRefrig(
899 2 : state, fluidNameSteam, TempSteamIn, 0.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
900 :
901 2 : state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate =
902 2 : DesCoilLoad / (SteamDensity * (LatentHeatSteam + state.dataSteamCoils->SteamCoil(CoilNum).DegOfSubcooling * CpWater));
903 : // PlantSizData(PltSizSteamNum)%DeltaT*CPHW(PlantSizData(PltSizSteamNum)%ExitTemp)))
904 : } else {
905 0 : state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate = 0.0;
906 : }
907 : }
908 : // issue warning if hw coil has zero flow
909 15 : if (state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate == 0.0) {
910 0 : ShowWarningError(
911 0 : state, format("The design coil load is zero for COIL:Heating:Steam {}", state.dataSteamCoils->SteamCoil(CoilNum).Name));
912 0 : ShowContinueError(state, "The autosize value for max Steam flow rate is zero");
913 : }
914 30 : BaseSizer::reportSizerOutput(state,
915 : "Coil:Heating:Steam",
916 15 : state.dataSteamCoils->SteamCoil(CoilNum).Name,
917 : "Maximum Steam Flow Rate [m3/s]",
918 15 : state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate);
919 : }
920 : } // end zone coil ELSE - IF
921 :
922 : } else {
923 : // if there is no heating Plant Sizing object and autosizng was requested, issue an error message
924 2 : if (state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate == AutoSize) {
925 0 : ShowSevereError(state, "Autosizing of Steam coil requires a heating loop Sizing:Plant object");
926 0 : ShowContinueError(state, format("Occurs in Steam coil object= {}", state.dataSteamCoils->SteamCoil(CoilNum).Name));
927 0 : ErrorsFound = true;
928 : }
929 : } // end of heating Plant Sizing existence IF - ELSE
930 :
931 : // save the design Steam volumetric flow rate for use by the Steam loop sizing algorithms
932 40 : RegisterPlantCompDesignFlow(
933 20 : state, state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum, state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate);
934 :
935 60 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilHeatingCapacity(state,
936 20 : state.dataSteamCoils->SteamCoil(CoilNum).Name,
937 : "Coil:Heating:Steam",
938 : DesCoilLoad,
939 : coilWasAutosized,
940 20 : state.dataSize->CurSysNum,
941 20 : state.dataSize->CurZoneEqNum,
942 20 : state.dataSize->CurOASysNum,
943 : 0.0,
944 : 1.0,
945 : -999.0,
946 : -999.0);
947 60 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilWaterFlowNodeNums(state,
948 20 : state.dataSteamCoils->SteamCoil(CoilNum).Name,
949 : "Coil:Heating:Steam",
950 20 : state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamVolFlowRate,
951 : coilWasAutosized,
952 20 : state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
953 20 : state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
954 20 : state.dataSteamCoils->SteamCoil(CoilNum).plantLoc.loopNum);
955 60 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilWaterHeaterCapacityNodeNums(
956 : state,
957 20 : state.dataSteamCoils->SteamCoil(CoilNum).Name,
958 : "Coil:Heating:Steam",
959 : DesCoilLoad,
960 : coilWasAutosized,
961 20 : state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
962 20 : state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
963 20 : state.dataSteamCoils->SteamCoil(CoilNum).plantLoc.loopNum);
964 40 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntWaterTemp(
965 20 : state, state.dataSteamCoils->SteamCoil(CoilNum).Name, "Coil:Heating:Steam", TempSteamIn); // coil report
966 60 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgWaterTemp(
967 : state,
968 20 : state.dataSteamCoils->SteamCoil(CoilNum).Name,
969 : "Coil:Heating:Steam",
970 20 : TempSteamIn - state.dataSteamCoils->SteamCoil(CoilNum).DegOfSubcooling); // coil report
971 60 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilWaterDeltaT(
972 : state,
973 20 : state.dataSteamCoils->SteamCoil(CoilNum).Name,
974 : "Coil:Heating:Steam",
975 20 : state.dataSteamCoils->SteamCoil(CoilNum).DegOfSubcooling); // coil report
976 20 : state.dataSteamCoils->SteamCoil(CoilNum).DesCoilCapacity = DesCoilLoad;
977 20 : state.dataSteamCoils->SteamCoil(CoilNum).DesAirVolFlow = DesVolFlow;
978 20 : if (ErrorsFound) {
979 0 : ShowFatalError(state, "Preceding Steam coil sizing errors cause program termination");
980 : }
981 :
982 : // There is no standard rating for heating coils at this point, so fill with dummy flag values
983 40 : state.dataRptCoilSelection->coilSelectionReportObj->setRatedCoilConditions(state,
984 20 : state.dataSteamCoils->SteamCoil(CoilNum).Name,
985 : "Coil:Heating:Steam",
986 : -999.0,
987 : -999.0,
988 : -999.0,
989 : -999.0,
990 : -999.0,
991 : -999.0,
992 : -999.0,
993 : -999.0,
994 : -999.0,
995 : -999.0,
996 : -999.0,
997 : -999.0,
998 : -999.0);
999 20 : }
1000 :
1001 : // End Initialization Section of the Module
1002 :
1003 : // Begin Algorithm Section of the Module
1004 :
1005 227370 : void CalcSteamAirCoil(EnergyPlusData &state,
1006 : int const CoilNum,
1007 : Real64 const QCoilRequested, // requested coil load
1008 : Real64 &QCoilActual, // coil load actually delivered
1009 : HVAC::FanOp const fanOp, // fan operating mode
1010 : Real64 const PartLoadRatio // part-load ratio of heating coil
1011 : )
1012 : {
1013 : // SUBROUTINE INFORMATION:
1014 : // AUTHOR Rahul Chillar
1015 : // DATE WRITTEN Jan 2005
1016 : // MODIFIED Sep. 2012, B. Griffith, add calls to SetComponentFlowRate for plant interactions
1017 : // Jul. 2016, R. Zhang, Applied the coil supply air temperature sensor offset fault model
1018 : // RE-ENGINEERED na
1019 :
1020 : // PURPOSE OF THIS SUBROUTINE:
1021 : // Simple Steam to air heat exchanger which,
1022 : // serves as an interface for distributing heat from boiler to zones.
1023 :
1024 : // METHODOLOGY EMPLOYED:
1025 : // Steam coils are different, All of steam condenses in heat exchanger
1026 : // Steam traps allow only water to leave the coil,the degree of subcooling
1027 : // desired is input by the user, which is used to calculate water outlet temp.
1028 : // Heat exchange is = Latent Heat + Sensible heat,coil effectivness is 1.0
1029 :
1030 : using HVAC::TempControlTol;
1031 : using PlantUtilities::SetComponentFlowRate;
1032 :
1033 : static constexpr std::string_view RoutineName("CalcSteamAirCoil");
1034 : static constexpr std::string_view RoutineNameSizeSteamCoil("SizeSteamCoil");
1035 :
1036 227370 : Real64 SteamMassFlowRate(0.0);
1037 227370 : Real64 AirMassFlow(0.0); // [kg/sec]
1038 227370 : Real64 TempAirIn(0.0); // [C]
1039 227370 : Real64 TempAirOut(0.0); // [C]
1040 227370 : Real64 Win(0.0);
1041 227370 : Real64 TempSteamIn(0.0);
1042 227370 : Real64 TempWaterOut(0.0);
1043 227370 : Real64 CapacitanceAir(0.0);
1044 227370 : Real64 HeatingCoilLoad(0.0);
1045 227370 : Real64 CoilPress(0.0);
1046 227370 : Real64 EnthSteamInDry(0.0);
1047 227370 : Real64 EnthSteamOutWet(0.0);
1048 227370 : Real64 LatentHeatSteam(0.0);
1049 227370 : Real64 SubcoolDeltaTemp(0.0);
1050 227370 : Real64 TempSetPoint(0.0);
1051 227370 : Real64 QCoilReq(0.0);
1052 227370 : Real64 QCoilCap(0.0);
1053 227370 : Real64 QSteamCoilMaxHT(0.0);
1054 227370 : Real64 TempWaterAtmPress(0.0);
1055 227370 : Real64 TempLoopOutToPump(0.0);
1056 227370 : Real64 EnergyLossToEnvironment(0.0);
1057 227370 : Real64 EnthCoilOutlet(0.0);
1058 227370 : Real64 EnthPumpInlet(0.0);
1059 227370 : Real64 EnthAtAtmPress(0.0);
1060 227370 : Real64 CpWater(0.0);
1061 :
1062 227370 : QCoilReq = QCoilRequested;
1063 227370 : TempAirIn = state.dataSteamCoils->SteamCoil(CoilNum).InletAirTemp;
1064 227370 : Win = state.dataSteamCoils->SteamCoil(CoilNum).InletAirHumRat;
1065 227370 : TempSteamIn = state.dataSteamCoils->SteamCoil(CoilNum).InletSteamTemp;
1066 227370 : CoilPress = state.dataSteamCoils->SteamCoil(CoilNum).InletSteamPress;
1067 227370 : SubcoolDeltaTemp = state.dataSteamCoils->SteamCoil(CoilNum).DegOfSubcooling;
1068 227370 : TempSetPoint = state.dataSteamCoils->SteamCoil(CoilNum).DesiredOutletTemp;
1069 :
1070 : // If there is a fault of coil SAT Sensor
1071 227370 : if (state.dataSteamCoils->SteamCoil(CoilNum).FaultyCoilSATFlag && (!state.dataGlobal->WarmupFlag) && (!state.dataGlobal->DoingSizing) &&
1072 0 : (!state.dataGlobal->KickOffSimulation)) {
1073 : // calculate the sensor offset using fault information
1074 0 : int FaultIndex = state.dataSteamCoils->SteamCoil(CoilNum).FaultyCoilSATIndex;
1075 0 : state.dataSteamCoils->SteamCoil(CoilNum).FaultyCoilSATOffset =
1076 0 : state.dataFaultsMgr->FaultsCoilSATSensor(FaultIndex).CalFaultOffsetAct(state);
1077 : // update the TempSetPoint
1078 0 : TempSetPoint -= state.dataSteamCoils->SteamCoil(CoilNum).FaultyCoilSATOffset;
1079 : }
1080 :
1081 : // adjust mass flow rates for cycling fan cycling coil operation
1082 227370 : if (fanOp == HVAC::FanOp::Cycling) {
1083 34948 : if (PartLoadRatio > 0.0) {
1084 15992 : AirMassFlow = state.dataSteamCoils->SteamCoil(CoilNum).InletAirMassFlowRate / PartLoadRatio;
1085 15992 : SteamMassFlowRate = min(state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate / PartLoadRatio,
1086 15992 : state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamMassFlowRate);
1087 15992 : QCoilReq /= PartLoadRatio;
1088 : } else {
1089 18956 : AirMassFlow = 0.0;
1090 18956 : SteamMassFlowRate = 0.0;
1091 : }
1092 : } else {
1093 192422 : AirMassFlow = state.dataSteamCoils->SteamCoil(CoilNum).InletAirMassFlowRate;
1094 192422 : SteamMassFlowRate = state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate;
1095 : }
1096 :
1097 227370 : if (AirMassFlow > 0.0) { // If the coil is operating
1098 208103 : CapacitanceAir = PsyCpAirFnW(Win) * AirMassFlow;
1099 : } else {
1100 19267 : CapacitanceAir = 0.0;
1101 : }
1102 :
1103 : // If the coil is operating there should be some heating capacitance
1104 : // across the coil, so do the simulation. If not set outlet to inlet and no load.
1105 : // Also the coil has to be scheduled to be available
1106 : // Control output to meet load QCoilReq. Load Controlled Coil.
1107 227370 : switch (state.dataSteamCoils->SteamCoil(CoilNum).TypeOfCoil) {
1108 :
1109 177701 : case CoilControlType::ZoneLoadControl:
1110 158452 : if ((CapacitanceAir > 0.0) && ((state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate) > 0.0) &&
1111 101016 : (GetCurrentScheduleValue(state, state.dataSteamCoils->SteamCoil(CoilNum).SchedPtr) > 0.0 ||
1112 336153 : state.dataSteamCoils->MySizeFlag(CoilNum)) &&
1113 : (QCoilReq > 0.0)) {
1114 :
1115 : // Steam heat exchangers would not have effectivness, since all of the steam is
1116 : // converted to water and only then the steam trap allows it to leave the heat
1117 : // exchanger, subsequently heat exchange is latent heat + subcooling.
1118 84538 : EnthSteamInDry = FluidProperties::GetSatEnthalpyRefrig(
1119 42269 : state, fluidNameSteam, TempSteamIn, 1.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
1120 84538 : EnthSteamOutWet = FluidProperties::GetSatEnthalpyRefrig(
1121 42269 : state, fluidNameSteam, TempSteamIn, 0.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
1122 :
1123 42269 : LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet;
1124 :
1125 : // CpWater = GetSpecificHeatGlycol('WATER', &
1126 : // TempSteamIn, &
1127 : // PlantLoop(SteamCoil(CoilNum)%LoopNum)%FluidIndex, &
1128 : // 'CalcSteamAirCoil')
1129 :
1130 84538 : CpWater = FluidProperties::GetSatSpecificHeatRefrig(
1131 42269 : state, fluidNameSteam, TempSteamIn, 0.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineNameSizeSteamCoil);
1132 :
1133 : // Max Heat Transfer
1134 42269 : QSteamCoilMaxHT = state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamMassFlowRate * (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
1135 42269 : state.dataSteamCoils->SteamCoil(CoilNum).OperatingCapacity = QSteamCoilMaxHT;
1136 :
1137 : // Determine the Max coil capacity and check for the same.
1138 42269 : if (QCoilReq > QSteamCoilMaxHT) {
1139 0 : QCoilCap = QSteamCoilMaxHT;
1140 : } else {
1141 42269 : QCoilCap = QCoilReq;
1142 : }
1143 :
1144 : // Steam Mass Flow Rate Required
1145 42269 : SteamMassFlowRate = QCoilCap / (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
1146 :
1147 84538 : SetComponentFlowRate(state,
1148 : SteamMassFlowRate,
1149 42269 : state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
1150 42269 : state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
1151 42269 : state.dataSteamCoils->SteamCoil(CoilNum).plantLoc);
1152 :
1153 : // recalculate if mass flow rate changed in previous call.
1154 42269 : QCoilCap = SteamMassFlowRate * (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
1155 :
1156 : // In practice Sensible & Superheated heat transfer is negligible compared to latent part.
1157 : // This is required for outlet water temperature, otherwise it will be saturation temperature.
1158 : // Steam Trap drains off all the Water formed.
1159 : // Here Degree of Subcooling is used to calculate hot water return temperature.
1160 :
1161 : // Calculating Water outlet temperature
1162 42269 : TempWaterOut = TempSteamIn - SubcoolDeltaTemp;
1163 :
1164 : // Total Heat Transfer to air
1165 42269 : HeatingCoilLoad = QCoilCap;
1166 :
1167 : // Temperature of air at outlet
1168 42269 : TempAirOut = TempAirIn + QCoilCap / (AirMassFlow * PsyCpAirFnW(Win));
1169 :
1170 42269 : state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate = SteamMassFlowRate;
1171 42269 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate = SteamMassFlowRate;
1172 :
1173 : //************************* Loop Losses *****************************
1174 : // Loop pressure return considerations included in steam coil since the pipes are
1175 : // perfect and do not account for losses.
1176 : // Return water is condensate at atmoshperic pressure
1177 : // Process is considered constant enthalpy expansion
1178 : // No quality function in EnergyPlus hence no option left apart from
1179 : // considering saturated state.
1180 : // StdBaroPress=101325
1181 :
1182 42269 : TempWaterAtmPress = FluidProperties::GetSatTemperatureRefrig(
1183 42269 : state, fluidNameSteam, state.dataEnvrn->StdBaroPress, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
1184 :
1185 : // Point 4 at atm - loop delta subcool during return journery back to pump
1186 42269 : TempLoopOutToPump = TempWaterAtmPress - state.dataSteamCoils->SteamCoil(CoilNum).LoopSubcoolReturn;
1187 :
1188 : // Actual Steam Coil Outlet Enthalpy
1189 84538 : EnthCoilOutlet = FluidProperties::GetSatEnthalpyRefrig(
1190 42269 : state, fluidNameSteam, TempSteamIn, 0.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName) -
1191 42269 : CpWater * SubcoolDeltaTemp;
1192 :
1193 : // Enthalpy at Point 4
1194 84538 : EnthAtAtmPress = FluidProperties::GetSatEnthalpyRefrig(
1195 42269 : state, fluidNameSteam, TempWaterAtmPress, 0.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
1196 :
1197 : // Reported value of coil outlet enthalpy at the node to match the node outlet temperature
1198 84538 : CpWater = FluidProperties::GetSatSpecificHeatRefrig(
1199 42269 : state, fluidNameSteam, TempLoopOutToPump, 0.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineNameSizeSteamCoil);
1200 :
1201 42269 : EnthPumpInlet = EnthAtAtmPress - CpWater * state.dataSteamCoils->SteamCoil(CoilNum).LoopSubcoolReturn;
1202 :
1203 42269 : state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy = EnthPumpInlet;
1204 :
1205 : // Point 3-Point 5,
1206 42269 : EnergyLossToEnvironment = SteamMassFlowRate * (EnthCoilOutlet - EnthPumpInlet);
1207 :
1208 : // Loss to enviornment due to pressure drop
1209 42269 : state.dataSteamCoils->SteamCoil(CoilNum).LoopLoss = EnergyLossToEnvironment;
1210 : //************************* Loop Losses *****************************
1211 : } else { // Coil is not running.
1212 :
1213 135432 : TempAirOut = TempAirIn;
1214 135432 : TempWaterOut = TempSteamIn;
1215 135432 : HeatingCoilLoad = 0.0;
1216 135432 : state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy = state.dataSteamCoils->SteamCoil(CoilNum).InletSteamEnthalpy;
1217 135432 : state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate = 0.0;
1218 135432 : state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamQuality = 0.0;
1219 135432 : state.dataSteamCoils->SteamCoil(CoilNum).LoopLoss = 0.0;
1220 135432 : TempLoopOutToPump = TempWaterOut;
1221 : }
1222 177701 : break;
1223 49669 : case CoilControlType::TemperatureSetPoint:
1224 : // Control coil output to meet a Setpoint Temperature.
1225 49651 : if ((CapacitanceAir > 0.0) && ((state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate) > 0.0) &&
1226 20275 : (GetCurrentScheduleValue(state, state.dataSteamCoils->SteamCoil(CoilNum).SchedPtr) > 0.0 ||
1227 99320 : state.dataSteamCoils->MySizeFlag(CoilNum)) &&
1228 5229 : (std::abs(TempSetPoint - TempAirIn) > TempControlTol)) {
1229 :
1230 : // Steam heat exchangers would not have effectivness, since all of the steam is
1231 : // converted to water and only then the steam trap allows it to leave the heat
1232 : // exchanger, subsequently heat exchange is latent heat + subcooling.
1233 10458 : EnthSteamInDry = FluidProperties::GetSatEnthalpyRefrig(
1234 5229 : state, fluidNameSteam, TempSteamIn, 1.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
1235 10458 : EnthSteamOutWet = FluidProperties::GetSatEnthalpyRefrig(
1236 5229 : state, fluidNameSteam, TempSteamIn, 0.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
1237 5229 : LatentHeatSteam = EnthSteamInDry - EnthSteamOutWet;
1238 :
1239 : // CpWater = GetSpecificHeatGlycol('WATER', &
1240 : // TempSteamIn, &
1241 : // PlantLoop(SteamCoil(CoilNum)%LoopNum)%FluidIndex, &
1242 : // 'CalcSteamAirCoil')
1243 10458 : CpWater = FluidProperties::GetSatSpecificHeatRefrig(
1244 5229 : state, fluidNameSteam, TempSteamIn, 0.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineNameSizeSteamCoil);
1245 :
1246 : // Max Heat Transfer
1247 5229 : QSteamCoilMaxHT = state.dataSteamCoils->SteamCoil(CoilNum).MaxSteamMassFlowRate * (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
1248 :
1249 : // Coil Load in case of temperature setpoint
1250 5229 : QCoilCap = CapacitanceAir * (TempSetPoint - TempAirIn);
1251 :
1252 : // Check to see if setpoint above enetering temperature. If not, set
1253 : // output to zero.
1254 5229 : if (QCoilCap <= 0.0) {
1255 3213 : QCoilCap = 0.0;
1256 3213 : TempAirOut = TempAirIn;
1257 :
1258 : // Steam Mass Flow Rate Required
1259 3213 : SteamMassFlowRate = 0.0;
1260 6426 : SetComponentFlowRate(state,
1261 : SteamMassFlowRate,
1262 3213 : state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
1263 3213 : state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
1264 3213 : state.dataSteamCoils->SteamCoil(CoilNum).plantLoc);
1265 : // Inlet equal to outlet when not required to run.
1266 3213 : TempWaterOut = TempSteamIn;
1267 :
1268 : // Total Heat Transfer to air
1269 3213 : HeatingCoilLoad = QCoilCap;
1270 :
1271 : // The HeatingCoilLoad is the change in the enthalpy of the water
1272 3213 : state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy = state.dataSteamCoils->SteamCoil(CoilNum).InletSteamEnthalpy;
1273 :
1274 : // Outlet flow rate set to inlet
1275 3213 : state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate = SteamMassFlowRate;
1276 3213 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate = SteamMassFlowRate;
1277 :
1278 2016 : } else if (QCoilCap > QSteamCoilMaxHT) {
1279 : // Setting to Maximum Coil Capacity
1280 0 : QCoilCap = QSteamCoilMaxHT;
1281 :
1282 : // Temperature of air at outlet
1283 0 : TempAirOut = TempAirIn + QCoilCap / (AirMassFlow * PsyCpAirFnW(Win));
1284 :
1285 : // In practice Sensible & Superheated heat transfer is negligible compared to latent part.
1286 : // This is required for outlet water temperature, otherwise it will be saturation temperature.
1287 : // Steam Trap drains off all the Water formed.
1288 : // Here Degree of Subcooling is used to calculate hot water return temperature.
1289 :
1290 : // Calculating Water outlet temperature
1291 0 : TempWaterOut = TempSteamIn - SubcoolDeltaTemp;
1292 :
1293 : // Steam Mass Flow Rate Required
1294 0 : SteamMassFlowRate = QCoilCap / (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
1295 0 : SetComponentFlowRate(state,
1296 : SteamMassFlowRate,
1297 0 : state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
1298 0 : state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
1299 0 : state.dataSteamCoils->SteamCoil(CoilNum).plantLoc);
1300 :
1301 : // recalculate in case previous call changed mass flow rate
1302 0 : QCoilCap = SteamMassFlowRate * (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
1303 0 : TempAirOut = TempAirIn + QCoilCap / (AirMassFlow * PsyCpAirFnW(Win));
1304 :
1305 : // Total Heat Transfer to air
1306 0 : HeatingCoilLoad = QCoilCap;
1307 :
1308 : // The HeatingCoilLoad is the change in the enthalpy of the water
1309 0 : state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy =
1310 0 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamEnthalpy - HeatingCoilLoad / SteamMassFlowRate;
1311 0 : state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate = SteamMassFlowRate;
1312 0 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate = SteamMassFlowRate;
1313 :
1314 : } else {
1315 : // Temp air out is temperature Setpoint
1316 2016 : TempAirOut = TempSetPoint;
1317 :
1318 : // In practice Sensible & Superheated heat transfer is negligible compared to latent part.
1319 : // This is required for outlet water temperature, otherwise it will be saturation temperature.
1320 : // Steam Trap drains off all the Water formed.
1321 : // Here Degree of Subcooling is used to calculate hot water return temperature.
1322 :
1323 : // Calculating Water outlet temperature
1324 2016 : TempWaterOut = TempSteamIn - SubcoolDeltaTemp;
1325 :
1326 : // Steam Mass Flow Rate Required
1327 2016 : SteamMassFlowRate = QCoilCap / (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
1328 4032 : SetComponentFlowRate(state,
1329 : SteamMassFlowRate,
1330 2016 : state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
1331 2016 : state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
1332 2016 : state.dataSteamCoils->SteamCoil(CoilNum).plantLoc);
1333 :
1334 : // recalculate in case previous call changed mass flow rate
1335 2016 : QCoilCap = SteamMassFlowRate * (LatentHeatSteam + SubcoolDeltaTemp * CpWater);
1336 2016 : TempAirOut = TempAirIn + QCoilCap / (AirMassFlow * PsyCpAirFnW(Win));
1337 :
1338 : // Total Heat Transfer to air
1339 2016 : HeatingCoilLoad = QCoilCap;
1340 :
1341 2016 : state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate = SteamMassFlowRate;
1342 2016 : state.dataSteamCoils->SteamCoil(CoilNum).InletSteamMassFlowRate = SteamMassFlowRate;
1343 :
1344 : //************************* Loop Losses *****************************
1345 : // Loop pressure return considerations included in steam coil since the pipes are
1346 : // perfect and do not account for losses.
1347 :
1348 : // Return water is condensate at atmoshperic pressure
1349 : // Process is considered constant enthalpy expansion
1350 : // No quality function in EnergyPlus hence no option left apart from
1351 : // considering saturated state.
1352 : // StdBaroPress=101325
1353 :
1354 2016 : TempWaterAtmPress = FluidProperties::GetSatTemperatureRefrig(
1355 2016 : state, fluidNameSteam, state.dataEnvrn->StdBaroPress, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
1356 :
1357 : // Point 4 at atm - loop delta subcool during return journery back to pump
1358 2016 : TempLoopOutToPump = TempWaterAtmPress - state.dataSteamCoils->SteamCoil(CoilNum).LoopSubcoolReturn;
1359 :
1360 : // Actual Steam Coil Outlet Enthalpy
1361 4032 : EnthCoilOutlet = FluidProperties::GetSatEnthalpyRefrig(
1362 2016 : state, fluidNameSteam, TempSteamIn, 0.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName) -
1363 2016 : CpWater * SubcoolDeltaTemp;
1364 :
1365 : // Enthalpy at Point 4
1366 4032 : EnthAtAtmPress = FluidProperties::GetSatEnthalpyRefrig(
1367 2016 : state, fluidNameSteam, TempWaterAtmPress, 0.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineName);
1368 :
1369 4032 : CpWater = FluidProperties::GetSatSpecificHeatRefrig(
1370 2016 : state, fluidNameSteam, TempLoopOutToPump, 0.0, state.dataSteamCoils->SteamCoil(CoilNum).FluidIndex, RoutineNameSizeSteamCoil);
1371 :
1372 : // Reported value of coil outlet enthalpy at the node to match the node outlet temperature
1373 2016 : EnthPumpInlet = EnthAtAtmPress - CpWater * state.dataSteamCoils->SteamCoil(CoilNum).LoopSubcoolReturn;
1374 :
1375 2016 : state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy = EnthPumpInlet;
1376 :
1377 : // Point 3-Point 5,
1378 2016 : EnergyLossToEnvironment = SteamMassFlowRate * (EnthCoilOutlet - EnthPumpInlet);
1379 :
1380 : // Loss to enviornment due to pressure drop
1381 2016 : state.dataSteamCoils->SteamCoil(CoilNum).LoopLoss = EnergyLossToEnvironment;
1382 : //************************* Loop Losses *****************************
1383 : }
1384 :
1385 : } else { // If not running Conditions do not change across coil from inlet to outlet
1386 44440 : SteamMassFlowRate = 0.0;
1387 88880 : SetComponentFlowRate(state,
1388 : SteamMassFlowRate,
1389 44440 : state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum,
1390 44440 : state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum,
1391 44440 : state.dataSteamCoils->SteamCoil(CoilNum).plantLoc);
1392 44440 : TempAirOut = TempAirIn;
1393 44440 : TempWaterOut = TempSteamIn;
1394 44440 : HeatingCoilLoad = 0.0;
1395 44440 : state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy = state.dataSteamCoils->SteamCoil(CoilNum).InletSteamEnthalpy;
1396 44440 : state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamMassFlowRate = 0.0;
1397 44440 : state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamQuality = 0.0;
1398 44440 : state.dataSteamCoils->SteamCoil(CoilNum).LoopLoss = 0.0;
1399 44440 : TempLoopOutToPump = TempWaterOut;
1400 : }
1401 49669 : break;
1402 0 : default:
1403 0 : assert(false);
1404 : }
1405 :
1406 227370 : if (fanOp == HVAC::FanOp::Cycling) {
1407 34948 : HeatingCoilLoad *= PartLoadRatio;
1408 : }
1409 :
1410 : // Set the outlet conditions
1411 227370 : state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilRate = HeatingCoilLoad;
1412 227370 : state.dataSteamCoils->SteamCoil(CoilNum).OutletAirTemp = TempAirOut;
1413 227370 : state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamTemp = TempLoopOutToPump;
1414 227370 : state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamQuality = 0.0;
1415 227370 : QCoilActual = HeatingCoilLoad;
1416 :
1417 : // This SteamCoil does not change the moisture or Mass Flow across the component
1418 227370 : state.dataSteamCoils->SteamCoil(CoilNum).OutletAirHumRat = state.dataSteamCoils->SteamCoil(CoilNum).InletAirHumRat;
1419 227370 : state.dataSteamCoils->SteamCoil(CoilNum).OutletAirMassFlowRate = state.dataSteamCoils->SteamCoil(CoilNum).InletAirMassFlowRate;
1420 : // Set the outlet enthalpys for air and water
1421 227370 : state.dataSteamCoils->SteamCoil(CoilNum).OutletAirEnthalpy =
1422 227370 : PsyHFnTdbW(state.dataSteamCoils->SteamCoil(CoilNum).OutletAirTemp, state.dataSteamCoils->SteamCoil(CoilNum).OutletAirHumRat);
1423 227370 : }
1424 :
1425 : // Beginning of Update subroutines for the SteamCoil Module
1426 :
1427 227370 : void UpdateSteamCoil(EnergyPlusData &state, int const CoilNum)
1428 : {
1429 : // SUBROUTINE INFORMATION:
1430 : // AUTHOR Rahul Chillar
1431 : // DATE WRITTEN Jan 2005
1432 : // MODIFIED na
1433 : // RE-ENGINEERED na
1434 :
1435 : // PURPOSE OF THIS SUBROUTINE:
1436 : // This subroutine updates the coil outlet nodes.
1437 :
1438 : // METHODOLOGY EMPLOYED:
1439 : // Data is moved from the coil data structure to the coil outlet nodes.
1440 :
1441 : using PlantUtilities::SafeCopyPlantNode;
1442 :
1443 : int AirInletNode;
1444 : int SteamInletNode;
1445 : int AirOutletNode;
1446 : int SteamOutletNode;
1447 :
1448 227370 : AirInletNode = state.dataSteamCoils->SteamCoil(CoilNum).AirInletNodeNum;
1449 227370 : SteamInletNode = state.dataSteamCoils->SteamCoil(CoilNum).SteamInletNodeNum;
1450 227370 : AirOutletNode = state.dataSteamCoils->SteamCoil(CoilNum).AirOutletNodeNum;
1451 227370 : SteamOutletNode = state.dataSteamCoils->SteamCoil(CoilNum).SteamOutletNodeNum;
1452 :
1453 : // Set the outlet air nodes of the SteamCoil
1454 227370 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRate = state.dataSteamCoils->SteamCoil(CoilNum).OutletAirMassFlowRate;
1455 227370 : state.dataLoopNodes->Node(AirOutletNode).Temp = state.dataSteamCoils->SteamCoil(CoilNum).OutletAirTemp;
1456 227370 : state.dataLoopNodes->Node(AirOutletNode).HumRat = state.dataSteamCoils->SteamCoil(CoilNum).OutletAirHumRat;
1457 227370 : state.dataLoopNodes->Node(AirOutletNode).Enthalpy = state.dataSteamCoils->SteamCoil(CoilNum).OutletAirEnthalpy;
1458 :
1459 227370 : SafeCopyPlantNode(state, SteamInletNode, SteamOutletNode);
1460 :
1461 : // Set the outlet Steam nodes for the Coil
1462 : // Node(SteamOutletNode)%MassFlowRate = SteamCoil(CoilNum)%OutletSteamMassFlowRate
1463 227370 : state.dataLoopNodes->Node(SteamOutletNode).Temp = state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamTemp;
1464 227370 : state.dataLoopNodes->Node(SteamOutletNode).Enthalpy = state.dataSteamCoils->SteamCoil(CoilNum).OutletWaterEnthalpy;
1465 227370 : state.dataLoopNodes->Node(SteamOutletNode).Quality = state.dataSteamCoils->SteamCoil(CoilNum).OutletSteamQuality;
1466 : // Node(SteamInletNode)%MassFlowRate = SteamCoil(CoilNum)%OutletSteamMassFlowRate
1467 :
1468 : // Set the outlet nodes for properties that just pass through & not used
1469 227370 : state.dataLoopNodes->Node(AirOutletNode).Quality = state.dataLoopNodes->Node(AirInletNode).Quality;
1470 227370 : state.dataLoopNodes->Node(AirOutletNode).Press = state.dataLoopNodes->Node(AirInletNode).Press;
1471 227370 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMin = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMin;
1472 227370 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMax = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax;
1473 227370 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMinAvail;
1474 227370 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMaxAvail;
1475 :
1476 : // Set the outlet nodes for properties that just pass through & not used
1477 :
1478 : // Node(SteamOutletNode)%Press = Node(SteamInletNode)%Press
1479 : // Node(SteamOutletNode)%Press = StdBaroPress ! Water out at atm pressure
1480 : // Node(SteamOutletNode)%HumRat = Node(SteamInletNode)%HumRat
1481 : // Node(SteamOutletNode)%MassFlowRateMin = Node(SteamInletNode)%MassFlowRateMin
1482 : // Node(SteamOutletNode)%MassFlowRateMax = Node(SteamInletNode)%MassFlowRateMax
1483 : // Node(SteamOutletNode)%MassFlowRateMinAvail= Node(SteamInletNode)%MassFlowRateMinAvail
1484 : // Node(SteamOutletNode)%MassFlowRateMaxAvail= Node(SteamInletNode)%MassFlowRateMaxAvail
1485 :
1486 : // IF (SteamCoil(CoilNum)%InletSteamMassFlowRate.EQ.0.0) THEN
1487 : // Node(SteamInletNode)%MassFlowRate = 0.0
1488 : // Node(SteamInletNode)%MassFlowRateMinAvail = 0.0
1489 : // Node(SteamOutletNode)%MassFlowRateMinAvail= 0.0
1490 : // END IF
1491 :
1492 227370 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
1493 0 : state.dataLoopNodes->Node(AirOutletNode).CO2 = state.dataLoopNodes->Node(AirInletNode).CO2;
1494 : }
1495 227370 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
1496 0 : state.dataLoopNodes->Node(AirOutletNode).GenContam = state.dataLoopNodes->Node(AirInletNode).GenContam;
1497 : }
1498 227370 : }
1499 :
1500 : // End of Update subroutines for the SteamCoil Module
1501 :
1502 : // Beginning of Reporting subroutines for the SteamCoil Module
1503 :
1504 227370 : void ReportSteamCoil(EnergyPlusData &state, int const CoilNum)
1505 : {
1506 : // SUBROUTINE INFORMATION:
1507 : // AUTHOR Rahul Chillar
1508 : // DATE WRITTEN Jan 2005
1509 : // MODIFIED na
1510 : // RE-ENGINEERED na
1511 :
1512 : // PURPOSE OF THIS SUBROUTINE:
1513 : // This subroutine updates the report variable for the coils.
1514 :
1515 : // Report the SteamCoil energy from this component
1516 227370 : state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilEnergy =
1517 227370 : state.dataSteamCoils->SteamCoil(CoilNum).TotSteamHeatingCoilRate * state.dataHVACGlobal->TimeStepSysSec;
1518 227370 : }
1519 :
1520 : // End of Reporting subroutines for the SteamCoil Module
1521 :
1522 : // Utility subroutines for the SteamCoil Module
1523 :
1524 4 : int GetSteamCoilIndex(EnergyPlusData &state,
1525 : std::string_view CoilType, // must match coil types in this module
1526 : std::string const &CoilName, // must match coil names for the coil type
1527 : bool &ErrorsFound // set to true if problem
1528 : )
1529 : {
1530 :
1531 : // FUNCTION INFORMATION:
1532 : // AUTHOR R. Raustad
1533 : // DATE WRITTEN August 2007
1534 : // MODIFIED na
1535 : // RE-ENGINEERED na
1536 :
1537 : // PURPOSE OF THIS FUNCTION:
1538 : // This function looks up the index for the given coil and returns it. If
1539 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
1540 : // as zero.
1541 :
1542 : // Return value
1543 : int IndexNum; // returned air inlet node number of matched coil
1544 :
1545 : // Obtains and Allocates SteamCoil related parameters from input file
1546 4 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
1547 4 : GetSteamCoilInput(state);
1548 4 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
1549 : }
1550 :
1551 4 : if (CoilType == "COIL:HEATING:STEAM") {
1552 4 : IndexNum = Util::FindItemInList(CoilName, state.dataSteamCoils->SteamCoil);
1553 : } else {
1554 0 : IndexNum = 0;
1555 : }
1556 :
1557 4 : if (IndexNum == 0) {
1558 0 : ShowSevereError(state, format(R"(GetSteamCoilIndex: Could not find CoilType="{}" with Name="{}")", CoilType, CoilName));
1559 0 : ErrorsFound = true;
1560 : }
1561 :
1562 4 : return IndexNum;
1563 : }
1564 :
1565 0 : int GetCompIndex(EnergyPlusData &state, std::string_view const coilName)
1566 : {
1567 0 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
1568 0 : GetSteamCoilInput(state);
1569 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
1570 : }
1571 :
1572 0 : int indexNum = Util::FindItemInList(coilName, state.dataSteamCoils->SteamCoil);
1573 :
1574 0 : if (indexNum == 0) { // may not find coil name
1575 0 : ShowSevereError(state, format("GetSteamCoilIndex: Could not find CoilType = Coil:Heating:Steam with Name = \"{}\"", coilName));
1576 : }
1577 :
1578 0 : return indexNum;
1579 : }
1580 :
1581 0 : void CheckSteamCoilSchedule(
1582 : EnergyPlusData &state, [[maybe_unused]] std::string const &CompType, std::string_view CompName, Real64 &Value, int &CompIndex)
1583 : {
1584 :
1585 : // SUBROUTINE INFORMATION:
1586 : // AUTHOR Linda Lawrie
1587 : // DATE WRITTEN March 2006
1588 : // MODIFIED na
1589 : // RE-ENGINEERED na
1590 :
1591 : // PURPOSE OF THIS SUBROUTINE:
1592 : // Gets the correct schedule value for this coil
1593 :
1594 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1595 : int CoilNum;
1596 :
1597 : // Obtains and Allocates SteamCoil related parameters from input file
1598 0 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
1599 0 : GetSteamCoilInput(state);
1600 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
1601 : }
1602 :
1603 : // Find the correct Coil number
1604 0 : if (CompIndex == 0) {
1605 0 : CoilNum = Util::FindItemInList(CompName, state.dataSteamCoils->SteamCoil);
1606 0 : if (CoilNum == 0) {
1607 0 : ShowFatalError(state, format("CheckSteamCoilSchedule: Coil not found={}", CompName));
1608 : }
1609 0 : CompIndex = CoilNum;
1610 0 : Value = GetCurrentScheduleValue(state, state.dataSteamCoils->SteamCoil(CoilNum).SchedPtr); // not scheduled?
1611 : } else {
1612 0 : CoilNum = CompIndex;
1613 0 : if (CoilNum > state.dataSteamCoils->NumSteamCoils || CoilNum < 1) {
1614 0 : ShowFatalError(state,
1615 0 : format("SimulateSteamCoilComponents: Invalid CompIndex passed={}, Number of Steam Coils={}, Coil name={}",
1616 : CoilNum,
1617 0 : state.dataSteamCoils->NumSteamCoils,
1618 : CompName));
1619 : }
1620 0 : if (CompName != state.dataSteamCoils->SteamCoil(CoilNum).Name) {
1621 0 : ShowFatalError(state,
1622 0 : format("SimulateSteamCoilComponents: Invalid CompIndex passed={}, Coil name={}, stored Coil Name for that index={}",
1623 : CoilNum,
1624 : CompName,
1625 0 : state.dataSteamCoils->SteamCoil(CoilNum).Name));
1626 : }
1627 0 : Value = GetCurrentScheduleValue(state, state.dataSteamCoils->SteamCoil(CoilNum).SchedPtr); // not scheduled?
1628 : }
1629 0 : }
1630 :
1631 0 : Real64 GetCoilMaxWaterFlowRate(EnergyPlusData &state,
1632 : std::string const &CoilType, // must match coil types in this module
1633 : std::string const &CoilName, // must match coil names for the coil type
1634 : bool &ErrorsFound // set to true if problem
1635 : )
1636 : {
1637 :
1638 : // FUNCTION INFORMATION:
1639 : // AUTHOR Linda Lawrie
1640 : // DATE WRITTEN November 2006
1641 : // MODIFIED na
1642 : // RE-ENGINEERED na
1643 :
1644 : // PURPOSE OF THIS FUNCTION:
1645 : // This function looks up the max water flow rate for the given coil and returns it. If
1646 : // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
1647 : // as negative.
1648 :
1649 : // Return value
1650 : Real64 MaxWaterFlowRate; // returned max water flow rate of matched coil
1651 :
1652 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
1653 : int WhichCoil;
1654 :
1655 : // Obtains and Allocates SteamCoil related parameters from input file
1656 0 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
1657 0 : GetSteamCoilInput(state);
1658 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
1659 : }
1660 :
1661 0 : if (Util::SameString(CoilType, "Coil:Heating:Steam")) {
1662 0 : WhichCoil = Util::FindItem(CoilName, state.dataSteamCoils->SteamCoil);
1663 0 : if (WhichCoil != 0) {
1664 : // coil does not specify MaxWaterFlowRate
1665 0 : MaxWaterFlowRate = 0.0;
1666 0 : ShowRecurringWarningErrorAtEnd(state, "Requested Max Water Flow Rate from COIL:Heating:Steam N/A", state.dataSteamCoils->ErrCount);
1667 : }
1668 : } else {
1669 0 : WhichCoil = 0;
1670 : }
1671 :
1672 0 : if (WhichCoil == 0) {
1673 0 : ShowSevereError(state, format("GetCoilMaxWaterFlowRate: Could not find CoilType=\"{}\" with Name=\"{}\"", CoilType, CoilName));
1674 0 : ErrorsFound = true;
1675 0 : MaxWaterFlowRate = -1000.0;
1676 : }
1677 :
1678 0 : return MaxWaterFlowRate;
1679 : }
1680 :
1681 8 : Real64 GetCoilMaxSteamFlowRate(EnergyPlusData &state,
1682 : int const CoilIndex, // must match coil types in this module
1683 : bool &ErrorsFound // set to true if problem
1684 : )
1685 : {
1686 :
1687 : // FUNCTION INFORMATION:
1688 : // AUTHOR R. Raustad
1689 : // DATE WRITTEN August 2007
1690 : // MODIFIED na
1691 : // RE-ENGINEERED na
1692 :
1693 : // PURPOSE OF THIS FUNCTION:
1694 : // This function looks up the max steam flow rate for the given coil and returns it. If
1695 : // incorrect coil type or name is given, ErrorsFound is returned as true and flow rate is returned
1696 : // as zero.
1697 :
1698 : // Return value
1699 : Real64 MaxSteamFlowRate; // returned max steam flow rate of matched coil
1700 :
1701 : // Obtains and Allocates SteamCoil related parameters from input file
1702 8 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
1703 0 : GetSteamCoilInput(state);
1704 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
1705 : }
1706 :
1707 8 : if (CoilIndex == 0) {
1708 0 : ShowSevereError(state, "GetCoilMaxSteamFlowRate: Could not find CoilType = \"Coil:Heating:Steam\"");
1709 0 : ErrorsFound = true;
1710 0 : MaxSteamFlowRate = 0.0;
1711 : } else {
1712 8 : MaxSteamFlowRate = state.dataSteamCoils->SteamCoil(CoilIndex).MaxSteamVolFlowRate;
1713 : }
1714 :
1715 8 : return MaxSteamFlowRate;
1716 : }
1717 :
1718 2 : int GetCoilAirInletNode(EnergyPlusData &state,
1719 : int const CoilIndex, // must match coil types in this module
1720 : std::string const &CoilName, // must match coil names for the coil type
1721 : bool &ErrorsFound // set to true if problem
1722 : )
1723 : {
1724 :
1725 : // FUNCTION INFORMATION:
1726 : // AUTHOR R. Raustad
1727 : // DATE WRITTEN July 2007
1728 : // MODIFIED na
1729 : // RE-ENGINEERED na
1730 :
1731 : // PURPOSE OF THIS FUNCTION:
1732 : // This function looks up the air inlet node number for the given coil and returns it. If
1733 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
1734 : // as zero.
1735 :
1736 : // Return value
1737 : int NodeNumber; // returned air inlet node number of matched coil
1738 :
1739 : // Obtains and Allocates SteamCoil related parameters from input file
1740 2 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
1741 0 : GetSteamCoilInput(state);
1742 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
1743 : }
1744 :
1745 2 : if (CoilIndex == 0) {
1746 0 : ShowSevereError(state, format("GetCoilAirInletNode: Could not find CoilType = \"Coil:Heating:Steam\" with Name = {}", CoilName));
1747 0 : ErrorsFound = true;
1748 0 : NodeNumber = 0;
1749 : } else {
1750 2 : NodeNumber = state.dataSteamCoils->SteamCoil(CoilIndex).AirInletNodeNum;
1751 : }
1752 :
1753 2 : return NodeNumber;
1754 : }
1755 :
1756 2 : int GetCoilAirOutletNode(EnergyPlusData &state,
1757 : int const CoilIndex, // must match coil types in this module
1758 : std::string const &CoilName, // must match coil names for the coil type
1759 : bool &ErrorsFound // set to true if problem
1760 : )
1761 : {
1762 :
1763 : // FUNCTION INFORMATION:
1764 : // AUTHOR R. Raustad
1765 : // DATE WRITTEN July 2007
1766 : // MODIFIED na
1767 : // RE-ENGINEERED na
1768 :
1769 : // PURPOSE OF THIS FUNCTION:
1770 : // This function looks up the air outlet node number for the given coil and returns it. If
1771 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
1772 : // as zero.
1773 :
1774 : // METHODOLOGY EMPLOYED:
1775 : // na
1776 :
1777 : // REFERENCES:
1778 : // na
1779 :
1780 : // USE STATEMENTS:
1781 : // na
1782 :
1783 : // Return value
1784 : int NodeNumber; // returned air inlet node number of matched coil
1785 :
1786 : // Obtains and Allocates SteamCoil related parameters from input file
1787 2 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
1788 0 : GetSteamCoilInput(state);
1789 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
1790 : }
1791 :
1792 2 : if (CoilIndex == 0) {
1793 0 : ShowSevereError(state, format("GetCoilAirOutletNode: Could not find CoilType = \"Coil:Heating:Steam\" with Name = {}", CoilName));
1794 0 : ErrorsFound = true;
1795 0 : NodeNumber = 0;
1796 : } else {
1797 2 : NodeNumber = state.dataSteamCoils->SteamCoil(CoilIndex).AirOutletNodeNum;
1798 : }
1799 :
1800 2 : return NodeNumber;
1801 : }
1802 :
1803 0 : int GetCoilAirOutletNode(EnergyPlusData &state,
1804 : std::string const &CoilType, // must match coil types in this module
1805 : std::string const &CoilName, // must match coil names for the coil type
1806 : [[maybe_unused]] bool &ErrorsFound // set to true if problem
1807 : )
1808 : {
1809 :
1810 : // FUNCTION INFORMATION:
1811 : // AUTHOR R. Raustad
1812 : // DATE WRITTEN July 2007
1813 : // MODIFIED na
1814 : // RE-ENGINEERED na
1815 :
1816 : // PURPOSE OF THIS FUNCTION:
1817 : // This function looks up the air outlet node number for the given coil and returns it. If
1818 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
1819 : // as zero.
1820 :
1821 : // Return value
1822 : int NodeNumber; // returned air inlet node number of matched coil
1823 :
1824 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
1825 : int IndexNum; // returned air inlet node number of matched coil
1826 :
1827 : // Obtains and Allocates SteamCoil related parameters from input file
1828 0 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
1829 0 : GetSteamCoilInput(state);
1830 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
1831 : }
1832 :
1833 0 : if (Util::SameString(CoilType, "Coil:Heating:Steam")) {
1834 0 : IndexNum = Util::FindItem(CoilName, state.dataSteamCoils->SteamCoil);
1835 : } else {
1836 0 : IndexNum = 0;
1837 : }
1838 :
1839 0 : if (IndexNum == 0) {
1840 0 : NodeNumber = 0;
1841 : } else {
1842 0 : NodeNumber = state.dataSteamCoils->SteamCoil(IndexNum).AirOutletNodeNum;
1843 : }
1844 :
1845 0 : return NodeNumber;
1846 : }
1847 :
1848 0 : int GetCoilSteamInletNode(EnergyPlusData &state,
1849 : int const CoilIndex, // must match coil types in this module
1850 : std::string const &CoilName, // must match coil names for the coil type
1851 : bool &ErrorsFound // set to true if problem
1852 : )
1853 : {
1854 :
1855 : // FUNCTION INFORMATION:
1856 : // AUTHOR R. Raustad
1857 : // DATE WRITTEN July 2007
1858 : // MODIFIED na
1859 : // RE-ENGINEERED na
1860 :
1861 : // PURPOSE OF THIS FUNCTION:
1862 : // This function looks up the steam inlet node number for the given coil and returns it. If
1863 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
1864 : // as zero.
1865 :
1866 : // Return value
1867 : int NodeNumber; // returned air inlet node number of matched coil
1868 :
1869 : // Obtains and Allocates SteamCoil related parameters from input file
1870 0 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
1871 0 : GetSteamCoilInput(state);
1872 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
1873 : }
1874 :
1875 0 : if (CoilIndex == 0) {
1876 0 : ShowSevereError(state, format("GetCoilSteamInletNode: Could not find CoilType = \"Coil:Heating:Steam\" with Name = {}", CoilName));
1877 0 : ErrorsFound = true;
1878 0 : NodeNumber = 0;
1879 : } else {
1880 0 : NodeNumber = state.dataSteamCoils->SteamCoil(CoilIndex).SteamInletNodeNum;
1881 : }
1882 :
1883 0 : return NodeNumber;
1884 : }
1885 :
1886 28 : int GetCoilSteamInletNode(EnergyPlusData &state,
1887 : std::string const &CoilType, // must match coil types in this module
1888 : std::string const &CoilName, // must match coil names for the coil type
1889 : bool &ErrorsFound // set to true if problem
1890 : )
1891 : {
1892 :
1893 : // FUNCTION INFORMATION:
1894 : // AUTHOR L. Lawrie (based on R. Raustad)
1895 : // DATE WRITTEN June 2008
1896 : // MODIFIED na
1897 : // RE-ENGINEERED na
1898 :
1899 : // PURPOSE OF THIS FUNCTION:
1900 : // This function looks up the steam inlet node number for the given coil and returns it. If
1901 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
1902 : // as zero.
1903 :
1904 : // Return value
1905 : int NodeNumber; // returned air inlet node number of matched coil
1906 :
1907 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
1908 : int IndexNum; // returned air inlet node number of matched coil
1909 :
1910 : // Obtains and Allocates SteamCoil related parameters from input file
1911 28 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
1912 3 : GetSteamCoilInput(state);
1913 3 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
1914 : }
1915 :
1916 28 : if (Util::SameString(CoilType, "Coil:Heating:Steam")) {
1917 28 : IndexNum = Util::FindItem(CoilName, state.dataSteamCoils->SteamCoil);
1918 : } else {
1919 0 : IndexNum = 0;
1920 : }
1921 :
1922 28 : if (IndexNum == 0) {
1923 0 : ShowSevereError(state, format("GetCoilSteamInletNode: Could not find CoilType = \"Coil:Heating:Steam\" with Name = {}", CoilName));
1924 0 : ErrorsFound = true;
1925 0 : NodeNumber = 0;
1926 : } else {
1927 28 : NodeNumber = state.dataSteamCoils->SteamCoil(IndexNum).SteamInletNodeNum;
1928 : }
1929 :
1930 28 : return NodeNumber;
1931 : }
1932 :
1933 0 : int GetCoilSteamOutletNode(EnergyPlusData &state,
1934 : int const CoilIndex, // must match coil types in this module
1935 : std::string const &CoilName, // must match coil names for the coil type
1936 : bool &ErrorsFound // set to true if problem
1937 : )
1938 : {
1939 :
1940 : // FUNCTION INFORMATION:
1941 : // AUTHOR R. Raustad
1942 : // DATE WRITTEN July 2007
1943 : // MODIFIED na
1944 : // RE-ENGINEERED na
1945 :
1946 : // PURPOSE OF THIS FUNCTION:
1947 : // This function looks up the steam inlet node number for the given coil and returns it. If
1948 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
1949 : // as zero.
1950 :
1951 : // Return value
1952 : int NodeNumber; // returned air inlet node number of matched coil
1953 :
1954 : // Obtains and Allocates SteamCoil related parameters from input file
1955 0 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
1956 0 : GetSteamCoilInput(state);
1957 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
1958 : }
1959 :
1960 0 : if (CoilIndex == 0) {
1961 0 : ShowSevereError(state, format("GetCoilSteamInletNode: Could not find CoilType = \"Coil:Heating:Steam\" with Name = {}", CoilName));
1962 0 : ErrorsFound = true;
1963 0 : NodeNumber = 0;
1964 : } else {
1965 0 : NodeNumber = state.dataSteamCoils->SteamCoil(CoilIndex).SteamOutletNodeNum;
1966 : }
1967 :
1968 0 : return NodeNumber;
1969 : }
1970 :
1971 13 : int GetCoilSteamOutletNode(EnergyPlusData &state,
1972 : std::string_view CoilType, // must match coil types in this module
1973 : std::string const &CoilName, // must match coil names for the coil type
1974 : bool &ErrorsFound // set to true if problem
1975 : )
1976 : {
1977 :
1978 : // FUNCTION INFORMATION:
1979 : // AUTHOR L. Lawrie (based on R. Raustad)
1980 : // DATE WRITTEN June 2008
1981 : // MODIFIED na
1982 : // RE-ENGINEERED na
1983 :
1984 : // PURPOSE OF THIS FUNCTION:
1985 : // This function looks up the steam inlet node number for the given coil and returns it. If
1986 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
1987 : // as zero.
1988 :
1989 : // Return value
1990 : int NodeNumber; // returned air inlet node number of matched coil
1991 :
1992 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
1993 : int IndexNum; // returned air inlet node number of matched coil
1994 :
1995 : // Obtains and Allocates SteamCoil related parameters from input file
1996 13 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
1997 0 : GetSteamCoilInput(state);
1998 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
1999 : }
2000 :
2001 13 : if (Util::SameString(CoilType, "Coil:Heating:Steam")) {
2002 13 : IndexNum = Util::FindItem(CoilName, state.dataSteamCoils->SteamCoil);
2003 : } else {
2004 0 : IndexNum = 0;
2005 : }
2006 :
2007 13 : if (IndexNum == 0) {
2008 0 : ShowSevereError(state, format("GetCoilSteamInletNode: Could not find CoilType = \"Coil:Heating:Steam\" with Name = {}", CoilName));
2009 0 : ErrorsFound = true;
2010 0 : NodeNumber = 0;
2011 : } else {
2012 13 : NodeNumber = state.dataSteamCoils->SteamCoil(IndexNum).SteamOutletNodeNum;
2013 : }
2014 :
2015 13 : return NodeNumber;
2016 : }
2017 :
2018 6622 : Real64 GetCoilCapacity(EnergyPlusData &state,
2019 : std::string const &CoilType, // must match coil types in this module
2020 : std::string const &CoilName, // must match coil names for the coil type
2021 : bool &ErrorsFound // set to true if problem
2022 : )
2023 : {
2024 :
2025 : // FUNCTION INFORMATION:
2026 : // AUTHOR R. Raustad
2027 : // DATE WRITTEN July 2007
2028 : // MODIFIED na
2029 : // RE-ENGINEERED na
2030 :
2031 : // PURPOSE OF THIS FUNCTION:
2032 : // This function looks up the steam coils operating capacity and returns it. If
2033 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
2034 : // as zero.
2035 :
2036 : // Return value
2037 : Real64 Capacity; // returned operating capacity of matched coil (W)
2038 :
2039 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2040 : int WhichCoil;
2041 :
2042 : // Obtains and Allocates SteamCoil related parameters from input file
2043 6622 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
2044 0 : GetSteamCoilInput(state);
2045 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
2046 : }
2047 :
2048 6622 : if (Util::SameString(CoilType, "Coil:Heating:Steam")) {
2049 6622 : WhichCoil = Util::FindItem(CoilName, state.dataSteamCoils->SteamCoil);
2050 6622 : if (WhichCoil != 0) {
2051 : // coil does not specify MaxWaterFlowRate
2052 6622 : Capacity = state.dataSteamCoils->SteamCoil(WhichCoil).OperatingCapacity;
2053 : }
2054 : } else {
2055 0 : WhichCoil = 0;
2056 : }
2057 :
2058 6622 : if (WhichCoil == 0) {
2059 0 : ShowSevereError(state, format("GetCoilSteamInletNode: Could not find CoilType=\"{}\" with Name=\"{}\"", CoilType, CoilName));
2060 0 : ErrorsFound = true;
2061 0 : Capacity = 0.0;
2062 : }
2063 :
2064 6622 : return Capacity;
2065 : }
2066 :
2067 0 : CoilControlType GetTypeOfCoil(EnergyPlusData &state,
2068 : int const CoilIndex, // must match coil types in this module
2069 : std::string const &CoilName, // must match coil names for the coil type
2070 : bool &ErrorsFound // set to true if problem
2071 : )
2072 : {
2073 :
2074 : // FUNCTION INFORMATION:
2075 : // AUTHOR R. Raustad
2076 : // DATE WRITTEN July 2007
2077 : // MODIFIED na
2078 : // RE-ENGINEERED na
2079 :
2080 : // PURPOSE OF THIS FUNCTION:
2081 : // This function looks up the steam coils operating capacity and returns it. If
2082 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
2083 : // as zero.
2084 :
2085 : // Obtains and Allocates SteamCoil related parameters from input file
2086 0 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
2087 0 : GetSteamCoilInput(state);
2088 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
2089 : }
2090 :
2091 0 : if (CoilIndex == 0) {
2092 0 : ShowSevereError(state, format("GetCoilSteamInletNode: Could not find CoilType = \"Coil:Heating:Steam\" with Name = {}", CoilName));
2093 0 : ErrorsFound = true;
2094 0 : return CoilControlType::Invalid;
2095 : } else {
2096 0 : return state.dataSteamCoils->SteamCoil(CoilIndex).TypeOfCoil;
2097 : }
2098 : }
2099 :
2100 0 : int GetSteamCoilControlNodeNum(EnergyPlusData &state,
2101 : std::string const &CoilType, // must match coil types in this module
2102 : std::string const &CoilName, // must match coil names for the coil type
2103 : bool &ErrorFlag // set to true if problem
2104 : )
2105 : {
2106 :
2107 : // FUNCTION INFORMATION:
2108 : // AUTHOR B. Nigusse, FSEC
2109 : // DATE WRITTEN January 2012
2110 : // MODIFIED na
2111 : // RE-ENGINEERED na
2112 :
2113 : // PURPOSE OF THIS FUNCTION:
2114 : // This function looks up the steam coils and returns the steam control node number. If
2115 : // incorrect coil type or name is given, ErrorsFound is returned as true and node number is returned
2116 : // as zero.
2117 :
2118 : // Return value
2119 : int NodeNumber; // returned node number of matched coil
2120 :
2121 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2122 : int WhichCoil;
2123 :
2124 : // Obtains and Allocates SteamCoil related parameters from input file
2125 0 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
2126 0 : GetSteamCoilInput(state);
2127 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
2128 : }
2129 :
2130 0 : WhichCoil = 0;
2131 0 : NodeNumber = 0;
2132 0 : if (Util::SameString(CoilType, "Coil:Heating:Steam")) {
2133 0 : WhichCoil = Util::FindItem(CoilName, state.dataSteamCoils->SteamCoil);
2134 0 : if (WhichCoil != 0) {
2135 0 : NodeNumber = state.dataSteamCoils->SteamCoil(WhichCoil).TempSetPointNodeNum;
2136 : }
2137 : } else {
2138 0 : WhichCoil = 0;
2139 : }
2140 :
2141 0 : if (WhichCoil == 0) {
2142 0 : ShowSevereError(state, format("GetSteamCoilControlNodeNum: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
2143 0 : ErrorFlag = true;
2144 0 : NodeNumber = 0;
2145 : }
2146 :
2147 0 : return NodeNumber;
2148 : }
2149 :
2150 0 : int GetSteamCoilAvailScheduleIndex(EnergyPlusData &state,
2151 : std::string const &CoilType, // must match coil types in this module
2152 : std::string const &CoilName, // must match coil names for the coil type
2153 : bool &ErrorsFound // set to true if problem
2154 : )
2155 : {
2156 :
2157 : // FUNCTION INFORMATION:
2158 : // AUTHOR Chandan Sharma, FSEC
2159 : // DATE WRITTEN February 2013
2160 : // MODIFIED na
2161 : // RE-ENGINEERED na
2162 :
2163 : // PURPOSE OF THIS FUNCTION:
2164 : // This function looks up the given coil and returns the availability schedule index. If
2165 : // incorrect coil type or name is given, ErrorsFound is returned as true and index is returned
2166 : // as zero.
2167 :
2168 : // Return value
2169 : int AvailSchIndex; // returned availability schedule of matched coil
2170 :
2171 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2172 : int WhichCoil;
2173 :
2174 : // Obtains and Allocates HeatingCoil related parameters from input file
2175 0 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) { // First time subroutine has been entered
2176 0 : GetSteamCoilInput(state);
2177 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
2178 : }
2179 :
2180 0 : WhichCoil = 0;
2181 0 : AvailSchIndex = 0;
2182 :
2183 0 : if (Util::SameString(CoilType, "Coil:Heating:Steam")) {
2184 0 : WhichCoil = Util::FindItem(CoilName, state.dataSteamCoils->SteamCoil);
2185 0 : if (WhichCoil != 0) {
2186 0 : AvailSchIndex = state.dataSteamCoils->SteamCoil(WhichCoil).SchedPtr;
2187 : }
2188 : } else {
2189 0 : WhichCoil = 0;
2190 : }
2191 :
2192 0 : if (WhichCoil == 0) {
2193 0 : ShowSevereError(state, format("GetCoilAvailScheduleIndex: Could not find Coil, Type=\"{}\" Name=\"{}\"", CoilType, CoilName));
2194 0 : ErrorsFound = true;
2195 0 : AvailSchIndex = 0;
2196 : }
2197 :
2198 0 : return AvailSchIndex;
2199 : }
2200 :
2201 0 : void SetSteamCoilData(EnergyPlusData &state,
2202 : int const CoilNum, // Number of hot water heating Coil
2203 : bool &ErrorsFound, // Set to true if certain errors found
2204 : ObjexxFCL::Optional_bool DesiccantRegenerationCoil, // Flag that this coil is used as regeneration air heating coil
2205 : ObjexxFCL::Optional_int DesiccantDehumIndex // Index for the desiccant dehum system where this caoil is used
2206 : )
2207 : {
2208 :
2209 : // FUNCTION INFORMATION:
2210 : // AUTHOR Bereket Nigusse
2211 : // DATE WRITTEN February 2016
2212 : // MODIFIED na
2213 : // RE-ENGINEERED na
2214 :
2215 : // PURPOSE OF THIS FUNCTION:
2216 : // This function sets data to water Heating Coil using the coil index and arguments passed
2217 :
2218 0 : if (state.dataSteamCoils->GetSteamCoilsInputFlag) {
2219 0 : GetSteamCoilInput(state);
2220 0 : state.dataSteamCoils->GetSteamCoilsInputFlag = false;
2221 : }
2222 :
2223 0 : if (CoilNum <= 0 || CoilNum > state.dataSteamCoils->NumSteamCoils) {
2224 0 : ShowSevereError(state,
2225 0 : format("SetHeatingCoilData: called with heating coil Number out of range={} should be >0 and <{}",
2226 : CoilNum,
2227 0 : state.dataSteamCoils->NumSteamCoils));
2228 0 : ErrorsFound = true;
2229 0 : return;
2230 : }
2231 :
2232 0 : if (present(DesiccantRegenerationCoil)) {
2233 0 : state.dataSteamCoils->SteamCoil(CoilNum).DesiccantRegenerationCoil = DesiccantRegenerationCoil;
2234 : }
2235 :
2236 0 : if (present(DesiccantDehumIndex)) {
2237 0 : state.dataSteamCoils->SteamCoil(CoilNum).DesiccantDehumNum = DesiccantDehumIndex;
2238 : }
2239 : }
2240 : // End of Utility subroutines for the SteamCoil Module
2241 :
2242 : } // namespace SteamCoils
2243 :
2244 : } // namespace EnergyPlus
|