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/Data/EnergyPlusData.hh>
59 : #include <EnergyPlus/DataContaminantBalance.hh>
60 : #include <EnergyPlus/DataHVACGlobals.hh>
61 : #include <EnergyPlus/DataLoopNode.hh>
62 : #include <EnergyPlus/FluidProperties.hh>
63 : #include <EnergyPlus/General.hh>
64 : #include <EnergyPlus/GlobalNames.hh>
65 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
66 : #include <EnergyPlus/NodeInputManager.hh>
67 : #include <EnergyPlus/OutputProcessor.hh>
68 : #include <EnergyPlus/OutputReportPredefined.hh>
69 : #include <EnergyPlus/Plant/DataPlant.hh>
70 : #include <EnergyPlus/PlantUtilities.hh>
71 : #include <EnergyPlus/Psychrometrics.hh>
72 : #include <EnergyPlus/UtilityRoutines.hh>
73 : #include <EnergyPlus/WaterToAirHeatPump.hh>
74 :
75 : namespace EnergyPlus {
76 :
77 : namespace WaterToAirHeatPump {
78 : // Module containing the Water to Air Heat Pump simulation routines
79 :
80 : // MODULE INFORMATION:
81 : // AUTHOR Hui Jin
82 : // DATE WRITTEN Oct 2000
83 : // MODIFIED Dan Fisher, Kenneth Tang (Jan 2004)
84 : // Brent Griffith, plant upgrades, fluid props
85 : // RE-ENGINEERED na
86 :
87 : // PURPOSE OF THIS MODULE:
88 : // To encapsulate the data and algorithms required to
89 : // manage the Water to Air Heat Pump Component
90 :
91 : // METHODOLOGY EMPLOYED:
92 :
93 : // REFERENCES:
94 : // Jin, H. 2002. Parameter Estimation Based Models of Water Source Heat Pumps. Phd Thesis.
95 : // Oklahoma State University.
96 :
97 : using namespace DataLoopNode;
98 : using DataHVACGlobals::ContFanCycCoil;
99 : using DataHVACGlobals::CycFanCycCoil;
100 :
101 : static constexpr std::string_view fluidNameWater("WATER");
102 :
103 2046263 : void SimWatertoAirHP(EnergyPlusData &state,
104 : std::string_view CompName, // component name
105 : int &CompIndex, // Index for Component name
106 : Real64 const DesignAirflow, // design air flow rate
107 : int const CyclingScheme, // cycling scheme--either continuous fan/cycling compressor or
108 : bool const FirstHVACIteration, // first iteration flag
109 : Real64 const RuntimeFrac, // compressor run time fraction
110 : Real64 &MaxONOFFCyclesperHour, // Maximum cycling rate of heat pump [cycles/hr]
111 : Real64 &HPTimeConstant, // Heat pump time constant [s]
112 : Real64 &FanDelayTime, // Fan delay time, time delay for the HP's fan to
113 : bool const InitFlag, // initialization flag used to suppress property routine errors
114 : Real64 const SensLoad, // sensible load
115 : Real64 const LatentLoad, // latent load
116 : DataHVACGlobals::CompressorOperation const CompressorOp,
117 : Real64 const PartLoadRatio)
118 : {
119 :
120 : // SUBROUTINE INFORMATION:
121 : // AUTHOR Hui Jin
122 : // DATE WRITTEN Oct 2000
123 : // MODIFIED Dan Fisher, Kenneth Tang (Jan 2004)
124 : // RE-ENGINEERED na
125 :
126 : // PURPOSE OF THIS SUBROUTINE:
127 : // This subroutine manages Water to Air Heat Pump component simulation.
128 :
129 : // Using/Aliasing
130 : using FluidProperties::FindGlycol;
131 :
132 : // shut off after compressor cycle off [s]
133 : // cycling fan/cycling compressor
134 :
135 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
136 : int HPNum; // The WatertoAirHP that you are currently loading input into
137 :
138 : // Obtains and Allocates WatertoAirHP related parameters from input file
139 2046263 : if (state.dataWaterToAirHeatPump->GetCoilsInputFlag) { // First time subroutine has been entered
140 0 : state.dataWaterToAirHeatPump->WaterIndex = FindGlycol(state, fluidNameWater); // Initialize the WaterIndex once
141 0 : GetWatertoAirHPInput(state);
142 0 : state.dataWaterToAirHeatPump->GetCoilsInputFlag = false;
143 : }
144 :
145 2046263 : if (CompIndex == 0) {
146 0 : HPNum = UtilityRoutines::FindItemInList(CompName, state.dataWaterToAirHeatPump->WatertoAirHP);
147 0 : if (HPNum == 0) {
148 0 : ShowFatalError(state, format("WaterToAir HP not found={}", CompName));
149 : }
150 0 : CompIndex = HPNum;
151 : } else {
152 2046263 : HPNum = CompIndex;
153 2046263 : if (HPNum > state.dataWaterToAirHeatPump->NumWatertoAirHPs || HPNum < 1) {
154 0 : ShowFatalError(state,
155 0 : format("SimWatertoAirHP: Invalid CompIndex passed={}, Number of Water to Air HPs={}, WaterToAir HP name={}",
156 : HPNum,
157 0 : state.dataWaterToAirHeatPump->NumWatertoAirHPs,
158 0 : CompName));
159 : }
160 2046263 : if (state.dataWaterToAirHeatPump->CheckEquipName(HPNum)) {
161 38 : if (!CompName.empty() && CompName != state.dataWaterToAirHeatPump->WatertoAirHP(HPNum).Name) {
162 0 : ShowFatalError(
163 : state,
164 0 : format("SimWatertoAirHP: Invalid CompIndex passed={}, WaterToAir HP name={}, stored WaterToAir HP Name for that index={}",
165 : HPNum,
166 : CompName,
167 0 : state.dataWaterToAirHeatPump->WatertoAirHP(HPNum).Name));
168 : }
169 38 : state.dataWaterToAirHeatPump->CheckEquipName(HPNum) = false;
170 : }
171 : }
172 : // Calculate the Correct Water to Air HP Model with the current HPNum
173 :
174 2046263 : if (state.dataWaterToAirHeatPump->WatertoAirHP(HPNum).WAHPType == DataPlant::PlantEquipmentType::CoilWAHPCoolingParamEst) {
175 1023134 : InitWatertoAirHP(
176 : state, HPNum, InitFlag, MaxONOFFCyclesperHour, HPTimeConstant, FanDelayTime, SensLoad, LatentLoad, DesignAirflow, PartLoadRatio);
177 1023134 : CalcWatertoAirHPCooling(state, HPNum, CyclingScheme, FirstHVACIteration, RuntimeFrac, InitFlag, SensLoad, CompressorOp, PartLoadRatio);
178 :
179 1023134 : UpdateWatertoAirHP(state, HPNum);
180 :
181 1023129 : } else if (state.dataWaterToAirHeatPump->WatertoAirHP(HPNum).WAHPType == DataPlant::PlantEquipmentType::CoilWAHPHeatingParamEst) {
182 1023129 : InitWatertoAirHP(
183 : state, HPNum, InitFlag, MaxONOFFCyclesperHour, HPTimeConstant, FanDelayTime, SensLoad, LatentLoad, DesignAirflow, PartLoadRatio);
184 1023129 : CalcWatertoAirHPHeating(state, HPNum, CyclingScheme, FirstHVACIteration, RuntimeFrac, InitFlag, SensLoad, CompressorOp, PartLoadRatio);
185 :
186 1023129 : UpdateWatertoAirHP(state, HPNum);
187 :
188 : } else {
189 0 : ShowFatalError(state, "SimWatertoAirHP: AirtoAir heatpump not in either HEATING or COOLING");
190 : }
191 2046263 : }
192 :
193 : // Get Input Section of the Module
194 : //******************************************************************************
195 :
196 6 : void GetWatertoAirHPInput(EnergyPlusData &state)
197 : {
198 :
199 : // SUBROUTINE INFORMATION:
200 : // AUTHOR Hui Jin
201 : // DATE WRITTEN Oct 2000
202 : // MODIFIED Dan Fisher, Kenneth Tang (Jan 2004)
203 : // RE-ENGINEERED na
204 :
205 : // PURPOSE OF THIS SUBROUTINE:
206 : // Obtains input data for HPs and stores it in HP data structures
207 :
208 : // METHODOLOGY EMPLOYED:
209 : // Uses "Get" routines to read in data.
210 :
211 : // Using/Aliasing
212 : using namespace NodeInputManager;
213 : using BranchNodeConnections::TestCompSet;
214 : using FluidProperties::CheckFluidPropertyName;
215 : using FluidProperties::FindGlycol;
216 : using GlobalNames::VerifyUniqueCoilName;
217 : using PlantUtilities::RegisterPlantCompDesignFlow;
218 : using namespace OutputReportPredefined;
219 :
220 : // SUBROUTINE PARAMETER DEFINITIONS:
221 : static constexpr std::string_view RoutineName("GetWatertoAirHPInput: "); // include trailing blank space
222 :
223 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
224 : int HPNum; // The Water to Air HP that you are currently loading input into
225 : int NumCool;
226 : int NumHeat;
227 : int WatertoAirHPNum;
228 : int NumAlphas;
229 : int NumParams;
230 : int NumNums;
231 6 : int MaxNums(0); // Maximum number of numeric input fields
232 6 : int MaxAlphas(0); // Maximum number of alpha input fields
233 : int IOStat;
234 6 : bool ErrorsFound(false); // If errors detected in input
235 12 : std::string CurrentModuleObject; // for ease in getting objects
236 12 : Array1D_string AlphArray; // Alpha input items for object
237 12 : Array1D_string cAlphaFields; // Alpha field names
238 12 : Array1D_string cNumericFields; // Numeric field names
239 12 : Array1D<Real64> NumArray; // Numeric input items for object
240 12 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
241 12 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
242 :
243 6 : constexpr std::array<std::string_view, static_cast<int>(CompressorType::Num)> CompressTypeNamesUC{"RECIPROCATING", "ROTARY", "SCROLL"};
244 :
245 6 : NumCool = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:WaterToAirHeatPump:ParameterEstimation");
246 6 : NumHeat = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:WaterToAirHeatPump:ParameterEstimation");
247 6 : state.dataWaterToAirHeatPump->NumWatertoAirHPs = NumCool + NumHeat;
248 6 : HPNum = 0;
249 :
250 6 : if (state.dataWaterToAirHeatPump->NumWatertoAirHPs <= 0) {
251 0 : ShowSevereError(state, "No Equipment found in SimWatertoAirHP");
252 0 : ErrorsFound = true;
253 : }
254 :
255 : // Allocate Arrays
256 6 : if (state.dataWaterToAirHeatPump->NumWatertoAirHPs > 0) {
257 6 : state.dataWaterToAirHeatPump->WatertoAirHP.allocate(state.dataWaterToAirHeatPump->NumWatertoAirHPs);
258 6 : state.dataWaterToAirHeatPump->CheckEquipName.dimension(state.dataWaterToAirHeatPump->NumWatertoAirHPs, true);
259 : }
260 :
261 12 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
262 6 : state, "Coil:Cooling:WaterToAirHeatPump:ParameterEstimation", NumParams, NumAlphas, NumNums);
263 6 : MaxNums = max(MaxNums, NumNums);
264 6 : MaxAlphas = max(MaxAlphas, NumAlphas);
265 12 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
266 6 : state, "Coil:Heating:WaterToAirHeatPump:ParameterEstimation", NumParams, NumAlphas, NumNums);
267 6 : MaxNums = max(MaxNums, NumNums);
268 6 : MaxAlphas = max(MaxAlphas, NumAlphas);
269 6 : AlphArray.allocate(MaxAlphas);
270 6 : cAlphaFields.allocate(MaxAlphas);
271 6 : lAlphaBlanks.dimension(MaxAlphas, true);
272 6 : cNumericFields.allocate(MaxNums);
273 6 : lNumericBlanks.dimension(MaxNums, true);
274 6 : NumArray.dimension(MaxNums, 0.0);
275 :
276 : // Get the data for detailed cooling Heat Pump
277 6 : CurrentModuleObject = "Coil:Cooling:WaterToAirHeatPump:ParameterEstimation";
278 :
279 25 : for (WatertoAirHPNum = 1; WatertoAirHPNum <= NumCool; ++WatertoAirHPNum) {
280 :
281 19 : ++HPNum;
282 :
283 19 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
284 : CurrentModuleObject,
285 : HPNum,
286 : AlphArray,
287 : NumAlphas,
288 : NumArray,
289 : NumNums,
290 : IOStat,
291 : lNumericBlanks,
292 : lAlphaBlanks,
293 : cAlphaFields,
294 : cNumericFields);
295 :
296 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
297 19 : VerifyUniqueCoilName(state, CurrentModuleObject, AlphArray(1), ErrorsFound, CurrentModuleObject + " Name");
298 :
299 19 : auto &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
300 :
301 19 : heatPump.Name = AlphArray(1);
302 19 : heatPump.WatertoAirHPType = "COOLING";
303 19 : heatPump.WAHPType = DataPlant::PlantEquipmentType::CoilWAHPCoolingParamEst;
304 19 : heatPump.Refrigerant = AlphArray(3);
305 19 : heatPump.DesignWaterVolFlowRate = NumArray(1);
306 19 : heatPump.CoolingCapacity = NumArray(2);
307 19 : heatPump.Twet_Rated = NumArray(3);
308 19 : heatPump.Gamma_Rated = NumArray(4);
309 :
310 19 : heatPump.HighPressCutoff = NumArray(5);
311 19 : heatPump.LowPressCutoff = NumArray(6);
312 :
313 19 : heatPump.WaterInletNodeNum = GetOnlySingleNode(state,
314 19 : AlphArray(4),
315 : ErrorsFound,
316 : DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpParameterEstimation,
317 19 : AlphArray(1),
318 : DataLoopNode::NodeFluidType::Water,
319 : DataLoopNode::ConnectionType::Inlet,
320 : NodeInputManager::CompFluidStream::Secondary,
321 19 : ObjectIsNotParent);
322 19 : heatPump.WaterOutletNodeNum = GetOnlySingleNode(state,
323 19 : AlphArray(5),
324 : ErrorsFound,
325 : DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpParameterEstimation,
326 19 : AlphArray(1),
327 : DataLoopNode::NodeFluidType::Water,
328 : DataLoopNode::ConnectionType::Outlet,
329 : NodeInputManager::CompFluidStream::Secondary,
330 19 : ObjectIsNotParent);
331 19 : heatPump.AirInletNodeNum = GetOnlySingleNode(state,
332 19 : AlphArray(6),
333 : ErrorsFound,
334 : DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpParameterEstimation,
335 19 : AlphArray(1),
336 : DataLoopNode::NodeFluidType::Air,
337 : DataLoopNode::ConnectionType::Inlet,
338 : NodeInputManager::CompFluidStream::Primary,
339 19 : ObjectIsNotParent);
340 19 : heatPump.AirOutletNodeNum = GetOnlySingleNode(state,
341 19 : AlphArray(7),
342 : ErrorsFound,
343 : DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpParameterEstimation,
344 19 : AlphArray(1),
345 : DataLoopNode::NodeFluidType::Air,
346 : DataLoopNode::ConnectionType::Outlet,
347 : NodeInputManager::CompFluidStream::Primary,
348 19 : ObjectIsNotParent);
349 :
350 : // 2010-01-13 ESL: Jason Glazer noted that these were out of order previously, but they are good now
351 19 : heatPump.LoadSideTotalUACoeff = NumArray(7);
352 19 : heatPump.LoadSideOutsideUACoeff = NumArray(8);
353 :
354 38 : if ((heatPump.LoadSideOutsideUACoeff < DataGlobalConstants::rTinyValue) ||
355 19 : (heatPump.LoadSideTotalUACoeff < DataGlobalConstants::rTinyValue)) {
356 0 : ShowSevereError(state, "Input problem for " + CurrentModuleObject + '=' + heatPump.Name);
357 0 : ShowContinueError(state, " One or both load side UA values entered are below tolerance, likely zero or blank.");
358 0 : ShowContinueError(state, " Verify inputs, as the parameter syntax for this object went through a change with");
359 0 : ShowContinueError(state, " the release of EnergyPlus version 5.");
360 0 : ErrorsFound = true;
361 : }
362 :
363 19 : heatPump.SuperheatTemp = NumArray(9);
364 19 : heatPump.PowerLosses = NumArray(10);
365 19 : heatPump.LossFactor = NumArray(11);
366 :
367 19 : heatPump.compressorType =
368 38 : static_cast<CompressorType>(getEnumerationValue(CompressTypeNamesUC, UtilityRoutines::MakeUPPERCase(AlphArray(2))));
369 :
370 19 : switch (heatPump.compressorType) {
371 0 : case CompressorType::Reciprocating: {
372 0 : heatPump.CompPistonDisp = NumArray(12);
373 0 : heatPump.CompSucPressDrop = NumArray(13);
374 0 : heatPump.CompClearanceFactor = NumArray(14);
375 0 : break;
376 : }
377 0 : case CompressorType::Rotary: {
378 0 : heatPump.CompPistonDisp = NumArray(12);
379 0 : heatPump.CompSucPressDrop = NumArray(13);
380 0 : break;
381 : }
382 19 : case CompressorType::Scroll: {
383 19 : heatPump.RefVolFlowRate = NumArray(15);
384 19 : heatPump.VolumeRatio = NumArray(16);
385 19 : heatPump.LeakRateCoeff = NumArray(17);
386 19 : break;
387 : }
388 0 : default: {
389 0 : ShowSevereError(
390 : state,
391 0 : format("{}Invalid {} ({}) entered. {}={}", RoutineName, cAlphaFields(2), AlphArray(2), CurrentModuleObject, heatPump.Name));
392 0 : ErrorsFound = true;
393 0 : break;
394 : }
395 : }
396 :
397 19 : heatPump.SourceSideUACoeff = NumArray(18);
398 19 : heatPump.SourceSideHTR1 = NumArray(19);
399 19 : heatPump.SourceSideHTR2 = NumArray(20);
400 :
401 19 : TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(4), AlphArray(5), "Water Nodes");
402 19 : TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(6), AlphArray(7), "Air Nodes");
403 :
404 : // Setup Report variables for the detailed cooling Heat Pump
405 : // CurrentModuleObject = "Coil:Cooling:WaterToAirHeatPump:ParameterEstimation"
406 38 : SetupOutputVariable(state,
407 : "Cooling Coil Electricity Energy",
408 : OutputProcessor::Unit::J,
409 : heatPump.Energy,
410 : OutputProcessor::SOVTimeStepType::System,
411 : OutputProcessor::SOVStoreType::Summed,
412 : heatPump.Name,
413 : _,
414 : "Electricity",
415 : "Cooling",
416 : _,
417 19 : "System");
418 38 : SetupOutputVariable(state,
419 : "Cooling Coil Total Cooling Energy",
420 : OutputProcessor::Unit::J,
421 : heatPump.EnergyLoadTotal,
422 : OutputProcessor::SOVTimeStepType::System,
423 : OutputProcessor::SOVStoreType::Summed,
424 : heatPump.Name,
425 : _,
426 : "ENERGYTRANSFER",
427 : "COOLINGCOILS",
428 : _,
429 19 : "System");
430 38 : SetupOutputVariable(state,
431 : "Cooling Coil Sensible Cooling Energy",
432 : OutputProcessor::Unit::J,
433 : heatPump.EnergySensible,
434 : OutputProcessor::SOVTimeStepType::System,
435 : OutputProcessor::SOVStoreType::Summed,
436 19 : heatPump.Name);
437 38 : SetupOutputVariable(state,
438 : "Cooling Coil Latent Cooling Energy",
439 : OutputProcessor::Unit::J,
440 : heatPump.EnergyLatent,
441 : OutputProcessor::SOVTimeStepType::System,
442 : OutputProcessor::SOVStoreType::Summed,
443 19 : heatPump.Name);
444 38 : SetupOutputVariable(state,
445 : "Cooling Coil Source Side Heat Transfer Energy",
446 : OutputProcessor::Unit::J,
447 : heatPump.EnergySource,
448 : OutputProcessor::SOVTimeStepType::System,
449 : OutputProcessor::SOVStoreType::Summed,
450 : heatPump.Name,
451 : _,
452 : "PLANTLOOPCOOLINGDEMAND",
453 : "COOLINGCOILS",
454 : _,
455 19 : "System");
456 :
457 : // save the design source side flow rate for use by plant loop sizing algorithms
458 19 : RegisterPlantCompDesignFlow(state, heatPump.WaterInletNodeNum, 0.5 * heatPump.DesignWaterVolFlowRate);
459 :
460 : // create predefined report entries
461 19 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilType, heatPump.Name, CurrentModuleObject);
462 19 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, heatPump.Name, heatPump.CoolingCapacity);
463 19 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSensCap, heatPump.Name, "-");
464 19 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilLatCap, heatPump.Name, "-");
465 19 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, heatPump.Name, "-");
466 19 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, heatPump.Name, "-");
467 : }
468 :
469 6 : CurrentModuleObject = "Coil:Heating:WaterToAirHeatPump:ParameterEstimation";
470 :
471 25 : for (WatertoAirHPNum = 1; WatertoAirHPNum <= NumHeat; ++WatertoAirHPNum) {
472 :
473 19 : ++HPNum;
474 :
475 19 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
476 : CurrentModuleObject,
477 : WatertoAirHPNum,
478 : AlphArray,
479 : NumAlphas,
480 : NumArray,
481 : NumNums,
482 : IOStat,
483 : lNumericBlanks,
484 : lAlphaBlanks,
485 : cAlphaFields,
486 : cNumericFields);
487 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
488 19 : VerifyUniqueCoilName(state, CurrentModuleObject, AlphArray(1), ErrorsFound, CurrentModuleObject + " Name");
489 19 : auto &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
490 :
491 19 : heatPump.Name = AlphArray(1);
492 19 : heatPump.WatertoAirHPType = "HEATING";
493 19 : heatPump.WAHPType = DataPlant::PlantEquipmentType::CoilWAHPHeatingParamEst;
494 19 : heatPump.Refrigerant = AlphArray(3);
495 19 : heatPump.DesignWaterVolFlowRate = NumArray(1);
496 19 : heatPump.HeatingCapacity = NumArray(2);
497 :
498 19 : heatPump.HighPressCutoff = NumArray(3);
499 19 : heatPump.LowPressCutoff = NumArray(4);
500 :
501 19 : heatPump.WaterInletNodeNum = GetOnlySingleNode(state,
502 19 : AlphArray(4),
503 : ErrorsFound,
504 : DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpParameterEstimation,
505 19 : AlphArray(1),
506 : DataLoopNode::NodeFluidType::Water,
507 : DataLoopNode::ConnectionType::Inlet,
508 : NodeInputManager::CompFluidStream::Secondary,
509 19 : ObjectIsNotParent);
510 19 : heatPump.WaterOutletNodeNum = GetOnlySingleNode(state,
511 19 : AlphArray(5),
512 : ErrorsFound,
513 : DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpParameterEstimation,
514 19 : AlphArray(1),
515 : DataLoopNode::NodeFluidType::Water,
516 : DataLoopNode::ConnectionType::Outlet,
517 : NodeInputManager::CompFluidStream::Secondary,
518 19 : ObjectIsNotParent);
519 19 : heatPump.AirInletNodeNum = GetOnlySingleNode(state,
520 19 : AlphArray(6),
521 : ErrorsFound,
522 : DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpParameterEstimation,
523 19 : AlphArray(1),
524 : DataLoopNode::NodeFluidType::Air,
525 : DataLoopNode::ConnectionType::Inlet,
526 : NodeInputManager::CompFluidStream::Primary,
527 19 : ObjectIsNotParent);
528 19 : heatPump.AirOutletNodeNum = GetOnlySingleNode(state,
529 19 : AlphArray(7),
530 : ErrorsFound,
531 : DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpParameterEstimation,
532 19 : AlphArray(1),
533 : DataLoopNode::NodeFluidType::Air,
534 : DataLoopNode::ConnectionType::Outlet,
535 : NodeInputManager::CompFluidStream::Primary,
536 19 : ObjectIsNotParent);
537 :
538 19 : heatPump.LoadSideTotalUACoeff = NumArray(5);
539 19 : if (heatPump.LoadSideTotalUACoeff < DataGlobalConstants::rTinyValue) {
540 0 : ShowSevereError(state, "Input problem for " + CurrentModuleObject + '=' + heatPump.Name);
541 0 : ShowContinueError(state, " Load side UA value is less than tolerance, likely zero or blank.");
542 0 : ShowContinueError(state, " Verify inputs, as the parameter syntax for this object went through a change with");
543 0 : ShowContinueError(state, " the release of EnergyPlus version 5.");
544 0 : ErrorsFound = true;
545 : }
546 :
547 19 : heatPump.SuperheatTemp = NumArray(6);
548 19 : heatPump.PowerLosses = NumArray(7);
549 19 : heatPump.LossFactor = NumArray(8);
550 :
551 19 : heatPump.compressorType =
552 38 : static_cast<CompressorType>(getEnumerationValue(CompressTypeNamesUC, UtilityRoutines::MakeUPPERCase(AlphArray(2))));
553 19 : switch (heatPump.compressorType) {
554 0 : case CompressorType::Reciprocating: {
555 0 : heatPump.CompPistonDisp = NumArray(9);
556 0 : heatPump.CompSucPressDrop = NumArray(10);
557 0 : heatPump.CompClearanceFactor = NumArray(11);
558 0 : break;
559 : }
560 0 : case CompressorType::Rotary: {
561 0 : heatPump.CompPistonDisp = NumArray(9);
562 0 : heatPump.CompSucPressDrop = NumArray(10);
563 0 : break;
564 : }
565 19 : case CompressorType::Scroll: {
566 19 : heatPump.RefVolFlowRate = NumArray(12);
567 19 : heatPump.VolumeRatio = NumArray(13);
568 19 : heatPump.LeakRateCoeff = NumArray(14);
569 19 : break;
570 : }
571 0 : default: {
572 0 : ShowSevereError(
573 : state,
574 0 : format("{}Invalid {} ({}) entered. {}={}", RoutineName, cAlphaFields(2), AlphArray(2), CurrentModuleObject, heatPump.Name));
575 0 : ErrorsFound = true;
576 0 : break;
577 : }
578 : }
579 :
580 19 : heatPump.SourceSideUACoeff = NumArray(15);
581 19 : heatPump.SourceSideHTR1 = NumArray(16);
582 19 : heatPump.SourceSideHTR2 = NumArray(17);
583 :
584 19 : TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(4), AlphArray(5), "Water Nodes");
585 19 : TestCompSet(state, CurrentModuleObject, AlphArray(1), AlphArray(6), AlphArray(7), "Air Nodes");
586 :
587 : // CurrentModuleObject = "Coil:Heating:WaterToAirHeatPump:ParameterEstimation"
588 38 : SetupOutputVariable(state,
589 : "Heating Coil Electricity Energy",
590 : OutputProcessor::Unit::J,
591 : heatPump.Energy,
592 : OutputProcessor::SOVTimeStepType::System,
593 : OutputProcessor::SOVStoreType::Summed,
594 : heatPump.Name,
595 : _,
596 : "Electricity",
597 : "Heating",
598 : _,
599 19 : "System");
600 38 : SetupOutputVariable(state,
601 : "Heating Coil Heating Energy",
602 : OutputProcessor::Unit::J,
603 : heatPump.EnergyLoadTotal,
604 : OutputProcessor::SOVTimeStepType::System,
605 : OutputProcessor::SOVStoreType::Summed,
606 : heatPump.Name,
607 : _,
608 : "ENERGYTRANSFER",
609 : "HEATINGCOILS",
610 : _,
611 19 : "System");
612 38 : SetupOutputVariable(state,
613 : "Heating Coil Source Side Heat Transfer Energy",
614 : OutputProcessor::Unit::J,
615 : heatPump.EnergySource,
616 : OutputProcessor::SOVTimeStepType::System,
617 : OutputProcessor::SOVStoreType::Summed,
618 : heatPump.Name,
619 : _,
620 : "PLANTLOOPHEATINGDEMAND",
621 : "HEATINGCOILS",
622 : _,
623 19 : "System");
624 :
625 : // save the design source side flow rate for use by plant loop sizing algorithms
626 19 : RegisterPlantCompDesignFlow(state, heatPump.WaterInletNodeNum, 0.5 * heatPump.DesignWaterVolFlowRate);
627 :
628 : // create predefined report entries
629 19 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilType, heatPump.Name, CurrentModuleObject);
630 19 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, heatPump.Name, heatPump.HeatingCapacity);
631 19 : PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, heatPump.Name, "-");
632 : }
633 :
634 6 : AlphArray.deallocate();
635 6 : cAlphaFields.deallocate();
636 6 : lAlphaBlanks.deallocate();
637 6 : cNumericFields.deallocate();
638 6 : lNumericBlanks.deallocate();
639 6 : NumArray.deallocate();
640 :
641 6 : if (ErrorsFound) {
642 0 : ShowFatalError(state, format("{}Errors found getting input. Program terminates.", RoutineName));
643 : }
644 :
645 44 : for (HPNum = 1; HPNum <= state.dataWaterToAirHeatPump->NumWatertoAirHPs; ++HPNum) {
646 :
647 38 : auto &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
648 38 : if (heatPump.WAHPType == DataPlant::PlantEquipmentType::CoilWAHPCoolingParamEst) {
649 : // COOLING COIL: Setup Report variables for the Heat Pump
650 38 : SetupOutputVariable(state,
651 : "Cooling Coil Electricity Rate",
652 : OutputProcessor::Unit::W,
653 : heatPump.Power,
654 : OutputProcessor::SOVTimeStepType::System,
655 : OutputProcessor::SOVStoreType::Average,
656 19 : heatPump.Name);
657 :
658 38 : SetupOutputVariable(state,
659 : "Cooling Coil Total Cooling Rate",
660 : OutputProcessor::Unit::W,
661 : heatPump.QLoadTotal,
662 : OutputProcessor::SOVTimeStepType::System,
663 : OutputProcessor::SOVStoreType::Average,
664 19 : heatPump.Name);
665 :
666 38 : SetupOutputVariable(state,
667 : "Cooling Coil Sensible Cooling Rate",
668 : OutputProcessor::Unit::W,
669 : heatPump.QSensible,
670 : OutputProcessor::SOVTimeStepType::System,
671 : OutputProcessor::SOVStoreType::Average,
672 19 : heatPump.Name);
673 :
674 38 : SetupOutputVariable(state,
675 : "Cooling Coil Latent Cooling Rate",
676 : OutputProcessor::Unit::W,
677 : heatPump.QLatent,
678 : OutputProcessor::SOVTimeStepType::System,
679 : OutputProcessor::SOVStoreType::Average,
680 19 : heatPump.Name);
681 :
682 38 : SetupOutputVariable(state,
683 : "Cooling Coil Source Side Heat Transfer Rate",
684 : OutputProcessor::Unit::W,
685 : heatPump.QSource,
686 : OutputProcessor::SOVTimeStepType::System,
687 : OutputProcessor::SOVStoreType::Average,
688 19 : heatPump.Name);
689 :
690 38 : SetupOutputVariable(state,
691 : "Cooling Coil Part Load Ratio",
692 : OutputProcessor::Unit::None,
693 : heatPump.PartLoadRatio,
694 : OutputProcessor::SOVTimeStepType::System,
695 : OutputProcessor::SOVStoreType::Average,
696 19 : heatPump.Name);
697 38 : SetupOutputVariable(state,
698 : "Cooling Coil Runtime Fraction",
699 : OutputProcessor::Unit::None,
700 : heatPump.RunFrac,
701 : OutputProcessor::SOVTimeStepType::System,
702 : OutputProcessor::SOVStoreType::Average,
703 19 : heatPump.Name);
704 :
705 38 : SetupOutputVariable(state,
706 : "Cooling Coil Air Mass Flow Rate",
707 : OutputProcessor::Unit::kg_s,
708 : heatPump.OutletAirMassFlowRate,
709 : OutputProcessor::SOVTimeStepType::System,
710 : OutputProcessor::SOVStoreType::Average,
711 19 : heatPump.Name);
712 38 : SetupOutputVariable(state,
713 : "Cooling Coil Air Inlet Temperature",
714 : OutputProcessor::Unit::C,
715 : heatPump.InletAirDBTemp,
716 : OutputProcessor::SOVTimeStepType::System,
717 : OutputProcessor::SOVStoreType::Average,
718 19 : heatPump.Name);
719 38 : SetupOutputVariable(state,
720 : "Cooling Coil Air Inlet Humidity Ratio",
721 : OutputProcessor::Unit::kgWater_kgDryAir,
722 : heatPump.InletAirHumRat,
723 : OutputProcessor::SOVTimeStepType::System,
724 : OutputProcessor::SOVStoreType::Average,
725 19 : heatPump.Name);
726 38 : SetupOutputVariable(state,
727 : "Cooling Coil Air Outlet Temperature",
728 : OutputProcessor::Unit::C,
729 : heatPump.OutletAirDBTemp,
730 : OutputProcessor::SOVTimeStepType::System,
731 : OutputProcessor::SOVStoreType::Average,
732 19 : heatPump.Name);
733 38 : SetupOutputVariable(state,
734 : "Cooling Coil Air Outlet Humidity Ratio",
735 : OutputProcessor::Unit::kgWater_kgDryAir,
736 : heatPump.OutletAirHumRat,
737 : OutputProcessor::SOVTimeStepType::System,
738 : OutputProcessor::SOVStoreType::Average,
739 19 : heatPump.Name);
740 :
741 38 : SetupOutputVariable(state,
742 : "Cooling Coil Source Side Mass Flow Rate",
743 : OutputProcessor::Unit::kg_s,
744 : heatPump.OutletWaterMassFlowRate,
745 : OutputProcessor::SOVTimeStepType::System,
746 : OutputProcessor::SOVStoreType::Average,
747 19 : heatPump.Name);
748 38 : SetupOutputVariable(state,
749 : "Cooling Coil Source Side Inlet Temperature",
750 : OutputProcessor::Unit::C,
751 : heatPump.InletWaterTemp,
752 : OutputProcessor::SOVTimeStepType::System,
753 : OutputProcessor::SOVStoreType::Average,
754 19 : heatPump.Name);
755 38 : SetupOutputVariable(state,
756 : "Cooling Coil Source Side Outlet Temperature",
757 : OutputProcessor::Unit::C,
758 : heatPump.OutletWaterTemp,
759 : OutputProcessor::SOVTimeStepType::System,
760 : OutputProcessor::SOVStoreType::Average,
761 19 : heatPump.Name);
762 19 : } else if (heatPump.WAHPType == DataPlant::PlantEquipmentType::CoilWAHPHeatingParamEst) {
763 : // HEATING COIL Setup Report variables for the Heat Pump
764 38 : SetupOutputVariable(state,
765 : "Heating Coil Electricity Rate",
766 : OutputProcessor::Unit::W,
767 : heatPump.Power,
768 : OutputProcessor::SOVTimeStepType::System,
769 : OutputProcessor::SOVStoreType::Average,
770 19 : heatPump.Name);
771 :
772 38 : SetupOutputVariable(state,
773 : "Heating Coil Heating Rate",
774 : OutputProcessor::Unit::W,
775 : heatPump.QLoadTotal,
776 : OutputProcessor::SOVTimeStepType::System,
777 : OutputProcessor::SOVStoreType::Average,
778 19 : heatPump.Name);
779 :
780 38 : SetupOutputVariable(state,
781 : "Heating Coil Sensible Heating Rate",
782 : OutputProcessor::Unit::W,
783 : heatPump.QSensible,
784 : OutputProcessor::SOVTimeStepType::System,
785 : OutputProcessor::SOVStoreType::Average,
786 19 : heatPump.Name);
787 :
788 38 : SetupOutputVariable(state,
789 : "Heating Coil Source Side Heat Transfer Rate",
790 : OutputProcessor::Unit::W,
791 : heatPump.QSource,
792 : OutputProcessor::SOVTimeStepType::System,
793 : OutputProcessor::SOVStoreType::Average,
794 19 : heatPump.Name);
795 :
796 38 : SetupOutputVariable(state,
797 : "Heating Coil Part Load Ratio",
798 : OutputProcessor::Unit::None,
799 : heatPump.PartLoadRatio,
800 : OutputProcessor::SOVTimeStepType::System,
801 : OutputProcessor::SOVStoreType::Average,
802 19 : heatPump.Name);
803 38 : SetupOutputVariable(state,
804 : "Heating Coil Runtime Fraction",
805 : OutputProcessor::Unit::None,
806 : heatPump.RunFrac,
807 : OutputProcessor::SOVTimeStepType::System,
808 : OutputProcessor::SOVStoreType::Average,
809 19 : heatPump.Name);
810 :
811 38 : SetupOutputVariable(state,
812 : "Heating Coil Air Mass Flow Rate",
813 : OutputProcessor::Unit::kg_s,
814 : heatPump.OutletAirMassFlowRate,
815 : OutputProcessor::SOVTimeStepType::System,
816 : OutputProcessor::SOVStoreType::Average,
817 19 : heatPump.Name);
818 38 : SetupOutputVariable(state,
819 : "Heating Coil Air Inlet Temperature",
820 : OutputProcessor::Unit::C,
821 : heatPump.InletAirDBTemp,
822 : OutputProcessor::SOVTimeStepType::System,
823 : OutputProcessor::SOVStoreType::Average,
824 19 : heatPump.Name);
825 38 : SetupOutputVariable(state,
826 : "Heating Coil Air Inlet Humidity Ratio",
827 : OutputProcessor::Unit::kgWater_kgDryAir,
828 : heatPump.InletAirHumRat,
829 : OutputProcessor::SOVTimeStepType::System,
830 : OutputProcessor::SOVStoreType::Average,
831 19 : heatPump.Name);
832 38 : SetupOutputVariable(state,
833 : "Heating Coil Air Outlet Temperature",
834 : OutputProcessor::Unit::C,
835 : heatPump.OutletAirDBTemp,
836 : OutputProcessor::SOVTimeStepType::System,
837 : OutputProcessor::SOVStoreType::Average,
838 19 : heatPump.Name);
839 38 : SetupOutputVariable(state,
840 : "Heating Coil Air Outlet Humidity Ratio",
841 : OutputProcessor::Unit::kgWater_kgDryAir,
842 : heatPump.OutletAirHumRat,
843 : OutputProcessor::SOVTimeStepType::System,
844 : OutputProcessor::SOVStoreType::Average,
845 19 : heatPump.Name);
846 :
847 38 : SetupOutputVariable(state,
848 : "Heating Coil Source Side Mass Flow Rate",
849 : OutputProcessor::Unit::kg_s,
850 : heatPump.OutletWaterMassFlowRate,
851 : OutputProcessor::SOVTimeStepType::System,
852 : OutputProcessor::SOVStoreType::Average,
853 19 : heatPump.Name);
854 38 : SetupOutputVariable(state,
855 : "Heating Coil Source Side Inlet Temperature",
856 : OutputProcessor::Unit::C,
857 : heatPump.InletWaterTemp,
858 : OutputProcessor::SOVTimeStepType::System,
859 : OutputProcessor::SOVStoreType::Average,
860 19 : heatPump.Name);
861 38 : SetupOutputVariable(state,
862 : "Heating Coil Source Side Outlet Temperature",
863 : OutputProcessor::Unit::C,
864 : heatPump.OutletWaterTemp,
865 : OutputProcessor::SOVTimeStepType::System,
866 : OutputProcessor::SOVStoreType::Average,
867 19 : heatPump.Name);
868 : }
869 : }
870 6 : }
871 :
872 2046263 : void InitWatertoAirHP(EnergyPlusData &state,
873 : int const HPNum, // index to main heat pump data structure
874 : bool const InitFlag,
875 : Real64 const MaxONOFFCyclesperHour, // Maximum cycling rate of heat pump [cycles/hr]
876 : Real64 const HPTimeConstant, // Heat pump time constant [s]
877 : Real64 const FanDelayTime, // Fan delay time, time delay for the HP's fan to
878 : Real64 const SensLoad,
879 : Real64 const LatentLoad,
880 : Real64 const DesignAirFlow,
881 : Real64 const PartLoadRatio)
882 : {
883 :
884 : // SUBROUTINE INFORMATION:
885 : // AUTHOR Hui Jin
886 : // DATE WRITTEN Oct 2000
887 : // MODIFIED Dan Fisher, Kenneth Tang (Jan 2004)
888 : // Brent Griffith, Sept 2010, plant upgrades, general fluid properties
889 :
890 : // RE-ENGINEERED na
891 :
892 : // PURPOSE OF THIS SUBROUTINE:
893 : // This subroutine is for initializations of the Water to Air HP Components.
894 :
895 : // METHODOLOGY EMPLOYED:
896 : // Uses the status flags to trigger initializations.
897 :
898 : // Using/Aliasing
899 : using FluidProperties::GetDensityGlycol;
900 : using FluidProperties::GetSpecificHeatGlycol;
901 : using PlantUtilities::InitComponentNodes;
902 : using PlantUtilities::ScanPlantLoopsForObject;
903 : using PlantUtilities::SetComponentFlowRate;
904 2046263 : auto &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
905 :
906 : // Locals
907 : // SUBROUTINE ARGUMENT DEFINITIONS:
908 : // shut off after compressor cycle off [s]
909 :
910 : // SUBROUTINE PARAMETER DEFINITIONS:
911 : // REAL(r64), PARAMETER :: CpWater=4210.d0 ! Specific heat of water J/kg_C
912 : static constexpr std::string_view RoutineName("InitWatertoAirHP");
913 :
914 : // INTERFACE BLOCK SPECIFICATIONS
915 : // na
916 :
917 : // DERIVED TYPE DEFINITIONS
918 : // na
919 :
920 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
921 : int AirInletNode; // air inlet node number
922 : int WaterInletNode; // water inlet node number
923 : int PlantOutletNode;
924 : Real64 rho; // local fluid density
925 : Real64 Cp; // local fluid specific heat
926 : bool errFlag;
927 :
928 2046263 : if (state.dataWaterToAirHeatPump->MyOneTimeFlag) {
929 6 : state.dataWaterToAirHeatPump->MyEnvrnFlag.allocate(state.dataWaterToAirHeatPump->NumWatertoAirHPs);
930 6 : state.dataWaterToAirHeatPump->MyPlantScanFlag.allocate(state.dataWaterToAirHeatPump->NumWatertoAirHPs);
931 6 : state.dataWaterToAirHeatPump->MyEnvrnFlag = true;
932 6 : state.dataWaterToAirHeatPump->MyPlantScanFlag = true;
933 6 : state.dataWaterToAirHeatPump->MyOneTimeFlag = false;
934 : }
935 :
936 2046263 : if (state.dataWaterToAirHeatPump->MyPlantScanFlag(HPNum) && allocated(state.dataPlnt->PlantLoop)) {
937 38 : errFlag = false;
938 38 : ScanPlantLoopsForObject(state, heatPump.Name, heatPump.WAHPType, heatPump.plantLoc, errFlag, _, _, _, _, _);
939 :
940 38 : if (state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).FluidName == "WATER") {
941 34 : if (heatPump.SourceSideUACoeff < DataGlobalConstants::rTinyValue) {
942 0 : ShowSevereError(state, "Input problem for water to air heat pump, \"" + heatPump.Name + "\".");
943 0 : ShowContinueError(state, " Source side UA value is less than tolerance, likely zero or blank.");
944 0 : ShowContinueError(state, " Verify inputs, as the parameter syntax for this object went through a change with");
945 0 : ShowContinueError(state, " the release of EnergyPlus version 5.");
946 0 : errFlag = true;
947 : }
948 : } else {
949 4 : if ((heatPump.SourceSideHTR1 < DataGlobalConstants::rTinyValue) || (heatPump.SourceSideHTR2 < DataGlobalConstants::rTinyValue)) {
950 0 : ShowSevereError(state, "Input problem for water to air heat pump, \"" + heatPump.Name + "\".");
951 0 : ShowContinueError(state, " A source side heat transfer resistance value is less than tolerance, likely zero or blank.");
952 0 : ShowContinueError(state, " Verify inputs, as the parameter syntax for this object went through a change with");
953 0 : ShowContinueError(state, " the release of EnergyPlus version 5.");
954 0 : errFlag = true;
955 : }
956 : }
957 :
958 38 : if (errFlag) {
959 0 : ShowFatalError(state, "InitWatertoAirHP: Program terminated for previous conditions.");
960 : }
961 :
962 38 : state.dataWaterToAirHeatPump->MyPlantScanFlag(HPNum) = false;
963 : }
964 :
965 : // Do the Begin Environment initializations
966 2046483 : if (state.dataGlobal->BeginEnvrnFlag && state.dataWaterToAirHeatPump->MyEnvrnFlag(HPNum) &&
967 220 : !state.dataWaterToAirHeatPump->MyPlantScanFlag(HPNum)) {
968 : // Do the initializations to start simulation
969 : // Set water and air inlet nodes
970 220 : AirInletNode = heatPump.AirInletNodeNum;
971 220 : WaterInletNode = heatPump.WaterInletNodeNum;
972 :
973 : // Initialize all report variables to a known state at beginning of simulation
974 220 : heatPump.Power = 0.0;
975 220 : heatPump.Energy = 0.0;
976 220 : heatPump.QLoadTotal = 0.0;
977 220 : heatPump.QSensible = 0.0;
978 220 : heatPump.QLatent = 0.0;
979 220 : heatPump.QSource = 0.0;
980 220 : heatPump.EnergyLoadTotal = 0.0;
981 220 : heatPump.EnergySensible = 0.0;
982 220 : heatPump.EnergyLatent = 0.0;
983 220 : heatPump.EnergySource = 0.0;
984 220 : heatPump.RunFrac = 0.0;
985 220 : heatPump.PartLoadRatio = 0.0;
986 220 : heatPump.OutletAirDBTemp = 0.0;
987 220 : heatPump.OutletAirHumRat = 0.0;
988 220 : heatPump.InletAirDBTemp = 0.0;
989 220 : heatPump.InletAirHumRat = 0.0;
990 220 : heatPump.OutletWaterTemp = 0.0;
991 220 : heatPump.InletWaterTemp = 0.0;
992 220 : heatPump.InletAirMassFlowRate = 0.0;
993 220 : heatPump.InletWaterMassFlowRate = 0.0;
994 220 : heatPump.OutletAirEnthalpy = 0.0;
995 220 : heatPump.OutletWaterEnthalpy = 0.0;
996 :
997 : // The rest of the one time initializations
998 440 : rho = GetDensityGlycol(state,
999 220 : state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).FluidName,
1000 : DataGlobalConstants::InitConvTemp,
1001 220 : state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).FluidIndex,
1002 : RoutineName);
1003 440 : Cp = GetSpecificHeatGlycol(state,
1004 220 : state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).FluidName,
1005 : DataGlobalConstants::InitConvTemp,
1006 220 : state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).FluidIndex,
1007 : RoutineName);
1008 :
1009 220 : heatPump.DesignWaterMassFlowRate = rho * heatPump.DesignWaterVolFlowRate;
1010 220 : heatPump.MaxONOFFCyclesperHour = MaxONOFFCyclesperHour;
1011 220 : heatPump.HPTimeConstant = HPTimeConstant;
1012 220 : heatPump.FanDelayTime = FanDelayTime;
1013 :
1014 220 : PlantOutletNode = DataPlant::CompData::getPlantComponent(state, heatPump.plantLoc).NodeNumOut;
1015 220 : InitComponentNodes(state, 0.0, heatPump.DesignWaterMassFlowRate, WaterInletNode, PlantOutletNode);
1016 :
1017 220 : state.dataLoopNodes->Node(WaterInletNode).Temp = 5.0;
1018 220 : state.dataLoopNodes->Node(WaterInletNode).Enthalpy = Cp * state.dataLoopNodes->Node(WaterInletNode).Temp;
1019 220 : state.dataLoopNodes->Node(WaterInletNode).Quality = 0.0;
1020 220 : state.dataLoopNodes->Node(WaterInletNode).Press = 0.0;
1021 220 : state.dataLoopNodes->Node(WaterInletNode).HumRat = 0.0;
1022 :
1023 220 : state.dataLoopNodes->Node(PlantOutletNode).Temp = 5.0;
1024 220 : state.dataLoopNodes->Node(PlantOutletNode).Enthalpy = Cp * state.dataLoopNodes->Node(WaterInletNode).Temp;
1025 220 : state.dataLoopNodes->Node(PlantOutletNode).Quality = 0.0;
1026 220 : state.dataLoopNodes->Node(PlantOutletNode).Press = 0.0;
1027 220 : state.dataLoopNodes->Node(PlantOutletNode).HumRat = 0.0;
1028 :
1029 220 : heatPump.SimFlag = true;
1030 :
1031 220 : state.dataWaterToAirHeatPump->MyEnvrnFlag(HPNum) = false;
1032 : } // End If for the Begin Environment initializations
1033 :
1034 2046263 : if (!state.dataGlobal->BeginEnvrnFlag) {
1035 2045262 : state.dataWaterToAirHeatPump->MyEnvrnFlag(HPNum) = true;
1036 : }
1037 :
1038 : // Do the following initializations (every time step): This should be the info from
1039 : // the previous components outlets or the node data in this section.
1040 : // First set the conditions for the air into the heat pump model
1041 :
1042 : // Set water and air inlet nodes
1043 2046263 : AirInletNode = heatPump.AirInletNodeNum;
1044 2046263 : WaterInletNode = heatPump.WaterInletNodeNum;
1045 :
1046 : // ! Set heat pump simulation flag to false if the air loop and water loop conditions have not changed
1047 : // IF( .NOT. (BeginEnvrnFlag .and. MyEnvrnFlag) .AND. (&
1048 : // WatertoAirHP(HPNum)%InletWaterTemp >= (Node(WaterInletNode)%Temp + TempTOL) .OR. &
1049 : // WatertoAirHP(HPNum)%InletWaterTemp <= (Node(WaterInletNode)%Temp - TempTOL) .OR. &
1050 : // WatertoAirHP(HPNum)%InletWaterEnthalpy >= (Node(WaterInletNode)%Enthalpy + EnthTOL) .OR. &
1051 : // WatertoAirHP(HPNum)%InletWaterEnthalpy <= (Node(WaterInletNode)%Enthalpy - EnthTOL) .OR. &!!
1052 :
1053 : // WatertoAirHP(HPNum)%InletAirDBTemp >= (Node(AirInletNode)%Temp + TempTOL) .OR. &
1054 : // WatertoAirHP(HPNum)%InletAirDBTemp <= (Node(AirInletNode)%Temp - TempTOL) .OR. &
1055 : // WatertoAirHP(HPNum)%InletAirHumRat >= (Node(AirInletNode)%HumRat + HumRatTOL) .OR. &
1056 : // WatertoAirHP(HPNum)%InletAirHumRat <= (Node(AirInletNode)%HumRat - HumRatTOL) .OR. &
1057 : // WatertoAirHP(HPNum)%InletAirEnthalpy >= (Node(AirInletNode)%Enthalpy + EnthTOL) .OR. &
1058 : // WatertoAirHP(HPNum)%InletAirEnthalpy <= (Node(AirInletNode)%Enthalpy - EnthTOL) .OR. &
1059 : // WatertoAirHP(HPNum)%InletAirMassFlowRate > 0.0))THEN
1060 : // WatertoAirHP(HPNum)%SimFlag =.TRUE.
1061 : // ELSE
1062 : // WatertoAirHP(HPNum)%SimFlag =.FALSE.
1063 : // ENDIF
1064 :
1065 2046263 : if (((SensLoad != 0.0 || LatentLoad != 0.0) || (SensLoad == 0.0 && InitFlag)) && state.dataLoopNodes->Node(AirInletNode).MassFlowRate > 0.0 &&
1066 : PartLoadRatio > 0.0) {
1067 : // set the water side flow rate to the design flow rate unless constrained by
1068 : // the demand side manager (MIN/MAX available). now done by call to setcomponentFlowRate
1069 746155 : heatPump.InletWaterMassFlowRate = heatPump.DesignWaterMassFlowRate;
1070 746155 : heatPump.InletAirMassFlowRate = DesignAirFlow; // This is required instead of the node temperature
1071 : // because the air loop operates handles part load for
1072 : // cycling equipment by modulating the air flow rate
1073 : // the heat pump model requires an accurate (i.e. full load
1074 : // flow rate for accurate simulation.
1075 : } else { // heat pump is off
1076 1300108 : heatPump.InletWaterMassFlowRate = 0.0;
1077 :
1078 1300108 : heatPump.InletAirMassFlowRate = 0.0;
1079 : }
1080 : // constrain water flow provided by plant
1081 2046263 : SetComponentFlowRate(state, heatPump.InletWaterMassFlowRate, heatPump.WaterInletNodeNum, heatPump.WaterOutletNodeNum, heatPump.plantLoc);
1082 :
1083 2046263 : heatPump.InletWaterTemp = state.dataLoopNodes->Node(WaterInletNode).Temp;
1084 : // IF (WatertoAirHP(HPNum)%InletWaterTemp < 0.0) THEN ! Debug trap
1085 : // Temptemp = Node(WaterInletNode)%Temp
1086 : // ENDIF
1087 2046263 : heatPump.InletWaterEnthalpy = state.dataLoopNodes->Node(WaterInletNode).Enthalpy;
1088 :
1089 2046263 : heatPump.InletAirDBTemp = state.dataLoopNodes->Node(AirInletNode).Temp;
1090 2046263 : heatPump.InletAirHumRat = state.dataLoopNodes->Node(AirInletNode).HumRat;
1091 2046263 : heatPump.InletAirEnthalpy = state.dataLoopNodes->Node(AirInletNode).Enthalpy;
1092 :
1093 2046263 : heatPump.Power = 0.0;
1094 2046263 : heatPump.Energy = 0.0;
1095 2046263 : heatPump.QLoadTotal = 0.0;
1096 2046263 : heatPump.QSensible = 0.0;
1097 2046263 : heatPump.QLatent = 0.0;
1098 2046263 : heatPump.QSource = 0.0;
1099 2046263 : heatPump.EnergyLoadTotal = 0.0;
1100 2046263 : heatPump.EnergySensible = 0.0;
1101 2046263 : heatPump.EnergyLatent = 0.0;
1102 2046263 : heatPump.EnergySource = 0.0;
1103 2046263 : heatPump.RunFrac = 0.0;
1104 2046263 : heatPump.OutletAirDBTemp = 0.0;
1105 2046263 : heatPump.OutletAirHumRat = 0.0;
1106 2046263 : heatPump.OutletWaterTemp = 0.0;
1107 2046263 : heatPump.OutletAirEnthalpy = 0.0;
1108 2046263 : heatPump.OutletWaterEnthalpy = 0.0;
1109 2046263 : }
1110 :
1111 1023134 : void CalcWatertoAirHPCooling(EnergyPlusData &state,
1112 : int const HPNum, // heat pump number
1113 : int const CyclingScheme, // fan/compressor cycling scheme indicator
1114 : bool const FirstHVACIteration, // first iteration flag
1115 : Real64 const RuntimeFrac,
1116 : [[maybe_unused]] bool const InitFlag, // suppress property errors if true
1117 : Real64 const SensDemand,
1118 : DataHVACGlobals::CompressorOperation const CompressorOp,
1119 : Real64 const PartLoadRatio)
1120 : {
1121 :
1122 : // SUBROUTINE INFORMATION:
1123 : // AUTHOR Hui Jin
1124 : // DATE WRITTEN Oct 2000
1125 : // MODIFIED Dan Fisher, Kenneth Tang (Jan 2004), R. Raustad (Oct 2006) Revised iteration technique
1126 : // RE-ENGINEERED na
1127 :
1128 : // PURPOSE OF THIS SUBROUTINE:
1129 : // Simulates a parameter estimation based water to air heat pump model
1130 :
1131 : // Using/Aliasing
1132 : using namespace FluidProperties;
1133 : using General::SolveRoot;
1134 : using Psychrometrics::PsyCpAirFnW;
1135 : using Psychrometrics::PsyHFnTdbW; // ,PsyHFnTdbRhPb,PsyWFnTdpPb
1136 : using Psychrometrics::PsyTdbFnHW;
1137 : using Psychrometrics::PsyTsatFnHPb;
1138 : using Psychrometrics::PsyTwbFnTdbWPb;
1139 : using Psychrometrics::PsyWFnTdbH;
1140 1023134 : auto &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
1141 :
1142 : // SUBROUTINE PARAMETER DEFINITIONS:
1143 1023134 : constexpr Real64 CpWater(4210.0); // Specific heat of water J/kg_C
1144 1023134 : constexpr Real64 DegreeofSuperheat(80.0); // Initial guess of degree of superheat
1145 1023134 : constexpr Real64 gamma(1.114); // Expansion Coefficient
1146 1023134 : constexpr Real64 ERR(0.01); // Error Value
1147 1023134 : constexpr Real64 PB(1.013e5); // Barometric Pressure (Pa)
1148 :
1149 1023134 : constexpr int STOP1(1000); // Iteration stopper1
1150 1023134 : constexpr int STOP2(1000); // Iteration stopper2
1151 1023134 : constexpr int STOP3(1000); // Iteration stopper3
1152 :
1153 : static constexpr std::string_view RoutineNameSourceSideInletTemp("CalcWatertoAirHPCooling:SourceSideInletTemp");
1154 : static constexpr std::string_view RoutineNameSourceSideTemp("CalcWatertoAirHPCooling:SourceSideTemp");
1155 : static constexpr std::string_view RoutineNameLoadSideTemp("CalcWatertoAirHPCooling:LoadSideTemp");
1156 : static constexpr std::string_view RoutineNameLoadSideSurfaceTemp("CalcWatertoAirHPCooling:LoadSideSurfaceTemp");
1157 : static constexpr std::string_view RoutineNameLoadSideEvapTemp("CalcWatertoAirHPCooling:LoadSideEvapTemp");
1158 : static constexpr std::string_view RoutineNameLoadSideOutletEnthalpy("CalcWatertoAirHPCooling:LoadSideOutletEnthalpy");
1159 : static constexpr std::string_view RoutineNameCompressInletTemp("CalcWatertoAirHPCooling:CompressInletTemp");
1160 : static constexpr std::string_view RoutineNameSuctionPr("CalcWatertoAirHPCooling:SuctionPr");
1161 : static constexpr std::string_view RoutineNameCompSuctionTemp("CalcWatertoAirHPCooling:CompSuctionTemp");
1162 :
1163 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1164 : int NumIteration2; // Number of Iteration2
1165 : int NumIteration3; // Number of Iteration3
1166 : int NumIteration4; // Number of Iteration4 (use of latent degradation model ONLY)
1167 : int SourceSideFluidIndex; // Source Side Fluid Index
1168 1300984 : std::string SourceSideFluidName; // Name of source side fluid
1169 : Real64 Quality; // Quality of Refrigerant
1170 : Real64 SourceSideOutletTemp; // Source Side Outlet Temperature [C]
1171 : Real64 SourceSideVolFlowRate; // Source Side Volumetric Flow Rate [m3/s]
1172 : Real64 DegradFactor; // Degradation Factor [~]
1173 : Real64 CpFluid; // Specific heat of source side fluid(J/kg)
1174 : Real64 LoadSideInletWBTemp; // Wet-bulb temperature of indoor inlet air [C]
1175 : Real64 LoadSideInletDBTemp; // Load Side Inlet Dry Bulb Temp [C]
1176 : Real64 LoadSideInletHumRat; // Load Side Inlet Humidity Ratio [kg/kg]
1177 : Real64 LoadSideOutletDBTemp; // Load Side Outlet Dry Bulb Temperature [C]
1178 : Real64 LoadSideOutletHumRat; // Load Side Outlet Humidity Ratio [kg/kg]
1179 : Real64 LoadSideAirInletEnth; // Load Side Inlet Enthalpy [J/kg]
1180 : Real64 LoadSideAirOutletEnth; // Load Side Outlet Enthalpy [J/kg]
1181 : Real64 EffectiveSurfaceTemp; // Effective Surface Temperature [C]
1182 : Real64 EffectiveSatEnth; // Saturated Enthalpy of Air Corresponding to the Effective Surface Temperature [J/kg]
1183 : Real64 QSource; // Source Side Heat Transfer Rate [W]
1184 : Real64 QLoadTotal; // Load Side Total Heat Transfer Rate [W]
1185 : Real64 QSensible; // Load Side Sensible Heat Transfer Rate [W]
1186 : Real64 Power; // Power Consumption [W]
1187 : Real64 EvapTemp; // Evaporating Temperature [C]
1188 : Real64 ANTUWET; // Number of Transfer Unit for Wet Condition
1189 : Real64 EffectWET; // Load Side Heat Exchanger Effectiveness
1190 : Real64 EvapSatEnth; // Saturated Enthalpy of Air Corresponding to the Evaporating Temperature [J/kg]
1191 : Real64 SourceSideEffect; // Source Side Heat Exchanger Effectiveness
1192 : Real64 SourceSideTemp; // Source Side Saturated Refrigerant Temperature [C]
1193 : Real64 LoadSideTemp; // Load Side Saturated Refrigerant Temperature [C]
1194 : Real64 SourceSidePressure; // Source Side Saturated Refrigerant Pressure [Pa]
1195 : Real64 LoadSidePressure; // Load Side Saturated Refrigerant Pressure [Pa]
1196 : Real64 SuctionPr; // Compressor Suction Pressure [Pa]
1197 : Real64 DischargePr; // Compressor Discharge Pressure [Pa]
1198 : Real64 CompressInletTemp; // Temperature of the Refrigerant Entering the Compressor [C]
1199 : Real64 MassRef; // Mass Flow Rate of Refrigerant [kg/s]
1200 : Real64 SourceSideOutletEnth; // Enthalpy of Refrigerant leaving the Source Side Heat Exchanger [J/kg]
1201 : Real64 LoadSideOutletEnth; // Enthalpy of Refrigerant leaving the Load Side Heat Exchanger [J/kg]
1202 : Real64 CpAir; // Specific Heat of Air [J/kg_C]
1203 : Real64 SuperHeatEnth; // Enthalpy of the Superheated Refrigerant [J/kg]
1204 : Real64 CompSuctionTemp1; // Guess of the Temperature of the Refrigerant Entering the Compressor #1 [C]
1205 : Real64 CompSuctionTemp2; // Guess of the Temperature of the Refrigerant Entering the Compressor #2 [C]
1206 : Real64 CompSuctionEnth; // Enthalpy of the Refrigerant Entering the Compressor [J/kg]
1207 : Real64 CompSuctionDensity; // Density of the Refrigerant Entering the Compressor [kg/m3]
1208 : Real64 CompSuctionSatTemp; // Temperature of Saturated Refrigerant at Compressor Suction Pressure [C]
1209 : bool LatDegradModelSimFlag; // Latent degradation model simulation flag
1210 : bool StillSimulatingFlag; // Final Simulation Flag
1211 : bool Converged; // overall convergence Flag
1212 : Real64 QLatRated; // Qlatent at rated conditions of indoor(TDB,TWB)=(26.7C,19.4C)
1213 : Real64 QLatActual; // Qlatent at actual operating conditions
1214 : Real64 SHRss; // Sensible heat ratio at steady state
1215 : Real64 SHReff; // Effective sensible heat ratio at part-load condition
1216 : int SolFlag; // Solution flag returned from RegulaFalsi function
1217 : Real64 LoadSideAirInletEnth_Unit; // calc conditions for unit
1218 : Real64 LoadResidual; // loop convergence criteria
1219 : Real64 SourceResidual; // loop convergence criteria
1220 1023134 : Real64 RelaxParam(0.5); // Relaxation Parameter
1221 :
1222 1023134 : if (state.dataWaterToAirHeatPump->firstTime) {
1223 : // Set indoor air conditions to the rated condition
1224 6 : state.dataWaterToAirHeatPump->LoadSideInletDBTemp_Init = 26.7;
1225 6 : state.dataWaterToAirHeatPump->LoadSideInletHumRat_Init = 0.0111;
1226 6 : state.dataWaterToAirHeatPump->LoadSideAirInletEnth_Init =
1227 6 : PsyHFnTdbW(state.dataWaterToAirHeatPump->LoadSideInletDBTemp_Init, state.dataWaterToAirHeatPump->LoadSideInletHumRat_Init);
1228 6 : state.dataWaterToAirHeatPump->firstTime = false;
1229 : }
1230 :
1231 : // SET LOCAL VARIABLES FROM DATA STRUCTURE (for code readability)
1232 : // Set indoor air conditions to the actual condition
1233 1023134 : CpAir = PsyCpAirFnW(heatPump.InletAirHumRat);
1234 1023134 : LoadSideAirInletEnth_Unit = PsyHFnTdbW(heatPump.InletAirDBTemp, heatPump.InletAirHumRat);
1235 1023134 : SourceSideFluidName = state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).FluidName;
1236 1023134 : SourceSideFluidIndex = state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).FluidIndex;
1237 1023134 : SourceSideVolFlowRate =
1238 1023134 : heatPump.InletWaterMassFlowRate /
1239 1023134 : GetDensityGlycol(state, SourceSideFluidName, heatPump.InletWaterTemp, SourceSideFluidIndex, RoutineNameSourceSideInletTemp);
1240 :
1241 1023134 : StillSimulatingFlag = true;
1242 :
1243 : // If heat pump is not operating, return
1244 1023134 : if (SensDemand == 0.0 || heatPump.InletAirMassFlowRate <= 0.0 || heatPump.InletWaterMassFlowRate <= 0.0) {
1245 745284 : heatPump.SimFlag = false;
1246 745284 : return;
1247 : } else {
1248 277850 : heatPump.SimFlag = true;
1249 : }
1250 :
1251 277850 : if (CompressorOp == DataHVACGlobals::CompressorOperation::Off) {
1252 0 : heatPump.SimFlag = false;
1253 0 : return;
1254 : }
1255 :
1256 277850 : if (FirstHVACIteration) {
1257 59450 : state.dataWaterToAirHeatPump->initialQSource_calc = heatPump.CoolingCapacity;
1258 59450 : state.dataWaterToAirHeatPump->initialQLoadTotal_calc = heatPump.CoolingCapacity;
1259 : }
1260 :
1261 277850 : if (state.dataWaterToAirHeatPump->initialQLoadTotal_calc == 0.0)
1262 0 : state.dataWaterToAirHeatPump->initialQLoadTotal_calc = heatPump.CoolingCapacity;
1263 277850 : if (state.dataWaterToAirHeatPump->initialQSource_calc == 0.0) state.dataWaterToAirHeatPump->initialQSource_calc = heatPump.CoolingCapacity;
1264 :
1265 : // Loop the calculation at least twice depending whether the latent degradation model
1266 : // is enabled. 1st iteration to calculate the QLatent(rated) at (TDB,TWB)indoorair=(26.7C,19.4C)
1267 : // and 2nd iteration to calculate the QLatent(actual)
1268 :
1269 277850 : QLatRated = 0.0;
1270 277850 : QLatActual = 0.0;
1271 : // IF((RuntimeFrac .GE. 1.0) .OR. (Twet_rated .LE. 0.0) .OR. (Gamma_rated .LE. 0.0)) THEN
1272 : // Cycling fan does not required latent degradation model, only the constant fan case
1273 277850 : if ((RuntimeFrac >= 1.0) || (heatPump.Twet_Rated <= 0.0) || (heatPump.Gamma_Rated <= 0.0) || (CyclingScheme == CycFanCycCoil)) {
1274 277850 : LatDegradModelSimFlag = false;
1275 : // Set NumIteration4=1 so that latent model would quit after 1 simulation with the actual condition
1276 277850 : NumIteration4 = 1;
1277 : } else {
1278 0 : LatDegradModelSimFlag = true;
1279 : // Set NumIteration4=0 so that latent model would simulate twice with rated and actual condition
1280 0 : NumIteration4 = 0;
1281 : }
1282 :
1283 : // Tuned Hoisted quantities out of nested loop that don't change
1284 277850 : Real64 const LoadSideMassFlowRate_CpAir_inv(1.0 / (heatPump.InletAirMassFlowRate * CpAir));
1285 : Real64 const LoadSideEffec(1.0 -
1286 277850 : std::exp(-heatPump.LoadSideOutsideUACoeff *
1287 277850 : LoadSideMassFlowRate_CpAir_inv)); // Load Side Effectiveness based on Outside Heat Transfer Coefficient
1288 277850 : Real64 const LoadSideEffec_MassFlowRate_inv(1.0 / (LoadSideEffec * heatPump.InletAirMassFlowRate));
1289 277850 : ANTUWET = heatPump.LoadSideTotalUACoeff * LoadSideMassFlowRate_CpAir_inv;
1290 277850 : EffectWET = 1.0 - std::exp(-ANTUWET);
1291 :
1292 : while (true) {
1293 277850 : ++NumIteration4;
1294 277850 : if (NumIteration4 == 1) {
1295 : // Set indoor air conditions to the rated condition
1296 0 : LoadSideInletDBTemp = state.dataWaterToAirHeatPump->LoadSideInletDBTemp_Init;
1297 0 : LoadSideInletHumRat = state.dataWaterToAirHeatPump->LoadSideInletHumRat_Init;
1298 0 : LoadSideAirInletEnth = state.dataWaterToAirHeatPump->LoadSideAirInletEnth_Init;
1299 : } else {
1300 : // Set indoor air conditions to the actual condition
1301 277850 : LoadSideInletDBTemp = heatPump.InletAirDBTemp;
1302 277850 : LoadSideInletHumRat = heatPump.InletAirHumRat;
1303 277850 : LoadSideAirInletEnth = LoadSideAirInletEnth_Unit;
1304 : }
1305 :
1306 : // Outerloop: Calculate source side heat transfer
1307 277850 : NumIteration2 = 0;
1308 277850 : Converged = false;
1309 277850 : StillSimulatingFlag = true;
1310 277850 : SourceResidual = 1.0;
1311 1695134 : while (StillSimulatingFlag) {
1312 708642 : if (Converged) StillSimulatingFlag = false;
1313 :
1314 708642 : ++NumIteration2;
1315 708642 : if (NumIteration2 == 1) RelaxParam = 0.5;
1316 :
1317 708642 : if (NumIteration2 > STOP2) {
1318 0 : heatPump.SimFlag = false;
1319 0 : return;
1320 : }
1321 :
1322 : // Innerloop: Calculate load side heat transfer
1323 708642 : NumIteration3 = 0;
1324 708642 : LoadResidual = 1.0;
1325 2711566 : while (LoadResidual > ERR) {
1326 :
1327 1001462 : ++NumIteration3;
1328 :
1329 1001462 : if (NumIteration3 > STOP3) {
1330 0 : heatPump.SimFlag = false;
1331 0 : return;
1332 : }
1333 :
1334 : // Determine Effectiveness of Source Side
1335 1001462 : CpFluid = GetSpecificHeatGlycol(
1336 : state, SourceSideFluidName, heatPump.InletWaterTemp, SourceSideFluidIndex, RoutineNameSourceSideInletTemp);
1337 :
1338 : // IF (SourceSideFluidName=='WATER') THEN
1339 1001462 : if (SourceSideFluidIndex == state.dataWaterToAirHeatPump->WaterIndex) { // SourceSideFluidName=='Water'
1340 962055 : SourceSideEffect = 1.0 - std::exp(-heatPump.SourceSideUACoeff / (CpFluid * heatPump.InletWaterMassFlowRate));
1341 : } else {
1342 39407 : DegradFactor = DegradF(state, SourceSideFluidName, heatPump.InletWaterTemp, SourceSideFluidIndex);
1343 39407 : SourceSideEffect =
1344 39407 : 1.0 / ((heatPump.SourceSideHTR1 * std::pow(SourceSideVolFlowRate, -0.8)) / DegradFactor + heatPump.SourceSideHTR2);
1345 : }
1346 :
1347 : // Determine Source Side Tempertaure (Condensing Temp in this case)
1348 2002924 : SourceSideTemp = heatPump.InletWaterTemp + state.dataWaterToAirHeatPump->initialQSource_calc /
1349 1001462 : (SourceSideEffect * CpFluid * heatPump.InletWaterMassFlowRate);
1350 :
1351 : // Compute the Effective Surface Temperature
1352 1001462 : EffectiveSatEnth = LoadSideAirInletEnth - state.dataWaterToAirHeatPump->initialQLoadTotal_calc * LoadSideEffec_MassFlowRate_inv;
1353 :
1354 : // ! Set up the Initial Range of Effective Surface Temperature
1355 : // IF(.NOT. Converged)THEN
1356 : // EffectiveSurfaceTemp1=-100.
1357 : // EffectiveSurfaceTemp2=200.
1358 : // END IF
1359 : // ! Iterate to calculate the effective surface temp from the corresponding enthalpy
1360 : // NumIteration1=0
1361 : // LOOP1: DO
1362 : // NumIteration1=NumIteration1+1
1363 : // IF (NumIteration1.GT.STOP1) THEN
1364 : // WatertoAirHP(HPNum)%SimFlag = .FALSE.
1365 : // RETURN
1366 : // END IF
1367 : // EffectiveSurfaceTemp=0.5d0*(EffectiveSurfaceTemp1+EffectiveSurfaceTemp2)
1368 : // EffectiveSatEnth1=PsyHFnTdbRhPb(EffectiveSurfaceTemp,1.0,PB)
1369 : // IF(ABS(EffectiveSatEnth-EffectiveSatEnth1).LT.0.01 .OR. &
1370 : // ABS(EffectiveSurfaceTemp1-EffectiveSurfaceTemp2).LT.0.001) THEN
1371 : // EXIT LOOP1
1372 : // END IF
1373 : // IF(EffectiveSatEnth1.LT.EffectiveSatEnth) THEN
1374 : // EffectiveSurfaceTemp1=EffectiveSurfaceTemp
1375 : // ELSE
1376 : // EffectiveSurfaceTemp2=EffectiveSurfaceTemp
1377 : // END IF
1378 : // END DO LOOP1
1379 :
1380 1001462 : EffectiveSurfaceTemp = PsyTsatFnHPb(state, EffectiveSatEnth, PB, RoutineNameLoadSideSurfaceTemp);
1381 :
1382 1001462 : QSensible = heatPump.InletAirMassFlowRate * CpAir * (LoadSideInletDBTemp - EffectiveSurfaceTemp) * LoadSideEffec;
1383 1001462 : EvapSatEnth =
1384 1001462 : LoadSideAirInletEnth - state.dataWaterToAirHeatPump->initialQLoadTotal_calc / (EffectWET * heatPump.InletAirMassFlowRate);
1385 :
1386 1001462 : EvapTemp = PsyTsatFnHPb(state, EvapSatEnth, PB, RoutineNameLoadSideEvapTemp);
1387 :
1388 : // Load Side Saturated Temperature (Evaporating Temp in this case)
1389 1001462 : LoadSideTemp = EvapTemp;
1390 :
1391 : // Determine the Load Side and Source Side Saturated Temp (evaporating and condensing pressures)
1392 1001462 : SourceSidePressure = GetSatPressureRefrig(
1393 1001462 : state, heatPump.Refrigerant, SourceSideTemp, state.dataWaterToAirHeatPump->RefrigIndex, RoutineNameSourceSideTemp);
1394 1001462 : LoadSidePressure = GetSatPressureRefrig(
1395 1001462 : state, heatPump.Refrigerant, LoadSideTemp, state.dataWaterToAirHeatPump->RefrigIndex, RoutineNameLoadSideTemp);
1396 :
1397 1001462 : if (LoadSidePressure < heatPump.LowPressCutoff && !FirstHVACIteration) {
1398 0 : if (!state.dataGlobal->WarmupFlag) {
1399 0 : ShowRecurringWarningErrorAtEnd(
1400 : state,
1401 0 : format("WaterToAir Heat pump:cooling [{}] shut off on low pressure < {:.0R}", heatPump.Name, heatPump.LowPressCutoff),
1402 : heatPump.LowPressClgError,
1403 : LoadSidePressure,
1404 : LoadSidePressure,
1405 : _,
1406 : "[Pa]",
1407 : "[Pa]");
1408 : }
1409 0 : heatPump.SimFlag = false;
1410 0 : return;
1411 : }
1412 :
1413 1001462 : if (SourceSidePressure > heatPump.HighPressCutoff && !FirstHVACIteration) {
1414 0 : if (!state.dataGlobal->WarmupFlag) {
1415 0 : ShowRecurringWarningErrorAtEnd(state,
1416 0 : format("WaterToAir Heat pump:cooling [{}] shut off on high pressure > {:.0R}",
1417 : heatPump.Name,
1418 0 : heatPump.HighPressCutoff),
1419 : heatPump.HighPressClgError,
1420 : heatPump.InletWaterTemp,
1421 : heatPump.InletWaterTemp,
1422 : _,
1423 : "SourceSideInletTemp[C]",
1424 : "SourceSideInletTemp[C]");
1425 : }
1426 0 : heatPump.SimFlag = false;
1427 0 : return;
1428 : }
1429 :
1430 : // Determine Suction Pressure & Discharge Pressure at Compressor Exit
1431 1001462 : if (heatPump.compressorType == CompressorType::Reciprocating) { // RECIPROCATING
1432 0 : SuctionPr = LoadSidePressure - heatPump.CompSucPressDrop;
1433 0 : DischargePr = SourceSidePressure + heatPump.CompSucPressDrop;
1434 1001462 : } else if (heatPump.compressorType == CompressorType::Rotary) { // ROTARY
1435 0 : SuctionPr = LoadSidePressure;
1436 0 : DischargePr = SourceSidePressure + heatPump.CompSucPressDrop;
1437 1001462 : } else if (heatPump.compressorType == CompressorType::Scroll) { // SCROLL
1438 1001462 : SuctionPr = LoadSidePressure;
1439 1001462 : DischargePr = SourceSidePressure;
1440 : }
1441 :
1442 : // Determine the Load Side Outlet Enthalpy (Saturated Gas)
1443 1001462 : Quality = 1.0;
1444 1001462 : LoadSideOutletEnth = GetSatEnthalpyRefrig(
1445 1001462 : state, heatPump.Refrigerant, LoadSideTemp, Quality, state.dataWaterToAirHeatPump->RefrigIndex, RoutineNameLoadSideTemp);
1446 :
1447 : // Determine Source Side Outlet Enthalpy (Saturated Liquid)
1448 1001462 : Quality = 0.0;
1449 1001462 : SourceSideOutletEnth = GetSatEnthalpyRefrig(
1450 1001462 : state, heatPump.Refrigerant, SourceSideTemp, Quality, state.dataWaterToAirHeatPump->RefrigIndex, RoutineNameSourceSideTemp);
1451 : // Determine Superheated Temperature of the Load Side outlet/compressor Inlet
1452 1001462 : CompressInletTemp = LoadSideTemp + heatPump.SuperheatTemp;
1453 :
1454 : // Determine the Enthalpy of the Superheated Fluid at Load Side Outlet/Compressor Inlet
1455 1001462 : SuperHeatEnth = GetSupHeatEnthalpyRefrig(state,
1456 : heatPump.Refrigerant,
1457 : CompressInletTemp,
1458 : LoadSidePressure,
1459 1001462 : state.dataWaterToAirHeatPump->RefrigIndex,
1460 : RoutineNameCompressInletTemp);
1461 :
1462 : // Determining the suction state of the fluid from inlet state involves interation
1463 : // Method employed...
1464 : // Determine the saturated temp at suction pressure, shoot out into the superheated region find the enthalpy
1465 : // check that with the inlet enthalpy ( as suction loss is isenthalpic). Iterate till desired accuracy is reached
1466 1001462 : if (!Converged) {
1467 723612 : CompSuctionSatTemp = GetSatTemperatureRefrig(
1468 723612 : state, heatPump.Refrigerant, SuctionPr, state.dataWaterToAirHeatPump->RefrigIndex, RoutineNameSuctionPr);
1469 723612 : CompSuctionTemp1 = CompSuctionSatTemp;
1470 :
1471 : // Shoot into the Superheated Region
1472 723612 : CompSuctionTemp2 = CompSuctionSatTemp + DegreeofSuperheat;
1473 : }
1474 :
1475 18026316 : auto f = [&state, SuctionPr, SuperHeatEnth](Real64 const CompSuctionTemp) {
1476 : static constexpr std::string_view RoutineName("CalcWaterToAirHPHeating:CalcCompSuctionTemp");
1477 6008772 : std::string Refrigerant; // Name of refrigerant
1478 3004386 : int refrigIndex = state.dataWaterToAirHeatPump->RefrigIndex;
1479 6008772 : Real64 compSuctionEnth = GetSupHeatEnthalpyRefrig(state, Refrigerant, CompSuctionTemp, SuctionPr, refrigIndex, RoutineName);
1480 9013158 : return (compSuctionEnth - SuperHeatEnth) / SuperHeatEnth;
1481 1001462 : };
1482 :
1483 2002924 : General::SolveRoot(
1484 1001462 : state, ERR, STOP1, SolFlag, state.dataWaterToAirHeatPump->CompSuctionTemp, f, CompSuctionTemp1, CompSuctionTemp2);
1485 1001462 : if (SolFlag == -1) {
1486 0 : heatPump.SimFlag = false;
1487 0 : return;
1488 : }
1489 2002924 : CompSuctionEnth = GetSupHeatEnthalpyRefrig(state,
1490 : heatPump.Refrigerant,
1491 1001462 : state.dataWaterToAirHeatPump->CompSuctionTemp,
1492 : SuctionPr,
1493 1001462 : state.dataWaterToAirHeatPump->RefrigIndex,
1494 : RoutineNameCompSuctionTemp);
1495 2002924 : CompSuctionDensity = GetSupHeatDensityRefrig(state,
1496 : heatPump.Refrigerant,
1497 1001462 : state.dataWaterToAirHeatPump->CompSuctionTemp,
1498 : SuctionPr,
1499 1001462 : state.dataWaterToAirHeatPump->RefrigIndex,
1500 : RoutineNameCompSuctionTemp);
1501 :
1502 : // Find Refrigerant Flow Rate
1503 1001462 : switch (heatPump.compressorType) {
1504 0 : case CompressorType::Reciprocating: {
1505 0 : MassRef =
1506 0 : heatPump.CompPistonDisp * CompSuctionDensity *
1507 0 : (1.0 + heatPump.CompClearanceFactor - heatPump.CompClearanceFactor * std::pow(DischargePr / SuctionPr, 1.0 / gamma));
1508 0 : break;
1509 : }
1510 0 : case CompressorType::Rotary: {
1511 0 : MassRef = heatPump.CompPistonDisp * CompSuctionDensity;
1512 0 : break;
1513 : }
1514 1001462 : case CompressorType::Scroll: {
1515 1001462 : MassRef = heatPump.RefVolFlowRate * CompSuctionDensity - heatPump.LeakRateCoeff * (DischargePr / SuctionPr);
1516 1001462 : break;
1517 : }
1518 0 : default:
1519 0 : break;
1520 : }
1521 1001462 : MassRef = max(0.0, MassRef);
1522 :
1523 : // Find the Load Side Heat Transfer
1524 1001462 : QLoadTotal = MassRef * (LoadSideOutletEnth - SourceSideOutletEnth);
1525 2002924 : LoadResidual = std::abs(QLoadTotal - state.dataWaterToAirHeatPump->initialQLoadTotal_calc) /
1526 1001462 : state.dataWaterToAirHeatPump->initialQLoadTotal_calc;
1527 1001462 : state.dataWaterToAirHeatPump->initialQLoadTotal_calc +=
1528 1001462 : RelaxParam * (QLoadTotal - state.dataWaterToAirHeatPump->initialQLoadTotal_calc);
1529 1001462 : if (NumIteration3 > 8) RelaxParam = 0.3;
1530 : }
1531 :
1532 : // Determine the Power Consumption
1533 708642 : switch (heatPump.compressorType) {
1534 0 : case CompressorType::Reciprocating:
1535 : case CompressorType::Rotary: {
1536 0 : Power = heatPump.PowerLosses + (1.0 / heatPump.LossFactor) * (MassRef * gamma / (gamma - 1.0) * SuctionPr / CompSuctionDensity *
1537 0 : (std::pow(DischargePr / SuctionPr, (gamma - 1.0) / gamma) - 1.0));
1538 0 : break;
1539 : }
1540 708642 : case CompressorType::Scroll: {
1541 1417284 : Power = heatPump.PowerLosses + (1.0 / heatPump.LossFactor) * (gamma / (gamma - 1.0)) * SuctionPr * heatPump.RefVolFlowRate *
1542 1417284 : (((gamma - 1.0) / gamma) * ((DischargePr / SuctionPr) / heatPump.VolumeRatio) +
1543 1417284 : ((1.0 / gamma) * std::pow(heatPump.VolumeRatio, gamma - 1.0)) - 1.0);
1544 708642 : break;
1545 : }
1546 0 : default:
1547 0 : break;
1548 : }
1549 :
1550 : // Determine the Sourceside Heat Rate
1551 708642 : QSource = Power + QLoadTotal;
1552 708642 : SourceResidual =
1553 708642 : std::abs(QSource - state.dataWaterToAirHeatPump->initialQSource_calc) / state.dataWaterToAirHeatPump->initialQSource_calc;
1554 708642 : if (SourceResidual < ERR) Converged = true;
1555 708642 : state.dataWaterToAirHeatPump->initialQSource_calc += RelaxParam * (QSource - state.dataWaterToAirHeatPump->initialQSource_calc);
1556 708642 : if (NumIteration2 > 8) RelaxParam = 0.2;
1557 : }
1558 :
1559 277850 : if (SuctionPr < heatPump.LowPressCutoff) {
1560 0 : ShowWarningError(state, "Heat pump:cooling shut down on low pressure");
1561 0 : heatPump.SimFlag = false;
1562 : }
1563 :
1564 277850 : if (DischargePr > heatPump.HighPressCutoff && !FirstHVACIteration) {
1565 0 : ShowWarningError(state, "Heat pump:cooling shut down on high pressure");
1566 0 : heatPump.SimFlag = false;
1567 : }
1568 :
1569 277850 : if (QSensible > QLoadTotal) {
1570 0 : QSensible = QLoadTotal;
1571 : }
1572 :
1573 277850 : if (LatDegradModelSimFlag) {
1574 0 : if (NumIteration4 == 1) {
1575 0 : QLatRated = QLoadTotal - QSensible;
1576 :
1577 0 : } else if (NumIteration4 == 2) {
1578 0 : QLatActual = QLoadTotal - QSensible;
1579 0 : SHRss = QSensible / QLoadTotal;
1580 0 : LoadSideInletWBTemp = PsyTwbFnTdbWPb(state, LoadSideInletDBTemp, LoadSideInletHumRat, PB);
1581 0 : SHReff = CalcEffectiveSHR(
1582 : state, HPNum, SHRss, CyclingScheme, RuntimeFrac, QLatRated, QLatActual, LoadSideInletDBTemp, LoadSideInletWBTemp);
1583 : // Update sensible capacity based on effective SHR
1584 0 : QSensible = QLoadTotal * SHReff;
1585 0 : goto LOOPLatentDegradationModel_exit;
1586 : }
1587 : } else {
1588 :
1589 277850 : SHReff = QSensible / QLoadTotal;
1590 277850 : goto LOOPLatentDegradationModel_exit;
1591 : }
1592 0 : }
1593 277850 : LOOPLatentDegradationModel_exit:;
1594 :
1595 : // calculate coil outlet state variables
1596 277850 : LoadSideAirOutletEnth = LoadSideAirInletEnth - QLoadTotal / heatPump.InletAirMassFlowRate;
1597 277850 : LoadSideOutletDBTemp = LoadSideInletDBTemp - QSensible * LoadSideMassFlowRate_CpAir_inv;
1598 277850 : LoadSideOutletHumRat = PsyWFnTdbH(state, LoadSideOutletDBTemp, LoadSideAirOutletEnth, RoutineNameLoadSideOutletEnthalpy);
1599 277850 : SourceSideOutletTemp = heatPump.InletWaterTemp + QSource / (heatPump.InletWaterMassFlowRate * CpWater);
1600 :
1601 : // Actual outlet conditions are "average" for time step
1602 277850 : if (CyclingScheme == ContFanCycCoil) {
1603 : // continuous fan, cycling compressor
1604 0 : heatPump.OutletAirEnthalpy = PartLoadRatio * LoadSideAirOutletEnth + (1.0 - PartLoadRatio) * LoadSideAirInletEnth;
1605 0 : heatPump.OutletAirHumRat = PartLoadRatio * LoadSideOutletHumRat + (1.0 - PartLoadRatio) * LoadSideInletHumRat;
1606 0 : heatPump.OutletAirDBTemp = PsyTdbFnHW(heatPump.OutletAirEnthalpy, heatPump.OutletAirHumRat);
1607 : } else {
1608 : // default to cycling fan, cycling compressor
1609 277850 : heatPump.OutletAirEnthalpy = LoadSideAirOutletEnth;
1610 277850 : heatPump.OutletAirHumRat = LoadSideOutletHumRat;
1611 277850 : heatPump.OutletAirDBTemp = LoadSideOutletDBTemp;
1612 : }
1613 :
1614 : // scale heat transfer rates and power to run time
1615 277850 : QLoadTotal *= PartLoadRatio;
1616 277850 : QSensible *= PartLoadRatio;
1617 277850 : Power *= RuntimeFrac;
1618 277850 : QSource *= PartLoadRatio;
1619 :
1620 : // Update heat pump data structure
1621 277850 : state.dataHVACGlobal->DXElecCoolingPower = Power;
1622 277850 : heatPump.Power = Power;
1623 277850 : heatPump.QLoadTotal = QLoadTotal;
1624 277850 : heatPump.QSensible = QSensible;
1625 277850 : heatPump.QLatent = QLoadTotal - QSensible;
1626 277850 : heatPump.QSource = QSource;
1627 277850 : heatPump.RunFrac = RuntimeFrac;
1628 277850 : heatPump.PartLoadRatio = PartLoadRatio;
1629 :
1630 : // Air-side outlet conditions are already calculated above
1631 277850 : heatPump.OutletAirMassFlowRate = heatPump.InletAirMassFlowRate;
1632 277850 : heatPump.OutletWaterTemp = SourceSideOutletTemp;
1633 277850 : heatPump.OutletWaterMassFlowRate = heatPump.InletWaterMassFlowRate;
1634 277850 : heatPump.OutletWaterEnthalpy = heatPump.InletWaterEnthalpy + QSource / heatPump.InletWaterMassFlowRate;
1635 : }
1636 :
1637 1023129 : void CalcWatertoAirHPHeating(EnergyPlusData &state,
1638 : int const HPNum, // heat pump number
1639 : int const CyclingScheme, // fan/compressor cycling scheme indicator
1640 : bool const FirstHVACIteration, // first iteration flag
1641 : Real64 const RuntimeFrac,
1642 : [[maybe_unused]] bool const InitFlag, // first iteration flag
1643 : Real64 const SensDemand,
1644 : DataHVACGlobals::CompressorOperation const CompressorOp,
1645 : Real64 const PartLoadRatio)
1646 : {
1647 :
1648 : // SUBROUTINE INFORMATION:
1649 : // AUTHOR Hui Jin
1650 : // DATE WRITTEN Oct 2000
1651 : // MODIFIED R. Raustad (Oct 2006) Revised iteration technique
1652 : // RE-ENGINEERED na
1653 :
1654 : // PURPOSE OF THIS SUBROUTINE:
1655 : // Simulates a parameter estimation based water to air heat pump model
1656 :
1657 : // Using/Aliasing
1658 : using namespace FluidProperties;
1659 : using General::SolveRoot;
1660 : using Psychrometrics::PsyCpAirFnW; // ,PsyHFnTdbRhPb,PsyWFnTdpPb
1661 : using Psychrometrics::PsyTdbFnHW;
1662 : using Psychrometrics::PsyWFnTdbH;
1663 1023129 : auto &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
1664 :
1665 : // Locals
1666 : // SUBROUTINE ARGUMENT DEFINITIONS:
1667 :
1668 : // SUBROUTINE PARAMETER DEFINITIONS:
1669 1023129 : Real64 constexpr CpWater(4210.0); // Specific heat of water J/kg_C
1670 1023129 : Real64 constexpr DegreeofSuperheat(80.0); // Initial guess of degree of superheat
1671 1023129 : Real64 constexpr gamma(1.114); // Expnasion Coefficient
1672 1023129 : Real64 RelaxParam(0.5); // Relaxation Parameter
1673 1023129 : Real64 constexpr ERR(0.01); // Error Value
1674 1023129 : int constexpr STOP1(1000); // Iteration stopper1
1675 1023129 : int constexpr STOP2(1000); // Iteration stopper2
1676 1023129 : int constexpr STOP3(1000); // Iteration stopper3
1677 :
1678 : static constexpr std::string_view RoutineNameSourceSideInletTemp("CalcWatertoAirHPHeating:SourceSideInletTemp");
1679 : static constexpr std::string_view RoutineNameSourceSideTemp("CalcWatertoAirHPHeating:SourceSideTemp");
1680 : static constexpr std::string_view RoutineNameLoadSideTemp("CalcWatertoAirHPHeating:LoadSideTemp");
1681 : static constexpr std::string_view RoutineNameLoadSideOutletEnthalpy("CalcWatertoAirHPHeating:LoadSideOutletEnthalpy");
1682 : static constexpr std::string_view RoutineNameCompressInletTemp("CalcWatertoAirHPHeating:CompressInletTemp");
1683 : static constexpr std::string_view RoutineNameSuctionPr("CalcWatertoAirHPHeating:SuctionPr");
1684 : static constexpr std::string_view RoutineNameCompSuctionTemp("CalcWatertoAirHPHeating:CompSuctionTemp");
1685 :
1686 : // INTERFACE BLOCK SPECIFICATIONS
1687 : // na
1688 :
1689 : // DERIVED TYPE DEFINITIONS
1690 : // na
1691 :
1692 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1693 : // INTEGER :: NumIteration1 ! Number of Iteration1
1694 : int NumIteration2; // Number of Iteration2
1695 : int NumIteration3; // Number of Iteration3
1696 : int SourceSideFluidIndex; // Source Side Fluid Index
1697 :
1698 1491434 : std::string SourceSideFluidName; // Name of source side fluid
1699 : // CHARACTER(len=25) :: CErrCount
1700 : // Pressure Ratio and Leakage Rate [~]
1701 : Real64 Quality;
1702 : Real64 SourceSideOutletTemp; // Source Side Outlet Temperature [C]
1703 : Real64 SourceSideVolFlowRate; // Source Side Volumetric Flow Rate [m3/s]
1704 : Real64 CpFluid; // Specific heat of source side fluid(J/kg)
1705 : Real64 LoadSideOutletDBTemp; // Load Side Outlet Dry Bulb Temperature [C]
1706 : Real64 LoadSideOutletHumRat; // Load Side Outlet Humidity Ratio [kg/kg]
1707 : Real64 LoadSideAirOutletEnth; // Load Side Outlet Enthalpy [J/kg]
1708 : Real64 CpAir; // Specific Heat of Air [J/kg_C]
1709 : Real64 DegradFactor; // Degradation Factor [~]
1710 : Real64 QSource; // Source Side Heat Transfer Rate [W]
1711 : Real64 QLoadTotal; // Load Side Heat Transfer Rate [W]
1712 : Real64 Power; // Power Consumption [W]
1713 :
1714 : Real64 SourceSideEffect; // Source Side Heat Exchanger Effectiveness
1715 : Real64 SourceSideTemp; // Source Side Saturated Refrigerant Temperature [C]
1716 : Real64 LoadSideTemp; // Load Side Saturated Refrigerant Temperature [C]
1717 : Real64 SourceSidePressure; // Source Side Saturated Refrigerant Pressure [Pa]
1718 : Real64 LoadSidePressure; // Load Side Saturated Refrigerant Pressure [Pa]
1719 : Real64 SuctionPr; // Compressor Suction Pressure [Pa]
1720 : Real64 DischargePr; // Compressor Discharge Pressure [Pa]
1721 : Real64 CompressInletTemp; // Temperature of the Refrigerant Entering the Compressor [C]
1722 : Real64 MassRef; // Mass Flow Rate of Refrigerant [kg/s]
1723 : Real64 SourceSideOutletEnth; // Enthalpy of Refrigerant leaving the Source Side Heat Exchanger [J/kg]
1724 : Real64 LoadSideOutletEnth; // Enthalpy of Refrigerant leaving the Load Side Heat Exchanger [J/kg]
1725 : Real64 SuperHeatEnth; // Enthalpy of the Superheated Refrigerant [J/kg]
1726 : Real64 CompSuctionTemp1; // Guess of the Temperature of the Refrigerant Entering the
1727 : // Compressor #1 [C]
1728 : Real64 CompSuctionTemp2; // Guess of the Temperature of the Refrigerant Entering the
1729 : // Compressor #2 [C]
1730 : Real64 CompSuctionTemp; // Temperature of the Refrigerant Entering the Compressor [C]
1731 : Real64 CompSuctionEnth; // Enthalpy of the Refrigerant Entering the Compressor [J/kg]
1732 : Real64 CompSuctionDensity; // Density of the Refrigerant Entering the Compressorkg/m3
1733 : Real64 CompSuctionSatTemp; // Temperature of Saturated Refrigerant at Compressor Suction Pressure [C]
1734 : bool StillSimulatingFlag; // Final Simulation Flag
1735 : bool Converged; // Overall convergence Flag
1736 : int SolFlag; // Solution flag returned from RegulaFalsi function
1737 : Real64 LoadResidual; // loop convergence criteria
1738 : Real64 SourceResidual; // loop convergence criteria
1739 :
1740 : // LOAD LOCAL VARIABLES FROM DATA STRUCTURE (for code readability)
1741 :
1742 1023129 : CpAir = PsyCpAirFnW(heatPump.InletAirHumRat);
1743 1023129 : SourceSideFluidName = state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).FluidName;
1744 1023129 : SourceSideFluidIndex = state.dataPlnt->PlantLoop(heatPump.plantLoc.loopNum).FluidIndex;
1745 1023129 : SourceSideVolFlowRate =
1746 1023129 : heatPump.InletWaterMassFlowRate /
1747 1023129 : GetDensityGlycol(state, SourceSideFluidName, heatPump.InletWaterTemp, SourceSideFluidIndex, RoutineNameSourceSideInletTemp);
1748 :
1749 : // If heat pump is not operating, return
1750 1023129 : if (SensDemand == 0.0 || heatPump.InletAirMassFlowRate <= 0.0 || heatPump.InletWaterMassFlowRate <= 0.0) {
1751 554824 : heatPump.SimFlag = false;
1752 554824 : return;
1753 : } else {
1754 468305 : heatPump.SimFlag = true;
1755 : }
1756 :
1757 468305 : if (CompressorOp == DataHVACGlobals::CompressorOperation::Off) {
1758 0 : heatPump.SimFlag = false;
1759 0 : return;
1760 : }
1761 :
1762 468305 : if (FirstHVACIteration) {
1763 98358 : state.dataWaterToAirHeatPump->initialQLoad = heatPump.HeatingCapacity;
1764 98358 : state.dataWaterToAirHeatPump->initialQSource = heatPump.HeatingCapacity;
1765 : }
1766 :
1767 468305 : if (state.dataWaterToAirHeatPump->initialQLoad == 0.0) state.dataWaterToAirHeatPump->initialQLoad = heatPump.HeatingCapacity;
1768 468305 : if (state.dataWaterToAirHeatPump->initialQSource == 0.0) state.dataWaterToAirHeatPump->initialQSource = heatPump.HeatingCapacity;
1769 :
1770 : // Tuned Hoisted quantities out of nested loop that don't change
1771 468305 : Real64 const LoadSideMassFlowRate_CpAir_inv(1.0 / (heatPump.InletAirMassFlowRate * CpAir));
1772 : Real64 const LoadSideEffect(1.0 -
1773 468305 : std::exp(-heatPump.LoadSideTotalUACoeff *
1774 468305 : LoadSideMassFlowRate_CpAir_inv)); // Load Side Effectiveness based on Outside Heat Transfer Coefficient
1775 468305 : Real64 const LoadSideEffect_CpAir_MassFlowRate_inv(1.0 / (LoadSideEffect * CpAir * heatPump.InletAirMassFlowRate));
1776 :
1777 : // Outerloop: calculate load side heat transfer
1778 468305 : NumIteration3 = 0;
1779 468305 : Converged = false;
1780 468305 : StillSimulatingFlag = true;
1781 468305 : LoadResidual = 1.0;
1782 3194097 : while (StillSimulatingFlag) {
1783 1362896 : if (Converged) StillSimulatingFlag = false;
1784 :
1785 1362896 : ++NumIteration3;
1786 1362896 : if (NumIteration3 == 1) RelaxParam = 0.5;
1787 :
1788 1362896 : if (NumIteration3 > STOP3) {
1789 0 : heatPump.SimFlag = false;
1790 0 : return;
1791 : }
1792 :
1793 : // Innerloop: calculate load side heat transfer
1794 1362896 : NumIteration2 = 0;
1795 1362896 : SourceResidual = 1.0;
1796 5323248 : while (SourceResidual > ERR) {
1797 :
1798 1980176 : ++NumIteration2;
1799 :
1800 1980176 : if (NumIteration2 > STOP2) {
1801 0 : heatPump.SimFlag = false;
1802 0 : return;
1803 : }
1804 :
1805 : // Determine Effectiveness of Source Side
1806 1980176 : CpFluid =
1807 1980176 : GetSpecificHeatGlycol(state, SourceSideFluidName, heatPump.InletWaterTemp, SourceSideFluidIndex, RoutineNameSourceSideInletTemp);
1808 :
1809 : // IF (SourceSideFluidName=='WATER') THEN
1810 1980176 : if (SourceSideFluidIndex == state.dataWaterToAirHeatPump->WaterIndex) {
1811 1648298 : SourceSideEffect =
1812 1648298 : 1.0 - std::exp(-heatPump.SourceSideUACoeff / (CpFluid * heatPump.InletWaterMassFlowRate)); // SourceSideFluidName=='Water'
1813 : } else {
1814 331878 : DegradFactor = DegradF(state, SourceSideFluidName, heatPump.InletWaterTemp, SourceSideFluidIndex);
1815 331878 : SourceSideEffect =
1816 331878 : 1.0 / ((heatPump.SourceSideHTR1 * std::pow(SourceSideVolFlowRate, -0.8)) / DegradFactor + heatPump.SourceSideHTR2);
1817 : }
1818 :
1819 : // Determine Source Side Tempertaure (Evap. Temp for this mode)
1820 3960352 : SourceSideTemp = heatPump.InletWaterTemp -
1821 1980176 : state.dataWaterToAirHeatPump->initialQSource / (SourceSideEffect * CpFluid * heatPump.InletWaterMassFlowRate);
1822 :
1823 : // Determine Load Side Tempertaure (Condensing Temp for this mode)
1824 1980176 : LoadSideTemp = heatPump.InletAirDBTemp + state.dataWaterToAirHeatPump->initialQLoad * LoadSideEffect_CpAir_MassFlowRate_inv;
1825 :
1826 : // Determine the Load Side and Source Side Saturated Temp (evaporating and condensing pressures)
1827 1980176 : SourceSidePressure = GetSatPressureRefrig(
1828 1980176 : state, heatPump.Refrigerant, SourceSideTemp, state.dataWaterToAirHeatPump->RefrigIndex, RoutineNameSourceSideTemp);
1829 1980176 : LoadSidePressure = GetSatPressureRefrig(
1830 1980176 : state, heatPump.Refrigerant, LoadSideTemp, state.dataWaterToAirHeatPump->RefrigIndex, RoutineNameLoadSideTemp);
1831 1980176 : if (SourceSidePressure < heatPump.LowPressCutoff && !FirstHVACIteration) {
1832 0 : if (!state.dataGlobal->WarmupFlag) {
1833 0 : ShowRecurringWarningErrorAtEnd(
1834 : state,
1835 0 : format("WaterToAir Heat pump:heating [{}] shut off on low pressure < {:.0R}", heatPump.Name, heatPump.LowPressCutoff),
1836 : heatPump.LowPressHtgError,
1837 : SourceSidePressure,
1838 : SourceSidePressure,
1839 : _,
1840 : "[Pa]",
1841 : "[Pa]");
1842 : }
1843 0 : heatPump.SimFlag = false;
1844 0 : return;
1845 : }
1846 :
1847 1980176 : if (LoadSidePressure > heatPump.HighPressCutoff && !FirstHVACIteration) {
1848 0 : if (!state.dataGlobal->WarmupFlag) {
1849 0 : ShowRecurringWarningErrorAtEnd(
1850 : state,
1851 0 : format("WaterToAir Heat pump:heating [{}] shut off on high pressure > {:.0R}", heatPump.Name, heatPump.HighPressCutoff),
1852 : heatPump.HighPressHtgError,
1853 : heatPump.InletWaterTemp,
1854 : heatPump.InletWaterTemp,
1855 : _,
1856 : "SourceSideInletTemp[C]",
1857 : "SourceSideInletTemp[C]");
1858 : }
1859 : // CALL ShowWarningError(state, 'Heat pump:heating shut off on high pressure')
1860 : // WRITE(CErrCount,*) SourceSideInletTemp
1861 : // CErrCount=ADJUSTL(CErrCount)
1862 : // CALL ShowContinueError(state, 'Source side inlet temperature too low, T='//TRIM(CErrCount))
1863 : // CALL ShowContinueError(state, 'Heat pump heating demand not met by plant side')
1864 0 : heatPump.SimFlag = false;
1865 0 : return;
1866 : }
1867 :
1868 : // Determine Suction Pressure at Compressor Entrance & Discharge Pressure at Compressor Exit
1869 1980176 : switch (heatPump.compressorType) {
1870 0 : case CompressorType::Reciprocating: {
1871 0 : SuctionPr = SourceSidePressure - heatPump.CompSucPressDrop;
1872 0 : DischargePr = LoadSidePressure + heatPump.CompSucPressDrop;
1873 0 : break;
1874 : }
1875 0 : case CompressorType::Rotary: {
1876 0 : SuctionPr = SourceSidePressure;
1877 0 : DischargePr = LoadSidePressure + heatPump.CompSucPressDrop;
1878 0 : break;
1879 : }
1880 1980176 : case CompressorType::Scroll: {
1881 1980176 : SuctionPr = SourceSidePressure;
1882 1980176 : DischargePr = LoadSidePressure;
1883 1980176 : break;
1884 : }
1885 0 : default:
1886 0 : break;
1887 : }
1888 :
1889 : // Determine the Source Side Outlet Enthalpy
1890 : // Quality of the refrigerant leaving the evaporator is saturated gas
1891 1980176 : Quality = 1.0;
1892 1980176 : SourceSideOutletEnth = GetSatEnthalpyRefrig(
1893 1980176 : state, heatPump.Refrigerant, SourceSideTemp, Quality, state.dataWaterToAirHeatPump->RefrigIndex, RoutineNameSourceSideTemp);
1894 :
1895 : // Determine Load Side Outlet Enthalpy
1896 : // Quality of the refrigerant leaving the condenser is saturated liguid
1897 1980176 : Quality = 0.0;
1898 1980176 : LoadSideOutletEnth = GetSatEnthalpyRefrig(
1899 1980176 : state, heatPump.Refrigerant, LoadSideTemp, Quality, state.dataWaterToAirHeatPump->RefrigIndex, RoutineNameLoadSideTemp);
1900 :
1901 : // Determine Superheated Temperature of the Source Side outlet/compressor Inlet
1902 1980176 : CompressInletTemp = SourceSideTemp + heatPump.SuperheatTemp;
1903 :
1904 : // Determine the Enathalpy of the Superheated Fluid at Source Side Outlet/Compressor Inlet
1905 1980176 : SuperHeatEnth = GetSupHeatEnthalpyRefrig(state,
1906 : heatPump.Refrigerant,
1907 : CompressInletTemp,
1908 : SourceSidePressure,
1909 1980176 : state.dataWaterToAirHeatPump->RefrigIndex,
1910 : RoutineNameCompressInletTemp);
1911 :
1912 : // Determining the suction state of the fluid from inlet state involves interation
1913 : // Method employed...
1914 : // Determine the saturated temp at suction pressure, shoot out into the superheated region find the enthalpy
1915 : // check that with the inlet enthalpy ( as suction loss is isenthalpic). Iterate till desired accuracy is reached
1916 :
1917 1980176 : if (!Converged) {
1918 1511871 : CompSuctionSatTemp = GetSatTemperatureRefrig(
1919 1511871 : state, heatPump.Refrigerant, SuctionPr, state.dataWaterToAirHeatPump->RefrigIndex, RoutineNameSuctionPr);
1920 1511871 : CompSuctionTemp1 = CompSuctionSatTemp;
1921 :
1922 : // Shoot into the Superheated Region
1923 1511871 : CompSuctionTemp2 = CompSuctionSatTemp + DegreeofSuperheat;
1924 : }
1925 :
1926 : // ! Iterate to find the Suction State
1927 : // NumIteration1=0
1928 : // LOOP: DO
1929 : // NumIteration1=NumIteration1+1
1930 : // IF (NumIteration1.GT.STOP1) THEN
1931 : // WatertoAirHP(HPNum)%SimFlag = .FALSE.
1932 : // RETURN
1933 : // END IF
1934 : // CompSuctionTemp = 0.5d0 * ( CompSuctionTemp1 + CompSuctionTemp2 )
1935 : // CompSuctionEnth = GetSupHeatEnthalpyRefrig(Refrigerant, CompSuctionTemp, SuctionPr, RefrigIndex)
1936 : // CompSuctionDensity = GetSupHeatDensityRefrig(Refrigerant, CompSuctionTemp, SuctionPr, RefrigIndex)
1937 : // IF (ABS(CompsuctionEnth-SuperHeatEnth)/SuperHeatEnth < ERR) THEN
1938 : // EXIT LOOP
1939 : // END IF
1940 : // IF ( CompsuctionEnth < SuperHeatEnth ) THEN
1941 : // CompSuctionTemp1 = CompSuctionTemp
1942 : // ELSE
1943 : // CompSuctionTemp2 = CompSuctionTemp
1944 : // END IF
1945 : // END DO LOOP
1946 :
1947 : // Do not need the name of the refrigerant if we already have the index (from above CALLs)
1948 :
1949 35643168 : auto f = [&state, SuctionPr, SuperHeatEnth](Real64 const CompSuctionTemp) {
1950 : static constexpr std::string_view RoutineName("CalcWaterToAirHPHeating:CalcCompSuctionTemp");
1951 11881056 : std::string Refrigerant; // Name of refrigerant
1952 5940528 : int refrigIndex = state.dataWaterToAirHeatPump->RefrigIndex;
1953 11881056 : Real64 compSuctionEnth = GetSupHeatEnthalpyRefrig(state, Refrigerant, CompSuctionTemp, SuctionPr, refrigIndex, RoutineName);
1954 17821584 : return (compSuctionEnth - SuperHeatEnth) / SuperHeatEnth;
1955 1980176 : };
1956 :
1957 1980176 : General::SolveRoot(state, ERR, STOP1, SolFlag, CompSuctionTemp, f, CompSuctionTemp1, CompSuctionTemp2);
1958 1980176 : if (SolFlag == -1) {
1959 0 : heatPump.SimFlag = false;
1960 0 : return;
1961 : }
1962 1980176 : CompSuctionEnth = GetSupHeatEnthalpyRefrig(
1963 1980176 : state, heatPump.Refrigerant, CompSuctionTemp, SuctionPr, state.dataWaterToAirHeatPump->RefrigIndex, RoutineNameCompSuctionTemp);
1964 1980176 : CompSuctionDensity = GetSupHeatDensityRefrig(
1965 1980176 : state, heatPump.Refrigerant, CompSuctionTemp, SuctionPr, state.dataWaterToAirHeatPump->RefrigIndex, RoutineNameCompSuctionTemp);
1966 :
1967 : // Find Refrigerant Flow Rate
1968 1980176 : switch (heatPump.compressorType) {
1969 0 : case CompressorType::Reciprocating: {
1970 0 : MassRef = heatPump.CompPistonDisp * CompSuctionDensity *
1971 0 : (1 + heatPump.CompClearanceFactor - heatPump.CompClearanceFactor * std::pow(DischargePr / SuctionPr, 1 / gamma));
1972 0 : break;
1973 : }
1974 0 : case CompressorType::Rotary: {
1975 0 : MassRef = heatPump.CompPistonDisp * CompSuctionDensity;
1976 0 : break;
1977 : }
1978 1980176 : case CompressorType::Scroll: {
1979 1980176 : MassRef = heatPump.RefVolFlowRate * CompSuctionDensity - heatPump.LeakRateCoeff * (DischargePr / SuctionPr);
1980 1980176 : break;
1981 : }
1982 0 : default:
1983 0 : break;
1984 : }
1985 1980176 : MassRef = max(0.0, MassRef);
1986 :
1987 : // Find the Source Side Heat Transfer
1988 1980176 : QSource = MassRef * (SourceSideOutletEnth - LoadSideOutletEnth);
1989 1980176 : SourceResidual = std::abs(QSource - state.dataWaterToAirHeatPump->initialQSource) / state.dataWaterToAirHeatPump->initialQSource;
1990 1980176 : state.dataWaterToAirHeatPump->initialQSource += RelaxParam * (QSource - state.dataWaterToAirHeatPump->initialQSource);
1991 1980176 : if (NumIteration2 > 8) RelaxParam = 0.3;
1992 : }
1993 :
1994 : // Determine the Power Consumption
1995 1362896 : switch (heatPump.compressorType) {
1996 0 : case CompressorType::Reciprocating:
1997 : case CompressorType::Rotary: {
1998 0 : Power = heatPump.PowerLosses + (1 / heatPump.LossFactor) * (MassRef * gamma / (gamma - 1) * SuctionPr / CompSuctionDensity *
1999 0 : (std::pow(DischargePr / SuctionPr, (gamma - 1) / gamma) - 1));
2000 0 : break;
2001 : }
2002 1362896 : case CompressorType::Scroll: {
2003 2725792 : Power = heatPump.PowerLosses + (1 / heatPump.LossFactor) * (gamma / (gamma - 1)) * SuctionPr * heatPump.RefVolFlowRate *
2004 2725792 : (((gamma - 1) / gamma) * ((DischargePr / SuctionPr) / heatPump.VolumeRatio) +
2005 2725792 : ((1 / gamma) * std::pow(heatPump.VolumeRatio, gamma - 1)) - 1);
2006 1362896 : break;
2007 : }
2008 0 : default:
2009 0 : break;
2010 : }
2011 :
2012 : // Determine the Load Side Heat Rate
2013 1362896 : QLoadTotal = Power + QSource;
2014 1362896 : LoadResidual = std::abs(QLoadTotal - state.dataWaterToAirHeatPump->initialQLoad) / state.dataWaterToAirHeatPump->initialQLoad;
2015 1362896 : if (LoadResidual < ERR) Converged = true;
2016 1362896 : state.dataWaterToAirHeatPump->initialQLoad += RelaxParam * (QLoadTotal - state.dataWaterToAirHeatPump->initialQLoad);
2017 1362896 : if (NumIteration3 > 8) RelaxParam = 0.2;
2018 : }
2019 :
2020 468305 : if (SuctionPr < heatPump.LowPressCutoff && !FirstHVACIteration) {
2021 0 : ShowWarningError(state, "Heat pump:heating shut down on low pressure");
2022 0 : heatPump.SimFlag = false;
2023 0 : return;
2024 : }
2025 :
2026 468305 : if (DischargePr > heatPump.HighPressCutoff && !FirstHVACIteration) {
2027 0 : ShowWarningError(state, "Heat pump:heating shut down on high pressure");
2028 0 : heatPump.SimFlag = false;
2029 0 : return;
2030 : }
2031 :
2032 : // calculate coil outlet state variables
2033 468305 : LoadSideAirOutletEnth = heatPump.InletAirEnthalpy + QLoadTotal / heatPump.InletAirMassFlowRate;
2034 468305 : LoadSideOutletDBTemp = heatPump.InletAirDBTemp + QLoadTotal / (heatPump.InletAirMassFlowRate * CpAir);
2035 468305 : LoadSideOutletHumRat = PsyWFnTdbH(state, LoadSideOutletDBTemp, LoadSideAirOutletEnth, RoutineNameLoadSideOutletEnthalpy);
2036 468305 : SourceSideOutletTemp = heatPump.InletWaterTemp - QSource / (heatPump.InletWaterMassFlowRate * CpWater);
2037 :
2038 : // Calculate actual outlet conditions for the run time fraction
2039 : // Actual outlet conditions are "average" for time step
2040 468305 : if (CyclingScheme == ContFanCycCoil) {
2041 : // continuous fan, cycling compressor
2042 0 : heatPump.OutletAirEnthalpy = PartLoadRatio * LoadSideAirOutletEnth + (1.0 - PartLoadRatio) * heatPump.InletAirEnthalpy;
2043 0 : heatPump.OutletAirHumRat = PartLoadRatio * LoadSideOutletHumRat + (1.0 - PartLoadRatio) * heatPump.InletAirHumRat;
2044 0 : heatPump.OutletAirDBTemp = PsyTdbFnHW(heatPump.OutletAirEnthalpy, heatPump.OutletAirHumRat);
2045 : } else {
2046 : // default to cycling fan, cycling compressor
2047 468305 : heatPump.OutletAirEnthalpy = LoadSideAirOutletEnth;
2048 468305 : heatPump.OutletAirHumRat = LoadSideOutletHumRat;
2049 468305 : heatPump.OutletAirDBTemp = LoadSideOutletDBTemp;
2050 : }
2051 : // scale heat transfer rates and power to run time
2052 468305 : QLoadTotal *= PartLoadRatio;
2053 468305 : Power *= RuntimeFrac;
2054 468305 : QSource *= PartLoadRatio;
2055 :
2056 : // Update heat pump data structure
2057 468305 : state.dataHVACGlobal->DXElecHeatingPower = Power;
2058 468305 : heatPump.Power = Power;
2059 468305 : heatPump.QLoadTotal = QLoadTotal;
2060 468305 : heatPump.QSensible = QLoadTotal;
2061 :
2062 468305 : heatPump.QSource = QSource;
2063 468305 : heatPump.RunFrac = RuntimeFrac;
2064 468305 : heatPump.PartLoadRatio = PartLoadRatio;
2065 :
2066 : // Air-side outlet conditions are already calculated above
2067 : // WatertoAirHP(HPNum)%OutletAirDBTemp=LoadSideOutletDBTemp
2068 : // WatertoAirHP(HPNum)%OutletAirHumRat=LoadsideOutletHumRat
2069 : // WatertoAirHP(HPNum)%OutletAirEnthalpy = LoadSideAirOutletEnth
2070 :
2071 468305 : heatPump.OutletAirMassFlowRate = heatPump.InletAirMassFlowRate;
2072 468305 : heatPump.OutletWaterTemp = SourceSideOutletTemp;
2073 468305 : heatPump.OutletWaterMassFlowRate = heatPump.InletWaterMassFlowRate;
2074 468305 : heatPump.OutletWaterEnthalpy = heatPump.InletWaterEnthalpy - QSource / heatPump.InletWaterMassFlowRate;
2075 : }
2076 :
2077 : // End Algorithm Section of the Module
2078 : // *****************************************************************************
2079 :
2080 : // End Algorithm Section of the Module
2081 : // *****************************************************************************
2082 :
2083 : // Beginning of Update subroutines for the WatertoAirHP Module
2084 : // *****************************************************************************
2085 :
2086 2046263 : void UpdateWatertoAirHP(EnergyPlusData &state, int const HPNum)
2087 : {
2088 : // SUBROUTINE INFORMATION:
2089 : // AUTHOR Hui Jin
2090 : // DATE WRITTEN Oct 2000
2091 : // MODIFIED na
2092 : // RE-ENGINEERED na
2093 :
2094 : // PURPOSE OF THIS SUBROUTINE:
2095 : // This subroutine updates the Water to Air Heat Pump outlet nodes.
2096 :
2097 : // METHODOLOGY EMPLOYED:
2098 : // Data is moved from the HP data structure to the HP outlet nodes.
2099 :
2100 : // Using/Aliasing
2101 2046263 : auto &TimeStepSys = state.dataHVACGlobal->TimeStepSys;
2102 2046263 : auto &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
2103 : using PlantUtilities::SafeCopyPlantNode;
2104 :
2105 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
2106 : Real64 ReportingConstant;
2107 :
2108 2046263 : ReportingConstant = TimeStepSys * DataGlobalConstants::SecInHour;
2109 : // WatertoAirHP(HPNum)%SimFlag=.FALSE.
2110 2046263 : if (!heatPump.SimFlag) {
2111 : // Heatpump is off; just pass through conditions
2112 1300108 : heatPump.Power = 0.0;
2113 1300108 : heatPump.Energy = 0.0;
2114 1300108 : heatPump.QLoadTotal = 0.0;
2115 1300108 : heatPump.QSensible = 0.0;
2116 1300108 : heatPump.QLatent = 0.0;
2117 1300108 : heatPump.QSource = 0.0;
2118 : // These will be overwritten below based on variables above that are already set to 0.
2119 : // WatertoAirHP(HPNum)%EnergyLoadTotal=0.0
2120 : // WatertoAirHP(HPNum)%EnergySensible=0.0
2121 : // WatertoAirHP(HPNum)%EnergySource=0.0
2122 : // WatertoAirHP(HPNum)%EnergyLatent=0.0
2123 1300108 : heatPump.RunFrac = 0.0;
2124 1300108 : heatPump.PartLoadRatio = 0.0;
2125 1300108 : heatPump.OutletAirDBTemp = heatPump.InletAirDBTemp;
2126 1300108 : heatPump.OutletAirHumRat = heatPump.InletAirHumRat;
2127 1300108 : heatPump.OutletWaterTemp = heatPump.InletWaterTemp;
2128 1300108 : heatPump.OutletAirMassFlowRate = heatPump.InletAirMassFlowRate;
2129 1300108 : heatPump.OutletWaterMassFlowRate = heatPump.InletWaterMassFlowRate;
2130 1300108 : heatPump.OutletAirEnthalpy = heatPump.InletAirEnthalpy;
2131 1300108 : heatPump.OutletWaterEnthalpy = heatPump.InletWaterEnthalpy;
2132 : }
2133 :
2134 : // Set the outlet air nodes of the WatertoAirHP
2135 2046263 : state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).MassFlowRate = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).MassFlowRate;
2136 2046263 : state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).Temp = heatPump.OutletAirDBTemp;
2137 2046263 : state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).HumRat = heatPump.OutletAirHumRat;
2138 2046263 : state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).Enthalpy = heatPump.OutletAirEnthalpy;
2139 :
2140 : // Set the outlet nodes for properties that just pass through & not used
2141 2046263 : SafeCopyPlantNode(state, heatPump.WaterInletNodeNum, heatPump.WaterOutletNodeNum);
2142 : // Set the outlet water nodes for the heat pump
2143 2046263 : state.dataLoopNodes->Node(heatPump.WaterOutletNodeNum).Temp = heatPump.OutletWaterTemp;
2144 2046263 : state.dataLoopNodes->Node(heatPump.WaterOutletNodeNum).Enthalpy = heatPump.OutletWaterEnthalpy;
2145 :
2146 : // Set the outlet nodes for properties that just pass through & not used
2147 2046263 : state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).Quality = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).Quality;
2148 2046263 : state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).Press = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).Press;
2149 2046263 : state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).MassFlowRateMin = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).MassFlowRateMin;
2150 2046263 : state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).MassFlowRateMax = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).MassFlowRateMax;
2151 2046263 : state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).MassFlowRateMinAvail =
2152 2046263 : state.dataLoopNodes->Node(heatPump.AirInletNodeNum).MassFlowRateMinAvail;
2153 2046263 : state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).MassFlowRateMaxAvail =
2154 2046263 : state.dataLoopNodes->Node(heatPump.AirInletNodeNum).MassFlowRateMaxAvail;
2155 :
2156 : // Pass through the load side mass flow rates
2157 2046263 : heatPump.InletAirMassFlowRate = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).MassFlowRate;
2158 2046263 : heatPump.OutletAirMassFlowRate = heatPump.InletAirMassFlowRate;
2159 :
2160 2046263 : heatPump.Energy = heatPump.Power * ReportingConstant;
2161 2046263 : heatPump.EnergyLoadTotal = heatPump.QLoadTotal * ReportingConstant;
2162 2046263 : heatPump.EnergySensible = heatPump.QSensible * ReportingConstant;
2163 2046263 : heatPump.EnergyLatent = heatPump.QLatent * ReportingConstant;
2164 2046263 : heatPump.EnergySource = heatPump.QSource * ReportingConstant;
2165 :
2166 2046263 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
2167 0 : state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).CO2 = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).CO2;
2168 : }
2169 2046263 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
2170 0 : state.dataLoopNodes->Node(heatPump.AirOutletNodeNum).GenContam = state.dataLoopNodes->Node(heatPump.AirInletNodeNum).GenContam;
2171 : }
2172 2046263 : }
2173 :
2174 : // End of Update subroutines for the WatertoAirHP Module
2175 : // *****************************************************************************
2176 :
2177 0 : Real64 CalcEffectiveSHR(EnergyPlusData &state,
2178 : int const HPNum, // Index number for cooling coil
2179 : Real64 const SHRss, // Steady-state sensible heat ratio
2180 : int const CyclingScheme, // fan/compressor cycling scheme indicator
2181 : Real64 const RTF, // Compressor run-time fraction
2182 : Real64 const QLatRated, // Rated latent capacity
2183 : Real64 const QLatActual, // Actual latent capacity
2184 : Real64 const EnteringDB, // Entering air dry-bulb temperature
2185 : Real64 const EnteringWB // Entering air wet-bulb temperature
2186 : )
2187 : {
2188 :
2189 : // FUNCTION INFORMATION:
2190 : // AUTHOR Richard Raustad, FSEC
2191 : // DATE WRITTEN September 2003
2192 : // MODIFIED Kenneth Tang (Aug 2004) Added capability for simulating CycFanCycCoil
2193 : // RE-ENGINEERED na
2194 :
2195 : // PURPOSE OF THIS FUNCTION:
2196 : // Adjust sensible heat ratio to account for degradation of DX coil latent
2197 : // capacity at part-load (cycling) conditions.
2198 :
2199 : // METHODOLOGY EMPLOYED:
2200 : // With model parameters entered by the user, the part-load latent performance
2201 : // of a DX cooling coil is determined for a constant air flow system with
2202 : // a cooling coil that cycles on/off. The model calculates the time
2203 : // required for condensate to begin falling from the cooling coil.
2204 : // Runtimes greater than this are integrated to a "part-load" latent
2205 : // capacity which is used to determine the "part-load" sensible heat ratio.
2206 : // See reference below for additional details (linear decay model, Eq. 8b).
2207 : // REFERENCES:
2208 : // "A Model to Predict the Latent Capacity of Air Conditioners and
2209 : // Heat Pumps at Part-Load Conditions with Constant Fan Operation"
2210 : // 1996 ASHRAE Transactions, Volume 102, Part 1, Pp. 266 - 274,
2211 : // Hugh I. Henderson, Jr., P.E., Kannan Rengarajan, P.E.
2212 :
2213 : // Using/Aliasing
2214 0 : auto &heatPump = state.dataWaterToAirHeatPump->WatertoAirHP(HPNum);
2215 :
2216 : // Return value
2217 : Real64 SHReff; // Effective sensible heat ratio, includes degradation due to cycling effects
2218 :
2219 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2220 : Real64 Twet; // Nominal time for condensate to begin leaving the coil's condensate drain line
2221 : // at the current operating conditions (sec)
2222 : Real64 Gamma; // Initial moisture evaporation rate divided by steady-state AC latent capacity
2223 : // at the current operating conditions
2224 : Real64 Twet_max; // Maximum allowed value for Twet
2225 : // shut off after compressor cycle off [s]
2226 :
2227 : Real64 Ton; // Coil on time (sec)
2228 : Real64 Toff; // Coil off time (sec)
2229 : Real64 Toffa; // Actual coil off time (sec). Equations valid for Toff <= (2.0 * Twet/Gamma)
2230 : Real64 aa; // Intermediate variable
2231 : Real64 To1; // Intermediate variable (first guess at To). To = time to the start of moisture removal
2232 : Real64 To2; // Intermediate variable (second guess at To). To = time to the start of moisture removal
2233 : Real64 Error; // Error for iteration (DO) loop
2234 : Real64 LHRmult; // Latent Heat Ratio (LHR) multiplier. The effective latent heat ratio LHR = (1-SHRss)*LHRmult
2235 :
2236 : // No moisture evaporation (latent degradation) occurs for runtime fraction of 1.0
2237 : // All latent degradation model parameters cause divide by 0.0 if not greater than 0.0
2238 : // Latent degradation model parameters initialize to 0.0 meaning no evaporation model used.
2239 0 : if ((RTF >= 1.0) || (QLatRated == 0.0) || (QLatActual == 0.0) || (heatPump.Twet_Rated <= 0.0) || (heatPump.Gamma_Rated <= 0.0) ||
2240 0 : (heatPump.MaxONOFFCyclesperHour <= 0.0) || (heatPump.HPTimeConstant <= 0.0) || (RTF <= 0.0)) {
2241 0 : SHReff = SHRss;
2242 0 : return SHReff;
2243 : }
2244 :
2245 0 : Twet_max = 9999.0; // high limit for Twet
2246 :
2247 : // Calculate the model parameters at the actual operating conditions
2248 0 : Twet = min(heatPump.Twet_Rated * QLatRated / (QLatActual + 1.e-10), Twet_max);
2249 0 : Gamma = heatPump.Gamma_Rated * QLatRated * (EnteringDB - EnteringWB) / ((26.7 - 19.4) * QLatActual + 1.e-10);
2250 :
2251 : // Calculate the compressor on and off times using a conventional thermostat curve
2252 0 : Ton = 3600.0 / (4.0 * heatPump.MaxONOFFCyclesperHour * (1.0 - RTF)); // duration of cooling coil on-cycle (sec)
2253 :
2254 0 : if ((CyclingScheme == CycFanCycCoil) && (heatPump.FanDelayTime != 0.0)) {
2255 : // For CycFanCycCoil, moisture is evaporated from the cooling coil back to the air stream
2256 : // until the fan cycle off. Assume no evaporation from the coil after the fan shuts off.
2257 0 : Toff = heatPump.FanDelayTime;
2258 : } else {
2259 : // For ContFanCycCoil, moisture is evaporated from the cooling coil back to the air stream
2260 : // for the entire heat pump off-cycle.
2261 0 : Toff = 3600.0 / (4.0 * heatPump.MaxONOFFCyclesperHour * RTF); // duration of cooling coil off-cycle (sec)
2262 : }
2263 :
2264 : // Cap Toff to meet the equation restriction
2265 0 : if (Gamma > 0.0) {
2266 0 : Toffa = min(Toff, 2.0 * Twet / Gamma);
2267 : } else {
2268 0 : Toffa = Toff;
2269 : }
2270 :
2271 : // Use sucessive substitution to solve for To
2272 0 : aa = (Gamma * Toffa) - (0.25 / Twet) * pow_2(Gamma) * pow_2(Toffa);
2273 :
2274 0 : To1 = aa + heatPump.HPTimeConstant;
2275 0 : Error = 1.0;
2276 0 : while (Error > 0.001) {
2277 0 : To2 = aa - heatPump.HPTimeConstant * (std::exp(-To1 / heatPump.HPTimeConstant) - 1.0);
2278 0 : Error = std::abs((To2 - To1) / To1);
2279 0 : To1 = To2;
2280 : }
2281 :
2282 : // Adjust Sensible Heat Ratio (SHR) using Latent Heat Ratio (LHR) multiplier
2283 : // Floating underflow errors occur when -Ton/HPTimeConstant is a large negative number.
2284 : // Cap lower limit at -700 to avoid the underflow errors.
2285 0 : aa = std::exp(max(-700.0, -Ton / heatPump.HPTimeConstant));
2286 : // Calculate latent heat ratio multiplier
2287 0 : LHRmult = max(((Ton - To2) / (Ton + heatPump.HPTimeConstant * (aa - 1.0))), 0.0);
2288 :
2289 : // Calculate part-load or "effective" sensible heat ratio
2290 0 : SHReff = 1.0 - (1.0 - SHRss) * LHRmult;
2291 :
2292 0 : if (SHReff < SHRss) SHReff = SHRss; // Effective SHR can be less than the steady-state SHR
2293 0 : if (SHReff > 1.0) SHReff = 1.0; // Effective sensible heat ratio can't be greater than 1.0
2294 :
2295 0 : return SHReff;
2296 : }
2297 :
2298 371285 : Real64 DegradF(EnergyPlusData &state,
2299 : std::string &FluidName, // Name of glycol used in source side
2300 : Real64 &Temp, // Temperature of the fluid
2301 : int &FluidIndex // Index number for the fluid
2302 : )
2303 : {
2304 : // FUNCTION INFORMATION:
2305 : // AUTHOR Kenneth Tang
2306 : // DATE WRITTEN October 2004
2307 : // MODIFIED na
2308 : // RE-ENGINEERED na
2309 :
2310 : // PURPOSE OF THIS FUNCTION:
2311 : // Calculate the degradation factor to predict the heat pump performance
2312 : // when antifreeze is used.
2313 : // METHODOLOGY EMPLOYED:
2314 : // Use FluidProperties to calculate the properties of water and glycol
2315 : // at the given temperature. Then substitute the properties into the equation.
2316 : // REFERENCES:
2317 : // Jin, H. 2002. Parameter Estimation Based Models of Water Source Heat Pumps. Phd Thesis.
2318 : // Oklahoma State University.
2319 :
2320 : // Using/Aliasing
2321 : using namespace FluidProperties;
2322 :
2323 : // Return value
2324 : Real64 DegradF;
2325 :
2326 : // Locals
2327 : // FUNCTION PARAMETER DEFINITIONS:
2328 : static constexpr std::string_view CalledFrom("HVACWaterToAir:DegradF");
2329 :
2330 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2331 : Real64 VisWater; // Viscosity of water [mPa-s]
2332 : Real64 DensityWater; // Density of water [kg/m3]
2333 : Real64 CpWater; // Specific heat of water [J/kg-K]
2334 : Real64 CondWater; // Conductivity of water [W/m-K]
2335 : Real64 VisCoolant; // Viscosity of water [mPa-s]
2336 : Real64 DensityCoolant; // Density of water [kg/m3]
2337 : Real64 CpCoolant; // Specific heat of water [J/kg-K]
2338 : Real64 CondCoolant; // Conductivity of water [W/m-K]
2339 :
2340 371285 : VisWater = GetViscosityGlycol(state, fluidNameWater, Temp, state.dataWaterToAirHeatPump->WaterIndex, CalledFrom);
2341 371285 : DensityWater = GetDensityGlycol(state, fluidNameWater, Temp, state.dataWaterToAirHeatPump->WaterIndex, CalledFrom);
2342 371285 : CpWater = GetSpecificHeatGlycol(state, fluidNameWater, Temp, state.dataWaterToAirHeatPump->WaterIndex, CalledFrom);
2343 371285 : CondWater = GetConductivityGlycol(state, fluidNameWater, Temp, state.dataWaterToAirHeatPump->WaterIndex, CalledFrom);
2344 371285 : VisCoolant = GetViscosityGlycol(state, FluidName, Temp, FluidIndex, CalledFrom);
2345 371285 : DensityCoolant = GetDensityGlycol(state, FluidName, Temp, FluidIndex, CalledFrom);
2346 371285 : CpCoolant = GetSpecificHeatGlycol(state, FluidName, Temp, FluidIndex, CalledFrom);
2347 371285 : CondCoolant = GetConductivityGlycol(state, FluidName, Temp, FluidIndex, CalledFrom);
2348 :
2349 742570 : DegradF = std::pow(VisCoolant / VisWater, -0.47) * std::pow(DensityCoolant / DensityWater, 0.8) * std::pow(CpCoolant / CpWater, 0.33) *
2350 371285 : std::pow(CondCoolant / CondWater, 0.67);
2351 :
2352 371285 : return DegradF;
2353 : }
2354 :
2355 38 : int GetCoilIndex(EnergyPlusData &state,
2356 : std::string const &CoilType, // must match coil types in this module
2357 : std::string const &CoilName, // must match coil names for the coil type
2358 : bool &ErrorsFound // set to true if problem
2359 : )
2360 : {
2361 :
2362 : // FUNCTION INFORMATION:
2363 : // AUTHOR R. Raustad
2364 : // DATE WRITTEN August 2007
2365 : // MODIFIED na
2366 : // RE-ENGINEERED na
2367 :
2368 : // PURPOSE OF THIS FUNCTION:
2369 : // This function looks up the given coil and returns the index. If
2370 : // incorrect coil type or name is given, ErrorsFound is returned as true and value is returned
2371 : // as zero.
2372 :
2373 : // Using/Aliasing
2374 : using FluidProperties::FindGlycol;
2375 :
2376 : // Return value
2377 : int IndexNum; // returned index of matched coil
2378 :
2379 : // Obtains and Allocates WatertoAirHP related parameters from input file
2380 38 : if (state.dataWaterToAirHeatPump->GetCoilsInputFlag) { // First time subroutine has been entered
2381 6 : GetWatertoAirHPInput(state);
2382 6 : state.dataWaterToAirHeatPump->WaterIndex = FindGlycol(state, fluidNameWater); // Initialize the WaterIndex once
2383 6 : state.dataWaterToAirHeatPump->GetCoilsInputFlag = false;
2384 : }
2385 :
2386 38 : IndexNum = UtilityRoutines::FindItemInList(CoilName, state.dataWaterToAirHeatPump->WatertoAirHP);
2387 :
2388 38 : if (IndexNum == 0) {
2389 0 : ShowSevereError(state, "Could not find CoilType=\"" + CoilType + "\" with Name=\"" + CoilName + "\"");
2390 0 : ErrorsFound = true;
2391 : }
2392 :
2393 38 : return IndexNum;
2394 : }
2395 :
2396 33 : Real64 GetCoilCapacity(EnergyPlusData &state,
2397 : std::string const &CoilType, // must match coil types in this module
2398 : std::string const &CoilName, // must match coil names for the coil type
2399 : bool &ErrorsFound // set to true if problem
2400 : )
2401 : {
2402 :
2403 : // FUNCTION INFORMATION:
2404 : // AUTHOR Linda Lawrie
2405 : // DATE WRITTEN February 2006
2406 : // MODIFIED na
2407 : // RE-ENGINEERED na
2408 :
2409 : // PURPOSE OF THIS FUNCTION:
2410 : // This function looks up the coil capacity for the given coil and returns it. If
2411 : // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
2412 : // as negative.
2413 :
2414 : // Using/Aliasing
2415 : using FluidProperties::FindGlycol;
2416 :
2417 : // Return value
2418 : Real64 CoilCapacity; // returned capacity of matched coil
2419 :
2420 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2421 : int WhichCoil;
2422 :
2423 : // Obtains and Allocates WatertoAirHP related parameters from input file
2424 33 : if (state.dataWaterToAirHeatPump->GetCoilsInputFlag) { // First time subroutine has been entered
2425 0 : state.dataWaterToAirHeatPump->WaterIndex = FindGlycol(state, fluidNameWater); // Initialize the WaterIndex once
2426 0 : GetWatertoAirHPInput(state);
2427 0 : state.dataWaterToAirHeatPump->GetCoilsInputFlag = false;
2428 : }
2429 :
2430 85 : if (UtilityRoutines::SameString(CoilType, "COIL:HEATING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION") ||
2431 52 : UtilityRoutines::SameString(CoilType, "COIL:COOLING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION")) {
2432 33 : WhichCoil = UtilityRoutines::FindItemInList(CoilName, state.dataWaterToAirHeatPump->WatertoAirHP);
2433 33 : if (WhichCoil != 0) {
2434 33 : if (UtilityRoutines::SameString(CoilType, "COIL:HEATING:WATERTOAIRHEATPUMP:PARAMETERESTIMATION")) {
2435 14 : CoilCapacity = state.dataWaterToAirHeatPump->WatertoAirHP(WhichCoil).HeatingCapacity;
2436 : } else {
2437 19 : CoilCapacity = state.dataWaterToAirHeatPump->WatertoAirHP(WhichCoil).CoolingCapacity;
2438 : }
2439 : }
2440 : } else {
2441 0 : WhichCoil = 0;
2442 : }
2443 :
2444 33 : if (WhichCoil == 0) {
2445 0 : ShowSevereError(state, "Could not find CoilType=\"" + CoilType + "\" with Name=\"" + CoilName + "\"");
2446 0 : ErrorsFound = true;
2447 0 : CoilCapacity = -1000.0;
2448 : }
2449 :
2450 33 : return CoilCapacity;
2451 : }
2452 :
2453 28 : int GetCoilInletNode(EnergyPlusData &state,
2454 : std::string const &CoilType, // must match coil types in this module
2455 : std::string const &CoilName, // must match coil names for the coil type
2456 : bool &ErrorsFound // set to true if problem
2457 : )
2458 : {
2459 :
2460 : // FUNCTION INFORMATION:
2461 : // AUTHOR Linda Lawrie
2462 : // DATE WRITTEN February 2006
2463 : // MODIFIED na
2464 : // RE-ENGINEERED na
2465 :
2466 : // PURPOSE OF THIS FUNCTION:
2467 : // This function looks up the given coil and returns the inlet node. If
2468 : // incorrect coil type or name is given, ErrorsFound is returned as true and value is returned
2469 : // as zero.
2470 :
2471 : // Using/Aliasing
2472 : using FluidProperties::FindGlycol;
2473 :
2474 : // Return value
2475 : int NodeNumber; // returned outlet node of matched coil
2476 :
2477 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2478 : int WhichCoil;
2479 :
2480 : // Obtains and Allocates WatertoAirHP related parameters from input file
2481 28 : if (state.dataWaterToAirHeatPump->GetCoilsInputFlag) { // First time subroutine has been entered
2482 0 : GetWatertoAirHPInput(state);
2483 0 : state.dataWaterToAirHeatPump->WaterIndex = FindGlycol(state, fluidNameWater); // Initialize the WaterIndex once
2484 0 : state.dataWaterToAirHeatPump->GetCoilsInputFlag = false;
2485 : }
2486 :
2487 28 : WhichCoil = UtilityRoutines::FindItemInList(CoilName, state.dataWaterToAirHeatPump->WatertoAirHP);
2488 28 : if (WhichCoil != 0) {
2489 28 : NodeNumber = state.dataWaterToAirHeatPump->WatertoAirHP(WhichCoil).AirInletNodeNum;
2490 : }
2491 :
2492 28 : if (WhichCoil == 0) {
2493 0 : ShowSevereError(state, "Could not find CoilType=\"" + CoilType + "\" with Name=\"" + CoilName + "\"");
2494 0 : ErrorsFound = true;
2495 0 : NodeNumber = 0;
2496 : }
2497 :
2498 28 : return NodeNumber;
2499 : }
2500 :
2501 28 : int GetCoilOutletNode(EnergyPlusData &state,
2502 : std::string const &CoilType, // must match coil types in this module
2503 : std::string const &CoilName, // must match coil names for the coil type
2504 : bool &ErrorsFound // set to true if problem
2505 : )
2506 : {
2507 :
2508 : // FUNCTION INFORMATION:
2509 : // AUTHOR R. Raustad
2510 : // DATE WRITTEN July 2007
2511 : // MODIFIED na
2512 : // RE-ENGINEERED na
2513 :
2514 : // PURPOSE OF THIS FUNCTION:
2515 : // This function looks up the given coil and returns the outlet node. If
2516 : // incorrect coil type or name is given, ErrorsFound is returned as true and value is returned
2517 : // as zero.
2518 :
2519 : // Using/Aliasing
2520 : using FluidProperties::FindGlycol;
2521 :
2522 : // Return value
2523 : int NodeNumber; // returned outlet node of matched coil
2524 :
2525 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
2526 : int WhichCoil;
2527 :
2528 : // Obtains and Allocates WatertoAirHP related parameters from input file
2529 28 : if (state.dataWaterToAirHeatPump->GetCoilsInputFlag) { // First time subroutine has been entered
2530 0 : GetWatertoAirHPInput(state);
2531 0 : state.dataWaterToAirHeatPump->WaterIndex = FindGlycol(state, fluidNameWater); // Initialize the WaterIndex once
2532 0 : state.dataWaterToAirHeatPump->GetCoilsInputFlag = false;
2533 : }
2534 :
2535 28 : WhichCoil = UtilityRoutines::FindItemInList(CoilName, state.dataWaterToAirHeatPump->WatertoAirHP);
2536 28 : if (WhichCoil != 0) {
2537 28 : NodeNumber = state.dataWaterToAirHeatPump->WatertoAirHP(WhichCoil).AirOutletNodeNum;
2538 : }
2539 :
2540 28 : if (WhichCoil == 0) {
2541 0 : ShowSevereError(state, "Could not find CoilType=\"" + CoilType + "\" with Name=\"" + CoilName + "\"");
2542 0 : ErrorsFound = true;
2543 0 : NodeNumber = 0;
2544 : }
2545 :
2546 28 : return NodeNumber;
2547 : }
2548 :
2549 : } // namespace WaterToAirHeatPump
2550 :
2551 2313 : } // namespace EnergyPlus
|