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