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/BranchNodeConnections.hh>
57 : #include <EnergyPlus/CurveManager.hh>
58 : #include <EnergyPlus/DXCoils.hh>
59 : #include <EnergyPlus/Data/EnergyPlusData.hh>
60 : #include <EnergyPlus/DataHVACGlobals.hh>
61 : #include <EnergyPlus/DataLoopNode.hh>
62 : #include <EnergyPlus/DataSizing.hh>
63 : #include <EnergyPlus/DesiccantDehumidifiers.hh>
64 : #include <EnergyPlus/EMSManager.hh>
65 : #include <EnergyPlus/Fans.hh>
66 : #include <EnergyPlus/FluidProperties.hh>
67 : #include <EnergyPlus/General.hh>
68 : #include <EnergyPlus/GeneralRoutines.hh>
69 : #include <EnergyPlus/GlobalNames.hh>
70 : #include <EnergyPlus/HVACFan.hh>
71 : #include <EnergyPlus/HeatRecovery.hh>
72 : #include <EnergyPlus/HeatingCoils.hh>
73 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
74 : #include <EnergyPlus/NodeInputManager.hh>
75 : #include <EnergyPlus/OutAirNodeManager.hh>
76 : #include <EnergyPlus/OutputProcessor.hh>
77 : #include <EnergyPlus/PlantUtilities.hh>
78 : #include <EnergyPlus/Psychrometrics.hh>
79 : #include <EnergyPlus/ScheduleManager.hh>
80 : #include <EnergyPlus/SteamCoils.hh>
81 : #include <EnergyPlus/UtilityRoutines.hh>
82 : #include <EnergyPlus/VariableSpeedCoils.hh>
83 : #include <EnergyPlus/WaterCoils.hh>
84 :
85 : namespace EnergyPlus {
86 :
87 : namespace DesiccantDehumidifiers {
88 :
89 : // Module containing the routines dealing with dehumidifiers
90 :
91 : // MODULE INFORMATION:
92 : // AUTHOR Michael J. Witte, GARD Analytics, Inc.
93 : // for Gas Research Institute
94 : // DATE WRITTEN March 2001
95 : // MODIFIED Jan 2005 M. J. Witte, GARD Analytics, Inc.
96 : // Add new control type option:
97 : // NODE LEAVING HUMRAT SETPOINT:BYPASS
98 : // Change existing control type to:
99 : // FIXED LEAVING HUMRAT SETPOINT:BYPASS
100 : // Work supported by ASHRAE research project 1254-RP
101 : // June 2007 R. Raustad, FSEC
102 : // Added new dehumidifier type -- DESICCANT DEHUMIDIFIER
103 : // Jan 2012 B. Nigusse, FSEC
104 : // Added steam and hot water heating coils
105 :
106 : // RE-ENGINEERED na
107 :
108 : // PURPOSE OF THIS MODULE:
109 : // To encapsulate the data and routines required to model desiccant dehumidifier
110 : // components in the EnergyPlus HVAC simulation
111 :
112 : // METHODOLOGY EMPLOYED:
113 : // The desiccant dehumidifier emcompasses not just the component but also its
114 : // control. The desiccant dehumidifier removes moisture from its air inlet to meet
115 : // the HumRatMax setpoint at its exit node. The HumRatMax is set by
116 : // an external setpoint manager or is a fixed user input.
117 :
118 : // REFERENCES: na
119 :
120 : // OTHER NOTES: This module is based substantially on the Humidifiers module.
121 : // authored by Fred Buhl.
122 : // Development of portions of this module was funded by the Gas Research Institute.
123 : // (Please see copyright and disclaimer information at end of module)
124 :
125 : // USE STATEMENTS:
126 : // Use statements for data only modules
127 : // Using/Aliasing
128 : using namespace DataLoopNode;
129 : using DataHVACGlobals::BlowThru;
130 : using DataHVACGlobals::Coil_HeatingElectric;
131 : using DataHVACGlobals::Coil_HeatingGasOrOtherFuel;
132 : using DataHVACGlobals::Coil_HeatingSteam;
133 : using DataHVACGlobals::Coil_HeatingWater;
134 : using DataHVACGlobals::ContFanCycCoil;
135 : using DataHVACGlobals::DrawThru;
136 : using DataHVACGlobals::SmallMassFlow;
137 : // Use statements for access to subroutines in other modules
138 : using namespace ScheduleManager;
139 : using namespace HeatingCoils;
140 : using namespace Fans;
141 : using namespace Curve;
142 : using namespace Psychrometrics;
143 : using FluidProperties::GetSatDensityRefrig;
144 :
145 771 : static std::string const fluidNameSteam("STEAM");
146 :
147 275214 : void SimDesiccantDehumidifier(EnergyPlusData &state,
148 : std::string const &CompName, // name of the dehumidifier unit
149 : bool const FirstHVACIteration, // TRUE if 1st HVAC simulation of system timestep
150 : int &CompIndex)
151 : {
152 :
153 : // SUBROUTINE INFORMATION:
154 : // AUTHOR Michael J. Witte, GARD Analytics, Inc.
155 : // for Gas Research Institute
156 : // DATE WRITTEN March 2001
157 : // MODIFIED June 2007, R. Raustad, Added new dehumidifier type -- DESICCANT DEHUMIDIFIER
158 : // RE-ENGINEERED na
159 :
160 : // PURPOSE OF THIS SUBROUTINE:
161 : // Manage the simulation of an air dehumidifier
162 :
163 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
164 : int DesicDehumNum; // index of solid desiccant unit being simulated
165 : Real64 HumRatNeeded; // process air leaving humidity ratio set by controller [kg water/kg air]
166 :
167 275214 : if (state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier) {
168 7 : GetDesiccantDehumidifierInput(state);
169 7 : state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier = false;
170 : }
171 :
172 : // Get the desiccant dehumidifier unit index
173 275214 : if (CompIndex == 0) {
174 9 : DesicDehumNum = UtilityRoutines::FindItemInList(CompName, state.dataDesiccantDehumidifiers->DesicDehum);
175 9 : if (DesicDehumNum == 0) {
176 0 : ShowFatalError(state, "SimDesiccantDehumidifier: Unit not found=" + CompName);
177 : }
178 9 : CompIndex = DesicDehumNum;
179 : } else {
180 275205 : DesicDehumNum = CompIndex;
181 275205 : if (DesicDehumNum > state.dataDesiccantDehumidifiers->NumDesicDehums || DesicDehumNum < 1) {
182 0 : ShowFatalError(state,
183 0 : format("SimDesiccantDehumidifier: Invalid CompIndex passed={}, Number of Units={}, Entered Unit name={}",
184 : DesicDehumNum,
185 0 : state.dataDesiccantDehumidifiers->NumDesicDehums,
186 0 : CompName));
187 : }
188 275205 : if (CompName != state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).Name) {
189 0 : ShowFatalError(state,
190 0 : format("SimDesiccantDehumidifier: Invalid CompIndex passed={}, Unit name={}, stored Unit Name for that index={}",
191 : DesicDehumNum,
192 : CompName,
193 0 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).Name));
194 : }
195 : }
196 :
197 275214 : InitDesiccantDehumidifier(state, DesicDehumNum, FirstHVACIteration);
198 :
199 275214 : ControlDesiccantDehumidifier(state, DesicDehumNum, HumRatNeeded, FirstHVACIteration);
200 :
201 : // call the correct dehumidifier calculation routine
202 275214 : switch (state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).DehumTypeCode) {
203 93953 : case DesicDehumType::Solid: {
204 93953 : CalcSolidDesiccantDehumidifier(state, DesicDehumNum, HumRatNeeded, FirstHVACIteration);
205 93953 : } break;
206 181261 : case DesicDehumType::Generic: {
207 181261 : CalcGenericDesiccantDehumidifier(state, DesicDehumNum, HumRatNeeded, FirstHVACIteration);
208 181261 : } break;
209 0 : default: {
210 0 : ShowFatalError(state, "Invalid type, Desiccant Dehumidifer=" + state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).DehumType);
211 0 : } break;
212 : }
213 :
214 275214 : UpdateDesiccantDehumidifier(state, DesicDehumNum);
215 :
216 275214 : ReportDesiccantDehumidifier(state, DesicDehumNum);
217 275214 : }
218 :
219 7 : void GetDesiccantDehumidifierInput(EnergyPlusData &state)
220 : {
221 :
222 : // SUBROUTINE INFORMATION:
223 : // AUTHOR Michael J. Witte, GARD Analytics, Inc.
224 : // for Gas Research Institute
225 : // DATE WRITTEN March 2001
226 : // MODIFIED Jan 2005 M. J. Witte, GARD Analytics, Inc.
227 : // Add new control type option:
228 : // NODE LEAVING HUMRAT SETPOINT:BYPASS
229 : // Change existing control type to:
230 : // FIXED LEAVING HUMRAT SETPOINT:BYPASS
231 : // Work supported by ASHRAE research project 1254-RP
232 : // June 2007 R. Raustad, FSEC
233 : // Added new dehumidifier type -- DESICCANT DEHUMIDIFIER
234 : // RE-ENGINEERED na
235 :
236 : // PURPOSE OF THIS SUBROUTINE:
237 : // Obtains input data for humidifiers and stores it in dehumidifier data structures.
238 :
239 : // METHODOLOGY EMPLOYED:
240 : // Uses InputProcessor "Get" routines to obtain data.
241 :
242 : // Using/Aliasing
243 : using BranchNodeConnections::SetUpCompSets;
244 : using BranchNodeConnections::TestCompSet;
245 : using NodeInputManager::GetOnlySingleNode;
246 7 : auto &GetDXCoilOutletNode(DXCoils::GetCoilOutletNode);
247 : using DXCoils::GetCoilCondenserInletNode;
248 : using DXCoils::GetDXCoilBypassedFlowFrac;
249 : using DXCoils::GetDXCoilIndex;
250 7 : auto &GetDXCoilCapacity(DXCoils::GetCoilCapacity);
251 : using HeatRecovery::GetSecondaryInletNode;
252 : using HeatRecovery::GetSecondaryOutletNode;
253 : using HeatRecovery::GetSupplyInletNode;
254 : using HeatRecovery::GetSupplyOutletNode;
255 7 : auto &GetHeatingCoilInletNode(HeatingCoils::GetCoilInletNode);
256 7 : auto &GetHeatingCoilOutletNode(HeatingCoils::GetCoilOutletNode);
257 7 : auto &GetHeatReclaimSourceIndexNum(HeatingCoils::GetHeatReclaimSourceIndex);
258 7 : auto &GetHeatingCoilIndex(HeatingCoils::GetCoilIndex);
259 7 : auto &GetHeatingCoilControlNodeNum(HeatingCoils::GetCoilControlNodeNum);
260 : using WaterCoils::GetCoilMaxWaterFlowRate;
261 : using WaterCoils::GetCoilWaterInletNode;
262 : using WaterCoils::GetWaterCoilIndex;
263 7 : auto &GetWaterCoilInletNode(WaterCoils::GetCoilInletNode);
264 7 : auto &GetWaterCoilOutletNode(WaterCoils::GetCoilOutletNode);
265 7 : auto &GetSteamCoilAirInletNode(SteamCoils::GetCoilAirInletNode);
266 : using SteamCoils::GetCoilAirOutletNode;
267 : using SteamCoils::GetCoilSteamInletNode;
268 : using SteamCoils::GetSteamCoilIndex;
269 7 : auto &GetCoilMaxSteamFlowRate(SteamCoils::GetCoilMaxSteamFlowRate);
270 : using OutAirNodeManager::CheckAndAddAirNodeNumber;
271 : using OutAirNodeManager::CheckOutAirNodeNumber;
272 : using SteamCoils::GetSteamCoilControlNodeNum;
273 : using SteamCoils::SetSteamCoilData;
274 : using WaterCoils::SetWaterCoilData;
275 :
276 : // SUBROUTINE PARAMETER DEFINITIONS:
277 : static constexpr std::string_view RoutineName("GetDesiccantDehumidifierInput: "); // include trailing blank space
278 7 : static std::string const dehumidifierDesiccantNoFans("Dehumidifier:Desiccant:NoFans");
279 :
280 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
281 : int DesicDehumIndex; // Loop index
282 : int DesicDehumNum; // Current desiccant dehumidifier number
283 : int NumAlphas; // Number of Alphas for each GetObjectItem call
284 : int NumNumbers; // Number of Numbers for each GetObjectItem call
285 : int IOStatus; // Used in GetObjectItem
286 7 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
287 7 : bool ErrorsFound2(false); // Set to true if errors in input, fatal at end of routine
288 7 : bool ErrorsFoundGeneric(false); // Set to true if errors in input, fatal at end of routine
289 : bool IsNotOK; // Flag to verify name
290 : bool OANodeError; // Flag for check on outside air node
291 14 : std::string RegenFanInlet; // Desiccant system regeneration air fan inlet node
292 14 : std::string RegenFanOutlet; // Desiccant system regeneration air fan outlet node
293 14 : std::string RegenCoilInlet; // Desiccant system regeneration air heater inlet node
294 14 : std::string RegenCoilOutlet; // Desiccant system regeneration air heater outlet node
295 14 : std::string ProcAirInlet; // HX process air inlet node
296 14 : std::string ProcAirOutlet; // HX process air outlet node
297 14 : std::string RegenAirInlet; // HX regeneration air inlet node
298 14 : std::string RegenAirOutlet; // HX regeneration air outlet node
299 14 : std::string CurrentModuleObject; // for ease in getting objects
300 : int DesuperHeaterIndex; // Index of desuperheater heating coil
301 : int RegenCoilControlNodeNum; // Control node number of regen heating coil
302 : Real64 CoilBypassedFlowFrac; // Bypass air fraction for multimode DX coils
303 14 : Array1D_string Alphas; // Alpha input items for object
304 14 : Array1D_string cAlphaFields; // Alpha field names
305 14 : Array1D_string cNumericFields; // Numeric field names
306 14 : Array1D<Real64> Numbers; // Numeric input items for object
307 14 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
308 14 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
309 : int RegenCoilAirInletNode; // regen heating coil air inlet node number
310 : int RegenCoilAirOutletNode; // regen heating coil air outlet node number
311 : bool errFlag; // local error flag
312 14 : std::string RegenCoilType; // Regen heating coil type
313 14 : std::string RegenCoilName; // Regen heating coil name
314 : int SteamIndex; // steam coil Index
315 7 : bool RegairHeatingCoilFlag(false); // local error flag
316 :
317 7 : auto &DesicDehum(state.dataDesiccantDehumidifiers->DesicDehum);
318 7 : auto &MaxNums(state.dataDesiccantDehumidifiers->MaxNums);
319 7 : auto &MaxAlphas(state.dataDesiccantDehumidifiers->MaxAlphas);
320 7 : auto &TotalArgs(state.dataDesiccantDehumidifiers->TotalArgs);
321 7 : auto &SteamDensity(state.dataDesiccantDehumidifiers->SteamDensity);
322 :
323 7 : state.dataDesiccantDehumidifiers->NumSolidDesicDehums =
324 7 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, dehumidifierDesiccantNoFans);
325 7 : state.dataDesiccantDehumidifiers->NumGenericDesicDehums =
326 14 : state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Dehumidifier:Desiccant:System");
327 7 : state.dataDesiccantDehumidifiers->NumDesicDehums =
328 7 : state.dataDesiccantDehumidifiers->NumSolidDesicDehums + state.dataDesiccantDehumidifiers->NumGenericDesicDehums;
329 : // allocate the data array
330 7 : state.dataDesiccantDehumidifiers->DesicDehum.allocate(state.dataDesiccantDehumidifiers->NumDesicDehums);
331 7 : state.dataDesiccantDehumidifiers->UniqueDesicDehumNames.reserve(state.dataDesiccantDehumidifiers->NumDesicDehums);
332 7 : state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier = false;
333 :
334 7 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, dehumidifierDesiccantNoFans, TotalArgs, NumAlphas, NumNumbers);
335 7 : MaxNums = max(MaxNums, NumNumbers);
336 7 : MaxAlphas = max(MaxAlphas, NumAlphas);
337 7 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(state, "Dehumidifier:Desiccant:System", TotalArgs, NumAlphas, NumNumbers);
338 7 : MaxNums = max(MaxNums, NumNumbers);
339 7 : MaxAlphas = max(MaxAlphas, NumAlphas);
340 :
341 7 : Alphas.allocate(MaxAlphas);
342 7 : cAlphaFields.allocate(MaxAlphas);
343 7 : cNumericFields.allocate(MaxNums);
344 7 : Numbers.dimension(MaxNums, 0.0);
345 7 : lAlphaBlanks.dimension(MaxAlphas, true);
346 7 : lNumericBlanks.dimension(MaxNums, true);
347 :
348 : // loop over solid desiccant dehumidifiers and load the input data
349 7 : CurrentModuleObject = dehumidifierDesiccantNoFans;
350 12 : for (DesicDehumIndex = 1; DesicDehumIndex <= state.dataDesiccantDehumidifiers->NumSolidDesicDehums; ++DesicDehumIndex) {
351 5 : RegenCoilAirInletNode = 0;
352 5 : RegenCoilAirOutletNode = 0;
353 5 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
354 : CurrentModuleObject,
355 : DesicDehumIndex,
356 : Alphas,
357 : NumAlphas,
358 : Numbers,
359 : NumNumbers,
360 : IOStatus,
361 : lNumericBlanks,
362 : lAlphaBlanks,
363 : cAlphaFields,
364 : cNumericFields);
365 5 : DesicDehumNum = DesicDehumIndex;
366 :
367 10 : GlobalNames::VerifyUniqueInterObjectName(
368 10 : state, state.dataDesiccantDehumidifiers->UniqueDesicDehumNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFound);
369 5 : DesicDehum(DesicDehumNum).Name = Alphas(1);
370 5 : DesicDehum(DesicDehumNum).DehumType = CurrentModuleObject;
371 5 : DesicDehum(DesicDehumNum).DehumTypeCode = DesicDehumType::Solid;
372 5 : DesicDehum(DesicDehumNum).Sched = Alphas(2);
373 5 : if (lAlphaBlanks(2)) {
374 0 : DesicDehum(DesicDehumNum).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
375 : } else {
376 5 : DesicDehum(DesicDehumNum).SchedPtr = GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer
377 5 : if (DesicDehum(DesicDehumNum).SchedPtr == 0) {
378 0 : ShowSevereError(state,
379 0 : std::string{RoutineName} + CurrentModuleObject + ": invalid " + cAlphaFields(2) + " entered =" + Alphas(2) +
380 0 : " for " + cAlphaFields(1) + '=' + Alphas(1));
381 0 : ErrorsFound = true;
382 : }
383 : }
384 : // For node connections, this object is both a parent and a non-parent, because the
385 : // Desiccant wheel is not called out as a separate component, its nodes must be connected
386 : // as ObjectIsNotParent. But for the Regen fan, the nodes are connected as ObjectIsParent
387 5 : DesicDehum(DesicDehumNum).ProcAirInNode = GetOnlySingleNode(state,
388 5 : Alphas(3),
389 : ErrorsFound,
390 : DataLoopNode::ConnectionObjectType::DehumidifierDesiccantNoFans,
391 5 : Alphas(1),
392 : DataLoopNode::NodeFluidType::Air,
393 : DataLoopNode::ConnectionType::Inlet,
394 : NodeInputManager::CompFluidStream::Primary,
395 5 : ObjectIsNotParent);
396 :
397 5 : DesicDehum(DesicDehumNum).ProcAirOutNode = GetOnlySingleNode(state,
398 5 : Alphas(4),
399 : ErrorsFound,
400 : DataLoopNode::ConnectionObjectType::DehumidifierDesiccantNoFans,
401 5 : Alphas(1),
402 : DataLoopNode::NodeFluidType::Air,
403 : DataLoopNode::ConnectionType::Outlet,
404 : NodeInputManager::CompFluidStream::Primary,
405 5 : ObjectIsNotParent);
406 :
407 5 : DesicDehum(DesicDehumNum).RegenAirInNode = GetOnlySingleNode(state,
408 5 : Alphas(5),
409 : ErrorsFound,
410 : DataLoopNode::ConnectionObjectType::DehumidifierDesiccantNoFans,
411 5 : Alphas(1),
412 : DataLoopNode::NodeFluidType::Air,
413 : DataLoopNode::ConnectionType::Inlet,
414 : NodeInputManager::CompFluidStream::Secondary,
415 5 : ObjectIsNotParent);
416 :
417 5 : DesicDehum(DesicDehumNum).RegenFanInNode = GetOnlySingleNode(state,
418 5 : Alphas(6),
419 : ErrorsFound,
420 : DataLoopNode::ConnectionObjectType::DehumidifierDesiccantNoFans,
421 5 : Alphas(1),
422 : DataLoopNode::NodeFluidType::Air,
423 : DataLoopNode::ConnectionType::Internal,
424 : NodeInputManager::CompFluidStream::Secondary,
425 5 : ObjectIsParent);
426 :
427 5 : if (UtilityRoutines::SameString(Alphas(7), "LEAVING HUMRAT:BYPASS")) {
428 0 : ShowWarningError(state, std::string{RoutineName} + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
429 0 : ShowContinueError(state, "Obsolete " + cAlphaFields(7) + " = " + Alphas(7));
430 0 : ShowContinueError(state, "setting to LeavingMaximumHumidityRatioSetpoint");
431 0 : DesicDehum(DesicDehumNum).controlType = DesicDehumCtrlType::FixedHumratBypass;
432 : }
433 5 : if (UtilityRoutines::SameString(Alphas(7), "LeavingMaximumHumidityRatioSetpoint"))
434 3 : DesicDehum(DesicDehumNum).controlType = DesicDehumCtrlType::FixedHumratBypass;
435 5 : if (UtilityRoutines::SameString(Alphas(7), "SystemNodeMaximumHumidityRatioSetpoint"))
436 2 : DesicDehum(DesicDehumNum).controlType = DesicDehumCtrlType::NodeHumratBypass;
437 5 : if (DesicDehum(DesicDehumNum).controlType == DesicDehumCtrlType::Invalid) {
438 0 : ShowWarningError(state, std::string{RoutineName} + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
439 0 : ShowContinueError(state, "Invalid " + cAlphaFields(7) + " = " + Alphas(7));
440 0 : ShowContinueError(state, "setting to LeavingMaximumHumidityRatioSetpoint");
441 0 : DesicDehum(DesicDehumNum).controlType = DesicDehumCtrlType::FixedHumratBypass;
442 : }
443 5 : DesicDehum(DesicDehumNum).HumRatSet = Numbers(1);
444 5 : DesicDehum(DesicDehumNum).NomProcAirVolFlow = Numbers(2);
445 5 : DesicDehum(DesicDehumNum).NomProcAirVel = Numbers(3);
446 :
447 5 : DesicDehum(DesicDehumNum).RegenCoilType = Alphas(8);
448 5 : DesicDehum(DesicDehumNum).RegenCoilName = Alphas(9);
449 5 : RegenCoilType = Alphas(8);
450 5 : RegenCoilName = Alphas(9);
451 :
452 15 : if (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenCoilType, "Coil:Heating:Electric") ||
453 10 : UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenCoilType, "Coil:Heating:Fuel")) {
454 5 : if (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenCoilType, "Coil:Heating:Electric"))
455 0 : DesicDehum(DesicDehumNum).RegenCoilType_Num = Coil_HeatingElectric;
456 5 : if (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenCoilType, "Coil:Heating:Fuel"))
457 5 : DesicDehum(DesicDehumNum).RegenCoilType_Num = Coil_HeatingGasOrOtherFuel;
458 10 : ValidateComponent(state,
459 5 : DesicDehum(DesicDehumNum).RegenCoilType,
460 5 : DesicDehum(DesicDehumNum).RegenCoilName,
461 : ErrorsFound2,
462 10 : CurrentModuleObject + '=' + Alphas(1));
463 5 : if (ErrorsFound2) ErrorsFound = true;
464 5 : GetHeatingCoilIndex(state, DesicDehum(DesicDehumNum).RegenCoilName, DesicDehum(DesicDehumNum).RegenCoilIndex, ErrorsFound2);
465 5 : if (ErrorsFound2) ErrorsFound = true;
466 :
467 0 : } else if (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenCoilType, "Coil:Heating:Water")) {
468 0 : DesicDehum(DesicDehumNum).RegenCoilType_Num = Coil_HeatingWater;
469 0 : ValidateComponent(state, RegenCoilType, RegenCoilName, IsNotOK, CurrentModuleObject);
470 0 : if (IsNotOK) {
471 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
472 0 : ErrorsFound = true;
473 : } else { // mine data from heating coil object
474 0 : errFlag = false;
475 0 : DesicDehum(DesicDehumNum).RegenCoilIndex = GetWaterCoilIndex(state, "COIL:HEATING:WATER", RegenCoilName, errFlag);
476 0 : if (DesicDehum(DesicDehumNum).RegenCoilIndex == 0) {
477 0 : ShowSevereError(state,
478 0 : std::string{RoutineName} + CurrentModuleObject + " illegal " + cAlphaFields(9) + " = " + RegenCoilName);
479 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
480 0 : ErrorsFound = true;
481 : }
482 :
483 : // Get the Heating Coil Hot water Inlet or control Node number
484 0 : errFlag = false;
485 0 : DesicDehum(DesicDehumNum).CoilControlNode = GetCoilWaterInletNode(state, "Coil:Heating:Water", RegenCoilName, errFlag);
486 0 : if (errFlag) {
487 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
488 0 : ErrorsFound = true;
489 : }
490 :
491 : // Get the Regeneration Heating Coil hot water max volume flow rate
492 0 : errFlag = false;
493 0 : DesicDehum(DesicDehumNum).MaxCoilFluidFlow = GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", RegenCoilName, errFlag);
494 0 : if (errFlag) {
495 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
496 0 : ErrorsFound = true;
497 : }
498 :
499 : // Get the Regeneration Heating Coil Inlet Node
500 0 : errFlag = false;
501 0 : RegenCoilAirInletNode = GetWaterCoilInletNode(state, "Coil:Heating:Water", RegenCoilName, errFlag);
502 0 : DesicDehum(DesicDehumNum).RegenCoilInletNode = RegenCoilAirInletNode;
503 0 : if (errFlag) {
504 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
505 0 : ErrorsFound = true;
506 : }
507 :
508 : // Get the Regeneration Heating Coil Outlet Node
509 0 : errFlag = false;
510 0 : RegenCoilAirOutletNode = GetWaterCoilOutletNode(state, "Coil:Heating:Water", RegenCoilName, errFlag);
511 0 : DesicDehum(DesicDehumNum).RegenCoilOutletNode = RegenCoilAirOutletNode;
512 0 : if (errFlag) {
513 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
514 0 : ErrorsFound = true;
515 : }
516 : }
517 0 : } else if (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenCoilType, "Coil:Heating:Steam")) {
518 0 : DesicDehum(DesicDehumNum).RegenCoilType_Num = Coil_HeatingSteam;
519 0 : ValidateComponent(state, Alphas(8), RegenCoilName, IsNotOK, CurrentModuleObject);
520 0 : if (IsNotOK) {
521 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
522 0 : ErrorsFound = true;
523 : } else { // mine data from the regeneration heating coil object
524 :
525 0 : errFlag = false;
526 0 : DesicDehum(DesicDehumNum).RegenCoilIndex = GetSteamCoilIndex(state, "COIL:HEATING:STEAM", RegenCoilName, errFlag);
527 0 : if (DesicDehum(DesicDehumNum).RegenCoilIndex == 0) {
528 0 : ShowSevereError(state,
529 0 : std::string{RoutineName} + CurrentModuleObject + " illegal " + cAlphaFields(9) + " = " + RegenCoilName);
530 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
531 0 : ErrorsFound = true;
532 : }
533 :
534 : // Get the regeneration Heating Coil steam inlet node number
535 0 : errFlag = false;
536 0 : DesicDehum(DesicDehumNum).CoilControlNode = GetCoilSteamInletNode(state, "Coil:Heating:Steam", RegenCoilName, errFlag);
537 0 : if (errFlag) {
538 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
539 0 : ErrorsFound = true;
540 : }
541 :
542 : // Get the regeneration heating Coil steam max volume flow rate
543 0 : DesicDehum(DesicDehumNum).MaxCoilFluidFlow = GetCoilMaxSteamFlowRate(state, DesicDehum(DesicDehumNum).RegenCoilIndex, errFlag);
544 0 : if (DesicDehum(DesicDehumNum).MaxCoilFluidFlow > 0.0) {
545 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
546 0 : SteamDensity = GetSatDensityRefrig(
547 0 : state, fluidNameSteam, state.dataDesiccantDehumidifiers->TempSteamIn, 1.0, SteamIndex, dehumidifierDesiccantNoFans);
548 0 : DesicDehum(DesicDehumNum).MaxCoilFluidFlow *= SteamDensity;
549 : }
550 :
551 : // Get the regeneration heating Coil Inlet Node
552 0 : errFlag = false;
553 0 : RegenCoilAirInletNode = GetSteamCoilAirInletNode(state, DesicDehum(DesicDehumNum).RegenCoilIndex, RegenCoilName, errFlag);
554 0 : DesicDehum(DesicDehumNum).RegenCoilInletNode = RegenCoilAirInletNode;
555 0 : if (errFlag) {
556 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
557 0 : ErrorsFound = true;
558 : }
559 :
560 : // Get the regeneration heating Coil Outlet Node
561 0 : errFlag = false;
562 0 : RegenCoilAirOutletNode = GetCoilAirOutletNode(state, DesicDehum(DesicDehumNum).RegenCoilIndex, RegenCoilName, errFlag);
563 0 : DesicDehum(DesicDehumNum).RegenCoilOutletNode = RegenCoilAirOutletNode;
564 0 : if (errFlag) {
565 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
566 0 : ErrorsFound = true;
567 : }
568 : }
569 : } else {
570 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + " = " + Alphas(1));
571 0 : ShowContinueError(state, "Illegal " + cAlphaFields(8) + " = " + DesicDehum(DesicDehumNum).RegenCoilType);
572 0 : ErrorsFound = true;
573 : }
574 :
575 5 : DesicDehum(DesicDehumNum).NomRotorPower = Numbers(4);
576 5 : DesicDehum(DesicDehumNum).RegenFanType = Alphas(10);
577 5 : DesicDehum(DesicDehumNum).RegenFanName = Alphas(11);
578 :
579 5 : TestCompSet(state, DesicDehum(DesicDehumNum).DehumType, DesicDehum(DesicDehumNum).Name, Alphas(3), Alphas(4), "Process Air Nodes");
580 :
581 : // Set up component set for regen coil
582 5 : SetUpCompSets(state, DesicDehum(DesicDehumNum).DehumType, DesicDehum(DesicDehumNum).Name, Alphas(8), Alphas(9), "UNDEFINED", "UNDEFINED");
583 :
584 : // Set up component set for regen fan
585 5 : SetUpCompSets(state, DesicDehum(DesicDehumNum).DehumType, DesicDehum(DesicDehumNum).Name, Alphas(10), Alphas(11), Alphas(6), "UNDEFINED");
586 :
587 5 : if ((!UtilityRoutines::SameString(Alphas(12), "Default")) && (UtilityRoutines::SameString(Alphas(12), "UserCurves"))) {
588 0 : ShowWarningError(state, std::string{RoutineName} + CurrentModuleObject + ": Invalid" + cAlphaFields(12) + " = " + Alphas(12));
589 0 : ShowContinueError(state, "resetting to Default");
590 0 : DesicDehum(DesicDehumNum).PerformanceModel_Num = PerformanceModel::Default;
591 : }
592 :
593 5 : if (UtilityRoutines::SameString(Alphas(12), "UserCurves")) {
594 0 : DesicDehum(DesicDehumNum).PerformanceModel_Num = PerformanceModel::UserCurves;
595 0 : DesicDehum(DesicDehumNum).ProcDryBulbCurvefTW = GetCurveIndex(state, Alphas(13));
596 0 : if (DesicDehum(DesicDehumNum).ProcDryBulbCurvefTW == 0) {
597 0 : ShowSevereError(state, std::string{RoutineName} + "Curve object=" + Alphas(13) + " not found.");
598 0 : ErrorsFound2 = true;
599 : }
600 0 : DesicDehum(DesicDehumNum).ProcDryBulbCurvefV = GetCurveIndex(state, Alphas(14));
601 0 : if (DesicDehum(DesicDehumNum).ProcDryBulbCurvefV == 0) {
602 0 : ShowSevereError(state, std::string{RoutineName} + "Curve object=" + Alphas(14) + " not found.");
603 0 : ErrorsFound2 = true;
604 : }
605 0 : DesicDehum(DesicDehumNum).ProcHumRatCurvefTW = GetCurveIndex(state, Alphas(15));
606 0 : if (DesicDehum(DesicDehumNum).ProcHumRatCurvefTW == 0) {
607 0 : ShowSevereError(state, std::string{RoutineName} + "Curve object=" + Alphas(15) + " not found.");
608 0 : ErrorsFound2 = true;
609 : }
610 0 : DesicDehum(DesicDehumNum).ProcHumRatCurvefV = GetCurveIndex(state, Alphas(16));
611 0 : if (DesicDehum(DesicDehumNum).ProcHumRatCurvefV == 0) {
612 0 : ShowSevereError(state, std::string{RoutineName} + "Curve object=" + Alphas(16) + " not found.");
613 0 : ErrorsFound2 = true;
614 : }
615 0 : DesicDehum(DesicDehumNum).RegenEnergyCurvefTW = GetCurveIndex(state, Alphas(17));
616 0 : if (DesicDehum(DesicDehumNum).RegenEnergyCurvefTW == 0) {
617 0 : ShowSevereError(state, std::string{RoutineName} + "Curve object=" + Alphas(17) + " not found.");
618 0 : ErrorsFound2 = true;
619 : }
620 0 : DesicDehum(DesicDehumNum).RegenEnergyCurvefV = GetCurveIndex(state, Alphas(18));
621 0 : if (DesicDehum(DesicDehumNum).RegenEnergyCurvefV == 0) {
622 0 : ShowSevereError(state, std::string{RoutineName} + "Curve object=" + Alphas(18) + " not found.");
623 0 : ErrorsFound2 = true;
624 : }
625 0 : DesicDehum(DesicDehumNum).RegenVelCurvefTW = GetCurveIndex(state, Alphas(19));
626 0 : if (DesicDehum(DesicDehumNum).RegenVelCurvefTW == 0) {
627 0 : ShowSevereError(state, std::string{RoutineName} + "Curve object=" + Alphas(19) + " not found.");
628 0 : ErrorsFound2 = true;
629 : }
630 0 : DesicDehum(DesicDehumNum).RegenVelCurvefV = GetCurveIndex(state, Alphas(20));
631 0 : if (DesicDehum(DesicDehumNum).RegenVelCurvefV == 0) {
632 0 : ShowSevereError(state, std::string{RoutineName} + "Curve object=" + Alphas(20) + " not found.");
633 0 : ErrorsFound2 = true;
634 : }
635 0 : if (ErrorsFound2) {
636 0 : ShowSevereError(state, std::string{RoutineName} + CurrentModuleObject + " = " + Alphas(1));
637 0 : ShowContinueError(state, "Errors found in getting performance curves.");
638 0 : ErrorsFound = true;
639 : }
640 0 : DesicDehum(DesicDehumNum).NomRegenTemp = Numbers(5);
641 : // Validate regen fan type, for user defined curves, can be constant or variable volume
642 0 : if ((UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenFanType, "FAN:CONSTANTVOLUME")) ||
643 0 : (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenFanType, "FAN:VARIABLEVOLUME") ||
644 0 : UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenFanType, "FAN:SYSTEMMODEL"))) {
645 0 : ValidateComponent(state,
646 0 : DesicDehum(DesicDehumNum).RegenFanType,
647 0 : DesicDehum(DesicDehumNum).RegenFanName,
648 : ErrorsFound2,
649 0 : CurrentModuleObject + " = " + Alphas(1));
650 0 : if (ErrorsFound2) ErrorsFound = true;
651 : } else {
652 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
653 0 : ShowContinueError(state, "Illegal " + cAlphaFields(10) + " = " + DesicDehum(DesicDehumNum).RegenFanType);
654 0 : ErrorsFound = true;
655 : }
656 : } else {
657 : // If DEFAULT performance model, set operating limits curves. Unit is off outside this range
658 5 : DesicDehum(DesicDehumNum).PerformanceModel_Num = PerformanceModel::Default;
659 10 : for (auto &e : DesicDehum) {
660 5 : e.MinProcAirInTemp = 1.67; // 35 F
661 5 : e.MaxProcAirInTemp = 48.89; // 120 F
662 5 : e.MinProcAirInHumRat = 0.002857; // 20 gr/lb
663 5 : e.MaxProcAirInHumRat = 0.02857; // 200 gr/lb
664 : }
665 : // If DEFAULT performance model, warn if curve names and nominal regen temp have values
666 20 : if ((!lAlphaBlanks(13)) || (!lAlphaBlanks(14)) || (!lAlphaBlanks(15)) || (!lAlphaBlanks(16)) || (!lAlphaBlanks(17)) ||
667 15 : (!lAlphaBlanks(18)) || (!lAlphaBlanks(19)) || (!lAlphaBlanks(20))) {
668 0 : ShowWarningError(state, CurrentModuleObject + " = " + Alphas(1));
669 0 : ShowContinueError(state, "DEFAULT performance selected, curve names and nominal regen temp will be ignored.");
670 : }
671 5 : if (DesicDehum(DesicDehumNum).NomProcAirVel > 4.064) {
672 0 : ShowWarningError(state, CurrentModuleObject + " = " + Alphas(1));
673 0 : ShowContinueError(state,
674 0 : format("{} > 4.064 m/s.; Value in input={:.3R}", cNumericFields(3), DesicDehum(DesicDehumNum).NomProcAirVel));
675 0 : ShowContinueError(state, "DEFAULT performance curves not valid outside 2.032 to 4.064 m/s (400 to 800 fpm).");
676 : }
677 5 : if (DesicDehum(DesicDehumNum).NomProcAirVel < 2.032) {
678 0 : ShowWarningError(state, CurrentModuleObject + " = " + Alphas(1));
679 0 : ShowContinueError(state,
680 0 : format("{} < 2.032 m/s.; Value in input={:.3R}", cNumericFields(3), DesicDehum(DesicDehumNum).NomProcAirVel));
681 0 : ShowContinueError(state, "DEFAULT performance curves not valid outside 2.032 to 4.064 m/s (400 to 800 fpm).");
682 : }
683 : // Validate regen fan type, for default curves, can only variable volume
684 5 : if (DesicDehum(DesicDehumNum).RegenFanType == "FAN:VARIABLEVOLUME" || DesicDehum(DesicDehumNum).RegenFanType == "FAN:SYSTEMMODEL") {
685 10 : ValidateComponent(state,
686 5 : DesicDehum(DesicDehumNum).RegenFanType,
687 5 : DesicDehum(DesicDehumNum).RegenFanName,
688 : ErrorsFound2,
689 10 : CurrentModuleObject + " = " + Alphas(1));
690 5 : if (ErrorsFound2) ErrorsFound = true;
691 : } else {
692 0 : ShowSevereError(state, CurrentModuleObject + " = " + Alphas(1));
693 0 : ShowContinueError(state, "Illegal " + cAlphaFields(10) + " = " + DesicDehum(DesicDehumNum).RegenFanType);
694 0 : ShowContinueError(state, "For DEFAULT performance model, the regen fan type must be Fan:VariableVolume");
695 0 : ErrorsFound = true;
696 : }
697 : }
698 : // process regen fan
699 5 : ErrorsFound2 = false;
700 5 : if (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenFanType, "Fan:SystemModel")) {
701 1 : DesicDehum(DesicDehumNum).regenFanType_Num = DataHVACGlobals::FanType_SystemModelObject;
702 1 : state.dataHVACFan->fanObjs.emplace_back(new HVACFan::FanSystem(state, DesicDehum(DesicDehumNum).RegenFanName)); // call constructor
703 1 : DesicDehum(DesicDehumNum).RegenFanIndex = HVACFan::getFanObjectVectorIndex(state, DesicDehum(DesicDehumNum).RegenFanName);
704 1 : DesicDehum(DesicDehumNum).RegenFanInNode = state.dataHVACFan->fanObjs[DesicDehum(DesicDehumNum).RegenFanIndex]->inletNodeNum;
705 1 : DesicDehum(DesicDehumNum).RegenFanOutNode = state.dataHVACFan->fanObjs[DesicDehum(DesicDehumNum).RegenFanIndex]->outletNodeNum;
706 :
707 : } else {
708 12 : GetFanType(state,
709 4 : DesicDehum(DesicDehumNum).RegenFanName,
710 4 : DesicDehum(DesicDehumNum).regenFanType_Num,
711 : errFlag,
712 : CurrentModuleObject,
713 4 : DesicDehum(DesicDehumNum).Name);
714 4 : DesicDehum(DesicDehumNum).RegenFanInNode =
715 4 : GetFanInletNode(state, DesicDehum(DesicDehumNum).RegenFanType, DesicDehum(DesicDehumNum).RegenFanName, ErrorsFound2);
716 4 : if (ErrorsFound2) {
717 0 : ShowContinueError(state, "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
718 0 : ErrorsFoundGeneric = true;
719 : }
720 :
721 4 : ErrorsFound2 = false;
722 4 : DesicDehum(DesicDehumNum).RegenFanOutNode =
723 4 : GetFanOutletNode(state, DesicDehum(DesicDehumNum).RegenFanType, DesicDehum(DesicDehumNum).RegenFanName, ErrorsFound2);
724 12 : GetFanIndex(state,
725 4 : DesicDehum(DesicDehumNum).RegenFanName,
726 4 : DesicDehum(DesicDehumNum).RegenFanIndex,
727 : ErrorsFound2,
728 4 : DesicDehum(DesicDehumNum).RegenFanType);
729 4 : if (ErrorsFound2) {
730 0 : ShowContinueError(state, "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
731 0 : ErrorsFoundGeneric = true;
732 : }
733 : }
734 : }
735 :
736 11 : for (DesicDehumIndex = 1; DesicDehumIndex <= state.dataDesiccantDehumidifiers->NumGenericDesicDehums; ++DesicDehumIndex) {
737 4 : RegenCoilAirInletNode = 0;
738 4 : RegenCoilAirOutletNode = 0;
739 :
740 4 : CurrentModuleObject = "Dehumidifier:Desiccant:System";
741 :
742 4 : DesicDehumNum = DesicDehumIndex + state.dataDesiccantDehumidifiers->NumSolidDesicDehums;
743 4 : DesicDehum(DesicDehumNum).DehumType = CurrentModuleObject;
744 4 : DesicDehum(DesicDehumNum).DehumTypeCode = DesicDehumType::Generic;
745 8 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
746 4 : DesicDehum(DesicDehumNum).DehumType,
747 : DesicDehumIndex,
748 : Alphas,
749 : NumAlphas,
750 : Numbers,
751 : NumNumbers,
752 : IOStatus,
753 : lNumericBlanks,
754 : lAlphaBlanks,
755 : cAlphaFields,
756 : cNumericFields);
757 8 : GlobalNames::VerifyUniqueInterObjectName(
758 8 : state, state.dataDesiccantDehumidifiers->UniqueDesicDehumNames, Alphas(1), CurrentModuleObject, cAlphaFields(1), ErrorsFoundGeneric);
759 4 : DesicDehum(DesicDehumNum).Name = Alphas(1);
760 :
761 4 : ErrorsFound2 = false;
762 8 : ValidateComponent(state,
763 4 : DesicDehum(DesicDehumNum).DehumType,
764 4 : DesicDehum(DesicDehumNum).Name,
765 : ErrorsFound2,
766 8 : DesicDehum(DesicDehumNum).DehumType + " = \"" + DesicDehum(DesicDehumNum).Name + "\"");
767 4 : if (ErrorsFound2) {
768 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\" is not unique");
769 0 : ErrorsFoundGeneric = true;
770 : }
771 :
772 4 : DesicDehum(DesicDehumNum).Sched = Alphas(2);
773 4 : if (lAlphaBlanks(2)) {
774 0 : DesicDehum(DesicDehumNum).SchedPtr = DataGlobalConstants::ScheduleAlwaysOn;
775 : } else {
776 4 : DesicDehum(DesicDehumNum).SchedPtr = GetScheduleIndex(state, Alphas(2)); // convert schedule name to pointer
777 4 : if (DesicDehum(DesicDehumNum).SchedPtr == 0) {
778 0 : ShowSevereError(state,
779 0 : std::string{RoutineName} + CurrentModuleObject + ": invalid " + cAlphaFields(2) + " entered =" + Alphas(2) +
780 0 : " for " + cAlphaFields(1) + '=' + Alphas(1));
781 0 : ErrorsFound = true;
782 : }
783 : }
784 :
785 4 : DesicDehum(DesicDehumNum).HXType = Alphas(3);
786 4 : DesicDehum(DesicDehumNum).HXName = Alphas(4);
787 :
788 4 : if (!UtilityRoutines::SameString(DesicDehum(DesicDehumNum).HXType, "HeatExchanger:Desiccant:BalancedFlow")) {
789 0 : ShowWarningError(state, DesicDehum(DesicDehumNum).DehumType + " = \"" + DesicDehum(DesicDehumNum).Name + "\"");
790 0 : ShowContinueError(state, "Invalid " + cAlphaFields(3) + " = " + DesicDehum(DesicDehumNum).HXType);
791 0 : ErrorsFoundGeneric = true;
792 : } else {
793 4 : DesicDehum(DesicDehumNum).HXTypeNum = BalancedHX;
794 : }
795 :
796 4 : ErrorsFound2 = false;
797 8 : ValidateComponent(state,
798 4 : DesicDehum(DesicDehumNum).HXType,
799 4 : DesicDehum(DesicDehumNum).HXName,
800 : ErrorsFound2,
801 8 : DesicDehum(DesicDehumNum).DehumType + " = \"" + DesicDehum(DesicDehumNum).Name + "\"");
802 4 : if (ErrorsFound2) ErrorsFoundGeneric = true;
803 :
804 4 : ErrorsFound2 = false;
805 4 : DesicDehum(DesicDehumNum).HXProcInNode = GetSecondaryInletNode(state, DesicDehum(DesicDehumNum).HXName, ErrorsFound2);
806 4 : if (ErrorsFound2) {
807 0 : ShowContinueError(state, "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
808 0 : ErrorsFoundGeneric = true;
809 : }
810 :
811 4 : ProcAirInlet = state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).HXProcInNode);
812 :
813 4 : DesicDehum(DesicDehumNum).ProcAirInNode = GetOnlySingleNode(state,
814 : ProcAirInlet,
815 : ErrorsFound,
816 : DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
817 4 : DesicDehum(DesicDehumNum).Name,
818 : DataLoopNode::NodeFluidType::Air,
819 : DataLoopNode::ConnectionType::Inlet,
820 : NodeInputManager::CompFluidStream::Primary,
821 4 : ObjectIsParent);
822 :
823 4 : ErrorsFound2 = false;
824 4 : DesicDehum(DesicDehumNum).HXProcOutNode = GetSecondaryOutletNode(state, DesicDehum(DesicDehumNum).HXName, ErrorsFound2);
825 4 : if (ErrorsFound2) {
826 0 : ShowContinueError(state, "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
827 0 : ErrorsFoundGeneric = true;
828 : }
829 :
830 4 : ProcAirOutlet = state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).HXProcOutNode);
831 :
832 4 : DesicDehum(DesicDehumNum).ProcAirOutNode = GetOnlySingleNode(state,
833 : ProcAirOutlet,
834 : ErrorsFound,
835 : DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
836 4 : DesicDehum(DesicDehumNum).Name,
837 : DataLoopNode::NodeFluidType::Air,
838 : DataLoopNode::ConnectionType::Outlet,
839 : NodeInputManager::CompFluidStream::Primary,
840 4 : ObjectIsParent);
841 :
842 4 : TestCompSet(state, DesicDehum(DesicDehumNum).DehumType, DesicDehum(DesicDehumNum).Name, ProcAirInlet, ProcAirOutlet, "Process Air Nodes");
843 :
844 4 : ErrorsFound2 = false;
845 4 : DesicDehum(DesicDehumNum).HXRegenInNode = GetSupplyInletNode(state, DesicDehum(DesicDehumNum).HXName, ErrorsFound2);
846 4 : if (ErrorsFound2) {
847 0 : ShowContinueError(state, "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
848 0 : ErrorsFoundGeneric = true;
849 : }
850 :
851 4 : ErrorsFound2 = false;
852 4 : DesicDehum(DesicDehumNum).HXRegenOutNode = GetSupplyOutletNode(state, DesicDehum(DesicDehumNum).HXName, ErrorsFound2);
853 4 : if (ErrorsFound2) {
854 0 : ShowContinueError(state, "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
855 0 : ErrorsFoundGeneric = true;
856 : }
857 :
858 8 : DesicDehum(DesicDehumNum).ControlNodeNum = GetOnlySingleNode(state,
859 4 : Alphas(5),
860 : ErrorsFound,
861 : DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
862 4 : DesicDehum(DesicDehumNum).Name,
863 : DataLoopNode::NodeFluidType::Air,
864 : DataLoopNode::ConnectionType::Sensor,
865 : NodeInputManager::CompFluidStream::Primary,
866 4 : ObjectIsNotParent);
867 :
868 4 : if (DesicDehum(DesicDehumNum).ControlNodeNum == 0) {
869 0 : ShowContinueError(state, DesicDehum(DesicDehumNum).DehumType + " = \"" + DesicDehum(DesicDehumNum).Name + "\"");
870 0 : ShowSevereError(state, cAlphaFields(5) + " must be specified.");
871 0 : ErrorsFoundGeneric = true;
872 : }
873 :
874 4 : DesicDehum(DesicDehumNum).RegenFanType = Alphas(6);
875 4 : DesicDehum(DesicDehumNum).RegenFanName = Alphas(7);
876 :
877 11 : if (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenFanType, "Fan:OnOff") ||
878 10 : UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenFanType, "Fan:ConstantVolume") ||
879 6 : UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenFanType, "Fan:SystemModel")) {
880 4 : ErrorsFound2 = false;
881 8 : ValidateComponent(state,
882 4 : DesicDehum(DesicDehumNum).RegenFanType,
883 4 : DesicDehum(DesicDehumNum).RegenFanName,
884 : ErrorsFound2,
885 8 : DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
886 4 : if (ErrorsFound2) ErrorsFoundGeneric = true;
887 : } else {
888 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
889 0 : ShowContinueError(state, "Illegal " + cAlphaFields(6) + " = " + DesicDehum(DesicDehumNum).RegenFanType);
890 0 : ErrorsFoundGeneric = true;
891 : }
892 :
893 4 : if (UtilityRoutines::SameString(Alphas(8), "DrawThrough")) {
894 4 : DesicDehum(DesicDehumNum).RegenFanPlacement = DrawThru;
895 0 : } else if (UtilityRoutines::SameString(Alphas(8), "BlowThrough")) {
896 0 : DesicDehum(DesicDehumNum).RegenFanPlacement = BlowThru;
897 : } else {
898 0 : ShowWarningError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
899 0 : ShowContinueError(state, "Illegal " + cAlphaFields(8) + " = " + Alphas(8));
900 0 : ShowContinueError(state, "...resetting to DEFAULT of DRAW THROUGH");
901 0 : DesicDehum(DesicDehumNum).RegenFanPlacement = DrawThru;
902 : }
903 :
904 4 : ErrorsFound2 = false;
905 4 : if (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenFanType, "Fan:SystemModel")) {
906 2 : DesicDehum(DesicDehumNum).regenFanType_Num = DataHVACGlobals::FanType_SystemModelObject;
907 2 : state.dataHVACFan->fanObjs.emplace_back(new HVACFan::FanSystem(state, DesicDehum(DesicDehumNum).RegenFanName)); // call constructor
908 2 : DesicDehum(DesicDehumNum).RegenFanIndex = HVACFan::getFanObjectVectorIndex(state, DesicDehum(DesicDehumNum).RegenFanName);
909 2 : DesicDehum(DesicDehumNum).RegenFanInNode = state.dataHVACFan->fanObjs[DesicDehum(DesicDehumNum).RegenFanIndex]->inletNodeNum;
910 2 : DesicDehum(DesicDehumNum).RegenFanOutNode = state.dataHVACFan->fanObjs[DesicDehum(DesicDehumNum).RegenFanIndex]->outletNodeNum;
911 : } else {
912 6 : GetFanType(state,
913 2 : DesicDehum(DesicDehumNum).RegenFanName,
914 2 : DesicDehum(DesicDehumNum).regenFanType_Num,
915 : errFlag,
916 : CurrentModuleObject,
917 2 : DesicDehum(DesicDehumNum).Name);
918 2 : DesicDehum(DesicDehumNum).RegenFanInNode =
919 2 : GetFanInletNode(state, DesicDehum(DesicDehumNum).RegenFanType, DesicDehum(DesicDehumNum).RegenFanName, ErrorsFound2);
920 2 : if (ErrorsFound2) {
921 0 : ShowContinueError(state, "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
922 0 : ErrorsFoundGeneric = true;
923 : }
924 :
925 2 : ErrorsFound2 = false;
926 2 : DesicDehum(DesicDehumNum).RegenFanOutNode =
927 2 : GetFanOutletNode(state, DesicDehum(DesicDehumNum).RegenFanType, DesicDehum(DesicDehumNum).RegenFanName, ErrorsFound2);
928 6 : GetFanIndex(state,
929 2 : DesicDehum(DesicDehumNum).RegenFanName,
930 2 : DesicDehum(DesicDehumNum).RegenFanIndex,
931 : ErrorsFound2,
932 2 : DesicDehum(DesicDehumNum).RegenFanType);
933 2 : if (ErrorsFound2) {
934 0 : ShowContinueError(state, "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
935 0 : ErrorsFoundGeneric = true;
936 : }
937 : }
938 :
939 4 : DesicDehum(DesicDehumNum).RegenCoilType = Alphas(9);
940 4 : DesicDehum(DesicDehumNum).RegenCoilName = Alphas(10);
941 4 : RegenCoilType = Alphas(9);
942 4 : RegenCoilName = Alphas(10);
943 4 : DesicDehum(DesicDehumNum).RegenSetPointTemp = Numbers(1);
944 :
945 4 : if (!lAlphaBlanks(10)) {
946 12 : if (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenCoilType, "Coil:Heating:Electric") ||
947 8 : UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenCoilType, "Coil:Heating:Fuel")) {
948 4 : if (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenCoilType, "Coil:Heating:Electric"))
949 0 : DesicDehum(DesicDehumNum).RegenCoilType_Num = Coil_HeatingElectric;
950 4 : if (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenCoilType, "Coil:Heating:Fuel"))
951 4 : DesicDehum(DesicDehumNum).RegenCoilType_Num = Coil_HeatingGasOrOtherFuel;
952 4 : ErrorsFound2 = false;
953 4 : ValidateComponent(state,
954 : RegenCoilType,
955 : RegenCoilName,
956 : ErrorsFound2,
957 8 : DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
958 4 : if (ErrorsFound2) ErrorsFoundGeneric = true;
959 :
960 4 : if (DesicDehum(DesicDehumNum).RegenSetPointTemp <= 0.0) {
961 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
962 0 : ShowContinueError(state, cNumericFields(1) + " must be greater than 0.");
963 0 : ErrorsFoundGeneric = true;
964 : }
965 :
966 4 : ErrorsFound2 = false;
967 4 : DesicDehum(DesicDehumNum).RegenCoilInletNode = GetHeatingCoilInletNode(state, RegenCoilType, RegenCoilName, ErrorsFound2);
968 4 : if (ErrorsFound2) {
969 0 : ShowContinueError(state,
970 0 : "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
971 0 : ErrorsFoundGeneric = true;
972 : }
973 :
974 4 : ErrorsFound2 = false;
975 4 : DesicDehum(DesicDehumNum).RegenCoilOutletNode = GetHeatingCoilOutletNode(state, RegenCoilType, RegenCoilName, ErrorsFound2);
976 4 : if (ErrorsFound2) {
977 0 : ShowContinueError(state,
978 0 : "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
979 0 : ErrorsFoundGeneric = true;
980 : }
981 :
982 4 : ErrorsFound2 = false;
983 4 : GetHeatingCoilIndex(state, RegenCoilName, DesicDehum(DesicDehumNum).RegenCoilIndex, ErrorsFound2);
984 4 : if (ErrorsFound2) {
985 0 : ShowContinueError(state,
986 0 : "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
987 0 : ErrorsFoundGeneric = true;
988 : }
989 :
990 4 : ErrorsFound2 = false;
991 4 : RegenCoilControlNodeNum = GetHeatingCoilControlNodeNum(state, RegenCoilType, RegenCoilName, ErrorsFound2);
992 4 : if (ErrorsFound2) {
993 0 : ShowContinueError(state,
994 0 : "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
995 0 : ErrorsFoundGeneric = true;
996 : }
997 :
998 4 : if (RegenCoilControlNodeNum > 0) {
999 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1000 0 : ShowContinueError(
1001 : state,
1002 0 : format("{} is specified as {:.3R} C in this object.", cNumericFields(1), DesicDehum(DesicDehumNum).RegenSetPointTemp));
1003 0 : ShowContinueError(state, " Do not specify a coil temperature setpoint node name in the regeneration air heater object.");
1004 0 : ShowContinueError(state, "..." + cAlphaFields(9) + " = " + DesicDehum(DesicDehumNum).RegenCoilType);
1005 0 : ShowContinueError(state, "..." + cAlphaFields(10) + " = " + DesicDehum(DesicDehumNum).RegenCoilName);
1006 0 : ShowContinueError(state,
1007 0 : "...heating coil temperature setpoint node = " + state.dataLoopNodes->NodeID(RegenCoilControlNodeNum));
1008 0 : ShowContinueError(state, "...leave the heating coil temperature setpoint node name blank in the regen heater object.");
1009 0 : ErrorsFoundGeneric = true;
1010 : }
1011 :
1012 4 : RegairHeatingCoilFlag = true;
1013 4 : SetHeatingCoilData(state, DesicDehum(DesicDehumNum).RegenCoilIndex, ErrorsFound2, RegairHeatingCoilFlag, DesicDehumNum);
1014 4 : if (ErrorsFound2) {
1015 0 : ShowContinueError(state,
1016 0 : "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1017 0 : ErrorsFoundGeneric = true;
1018 : }
1019 :
1020 0 : } else if (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenCoilType, "Coil:Heating:Water")) {
1021 0 : DesicDehum(DesicDehumNum).RegenCoilType_Num = Coil_HeatingWater;
1022 0 : ValidateComponent(state, RegenCoilType, RegenCoilName, IsNotOK, CurrentModuleObject);
1023 0 : if (IsNotOK) {
1024 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1025 0 : ErrorsFound = true;
1026 : } else { // mine data from heating coil object
1027 0 : errFlag = false;
1028 0 : DesicDehum(DesicDehumNum).RegenCoilIndex = GetWaterCoilIndex(state, "COIL:HEATING:WATER", RegenCoilName, errFlag);
1029 0 : if (DesicDehum(DesicDehumNum).RegenCoilIndex == 0) {
1030 0 : ShowSevereError(state, CurrentModuleObject + " illegal " + cAlphaFields(9) + " = " + RegenCoilName);
1031 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
1032 0 : ErrorsFound = true;
1033 : }
1034 :
1035 0 : if (DesicDehum(DesicDehumNum).RegenSetPointTemp <= 0.0) {
1036 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1037 0 : ShowContinueError(state, cNumericFields(1) + " must be greater than 0.");
1038 0 : ErrorsFoundGeneric = true;
1039 : }
1040 :
1041 : // Get the Heating Coil Hot water Inlet or control Node number
1042 0 : errFlag = false;
1043 0 : DesicDehum(DesicDehumNum).CoilControlNode = GetCoilWaterInletNode(state, "Coil:Heating:Water", RegenCoilName, errFlag);
1044 0 : if (errFlag) {
1045 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
1046 0 : ErrorsFound = true;
1047 : }
1048 :
1049 : // Get the Regeneration Heating Coil hot water max volume flow rate
1050 0 : errFlag = false;
1051 0 : DesicDehum(DesicDehumNum).MaxCoilFluidFlow = GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", RegenCoilName, errFlag);
1052 0 : if (errFlag) {
1053 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
1054 0 : ErrorsFound = true;
1055 : }
1056 :
1057 : // Get the Regeneration Heating Coil Inlet Node
1058 0 : errFlag = false;
1059 0 : RegenCoilAirInletNode = GetWaterCoilInletNode(state, "Coil:Heating:Water", RegenCoilName, errFlag);
1060 0 : DesicDehum(DesicDehumNum).RegenCoilInletNode = RegenCoilAirInletNode;
1061 0 : if (errFlag) {
1062 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
1063 0 : ErrorsFound = true;
1064 : }
1065 :
1066 : // Get the Regeneration Heating Coil Outlet Node
1067 0 : errFlag = false;
1068 0 : RegenCoilAirOutletNode = GetWaterCoilOutletNode(state, "Coil:Heating:Water", RegenCoilName, errFlag);
1069 0 : DesicDehum(DesicDehumNum).RegenCoilOutletNode = RegenCoilAirOutletNode;
1070 0 : if (errFlag) {
1071 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
1072 0 : ErrorsFound = true;
1073 : }
1074 :
1075 0 : RegairHeatingCoilFlag = true;
1076 0 : SetWaterCoilData(state, DesicDehum(DesicDehumNum).RegenCoilIndex, ErrorsFound2, RegairHeatingCoilFlag, DesicDehumNum);
1077 0 : if (ErrorsFound2) {
1078 0 : ShowContinueError(state,
1079 0 : "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1080 0 : ErrorsFoundGeneric = true;
1081 : }
1082 : }
1083 0 : } else if (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).RegenCoilType, "Coil:Heating:Steam")) {
1084 0 : DesicDehum(DesicDehumNum).RegenCoilType_Num = Coil_HeatingSteam;
1085 0 : ValidateComponent(state, RegenCoilType, RegenCoilName, IsNotOK, CurrentModuleObject);
1086 0 : if (IsNotOK) {
1087 0 : ShowContinueError(state, "...occurs in " + CurrentModuleObject + " = " + Alphas(1));
1088 0 : ErrorsFound = true;
1089 : } else { // mine data from the regeneration heating coil object
1090 0 : if (DesicDehum(DesicDehumNum).RegenSetPointTemp <= 0.0) {
1091 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1092 0 : ShowContinueError(state, cNumericFields(1) + " must be greater than 0.");
1093 0 : ErrorsFoundGeneric = true;
1094 : }
1095 :
1096 0 : errFlag = false;
1097 0 : DesicDehum(DesicDehumNum).RegenCoilIndex = GetSteamCoilIndex(state, "COIL:HEATING:STEAM", RegenCoilName, errFlag);
1098 0 : if (DesicDehum(DesicDehumNum).RegenCoilIndex == 0) {
1099 0 : ShowSevereError(state, CurrentModuleObject + " illegal " + cAlphaFields(9) + " = " + RegenCoilName);
1100 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
1101 0 : ErrorsFound = true;
1102 : }
1103 :
1104 : // Get the regeneration Heating Coil steam inlet node number
1105 0 : errFlag = false;
1106 0 : DesicDehum(DesicDehumNum).CoilControlNode = GetCoilSteamInletNode(state, "Coil:Heating:Steam", RegenCoilName, errFlag);
1107 0 : if (errFlag) {
1108 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
1109 0 : ErrorsFound = true;
1110 : }
1111 :
1112 : // Get the regeneration heating Coil steam max volume flow rate
1113 0 : DesicDehum(DesicDehumNum).MaxCoilFluidFlow =
1114 0 : GetCoilMaxSteamFlowRate(state, DesicDehum(DesicDehumNum).RegenCoilIndex, errFlag);
1115 0 : if (DesicDehum(DesicDehumNum).MaxCoilFluidFlow > 0.0) {
1116 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
1117 0 : SteamDensity = GetSatDensityRefrig(
1118 0 : state, fluidNameSteam, state.dataDesiccantDehumidifiers->TempSteamIn, 1.0, SteamIndex, dehumidifierDesiccantNoFans);
1119 0 : DesicDehum(DesicDehumNum).MaxCoilFluidFlow *= SteamDensity;
1120 : }
1121 :
1122 : // Get the regeneration heating Coil Inlet Node
1123 0 : errFlag = false;
1124 0 : RegenCoilAirInletNode = GetSteamCoilAirInletNode(state, DesicDehum(DesicDehumNum).RegenCoilIndex, RegenCoilName, errFlag);
1125 0 : DesicDehum(DesicDehumNum).RegenCoilInletNode = RegenCoilAirInletNode;
1126 0 : if (errFlag) {
1127 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
1128 0 : ErrorsFound = true;
1129 : }
1130 :
1131 : // Get the regeneration heating Coil Outlet Node
1132 0 : errFlag = false;
1133 0 : RegenCoilAirOutletNode = GetCoilAirOutletNode(state, DesicDehum(DesicDehumNum).RegenCoilIndex, RegenCoilName, errFlag);
1134 0 : DesicDehum(DesicDehumNum).RegenCoilOutletNode = RegenCoilAirOutletNode;
1135 0 : if (errFlag) {
1136 0 : ShowContinueError(state, "Occurs in " + CurrentModuleObject + " = " + DesicDehum(DesicDehumNum).Name);
1137 0 : ErrorsFound = true;
1138 : }
1139 : }
1140 :
1141 0 : ErrorsFound2 = false;
1142 0 : RegenCoilControlNodeNum = GetSteamCoilControlNodeNum(state, RegenCoilType, RegenCoilName, ErrorsFound2);
1143 :
1144 0 : if (ErrorsFound2) {
1145 0 : ShowContinueError(state,
1146 0 : "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1147 0 : ErrorsFoundGeneric = true;
1148 : }
1149 :
1150 0 : if (RegenCoilControlNodeNum > 0) {
1151 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1152 0 : ShowContinueError(
1153 : state,
1154 0 : format("{} is specified as {:.3R} C in this object.", cNumericFields(1), DesicDehum(DesicDehumNum).RegenSetPointTemp));
1155 0 : ShowContinueError(state, " Do not specify a coil temperature setpoint node name in the regeneration air heater object.");
1156 0 : ShowContinueError(state, "..." + cAlphaFields(9) + " = " + DesicDehum(DesicDehumNum).RegenCoilType);
1157 0 : ShowContinueError(state, "..." + cAlphaFields(10) + " = " + DesicDehum(DesicDehumNum).RegenCoilName);
1158 0 : ShowContinueError(state,
1159 0 : "...heating coil temperature setpoint node = " + state.dataLoopNodes->NodeID(RegenCoilControlNodeNum));
1160 0 : ShowContinueError(state, "...leave the heating coil temperature setpoint node name blank in the regen heater object.");
1161 0 : ErrorsFoundGeneric = true;
1162 : }
1163 :
1164 0 : RegairHeatingCoilFlag = true;
1165 0 : SetSteamCoilData(state, DesicDehum(DesicDehumNum).RegenCoilIndex, ErrorsFound2, RegairHeatingCoilFlag, DesicDehumNum);
1166 0 : if (ErrorsFound2) {
1167 0 : ShowContinueError(state,
1168 0 : "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1169 0 : ErrorsFoundGeneric = true;
1170 : }
1171 :
1172 : } else {
1173 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1174 0 : ShowContinueError(state, "Illegal " + cAlphaFields(9) + " = " + DesicDehum(DesicDehumNum).RegenCoilType);
1175 0 : ErrorsFoundGeneric = true;
1176 : }
1177 : }
1178 :
1179 4 : RegenAirInlet = state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).HXRegenInNode);
1180 :
1181 4 : RegenAirOutlet = state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).HXRegenOutNode);
1182 :
1183 4 : RegenFanInlet = state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).RegenFanInNode);
1184 :
1185 4 : RegenFanOutlet = state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).RegenFanOutNode);
1186 :
1187 4 : if (!lAlphaBlanks(10)) {
1188 4 : RegenCoilInlet = state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).RegenCoilInletNode);
1189 :
1190 4 : RegenCoilOutlet = state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).RegenCoilOutletNode);
1191 : }
1192 :
1193 20 : SetUpCompSets(state,
1194 4 : DesicDehum(DesicDehumNum).DehumType,
1195 4 : DesicDehum(DesicDehumNum).Name,
1196 4 : DesicDehum(DesicDehumNum).HXType,
1197 4 : DesicDehum(DesicDehumNum).HXName,
1198 : ProcAirInlet,
1199 4 : ProcAirOutlet);
1200 :
1201 20 : SetUpCompSets(state,
1202 4 : DesicDehum(DesicDehumNum).DehumType,
1203 4 : DesicDehum(DesicDehumNum).Name,
1204 4 : DesicDehum(DesicDehumNum).RegenFanType,
1205 4 : DesicDehum(DesicDehumNum).RegenFanName,
1206 : RegenFanInlet,
1207 4 : RegenFanOutlet);
1208 :
1209 4 : if (!lAlphaBlanks(10)) {
1210 20 : SetUpCompSets(state,
1211 4 : DesicDehum(DesicDehumNum).DehumType,
1212 4 : DesicDehum(DesicDehumNum).Name,
1213 4 : DesicDehum(DesicDehumNum).RegenCoilType,
1214 4 : DesicDehum(DesicDehumNum).RegenCoilName,
1215 : RegenCoilInlet,
1216 4 : RegenCoilOutlet);
1217 : }
1218 :
1219 4 : if (DesicDehum(DesicDehumNum).RegenFanPlacement == BlowThru) {
1220 0 : DesicDehum(DesicDehumNum).RegenAirInNode = GetOnlySingleNode(state,
1221 : RegenFanInlet,
1222 : ErrorsFound,
1223 : DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
1224 0 : DesicDehum(DesicDehumNum).Name,
1225 : DataLoopNode::NodeFluidType::Air,
1226 : DataLoopNode::ConnectionType::Inlet,
1227 : NodeInputManager::CompFluidStream::Primary,
1228 0 : ObjectIsParent);
1229 0 : DesicDehum(DesicDehumNum).RegenAirOutNode = GetOnlySingleNode(state,
1230 : RegenAirOutlet,
1231 : ErrorsFound,
1232 : DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
1233 0 : DesicDehum(DesicDehumNum).Name,
1234 : DataLoopNode::NodeFluidType::Air,
1235 : DataLoopNode::ConnectionType::Outlet,
1236 : NodeInputManager::CompFluidStream::Primary,
1237 0 : ObjectIsParent);
1238 0 : if (!lAlphaBlanks(10)) {
1239 0 : if (DesicDehum(DesicDehumNum).RegenFanOutNode != DesicDehum(DesicDehumNum).RegenCoilInletNode) {
1240 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1241 0 : ShowContinueError(state,
1242 : "Regen fan outlet node name and regen heater inlet node name do not match for fan placement: Blow Through");
1243 0 : ShowContinueError(state,
1244 0 : "...Regen fan outlet node = " + state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).RegenFanOutNode));
1245 0 : ShowContinueError(
1246 0 : state, "...Regen heater inlet node = " + state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).RegenCoilInletNode));
1247 0 : ErrorsFoundGeneric = true;
1248 : }
1249 0 : if (DesicDehum(DesicDehumNum).RegenCoilOutletNode != DesicDehum(DesicDehumNum).HXRegenInNode) {
1250 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1251 0 : ShowContinueError(state,
1252 : "Regen heater outlet node name and desiccant heat exchanger regen inlet node name do not match for fan "
1253 : "placement: Blow Through");
1254 0 : ShowContinueError(
1255 0 : state, "...Regen heater outlet node = " + state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).RegenCoilOutletNode));
1256 0 : ShowContinueError(state,
1257 0 : "...HX regen inlet node = " + state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).HXRegenInNode));
1258 0 : ErrorsFoundGeneric = true;
1259 : }
1260 : } else {
1261 0 : if (DesicDehum(DesicDehumNum).RegenFanOutNode != DesicDehum(DesicDehumNum).HXRegenInNode) {
1262 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1263 0 : ShowContinueError(
1264 : state,
1265 : "Regen fan outlet node name and desiccant heat exchanger inlet node name do not match for fan placement: Blow Through");
1266 0 : ShowContinueError(state,
1267 0 : "...Regen fan outlet node = " + state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).RegenFanOutNode));
1268 0 : ShowContinueError(state,
1269 0 : "...Desiccant HX inlet node = " + state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).HXRegenInNode));
1270 0 : ErrorsFoundGeneric = true;
1271 : }
1272 : }
1273 : } else { // ELSE for IF (DesicDehum(DesicDehumNum)%RegenFanPlacement == BlowThru)THEN
1274 4 : DesicDehum(DesicDehumNum).RegenAirOutNode = GetOnlySingleNode(state,
1275 : RegenFanOutlet,
1276 : ErrorsFound,
1277 : DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
1278 4 : DesicDehum(DesicDehumNum).Name,
1279 : DataLoopNode::NodeFluidType::Air,
1280 : DataLoopNode::ConnectionType::Outlet,
1281 : NodeInputManager::CompFluidStream::Primary,
1282 4 : ObjectIsParent);
1283 4 : if (!lAlphaBlanks(10)) {
1284 4 : DesicDehum(DesicDehumNum).RegenAirInNode = GetOnlySingleNode(state,
1285 : RegenCoilInlet,
1286 : ErrorsFound,
1287 : DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
1288 4 : DesicDehum(DesicDehumNum).Name,
1289 : DataLoopNode::NodeFluidType::Air,
1290 : DataLoopNode::ConnectionType::Inlet,
1291 : NodeInputManager::CompFluidStream::Primary,
1292 4 : ObjectIsParent);
1293 4 : if (DesicDehum(DesicDehumNum).RegenCoilOutletNode != DesicDehum(DesicDehumNum).HXRegenInNode) {
1294 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1295 0 : ShowContinueError(state,
1296 : "Regen heater outlet node name and desiccant heat exchanger regen inlet node name do not match for fan "
1297 : "placement: Draw Through");
1298 0 : ShowContinueError(
1299 0 : state, "...Regen heater outlet node = " + state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).RegenCoilOutletNode));
1300 0 : ShowContinueError(state,
1301 0 : "...HX regen inlet node = " + state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).HXRegenInNode));
1302 0 : ErrorsFoundGeneric = true;
1303 : }
1304 : } else {
1305 0 : DesicDehum(DesicDehumNum).RegenAirInNode = GetOnlySingleNode(state,
1306 : RegenAirInlet,
1307 : ErrorsFound,
1308 : DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
1309 0 : DesicDehum(DesicDehumNum).Name,
1310 : DataLoopNode::NodeFluidType::Air,
1311 : DataLoopNode::ConnectionType::Inlet,
1312 : NodeInputManager::CompFluidStream::Primary,
1313 0 : ObjectIsParent);
1314 : }
1315 4 : if (DesicDehum(DesicDehumNum).RegenFanInNode != DesicDehum(DesicDehumNum).HXRegenOutNode) {
1316 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1317 0 : ShowContinueError(
1318 : state,
1319 : "Regen fan inlet node name and desiccant heat exchanger regen outlet node name do not match for fan placement: Draw Through");
1320 0 : ShowContinueError(state, "...Regen fan inlet node = " + state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).RegenFanInNode));
1321 0 : ShowContinueError(state, "...HX regen outlet node = " + state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).HXRegenOutNode));
1322 0 : ErrorsFoundGeneric = true;
1323 : }
1324 : }
1325 :
1326 4 : DesicDehum(DesicDehumNum).CoolingCoilType = Alphas(11);
1327 4 : DesicDehum(DesicDehumNum).CoolingCoilName = Alphas(12);
1328 :
1329 4 : if (!lAlphaBlanks(12)) {
1330 5 : if ((UtilityRoutines::SameString(DesicDehum(DesicDehumNum).CoolingCoilType, "COIL:COOLING:DX:SINGLESPEED")) ||
1331 5 : (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).CoolingCoilType, "COIL:COOLING:DX:TWOSTAGEWITHHUMIDITYCONTROLMODE")) ||
1332 3 : (UtilityRoutines::SameString(DesicDehum(DesicDehumNum).CoolingCoilType, "COIL:COOLING:DX:VARIABLESPEED"))) {
1333 2 : ErrorsFound2 = false;
1334 4 : ValidateComponent(state,
1335 2 : DesicDehum(DesicDehumNum).CoolingCoilType,
1336 2 : DesicDehum(DesicDehumNum).CoolingCoilName,
1337 : ErrorsFound2,
1338 4 : DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1339 2 : if (ErrorsFound2) ErrorsFoundGeneric = true;
1340 :
1341 2 : if ((UtilityRoutines::SameString(DesicDehum(DesicDehumNum).CoolingCoilType, "COIL:COOLING:DX:SINGLESPEED"))) {
1342 1 : DesicDehum(DesicDehumNum).coolingCoil_TypeNum = DataHVACGlobals::CoilDX_CoolingSingleSpeed;
1343 1 : } else if ((UtilityRoutines::SameString(DesicDehum(DesicDehumNum).CoolingCoilType,
1344 1 : "COIL:COOLING:DX:TWOSTAGEWITHHUMIDITYCONTROLMODE"))) {
1345 0 : DesicDehum(DesicDehumNum).coolingCoil_TypeNum = DataHVACGlobals::CoilDX_CoolingTwoStageWHumControl;
1346 1 : } else if ((UtilityRoutines::SameString(DesicDehum(DesicDehumNum).CoolingCoilType, "COIL:COOLING:DX:VARIABLESPEED"))) {
1347 1 : DesicDehum(DesicDehumNum).coolingCoil_TypeNum = DataHVACGlobals::Coil_CoolingAirToAirVariableSpeed;
1348 : }
1349 :
1350 : } else {
1351 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + '=' + DesicDehum(DesicDehumNum).Name);
1352 0 : ShowContinueError(state, "Illegal " + cAlphaFields(11) + " = " + DesicDehum(DesicDehumNum).CoolingCoilType);
1353 0 : ErrorsFoundGeneric = true;
1354 : }
1355 :
1356 3 : if ((DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingSingleSpeed) ||
1357 1 : (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingTwoStageWHumControl)) {
1358 1 : ErrorsFound2 = false;
1359 2 : DesicDehum(DesicDehumNum).CoolingCoilOutletNode = GetDXCoilOutletNode(
1360 2 : state, DesicDehum(DesicDehumNum).CoolingCoilType, DesicDehum(DesicDehumNum).CoolingCoilName, ErrorsFound2);
1361 1 : DesicDehum(DesicDehumNum).CompanionCoilCapacity =
1362 1 : GetDXCoilCapacity(state, DesicDehum(DesicDehumNum).CoolingCoilType, DesicDehum(DesicDehumNum).CoolingCoilName, ErrorsFound2);
1363 1 : if (ErrorsFound2)
1364 0 : ShowContinueError(
1365 0 : state, "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).CoolingCoilName + "\"");
1366 :
1367 1 : ErrorsFound2 = false;
1368 3 : GetDXCoilIndex(state,
1369 1 : DesicDehum(DesicDehumNum).CoolingCoilName,
1370 1 : DesicDehum(DesicDehumNum).DXCoilIndex,
1371 : ErrorsFound2,
1372 1 : DesicDehum(DesicDehumNum).CoolingCoilType);
1373 1 : if (ErrorsFound2)
1374 0 : ShowContinueError(
1375 0 : state, "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).CoolingCoilName + "\"");
1376 1 : } else if (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::Coil_CoolingAirToAirVariableSpeed) {
1377 1 : ErrorsFound2 = false;
1378 2 : DesicDehum(DesicDehumNum).CoolingCoilOutletNode = VariableSpeedCoils::GetCoilOutletNodeVariableSpeed(
1379 2 : state, DesicDehum(DesicDehumNum).CoolingCoilType, DesicDehum(DesicDehumNum).CoolingCoilName, ErrorsFound2);
1380 1 : ErrorsFound2 = false;
1381 2 : DesicDehum(DesicDehumNum).CompanionCoilCapacity = VariableSpeedCoils::GetCoilCapacityVariableSpeed(
1382 2 : state, DesicDehum(DesicDehumNum).CoolingCoilType, DesicDehum(DesicDehumNum).CoolingCoilName, ErrorsFound2);
1383 1 : if (ErrorsFound2)
1384 0 : ShowContinueError(
1385 0 : state, "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).CoolingCoilName + "\"");
1386 1 : ErrorsFound2 = false;
1387 2 : DesicDehum(DesicDehumNum).DXCoilIndex = VariableSpeedCoils::GetCoilIndexVariableSpeed(
1388 2 : state, DesicDehum(DesicDehumNum).CoolingCoilType, DesicDehum(DesicDehumNum).CoolingCoilName, ErrorsFound2);
1389 1 : if (ErrorsFound2)
1390 0 : ShowContinueError(
1391 0 : state, "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).CoolingCoilName + "\"");
1392 : }
1393 :
1394 : } // (DesicDehum(DesicDehumNum)%CoolingCoilName /= Blank)THEN
1395 :
1396 4 : if (UtilityRoutines::SameString(Alphas(13), "Yes")) {
1397 2 : DesicDehum(DesicDehumNum).CoilUpstreamOfProcessSide = Selection::Yes;
1398 2 : } else if (lAlphaBlanks(13)) {
1399 2 : DesicDehum(DesicDehumNum).CoilUpstreamOfProcessSide = Selection::No;
1400 0 : } else if (UtilityRoutines::SameString(Alphas(13), "No")) {
1401 0 : DesicDehum(DesicDehumNum).CoilUpstreamOfProcessSide = Selection::No;
1402 : } else {
1403 0 : ShowWarningError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1404 0 : ShowContinueError(state, "Invalid choice for " + cAlphaFields(13) + " = " + Alphas(13));
1405 0 : ShowContinueError(state, "...resetting to the default value of No");
1406 0 : DesicDehum(DesicDehumNum).CoilUpstreamOfProcessSide = Selection::No;
1407 : }
1408 :
1409 4 : if (UtilityRoutines::SameString(Alphas(14), "Yes")) {
1410 2 : DesicDehum(DesicDehumNum).Preheat = Selection::Yes;
1411 2 : } else if (UtilityRoutines::SameString(Alphas(14), "No")) {
1412 0 : DesicDehum(DesicDehumNum).Preheat = Selection::No;
1413 2 : } else if (lAlphaBlanks(14)) {
1414 2 : DesicDehum(DesicDehumNum).Preheat = Selection::No;
1415 : } else {
1416 0 : ShowWarningError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1417 0 : ShowContinueError(state, "Invalid choice for " + cAlphaFields(14) + " = " + Alphas(14));
1418 0 : ShowContinueError(state, "...resetting to the default value of NO");
1419 0 : DesicDehum(DesicDehumNum).Preheat = Selection::No;
1420 : }
1421 :
1422 4 : if (DesicDehum(DesicDehumNum).DXCoilIndex > 0) {
1423 :
1424 2 : if (DesicDehum(DesicDehumNum).Preheat == Selection::Yes) { // Companion coil waste heat used for regeneration of desiccant
1425 2 : ErrorsFound2 = false;
1426 4 : DesuperHeaterIndex = GetHeatReclaimSourceIndexNum(
1427 4 : state, DesicDehum(DesicDehumNum).CoolingCoilType, DesicDehum(DesicDehumNum).CoolingCoilName, ErrorsFound2);
1428 2 : if (ErrorsFound2) {
1429 0 : ShowContinueError(state,
1430 0 : "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1431 0 : ErrorsFoundGeneric = true;
1432 : }
1433 :
1434 2 : if (DesuperHeaterIndex > 0) {
1435 0 : ShowWarningError(state, DesicDehum(DesicDehumNum).DehumType + '=' + DesicDehum(DesicDehumNum).Name);
1436 0 : ShowContinueError(state,
1437 : "A Coil:Heating:Desuperheater object should not be used when condenser waste heat is reclaimed for "
1438 : "desiccant regeneration.");
1439 0 : ShowContinueError(state,
1440 0 : "A Coil:Heating:Desuperheater object was found using waste heat from the " +
1441 0 : DesicDehum(DesicDehumNum).CoolingCoilType + " \"" + DesicDehum(DesicDehumNum).CoolingCoilName +
1442 : "\" object.");
1443 : // ErrorsFoundGeneric = .TRUE.
1444 : }
1445 : }
1446 3 : if ((DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingSingleSpeed) ||
1447 1 : (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingTwoStageWHumControl)) {
1448 1 : ErrorsFound2 = false;
1449 2 : DesicDehum(DesicDehumNum).CondenserInletNode = GetCoilCondenserInletNode(
1450 2 : state, DesicDehum(DesicDehumNum).CoolingCoilType, DesicDehum(DesicDehumNum).CoolingCoilName, ErrorsFound2);
1451 1 : } else if (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::Coil_CoolingAirToAirVariableSpeed) {
1452 1 : ErrorsFound2 = false;
1453 1 : DesicDehum(DesicDehumNum).CondenserInletNode =
1454 1 : VariableSpeedCoils::GetVSCoilCondenserInletNode(state, DesicDehum(DesicDehumNum).CoolingCoilName, ErrorsFound2);
1455 : }
1456 2 : if (DesicDehum(DesicDehumNum).CondenserInletNode == 0 && DesicDehum(DesicDehumNum).Preheat == Selection::Yes) {
1457 0 : DesicDehum(DesicDehumNum).CondenserInletNode =
1458 0 : GetOnlySingleNode(state,
1459 0 : DesicDehum(DesicDehumNum).CoolingCoilName + " Condenser Inlet Node",
1460 : ErrorsFound,
1461 : DataLoopNode::ConnectionObjectType::DehumidifierDesiccantSystem,
1462 0 : DesicDehum(DesicDehumNum).Name,
1463 : DataLoopNode::NodeFluidType::Air,
1464 : DataLoopNode::ConnectionType::OutsideAirReference,
1465 : NodeInputManager::CompFluidStream::Secondary,
1466 0 : ObjectIsNotParent);
1467 0 : CheckAndAddAirNodeNumber(state, DesicDehum(DesicDehumNum).CondenserInletNode, OANodeError);
1468 0 : if (!OANodeError) {
1469 0 : ShowWarningError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1470 0 : ShowContinueError(
1471 : state,
1472 0 : "The " + cAlphaFields(14) +
1473 : " input is specified as Yes and a condenser air inlet node name was not specified for the companion cooling coil.");
1474 0 : ShowContinueError(state,
1475 0 : "Adding condenser inlet air node for " + DesicDehum(DesicDehumNum).CoolingCoilType + " \"" +
1476 0 : DesicDehum(DesicDehumNum).CoolingCoilName + "\"");
1477 0 : ShowContinueError(
1478 0 : state, "...condenser inlet air node name = " + state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).CondenserInletNode));
1479 0 : ShowContinueError(state, "...this node name will be specified as an outdoor air node.");
1480 : }
1481 2 : } else if (DesicDehum(DesicDehumNum).Preheat == Selection::Yes) {
1482 2 : if (!CheckOutAirNodeNumber(state, DesicDehum(DesicDehumNum).CondenserInletNode)) {
1483 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1484 0 : ShowContinueError(state,
1485 0 : "The regeneration air inlet node must be specified as an outdoor air node when " + cAlphaFields(14) +
1486 : " is specified as Yes.");
1487 0 : ErrorsFoundGeneric = true;
1488 : }
1489 : }
1490 : }
1491 :
1492 4 : if (CheckOutAirNodeNumber(state, DesicDehum(DesicDehumNum).RegenAirInNode)) {
1493 2 : DesicDehum(DesicDehumNum).RegenInletIsOutsideAirNode = true;
1494 : }
1495 :
1496 4 : if (DesicDehum(DesicDehumNum).DXCoilIndex == 0 && DesicDehum(DesicDehumNum).Preheat == Selection::Yes) {
1497 0 : ShowWarningError(state, DesicDehum(DesicDehumNum).DehumType + '=' + DesicDehum(DesicDehumNum).Name);
1498 0 : ShowContinueError(state,
1499 0 : "A valid " + cAlphaFields(12) + " must be used when condenser waste heat is reclaimed for desiccant regeneration.");
1500 0 : ShowContinueError(state, "... " + cAlphaFields(11) + " = " + DesicDehum(DesicDehumNum).CoolingCoilType);
1501 0 : ShowContinueError(state, "... " + cAlphaFields(12) + " = " + DesicDehum(DesicDehumNum).CoolingCoilName);
1502 0 : ErrorsFoundGeneric = true;
1503 : }
1504 :
1505 4 : if (DesicDehum(DesicDehumNum).DXCoilIndex > 0 && DesicDehum(DesicDehumNum).CoilUpstreamOfProcessSide == Selection::Yes) {
1506 3 : if ((DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingSingleSpeed) ||
1507 1 : (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingTwoStageWHumControl)) {
1508 1 : ErrorsFound2 = false;
1509 2 : CoilBypassedFlowFrac = GetDXCoilBypassedFlowFrac(
1510 2 : state, DesicDehum(DesicDehumNum).CoolingCoilType, DesicDehum(DesicDehumNum).CoolingCoilName, ErrorsFound2);
1511 1 : } else if (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::Coil_CoolingAirToAirVariableSpeed) {
1512 1 : ErrorsFound2 = false;
1513 1 : CoilBypassedFlowFrac = 0.0; // bypass flow fraction not in VS coil model
1514 : }
1515 2 : if (ErrorsFound2)
1516 0 : ShowContinueError(
1517 0 : state, "...occurs in " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).CoolingCoilName + "\"");
1518 2 : if (CoilBypassedFlowFrac > 0.0) {
1519 0 : ShowWarningError(state, DesicDehum(DesicDehumNum).DehumType + '=' + DesicDehum(DesicDehumNum).Name);
1520 0 : ShowContinueError(state,
1521 0 : "A DX coil bypassed air flow fraction greater than 0 may not be used when the input for " + cAlphaFields(13) +
1522 : " is specified as Yes.");
1523 0 : ShowContinueError(
1524 : state,
1525 0 : "A DX coil with a bypassed air flow fraction greater than 0 may be upstream of the process inlet however the input for " +
1526 0 : cAlphaFields(13) + " must be specified as No.");
1527 0 : ShowContinueError(state, "... " + cAlphaFields(11) + " = " + DesicDehum(DesicDehumNum).CoolingCoilType);
1528 0 : ShowContinueError(state, "... " + cAlphaFields(12) + " = " + DesicDehum(DesicDehumNum).CoolingCoilName);
1529 0 : ErrorsFoundGeneric = true;
1530 : }
1531 2 : } else if (DesicDehum(DesicDehumNum).DXCoilIndex == 0 && DesicDehum(DesicDehumNum).CoilUpstreamOfProcessSide == Selection::Yes) {
1532 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1533 0 : ShowContinueError(state, "A valid companion coil must be specified when " + cAlphaFields(13) + " is specified as Yes.");
1534 0 : ErrorsFoundGeneric = true;
1535 : }
1536 :
1537 4 : if (!DesicDehum(DesicDehumNum).RegenInletIsOutsideAirNode && DesicDehum(DesicDehumNum).Preheat == Selection::Yes) {
1538 0 : ShowWarningError(state, DesicDehum(DesicDehumNum).DehumType + '=' + DesicDehum(DesicDehumNum).Name);
1539 0 : ShowContinueError(state,
1540 0 : "The desiccant dehumidifier regeneration air inlet must be specified as an outdoor air node when " +
1541 0 : cAlphaFields(14) + " is specified as Yes.");
1542 0 : ShowContinueError(state,
1543 0 : "... desiccant dehumidifier regeneration air inlet node name = " +
1544 0 : state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).RegenAirInNode));
1545 0 : ErrorsFoundGeneric = true;
1546 : }
1547 :
1548 4 : if (DesicDehum(DesicDehumNum).CoilUpstreamOfProcessSide == Selection::Yes) {
1549 2 : if (DesicDehum(DesicDehumNum).ProcAirInNode != DesicDehum(DesicDehumNum).CoolingCoilOutletNode) {
1550 0 : ShowSevereError(state, "For " + DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1551 0 : ShowContinueError(state, "Node names are inconsistent in companion cooling coil and desiccant heat exchanger objects.");
1552 0 : ShowContinueError(state,
1553 0 : "For companion cooling coil = " + DesicDehum(DesicDehumNum).CoolingCoilType + " \"" +
1554 0 : DesicDehum(DesicDehumNum).CoolingCoilName + "\"");
1555 0 : ShowContinueError(state,
1556 0 : "The outlet node name in cooling coil = " +
1557 0 : state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).CoolingCoilOutletNode));
1558 0 : ShowContinueError(state,
1559 0 : "For desiccant heat exchanger = " + DesicDehum(DesicDehumNum).HXType + " \"" +
1560 0 : DesicDehum(DesicDehumNum).HXName + "\"");
1561 0 : ShowContinueError(state,
1562 0 : "The process air inlet node name = " + state.dataLoopNodes->NodeID(DesicDehum(DesicDehumNum).ProcAirInNode));
1563 0 : ShowFatalError(state, "...previous error causes program termination.");
1564 : }
1565 : }
1566 :
1567 : // Exhaust Fan input
1568 4 : DesicDehum(DesicDehumNum).ExhaustFanMaxVolFlowRate = Numbers(2);
1569 4 : DesicDehum(DesicDehumNum).ExhaustFanMaxPower = Numbers(3);
1570 4 : DesicDehum(DesicDehumNum).ExhaustFanCurveIndex = GetCurveIndex(state, Alphas(15));
1571 :
1572 4 : if (DesicDehum(DesicDehumNum).ExhaustFanCurveIndex > 0) {
1573 6 : ErrorsFoundGeneric |= Curve::CheckCurveDims(state,
1574 2 : DesicDehum(DesicDehumNum).ExhaustFanCurveIndex, // Curve index
1575 : {1}, // Valid dimensions
1576 : RoutineName, // Routine name
1577 : CurrentModuleObject, // Object Type
1578 2 : DesicDehum(DesicDehumNum).Name, // Object Name
1579 2 : cAlphaFields(15)); // Field Name
1580 : }
1581 :
1582 4 : if (DesicDehum(DesicDehumNum).Preheat == Selection::Yes) {
1583 2 : ErrorsFound2 = false;
1584 2 : if (DesicDehum(DesicDehumNum).ExhaustFanMaxVolFlowRate <= 0) {
1585 0 : ErrorsFound2 = true;
1586 : }
1587 2 : if (DesicDehum(DesicDehumNum).ExhaustFanMaxPower <= 0) {
1588 0 : ErrorsFound2 = true;
1589 : }
1590 2 : if (ErrorsFound2) {
1591 0 : ShowSevereError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1592 0 : ShowContinueError(
1593 0 : state, cNumericFields(2) + " and " + cNumericFields(3) + " must be defined if " + cAlphaFields(14) + " field is \"Yes\".");
1594 : }
1595 2 : } else if (DesicDehum(DesicDehumNum).Preheat == Selection::No) {
1596 2 : if (DesicDehum(DesicDehumNum).ExhaustFanMaxVolFlowRate > 0.0) {
1597 0 : ShowWarningError(state, DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name + "\"");
1598 0 : ShowContinueError(state, cNumericFields(2) + " should be 0 if " + cAlphaFields(14) + " field is \"No\".");
1599 0 : ShowContinueError(state, "..." + cNumericFields(2) + " will not be used and is reset to 0.");
1600 0 : DesicDehum(DesicDehumNum).ExhaustFanMaxVolFlowRate = 0.0;
1601 : }
1602 : }
1603 : }
1604 :
1605 : // SET UP OUTPUTS
1606 12 : for (DesicDehumNum = 1; DesicDehumNum <= state.dataDesiccantDehumidifiers->NumSolidDesicDehums; ++DesicDehumNum) {
1607 : // Setup Report variables for the Desiccant Dehumidifiers
1608 20 : SetupOutputVariable(state,
1609 : "Dehumidifier Removed Water Mass",
1610 : OutputProcessor::Unit::kg,
1611 5 : DesicDehum(DesicDehumNum).WaterRemove,
1612 : OutputProcessor::SOVTimeStepType::System,
1613 : OutputProcessor::SOVStoreType::Summed,
1614 10 : DesicDehum(DesicDehumNum).Name);
1615 20 : SetupOutputVariable(state,
1616 : "Dehumidifier Removed Water Mass Flow Rate",
1617 : OutputProcessor::Unit::kg_s,
1618 5 : DesicDehum(DesicDehumNum).WaterRemoveRate,
1619 : OutputProcessor::SOVTimeStepType::System,
1620 : OutputProcessor::SOVStoreType::Average,
1621 10 : DesicDehum(DesicDehumNum).Name);
1622 20 : SetupOutputVariable(state,
1623 : "Dehumidifier Part Load Ratio",
1624 : OutputProcessor::Unit::None,
1625 5 : DesicDehum(DesicDehumNum).PartLoad,
1626 : OutputProcessor::SOVTimeStepType::System,
1627 : OutputProcessor::SOVStoreType::Average,
1628 10 : DesicDehum(DesicDehumNum).Name);
1629 20 : SetupOutputVariable(state,
1630 : "Dehumidifier Electricity Rate",
1631 : OutputProcessor::Unit::W,
1632 5 : DesicDehum(DesicDehumNum).ElecUseRate,
1633 : OutputProcessor::SOVTimeStepType::System,
1634 : OutputProcessor::SOVStoreType::Average,
1635 10 : DesicDehum(DesicDehumNum).Name);
1636 20 : SetupOutputVariable(state,
1637 : "Dehumidifier Electricity Energy",
1638 : OutputProcessor::Unit::J,
1639 5 : DesicDehum(DesicDehumNum).ElecUseEnergy,
1640 : OutputProcessor::SOVTimeStepType::System,
1641 : OutputProcessor::SOVStoreType::Summed,
1642 5 : DesicDehum(DesicDehumNum).Name,
1643 : _,
1644 : "Electricity",
1645 : "Cooling",
1646 : _,
1647 5 : "System");
1648 20 : SetupOutputVariable(state,
1649 : "Dehumidifier Regeneration Specific Energy",
1650 : OutputProcessor::Unit::J_kgWater,
1651 5 : DesicDehum(DesicDehumNum).SpecRegenEnergy,
1652 : OutputProcessor::SOVTimeStepType::System,
1653 : OutputProcessor::SOVStoreType::Average,
1654 10 : DesicDehum(DesicDehumNum).Name);
1655 20 : SetupOutputVariable(state,
1656 : "Dehumidifier Regeneration Rate",
1657 : OutputProcessor::Unit::W,
1658 5 : DesicDehum(DesicDehumNum).QRegen,
1659 : OutputProcessor::SOVTimeStepType::System,
1660 : OutputProcessor::SOVStoreType::Average,
1661 10 : DesicDehum(DesicDehumNum).Name);
1662 20 : SetupOutputVariable(state,
1663 : "Dehumidifier Regeneration Energy",
1664 : OutputProcessor::Unit::J,
1665 5 : DesicDehum(DesicDehumNum).RegenEnergy,
1666 : OutputProcessor::SOVTimeStepType::System,
1667 : OutputProcessor::SOVStoreType::Summed,
1668 10 : DesicDehum(DesicDehumNum).Name);
1669 20 : SetupOutputVariable(state,
1670 : "Dehumidifier Regeneration Air Speed",
1671 : OutputProcessor::Unit::m_s,
1672 5 : DesicDehum(DesicDehumNum).RegenAirVel,
1673 : OutputProcessor::SOVTimeStepType::System,
1674 : OutputProcessor::SOVStoreType::Average,
1675 10 : DesicDehum(DesicDehumNum).Name);
1676 20 : SetupOutputVariable(state,
1677 : "Dehumidifier Regeneration Air Mass Flow Rate",
1678 : OutputProcessor::Unit::kg_s,
1679 5 : DesicDehum(DesicDehumNum).RegenAirInMassFlowRate,
1680 : OutputProcessor::SOVTimeStepType::System,
1681 : OutputProcessor::SOVStoreType::Average,
1682 10 : DesicDehum(DesicDehumNum).Name);
1683 20 : SetupOutputVariable(state,
1684 : "Dehumidifier Process Air Mass Flow Rate",
1685 : OutputProcessor::Unit::kg_s,
1686 5 : DesicDehum(DesicDehumNum).ProcAirInMassFlowRate,
1687 : OutputProcessor::SOVTimeStepType::System,
1688 : OutputProcessor::SOVStoreType::Average,
1689 10 : DesicDehum(DesicDehumNum).Name);
1690 : }
1691 :
1692 11 : for (DesicDehumNum = 1; DesicDehumNum <= state.dataDesiccantDehumidifiers->NumGenericDesicDehums; ++DesicDehumNum) {
1693 : // Setup Report variables for the Desiccant Dehumidifiers
1694 16 : SetupOutputVariable(state,
1695 : "Dehumidifier Removed Water Mass",
1696 : OutputProcessor::Unit::kg,
1697 4 : DesicDehum(DesicDehumNum).WaterRemove,
1698 : OutputProcessor::SOVTimeStepType::System,
1699 : OutputProcessor::SOVStoreType::Summed,
1700 8 : DesicDehum(DesicDehumNum).Name);
1701 16 : SetupOutputVariable(state,
1702 : "Dehumidifier Removed Water Mass Flow Rate",
1703 : OutputProcessor::Unit::kg_s,
1704 4 : DesicDehum(DesicDehumNum).WaterRemoveRate,
1705 : OutputProcessor::SOVTimeStepType::System,
1706 : OutputProcessor::SOVStoreType::Average,
1707 8 : DesicDehum(DesicDehumNum).Name);
1708 16 : SetupOutputVariable(state,
1709 : "Dehumidifier Part Load Ratio",
1710 : OutputProcessor::Unit::None,
1711 4 : DesicDehum(DesicDehumNum).PartLoad,
1712 : OutputProcessor::SOVTimeStepType::System,
1713 : OutputProcessor::SOVStoreType::Average,
1714 8 : DesicDehum(DesicDehumNum).Name);
1715 4 : if (DesicDehum(DesicDehumNum).ExhaustFanMaxVolFlowRate > 0) {
1716 8 : SetupOutputVariable(state,
1717 : "Dehumidifier Exhaust Fan Electricity Rate",
1718 : OutputProcessor::Unit::W,
1719 2 : DesicDehum(DesicDehumNum).ExhaustFanPower,
1720 : OutputProcessor::SOVTimeStepType::System,
1721 : OutputProcessor::SOVStoreType::Average,
1722 4 : DesicDehum(DesicDehumNum).Name);
1723 8 : SetupOutputVariable(state,
1724 : "Dehumidifier Exhaust Fan Electricity Energy",
1725 : OutputProcessor::Unit::J,
1726 2 : DesicDehum(DesicDehumNum).ExhaustFanElecConsumption,
1727 : OutputProcessor::SOVTimeStepType::System,
1728 : OutputProcessor::SOVStoreType::Summed,
1729 2 : DesicDehum(DesicDehumNum).Name,
1730 : _,
1731 : "Electricity",
1732 : "Cooling",
1733 : _,
1734 2 : "System");
1735 : }
1736 : }
1737 :
1738 7 : if (ErrorsFound) {
1739 0 : ShowFatalError(state, "Errors found in getting Dehumidifier:Desiccant:NoFans input");
1740 7 : } else if (ErrorsFoundGeneric) {
1741 0 : ShowFatalError(state, "Errors found in getting DESICCANT DEHUMIDIFIER input");
1742 : }
1743 :
1744 7 : Alphas.deallocate();
1745 7 : cAlphaFields.deallocate();
1746 7 : cNumericFields.deallocate();
1747 7 : Numbers.deallocate();
1748 7 : lAlphaBlanks.deallocate();
1749 7 : lNumericBlanks.deallocate();
1750 7 : }
1751 :
1752 275214 : void InitDesiccantDehumidifier(EnergyPlusData &state,
1753 : int const DesicDehumNum, // number of the current dehumidifier being simulated
1754 : bool const FirstHVACIteration // TRUE if 1st HVAC simulation of system timestep
1755 : )
1756 : {
1757 :
1758 : // SUBROUTINE INFORMATION:
1759 : // AUTHOR Michael J. Witte, GARD Analytics, Inc.
1760 : // for Gas Research Institute
1761 : // DATE WRITTEN March 2001
1762 : // MODIFIED Jan 2005 M. J. Witte, GARD Analytics, Inc.
1763 : // Add setpoint validation for new control type option:
1764 : // NODE LEAVING HUMRAT SETPOINT:BYPASS
1765 : // Work supported by ASHRAE research project 1254-RP
1766 : // June 2007 R. Raustad, FSEC
1767 : // Added new dehumidifier type -- DESICCANT DEHUMIDIFIER
1768 : // May 2009, B. Griffith, NREL. added EMS node setpoint checks
1769 : // RE-ENGINEERED na
1770 :
1771 : // PURPOSE OF THIS SUBROUTINE:
1772 : // This subroutine is for initializations of the dehumidifier Components.
1773 :
1774 : // METHODOLOGY EMPLOYED:
1775 : // Uses the status flags to trigger initializations.
1776 :
1777 : // REFERENCES:
1778 : // na
1779 :
1780 : // Using/Aliasing
1781 275214 : auto &DoSetPointTest = state.dataHVACGlobal->DoSetPointTest;
1782 275214 : auto &SetPointErrorFlag = state.dataHVACGlobal->SetPointErrorFlag;
1783 : using EMSManager::CheckIfNodeSetPointManagedByEMS;
1784 : using Psychrometrics::PsyRhoAirFnPbTdbW;
1785 : using SteamCoils::SimulateSteamCoilComponents;
1786 275214 : auto &GetCoilMaxSteamFlowRate(SteamCoils::GetCoilMaxSteamFlowRate);
1787 : using DataSizing::AutoSize;
1788 : using FluidProperties::GetDensityGlycol;
1789 : using FluidProperties::GetSatDensityRefrig;
1790 : using PlantUtilities::InitComponentNodes;
1791 : using PlantUtilities::ScanPlantLoopsForObject;
1792 : using PlantUtilities::SetComponentFlowRate;
1793 : using WaterCoils::GetCoilMaxWaterFlowRate;
1794 : using WaterCoils::SimulateWaterCoilComponents;
1795 :
1796 : // SUBROUTINE PARAMETER DEFINITIONS:
1797 : static constexpr std::string_view RoutineName("InitDesiccantDehumidifier");
1798 275214 : static std::string const initCBVAV("InitCBVAV");
1799 :
1800 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1801 : int ProcInNode; // inlet node number
1802 : int RegenInNode; // inlet node number
1803 : int ControlNode; // control node number
1804 275214 : bool ErrorsFound(false); // Set to true if errors in input, fatal at end of routine
1805 : int SteamIndex; // steam coil index
1806 : Real64 FluidDensity; // steam or water coil fluid density
1807 : Real64 CoilMaxVolFlowRate; // water or steam max volumetric water flow rate
1808 : Real64 QCoilActual; // actual CBVAV steam heating coil load met (W)
1809 : bool ErrorFlag; // local error flag returned from data mining
1810 :
1811 275214 : auto &DesicDehum(state.dataDesiccantDehumidifiers->DesicDehum);
1812 275214 : auto &MyEnvrnFlag(state.dataDesiccantDehumidifiers->MyEnvrnFlag);
1813 275214 : auto &MyPlantScanFlag(state.dataDesiccantDehumidifiers->MyPlantScanFlag);
1814 :
1815 275214 : if (state.dataDesiccantDehumidifiers->InitDesiccantDehumidifierOneTimeFlag) {
1816 :
1817 : // initialize the environment and sizing flags
1818 7 : MyEnvrnFlag.allocate(state.dataDesiccantDehumidifiers->NumDesicDehums);
1819 7 : MyPlantScanFlag.allocate(state.dataDesiccantDehumidifiers->NumDesicDehums);
1820 7 : MyEnvrnFlag = true;
1821 :
1822 7 : state.dataDesiccantDehumidifiers->InitDesiccantDehumidifierOneTimeFlag = false;
1823 7 : MyPlantScanFlag = true;
1824 : }
1825 :
1826 275214 : if (MyPlantScanFlag(DesicDehumNum) && allocated(state.dataPlnt->PlantLoop)) {
1827 18 : if ((DesicDehum(DesicDehumNum).RegenCoilType_Num == Coil_HeatingWater) ||
1828 9 : (DesicDehum(DesicDehumNum).RegenCoilType_Num == Coil_HeatingSteam)) {
1829 0 : if (DesicDehum(DesicDehumNum).RegenCoilType_Num == Coil_HeatingWater) {
1830 0 : ErrorFlag = false;
1831 0 : ScanPlantLoopsForObject(state,
1832 0 : DesicDehum(DesicDehumNum).RegenCoilName,
1833 : DataPlant::PlantEquipmentType::CoilWaterSimpleHeating,
1834 0 : DesicDehum(DesicDehumNum).plantLoc,
1835 : ErrorFlag,
1836 : _,
1837 : _,
1838 : _,
1839 : _,
1840 : _);
1841 0 : if (ErrorFlag) {
1842 0 : ShowFatalError(state, "InitDesiccantDehumidifier: Program terminated for previous conditions.");
1843 : }
1844 :
1845 0 : ErrorFlag = false;
1846 0 : DesicDehum(DesicDehumNum).MaxCoilFluidFlow =
1847 0 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", DesicDehum(DesicDehumNum).RegenCoilName, ErrorFlag);
1848 0 : if (DesicDehum(DesicDehumNum).MaxCoilFluidFlow > 0.0) {
1849 0 : FluidDensity = GetDensityGlycol(state,
1850 0 : state.dataPlnt->PlantLoop(DesicDehum(DesicDehumNum).plantLoc.loopNum).FluidName,
1851 : DataGlobalConstants::HWInitConvTemp,
1852 0 : state.dataPlnt->PlantLoop(DesicDehum(DesicDehumNum).plantLoc.loopNum).FluidIndex,
1853 : initCBVAV);
1854 0 : DesicDehum(DesicDehumNum).MaxCoilFluidFlow *= FluidDensity;
1855 : }
1856 :
1857 0 : } else if (DesicDehum(DesicDehumNum).RegenCoilType_Num == Coil_HeatingSteam) {
1858 :
1859 0 : ErrorFlag = false;
1860 0 : ScanPlantLoopsForObject(state,
1861 0 : DesicDehum(DesicDehumNum).RegenCoilName,
1862 : DataPlant::PlantEquipmentType::CoilSteamAirHeating,
1863 0 : DesicDehum(DesicDehumNum).plantLoc,
1864 : ErrorFlag,
1865 : _,
1866 : _,
1867 : _,
1868 : _,
1869 : _);
1870 :
1871 0 : if (ErrorFlag) {
1872 0 : ShowFatalError(state, "InitDesiccantDehumidifier: Program terminated for previous conditions.");
1873 : }
1874 0 : ErrorFlag = false;
1875 0 : DesicDehum(DesicDehumNum).MaxCoilFluidFlow = GetCoilMaxSteamFlowRate(state, DesicDehum(DesicDehumNum).RegenCoilIndex, ErrorFlag);
1876 :
1877 0 : if (DesicDehum(DesicDehumNum).MaxCoilFluidFlow > 0.0) {
1878 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
1879 0 : FluidDensity =
1880 0 : GetSatDensityRefrig(state, fluidNameSteam, state.dataDesiccantDehumidifiers->TempSteamIn, 1.0, SteamIndex, RoutineName);
1881 0 : DesicDehum(DesicDehumNum).MaxCoilFluidFlow *= FluidDensity;
1882 : }
1883 : }
1884 :
1885 : // fill outlet node for regenartion hot water or steam heating coil
1886 0 : DesicDehum(DesicDehumNum).CoilOutletNode =
1887 0 : DataPlant::CompData::getPlantComponent(state, DesicDehum(DesicDehumNum).plantLoc).NodeNumOut;
1888 0 : MyPlantScanFlag(DesicDehumNum) = false;
1889 :
1890 : } else { // DesicDehum is not connected to plant
1891 9 : MyPlantScanFlag(DesicDehumNum) = false;
1892 : }
1893 275205 : } else if (MyPlantScanFlag(DesicDehumNum) && !state.dataGlobal->AnyPlantInModel) {
1894 0 : MyPlantScanFlag(DesicDehumNum) = false;
1895 : }
1896 :
1897 275214 : switch (DesicDehum(DesicDehumNum).DehumTypeCode) {
1898 93953 : case DesicDehumType::Solid: {
1899 93953 : if (!state.dataGlobal->SysSizingCalc && state.dataDesiccantDehumidifiers->MySetPointCheckFlag && DoSetPointTest) {
1900 5 : if (DesicDehum(DesicDehumNum).controlType == DesicDehumCtrlType::NodeHumratBypass) {
1901 2 : ControlNode = DesicDehum(DesicDehumNum).ProcAirOutNode;
1902 2 : if (ControlNode > 0) {
1903 2 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax == SensedNodeFlagValue) {
1904 0 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
1905 0 : ShowSevereError(state, "Missing humidity ratio setpoint (HumRatMax) for ");
1906 0 : ShowContinueError(state, "Dehumidifier:Desiccant:NoFans: " + DesicDehum(DesicDehumNum).Name);
1907 0 : ShowContinueError(state, "Node Referenced=" + state.dataLoopNodes->NodeID(ControlNode));
1908 0 : ShowContinueError(state, "use a Setpoint Manager to establish a setpoint at the process air outlet node.");
1909 0 : SetPointErrorFlag = true;
1910 : } else {
1911 0 : CheckIfNodeSetPointManagedByEMS(
1912 : state, ControlNode, EMSManager::SPControlType::HumidityRatioMaxSetPoint, SetPointErrorFlag);
1913 0 : if (SetPointErrorFlag) {
1914 0 : ShowSevereError(state, "Missing humidity ratio setpoint (HumRatMax) for ");
1915 0 : ShowContinueError(state, "Dehumidifier:Desiccant:NoFans: " + DesicDehum(DesicDehumNum).Name);
1916 0 : ShowContinueError(state, "Node Referenced=" + state.dataLoopNodes->NodeID(ControlNode));
1917 0 : ShowContinueError(state, "use a Setpoint Manager to establish a setpoint at the process air outlet node.");
1918 0 : ShowContinueError(state, "Or use EMS Actuator to establish a setpoint at the process air outlet node.");
1919 : }
1920 : }
1921 : }
1922 : }
1923 : }
1924 5 : state.dataDesiccantDehumidifiers->MySetPointCheckFlag = false;
1925 : }
1926 : // always do these initializations every iteration
1927 93953 : ProcInNode = DesicDehum(DesicDehumNum).ProcAirInNode;
1928 93953 : DesicDehum(DesicDehumNum).ProcAirInTemp = state.dataLoopNodes->Node(ProcInNode).Temp;
1929 93953 : DesicDehum(DesicDehumNum).ProcAirInHumRat = state.dataLoopNodes->Node(ProcInNode).HumRat;
1930 93953 : DesicDehum(DesicDehumNum).ProcAirInEnthalpy = state.dataLoopNodes->Node(ProcInNode).Enthalpy;
1931 93953 : DesicDehum(DesicDehumNum).ProcAirInMassFlowRate = state.dataLoopNodes->Node(ProcInNode).MassFlowRate;
1932 :
1933 : // Determine heating coil inlet conditions by calling it with zero load
1934 : // Not sure if this is really a good way to do this, should revisit for next release.
1935 93953 : CalcNonDXHeatingCoils(state, DesicDehumNum, FirstHVACIteration, 0.0);
1936 :
1937 93953 : RegenInNode = DesicDehum(DesicDehumNum).RegenAirInNode;
1938 93953 : DesicDehum(DesicDehumNum).RegenAirInTemp = state.dataLoopNodes->Node(RegenInNode).Temp;
1939 93953 : DesicDehum(DesicDehumNum).RegenAirInHumRat = state.dataLoopNodes->Node(RegenInNode).HumRat;
1940 93953 : DesicDehum(DesicDehumNum).RegenAirInEnthalpy = state.dataLoopNodes->Node(RegenInNode).Enthalpy;
1941 :
1942 93953 : DesicDehum(DesicDehumNum).WaterRemove = 0.0;
1943 93953 : DesicDehum(DesicDehumNum).ElecUseEnergy = 0.0;
1944 93953 : DesicDehum(DesicDehumNum).ElecUseRate = 0.0;
1945 :
1946 93953 : } break;
1947 181261 : case DesicDehumType::Generic: {
1948 : // Do the Begin Environment initializations
1949 181261 : if (state.dataGlobal->BeginEnvrnFlag && MyEnvrnFlag(DesicDehumNum)) {
1950 : // Change the Volume Flow Rates to Mass Flow Rates
1951 4 : DesicDehum(DesicDehumNum).ExhaustFanMaxMassFlowRate = DesicDehum(DesicDehumNum).ExhaustFanMaxVolFlowRate * state.dataEnvrn->StdRhoAir;
1952 :
1953 : // set fluid-side hardware limits
1954 4 : if (DesicDehum(DesicDehumNum).CoilControlNode > 0) {
1955 : // If water coil max water flow rate is autosized, simulate once in order to mine max water flow rate
1956 0 : if (DesicDehum(DesicDehumNum).MaxCoilFluidFlow == AutoSize) {
1957 0 : if (DesicDehum(DesicDehumNum).RegenCoilType_Num == Coil_HeatingWater) {
1958 0 : SimulateWaterCoilComponents(
1959 0 : state, DesicDehum(DesicDehumNum).RegenCoilName, FirstHVACIteration, DesicDehum(DesicDehumNum).RegenCoilIndex);
1960 0 : ErrorFlag = false;
1961 0 : CoilMaxVolFlowRate =
1962 0 : GetCoilMaxWaterFlowRate(state, "Coil:Heating:Water", DesicDehum(DesicDehumNum).RegenCoilName, ErrorFlag);
1963 0 : if (ErrorFlag) {
1964 0 : ErrorsFound = true;
1965 : }
1966 0 : if (CoilMaxVolFlowRate != AutoSize) {
1967 0 : FluidDensity = GetDensityGlycol(state,
1968 0 : state.dataPlnt->PlantLoop(DesicDehum(DesicDehumNum).plantLoc.loopNum).FluidName,
1969 : DataGlobalConstants::HWInitConvTemp,
1970 0 : state.dataPlnt->PlantLoop(DesicDehum(DesicDehumNum).plantLoc.loopNum).FluidIndex,
1971 : RoutineName);
1972 0 : DesicDehum(DesicDehumNum).MaxCoilFluidFlow = CoilMaxVolFlowRate * FluidDensity;
1973 : }
1974 : }
1975 0 : if (DesicDehum(DesicDehumNum).RegenCoilType_Num == Coil_HeatingSteam) {
1976 0 : SimulateSteamCoilComponents(state,
1977 0 : DesicDehum(DesicDehumNum).RegenCoilName,
1978 : FirstHVACIteration,
1979 0 : DesicDehum(DesicDehumNum).RegenCoilIndex,
1980 : 1.0,
1981 : QCoilActual); // simulate any load > 0 to get max capacity of steam coil
1982 0 : ErrorFlag = false;
1983 0 : CoilMaxVolFlowRate = GetCoilMaxSteamFlowRate(state, DesicDehum(DesicDehumNum).RegenCoilIndex, ErrorFlag);
1984 0 : if (ErrorFlag) {
1985 0 : ErrorsFound = true;
1986 : }
1987 0 : if (CoilMaxVolFlowRate != AutoSize) {
1988 0 : SteamIndex = 0; // Function GetSatDensityRefrig will look up steam index if 0 is passed
1989 0 : FluidDensity = GetSatDensityRefrig(
1990 0 : state, fluidNameSteam, state.dataDesiccantDehumidifiers->TempSteamIn, 1.0, SteamIndex, RoutineName);
1991 0 : DesicDehum(DesicDehumNum).MaxCoilFluidFlow = CoilMaxVolFlowRate * FluidDensity;
1992 : }
1993 : }
1994 : }
1995 0 : InitComponentNodes(state,
1996 : 0.0,
1997 0 : DesicDehum(DesicDehumNum).MaxCoilFluidFlow,
1998 0 : DesicDehum(DesicDehumNum).CoilControlNode,
1999 0 : DesicDehum(DesicDehumNum).CoilOutletNode);
2000 : }
2001 :
2002 4 : MyEnvrnFlag(DesicDehumNum) = false;
2003 : }
2004 :
2005 181261 : if (!state.dataGlobal->SysSizingCalc && state.dataDesiccantDehumidifiers->MySetPointCheckFlag && DoSetPointTest) {
2006 2 : ControlNode = DesicDehum(DesicDehumNum).ControlNodeNum;
2007 2 : if (ControlNode > 0) {
2008 2 : if (state.dataLoopNodes->Node(ControlNode).HumRatMax == SensedNodeFlagValue) {
2009 0 : if (!state.dataGlobal->AnyEnergyManagementSystemInModel) {
2010 0 : ShowSevereError(state, "Missing maximum humidity ratio setpoint (MaxHumRat) for ");
2011 0 : ShowContinueError(state, DesicDehum(DesicDehumNum).DehumType + ": " + DesicDehum(DesicDehumNum).Name);
2012 0 : ShowContinueError(state, "Node Referenced=" + state.dataLoopNodes->NodeID(ControlNode));
2013 0 : ShowContinueError(state, "use a Setpoint Manager to establish a \"MaxHumRat\" setpoint at the process air control node.");
2014 0 : SetPointErrorFlag = true;
2015 : } else {
2016 0 : CheckIfNodeSetPointManagedByEMS(
2017 : state, ControlNode, EMSManager::SPControlType::HumidityRatioMaxSetPoint, SetPointErrorFlag);
2018 0 : if (SetPointErrorFlag) {
2019 0 : ShowSevereError(state, "Missing maximum humidity ratio setpoint (MaxHumRat) for ");
2020 0 : ShowContinueError(state, DesicDehum(DesicDehumNum).DehumType + ": " + DesicDehum(DesicDehumNum).Name);
2021 0 : ShowContinueError(state, "Node Referenced=" + state.dataLoopNodes->NodeID(ControlNode));
2022 0 : ShowContinueError(state,
2023 : "use a Setpoint Manager to establish a \"MaxHumRat\" setpoint at the process air control node.");
2024 0 : ShowContinueError(state, "Or use EMS Actuator to establish a setpoint at the process air outlet node.");
2025 : }
2026 : }
2027 : }
2028 : }
2029 2 : state.dataDesiccantDehumidifiers->MySetPointCheckFlag = false;
2030 : }
2031 181261 : RegenInNode = DesicDehum(DesicDehumNum).RegenAirInNode;
2032 181261 : DesicDehum(DesicDehumNum).RegenAirInTemp = state.dataLoopNodes->Node(RegenInNode).Temp;
2033 181261 : DesicDehum(DesicDehumNum).RegenAirInMassFlowRate = state.dataLoopNodes->Node(RegenInNode).MassFlowRate;
2034 :
2035 181261 : DesicDehum(DesicDehumNum).ExhaustFanPower = 0.0;
2036 181261 : DesicDehum(DesicDehumNum).WaterRemoveRate = 0.0;
2037 181261 : } break;
2038 0 : default:
2039 0 : break;
2040 : }
2041 275214 : }
2042 :
2043 275214 : void ControlDesiccantDehumidifier(EnergyPlusData &state,
2044 : int const DesicDehumNum, // number of the current dehumidifier being simulated
2045 : Real64 &HumRatNeeded, // process air leaving humidity ratio set by controller [kg water/kg air]
2046 : [[maybe_unused]] bool const FirstHVACIteration // TRUE if 1st HVAC simulation of system timestep !unused1208
2047 : )
2048 : {
2049 :
2050 : // SUBROUTINE INFORMATION:
2051 : // AUTHOR Michael J. Witte, GARD Analytics, Inc.
2052 : // for Gas Research Institute
2053 : // DATE WRITTEN March 2001
2054 : // MODIFIED Jan 2005 M. J. Witte, GARD Analytics, Inc.
2055 : // Add new control type option:
2056 : // NODE LEAVING HUMRAT SETPOINT:BYPASS
2057 : // Change existing control type to:
2058 : // FIXED LEAVING HUMRAT SETPOINT:BYPASS
2059 : // Work supported by ASHRAE research project 1254-RP
2060 : // June 2007 R. Raustad, FSEC
2061 : // Added new dehumidifier type -- DESICCANT DEHUMIDIFIER
2062 : // RE-ENGINEERED na
2063 :
2064 : // PURPOSE OF THIS SUBROUTINE:
2065 : // This subroutine sets the output required from the dehumidifier
2066 :
2067 : // METHODOLOGY EMPLOYED:
2068 : // Uses a maximum humidity ratio setpoint to calculate required process
2069 : // leaving humidity ratio
2070 :
2071 : // REFERENCES:
2072 : // na
2073 :
2074 : // USE STATEMENTS:
2075 : // na
2076 :
2077 : // Locals
2078 : // SUBROUTINE ARGUMENT DEFINITIONS:
2079 :
2080 : // SUBROUTINE PARAMETER DEFINITIONS:
2081 : // na
2082 :
2083 : // INTERFACE BLOCK SPECIFICATIONS
2084 : // na
2085 :
2086 : // DERIVED TYPE DEFINITIONS
2087 : // na
2088 :
2089 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2090 : bool UnitOn; // unit on flag
2091 : Real64 ProcAirMassFlowRate; // process air mass flow rate [kg/s]
2092 : Real64 RegenAirMassFlowRate; // regen air mass flow rate [kg/s]
2093 :
2094 275214 : auto &DesicDehum(state.dataDesiccantDehumidifiers->DesicDehum);
2095 :
2096 275214 : ProcAirMassFlowRate = 0.0;
2097 275214 : RegenAirMassFlowRate = 0.0;
2098 275214 : UnitOn = true;
2099 :
2100 275214 : switch (DesicDehum(DesicDehumNum).DehumTypeCode) {
2101 93953 : case DesicDehumType::Solid: {
2102 93953 : if (DesicDehum(DesicDehumNum).HumRatSet <= 0.0) UnitOn = false;
2103 93953 : ProcAirMassFlowRate = DesicDehum(DesicDehumNum).ProcAirInMassFlowRate;
2104 93953 : if (ProcAirMassFlowRate <= SmallMassFlow) UnitOn = false;
2105 :
2106 93953 : if (GetCurrentScheduleValue(state, DesicDehum(DesicDehumNum).SchedPtr) <= 0.0) UnitOn = false;
2107 :
2108 : // If incoming conditions are outside valid range for curve fits, then shut unit off, do not issue warnings
2109 :
2110 93953 : if (UnitOn) {
2111 146881 : if ((DesicDehum(DesicDehumNum).ProcAirInTemp < DesicDehum(DesicDehumNum).MinProcAirInTemp) ||
2112 57488 : (DesicDehum(DesicDehumNum).ProcAirInTemp > DesicDehum(DesicDehumNum).MaxProcAirInTemp)) {
2113 31905 : UnitOn = false;
2114 : }
2115 146881 : if ((DesicDehum(DesicDehumNum).ProcAirInHumRat < DesicDehum(DesicDehumNum).MinProcAirInHumRat) ||
2116 57488 : (DesicDehum(DesicDehumNum).ProcAirInHumRat > DesicDehum(DesicDehumNum).MaxProcAirInHumRat)) {
2117 31905 : UnitOn = false;
2118 : }
2119 : }
2120 :
2121 93953 : if (UnitOn) {
2122 :
2123 : // perform the correct dehumidifier control strategy
2124 57488 : switch (DesicDehum(DesicDehumNum).controlType) {
2125 23360 : case DesicDehumCtrlType::FixedHumratBypass: {
2126 23360 : HumRatNeeded = DesicDehum(DesicDehumNum).HumRatSet;
2127 23360 : if (HumRatNeeded <= 0.0) {
2128 0 : ShowSevereError(state, "Dehumidifier:Desiccant:NoFans: " + DesicDehum(DesicDehumNum).Name);
2129 0 : ShowContinueError(state, format("Invalid Leaving Max Humidity Ratio Setpoint={:.8T}", HumRatNeeded));
2130 0 : ShowFatalError(state, "must be > 0.0");
2131 : }
2132 23360 : } break;
2133 34128 : case DesicDehumCtrlType::NodeHumratBypass: {
2134 34128 : HumRatNeeded = state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirOutNode).HumRatMax;
2135 34128 : } break;
2136 0 : default: {
2137 0 : ShowFatalError(state, "Invalid control type in desiccant dehumidifier = " + DesicDehum(DesicDehumNum).Name);
2138 0 : } break;
2139 : }
2140 :
2141 : // Setpoint of zero indicates no load from setpoint manager max hum
2142 57488 : if ((HumRatNeeded == 0.0) || (DesicDehum(DesicDehumNum).ProcAirInHumRat <= HumRatNeeded)) {
2143 384 : UnitOn = false;
2144 384 : HumRatNeeded = DesicDehum(DesicDehumNum).ProcAirInHumRat;
2145 : }
2146 : } else {
2147 36465 : HumRatNeeded = DesicDehum(DesicDehumNum).ProcAirInHumRat;
2148 : }
2149 :
2150 93953 : } break;
2151 181261 : case DesicDehumType::Generic: {
2152 181261 : ProcAirMassFlowRate = state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).MassFlowRate;
2153 181261 : if (ProcAirMassFlowRate <= SmallMassFlow) UnitOn = false;
2154 :
2155 181261 : if (GetCurrentScheduleValue(state, DesicDehum(DesicDehumNum).SchedPtr) <= 0.0) UnitOn = false;
2156 :
2157 181261 : if (UnitOn) {
2158 181243 : if (DesicDehum(DesicDehumNum).ControlNodeNum == DesicDehum(DesicDehumNum).ProcAirOutNode) {
2159 181243 : HumRatNeeded = state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ControlNodeNum).HumRatMax;
2160 : } else {
2161 0 : if (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ControlNodeNum).HumRatMax > 0.0) {
2162 0 : HumRatNeeded = state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ControlNodeNum).HumRatMax -
2163 0 : (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ControlNodeNum).HumRat -
2164 0 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirOutNode).HumRat);
2165 : } else {
2166 0 : HumRatNeeded = 0.0;
2167 : }
2168 : }
2169 :
2170 : // Setpoint of zero indicates no load from setpoint manager max hum
2171 181243 : if ((HumRatNeeded == 0.0) || (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).HumRat <= HumRatNeeded)) {
2172 176271 : HumRatNeeded = state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).HumRat;
2173 : }
2174 : } else {
2175 18 : HumRatNeeded = state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).HumRat;
2176 : }
2177 :
2178 181261 : } break;
2179 0 : default:
2180 0 : break;
2181 : }
2182 275214 : }
2183 :
2184 93953 : void CalcSolidDesiccantDehumidifier(EnergyPlusData &state,
2185 : int const DesicDehumNum, // number of the current dehumidifier being simulated
2186 : Real64 const HumRatNeeded, // process air leaving humidity ratio set by controller [kgWater/kgDryAir]
2187 : bool const FirstHVACIteration // TRUE if 1st HVAC simulation of system timestep
2188 : )
2189 : {
2190 :
2191 : // SUBROUTINE INFORMATION:
2192 : // AUTHOR Michael J. Witte, GARD Analytics, Inc.
2193 : // for Gas Research Institute
2194 : // DATE WRITTEN March 2001
2195 : // MODIFIED na
2196 : // RE-ENGINEERED na
2197 :
2198 : // PURPOSE OF THIS SUBROUTINE:
2199 : // Calculate the electricity consumption, regen heat requirements and the outlet
2200 : // conditions for a solid desiccant dehumidifier, given the inlet conditions and
2201 : // and the needed process leaving humidity ratio.
2202 :
2203 : // METHODOLOGY EMPLOYED:
2204 : // Given the entering conditions, the full-load outlet conditions are calculated.
2205 : // Adjust for part-load if required.
2206 : // Caclulate required regen energy and call regen coil and regen fan.
2207 : // Desiccant wheel leaving conditions and regen energy requirements are calculated
2208 : // from empirical curve fits. The user can select either default built-in
2209 : // performance curves, or use custom user-defined curves.
2210 :
2211 : // REFERENCES:
2212 : // The default performance curves represent a commerical-grade solid desiccant
2213 : // wheel typical of HVAC applications in the early 1990's. These curves were
2214 : // developed for Gas Research Institute by William W. Worek, University of Illinois
2215 : // at Chicago.
2216 :
2217 : // Using/Aliasing
2218 : using Psychrometrics::PsyHFnTdbW;
2219 : using Psychrometrics::PsyRhoAirFnPbTdbW;
2220 :
2221 : // Locals
2222 : // SUBROUTINE ARGUMENT DEFINITIONS:
2223 :
2224 : // SUBROUTINE PARAMETER DEFINITIONS:
2225 : // na
2226 :
2227 : // INTERFACE BLOCK SPECIFICATIONS
2228 : // na
2229 :
2230 : // DERIVED TYPE DEFINITIONS
2231 : // na
2232 :
2233 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2234 :
2235 : Real64 ProcAirInHumRat; // process inlet air humidity ratio [kgWater/kgDryAir]
2236 : Real64 ProcAirInTemp; // process inlet air temperature [C]
2237 : Real64 ProcAirOutHumRat; // process outlet air humidity ratio [kgWater/kgDryAir]
2238 : Real64 MinProcAirOutHumRat; // minimum available process outlet air humidity ratio [kgWater/kgDryAir]
2239 : Real64 ProcAirOutTemp; // process outlet air temperature [C]
2240 : Real64 ProcAirVel; // process air velocity [m/s]
2241 : Real64 QRegen; // regen heat input rate requested from regen coil [W]
2242 : Real64 QDelivered; // regen heat actually delivered by regen coil [W]
2243 : // REAL(r64) :: RegenAirInHumRat ! regen inlet air humidity ratio [kgWater/kgDryAir]
2244 : Real64 RegenAirInTemp; // regen inlet air temperature [C]
2245 : Real64 RegenAirVel; // regen air velocity [m/s]
2246 : Real64 ProcAirMassFlowRate; // process air mass flow rate [kg/s]
2247 : Real64 RegenAirMassFlowRate; // regen air mass flow rate [kg/s]
2248 : Real64 SpecRegenEnergy; // specific regen energy [J/kg of water removed]
2249 : Real64 NomRegenTemp; // nominal regen temperature for regen energy curve
2250 : Real64 ElecUseRate; // electricity consumption rate [W]
2251 : Real64 PartLoad; // fraction of dehumidification capacity required to meet setpoint
2252 : bool UnitOn; // unit on flag
2253 :
2254 : // Variables for hardwired coefficients for default performance model
2255 :
2256 : Real64 TC0;
2257 : Real64 TC1;
2258 : Real64 TC2;
2259 : Real64 TC3;
2260 : Real64 TC4;
2261 : Real64 TC5;
2262 : Real64 TC6;
2263 : Real64 TC7;
2264 : Real64 TC8;
2265 : Real64 TC9;
2266 : Real64 TC10;
2267 : Real64 TC11;
2268 : Real64 TC12;
2269 : Real64 TC13;
2270 : Real64 TC14;
2271 : Real64 TC15;
2272 :
2273 : Real64 WC0;
2274 : Real64 WC1;
2275 : Real64 WC2;
2276 : Real64 WC3;
2277 : Real64 WC4;
2278 : Real64 WC5;
2279 : Real64 WC6;
2280 : Real64 WC7;
2281 : Real64 WC8;
2282 : Real64 WC9;
2283 : Real64 WC10;
2284 : Real64 WC11;
2285 : Real64 WC12;
2286 : Real64 WC13;
2287 : Real64 WC14;
2288 : Real64 WC15;
2289 :
2290 : Real64 QC0;
2291 : Real64 QC1;
2292 : Real64 QC2;
2293 : Real64 QC3;
2294 : Real64 QC4;
2295 : Real64 QC5;
2296 : Real64 QC6;
2297 : Real64 QC7;
2298 : Real64 QC8;
2299 : Real64 QC9;
2300 : Real64 QC10;
2301 : Real64 QC11;
2302 : Real64 QC12;
2303 : Real64 QC13;
2304 : Real64 QC14;
2305 : Real64 QC15;
2306 :
2307 : Real64 RC0;
2308 : Real64 RC1;
2309 : Real64 RC2;
2310 : Real64 RC3;
2311 : Real64 RC4;
2312 : Real64 RC5;
2313 : Real64 RC6;
2314 : Real64 RC7;
2315 : Real64 RC8;
2316 : Real64 RC9;
2317 : Real64 RC10;
2318 : Real64 RC11;
2319 : Real64 RC12;
2320 : Real64 RC13;
2321 : Real64 RC14;
2322 : Real64 RC15;
2323 :
2324 93953 : auto &DesicDehum(state.dataDesiccantDehumidifiers->DesicDehum);
2325 93953 : auto &RhoAirStdInit(state.dataDesiccantDehumidifiers->RhoAirStdInit);
2326 :
2327 : // Setup internal variables for calculations
2328 :
2329 93953 : ProcAirInTemp = DesicDehum(DesicDehumNum).ProcAirInTemp;
2330 93953 : ProcAirInHumRat = DesicDehum(DesicDehumNum).ProcAirInHumRat;
2331 93953 : ProcAirMassFlowRate = DesicDehum(DesicDehumNum).ProcAirInMassFlowRate;
2332 93953 : ProcAirVel = DesicDehum(DesicDehumNum).NomProcAirVel;
2333 93953 : PartLoad = 0.0;
2334 :
2335 93953 : RegenAirInTemp = DesicDehum(DesicDehumNum).RegenAirInTemp;
2336 93953 : NomRegenTemp = DesicDehum(DesicDehumNum).NomRegenTemp;
2337 :
2338 : // Calculate min available process out humrat
2339 93953 : UnitOn = false;
2340 93953 : MinProcAirOutHumRat = 0.0; // MAX(MinProcAirOutHumRat,0.000857)
2341 :
2342 93953 : if (HumRatNeeded < ProcAirInHumRat) {
2343 :
2344 57104 : UnitOn = true;
2345 :
2346 57104 : switch (DesicDehum(DesicDehumNum).PerformanceModel_Num) { // Performance Model Part A
2347 57104 : case PerformanceModel::Default: {
2348 57104 : WC0 = 0.0148880824323806;
2349 57104 : WC1 = -0.000283393198398211;
2350 57104 : WC2 = -0.87802168940547;
2351 57104 : WC3 = -0.000713615831236411;
2352 57104 : WC4 = 0.0311261188874622;
2353 57104 : WC5 = 1.51738892142485e-06;
2354 57104 : WC6 = 0.0287250198281021;
2355 57104 : WC7 = 4.94796903231558e-06;
2356 57104 : WC8 = 24.0771139652826;
2357 57104 : WC9 = 0.000122270283927978;
2358 57104 : WC10 = -0.0151657189566474;
2359 57104 : WC11 = 3.91641393230322e-08;
2360 57104 : WC12 = 0.126032651553348;
2361 57104 : WC13 = 0.000391653854431574;
2362 57104 : WC14 = 0.002160537360507;
2363 57104 : WC15 = 0.00132732844211593;
2364 :
2365 171312 : MinProcAirOutHumRat = WC0 + WC1 * ProcAirInTemp + WC2 * ProcAirInHumRat + WC3 * ProcAirVel + WC4 * ProcAirInTemp * ProcAirInHumRat +
2366 171312 : WC5 * ProcAirInTemp * ProcAirVel + WC6 * ProcAirInHumRat * ProcAirVel + WC7 * ProcAirInTemp * ProcAirInTemp +
2367 171312 : WC8 * ProcAirInHumRat * ProcAirInHumRat + WC9 * ProcAirVel * ProcAirVel +
2368 114208 : WC10 * ProcAirInTemp * ProcAirInTemp * ProcAirInHumRat * ProcAirInHumRat +
2369 114208 : WC11 * ProcAirInTemp * ProcAirInTemp * ProcAirVel * ProcAirVel +
2370 171312 : WC12 * ProcAirInHumRat * ProcAirInHumRat * ProcAirVel * ProcAirVel + WC13 * std::log(ProcAirInTemp) +
2371 114208 : WC14 * std::log(ProcAirInHumRat) + WC15 * std::log(ProcAirVel);
2372 :
2373 : // limit to 6 grains/lb (0.000857 kg/kg)
2374 :
2375 57104 : } break;
2376 0 : case PerformanceModel::UserCurves: {
2377 0 : MinProcAirOutHumRat = CurveValue(state, DesicDehum(DesicDehumNum).ProcHumRatCurvefTW, ProcAirInTemp, ProcAirInHumRat) *
2378 0 : CurveValue(state, DesicDehum(DesicDehumNum).ProcHumRatCurvefV, ProcAirVel);
2379 0 : } break;
2380 :
2381 0 : default: {
2382 :
2383 0 : ShowFatalError(state,
2384 0 : format("Invalid performance model in desiccant dehumidifier = {}", DesicDehum(DesicDehumNum).PerformanceModel_Num));
2385 0 : } break;
2386 : } // Performance Model Part A
2387 :
2388 57104 : MinProcAirOutHumRat = max(MinProcAirOutHumRat, 0.000857);
2389 : }
2390 :
2391 93953 : if (MinProcAirOutHumRat >= ProcAirInHumRat) UnitOn = false;
2392 :
2393 93953 : if (UnitOn) {
2394 :
2395 : // Calculate partload fraction of dehumidification capacity required to meet setpoint
2396 57104 : PartLoad = 1.0;
2397 57104 : if (MinProcAirOutHumRat < HumRatNeeded) PartLoad = (ProcAirInHumRat - HumRatNeeded) / (ProcAirInHumRat - MinProcAirOutHumRat);
2398 57104 : PartLoad = max(0.0, PartLoad);
2399 57104 : PartLoad = min(1.0, PartLoad);
2400 :
2401 57104 : switch (DesicDehum(DesicDehumNum).PerformanceModel_Num) { // Performance Model Part B
2402 57104 : case PerformanceModel::Default: {
2403 : // Calculate leaving conditions
2404 57104 : TC0 = -38.7782841989449;
2405 57104 : TC1 = 2.0127655837628;
2406 57104 : TC2 = 5212.49360216097;
2407 57104 : TC3 = 15.2362536782665;
2408 57104 : TC4 = -80.4910419759181;
2409 57104 : TC5 = -0.105014122001509;
2410 57104 : TC6 = -229.668673645144;
2411 57104 : TC7 = -0.015424703743461;
2412 57104 : TC8 = -69440.0689831847;
2413 57104 : TC9 = -1.6686064694322;
2414 57104 : TC10 = 38.5855718977592;
2415 57104 : TC11 = 0.000196395381206009;
2416 57104 : TC12 = 386.179386548324;
2417 57104 : TC13 = -0.801959614172614;
2418 57104 : TC14 = -3.33080986818745;
2419 57104 : TC15 = -15.2034386065714;
2420 :
2421 171312 : ProcAirOutTemp = TC0 + TC1 * ProcAirInTemp + TC2 * ProcAirInHumRat + TC3 * ProcAirVel + TC4 * ProcAirInTemp * ProcAirInHumRat +
2422 171312 : TC5 * ProcAirInTemp * ProcAirVel + TC6 * ProcAirInHumRat * ProcAirVel + TC7 * ProcAirInTemp * ProcAirInTemp +
2423 171312 : TC8 * ProcAirInHumRat * ProcAirInHumRat + TC9 * ProcAirVel * ProcAirVel +
2424 114208 : TC10 * ProcAirInTemp * ProcAirInTemp * ProcAirInHumRat * ProcAirInHumRat +
2425 114208 : TC11 * ProcAirInTemp * ProcAirInTemp * ProcAirVel * ProcAirVel +
2426 171312 : TC12 * ProcAirInHumRat * ProcAirInHumRat * ProcAirVel * ProcAirVel + TC13 * std::log(ProcAirInTemp) +
2427 114208 : TC14 * std::log(ProcAirInHumRat) + TC15 * std::log(ProcAirVel);
2428 :
2429 : // Regen energy
2430 57104 : QC0 = -27794046.6291107;
2431 57104 : QC1 = -235725.171759615;
2432 57104 : QC2 = 975461343.331328;
2433 57104 : QC3 = -686069.373946731;
2434 57104 : QC4 = -17717307.3766266;
2435 57104 : QC5 = 31482.2539662489;
2436 57104 : QC6 = 55296552.8260743;
2437 57104 : QC7 = 6195.36070023868;
2438 57104 : QC8 = -8304781359.40435;
2439 57104 : QC9 = -188987.543809419;
2440 57104 : QC10 = 3933449.40965846;
2441 57104 : QC11 = -6.66122876558634;
2442 57104 : QC12 = -349102295.417547;
2443 57104 : QC13 = 83672.179730172;
2444 57104 : QC14 = -6059524.33170538;
2445 57104 : QC15 = 1220523.39525162;
2446 :
2447 171312 : SpecRegenEnergy = QC0 + QC1 * ProcAirInTemp + QC2 * ProcAirInHumRat + QC3 * ProcAirVel + QC4 * ProcAirInTemp * ProcAirInHumRat +
2448 171312 : QC5 * ProcAirInTemp * ProcAirVel + QC6 * ProcAirInHumRat * ProcAirVel + QC7 * ProcAirInTemp * ProcAirInTemp +
2449 171312 : QC8 * ProcAirInHumRat * ProcAirInHumRat + QC9 * ProcAirVel * ProcAirVel +
2450 114208 : QC10 * ProcAirInTemp * ProcAirInTemp * ProcAirInHumRat * ProcAirInHumRat +
2451 114208 : QC11 * ProcAirInTemp * ProcAirInTemp * ProcAirVel * ProcAirVel +
2452 171312 : QC12 * ProcAirInHumRat * ProcAirInHumRat * ProcAirVel * ProcAirVel + QC13 * std::log(ProcAirInTemp) +
2453 114208 : QC14 * std::log(ProcAirInHumRat) + QC15 * std::log(ProcAirVel);
2454 :
2455 : // Regen face velocity
2456 57104 : RC0 = -4.67358908091488;
2457 57104 : RC1 = 0.0654323095468338;
2458 57104 : RC2 = 396.950518702316;
2459 57104 : RC3 = 1.52610165426736;
2460 57104 : RC4 = -11.3955868430328;
2461 57104 : RC5 = 0.00520693906104437;
2462 57104 : RC6 = 57.783645385621;
2463 57104 : RC7 = -0.000464800668311693;
2464 57104 : RC8 = -5958.78613212602;
2465 57104 : RC9 = -0.205375818291012;
2466 57104 : RC10 = 5.26762675442845;
2467 57104 : RC11 = -8.88452553055039e-05;
2468 57104 : RC12 = -182.382479369311;
2469 57104 : RC13 = -0.100289774002047;
2470 57104 : RC14 = -0.486980507964251;
2471 57104 : RC15 = -0.972715425435447;
2472 :
2473 171312 : RegenAirVel = RC0 + RC1 * ProcAirInTemp + RC2 * ProcAirInHumRat + RC3 * ProcAirVel + RC4 * ProcAirInTemp * ProcAirInHumRat +
2474 171312 : RC5 * ProcAirInTemp * ProcAirVel + RC6 * ProcAirInHumRat * ProcAirVel + RC7 * ProcAirInTemp * ProcAirInTemp +
2475 171312 : RC8 * ProcAirInHumRat * ProcAirInHumRat + RC9 * ProcAirVel * ProcAirVel +
2476 114208 : RC10 * ProcAirInTemp * ProcAirInTemp * ProcAirInHumRat * ProcAirInHumRat +
2477 114208 : RC11 * ProcAirInTemp * ProcAirInTemp * ProcAirVel * ProcAirVel +
2478 171312 : RC12 * ProcAirInHumRat * ProcAirInHumRat * ProcAirVel * ProcAirVel + RC13 * std::log(ProcAirInTemp) +
2479 114208 : RC14 * std::log(ProcAirInHumRat) + RC15 * std::log(ProcAirVel);
2480 :
2481 57104 : } break;
2482 0 : case PerformanceModel::UserCurves: {
2483 :
2484 0 : ProcAirOutTemp = CurveValue(state, DesicDehum(DesicDehumNum).ProcDryBulbCurvefTW, ProcAirInTemp, ProcAirInHumRat) *
2485 0 : CurveValue(state, DesicDehum(DesicDehumNum).ProcDryBulbCurvefV, ProcAirVel);
2486 :
2487 0 : SpecRegenEnergy = CurveValue(state, DesicDehum(DesicDehumNum).RegenEnergyCurvefTW, ProcAirInTemp, ProcAirInHumRat) *
2488 0 : CurveValue(state, DesicDehum(DesicDehumNum).RegenEnergyCurvefV, ProcAirVel);
2489 :
2490 0 : RegenAirVel = CurveValue(state, DesicDehum(DesicDehumNum).RegenVelCurvefTW, ProcAirInTemp, ProcAirInHumRat) *
2491 0 : CurveValue(state, DesicDehum(DesicDehumNum).RegenVelCurvefV, ProcAirVel);
2492 :
2493 0 : } break;
2494 0 : default: {
2495 :
2496 0 : ShowFatalError(state,
2497 0 : format("Invalid performance model in desiccant dehumidifier = {}", DesicDehum(DesicDehumNum).PerformanceModel_Num));
2498 :
2499 : // Suppress uninitialized warnings
2500 0 : ProcAirOutTemp = 0.0;
2501 0 : SpecRegenEnergy = 0.0;
2502 0 : RegenAirVel = 0.0;
2503 0 : } break;
2504 : } // Performance Model Part B
2505 :
2506 57104 : ProcAirOutTemp = (1 - PartLoad) * ProcAirInTemp + (PartLoad)*ProcAirOutTemp;
2507 :
2508 57104 : ProcAirOutHumRat = (1 - PartLoad) * ProcAirInHumRat + (PartLoad)*MinProcAirOutHumRat;
2509 :
2510 : // Calculate water removal
2511 57104 : DesicDehum(DesicDehumNum).WaterRemoveRate = ProcAirMassFlowRate * (ProcAirInHumRat - ProcAirOutHumRat);
2512 :
2513 : // Adjust for regen inlet temperature
2514 57104 : SpecRegenEnergy *= (NomRegenTemp - RegenAirInTemp) / (NomRegenTemp - ProcAirInTemp);
2515 57104 : SpecRegenEnergy = max(SpecRegenEnergy, 0.0);
2516 57104 : QRegen = SpecRegenEnergy * DesicDehum(DesicDehumNum).WaterRemoveRate;
2517 :
2518 : // Above curves are based on a 90deg regen angle and 245deg process air angle
2519 57104 : RegenAirMassFlowRate = ProcAirMassFlowRate * 90.0 / 245.0 * RegenAirVel / ProcAirVel;
2520 :
2521 57104 : ElecUseRate = DesicDehum(DesicDehumNum).NomRotorPower;
2522 :
2523 : } else { // Unit is off
2524 :
2525 36849 : ProcAirOutTemp = ProcAirInTemp;
2526 36849 : ProcAirOutHumRat = ProcAirInHumRat;
2527 36849 : SpecRegenEnergy = 0.0;
2528 36849 : QRegen = 0.0;
2529 36849 : ElecUseRate = 0.0;
2530 36849 : RegenAirVel = 0.0;
2531 36849 : RegenAirMassFlowRate = 0.0;
2532 36849 : DesicDehum(DesicDehumNum).WaterRemoveRate = 0.0;
2533 36849 : PartLoad = 0.0;
2534 :
2535 : } // UnitOn/Off
2536 :
2537 : // Set regen mass flow
2538 93953 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenFanInNode).MassFlowRate = RegenAirMassFlowRate;
2539 93953 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenFanInNode).MassFlowRateMaxAvail = RegenAirMassFlowRate;
2540 : // Call regen fan
2541 93953 : if (DesicDehum(DesicDehumNum).regenFanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
2542 88511 : Fans::SimulateFanComponents(state, DesicDehum(DesicDehumNum).RegenFanName, FirstHVACIteration, DesicDehum(DesicDehumNum).RegenFanIndex);
2543 : } else {
2544 5442 : state.dataHVACFan->fanObjs[DesicDehum(DesicDehumNum).RegenFanIndex]->simulate(state, _, _, _, _);
2545 : }
2546 :
2547 : // Call regen heating coil
2548 93953 : CalcNonDXHeatingCoils(state, DesicDehumNum, FirstHVACIteration, QRegen, QDelivered);
2549 :
2550 : // Verify is requestd flow was delivered (must do after heating coil has executed to pass flow to RegenAirInNode)
2551 93953 : if (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate != RegenAirMassFlowRate) {
2552 : // Initialize standard air density
2553 0 : if (state.dataDesiccantDehumidifiers->CalcSolidDesiccantDehumidifierMyOneTimeFlag) {
2554 0 : RhoAirStdInit = state.dataEnvrn->StdRhoAir;
2555 : }
2556 0 : ShowRecurringSevereErrorAtEnd(state,
2557 : "Improper flow delivered by desiccant regen fan - RESULTS INVALID! Check regen fan capacity and schedule.",
2558 0 : DesicDehum(DesicDehumNum).RegenFanErrorIndex1);
2559 0 : ShowRecurringContinueErrorAtEnd(
2560 0 : state, DesicDehum(DesicDehumNum).DehumType + '=' + DesicDehum(DesicDehumNum).Name, DesicDehum(DesicDehumNum).RegenFanErrorIndex2);
2561 0 : RhoAirStdInit = state.dataEnvrn->StdRhoAir;
2562 0 : ShowRecurringContinueErrorAtEnd(state,
2563 0 : "Flow requested [m3/s] from " + DesicDehum(DesicDehumNum).RegenFanType + '=' +
2564 0 : DesicDehum(DesicDehumNum).RegenFanName,
2565 0 : DesicDehum(DesicDehumNum).RegenFanErrorIndex3,
2566 0 : (RegenAirMassFlowRate / RhoAirStdInit));
2567 0 : ShowRecurringContinueErrorAtEnd(
2568 : state,
2569 : "Flow request varied from delivered by [m3/s]",
2570 0 : DesicDehum(DesicDehumNum).RegenFanErrorIndex4,
2571 0 : ((RegenAirMassFlowRate - state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate) / RhoAirStdInit),
2572 0 : ((RegenAirMassFlowRate - state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate) / RhoAirStdInit));
2573 : }
2574 :
2575 : // Verify is requestd heating was delivered
2576 93953 : if (QDelivered < QRegen) {
2577 0 : ShowRecurringSevereErrorAtEnd(
2578 : state,
2579 : "Inadequate heat delivered by desiccant regen coil - RESULTS INVALID! Check regen coil capacity and schedule.",
2580 0 : DesicDehum(DesicDehumNum).RegenCapErrorIndex1);
2581 0 : ShowRecurringContinueErrorAtEnd(
2582 0 : state, DesicDehum(DesicDehumNum).DehumType + '=' + DesicDehum(DesicDehumNum).Name, DesicDehum(DesicDehumNum).RegenCapErrorIndex2);
2583 0 : ShowRecurringContinueErrorAtEnd(state,
2584 0 : "Load requested [W] from " + DesicDehum(DesicDehumNum).RegenCoilType + '=' +
2585 0 : DesicDehum(DesicDehumNum).RegenCoilName,
2586 0 : DesicDehum(DesicDehumNum).RegenCapErrorIndex3,
2587 : QRegen);
2588 0 : ShowRecurringContinueErrorAtEnd(
2589 0 : state, "Load request exceeded delivered by [W]", DesicDehum(DesicDehumNum).RegenCapErrorIndex4, (QRegen - QDelivered));
2590 : }
2591 :
2592 93953 : DesicDehum(DesicDehumNum).SpecRegenEnergy = SpecRegenEnergy;
2593 93953 : DesicDehum(DesicDehumNum).QRegen = QRegen;
2594 93953 : DesicDehum(DesicDehumNum).ElecUseRate = ElecUseRate;
2595 93953 : DesicDehum(DesicDehumNum).PartLoad = PartLoad;
2596 :
2597 93953 : DesicDehum(DesicDehumNum).ProcAirOutMassFlowRate = ProcAirMassFlowRate;
2598 93953 : DesicDehum(DesicDehumNum).ProcAirOutTemp = ProcAirOutTemp;
2599 93953 : DesicDehum(DesicDehumNum).ProcAirOutHumRat = ProcAirOutHumRat;
2600 93953 : DesicDehum(DesicDehumNum).ProcAirOutEnthalpy = PsyHFnTdbW(ProcAirOutTemp, ProcAirOutHumRat);
2601 93953 : DesicDehum(DesicDehumNum).RegenAirInMassFlowRate = RegenAirMassFlowRate;
2602 93953 : DesicDehum(DesicDehumNum).RegenAirVel = RegenAirVel;
2603 :
2604 : // DesicDehum(DesicDehumNum)%RegenAirOutTemp = -999.
2605 : // DesicDehum(DesicDehumNum)%RegenAirOutHumRat = -999.
2606 : // DesicDehum(DesicDehumNum)%RegenAirOutEnthalpy = -999.
2607 93953 : }
2608 :
2609 181261 : void CalcGenericDesiccantDehumidifier(EnergyPlusData &state,
2610 : int const DesicDehumNum, // number of the current dehumidifier being simulated
2611 : Real64 const HumRatNeeded, // process air leaving humidity ratio set by controller [kg water/kg air]
2612 : bool const FirstHVACIteration // TRUE if 1st HVAC simulation of system timestep
2613 : )
2614 : {
2615 :
2616 : // SUBROUTINE INFORMATION:
2617 : // AUTHOR Mangesh Basarkar, FSEC
2618 : // DATE WRITTEN May 2007
2619 : // MODIFIED na
2620 : // RE-ENGINEERED na
2621 :
2622 : // PURPOSE OF THIS SUBROUTINE:
2623 : // Calculate the electricity consumption, regen heat requirements and the outlet
2624 : // conditions for a desiccant dehumidifier, given the inlet conditions,
2625 : // DX coil part-load ratio, and/or the needed process leaving humidity ratio.
2626 :
2627 : // METHODOLOGY EMPLOYED:
2628 : // Given the entering conditions, the full-load outlet conditions are calculated.
2629 : // Adjust for part-load if required.
2630 : // Calculate the required regen energy and call the regen coil and the regen fan.
2631 :
2632 : // REFERENCES:
2633 : // Kosar, D. 2006. Dehumidification Enhancements, ASHRAE Journal, Vol. 48, No. 2, February 2006.
2634 : // Kosar, D. et al. 2006. Dehumidification Enhancement of Direct Expansion Systems Through Component
2635 : // Augmentation of the Cooling Coil. 15th Symposium on Improving Building Systems in Hot and Humid
2636 : // Climates, July 24-26, 2006.
2637 :
2638 : // Using/Aliasing
2639 : using HeatRecovery::SimHeatRecovery;
2640 : using Psychrometrics::PsyHFnTdbW;
2641 : using Psychrometrics::PsyRhoAirFnPbTdbW;
2642 :
2643 : // Locals
2644 : // SUBROUTINE ARGUMENT DEFINITIONS:
2645 :
2646 : // SUBROUTINE PARAMETER DEFINITIONS:
2647 181261 : Real64 constexpr MinVolFlowPerRatedTotQ(0.00002684); // m3/s per W = 200 cfm/ton,
2648 : // min vol flow per rated evaporator capacity
2649 :
2650 : // INTERFACE BLOCK SPECIFICATIONS
2651 : // na
2652 :
2653 : // DERIVED TYPE DEFINITIONS
2654 : // na
2655 :
2656 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2657 : Real64 DDPartLoadRatio; // fraction of dehumidification capacity required to meet setpoint
2658 : Real64 MassFlowRateNew; // new required mass flow rate calculated to keep regen setpoint temperature (kg/s)
2659 : Real64 CondenserWasteHeat; // Condenser waste heat (W)
2660 : Real64 CpAir; // Specific heat of air (J/kg-K)
2661 : Real64 NewRegenInTemp; // new temp calculated from condenser waste heat (C)
2662 : Real64 ExhaustFanMassFlowRate; // exhaust fan mass flow rate (kg/s)
2663 : Real64 ExhaustFanPLR; // exhaust fan run time fraction calculated from new mass flow rate for regen side
2664 : Real64 ExhaustFanPowerMod; // used to calculate exhaust fan power from flow fraction
2665 : Real64 VolFlowPerRatedTotQ; // flow rate per rated total cooling capacity of the companion coil (m3/s/W)
2666 : Real64 FanDeltaT; // used to account for fan heat when calculating regeneration heater energy (C)
2667 : Real64 OnOffFanPLF; // save air loop fan part load fracton while calculating exhaust fan power
2668 : Real64 RegenSetPointTemp; // regeneration temperature setpoint (C)
2669 : int RegenCoilIndex; // index to regeneration heating coil, 0 when not used
2670 : int CompanionCoilIndexNum; // index for companion DX cooling coil, 0 when DX coil is not used
2671 362522 : std::string MinVol; // character string used for error messages
2672 : bool UnitOn; // unit on flag
2673 : // LOGICAL :: SimFlag ! used to turn off additional simulation if DX Coil is off
2674 : Real64 QRegen_OASysFanAdjust; // temporary variable used to adjust regen heater load during iteration
2675 :
2676 181261 : auto &DesicDehum(state.dataDesiccantDehumidifiers->DesicDehum);
2677 181261 : auto &QRegen(state.dataDesiccantDehumidifiers->QRegen);
2678 :
2679 181261 : UnitOn = false;
2680 181261 : DDPartLoadRatio = 0.0;
2681 181261 : RegenCoilIndex = DesicDehum(DesicDehumNum).RegenCoilIndex;
2682 181261 : FanDeltaT = 0.0;
2683 181261 : RegenSetPointTemp = DesicDehum(DesicDehumNum).RegenSetPointTemp;
2684 181261 : ExhaustFanMassFlowRate = 0.0;
2685 :
2686 : // Save OnOffFanPartLoadFraction while performing exhaust fan calculations
2687 181261 : OnOffFanPLF = state.dataHVACGlobal->OnOffFanPartLoadFraction;
2688 181261 : state.dataHVACGlobal->OnOffFanPartLoadFraction = 1.0;
2689 :
2690 181261 : if (DesicDehum(DesicDehumNum).CoilUpstreamOfProcessSide == Selection::Yes) {
2691 : // Cooling coil directly upstream of desiccant dehumidifier, dehumidifier runs in tandem with DX coil
2692 :
2693 17404 : CompanionCoilIndexNum = DesicDehum(DesicDehumNum).DXCoilIndex;
2694 : } else {
2695 : // desiccant dehumidifier determines its own PLR
2696 163857 : CompanionCoilIndexNum = 0;
2697 : }
2698 :
2699 181261 : if (state.dataDesiccantDehumidifiers->CalcGenericDesiccantDehumidifierMyOneTimeFlag) {
2700 2 : state.dataDesiccantDehumidifiers->RhoAirStdInitCGDD = state.dataEnvrn->StdRhoAir;
2701 2 : state.dataDesiccantDehumidifiers->CalcGenericDesiccantDehumidifierMyOneTimeFlag = false;
2702 : }
2703 :
2704 181261 : if (HumRatNeeded < state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).HumRat) {
2705 4972 : UnitOn = true;
2706 : }
2707 :
2708 181261 : if (DesicDehum(DesicDehumNum).CoilUpstreamOfProcessSide == Selection::Yes) {
2709 24124 : if ((DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingSingleSpeed) ||
2710 6720 : (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingTwoStageWHumControl)) {
2711 10684 : if (state.dataDXCoils->DXCoilPartLoadRatio(DesicDehum(DesicDehumNum).DXCoilIndex) == 0.0) {
2712 3339 : UnitOn = false;
2713 : }
2714 : }
2715 : }
2716 :
2717 181261 : if (UnitOn) {
2718 :
2719 3731 : if (DesicDehum(DesicDehumNum).RegenInletIsOutsideAirNode) {
2720 2219 : if (DesicDehum(DesicDehumNum).HXTypeNum == BalancedHX) {
2721 2219 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate =
2722 2219 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).MassFlowRate;
2723 2219 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRateMaxAvail =
2724 2219 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).MassFlowRate;
2725 : }
2726 : }
2727 :
2728 : // Get conditions from DX Coil condenser if present (DXCoilIndex verified > 0 in GetInput)
2729 3731 : if (DesicDehum(DesicDehumNum).Preheat == Selection::Yes) {
2730 :
2731 : // condenser waste heat is proportional to DX coil PLR
2732 2742 : if ((DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingSingleSpeed) ||
2733 523 : (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingTwoStageWHumControl)) {
2734 1696 : CondenserWasteHeat = state.dataHeatBal->HeatReclaimDXCoil(DesicDehum(DesicDehumNum).DXCoilIndex).AvailCapacity;
2735 1696 : state.dataHeatBal->HeatReclaimDXCoil(DesicDehum(DesicDehumNum).DXCoilIndex).AvailCapacity = 0.0;
2736 523 : } else if (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::Coil_CoolingAirToAirVariableSpeed) {
2737 523 : CondenserWasteHeat = state.dataHeatBal->HeatReclaimVS_DXCoil(DesicDehum(DesicDehumNum).DXCoilIndex).AvailCapacity;
2738 523 : state.dataHeatBal->HeatReclaimVS_DXCoil(DesicDehum(DesicDehumNum).DXCoilIndex).AvailCapacity = 0.0;
2739 : }
2740 :
2741 2219 : CpAir = PsyCpAirFnW(state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).CondenserInletNode).HumRat);
2742 :
2743 2219 : if (DesicDehum(DesicDehumNum).RegenFanPlacement == BlowThru) {
2744 0 : if (DesicDehum(DesicDehumNum).regenFanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
2745 0 : Fans::SimulateFanComponents(
2746 0 : state, DesicDehum(DesicDehumNum).RegenFanName, FirstHVACIteration, DesicDehum(DesicDehumNum).RegenFanIndex);
2747 : } else {
2748 0 : state.dataHVACFan->fanObjs[DesicDehum(DesicDehumNum).RegenFanIndex]->simulate(state, _, _, _, _);
2749 : }
2750 0 : FanDeltaT = state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenFanOutNode).Temp -
2751 0 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenFanInNode).Temp;
2752 : // Adjust setpoint to account for fan heat
2753 0 : RegenSetPointTemp -= FanDeltaT;
2754 : }
2755 :
2756 : // CompanionCoilIndexNum .GT. 0 means the same thing as DesicDehum(DesicDehumNum)%CoilUpstreamOfProcessSide == Yes
2757 2219 : if (CompanionCoilIndexNum > 0) {
2758 2742 : if ((DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingSingleSpeed) ||
2759 523 : (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingTwoStageWHumControl)) {
2760 1696 : DDPartLoadRatio = state.dataDXCoils->DXCoilPartLoadRatio(DesicDehum(DesicDehumNum).DXCoilIndex);
2761 523 : } else if (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::Coil_CoolingAirToAirVariableSpeed) {
2762 523 : DDPartLoadRatio = 1.0; // condenser waste heat already includes modulation down
2763 : }
2764 : }
2765 :
2766 : // calculate actual condenser outlet node (regen inlet node) temperature
2767 2219 : if (CompanionCoilIndexNum > 0) {
2768 2742 : if ((DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingSingleSpeed) ||
2769 523 : (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingTwoStageWHumControl)) {
2770 1696 : if (state.dataDXCoils->DXCoilFanOpMode(DesicDehum(DesicDehumNum).DXCoilIndex) == ContFanCycCoil) {
2771 1696 : NewRegenInTemp =
2772 1696 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).CondenserInletNode).Temp +
2773 1696 : CondenserWasteHeat /
2774 1696 : (CpAir * (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate) * DDPartLoadRatio);
2775 1696 : CondenserWasteHeat /= DDPartLoadRatio;
2776 : } else {
2777 0 : NewRegenInTemp =
2778 0 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).CondenserInletNode).Temp +
2779 0 : CondenserWasteHeat / (CpAir * (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate));
2780 : }
2781 523 : } else if (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::Coil_CoolingAirToAirVariableSpeed) {
2782 523 : NewRegenInTemp =
2783 523 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).CondenserInletNode).Temp +
2784 523 : CondenserWasteHeat / (CpAir * (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate));
2785 : } else {
2786 0 : NewRegenInTemp =
2787 0 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).CondenserInletNode).Temp +
2788 0 : CondenserWasteHeat / (CpAir * (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate));
2789 : }
2790 : } else {
2791 0 : NewRegenInTemp =
2792 0 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).CondenserInletNode).Temp +
2793 0 : CondenserWasteHeat / (CpAir * (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate));
2794 : }
2795 :
2796 2219 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).Temp = NewRegenInTemp;
2797 2219 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).Enthalpy =
2798 2219 : PsyHFnTdbW(state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).Temp,
2799 2219 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).HumRat);
2800 2219 : MassFlowRateNew = 0.0;
2801 :
2802 2219 : if (DesicDehum(DesicDehumNum).ExhaustFanMaxVolFlowRate > 0) {
2803 :
2804 : // calculate mass flow rate required to maintain regen inlet setpoint temp
2805 2219 : if (NewRegenInTemp > RegenSetPointTemp) {
2806 1696 : if (RegenSetPointTemp - state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).CondenserInletNode).Temp != 0.0) {
2807 1696 : MassFlowRateNew =
2808 1696 : max(0.0,
2809 : CondenserWasteHeat /
2810 1696 : (CpAir * (RegenSetPointTemp - state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).CondenserInletNode).Temp)));
2811 : } else {
2812 0 : MassFlowRateNew = state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate;
2813 : }
2814 : }
2815 :
2816 : // calculate exhaust fan mass flow rate and new regen inlet temperature (may not be at setpoint)
2817 2219 : if (MassFlowRateNew > state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate) {
2818 1696 : ExhaustFanMassFlowRate = MassFlowRateNew - state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate;
2819 1696 : ExhaustFanMassFlowRate = max(0.0, min(ExhaustFanMassFlowRate, DesicDehum(DesicDehumNum).ExhaustFanMaxMassFlowRate));
2820 :
2821 1696 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).Temp =
2822 3392 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).CondenserInletNode).Temp +
2823 1696 : CondenserWasteHeat /
2824 1696 : (CpAir * (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate + ExhaustFanMassFlowRate));
2825 1696 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).HumRat =
2826 1696 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).CondenserInletNode).HumRat;
2827 1696 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).Enthalpy =
2828 1696 : PsyHFnTdbW(state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).Temp,
2829 1696 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).HumRat);
2830 : }
2831 : }
2832 :
2833 2219 : if (RegenCoilIndex > 0) {
2834 2219 : if (NewRegenInTemp < RegenSetPointTemp) {
2835 523 : CpAir = PsyCpAirFnW(state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).HumRat);
2836 : }
2837 2219 : QRegen = max(0.0,
2838 2219 : (CpAir * state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate *
2839 2219 : (RegenSetPointTemp - state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).Temp)));
2840 2219 : if (QRegen == 0.0) QRegen = -1.0;
2841 : }
2842 :
2843 : // CompanionCoilIndexNum .EQ. 0 means the same thing as DesicDehum(DesicDehumNum)%CoilUpstreamOfProcessSide == No
2844 2219 : if (CompanionCoilIndexNum == 0) {
2845 :
2846 0 : if (RegenCoilIndex > 0) {
2847 :
2848 0 : QRegen_OASysFanAdjust = QRegen;
2849 0 : if (DesicDehum(DesicDehumNum).RegenFanPlacement == BlowThru) {
2850 0 : if (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate > 0.0) {
2851 : // For VAV systems, fan may restrict air flow during iteration. Adjust QRegen proportional to Mdot
2852 : // reduction through fan
2853 0 : QRegen_OASysFanAdjust *= state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenFanOutNode).MassFlowRate /
2854 0 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenFanInNode).MassFlowRate;
2855 : }
2856 : }
2857 :
2858 0 : CalcNonDXHeatingCoils(state, DesicDehumNum, FirstHVACIteration, QRegen_OASysFanAdjust);
2859 : }
2860 :
2861 0 : SimHeatRecovery(state,
2862 0 : DesicDehum(DesicDehumNum).HXName,
2863 : FirstHVACIteration,
2864 0 : DesicDehum(DesicDehumNum).CompIndex,
2865 : ContFanCycCoil,
2866 : 1.0,
2867 : true,
2868 : CompanionCoilIndexNum,
2869 0 : DesicDehum(DesicDehumNum).RegenInletIsOutsideAirNode,
2870 : _,
2871 : _,
2872 0 : DesicDehum(DesicDehumNum).coolingCoil_TypeNum);
2873 :
2874 : // calculate desiccant part-load ratio
2875 0 : if (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).HumRat !=
2876 0 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirOutNode).HumRat) {
2877 0 : DDPartLoadRatio = (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).HumRat - HumRatNeeded) /
2878 0 : (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).HumRat -
2879 0 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirOutNode).HumRat);
2880 0 : DDPartLoadRatio = max(0.0, min(1.0, DDPartLoadRatio));
2881 : } else {
2882 0 : DDPartLoadRatio = 1.0;
2883 : }
2884 : }
2885 :
2886 2219 : if (ExhaustFanMassFlowRate > 0.0) {
2887 :
2888 : // calculate exhaust fan mass flow rate due to desiccant system operation
2889 1696 : ExhaustFanMassFlowRate *= DDPartLoadRatio;
2890 :
2891 : // calculate exhaust fan PLR due to desiccant system operation
2892 1696 : ExhaustFanPLR = ExhaustFanMassFlowRate / DesicDehum(DesicDehumNum).ExhaustFanMaxMassFlowRate;
2893 :
2894 : // find exhaust fan power multiplier using exhaust fan part-load ratio
2895 1696 : if (DesicDehum(DesicDehumNum).ExhaustFanCurveIndex > 0) {
2896 1696 : ExhaustFanPowerMod = min(1.0, max(0.0, CurveValue(state, DesicDehum(DesicDehumNum).ExhaustFanCurveIndex, ExhaustFanPLR)));
2897 : } else {
2898 0 : ExhaustFanPowerMod = 1.0;
2899 : }
2900 :
2901 : // calculate exhaust fan power due to desiccant operation
2902 1696 : DesicDehum(DesicDehumNum).ExhaustFanPower = DesicDehum(DesicDehumNum).ExhaustFanMaxPower * ExhaustFanPowerMod;
2903 : }
2904 :
2905 : } else { // ELSE for IF(DesicDehum(DesicDehumNum)%Preheat == Yes)THEN
2906 :
2907 1512 : if (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).HumRat > HumRatNeeded) {
2908 :
2909 : // Get Full load output of desiccant wheel
2910 1512 : if (DesicDehum(DesicDehumNum).RegenFanPlacement == BlowThru) {
2911 0 : if (DesicDehum(DesicDehumNum).regenFanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
2912 0 : Fans::SimulateFanComponents(
2913 0 : state, DesicDehum(DesicDehumNum).RegenFanName, FirstHVACIteration, DesicDehum(DesicDehumNum).RegenFanIndex);
2914 : } else {
2915 0 : state.dataHVACFan->fanObjs[DesicDehum(DesicDehumNum).RegenFanIndex]->simulate(state, _, _, _, _);
2916 : }
2917 :
2918 0 : FanDeltaT = state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenFanOutNode).Temp -
2919 0 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenFanInNode).Temp;
2920 0 : RegenSetPointTemp -= FanDeltaT;
2921 : }
2922 :
2923 1512 : if (RegenCoilIndex > 0) {
2924 1512 : CpAir = PsyCpAirFnW(state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).HumRat);
2925 1512 : QRegen = max(0.0,
2926 1512 : (CpAir * state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate *
2927 1512 : (RegenSetPointTemp - state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).Temp)));
2928 :
2929 1512 : QRegen_OASysFanAdjust = QRegen;
2930 1512 : if (DesicDehum(DesicDehumNum).RegenFanPlacement == BlowThru) {
2931 0 : if (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate > 0.0) {
2932 : // For VAV systems, fan may restrict air flow during iteration. Adjust QRegen proportional to Mdot
2933 : // reduction through fan
2934 0 : QRegen_OASysFanAdjust *= state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenFanOutNode).MassFlowRate /
2935 0 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenFanInNode).MassFlowRate;
2936 : }
2937 : }
2938 :
2939 1512 : if (QRegen_OASysFanAdjust == 0.0) QRegen_OASysFanAdjust = -1.0;
2940 1512 : CalcNonDXHeatingCoils(state, DesicDehumNum, FirstHVACIteration, QRegen_OASysFanAdjust);
2941 : }
2942 :
2943 : // CompanionCoilIndexNum .EQ. 0 means the same thing as DesicDehum(DesicDehumNum)%CoilUpstreamOfProcessSide == No
2944 1512 : if (CompanionCoilIndexNum == 0) {
2945 6048 : SimHeatRecovery(state,
2946 1512 : DesicDehum(DesicDehumNum).HXName,
2947 : FirstHVACIteration,
2948 1512 : DesicDehum(DesicDehumNum).CompIndex,
2949 : ContFanCycCoil,
2950 : 1.0,
2951 : true,
2952 : CompanionCoilIndexNum,
2953 1512 : DesicDehum(DesicDehumNum).RegenInletIsOutsideAirNode,
2954 : _,
2955 : _,
2956 1512 : DesicDehum(DesicDehumNum).coolingCoil_TypeNum);
2957 :
2958 : // calculate desiccant part-load ratio
2959 3024 : if (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).HumRat !=
2960 1512 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirOutNode).HumRat) {
2961 3024 : DDPartLoadRatio = (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).HumRat - HumRatNeeded) /
2962 3024 : (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).HumRat -
2963 1512 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirOutNode).HumRat);
2964 1512 : DDPartLoadRatio = max(0.0, min(1.0, DDPartLoadRatio));
2965 : } else {
2966 0 : DDPartLoadRatio = 1.0;
2967 : }
2968 : } else {
2969 0 : if ((DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingSingleSpeed) ||
2970 0 : (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingTwoStageWHumControl)) {
2971 0 : DDPartLoadRatio = state.dataDXCoils->DXCoilPartLoadRatio(DesicDehum(DesicDehumNum).DXCoilIndex);
2972 0 : } else if (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::Coil_CoolingAirToAirVariableSpeed) {
2973 0 : DDPartLoadRatio = 1.0; // condenser waste heat already includes modulation down
2974 : }
2975 : }
2976 : } else { // ELSE for IF(state.dataLoopNodes->Node(DesicDehum(DesicDehumNum)%ProcAirInNode)%HumRat .GT. HumRatNeeded)THEN
2977 0 : DDPartLoadRatio = 0.0;
2978 : } // END IF for IF(state.dataLoopNodes->Node(DesicDehum(DesicDehumNum)%ProcAirInNode)%HumRat .GT. HumRatNeeded)THEN
2979 :
2980 : } // END IF for IF(DesicDehum(DesicDehumNum)%Preheat == Yes)THEN
2981 :
2982 3731 : DesicDehum(DesicDehumNum).PartLoad = DDPartLoadRatio;
2983 3731 : QRegen_OASysFanAdjust = QRegen;
2984 :
2985 : // set average regeneration air mass flow rate based on desiccant cycling ratio (DDPartLoadRatio)
2986 3731 : if (DesicDehum(DesicDehumNum).RegenInletIsOutsideAirNode) {
2987 2219 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate *= DDPartLoadRatio;
2988 :
2989 : // **RR moved to here, only adjust regen heater load if mass flow rate is changed
2990 : // adjust regen heating coil capacity based on desiccant cycling ratio (PLR)
2991 2219 : QRegen_OASysFanAdjust *= DDPartLoadRatio;
2992 : }
2993 :
2994 : // Call regen fan, balanced desiccant HX and heating coil
2995 3731 : if (DesicDehum(DesicDehumNum).RegenFanPlacement == BlowThru) {
2996 0 : if (DesicDehum(DesicDehumNum).regenFanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
2997 0 : Fans::SimulateFanComponents(
2998 0 : state, DesicDehum(DesicDehumNum).RegenFanName, FirstHVACIteration, DesicDehum(DesicDehumNum).RegenFanIndex);
2999 : } else {
3000 0 : state.dataHVACFan->fanObjs[DesicDehum(DesicDehumNum).RegenFanIndex]->simulate(state, _, _, _, _);
3001 : }
3002 : }
3003 :
3004 3731 : if (RegenCoilIndex > 0) {
3005 :
3006 : //! adjust regen heating coil capacity based on desiccant cycling ratio (PLR)
3007 : // QRegen_OASysFanAdjust = QRegen * DDPartLoadRatio
3008 :
3009 3731 : if (DesicDehum(DesicDehumNum).RegenFanPlacement == BlowThru) {
3010 0 : if (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate > 0.0) {
3011 : // For VAV systems, fan may restrict air flow during iteration. Adjust QRegen proportional to Mdot reduction through fan
3012 0 : QRegen_OASysFanAdjust *= state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenFanOutNode).MassFlowRate /
3013 0 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenFanInNode).MassFlowRate;
3014 : }
3015 : }
3016 :
3017 3731 : if (QRegen_OASysFanAdjust == 0.0) QRegen_OASysFanAdjust = -1.0;
3018 3731 : CalcNonDXHeatingCoils(state, DesicDehumNum, FirstHVACIteration, QRegen_OASysFanAdjust);
3019 : }
3020 :
3021 14924 : SimHeatRecovery(state,
3022 3731 : DesicDehum(DesicDehumNum).HXName,
3023 : FirstHVACIteration,
3024 3731 : DesicDehum(DesicDehumNum).CompIndex,
3025 : ContFanCycCoil,
3026 : DDPartLoadRatio,
3027 : true,
3028 : CompanionCoilIndexNum,
3029 3731 : DesicDehum(DesicDehumNum).RegenInletIsOutsideAirNode,
3030 : _,
3031 : _,
3032 3731 : DesicDehum(DesicDehumNum).coolingCoil_TypeNum);
3033 :
3034 3731 : if (DesicDehum(DesicDehumNum).RegenFanPlacement == DrawThru) {
3035 3731 : if (DesicDehum(DesicDehumNum).regenFanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
3036 5349 : Fans::SimulateFanComponents(
3037 3566 : state, DesicDehum(DesicDehumNum).RegenFanName, FirstHVACIteration, DesicDehum(DesicDehumNum).RegenFanIndex);
3038 : } else {
3039 1948 : state.dataHVACFan->fanObjs[DesicDehum(DesicDehumNum).RegenFanIndex]->simulate(state, _, _, _, _);
3040 : }
3041 : }
3042 :
3043 : // Calculate water removal
3044 7462 : DesicDehum(DesicDehumNum).WaterRemoveRate = state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).MassFlowRate *
3045 7462 : (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirInNode).HumRat -
3046 3731 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).ProcAirOutNode).HumRat);
3047 :
3048 : // If preheat is Yes, exhaust fan is condenser fan, if CoilUpstreamOfProcessSide is No, DD runs an its own PLR
3049 3731 : if (DesicDehum(DesicDehumNum).Preheat == Selection::Yes && DesicDehum(DesicDehumNum).CoilUpstreamOfProcessSide == Selection::No) {
3050 : // should actually use DX coil RTF instead of PLR since fan power is being calculated
3051 0 : if ((DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingSingleSpeed) ||
3052 0 : (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingTwoStageWHumControl)) {
3053 0 : DesicDehum(DesicDehumNum).ExhaustFanPower +=
3054 0 : max(0.0,
3055 0 : (DesicDehum(DesicDehumNum).ExhaustFanMaxPower *
3056 0 : (state.dataDXCoils->DXCoilPartLoadRatio(DesicDehum(DesicDehumNum).DXCoilIndex) - DDPartLoadRatio)));
3057 0 : } else if (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::Coil_CoolingAirToAirVariableSpeed) {
3058 0 : DesicDehum(DesicDehumNum).ExhaustFanPower += max(0.0, (DesicDehum(DesicDehumNum).ExhaustFanMaxPower * (1.0 - DDPartLoadRatio)));
3059 : }
3060 : }
3061 :
3062 : } else { // unit must be off
3063 :
3064 177530 : DesicDehum(DesicDehumNum).PartLoad = 0.0;
3065 :
3066 177530 : if (DesicDehum(DesicDehumNum).RegenInletIsOutsideAirNode) {
3067 15185 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate = 0.0;
3068 15185 : state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRateMaxAvail = 0.0;
3069 : }
3070 :
3071 177530 : if (DesicDehum(DesicDehumNum).RegenFanPlacement == BlowThru) {
3072 0 : if (DesicDehum(DesicDehumNum).regenFanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
3073 0 : Fans::SimulateFanComponents(
3074 0 : state, DesicDehum(DesicDehumNum).RegenFanName, FirstHVACIteration, DesicDehum(DesicDehumNum).RegenFanIndex);
3075 : } else {
3076 0 : state.dataHVACFan->fanObjs[DesicDehum(DesicDehumNum).RegenFanIndex]->simulate(state, _, _, _, _);
3077 : }
3078 : }
3079 :
3080 177530 : if (RegenCoilIndex > 0) {
3081 177530 : CalcNonDXHeatingCoils(state, DesicDehumNum, FirstHVACIteration, -1.0);
3082 : }
3083 :
3084 710120 : SimHeatRecovery(state,
3085 177530 : DesicDehum(DesicDehumNum).HXName,
3086 : FirstHVACIteration,
3087 177530 : DesicDehum(DesicDehumNum).CompIndex,
3088 : ContFanCycCoil,
3089 : 0.0,
3090 : false,
3091 : CompanionCoilIndexNum,
3092 177530 : DesicDehum(DesicDehumNum).RegenInletIsOutsideAirNode,
3093 : _,
3094 : _,
3095 177530 : DesicDehum(DesicDehumNum).coolingCoil_TypeNum);
3096 :
3097 177530 : if (DesicDehum(DesicDehumNum).RegenFanPlacement == DrawThru) {
3098 177530 : if (DesicDehum(DesicDehumNum).regenFanType_Num != DataHVACGlobals::FanType_SystemModelObject) {
3099 318741 : Fans::SimulateFanComponents(
3100 212494 : state, DesicDehum(DesicDehumNum).RegenFanName, FirstHVACIteration, DesicDehum(DesicDehumNum).RegenFanIndex);
3101 : } else {
3102 71283 : state.dataHVACFan->fanObjs[DesicDehum(DesicDehumNum).RegenFanIndex]->simulate(state, _, _, _, _);
3103 : }
3104 : }
3105 :
3106 : // Turn on exhaust fan if DX Coil is operating
3107 177530 : if (DesicDehum(DesicDehumNum).ExhaustFanMaxVolFlowRate > 0) {
3108 15185 : if (DesicDehum(DesicDehumNum).DXCoilIndex > 0) {
3109 21382 : if ((DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingSingleSpeed) ||
3110 6197 : (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::CoilDX_CoolingTwoStageWHumControl)) {
3111 8988 : DDPartLoadRatio = state.dataDXCoils->DXCoilPartLoadRatio(DesicDehum(DesicDehumNum).DXCoilIndex);
3112 6197 : } else if (DesicDehum(DesicDehumNum).coolingCoil_TypeNum == DataHVACGlobals::Coil_CoolingAirToAirVariableSpeed) {
3113 6197 : DDPartLoadRatio = 1.0; // condenser waste heat already includes modulation down
3114 : }
3115 15185 : DesicDehum(DesicDehumNum).ExhaustFanPower = DesicDehum(DesicDehumNum).ExhaustFanMaxPower * DDPartLoadRatio;
3116 15185 : ExhaustFanMassFlowRate = DesicDehum(DesicDehumNum).ExhaustFanMaxMassFlowRate * DDPartLoadRatio;
3117 : }
3118 : }
3119 :
3120 : } // UnitOn/Off
3121 :
3122 : // check condenser minimum flow per rated total capacity
3123 181261 : if (DDPartLoadRatio > 0.0 && DesicDehum(DesicDehumNum).ExhaustFanMaxVolFlowRate > 0.0) {
3124 14065 : VolFlowPerRatedTotQ =
3125 28130 : (state.dataLoopNodes->Node(DesicDehum(DesicDehumNum).RegenAirInNode).MassFlowRate + ExhaustFanMassFlowRate) /
3126 14065 : max(0.00001,
3127 14065 : (DesicDehum(DesicDehumNum).CompanionCoilCapacity * DDPartLoadRatio * state.dataDesiccantDehumidifiers->RhoAirStdInitCGDD));
3128 14065 : if (!state.dataGlobal->WarmupFlag && (VolFlowPerRatedTotQ < MinVolFlowPerRatedTotQ)) {
3129 0 : ++DesicDehum(DesicDehumNum).ErrCount;
3130 0 : if (DesicDehum(DesicDehumNum).ErrCount < 2) {
3131 0 : ShowWarningError(state,
3132 0 : format("{} \"{}\" - Air volume flow rate per watt of total condenser waste heat is below the minimum "
3133 : "recommended at {:N} m3/s/W.",
3134 0 : DesicDehum(DesicDehumNum).DehumType,
3135 0 : DesicDehum(DesicDehumNum).Name,
3136 0 : VolFlowPerRatedTotQ));
3137 0 : ShowContinueErrorTimeStamp(state, "");
3138 0 : ShowContinueError(state,
3139 0 : format("Expected minimum for VolumeFlowperRatedTotalCondenserWasteHeat = [{:N}]", MinVolFlowPerRatedTotQ));
3140 0 : ShowContinueError(state, "Possible causes include inconsistent air flow rates in system components ");
3141 0 : ShowContinueError(state, "on the regeneration side of the desiccant dehumidifier.");
3142 : } else {
3143 0 : ShowRecurringWarningErrorAtEnd(
3144 : state,
3145 0 : DesicDehum(DesicDehumNum).DehumType + " \"" + DesicDehum(DesicDehumNum).Name +
3146 : "\" - Air volume flow rate per watt of rated total cooling capacity is out of range error continues...",
3147 0 : DesicDehum(DesicDehumNum).ErrIndex1,
3148 : VolFlowPerRatedTotQ,
3149 : VolFlowPerRatedTotQ);
3150 : }
3151 : } // flow per rated total capacity check ends
3152 : }
3153 :
3154 : // Reset OnOffFanPartLoadFraction for process side fan calculations
3155 181261 : state.dataHVACGlobal->OnOffFanPartLoadFraction = OnOffFanPLF;
3156 181261 : }
3157 :
3158 275214 : void UpdateDesiccantDehumidifier(EnergyPlusData &state, int const DesicDehumNum) // number of the current dehumidifier being simulated
3159 : {
3160 :
3161 : // SUBROUTINE INFORMATION:
3162 : // AUTHOR Michael J. Witte, GARD Analytics, Inc.
3163 : // for Gas Research Institute
3164 : // DATE WRITTEN March 2001
3165 : // MODIFIED na
3166 : // RE-ENGINEERED na
3167 :
3168 : // PURPOSE OF THIS SUBROUTINE:
3169 : // Moves dehumidifier output to the outlet nodes.
3170 :
3171 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3172 : int ProcInNode; // process air inlet node number
3173 : int ProcOutNode; // process air outlet node number
3174 :
3175 275214 : switch (state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).DehumTypeCode) {
3176 93953 : case DesicDehumType::Solid: {
3177 93953 : ProcInNode = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ProcAirInNode;
3178 93953 : ProcOutNode = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ProcAirOutNode;
3179 : // Set the process outlet air node of the dehumidifier
3180 93953 : state.dataLoopNodes->Node(ProcOutNode).Temp = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ProcAirOutTemp;
3181 93953 : state.dataLoopNodes->Node(ProcOutNode).HumRat = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ProcAirOutHumRat;
3182 93953 : state.dataLoopNodes->Node(ProcOutNode).Enthalpy = state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ProcAirOutEnthalpy;
3183 :
3184 : // Set the process outlet nodes for properties that just pass through & not used
3185 93953 : state.dataLoopNodes->Node(ProcOutNode).Quality = state.dataLoopNodes->Node(ProcInNode).Quality;
3186 93953 : state.dataLoopNodes->Node(ProcOutNode).Press = state.dataLoopNodes->Node(ProcInNode).Press;
3187 93953 : state.dataLoopNodes->Node(ProcOutNode).MassFlowRate = state.dataLoopNodes->Node(ProcInNode).MassFlowRate;
3188 93953 : state.dataLoopNodes->Node(ProcOutNode).MassFlowRateMin = state.dataLoopNodes->Node(ProcInNode).MassFlowRateMin;
3189 93953 : state.dataLoopNodes->Node(ProcOutNode).MassFlowRateMax = state.dataLoopNodes->Node(ProcInNode).MassFlowRateMax;
3190 93953 : state.dataLoopNodes->Node(ProcOutNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(ProcInNode).MassFlowRateMinAvail;
3191 93953 : state.dataLoopNodes->Node(ProcOutNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(ProcInNode).MassFlowRateMaxAvail;
3192 :
3193 : // RegenInNode =DesicDehum(DesicDehumNum)%RegenAirInNode
3194 : // RegenOutNode = DesicDehum(DesicDehumNum)%RegenAirOutNode
3195 : // Set the regen outlet air node of the dehumidifier
3196 : // Node(RegenOutNode)%Temp = DesicDehum(DesicDehumNum)%RegenAirOutTemp
3197 : // Node(RegenOutNode)%HumRat = DesicDehum(DesicDehumNum)%RegenAirOutHumRat
3198 : // Node(RegenOutNode)%Enthalpy = DesicDehum(DesicDehumNum)%RegenAirOutEnthalpy
3199 :
3200 : // Set the regen outlet nodes for properties that just pass through & not used
3201 : // Node(RegenOutNode)%Quality = Node(RegenInNode)%Quality
3202 : // Node(RegenOutNode)%Press = Node(RegenInNode)%Press
3203 : // Node(RegenOutNode)%MassFlowRate = Node(RegenInNode)%MassFlowRate
3204 : // Node(RegenOutNode)%MassFlowRateMin = Node(RegenInNode)%MassFlowRateMin
3205 : // Node(RegenOutNode)%MassFlowRateMax = Node(RegenInNode)%MassFlowRateMax
3206 : // Node(RegenOutNode)%MassFlowRateMinAvail= Node(RegenInNode)%MassFlowRateMinAvail
3207 : // Node(RegenOutNode)%MassFlowRateMaxAvail= Node(RegenInNode)%MassFlowRateMaxAvail
3208 :
3209 93953 : } break;
3210 181261 : case DesicDehumType::Generic: {
3211 181261 : return;
3212 : } break;
3213 0 : default:
3214 0 : break;
3215 : }
3216 : }
3217 :
3218 275214 : void ReportDesiccantDehumidifier(EnergyPlusData &state, int const DesicDehumNum) // number of the current dehumidifier being simulated
3219 : {
3220 :
3221 : // SUBROUTINE INFORMATION:
3222 : // AUTHOR Michael J. Witte, GARD Analytics, Inc.
3223 : // for Gas Research Institute
3224 : // DATE WRITTEN March 2001
3225 : // MODIFIED June 2007, R. Raustad, Added new dehumidifier type -- DESICCANT DEHUMIDIFIER
3226 : // RE-ENGINEERED na
3227 :
3228 : // PURPOSE OF THIS SUBROUTINE:
3229 : // Fill remaining report variables
3230 :
3231 : // METHODOLOGY EMPLOYED:
3232 : // na
3233 :
3234 : // REFERENCES:
3235 : // na
3236 :
3237 : // Using/Aliasing
3238 275214 : auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys;
3239 :
3240 : // Locals
3241 : // SUBROUTINE ARGUMENT DEFINITIONS:
3242 :
3243 : // SUBROUTINE PARAMETER DEFINITIONS:
3244 : // na
3245 :
3246 : // INTERFACE BLOCK SPECIFICATIONS
3247 : // na
3248 :
3249 : // DERIVED TYPE DEFINITIONS
3250 : // na
3251 :
3252 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3253 : Real64 ReportingConstant;
3254 :
3255 275214 : ReportingConstant = TimeStepSys * DataGlobalConstants::SecInHour;
3256 :
3257 275214 : switch (state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).DehumTypeCode) {
3258 93953 : case DesicDehumType::Solid: {
3259 93953 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).WaterRemove =
3260 93953 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).WaterRemoveRate * ReportingConstant;
3261 93953 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).RegenEnergy =
3262 93953 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).QRegen * ReportingConstant;
3263 93953 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ElecUseEnergy =
3264 93953 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ElecUseRate * ReportingConstant;
3265 93953 : } break;
3266 181261 : case DesicDehumType::Generic: {
3267 181261 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).WaterRemove =
3268 181261 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).WaterRemoveRate * ReportingConstant;
3269 181261 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ExhaustFanElecConsumption =
3270 181261 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).ExhaustFanPower * ReportingConstant;
3271 181261 : } break;
3272 0 : default:
3273 0 : break;
3274 : }
3275 275214 : }
3276 :
3277 370679 : void CalcNonDXHeatingCoils(EnergyPlusData &state,
3278 : int const DesicDehumNum, // Desiccant dehumidifier unit index
3279 : bool const FirstHVACIteration, // flag for first HVAC iteration in the time step
3280 : Real64 const RegenCoilLoad, // heating coil load to be met (Watts)
3281 : Optional<Real64> RegenCoilLoadmet // heating load met
3282 : )
3283 : {
3284 :
3285 : // SUBROUTINE INFORMATION:
3286 : // AUTHOR Bereket Nigusse, FSEC/UCF
3287 : // DATE WRITTEN January 2012
3288 : // MODIFIED na
3289 : // RE-ENGINEERED na
3290 :
3291 : // PURPOSE OF THIS SUBROUTINE:
3292 : // This subroutine simulates the four non dx heating coil types: Gas, Electric, hot water and steam.
3293 :
3294 : // METHODOLOGY EMPLOYED:
3295 : // Simply calls the different heating coil component. The hot water flow rate matching the coil load
3296 : // is calculated iteratively.
3297 :
3298 : // REFERENCES:
3299 : // na
3300 :
3301 : // USE STATEMENTS:
3302 :
3303 : // Using/Aliasing
3304 : using DataHVACGlobals::SmallLoad;
3305 :
3306 : using HeatingCoils::SimulateHeatingCoilComponents;
3307 : using PlantUtilities::SetComponentFlowRate;
3308 : using SteamCoils::SimulateSteamCoilComponents;
3309 : using WaterCoils::SimulateWaterCoilComponents;
3310 :
3311 : // Locals
3312 : // SUBROUTINE ARGUMENT DEFINITIONS:
3313 :
3314 : // SUBROUTINE PARAMETER DEFINITIONS:
3315 370679 : Real64 constexpr ErrTolerance(0.001); // convergence limit for hotwater coil
3316 370679 : int constexpr SolveMaxIter(50); // Max iteration for SolveRoot
3317 :
3318 : // INTERFACE BLOCK SPECIFICATIONS
3319 : // na
3320 :
3321 : // DERIVED TYPE DEFINITIONS
3322 : // na
3323 :
3324 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3325 : Real64 RegenCoilActual; // actual heating load met
3326 : Real64 mdot; // heating coil steam or hot water mass flow rate
3327 : Real64 MinWaterFlow; // minimum hot water mass flow rate
3328 : // unused REAL(r64) :: PartLoadFraction ! heating or cooling part load fraction
3329 : Real64 MaxHotWaterFlow; // maximum hot water mass flow rate, kg/s
3330 : Real64 HotWaterMdot; // actual hot water mass flow rate
3331 : int SolFlag;
3332 :
3333 370679 : auto &DesicDehum(state.dataDesiccantDehumidifiers->DesicDehum);
3334 :
3335 370679 : RegenCoilActual = 0.0;
3336 370679 : if (RegenCoilLoad > SmallLoad) {
3337 60651 : switch (DesicDehum(DesicDehumNum).RegenCoilType_Num) {
3338 60651 : case Coil_HeatingGasOrOtherFuel:
3339 : case Coil_HeatingElectric: {
3340 181953 : SimulateHeatingCoilComponents(state,
3341 60651 : DesicDehum(DesicDehumNum).RegenCoilName,
3342 : FirstHVACIteration,
3343 : RegenCoilLoad,
3344 60651 : DesicDehum(DesicDehumNum).RegenCoilIndex,
3345 : RegenCoilActual);
3346 60651 : } break;
3347 0 : case Coil_HeatingWater: {
3348 0 : MaxHotWaterFlow = DesicDehum(DesicDehumNum).MaxCoilFluidFlow;
3349 0 : SetComponentFlowRate(state,
3350 : MaxHotWaterFlow,
3351 0 : DesicDehum(DesicDehumNum).CoilControlNode,
3352 0 : DesicDehum(DesicDehumNum).CoilOutletNode,
3353 0 : DesicDehum(DesicDehumNum).plantLoc);
3354 0 : RegenCoilActual = RegenCoilLoad;
3355 : // simulate the regenerator hot water heating coil
3356 0 : SimulateWaterCoilComponents(
3357 0 : state, DesicDehum(DesicDehumNum).RegenCoilName, FirstHVACIteration, DesicDehum(DesicDehumNum).RegenCoilIndex, RegenCoilActual);
3358 :
3359 0 : if (RegenCoilActual > (RegenCoilLoad + SmallLoad)) {
3360 : // control water flow to obtain output matching RegenCoilLoad
3361 0 : SolFlag = 0;
3362 0 : MinWaterFlow = 0.0;
3363 0 : auto f = [&state, DesicDehumNum, FirstHVACIteration, RegenCoilLoad](Real64 HWFlow) {
3364 0 : Real64 RegenCoilHeatLoad = RegenCoilLoad;
3365 0 : Real64 RegenCoilActual = RegenCoilHeatLoad;
3366 0 : Real64 mdot = HWFlow;
3367 0 : PlantUtilities::SetComponentFlowRate(state,
3368 : mdot,
3369 0 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).CoilControlNode,
3370 0 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).CoilOutletNode,
3371 0 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).plantLoc);
3372 :
3373 : // simulate the hot water regenerator heating coil
3374 0 : WaterCoils::SimulateWaterCoilComponents(state,
3375 0 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).RegenCoilName,
3376 : FirstHVACIteration,
3377 0 : state.dataDesiccantDehumidifiers->DesicDehum(DesicDehumNum).RegenCoilIndex,
3378 : RegenCoilActual);
3379 0 : if (RegenCoilHeatLoad != 0.0) {
3380 0 : return (RegenCoilActual - RegenCoilHeatLoad) / RegenCoilHeatLoad;
3381 : } else { // Autodesk:Return ELSE added to assure return value is set
3382 0 : return 0.0;
3383 : }
3384 0 : };
3385 0 : General::SolveRoot(state, ErrTolerance, SolveMaxIter, SolFlag, HotWaterMdot, f, MinWaterFlow, MaxHotWaterFlow);
3386 0 : if (SolFlag == -1) {
3387 0 : if (DesicDehum(DesicDehumNum).HotWaterCoilMaxIterIndex == 0) {
3388 0 : ShowWarningMessage(state,
3389 0 : "CalcNonDXHeatingCoils: Hot water coil control failed for " + DesicDehum(DesicDehumNum).DehumType +
3390 0 : "=\"" + DesicDehum(DesicDehumNum).Name + "\"");
3391 0 : ShowContinueErrorTimeStamp(state, "");
3392 0 : ShowContinueError(state,
3393 0 : format("...Iteration limit [{}] exceeded in calculating hot water mass flow rate", SolveMaxIter));
3394 : }
3395 0 : ShowRecurringWarningErrorAtEnd(
3396 : state,
3397 0 : format("CalcNonDXHeatingCoils: Hot water coil control failed (iteration limit [{}]) for {}=\"{}\"",
3398 : SolveMaxIter,
3399 0 : DesicDehum(DesicDehumNum).DehumType,
3400 0 : DesicDehum(DesicDehumNum).Name),
3401 0 : DesicDehum(DesicDehumNum).HotWaterCoilMaxIterIndex);
3402 0 : } else if (SolFlag == -2) {
3403 0 : if (DesicDehum(DesicDehumNum).HotWaterCoilMaxIterIndex2 == 0) {
3404 0 : ShowWarningMessage(state,
3405 0 : "CalcNonDXHeatingCoils: Hot water coil control failed (maximum flow limits) for " +
3406 0 : DesicDehum(DesicDehumNum).DehumType + "=\"" + DesicDehum(DesicDehumNum).Name + "\"");
3407 0 : ShowContinueErrorTimeStamp(state, "");
3408 0 : ShowContinueError(state, "...Bad hot water maximum flow rate limits");
3409 0 : ShowContinueError(state, format("...Given minimum water flow rate={:.3R} kg/s", MinWaterFlow));
3410 0 : ShowContinueError(state, format("...Given maximum water flow rate={:.3R} kg/s", MaxHotWaterFlow));
3411 : }
3412 0 : ShowRecurringWarningErrorAtEnd(state,
3413 0 : "CalcNonDXHeatingCoils: Hot water coil control failed (flow limits) for " +
3414 0 : DesicDehum(DesicDehumNum).DehumType + "=\"" + DesicDehum(DesicDehumNum).Name + "\"",
3415 0 : DesicDehum(DesicDehumNum).HotWaterCoilMaxIterIndex2,
3416 : MaxHotWaterFlow,
3417 : MinWaterFlow,
3418 : _,
3419 : "[kg/s]",
3420 : "[kg/s]");
3421 : }
3422 :
3423 0 : RegenCoilActual = RegenCoilLoad;
3424 : // simulate the regenerator hot water heating coil
3425 0 : SimulateWaterCoilComponents(state,
3426 0 : DesicDehum(DesicDehumNum).RegenCoilName,
3427 : FirstHVACIteration,
3428 0 : DesicDehum(DesicDehumNum).RegenCoilIndex,
3429 : RegenCoilActual);
3430 : }
3431 0 : } break;
3432 0 : case Coil_HeatingSteam: {
3433 0 : mdot = DesicDehum(DesicDehumNum).MaxCoilFluidFlow;
3434 0 : SetComponentFlowRate(state,
3435 : mdot,
3436 0 : DesicDehum(DesicDehumNum).CoilControlNode,
3437 0 : DesicDehum(DesicDehumNum).CoilOutletNode,
3438 0 : DesicDehum(DesicDehumNum).plantLoc);
3439 : // simulate the regenerator steam heating coil
3440 0 : SimulateSteamCoilComponents(state,
3441 0 : DesicDehum(DesicDehumNum).RegenCoilName,
3442 : FirstHVACIteration,
3443 0 : DesicDehum(DesicDehumNum).RegenCoilIndex,
3444 : RegenCoilLoad,
3445 : RegenCoilActual);
3446 0 : } break;
3447 0 : default:
3448 0 : break;
3449 : }
3450 : } else {
3451 310028 : switch (DesicDehum(DesicDehumNum).RegenCoilType_Num) {
3452 310028 : case Coil_HeatingGasOrOtherFuel:
3453 : case Coil_HeatingElectric: {
3454 930084 : SimulateHeatingCoilComponents(state,
3455 310028 : DesicDehum(DesicDehumNum).RegenCoilName,
3456 : FirstHVACIteration,
3457 : RegenCoilLoad,
3458 310028 : DesicDehum(DesicDehumNum).RegenCoilIndex,
3459 : RegenCoilActual);
3460 310028 : } break;
3461 0 : case Coil_HeatingWater: {
3462 0 : mdot = 0.0;
3463 0 : SetComponentFlowRate(state,
3464 : mdot,
3465 0 : DesicDehum(DesicDehumNum).CoilControlNode,
3466 0 : DesicDehum(DesicDehumNum).CoilOutletNode,
3467 0 : DesicDehum(DesicDehumNum).plantLoc);
3468 0 : RegenCoilActual = RegenCoilLoad;
3469 : // simulate the regenerator hot water heating coil
3470 0 : SimulateWaterCoilComponents(
3471 0 : state, DesicDehum(DesicDehumNum).RegenCoilName, FirstHVACIteration, DesicDehum(DesicDehumNum).RegenCoilIndex, RegenCoilActual);
3472 0 : } break;
3473 0 : case Coil_HeatingSteam: {
3474 0 : mdot = 0.0;
3475 0 : SetComponentFlowRate(state,
3476 : mdot,
3477 0 : DesicDehum(DesicDehumNum).CoilControlNode,
3478 0 : DesicDehum(DesicDehumNum).CoilOutletNode,
3479 0 : DesicDehum(DesicDehumNum).plantLoc);
3480 : // simulate the regenerator steam heating coil
3481 0 : SimulateSteamCoilComponents(state,
3482 0 : DesicDehum(DesicDehumNum).RegenCoilName,
3483 : FirstHVACIteration,
3484 0 : DesicDehum(DesicDehumNum).RegenCoilIndex,
3485 : RegenCoilLoad,
3486 : RegenCoilActual);
3487 0 : } break;
3488 0 : default:
3489 0 : break;
3490 : }
3491 : }
3492 370679 : if (present(RegenCoilLoadmet)) RegenCoilLoadmet = RegenCoilActual;
3493 370679 : }
3494 :
3495 0 : int GetProcAirInletNodeNum(EnergyPlusData &state, std::string const &DesicDehumName, bool &ErrorsFound)
3496 : {
3497 :
3498 : // FUNCTION INFORMATION:
3499 : // AUTHOR Lixing Gu
3500 : // DATE WRITTEN May 2019
3501 : // MODIFIED na
3502 : // RE-ENGINEERED na
3503 :
3504 : // PURPOSE OF THIS FUNCTION:
3505 : // This function looks up the given Desiccant Dehumidifier and returns the process air inlet node number.
3506 : // If incorrect Desiccant Dehumidifier name is given, ErrorsFound is returned as true and node number as zero.
3507 :
3508 : // Return value
3509 : int NodeNum; // node number returned
3510 :
3511 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3512 : int WhichDesicDehum;
3513 :
3514 : // Obtains and Allocates heat exchanger related parameters from input file
3515 0 : if (state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier) {
3516 0 : GetDesiccantDehumidifierInput(state);
3517 0 : state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier = false;
3518 : }
3519 :
3520 0 : WhichDesicDehum = UtilityRoutines::FindItemInList(DesicDehumName, state.dataDesiccantDehumidifiers->DesicDehum);
3521 0 : if (WhichDesicDehum != 0) {
3522 0 : NodeNum = state.dataDesiccantDehumidifiers->DesicDehum(WhichDesicDehum).ProcAirInNode;
3523 : } else {
3524 0 : ShowSevereError(state, "GetProcAirInletNodeNum: Could not find Desciccant Dehumidifier = \"" + DesicDehumName + "\"");
3525 0 : ErrorsFound = true;
3526 0 : NodeNum = 0;
3527 : }
3528 :
3529 0 : return NodeNum;
3530 : }
3531 :
3532 0 : int GetProcAirOutletNodeNum(EnergyPlusData &state, std::string const &DesicDehumName, bool &ErrorsFound)
3533 : {
3534 : // FUNCTION INFORMATION:
3535 : // AUTHOR Lixing Gu
3536 : // DATE WRITTEN May 2019
3537 : // MODIFIED na
3538 : // RE-ENGINEERED na
3539 :
3540 : // PURPOSE OF THIS FUNCTION:
3541 : // This function looks up the given Desiccant Dehumidifier and returns the process air outlet node number.
3542 : // If incorrect Desiccant Dehumidifier name is given, ErrorsFound is returned as true and node number as zero.
3543 :
3544 : // Return value
3545 : int NodeNum; // node number returned
3546 :
3547 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3548 : int WhichDesicDehum;
3549 :
3550 : // Obtains and Allocates heat exchanger related parameters from input file
3551 0 : if (state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier) {
3552 0 : GetDesiccantDehumidifierInput(state);
3553 0 : state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier = false;
3554 : }
3555 :
3556 0 : WhichDesicDehum = UtilityRoutines::FindItemInList(DesicDehumName, state.dataDesiccantDehumidifiers->DesicDehum);
3557 0 : if (WhichDesicDehum != 0) {
3558 0 : NodeNum = state.dataDesiccantDehumidifiers->DesicDehum(WhichDesicDehum).ProcAirOutNode;
3559 : } else {
3560 0 : ShowSevereError(state, "GetProcAirInletNodeNum: Could not find Desciccant Dehumidifier = \"" + DesicDehumName + "\"");
3561 0 : ErrorsFound = true;
3562 0 : NodeNum = 0;
3563 : }
3564 :
3565 0 : return NodeNum;
3566 : }
3567 :
3568 0 : int GetRegAirInletNodeNum(EnergyPlusData &state, std::string const &DesicDehumName, bool &ErrorsFound)
3569 : {
3570 : // FUNCTION INFORMATION:
3571 : // AUTHOR Lixing Gu
3572 : // DATE WRITTEN May 2019
3573 : // MODIFIED na
3574 : // RE-ENGINEERED na
3575 :
3576 : // PURPOSE OF THIS FUNCTION:
3577 : // This function looks up the given Desiccant Dehumidifier and returns the regeneration air inlet node number.
3578 : // If incorrect Desiccant Dehumidifier name is given, ErrorsFound is returned as true and node number as zero.
3579 :
3580 : // Return value
3581 : int NodeNum; // node number returned
3582 :
3583 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3584 : int WhichDesicDehum;
3585 :
3586 : // Obtains and Allocates heat exchanger related parameters from input file
3587 0 : if (state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier) {
3588 0 : GetDesiccantDehumidifierInput(state);
3589 0 : state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier = false;
3590 : }
3591 :
3592 0 : WhichDesicDehum = UtilityRoutines::FindItemInList(DesicDehumName, state.dataDesiccantDehumidifiers->DesicDehum);
3593 0 : if (WhichDesicDehum != 0) {
3594 0 : NodeNum = state.dataDesiccantDehumidifiers->DesicDehum(WhichDesicDehum).RegenAirInNode;
3595 : } else {
3596 0 : ShowSevereError(state, "GetRegAirInletNodeNum: Could not find Desciccant Dehumidifier = \"" + DesicDehumName + "\"");
3597 0 : ErrorsFound = true;
3598 0 : NodeNum = 0;
3599 : }
3600 :
3601 0 : return NodeNum;
3602 : }
3603 :
3604 0 : int GetRegAirOutletNodeNum(EnergyPlusData &state, std::string const &DesicDehumName, bool &ErrorsFound)
3605 : {
3606 : // FUNCTION INFORMATION:
3607 : // AUTHOR Lixing Gu
3608 : // DATE WRITTEN May 2019
3609 : // MODIFIED na
3610 : // RE-ENGINEERED na
3611 :
3612 : // PURPOSE OF THIS FUNCTION:
3613 : // This function looks up the given Desiccant Dehumidifier and returns the regeneration air outlet node number.
3614 : // If incorrect Desiccant Dehumidifier name is given, ErrorsFound is returned as true and node number as zero.
3615 :
3616 : // Return value
3617 : int NodeNum; // node number returned
3618 :
3619 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3620 : int WhichDesicDehum;
3621 :
3622 : // Obtains and Allocates heat exchanger related parameters from input file
3623 0 : if (state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier) {
3624 0 : GetDesiccantDehumidifierInput(state);
3625 0 : state.dataDesiccantDehumidifiers->GetInputDesiccantDehumidifier = false;
3626 : }
3627 :
3628 0 : WhichDesicDehum = UtilityRoutines::FindItemInList(DesicDehumName, state.dataDesiccantDehumidifiers->DesicDehum);
3629 0 : if (WhichDesicDehum != 0) {
3630 0 : NodeNum = state.dataDesiccantDehumidifiers->DesicDehum(WhichDesicDehum).RegenAirOutNode;
3631 : } else {
3632 0 : ShowSevereError(state, "GetRegAirOutletNodeNum: Could not find Desciccant Dehumidifier = \"" + DesicDehumName + "\"");
3633 0 : ErrorsFound = true;
3634 0 : NodeNum = 0;
3635 : }
3636 :
3637 0 : return NodeNum;
3638 : }
3639 :
3640 : // End of Reporting subroutines for the SimAir Module
3641 : // *****************************************************************************
3642 :
3643 : // COPYRIGHT NOTICE
3644 :
3645 : // Portions Copyright (c) Gas Research Institute 2001. All rights reserved.
3646 :
3647 : // GRI LEGAL NOTICE
3648 : // Neither GRI, members of GRI nor any person or organization acting on behalf
3649 : // of either:
3650 :
3651 : // A. Makes any warranty of representation, express or implied with respect to
3652 : // the accuracy, completness, or usefulness of the information contained in
3653 : // in this program, including any warranty of merchantability or fitness of
3654 : // any purpose with respoect to the program, or that the use of any
3655 : // information disclosed in this program may not infringe privately-owned
3656 : // rights, or
3657 :
3658 : // B. Assumes any liability with respoct to the use of, or for any and all
3659 : // damages resulting from the use of the program or any portion thereof or
3660 : // any information disclosed therein.
3661 :
3662 : } // namespace DesiccantDehumidifiers
3663 :
3664 2313 : } // namespace EnergyPlus
|