Line data Source code
1 : // EnergyPlus, Copyright (c) 1996-2025, 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 :
54 : // EnergyPlus Headers
55 : #include <EnergyPlus/Autosizing/Base.hh>
56 : #include <EnergyPlus/BranchNodeConnections.hh>
57 : #include <EnergyPlus/CurveManager.hh>
58 : #include <EnergyPlus/Data/EnergyPlusData.hh>
59 : #include <EnergyPlus/DataAirSystems.hh>
60 : #include <EnergyPlus/DataContaminantBalance.hh>
61 : #include <EnergyPlus/DataEnvironment.hh>
62 : #include <EnergyPlus/DataHeatBalance.hh>
63 : #include <EnergyPlus/DataLoopNode.hh>
64 : #include <EnergyPlus/DataPrecisionGlobals.hh>
65 : #include <EnergyPlus/DataSizing.hh>
66 : #include <EnergyPlus/Fans.hh>
67 : #include <EnergyPlus/FluidProperties.hh>
68 : #include <EnergyPlus/General.hh>
69 : #include <EnergyPlus/GeneralRoutines.hh>
70 : #include <EnergyPlus/GlobalNames.hh>
71 : #include <EnergyPlus/InputProcessing/InputProcessor.hh>
72 : #include <EnergyPlus/NodeInputManager.hh>
73 : #include <EnergyPlus/OutputProcessor.hh>
74 : #include <EnergyPlus/OutputReportPredefined.hh>
75 : #include <EnergyPlus/PlantUtilities.hh>
76 : #include <EnergyPlus/Psychrometrics.hh>
77 : #include <EnergyPlus/UtilityRoutines.hh>
78 : #include <EnergyPlus/WaterThermalTanks.hh>
79 : #include <EnergyPlus/WaterToAirHeatPumpSimple.hh>
80 :
81 : namespace EnergyPlus {
82 :
83 : namespace WaterToAirHeatPumpSimple {
84 :
85 : // Module containing the Water to Air Heat Pump simulation routines
86 :
87 : // MODULE INFORMATION:
88 : // AUTHOR Arun Shenoy
89 : // DATE WRITTEN Nov 2003
90 : // MODIFIED Brent Griffith, Sept 2010 plant upgrades
91 : // RE-ENGINEERED Kenneth Tang (Jan 2005)
92 :
93 : // PURPOSE OF THIS MODULE:
94 : // To encapsulate the data and algorithms required to
95 : // manage the Water to Air Heat Pump Simple Component
96 :
97 : // METHODOLOGY EMPLOYED:
98 :
99 : // REFERENCES:
100 : // (1) Lash.T.A.,1992.Simulation and Analysis of a Water Loop Heat Pump System.
101 : // M.S. Thesis, University of Illinois at Urbana Champaign.
102 : // (2) Shenoy, Arun. 2004. Simulation, Modeling and Analysis of Water to Air Heat Pump.
103 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
104 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
105 : // (3) Tang,C.C.. 2005. Modeling Packaged Heat Pumps in a Quasi-Steady
106 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
107 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
108 :
109 : constexpr std::array<std::string_view, static_cast<int>(WatertoAirHP::Num)> WatertoAirHPNamesUC{"HEATING", "COOLING"};
110 :
111 99788 : void SimWatertoAirHPSimple(EnergyPlusData &state,
112 : std::string_view CompName, // Coil Name
113 : int &CompIndex, // Index for Component name
114 : Real64 const SensLoad, // Sensible demand load [W]
115 : Real64 const LatentLoad, // Latent demand load [W]
116 : HVAC::FanOp const fanOp, // Continuous fan OR cycling compressor
117 : HVAC::CompressorOp const compressorOp,
118 : Real64 const PartLoadRatio,
119 : bool const FirstHVACIteration,
120 : Real64 const OnOffAirFlowRatio // ratio of comp on to comp off air flow rate
121 : )
122 : {
123 :
124 : // AUTHOR Arun Shenoy
125 : // DATE WRITTEN Nov 2003
126 : // RE-ENGINEERED Kenneth Tang (Jan 2005)
127 :
128 : // PURPOSE OF THIS SUBROUTINE:
129 : // This subroutine manages Simple Water to Air Heat Pump component simulation.
130 :
131 : // REFERENCES:
132 : // (1) Lash.T.A.,1992.Simulation and Analysis of a Water Loop Heat Pump System.
133 : // M.S. Thesis, University of Illinois at Urbana Champaign.
134 : // (2) Shenoy, Arun. 2004. Simulation, Modeling and Analysis of Water to Air Heat Pump.
135 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
136 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
137 : // (3) Tang,C.C.. 2005. Modeling Packaged Heat Pumps in a Quasi-Steady
138 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
139 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
140 :
141 : // percent on-time (on-time/cycle time)
142 : // shut off after compressor cycle off [s]
143 :
144 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
145 : int HPNum; // The WatertoAirHP that you are currently loading input into
146 :
147 : // Obtains and Allocates WatertoAirHP related parameters from input file
148 99788 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
149 0 : GetSimpleWatertoAirHPInput(state);
150 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
151 : }
152 :
153 99788 : if (CompIndex == 0) {
154 0 : HPNum = Util::FindItemInList(CompName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
155 0 : if (HPNum == 0) {
156 0 : ShowFatalError(state, format("WaterToAirHPSimple not found= {}", CompName));
157 : }
158 0 : CompIndex = HPNum;
159 : } else {
160 99788 : HPNum = CompIndex;
161 99788 : if (HPNum > state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs || HPNum < 1) {
162 0 : ShowFatalError(state,
163 0 : format("SimWatertoAirHPSimple: Invalid CompIndex passed={}, Number of Water to Air HPs={}, WaterToAir HP name={}",
164 : HPNum,
165 0 : state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs,
166 : CompName));
167 : }
168 99788 : if (!CompName.empty() && CompName != state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum).Name) {
169 0 : ShowFatalError(
170 : state,
171 0 : format("SimWatertoAirHPSimple: Invalid CompIndex passed={}, WaterToAir HP name={}, stored WaterToAir HP Name for that index={}",
172 : HPNum,
173 : CompName,
174 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum).Name));
175 : }
176 : }
177 :
178 99788 : auto const &simpleWAHP = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum);
179 :
180 99788 : if (simpleWAHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit) {
181 : // Cooling mode
182 49895 : InitSimpleWatertoAirHP(state, HPNum, SensLoad, LatentLoad, fanOp, OnOffAirFlowRatio, FirstHVACIteration);
183 49895 : CalcHPCoolingSimple(state, HPNum, fanOp, SensLoad, LatentLoad, compressorOp, PartLoadRatio, OnOffAirFlowRatio);
184 49895 : UpdateSimpleWatertoAirHP(state, HPNum);
185 49893 : } else if (simpleWAHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit) {
186 : // Heating mode
187 49893 : InitSimpleWatertoAirHP(state, HPNum, SensLoad, DataPrecisionGlobals::constant_zero, fanOp, OnOffAirFlowRatio, FirstHVACIteration);
188 49893 : CalcHPHeatingSimple(state, HPNum, fanOp, SensLoad, compressorOp, PartLoadRatio, OnOffAirFlowRatio);
189 49893 : UpdateSimpleWatertoAirHP(state, HPNum);
190 : } else {
191 0 : ShowFatalError(state, "SimWatertoAirHPSimple: WatertoAir heatpump not in either HEATING or COOLING mode");
192 : }
193 99788 : }
194 :
195 6 : void GetSimpleWatertoAirHPInput(EnergyPlusData &state)
196 : {
197 :
198 : // SUBROUTINE INFORMATION:
199 : // AUTHOR Arun Shenoy
200 : // DATE WRITTEN Nov 2003
201 : // RE-ENGINEERED Kenneth Tang (Jan 2005)
202 :
203 : // PURPOSE OF THIS SUBROUTINE:
204 : // Obtains input data for HPs and stores it in HP data structures
205 :
206 : // METHODOLOGY EMPLOYED:
207 : // Uses "Get" routines to read in data.
208 :
209 : // REFERENCES:
210 : // (1) Lash.T.A.,1992.Simulation and Analysis of a Water loop Heat Pump System.
211 : // M.S. Thesis, University of Illinois at Urbana Champaign.
212 : // (2) Shenoy, Arun. 2004. Simulation, Modeling and Analysis of Water to Air Heat Pump.
213 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
214 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
215 : // (3) Tang,C.C.. 2005. Modeling Packaged Heat Pumps in a Quasi-Steady
216 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
217 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
218 :
219 : // SUBROUTINE PARAMETER DEFINITIONS:
220 : static constexpr std::string_view RoutineName("GetSimpleWatertoAirHPInput: "); // include trailing blank space
221 : static constexpr std::string_view routineName = "GetSimpleWatertoAirHPInput";
222 :
223 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
224 : int HPNum; // The Water to Air HP that you are currently loading input into
225 : int NumCool; // Counter for cooling coil
226 : int NumHeat; // Counter for heating coil
227 : int WatertoAirHPNum; // Counter
228 : int NumAlphas; // Number of variables in String format
229 : int NumNums; // Number of variables in Numeric format
230 : int NumParams; // Total number of input fields
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 6 : std::string CurrentModuleObject; // for ease in getting objects
236 6 : Array1D_string AlphArray; // Alpha input items for object
237 6 : Array1D_string cAlphaFields; // Alpha field names
238 6 : Array1D_string cNumericFields; // Numeric field names
239 6 : Array1D<Real64> NumArray; // Numeric input items for object
240 6 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
241 6 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
242 :
243 6 : NumCool = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:WaterToAirHeatPump:EquationFit");
244 6 : NumHeat = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:WaterToAirHeatPump:EquationFit");
245 6 : state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs = NumCool + NumHeat;
246 6 : HPNum = 0;
247 :
248 6 : if (state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs <= 0) {
249 0 : ShowSevereError(state, "No Equipment found in SimWatertoAirHPSimple");
250 0 : ErrorsFound = true;
251 : }
252 :
253 : // Allocate Arrays
254 6 : if (state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs > 0) {
255 6 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP.allocate(state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs);
256 6 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag.dimension(state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs, true);
257 6 : state.dataHeatBal->HeatReclaimSimple_WAHPCoil.allocate(state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs);
258 : }
259 :
260 6 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
261 : state, "Coil:Cooling:WaterToAirHeatPump:EquationFit", NumParams, NumAlphas, NumNums);
262 6 : MaxNums = max(MaxNums, NumNums);
263 6 : MaxAlphas = max(MaxAlphas, NumAlphas);
264 6 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
265 : state, "Coil:Heating:WaterToAirHeatPump:EquationFit", NumParams, NumAlphas, NumNums);
266 6 : MaxNums = max(MaxNums, NumNums);
267 6 : MaxAlphas = max(MaxAlphas, NumAlphas);
268 6 : AlphArray.allocate(MaxAlphas);
269 6 : cAlphaFields.allocate(MaxAlphas);
270 6 : lAlphaBlanks.dimension(MaxAlphas, true);
271 6 : cNumericFields.allocate(MaxNums);
272 6 : lNumericBlanks.dimension(MaxNums, true);
273 6 : NumArray.dimension(MaxNums, 0.0);
274 :
275 : // Get the data for cooling coil
276 6 : CurrentModuleObject = "Coil:Cooling:WaterToAirHeatPump:EquationFit";
277 :
278 12 : for (WatertoAirHPNum = 1; WatertoAirHPNum <= NumCool; ++WatertoAirHPNum) {
279 :
280 6 : ++HPNum;
281 6 : auto &simpleWAHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
282 6 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
283 : CurrentModuleObject,
284 : HPNum,
285 : AlphArray,
286 : NumAlphas,
287 : NumArray,
288 : NumNums,
289 : IOStat,
290 : lNumericBlanks,
291 : lAlphaBlanks,
292 : cAlphaFields,
293 : cNumericFields);
294 :
295 6 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, AlphArray(1)};
296 :
297 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
298 6 : GlobalNames::VerifyUniqueCoilName(state, CurrentModuleObject, AlphArray(1), ErrorsFound, format("{} Name", CurrentModuleObject));
299 6 : simpleWAHP.Name = AlphArray(1);
300 6 : simpleWAHP.WAHPType = WatertoAirHP::Cooling;
301 6 : simpleWAHP.WAHPPlantType = DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit;
302 6 : simpleWAHP.RatedAirVolFlowRate = NumArray(1);
303 6 : simpleWAHP.RatedWaterVolFlowRate = NumArray(2);
304 6 : simpleWAHP.RatedCapCoolTotal = NumArray(3);
305 6 : simpleWAHP.RatedCapCoolSens = NumArray(4);
306 6 : simpleWAHP.RatedCOPCoolAtRatedCdts = NumArray(5);
307 6 : simpleWAHP.RatedEntWaterTemp = NumArray(6);
308 6 : simpleWAHP.RatedEntAirDrybulbTemp = NumArray(7);
309 6 : simpleWAHP.RatedEntAirWetbulbTemp = NumArray(8);
310 :
311 6 : if (lAlphaBlanks(6)) {
312 0 : ShowSevereEmptyField(state, eoh, cAlphaFields(6));
313 0 : ErrorsFound = true;
314 6 : } else if ((simpleWAHP.TotalCoolCapCurve = Curve::GetCurve(state, AlphArray(6))) == nullptr) {
315 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(6), AlphArray(6));
316 0 : ErrorsFound = true;
317 6 : } else if (simpleWAHP.TotalCoolCapCurve->numDims != 4) {
318 0 : Curve::ShowSevereCurveDims(state, eoh, cAlphaFields(6), AlphArray(6), "4", simpleWAHP.TotalCoolCapCurve->numDims);
319 0 : ErrorsFound = true;
320 : }
321 :
322 6 : if (lAlphaBlanks(7)) {
323 0 : ShowSevereEmptyField(state, eoh, cAlphaFields(7));
324 0 : ErrorsFound = true;
325 6 : } else if ((simpleWAHP.SensCoolCapCurve = Curve::GetCurve(state, AlphArray(7))) == nullptr) {
326 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(7), AlphArray(7));
327 0 : ErrorsFound = true;
328 6 : } else if (simpleWAHP.SensCoolCapCurve->numDims != 5) {
329 0 : Curve::ShowSevereCurveDims(state, eoh, cAlphaFields(7), AlphArray(7), "5", simpleWAHP.SensCoolCapCurve->numDims);
330 0 : ErrorsFound = true;
331 : }
332 :
333 6 : if (lAlphaBlanks(8)) {
334 0 : ShowSevereEmptyField(state, eoh, cAlphaFields(8));
335 0 : ErrorsFound = true;
336 6 : } else if ((simpleWAHP.CoolPowCurve = Curve::GetCurve(state, AlphArray(8))) == nullptr) {
337 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(8), AlphArray(8));
338 0 : ErrorsFound = true;
339 6 : } else if (simpleWAHP.CoolPowCurve->numDims != 4) {
340 0 : Curve::ShowSevereCurveDims(state, eoh, cAlphaFields(8), AlphArray(8), "4", simpleWAHP.CoolPowCurve->numDims);
341 0 : ErrorsFound = true;
342 : }
343 :
344 6 : if (lAlphaBlanks(9)) {
345 0 : ShowSevereEmptyField(state, eoh, cAlphaFields(9));
346 0 : ErrorsFound = true;
347 6 : } else if ((simpleWAHP.PLFCurve = Curve::GetCurve(state, AlphArray(9))) == nullptr) {
348 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(9), AlphArray(9));
349 0 : ErrorsFound = true;
350 6 : } else if (simpleWAHP.PLFCurve->numDims != 1) {
351 0 : Curve::ShowSevereCurveDims(state, eoh, cAlphaFields(9), AlphArray(9), "1", simpleWAHP.PLFCurve->numDims);
352 0 : ErrorsFound = true;
353 : } else {
354 :
355 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
356 6 : Real64 MinCurveVal = 999.0;
357 6 : Real64 MaxCurveVal = -999.0;
358 6 : Real64 CurveInput = 0.0;
359 6 : Real64 MinCurvePLR{0.0};
360 6 : Real64 MaxCurvePLR{0.0};
361 :
362 606 : while (CurveInput <= 1.0) {
363 600 : Real64 CurveVal = simpleWAHP.PLFCurve->value(state, CurveInput);
364 600 : if (CurveVal < MinCurveVal) {
365 6 : MinCurveVal = CurveVal;
366 6 : MinCurvePLR = CurveInput;
367 : }
368 600 : if (CurveVal > MaxCurveVal) {
369 280 : MaxCurveVal = CurveVal;
370 280 : MaxCurvePLR = CurveInput;
371 : }
372 600 : CurveInput += 0.01;
373 : }
374 6 : if (MinCurveVal < 0.7) {
375 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, simpleWAHP.Name));
376 0 : ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFields(9), AlphArray(9)));
377 0 : ShowContinueError(state,
378 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
379 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
380 0 : Curve::SetCurveOutputMinValue(state, simpleWAHP.PLFCurve->Num, ErrorsFound, 0.7);
381 : }
382 :
383 6 : if (MaxCurveVal > 1.0) {
384 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, simpleWAHP.Name));
385 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(9), AlphArray(9)));
386 0 : ShowContinueError(state,
387 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
388 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
389 0 : Curve::SetCurveOutputMaxValue(state, simpleWAHP.PLFCurve->Num, ErrorsFound, 1.0);
390 : }
391 : }
392 :
393 6 : CheckSimpleWAHPRatedCurvesOutputs(state, simpleWAHP.Name);
394 6 : simpleWAHP.Twet_Rated = NumArray(9);
395 6 : simpleWAHP.Gamma_Rated = NumArray(10);
396 6 : simpleWAHP.MaxONOFFCyclesperHour = NumArray(11);
397 6 : simpleWAHP.LatentCapacityTimeConstant = NumArray(12);
398 6 : simpleWAHP.FanDelayTime = NumArray(13);
399 :
400 6 : state.dataHeatBal->HeatReclaimSimple_WAHPCoil(WatertoAirHPNum).Name = simpleWAHP.Name;
401 6 : state.dataHeatBal->HeatReclaimSimple_WAHPCoil(WatertoAirHPNum).SourceType = CurrentModuleObject;
402 :
403 6 : simpleWAHP.WaterInletNodeNum = GetOnlySingleNode(state,
404 6 : AlphArray(2),
405 : ErrorsFound,
406 : DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpEquationFit,
407 6 : simpleWAHP.Name,
408 : DataLoopNode::NodeFluidType::Water,
409 : DataLoopNode::ConnectionType::Inlet,
410 : NodeInputManager::CompFluidStream::Secondary,
411 : DataLoopNode::ObjectIsNotParent);
412 6 : simpleWAHP.WaterOutletNodeNum = GetOnlySingleNode(state,
413 6 : AlphArray(3),
414 : ErrorsFound,
415 : DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpEquationFit,
416 6 : simpleWAHP.Name,
417 : DataLoopNode::NodeFluidType::Water,
418 : DataLoopNode::ConnectionType::Outlet,
419 : NodeInputManager::CompFluidStream::Secondary,
420 : DataLoopNode::ObjectIsNotParent);
421 6 : simpleWAHP.AirInletNodeNum = GetOnlySingleNode(state,
422 6 : AlphArray(4),
423 : ErrorsFound,
424 : DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpEquationFit,
425 6 : simpleWAHP.Name,
426 : DataLoopNode::NodeFluidType::Air,
427 : DataLoopNode::ConnectionType::Inlet,
428 : NodeInputManager::CompFluidStream::Primary,
429 : DataLoopNode::ObjectIsNotParent);
430 12 : simpleWAHP.AirOutletNodeNum = GetOnlySingleNode(state,
431 6 : AlphArray(5),
432 : ErrorsFound,
433 : DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpEquationFit,
434 6 : simpleWAHP.Name,
435 : DataLoopNode::NodeFluidType::Air,
436 : DataLoopNode::ConnectionType::Outlet,
437 : NodeInputManager::CompFluidStream::Primary,
438 : DataLoopNode::ObjectIsNotParent);
439 :
440 12 : BranchNodeConnections::TestCompSet(state, CurrentModuleObject, simpleWAHP.Name, AlphArray(2), AlphArray(3), "Water Nodes");
441 6 : BranchNodeConnections::TestCompSet(state, CurrentModuleObject, simpleWAHP.Name, AlphArray(4), AlphArray(5), "Air Nodes");
442 :
443 : // Setup Report variables for the cooling coil
444 : // CurrentModuleObject = "Coil:Cooling:WaterToAirHeatPump:EquationFit"
445 12 : SetupOutputVariable(state,
446 : "Cooling Coil Electricity Energy",
447 : Constant::Units::J,
448 6 : simpleWAHP.Energy,
449 : OutputProcessor::TimeStepType::System,
450 : OutputProcessor::StoreType::Sum,
451 6 : simpleWAHP.Name,
452 : Constant::eResource::Electricity,
453 : OutputProcessor::Group::HVAC,
454 : OutputProcessor::EndUseCat::Cooling);
455 12 : SetupOutputVariable(state,
456 : "Cooling Coil Total Cooling Energy",
457 : Constant::Units::J,
458 6 : simpleWAHP.EnergyLoadTotal,
459 : OutputProcessor::TimeStepType::System,
460 : OutputProcessor::StoreType::Sum,
461 6 : simpleWAHP.Name,
462 : Constant::eResource::EnergyTransfer,
463 : OutputProcessor::Group::HVAC,
464 : OutputProcessor::EndUseCat::CoolingCoils);
465 12 : SetupOutputVariable(state,
466 : "Cooling Coil Sensible Cooling Energy",
467 : Constant::Units::J,
468 6 : simpleWAHP.EnergySensible,
469 : OutputProcessor::TimeStepType::System,
470 : OutputProcessor::StoreType::Sum,
471 6 : simpleWAHP.Name);
472 12 : SetupOutputVariable(state,
473 : "Cooling Coil Latent Cooling Energy",
474 : Constant::Units::J,
475 6 : simpleWAHP.EnergyLatent,
476 : OutputProcessor::TimeStepType::System,
477 : OutputProcessor::StoreType::Sum,
478 6 : simpleWAHP.Name);
479 12 : SetupOutputVariable(state,
480 : "Cooling Coil Source Side Heat Transfer Energy",
481 : Constant::Units::J,
482 6 : simpleWAHP.EnergySource,
483 : OutputProcessor::TimeStepType::System,
484 : OutputProcessor::StoreType::Sum,
485 6 : simpleWAHP.Name,
486 : Constant::eResource::PlantLoopCoolingDemand,
487 : OutputProcessor::Group::HVAC,
488 : OutputProcessor::EndUseCat::CoolingCoils);
489 :
490 : // create predefined report entries
491 6 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilType, simpleWAHP.Name, CurrentModuleObject);
492 12 : OutputReportPredefined::PreDefTableEntry(
493 6 : state, state.dataOutRptPredefined->pdchCoolCoilTotCap, simpleWAHP.Name, simpleWAHP.RatedCapCoolTotal);
494 12 : OutputReportPredefined::PreDefTableEntry(
495 6 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, simpleWAHP.Name, simpleWAHP.RatedCapCoolSens);
496 12 : OutputReportPredefined::PreDefTableEntry(
497 6 : state, state.dataOutRptPredefined->pdchCoolCoilLatCap, simpleWAHP.Name, simpleWAHP.RatedCapCoolTotal - simpleWAHP.RatedCapCoolSens);
498 12 : OutputReportPredefined::PreDefTableEntry(
499 6 : state, state.dataOutRptPredefined->pdchCoolCoilSHR, simpleWAHP.Name, simpleWAHP.RatedCapCoolSens / simpleWAHP.RatedCapCoolTotal);
500 12 : OutputReportPredefined::PreDefTableEntry(
501 6 : state, state.dataOutRptPredefined->pdchCoolCoilNomEff, simpleWAHP.Name, simpleWAHP.RatedPowerCool / simpleWAHP.RatedCapCoolTotal);
502 :
503 6 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWAHPType, simpleWAHP.Name, CurrentModuleObject);
504 : }
505 :
506 : // Get the data for heating coil
507 6 : CurrentModuleObject = "Coil:Heating:WaterToAirHeatPump:EquationFit";
508 :
509 10 : for (WatertoAirHPNum = 1; WatertoAirHPNum <= NumHeat; ++WatertoAirHPNum) {
510 :
511 4 : ++HPNum;
512 4 : auto &simpleWAHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
513 4 : state.dataInputProcessing->inputProcessor->getObjectItem(state,
514 : CurrentModuleObject,
515 : WatertoAirHPNum,
516 : AlphArray,
517 : NumAlphas,
518 : NumArray,
519 : NumNums,
520 : IOStat,
521 : lNumericBlanks,
522 : lAlphaBlanks,
523 : cAlphaFields,
524 : cNumericFields);
525 :
526 4 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, AlphArray(1)};
527 :
528 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
529 4 : GlobalNames::VerifyUniqueCoilName(state, CurrentModuleObject, AlphArray(1), ErrorsFound, format("{} Name", CurrentModuleObject));
530 4 : simpleWAHP.Name = AlphArray(1);
531 4 : simpleWAHP.WAHPType = WatertoAirHP::Heating;
532 4 : simpleWAHP.WAHPPlantType = DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit;
533 4 : simpleWAHP.RatedAirVolFlowRate = NumArray(1);
534 4 : simpleWAHP.RatedWaterVolFlowRate = NumArray(2);
535 4 : simpleWAHP.RatedCapHeat = NumArray(3);
536 4 : simpleWAHP.RatedCOPHeatAtRatedCdts = NumArray(4);
537 4 : simpleWAHP.RatedEntWaterTemp = NumArray(5);
538 4 : simpleWAHP.RatedEntAirDrybulbTemp = NumArray(6);
539 4 : simpleWAHP.RatioRatedHeatRatedTotCoolCap = NumArray(7);
540 :
541 4 : if (lAlphaBlanks(6)) {
542 0 : ShowSevereEmptyField(state, eoh, cAlphaFields(6));
543 0 : ErrorsFound = true;
544 4 : } else if ((simpleWAHP.HeatCapCurve = Curve::GetCurve(state, AlphArray(6))) == nullptr) {
545 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(6), AlphArray(6));
546 0 : ErrorsFound = true;
547 4 : } else if (simpleWAHP.HeatCapCurve->numDims != 4) {
548 0 : Curve::ShowSevereCurveDims(state, eoh, cAlphaFields(6), AlphArray(6), "4", simpleWAHP.HeatCapCurve->numDims);
549 0 : ErrorsFound = true;
550 : }
551 :
552 4 : if (lAlphaBlanks(7)) {
553 0 : ShowSevereEmptyField(state, eoh, cAlphaFields(7));
554 0 : ErrorsFound = true;
555 4 : } else if ((simpleWAHP.HeatPowCurve = Curve::GetCurve(state, AlphArray(7))) == nullptr) {
556 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(7), AlphArray(7));
557 0 : ErrorsFound = true;
558 4 : } else if (simpleWAHP.HeatPowCurve->numDims != 4) {
559 0 : Curve::ShowSevereCurveDims(state, eoh, cAlphaFields(7), AlphArray(7), "4", simpleWAHP.HeatPowCurve->numDims);
560 0 : ErrorsFound = true;
561 : }
562 :
563 4 : if (lAlphaBlanks(8)) {
564 0 : ShowSevereEmptyField(state, eoh, cAlphaFields(8));
565 0 : ErrorsFound = true;
566 4 : } else if ((simpleWAHP.PLFCurve = Curve::GetCurve(state, AlphArray(8))) == nullptr) {
567 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(8), AlphArray(8));
568 0 : ErrorsFound = true;
569 4 : } else if (simpleWAHP.PLFCurve->numDims != 1) {
570 0 : Curve::ShowSevereCurveDims(state, eoh, cAlphaFields(8), AlphArray(8), "1", simpleWAHP.PLFCurve->numDims);
571 0 : ErrorsFound = true;
572 : } else {
573 : // Test PLF curve minimum and maximum. Cap if less than 0.7 or greater than 1.0.
574 4 : Real64 MinCurveVal = 999.0;
575 4 : Real64 MaxCurveVal = -999.0;
576 4 : Real64 CurveInput = 0.0;
577 4 : Real64 MinCurvePLR{0.0};
578 4 : Real64 MaxCurvePLR{0.0};
579 :
580 404 : while (CurveInput <= 1.0) {
581 400 : Real64 CurveVal = simpleWAHP.PLFCurve->value(state, CurveInput);
582 400 : if (CurveVal < MinCurveVal) {
583 4 : MinCurveVal = CurveVal;
584 4 : MinCurvePLR = CurveInput;
585 396 : } else if (CurveVal > MaxCurveVal) {
586 236 : MaxCurveVal = CurveVal;
587 236 : MaxCurvePLR = CurveInput;
588 : }
589 400 : CurveInput += 0.01;
590 : }
591 :
592 4 : if (MinCurveVal < 0.7) {
593 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, simpleWAHP.Name));
594 0 : ShowContinueError(state, format("...{}=\"{}\" has out of range values.", cAlphaFields(8), AlphArray(8)));
595 0 : ShowContinueError(state,
596 0 : format("...Curve minimum must be >= 0.7, curve min at PLR = {:.2T} is {:.3T}", MinCurvePLR, MinCurveVal));
597 0 : ShowContinueError(state, "...Setting curve minimum to 0.7 and simulation continues.");
598 0 : Curve::SetCurveOutputMinValue(state, simpleWAHP.PLFCurve->Num, ErrorsFound, 0.7);
599 : }
600 :
601 4 : if (MaxCurveVal > 1.0) {
602 0 : ShowWarningError(state, format("{}{}=\"{}\", invalid", RoutineName, CurrentModuleObject, simpleWAHP.Name));
603 0 : ShowContinueError(state, format("...{} = {} has out of range value.", cAlphaFields(8), AlphArray(8)));
604 0 : ShowContinueError(state,
605 0 : format("...Curve maximum must be <= 1.0, curve max at PLR = {:.2T} is {:.3T}", MaxCurvePLR, MaxCurveVal));
606 0 : ShowContinueError(state, "...Setting curve maximum to 1.0 and simulation continues.");
607 0 : Curve::SetCurveOutputMaxValue(state, simpleWAHP.PLFCurve->Num, ErrorsFound, 1.0);
608 : }
609 : }
610 :
611 4 : CheckSimpleWAHPRatedCurvesOutputs(state, simpleWAHP.Name);
612 4 : simpleWAHP.WaterInletNodeNum = GetOnlySingleNode(state,
613 4 : AlphArray(2),
614 : ErrorsFound,
615 : DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpEquationFit,
616 4 : simpleWAHP.Name,
617 : DataLoopNode::NodeFluidType::Water,
618 : DataLoopNode::ConnectionType::Inlet,
619 : NodeInputManager::CompFluidStream::Secondary,
620 : DataLoopNode::ObjectIsNotParent);
621 4 : simpleWAHP.WaterOutletNodeNum = GetOnlySingleNode(state,
622 4 : AlphArray(3),
623 : ErrorsFound,
624 : DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpEquationFit,
625 4 : simpleWAHP.Name,
626 : DataLoopNode::NodeFluidType::Water,
627 : DataLoopNode::ConnectionType::Outlet,
628 : NodeInputManager::CompFluidStream::Secondary,
629 : DataLoopNode::ObjectIsNotParent);
630 4 : simpleWAHP.AirInletNodeNum = GetOnlySingleNode(state,
631 4 : AlphArray(4),
632 : ErrorsFound,
633 : DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpEquationFit,
634 4 : simpleWAHP.Name,
635 : DataLoopNode::NodeFluidType::Air,
636 : DataLoopNode::ConnectionType::Inlet,
637 : NodeInputManager::CompFluidStream::Primary,
638 : DataLoopNode::ObjectIsNotParent);
639 8 : simpleWAHP.AirOutletNodeNum = GetOnlySingleNode(state,
640 4 : AlphArray(5),
641 : ErrorsFound,
642 : DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpEquationFit,
643 4 : simpleWAHP.Name,
644 : DataLoopNode::NodeFluidType::Air,
645 : DataLoopNode::ConnectionType::Outlet,
646 : NodeInputManager::CompFluidStream::Primary,
647 : DataLoopNode::ObjectIsNotParent);
648 :
649 8 : BranchNodeConnections::TestCompSet(state, CurrentModuleObject, simpleWAHP.Name, AlphArray(2), AlphArray(3), "Water Nodes");
650 4 : BranchNodeConnections::TestCompSet(state, CurrentModuleObject, simpleWAHP.Name, AlphArray(4), AlphArray(5), "Air Nodes");
651 :
652 : // CurrentModuleObject = "Coil:Cooling:WaterToAirHeatPump:EquationFit"
653 8 : SetupOutputVariable(state,
654 : "Heating Coil Electricity Energy",
655 : Constant::Units::J,
656 4 : simpleWAHP.Energy,
657 : OutputProcessor::TimeStepType::System,
658 : OutputProcessor::StoreType::Sum,
659 4 : simpleWAHP.Name,
660 : Constant::eResource::Electricity,
661 : OutputProcessor::Group::HVAC,
662 : OutputProcessor::EndUseCat::Heating);
663 8 : SetupOutputVariable(state,
664 : "Heating Coil Heating Energy",
665 : Constant::Units::J,
666 4 : simpleWAHP.EnergyLoadTotal,
667 : OutputProcessor::TimeStepType::System,
668 : OutputProcessor::StoreType::Sum,
669 4 : simpleWAHP.Name,
670 : Constant::eResource::EnergyTransfer,
671 : OutputProcessor::Group::HVAC,
672 : OutputProcessor::EndUseCat::HeatingCoils);
673 8 : SetupOutputVariable(state,
674 : "Heating Coil Source Side Heat Transfer Energy",
675 : Constant::Units::J,
676 4 : simpleWAHP.EnergySource,
677 : OutputProcessor::TimeStepType::System,
678 : OutputProcessor::StoreType::Sum,
679 4 : simpleWAHP.Name,
680 : Constant::eResource::PlantLoopHeatingDemand,
681 : OutputProcessor::Group::HVAC,
682 : OutputProcessor::EndUseCat::HeatingCoils);
683 :
684 : // create predefined report entries
685 4 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilType, simpleWAHP.Name, CurrentModuleObject);
686 4 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, simpleWAHP.Name, simpleWAHP.RatedCapHeat);
687 8 : OutputReportPredefined::PreDefTableEntry(
688 4 : state, state.dataOutRptPredefined->pdchHeatCoilNomEff, simpleWAHP.Name, simpleWAHP.RatedPowerHeat / simpleWAHP.RatedCapHeat);
689 :
690 4 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWAHPType, simpleWAHP.Name, CurrentModuleObject);
691 : }
692 :
693 6 : AlphArray.deallocate();
694 6 : cAlphaFields.deallocate();
695 6 : lAlphaBlanks.deallocate();
696 6 : cNumericFields.deallocate();
697 6 : lNumericBlanks.deallocate();
698 6 : NumArray.deallocate();
699 :
700 6 : if (ErrorsFound) {
701 0 : ShowFatalError(state, format("{} Errors found getting input. Program terminates.", RoutineName));
702 : }
703 :
704 16 : for (HPNum = 1; HPNum <= state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs; ++HPNum) {
705 10 : auto &simpleWAHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
706 10 : if (simpleWAHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit) {
707 : // COOLING COIL Setup Report variables for the Heat Pump
708 12 : SetupOutputVariable(state,
709 : "Cooling Coil Electricity Rate",
710 : Constant::Units::W,
711 6 : simpleWAHP.Power,
712 : OutputProcessor::TimeStepType::System,
713 : OutputProcessor::StoreType::Average,
714 6 : simpleWAHP.Name);
715 12 : SetupOutputVariable(state,
716 : "Cooling Coil Total Cooling Rate",
717 : Constant::Units::W,
718 6 : simpleWAHP.QLoadTotal,
719 : OutputProcessor::TimeStepType::System,
720 : OutputProcessor::StoreType::Average,
721 6 : simpleWAHP.Name);
722 12 : SetupOutputVariable(state,
723 : "Cooling Coil Sensible Cooling Rate",
724 : Constant::Units::W,
725 6 : simpleWAHP.QSensible,
726 : OutputProcessor::TimeStepType::System,
727 : OutputProcessor::StoreType::Average,
728 6 : simpleWAHP.Name);
729 12 : SetupOutputVariable(state,
730 : "Cooling Coil Latent Cooling Rate",
731 : Constant::Units::W,
732 6 : simpleWAHP.QLatent,
733 : OutputProcessor::TimeStepType::System,
734 : OutputProcessor::StoreType::Average,
735 6 : simpleWAHP.Name);
736 12 : SetupOutputVariable(state,
737 : "Cooling Coil Source Side Heat Transfer Rate",
738 : Constant::Units::W,
739 6 : simpleWAHP.QSource,
740 : OutputProcessor::TimeStepType::System,
741 : OutputProcessor::StoreType::Average,
742 6 : simpleWAHP.Name);
743 12 : SetupOutputVariable(state,
744 : "Cooling Coil Part Load Ratio",
745 : Constant::Units::None,
746 6 : simpleWAHP.PartLoadRatio,
747 : OutputProcessor::TimeStepType::System,
748 : OutputProcessor::StoreType::Average,
749 6 : simpleWAHP.Name);
750 12 : SetupOutputVariable(state,
751 : "Cooling Coil Runtime Fraction",
752 : Constant::Units::None,
753 6 : simpleWAHP.RunFrac,
754 : OutputProcessor::TimeStepType::System,
755 : OutputProcessor::StoreType::Average,
756 6 : simpleWAHP.Name);
757 :
758 12 : SetupOutputVariable(state,
759 : "Cooling Coil Air Mass Flow Rate",
760 : Constant::Units::kg_s,
761 6 : simpleWAHP.AirMassFlowRate,
762 : OutputProcessor::TimeStepType::System,
763 : OutputProcessor::StoreType::Average,
764 6 : simpleWAHP.Name);
765 12 : SetupOutputVariable(state,
766 : "Cooling Coil Air Inlet Temperature",
767 : Constant::Units::C,
768 6 : simpleWAHP.InletAirDBTemp,
769 : OutputProcessor::TimeStepType::System,
770 : OutputProcessor::StoreType::Average,
771 6 : simpleWAHP.Name);
772 12 : SetupOutputVariable(state,
773 : "Cooling Coil Air Inlet Humidity Ratio",
774 : Constant::Units::kgWater_kgDryAir,
775 6 : simpleWAHP.InletAirHumRat,
776 : OutputProcessor::TimeStepType::System,
777 : OutputProcessor::StoreType::Average,
778 6 : simpleWAHP.Name);
779 12 : SetupOutputVariable(state,
780 : "Cooling Coil Air Outlet Temperature",
781 : Constant::Units::C,
782 6 : simpleWAHP.OutletAirDBTemp,
783 : OutputProcessor::TimeStepType::System,
784 : OutputProcessor::StoreType::Average,
785 6 : simpleWAHP.Name);
786 12 : SetupOutputVariable(state,
787 : "Cooling Coil Air Outlet Humidity Ratio",
788 : Constant::Units::kgWater_kgDryAir,
789 6 : simpleWAHP.OutletAirHumRat,
790 : OutputProcessor::TimeStepType::System,
791 : OutputProcessor::StoreType::Average,
792 6 : simpleWAHP.Name);
793 12 : SetupOutputVariable(state,
794 : "Cooling Coil Source Side Mass Flow Rate",
795 : Constant::Units::kg_s,
796 6 : simpleWAHP.WaterMassFlowRate,
797 : OutputProcessor::TimeStepType::System,
798 : OutputProcessor::StoreType::Average,
799 6 : simpleWAHP.Name);
800 12 : SetupOutputVariable(state,
801 : "Cooling Coil Source Side Inlet Temperature",
802 : Constant::Units::C,
803 6 : simpleWAHP.InletWaterTemp,
804 : OutputProcessor::TimeStepType::System,
805 : OutputProcessor::StoreType::Average,
806 6 : simpleWAHP.Name);
807 12 : SetupOutputVariable(state,
808 : "Cooling Coil Source Side Outlet Temperature",
809 : Constant::Units::C,
810 6 : simpleWAHP.OutletWaterTemp,
811 : OutputProcessor::TimeStepType::System,
812 : OutputProcessor::StoreType::Average,
813 6 : simpleWAHP.Name);
814 :
815 4 : } else if (simpleWAHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit) {
816 : // HEATING COIL Setup Report variables for the Heat Pump
817 8 : SetupOutputVariable(state,
818 : "Heating Coil Electricity Rate",
819 : Constant::Units::W,
820 4 : simpleWAHP.Power,
821 : OutputProcessor::TimeStepType::System,
822 : OutputProcessor::StoreType::Average,
823 4 : simpleWAHP.Name);
824 8 : SetupOutputVariable(state,
825 : "Heating Coil Heating Rate",
826 : Constant::Units::W,
827 4 : simpleWAHP.QLoadTotal,
828 : OutputProcessor::TimeStepType::System,
829 : OutputProcessor::StoreType::Average,
830 4 : simpleWAHP.Name);
831 8 : SetupOutputVariable(state,
832 : "Heating Coil Sensible Heating Rate",
833 : Constant::Units::W,
834 4 : simpleWAHP.QSensible,
835 : OutputProcessor::TimeStepType::System,
836 : OutputProcessor::StoreType::Average,
837 4 : simpleWAHP.Name);
838 :
839 8 : SetupOutputVariable(state,
840 : "Heating Coil Source Side Heat Transfer Rate",
841 : Constant::Units::W,
842 4 : simpleWAHP.QSource,
843 : OutputProcessor::TimeStepType::System,
844 : OutputProcessor::StoreType::Average,
845 4 : simpleWAHP.Name);
846 8 : SetupOutputVariable(state,
847 : "Heating Coil Part Load Ratio",
848 : Constant::Units::None,
849 4 : simpleWAHP.PartLoadRatio,
850 : OutputProcessor::TimeStepType::System,
851 : OutputProcessor::StoreType::Average,
852 4 : simpleWAHP.Name);
853 8 : SetupOutputVariable(state,
854 : "Heating Coil Runtime Fraction",
855 : Constant::Units::None,
856 4 : simpleWAHP.RunFrac,
857 : OutputProcessor::TimeStepType::System,
858 : OutputProcessor::StoreType::Average,
859 4 : simpleWAHP.Name);
860 :
861 8 : SetupOutputVariable(state,
862 : "Heating Coil Air Mass Flow Rate",
863 : Constant::Units::kg_s,
864 4 : simpleWAHP.AirMassFlowRate,
865 : OutputProcessor::TimeStepType::System,
866 : OutputProcessor::StoreType::Average,
867 4 : simpleWAHP.Name);
868 8 : SetupOutputVariable(state,
869 : "Heating Coil Air Inlet Temperature",
870 : Constant::Units::C,
871 4 : simpleWAHP.InletAirDBTemp,
872 : OutputProcessor::TimeStepType::System,
873 : OutputProcessor::StoreType::Average,
874 4 : simpleWAHP.Name);
875 8 : SetupOutputVariable(state,
876 : "Heating Coil Air Inlet Humidity Ratio",
877 : Constant::Units::kgWater_kgDryAir,
878 4 : simpleWAHP.InletAirHumRat,
879 : OutputProcessor::TimeStepType::System,
880 : OutputProcessor::StoreType::Average,
881 4 : simpleWAHP.Name);
882 8 : SetupOutputVariable(state,
883 : "Heating Coil Air Outlet Temperature",
884 : Constant::Units::C,
885 4 : simpleWAHP.OutletAirDBTemp,
886 : OutputProcessor::TimeStepType::System,
887 : OutputProcessor::StoreType::Average,
888 4 : simpleWAHP.Name);
889 8 : SetupOutputVariable(state,
890 : "Heating Coil Air Outlet Humidity Ratio",
891 : Constant::Units::kgWater_kgDryAir,
892 4 : simpleWAHP.OutletAirHumRat,
893 : OutputProcessor::TimeStepType::System,
894 : OutputProcessor::StoreType::Average,
895 4 : simpleWAHP.Name);
896 8 : SetupOutputVariable(state,
897 : "Heating Coil Source Side Mass Flow Rate",
898 : Constant::Units::kg_s,
899 4 : simpleWAHP.WaterMassFlowRate,
900 : OutputProcessor::TimeStepType::System,
901 : OutputProcessor::StoreType::Average,
902 4 : simpleWAHP.Name);
903 8 : SetupOutputVariable(state,
904 : "Heating Coil Source Side Inlet Temperature",
905 : Constant::Units::C,
906 4 : simpleWAHP.InletWaterTemp,
907 : OutputProcessor::TimeStepType::System,
908 : OutputProcessor::StoreType::Average,
909 4 : simpleWAHP.Name);
910 8 : SetupOutputVariable(state,
911 : "Heating Coil Source Side Outlet Temperature",
912 : Constant::Units::C,
913 4 : simpleWAHP.OutletWaterTemp,
914 : OutputProcessor::TimeStepType::System,
915 : OutputProcessor::StoreType::Average,
916 4 : simpleWAHP.Name);
917 : }
918 : }
919 6 : }
920 :
921 : // Beginning Initialization Section of the Module
922 : //******************************************************************************
923 :
924 99809 : void InitSimpleWatertoAirHP(EnergyPlusData &state,
925 : int const HPNum, // Current HPNum under simulation
926 : Real64 const SensLoad, // Control zone sensible load[W]
927 : Real64 const LatentLoad, // Control zone latent load[W]
928 : [[maybe_unused]] HVAC::FanOp const fanOp, // fan operating mode
929 : [[maybe_unused]] Real64 const OnOffAirFlowRatio, // ratio of compressor on flow to average flow over time step
930 : bool const FirstHVACIteration // Iteration flag
931 : )
932 : {
933 :
934 : // SUBROUTINE INFORMATION:
935 : // AUTHOR Arun Shenoy
936 : // DATE WRITTEN Nov 2003
937 : // RE-ENGINEERED Kenneth Tang (Jan 2005)
938 :
939 : // PURPOSE OF THIS SUBROUTINE:
940 : // This subroutine is for initializations of the Simple Water to Air HP Components.
941 :
942 : // METHODOLOGY EMPLOYED:
943 : // Uses the status flags to trigger initializations.
944 :
945 : // SUBROUTINE PARAMETER DEFINITIONS:
946 : static constexpr std::string_view RoutineName("InitSimpleWatertoAirHP");
947 :
948 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
949 : Real64 RatedAirMassFlowRate; // coil rated air mass flow rates
950 : Real64 rho; // local fluid density
951 :
952 99809 : if (state.dataWaterToAirHeatPumpSimple->MyOneTimeFlag) {
953 : // initialize the environment and sizing flags
954 6 : state.dataWaterToAirHeatPumpSimple->MySizeFlag.allocate(state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs);
955 6 : state.dataWaterToAirHeatPumpSimple->MyEnvrnFlag.allocate(state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs);
956 6 : state.dataWaterToAirHeatPumpSimple->MyPlantScanFlag.allocate(state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs);
957 6 : state.dataWaterToAirHeatPumpSimple->MySizeFlag = true;
958 6 : state.dataWaterToAirHeatPumpSimple->MyEnvrnFlag = true;
959 6 : state.dataWaterToAirHeatPumpSimple->MyPlantScanFlag = true;
960 6 : state.dataWaterToAirHeatPumpSimple->MyOneTimeFlag = false;
961 : }
962 :
963 99809 : auto &simpleWatertoAirHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
964 :
965 99809 : if (state.dataWaterToAirHeatPumpSimple->MyPlantScanFlag(HPNum) && allocated(state.dataPlnt->PlantLoop)) {
966 11 : bool errFlag = false;
967 22 : PlantUtilities::ScanPlantLoopsForObject(
968 11 : state, simpleWatertoAirHP.Name, simpleWatertoAirHP.WAHPPlantType, simpleWatertoAirHP.plantLoc, errFlag, _, _, _, _, _);
969 11 : if (errFlag) {
970 0 : ShowFatalError(state, "InitSimpleWatertoAirHP: Program terminated for previous conditions.");
971 : }
972 11 : state.dataWaterToAirHeatPumpSimple->MyPlantScanFlag(HPNum) = false;
973 : }
974 :
975 99809 : if (state.dataWaterToAirHeatPumpSimple->MySizeFlag(HPNum)) {
976 13 : if (!state.dataGlobal->SysSizingCalc && !state.dataWaterToAirHeatPumpSimple->MyPlantScanFlag(HPNum)) {
977 : // do the sizing once.
978 11 : SizeHVACWaterToAir(state, HPNum);
979 11 : state.dataWaterToAirHeatPumpSimple->MySizeFlag(HPNum) = false;
980 : }
981 : }
982 :
983 99809 : if (FirstHVACIteration) {
984 49552 : if (state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(HPNum)) {
985 1730 : if (simpleWatertoAirHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit) {
986 1728 : if (simpleWatertoAirHP.CompanionHeatingCoilNum > 0) {
987 1725 : if (simpleWatertoAirHP.WaterFlowMode) {
988 308 : simpleWatertoAirHP.LastOperatingMode = HVAC::Cooling;
989 308 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum).LastOperatingMode =
990 : HVAC::Cooling;
991 1417 : } else if (state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum).WaterFlowMode) {
992 678 : simpleWatertoAirHP.LastOperatingMode = HVAC::Heating;
993 678 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum).LastOperatingMode =
994 : HVAC::Heating;
995 : }
996 1725 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(simpleWatertoAirHP.CompanionHeatingCoilNum) = false;
997 : } else {
998 3 : if (simpleWatertoAirHP.WaterFlowMode) {
999 0 : simpleWatertoAirHP.LastOperatingMode = HVAC::Cooling;
1000 : }
1001 : }
1002 1728 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(HPNum) = false;
1003 : } else {
1004 : // it is a heating coil
1005 2 : if (simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
1006 0 : if (simpleWatertoAirHP.WaterFlowMode) {
1007 0 : simpleWatertoAirHP.LastOperatingMode = HVAC::Heating;
1008 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).LastOperatingMode =
1009 : HVAC::Heating;
1010 0 : } else if (state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).WaterFlowMode) {
1011 0 : simpleWatertoAirHP.LastOperatingMode = HVAC::Cooling;
1012 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).LastOperatingMode =
1013 : HVAC::Cooling;
1014 : }
1015 0 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(simpleWatertoAirHP.CompanionCoolingCoilNum) = false;
1016 : } else {
1017 2 : if (simpleWatertoAirHP.WaterFlowMode) {
1018 0 : simpleWatertoAirHP.LastOperatingMode = HVAC::Heating;
1019 : }
1020 : }
1021 2 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(HPNum) = false;
1022 : }
1023 : }
1024 : } else {
1025 50257 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(HPNum) = true;
1026 50257 : if (simpleWatertoAirHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit) {
1027 25129 : if (simpleWatertoAirHP.CompanionHeatingCoilNum > 0)
1028 25125 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(simpleWatertoAirHP.CompanionHeatingCoilNum) = true;
1029 : } else {
1030 25128 : if (simpleWatertoAirHP.CompanionCoolingCoilNum > 0)
1031 25124 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(simpleWatertoAirHP.CompanionCoolingCoilNum) = true;
1032 : }
1033 : }
1034 :
1035 : // Do the Begin Environment initializations
1036 99809 : if (state.dataGlobal->BeginEnvrnFlag) {
1037 :
1038 385 : if (state.dataWaterToAirHeatPumpSimple->MyEnvrnFlag(HPNum) && !state.dataWaterToAirHeatPumpSimple->MyPlantScanFlag(HPNum)) {
1039 :
1040 : // Initialize all report variables to a known state at beginning of simulation
1041 11 : simpleWatertoAirHP.AirVolFlowRate = 0.0;
1042 11 : simpleWatertoAirHP.InletAirDBTemp = 0.0;
1043 11 : simpleWatertoAirHP.InletAirHumRat = 0.0;
1044 11 : simpleWatertoAirHP.OutletAirDBTemp = 0.0;
1045 11 : simpleWatertoAirHP.OutletAirHumRat = 0.0;
1046 11 : simpleWatertoAirHP.WaterVolFlowRate = 0.0;
1047 11 : simpleWatertoAirHP.WaterMassFlowRate = 0.0;
1048 11 : simpleWatertoAirHP.InletWaterTemp = 0.0;
1049 11 : simpleWatertoAirHP.InletWaterEnthalpy = 0.0;
1050 11 : simpleWatertoAirHP.OutletWaterEnthalpy = 0.0;
1051 11 : simpleWatertoAirHP.OutletWaterTemp = 0.0;
1052 11 : simpleWatertoAirHP.Power = 0.0;
1053 11 : simpleWatertoAirHP.QLoadTotal = 0.0;
1054 11 : simpleWatertoAirHP.QLoadTotalReport = 0.0;
1055 11 : simpleWatertoAirHP.QSensible = 0.0;
1056 11 : simpleWatertoAirHP.QLatent = 0.0;
1057 11 : simpleWatertoAirHP.QSource = 0.0;
1058 11 : simpleWatertoAirHP.Energy = 0.0;
1059 11 : simpleWatertoAirHP.EnergyLoadTotal = 0.0;
1060 11 : simpleWatertoAirHP.EnergySensible = 0.0;
1061 11 : simpleWatertoAirHP.EnergyLatent = 0.0;
1062 11 : simpleWatertoAirHP.EnergySource = 0.0;
1063 11 : simpleWatertoAirHP.COP = 0.0;
1064 11 : simpleWatertoAirHP.RunFrac = 0.0;
1065 11 : simpleWatertoAirHP.PartLoadRatio = 0.0;
1066 :
1067 11 : if (simpleWatertoAirHP.RatedWaterVolFlowRate != DataSizing::AutoSize) {
1068 : rho =
1069 10 : state.dataPlnt->PlantLoop(simpleWatertoAirHP.plantLoc.loopNum).glycol->getDensity(state, Constant::InitConvTemp, RoutineName);
1070 :
1071 10 : simpleWatertoAirHP.DesignWaterMassFlowRate = rho * simpleWatertoAirHP.RatedWaterVolFlowRate;
1072 10 : PlantUtilities::InitComponentNodes(state,
1073 : 0.0,
1074 : simpleWatertoAirHP.DesignWaterMassFlowRate,
1075 : simpleWatertoAirHP.WaterInletNodeNum,
1076 : simpleWatertoAirHP.WaterOutletNodeNum);
1077 :
1078 10 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating && simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
1079 5 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).DesignWaterMassFlowRate =
1080 5 : rho *
1081 5 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).RatedWaterVolFlowRate;
1082 15 : PlantUtilities::InitComponentNodes(
1083 : state,
1084 : 0.0,
1085 5 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum)
1086 : .DesignWaterMassFlowRate,
1087 5 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).WaterInletNodeNum,
1088 5 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).WaterOutletNodeNum);
1089 : }
1090 : }
1091 :
1092 11 : simpleWatertoAirHP.SimFlag = true;
1093 :
1094 11 : state.dataWaterToAirHeatPumpSimple->MyEnvrnFlag(HPNum) = false;
1095 : }
1096 :
1097 : } // End If for the Begin Environment initializations
1098 :
1099 99809 : if (!state.dataGlobal->BeginEnvrnFlag) {
1100 99424 : state.dataWaterToAirHeatPumpSimple->MyEnvrnFlag(HPNum) = true;
1101 : }
1102 :
1103 : // Do the following initializations (every time step): This should be the info from
1104 : // the previous components outlets or the node data in this section.
1105 : // First set the conditions for the air into the heat pump model
1106 :
1107 : // Set water and air inlet nodes
1108 :
1109 99809 : int AirInletNode = simpleWatertoAirHP.AirInletNodeNum;
1110 99809 : int WaterInletNode = simpleWatertoAirHP.WaterInletNodeNum;
1111 :
1112 99809 : if ((SensLoad != 0.0 || LatentLoad != 0.0) && (state.dataLoopNodes->Node(AirInletNode).MassFlowRate > 0.0)) {
1113 44035 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate;
1114 :
1115 44035 : simpleWatertoAirHP.AirMassFlowRate = state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
1116 : // If air flow is less than 25% rated flow. Then throw warning
1117 44035 : RatedAirMassFlowRate =
1118 44035 : simpleWatertoAirHP.RatedAirVolFlowRate * Psychrometrics::PsyRhoAirFnPbTdbW(state,
1119 44035 : state.dataEnvrn->StdBaroPress,
1120 44035 : state.dataLoopNodes->Node(AirInletNode).Temp,
1121 44035 : state.dataLoopNodes->Node(AirInletNode).HumRat,
1122 : RoutineName);
1123 44035 : if (simpleWatertoAirHP.AirMassFlowRate < 0.25 * RatedAirMassFlowRate) {
1124 9184 : ShowRecurringWarningErrorAtEnd(state,
1125 : "Actual air mass flow rate is smaller than 25% of water-to-air heat pump coil rated air flow rate.",
1126 1148 : state.dataWaterToAirHeatPumpSimple->AirflowErrPointer,
1127 1148 : simpleWatertoAirHP.AirMassFlowRate,
1128 1148 : simpleWatertoAirHP.AirMassFlowRate);
1129 : }
1130 44035 : simpleWatertoAirHP.WaterFlowMode = true;
1131 : } else { // heat pump is off
1132 55774 : simpleWatertoAirHP.WaterFlowMode = false;
1133 55774 : simpleWatertoAirHP.WaterMassFlowRate = 0.0;
1134 55774 : simpleWatertoAirHP.AirMassFlowRate = 0.0;
1135 55774 : if ((simpleWatertoAirHP.WaterCyclingMode) == HVAC::WaterFlow::Constant) {
1136 0 : if (simpleWatertoAirHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit) {
1137 0 : if (simpleWatertoAirHP.CompanionHeatingCoilNum > 0) {
1138 0 : if (state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum).QLoadTotal > 0.0) {
1139 : // do nothing, there will be flow through this coil
1140 0 : } else if (simpleWatertoAirHP.LastOperatingMode == HVAC::Cooling) {
1141 : // set the flow rate to full design flow
1142 0 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate;
1143 : }
1144 : } else {
1145 0 : if (simpleWatertoAirHP.LastOperatingMode == HVAC::Cooling) {
1146 : // set the flow rate to full design flow
1147 0 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate;
1148 : }
1149 : }
1150 0 : } else if (simpleWatertoAirHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit) {
1151 : // It's a heating coil
1152 0 : if (simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
1153 0 : if (state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).QLoadTotal > 0.0) {
1154 : // do nothing, there will be flow through this coil
1155 0 : } else if (simpleWatertoAirHP.LastOperatingMode == HVAC::Heating) {
1156 : // set the flow rate to full design flow
1157 0 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate;
1158 : }
1159 : } else {
1160 0 : if (simpleWatertoAirHP.LastOperatingMode == HVAC::Heating) {
1161 : // set the flow rate to full design flow
1162 0 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate;
1163 : }
1164 : }
1165 : }
1166 : }
1167 : }
1168 :
1169 99809 : PlantUtilities::SetComponentFlowRate(state,
1170 99809 : simpleWatertoAirHP.WaterMassFlowRate,
1171 : simpleWatertoAirHP.WaterInletNodeNum,
1172 : simpleWatertoAirHP.WaterOutletNodeNum,
1173 99809 : simpleWatertoAirHP.plantLoc);
1174 :
1175 99809 : simpleWatertoAirHP.InletAirDBTemp = state.dataLoopNodes->Node(AirInletNode).Temp;
1176 99809 : simpleWatertoAirHP.InletAirHumRat = state.dataLoopNodes->Node(AirInletNode).HumRat;
1177 99809 : simpleWatertoAirHP.InletAirEnthalpy = state.dataLoopNodes->Node(AirInletNode).Enthalpy;
1178 99809 : simpleWatertoAirHP.InletWaterTemp = state.dataLoopNodes->Node(WaterInletNode).Temp;
1179 99809 : simpleWatertoAirHP.InletWaterEnthalpy = state.dataLoopNodes->Node(WaterInletNode).Enthalpy;
1180 99809 : simpleWatertoAirHP.OutletWaterTemp = simpleWatertoAirHP.InletWaterTemp;
1181 99809 : simpleWatertoAirHP.OutletWaterEnthalpy = simpleWatertoAirHP.InletWaterEnthalpy;
1182 :
1183 : // Outlet variables
1184 99809 : simpleWatertoAirHP.Power = 0.0;
1185 99809 : simpleWatertoAirHP.QLoadTotal = 0.0;
1186 99809 : simpleWatertoAirHP.QLoadTotalReport = 0.0;
1187 99809 : simpleWatertoAirHP.QSensible = 0.0;
1188 99809 : simpleWatertoAirHP.QLatent = 0.0;
1189 99809 : simpleWatertoAirHP.QSource = 0.0;
1190 99809 : simpleWatertoAirHP.Energy = 0.0;
1191 99809 : simpleWatertoAirHP.EnergyLoadTotal = 0.0;
1192 99809 : simpleWatertoAirHP.EnergySensible = 0.0;
1193 99809 : simpleWatertoAirHP.EnergyLatent = 0.0;
1194 99809 : simpleWatertoAirHP.EnergySource = 0.0;
1195 99809 : simpleWatertoAirHP.COP = 0.0;
1196 99809 : state.dataHeatBal->HeatReclaimSimple_WAHPCoil(HPNum).AvailCapacity = 0.0;
1197 99809 : }
1198 :
1199 16 : void SizeHVACWaterToAir(EnergyPlusData &state, int const HPNum)
1200 : {
1201 :
1202 : // SUBROUTINE INFORMATION:
1203 : // AUTHOR Richard Raustad, FSEC
1204 : // DATE WRITTEN June 2009
1205 : // MODIFIED August 2013 Daeho Kang, add component sizing table entries
1206 :
1207 : // PURPOSE OF THIS SUBROUTINE:
1208 : // This subroutine is for sizing WSHP Components for which nominal capacities
1209 : // and flow rates have not been specified in the input
1210 :
1211 : // METHODOLOGY EMPLOYED:
1212 : // Obtains heating capacities and flow rates from the zone or system sizing arrays.
1213 :
1214 16 : auto &simpleWatertoAirHP = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum);
1215 :
1216 : // SUBROUTINE PARAMETER DEFINITIONS:
1217 : static constexpr std::string_view RoutineName("SizeWaterToAirCoil");
1218 : static constexpr std::string_view RoutineNameAlt("SizeHVACWaterToAir");
1219 :
1220 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1221 : Real64 rhoair;
1222 : Real64 MixTemp; // Mixed air temperature at cooling design conditions
1223 : Real64 MixTempSys; // Mixed air temperature at cooling design conditions at system air flow
1224 : Real64 HeatMixTemp; // Mixed air temperature at heating design conditions
1225 : Real64 HeatMixTempSys; // Mixed air temperature at heating design conditions at system air flow
1226 : Real64 MixHumRat; // Mixed air humidity ratio at cooling design conditions
1227 : Real64 MixHumRatSys; // Mixed air humidity ratio at cooling design conditions at system air flow
1228 : Real64 HeatMixHumRat; // Mixed air humidity ratio at heating design conditions
1229 : Real64 HeatMixHumRatSys; // Mixed air humidity ratio at heating design conditions at system air flow
1230 : Real64 MixEnth; // Mixed air enthalpy at cooling design conditions
1231 : Real64 MixEnthSys; // Mixed air enthalpy at cooling design conditions at system air flow
1232 : Real64 MixWetBulb; // Mixed air wet-bulb temperature at cooling design conditions
1233 16 : Real64 RatedMixWetBulb = 0.0; // Rated mixed air wetbulb temperature
1234 16 : Real64 RatedMixDryBulb = 0.0; // Rated mixed air drybulb temperature
1235 16 : Real64 RatedHeatMixDryBulb = 0.0; // Rated mixed air drybulb temperature at heating design conditions
1236 : Real64 SupTemp; // Supply air temperature at cooling design conditions
1237 : Real64 HeatSupTemp; // Supply air temperature at heating design conditions
1238 : Real64 SupHumRat; // Supply air humidity ratio at cooling design conditions
1239 : Real64 SupEnth; // Supply air enthalpy at cooling design conditions
1240 : Real64 OutTemp; // Outdoor aur dry-bulb temperature at cooling design conditions
1241 : Real64 ratioTDB; // Load-side dry-bulb temperature ratio at cooling design conditions
1242 : Real64 HeatratioTDB; // Load-side dry-bulb temperature ratio at heating design conditions
1243 : Real64 ratioTWB; // Load-side wet-bulb temperature ratio at cooling design conditions
1244 : Real64 ratioTS; // Source-side temperature ratio at cooling design conditions
1245 : Real64 HeatratioTS; // Source-side temperature ratio at heating design conditions
1246 : Real64 RatedratioTDB; // Rated cooling load-side dry-bulb temperature ratio
1247 16 : Real64 RatedHeatratioTDB = 0.0; // Rated cooling load-side dry-bulb temperature ratio
1248 : Real64 RatedratioTWB; // Rated cooling load-side wet-bulb temperature ratio
1249 : Real64 RatedratioTS; // Rated cooling source-side temperature ratio
1250 : Real64 RatedHeatratioTS; // Rated heating source-side temperature ratio
1251 : Real64 OutAirFrac; // Outdoor air fraction at cooling design conditions
1252 : Real64 OutAirFracSys; // Outdoor air fraction at cooling design conditions at system air flow
1253 : Real64 HeatOutAirFrac; // Outdoor air fraction at heating design conditions
1254 : Real64 HeatOutAirFracSys; // Outdoor air fraction at heating design conditions at system air flow
1255 : Real64 VolFlowRate;
1256 : Real64 CoolCapAtPeak; // Load on the cooling coil at cooling design conditions
1257 : Real64 HeatCapAtPeak; // Load on the heating coil at heating design conditions
1258 16 : Real64 PeakTotCapTempModFac = 1.0; // Peak total cooling capacity curve modifier
1259 16 : Real64 RatedTotCapTempModFac = 1.0; // Rated total cooling capacity curve modifier
1260 16 : Real64 PeakHeatCapTempModFac = 1.0; // Peak heating capacity curve modifier
1261 : Real64 DesignEntWaterTemp; // Design entering coil water temperature
1262 : Real64 SensCapAtPeak; // Sensible load on the cooling coil at cooling design conditions
1263 16 : Real64 PeakSensCapTempModFac = 1.0; // Peak sensible cooling capacity curve modifier
1264 16 : Real64 RatedSensCapTempModFac = 1.0; // Rated sensible cooling capacity curve modifier
1265 16 : Real64 RatedHeatCapTempModFac = 1.0; // Rated heating capacity curve modifier
1266 16 : Real64 RatedCoolPowerTempModFac = 1.0; // Rated cooling power curve modifier
1267 16 : Real64 RatedHeatPowerTempModFac = 1.0; // Rated heating power curve modifier
1268 : Real64 RatedCapCoolTotalDesCDD; // Rated total cooling coil capacity determined at cooling design conditions
1269 16 : constexpr Real64 Tref(283.15); // Refrence Temperature for performance curves,10C [K]
1270 : int PltSizNum;
1271 : bool RatedCapCoolTotalAutoSized;
1272 : bool RatedCapCoolSensAutoSized;
1273 : bool ErrorsFound;
1274 16 : Real64 SystemCapacity = 0.0;
1275 : Real64 rho;
1276 : Real64 Cp;
1277 : bool IsAutoSize; // Indicator to autosize
1278 : bool HardSizeNoDesRun; // Indicator to hardsize and no sizing run
1279 : Real64 RatedAirVolFlowRateDes; // Autosized rated air flow for reporting
1280 : Real64 CoolingAirVolFlowRateDes; // Cooling desing day air flow
1281 : Real64 HeatingAirVolFlowRateDes; // Heating design day air flow
1282 : Real64 RatedAirVolFlowRateUser; // Hardsized rated air flow for reporting
1283 : Real64 RatedCapCoolTotalDes; // Autosized rated cooling capacity for reporting
1284 : Real64 RatedCapCoolTotalUser; // Hardsized rated cooling capacity for reporting
1285 : Real64 RatedCapCoolSensDes; // Autosized rated sensible cooling capacity for reporting
1286 : Real64 RatedCapCoolSensUser; // Hardsized rated sensible cooling capacity for reporting
1287 : Real64 RatedCapHeatDes; // Autosized rated heating capacity for reporting
1288 : Real64 RatedCapHeatUser; // Hardsized rated heating capacity for reporting
1289 : Real64 RatedWaterVolFlowRateDes; // Autosized rated water flow rate for reporting
1290 : Real64 RatedWaterVolFlowRateUser; // Hardsized rated water flow rate for reporting
1291 : Real64 RatedCapCoolHeatDD; // Rated cooling coil capacity based on heating design conditions
1292 : bool SizingDesRunThisAirSys; // true if a particular air system had a Sizing:System object and system sizing done
1293 : bool SizingDesRunThisZone; // true if a particular zone had a Sizing:Zone object and zone sizing was done
1294 16 : Real64 HeatdTratio = 1.0; // Temperature difference across coil adjustment factor
1295 16 : Real64 dHratio = 1.0; // Enthalpy difference across coil adjustment factor
1296 : Real64 HeatOAFrac; // Outdoor air fraction at heating design conditions
1297 : Real64 HeatOAFracSys; // Outdoor air fraction at heating design conditions at system air flow
1298 : Real64 HeatOATemp; // Outdoor air temperature at heating design conditions
1299 : Real64 OAFrac; // Outdooor air fraction
1300 : Real64 OAFracSys; // Outdoor air fraction at system air flow
1301 : Real64 OATemp; // Outdoor air temperature at cooling design conditions
1302 : Real64 OAHumRat; // Humidity ratio at cooling design conditions
1303 :
1304 16 : ErrorsFound = false;
1305 16 : IsAutoSize = false;
1306 16 : if (state.dataSize->SysSizingRunDone || state.dataSize->ZoneSizingRunDone) {
1307 7 : HardSizeNoDesRun = false;
1308 : } else {
1309 9 : HardSizeNoDesRun = true;
1310 : }
1311 16 : if (state.dataSize->CurSysNum > 0) {
1312 0 : CheckThisAirSystemForSizing(state, state.dataSize->CurSysNum, SizingDesRunThisAirSys);
1313 : } else {
1314 16 : SizingDesRunThisAirSys = false;
1315 : }
1316 16 : if (state.dataSize->CurZoneEqNum > 0) {
1317 9 : CheckThisZoneForSizing(state, state.dataSize->CurZoneEqNum, SizingDesRunThisZone);
1318 : } else {
1319 7 : SizingDesRunThisZone = false;
1320 : }
1321 16 : RatedAirVolFlowRateDes = 0.0;
1322 16 : RatedAirVolFlowRateUser = 0.0;
1323 16 : CoolingAirVolFlowRateDes = 0.0;
1324 16 : HeatingAirVolFlowRateDes = 0.0;
1325 16 : RatedCapCoolTotalDes = 0.0;
1326 16 : RatedCapCoolTotalUser = 0.0;
1327 16 : RatedCapCoolSensDes = 0.0;
1328 16 : RatedCapCoolSensUser = 0.0;
1329 16 : RatedCapHeatDes = 0.0;
1330 16 : RatedCapHeatUser = 0.0;
1331 16 : RatedWaterVolFlowRateDes = 0.0;
1332 16 : RatedWaterVolFlowRateUser = 0.0;
1333 16 : std::string CompType = format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]);
1334 :
1335 16 : if (simpleWatertoAirHP.RatedAirVolFlowRate == DataSizing::AutoSize) {
1336 7 : IsAutoSize = true;
1337 : }
1338 16 : if (state.dataSize->CurSysNum > 0) {
1339 0 : if (!IsAutoSize && !SizingDesRunThisAirSys) { // Simulation continue
1340 0 : HardSizeNoDesRun = true;
1341 0 : if (simpleWatertoAirHP.RatedAirVolFlowRate > 0.0) {
1342 0 : BaseSizer::reportSizerOutput(
1343 : state,
1344 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1345 : simpleWatertoAirHP.Name,
1346 : "User-Specified Rated Air Flow Rate [m3/s]",
1347 : simpleWatertoAirHP.RatedAirVolFlowRate);
1348 : }
1349 : } else {
1350 0 : CheckSysSizing(state,
1351 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1352 0 : simpleWatertoAirHP.Name);
1353 0 : if (state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow >= HVAC::SmallAirVolFlow) {
1354 0 : RatedAirVolFlowRateDes = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow;
1355 0 : CoolingAirVolFlowRateDes = state.dataSize->CalcSysSizing(state.dataSize->CurSysNum).DesCoolVolFlow;
1356 0 : HeatingAirVolFlowRateDes = state.dataSize->CalcSysSizing(state.dataSize->CurSysNum).DesHeatVolFlow;
1357 : } else {
1358 0 : RatedAirVolFlowRateDes = 0.0;
1359 : }
1360 : }
1361 16 : } else if (state.dataSize->CurZoneEqNum > 0) {
1362 9 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
1363 2 : HardSizeNoDesRun = true;
1364 2 : if (simpleWatertoAirHP.RatedAirVolFlowRate > 0.0) {
1365 6 : BaseSizer::reportSizerOutput(
1366 : state,
1367 4 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1368 : simpleWatertoAirHP.Name,
1369 : "User-Specified Rated Air Flow Rate [m3/s]",
1370 : simpleWatertoAirHP.RatedAirVolFlowRate);
1371 : }
1372 : } else {
1373 14 : CheckZoneSizing(state,
1374 14 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1375 : simpleWatertoAirHP.Name);
1376 7 : RatedAirVolFlowRateDes = max(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow,
1377 7 : state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatVolFlow);
1378 7 : CoolingAirVolFlowRateDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow;
1379 7 : HeatingAirVolFlowRateDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatVolFlow;
1380 7 : if (RatedAirVolFlowRateDes < HVAC::SmallAirVolFlow) {
1381 0 : RatedAirVolFlowRateDes = 0.0;
1382 : }
1383 : }
1384 : }
1385 16 : if (!HardSizeNoDesRun) {
1386 7 : if (IsAutoSize) {
1387 7 : simpleWatertoAirHP.RatedAirVolFlowRate = RatedAirVolFlowRateDes;
1388 21 : BaseSizer::reportSizerOutput(
1389 : state,
1390 14 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1391 : simpleWatertoAirHP.Name,
1392 : "Design Size Rated Air Flow Rate [m3/s]",
1393 : RatedAirVolFlowRateDes);
1394 : } else {
1395 0 : if (simpleWatertoAirHP.RatedAirVolFlowRate > 0.0 && RatedAirVolFlowRateDes > 0.0) {
1396 0 : RatedAirVolFlowRateUser = simpleWatertoAirHP.RatedAirVolFlowRate;
1397 0 : BaseSizer::reportSizerOutput(
1398 : state,
1399 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1400 : simpleWatertoAirHP.Name,
1401 : "Design Size Rated Air Flow Rate [m3/s]",
1402 : RatedAirVolFlowRateDes,
1403 : "User-Specified Rated Air Flow Rate [m3/s]",
1404 : RatedAirVolFlowRateUser);
1405 0 : if (state.dataGlobal->DisplayExtraWarnings) {
1406 0 : if ((std::abs(RatedAirVolFlowRateDes - RatedAirVolFlowRateUser) / RatedAirVolFlowRateUser) >
1407 0 : state.dataSize->AutoVsHardSizingThreshold) {
1408 0 : ShowMessage(
1409 : state,
1410 0 : format("SizeHVACWaterToAir: Potential issue with equipment sizing for coil {}:WATERTOAIRHEATPUMP:EQUATIONFIT \"{}\"",
1411 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
1412 0 : simpleWatertoAirHP.Name));
1413 0 : ShowContinueError(state, format("User-Specified Rated Air Volume Flow Rate of {:.5R} [m3/s]", RatedAirVolFlowRateUser));
1414 0 : ShowContinueError(state,
1415 0 : format("differs from Design Size Rated Air Volume Flow Rate of {:.5R} [m3/s]", RatedAirVolFlowRateDes));
1416 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1417 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1418 : }
1419 : }
1420 : }
1421 : }
1422 : }
1423 :
1424 16 : RatedCapCoolTotalAutoSized = false;
1425 16 : RatedCapCoolSensAutoSized = false;
1426 :
1427 16 : Real64 FanCoolLoad = 0.0;
1428 16 : Real64 FanHeatLoad = FanCoolLoad;
1429 16 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
1430 : // size rated total cooling capacity
1431 9 : if (simpleWatertoAirHP.RatedCapCoolTotal == DataSizing::AutoSize) {
1432 4 : RatedCapCoolTotalAutoSized = true;
1433 : }
1434 9 : if (SizingDesRunThisAirSys || SizingDesRunThisZone) HardSizeNoDesRun = false;
1435 9 : if (state.dataSize->CurSysNum > 0) {
1436 0 : if (!RatedCapCoolTotalAutoSized && !SizingDesRunThisAirSys) { // Simulation continue
1437 0 : HardSizeNoDesRun = true;
1438 0 : if (simpleWatertoAirHP.RatedCapCoolTotal > 0.0) {
1439 0 : BaseSizer::reportSizerOutput(
1440 : state,
1441 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1442 : simpleWatertoAirHP.Name,
1443 : "User-Specified Rated Total Cooling Capacity [W]",
1444 : simpleWatertoAirHP.RatedCapCoolTotal);
1445 : }
1446 : } else {
1447 0 : CheckSysSizing(
1448 : state,
1449 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1450 0 : simpleWatertoAirHP.Name);
1451 0 : if (CoolingAirVolFlowRateDes > 0.0) {
1452 0 : VolFlowRate = CoolingAirVolFlowRateDes;
1453 : } else {
1454 0 : VolFlowRate = HeatingAirVolFlowRateDes; // system air flow
1455 : }
1456 : // cooling design day calculations
1457 0 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
1458 0 : auto const &finalSysSizing = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum);
1459 0 : if (state.dataSize->CurOASysNum > 0) { // coil is in the OA stream
1460 0 : MixTemp = finalSysSizing.OutTempAtCoolPeak;
1461 0 : MixHumRat = finalSysSizing.OutHumRatAtCoolPeak;
1462 0 : SupTemp = finalSysSizing.PrecoolTemp;
1463 0 : SupHumRat = finalSysSizing.PrecoolHumRat;
1464 0 : MixTempSys = MixTemp;
1465 0 : MixHumRatSys = MixHumRat;
1466 : } else { // coil is on the main air loop
1467 0 : SupTemp = finalSysSizing.CoolSupTemp;
1468 0 : SupHumRat = finalSysSizing.CoolSupHumRat;
1469 0 : if (VolFlowRate > 0.0) {
1470 0 : OutAirFrac = finalSysSizing.DesOutAirVolFlow / VolFlowRate;
1471 0 : OutAirFracSys = finalSysSizing.DesOutAirVolFlow / RatedAirVolFlowRateDes;
1472 : } else {
1473 0 : OutAirFrac = 1.0;
1474 0 : OutAirFracSys = OutAirFrac;
1475 : }
1476 0 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
1477 0 : OutAirFracSys = min(1.0, max(0.0, OutAirFracSys));
1478 0 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).NumOACoolCoils ==
1479 : 0) { // there is no precooling of the OA stream
1480 0 : MixTemp = finalSysSizing.MixTempAtCoolPeak;
1481 0 : MixHumRat = finalSysSizing.MixHumRatAtCoolPeak;
1482 : // calculate mixed air temperature with system airflow
1483 0 : MixTempSys =
1484 0 : OutAirFracSys * finalSysSizing.OutTempAtCoolPeak + (1.0 - OutAirFracSys) * finalSysSizing.RetTempAtCoolPeak;
1485 0 : MixHumRatSys =
1486 0 : OutAirFracSys * finalSysSizing.OutHumRatAtCoolPeak + (1.0 - OutAirFracSys) * finalSysSizing.RetHumRatAtCoolPeak;
1487 : } else { // there is precooling of OA stream
1488 0 : MixTemp = OutAirFrac * finalSysSizing.PrecoolTemp + (1.0 - OutAirFrac) * finalSysSizing.RetTempAtCoolPeak;
1489 0 : MixHumRat = OutAirFrac * finalSysSizing.PrecoolHumRat + (1.0 - OutAirFrac) * finalSysSizing.RetHumRatAtCoolPeak;
1490 : // calculate mixed air temperature with system airflow
1491 0 : MixTempSys = OutAirFracSys * finalSysSizing.PrecoolTemp + (1.0 - OutAirFracSys) * finalSysSizing.RetTempAtCoolPeak;
1492 0 : MixHumRatSys =
1493 0 : OutAirFracSys * finalSysSizing.PrecoolHumRat + (1.0 - OutAirFracSys) * finalSysSizing.RetHumRatAtCoolPeak;
1494 : }
1495 : }
1496 : // supply air condition is capped with that of mixed air to avoid SHR > 1.0
1497 0 : SupTemp = min(MixTemp, SupTemp);
1498 0 : SupHumRat = min(MixHumRat, SupHumRat);
1499 0 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, MixTemp, MixHumRat, RoutineName);
1500 0 : MixEnth = Psychrometrics::PsyHFnTdbW(MixTemp, MixHumRat);
1501 0 : MixEnthSys = Psychrometrics::PsyHFnTdbW(MixTempSys, MixHumRatSys);
1502 0 : SupEnth = Psychrometrics::PsyHFnTdbW(SupTemp, SupHumRat);
1503 : // determine the coil ratio of coil dT with system air flow to design heating air flow
1504 0 : dHratio = (SupEnth - MixEnthSys) / (SupEnth - MixEnth);
1505 0 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid && state.dataSize->DataFanIndex > 0) { // add fan heat to coil load
1506 0 : FanCoolLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
1507 :
1508 0 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(MixHumRat);
1509 0 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace == HVAC::FanPlace::BlowThru) {
1510 0 : MixTemp += FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature entering the coil
1511 0 : } else if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace ==
1512 : HVAC::FanPlace::DrawThru) {
1513 0 : SupTemp -= FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature leaving the coil
1514 : }
1515 : }
1516 0 : CoolCapAtPeak = (rhoair * VolFlowRate * (MixEnth - SupEnth)) +
1517 : FanCoolLoad; // load on the cooling coil which includes ventilation load and fan heat
1518 0 : CoolCapAtPeak = max(0.0, CoolCapAtPeak);
1519 0 : MixWetBulb = Psychrometrics::PsyTwbFnTdbWPb(state, MixTemp, MixHumRat, state.dataEnvrn->StdBaroPress, RoutineName);
1520 0 : RatedMixWetBulb = simpleWatertoAirHP.RatedEntAirWetbulbTemp;
1521 : // calculate temperatue ratio at design day peak conditions
1522 0 : ratioTWB = (MixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1523 0 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
1524 : state,
1525 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1526 : simpleWatertoAirHP.Name,
1527 : simpleWatertoAirHP.WaterInletNodeNum,
1528 : simpleWatertoAirHP.WaterOutletNodeNum,
1529 : ErrorsFound,
1530 : false);
1531 0 : if (PltSizNum > 0) {
1532 0 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
1533 0 : ratioTS = (DesignEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1534 : } else {
1535 0 : ShowSevereError(state, "Autosizing of total cooling capacity requires a loop Sizing:Plant object");
1536 0 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
1537 0 : ShowContinueError(state,
1538 0 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
1539 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
1540 0 : simpleWatertoAirHP.Name));
1541 0 : ratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
1542 0 : ErrorsFound = true;
1543 : }
1544 : // calculate temperatue ratio at rated conditions
1545 0 : RatedratioTWB = (RatedMixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1546 0 : RatedratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1547 : // determine curve modifiers at peak and rated conditions
1548 0 : PeakTotCapTempModFac = simpleWatertoAirHP.TotalCoolCapCurve->value(state, ratioTWB, ratioTS, 1.0, 1.0);
1549 0 : RatedTotCapTempModFac = simpleWatertoAirHP.TotalCoolCapCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
1550 0 : RatedCoolPowerTempModFac = simpleWatertoAirHP.CoolPowCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
1551 : // calculate the rated total capacity based on peak conditions
1552 : // note: the rated total capacity can be different than the total capacity at
1553 : // rated conditions if the capacity curve isn't normalized at the rated
1554 : // conditions
1555 0 : RatedCapCoolTotalDes = (PeakTotCapTempModFac > 0.0) ? CoolCapAtPeak / PeakTotCapTempModFac : CoolCapAtPeak;
1556 : // reporting
1557 0 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirTemp(
1558 0 : state, simpleWatertoAirHP.Name, CompType, MixTemp, state.dataSize->CurSysNum, state.dataSize->CurZoneEqNum);
1559 0 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirHumRat(state, simpleWatertoAirHP.Name, CompType, MixHumRat);
1560 0 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirTemp(state, simpleWatertoAirHP.Name, CompType, SupTemp);
1561 0 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirHumRat(state, simpleWatertoAirHP.Name, CompType, SupHumRat);
1562 : } else {
1563 0 : RatedCapCoolTotalDes = 0.0;
1564 : }
1565 : }
1566 9 : } else if (state.dataSize->CurZoneEqNum > 0) {
1567 5 : if (!RatedCapCoolTotalAutoSized && !SizingDesRunThisZone) { // Simulation continue
1568 1 : HardSizeNoDesRun = true;
1569 1 : if (simpleWatertoAirHP.RatedCapCoolTotal > 0.0) {
1570 3 : BaseSizer::reportSizerOutput(
1571 : state,
1572 2 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1573 : simpleWatertoAirHP.Name,
1574 : "User-Specified Rated Total Cooling Capacity [W]",
1575 : simpleWatertoAirHP.RatedCapCoolTotal);
1576 : }
1577 : } else {
1578 8 : CheckZoneSizing(
1579 : state,
1580 8 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1581 : simpleWatertoAirHP.Name);
1582 4 : if (CoolingAirVolFlowRateDes > 0.0) {
1583 4 : VolFlowRate = CoolingAirVolFlowRateDes;
1584 : } else {
1585 0 : VolFlowRate = HeatingAirVolFlowRateDes; // system air flow
1586 : }
1587 4 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
1588 : // cooling design calculations
1589 4 : if (state.dataSize->ZoneEqDXCoil) {
1590 4 : if (state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow > 0.0) {
1591 0 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp;
1592 0 : MixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInHumRat;
1593 : // calculate mixed air temperature and humidity with system airflow
1594 0 : OAFrac = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA / CoolingAirVolFlowRateDes;
1595 0 : OAFracSys = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA / RatedAirVolFlowRateDes;
1596 0 : OATemp = (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp -
1597 0 : (1.0 - OAFrac) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneTempAtCoolPeak) /
1598 : OAFrac;
1599 0 : OAHumRat = (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInHumRat -
1600 0 : (1.0 - OAFrac) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneHumRatAtHeatPeak) /
1601 : OAFrac;
1602 0 : MixTempSys = OAFracSys * OATemp +
1603 0 : (1.0 - OAFracSys) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneTempAtCoolPeak;
1604 0 : MixHumRatSys = OAFracSys * OAHumRat +
1605 0 : (1.0 - OAFracSys) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneHumRatAtHeatPeak;
1606 : } else {
1607 4 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneRetTempAtCoolPeak;
1608 4 : MixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneHumRatAtCoolPeak;
1609 4 : MixTempSys = MixTemp;
1610 4 : MixHumRatSys = MixHumRat;
1611 : }
1612 : } else {
1613 0 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp;
1614 0 : MixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInHumRat;
1615 0 : MixTempSys = MixTemp;
1616 0 : MixHumRatSys = MixHumRat;
1617 : }
1618 4 : SupTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDesTemp;
1619 4 : SupHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDesHumRat;
1620 : // supply air condition is capped with that of mixed air to avoid SHR > 1.0
1621 4 : SupTemp = min(MixTemp, SupTemp);
1622 4 : SupHumRat = min(MixHumRat, SupHumRat);
1623 4 : int TimeStepNumAtMax = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).TimeStepNumAtCoolMax;
1624 4 : int DDNum = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDDNum;
1625 4 : if (DDNum > 0 && TimeStepNumAtMax > 0) {
1626 4 : OutTemp = state.dataSize->DesDayWeath(DDNum).Temp(TimeStepNumAtMax);
1627 : } else {
1628 0 : OutTemp = 0.0;
1629 : }
1630 4 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, MixTemp, MixHumRat, RoutineName);
1631 4 : MixEnth = Psychrometrics::PsyHFnTdbW(MixTemp, MixHumRat);
1632 4 : MixEnthSys = Psychrometrics::PsyHFnTdbW(MixTempSys, MixHumRatSys);
1633 4 : SupEnth = Psychrometrics::PsyHFnTdbW(SupTemp, SupHumRat);
1634 : // determine the coil ratio of coil dH with system air flow to design heating air flow
1635 4 : dHratio = (SupEnth - MixEnthSys) / (SupEnth - MixEnth);
1636 4 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid && state.dataSize->DataFanIndex > 0) { // add fan heat to coil load
1637 1 : FanCoolLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
1638 :
1639 1 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(MixHumRat);
1640 1 : if (state.dataSize->DataFanPlacement == HVAC::FanPlace::BlowThru) {
1641 1 : MixTemp += FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature entering the coil
1642 : } else {
1643 0 : SupTemp -= FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature leaving the coil
1644 : }
1645 : }
1646 4 : CoolCapAtPeak = (rhoair * VolFlowRate * (MixEnth - SupEnth)) +
1647 : FanCoolLoad; // load on the cooling coil which includes ventilation load and fan heat
1648 4 : CoolCapAtPeak = max(0.0, CoolCapAtPeak);
1649 4 : MixWetBulb = Psychrometrics::PsyTwbFnTdbWPb(state, MixTemp, MixHumRat, state.dataEnvrn->StdBaroPress, RoutineName);
1650 4 : RatedMixWetBulb = simpleWatertoAirHP.RatedEntAirWetbulbTemp;
1651 : // calculate temperatue ratio at design day peak conditions
1652 4 : ratioTWB = (MixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1653 8 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
1654 : state,
1655 8 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1656 : simpleWatertoAirHP.Name,
1657 : simpleWatertoAirHP.WaterInletNodeNum,
1658 : simpleWatertoAirHP.WaterOutletNodeNum,
1659 : ErrorsFound,
1660 : false);
1661 4 : if (PltSizNum > 0) {
1662 3 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
1663 3 : ratioTS = (DesignEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1664 : } else {
1665 2 : ShowSevereError(state, "Autosizing of total cooling capacity requires a loop Sizing:Plant object");
1666 2 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
1667 2 : ShowContinueError(state,
1668 2 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
1669 1 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
1670 1 : simpleWatertoAirHP.Name));
1671 1 : ratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
1672 1 : ErrorsFound = true;
1673 : }
1674 : // calculate temperatue ratio at rated conditions
1675 4 : RatedratioTWB = (RatedMixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1676 4 : RatedratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1677 : // determine curve modifiers at peak and rated conditions
1678 4 : PeakTotCapTempModFac = simpleWatertoAirHP.TotalCoolCapCurve->value(state, ratioTWB, ratioTS, 1.0, 1.0);
1679 4 : RatedTotCapTempModFac = simpleWatertoAirHP.TotalCoolCapCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
1680 4 : RatedCoolPowerTempModFac = simpleWatertoAirHP.CoolPowCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
1681 : // calculate the rated total capacity based on peak conditions
1682 : // note: the rated total capacity can be different than the total capacity at
1683 : // rated conditions if the capacity curve isn't normalized at the rated
1684 : // conditions
1685 4 : RatedCapCoolTotalDes = (PeakTotCapTempModFac > 0.0) ? CoolCapAtPeak / PeakTotCapTempModFac : CoolCapAtPeak;
1686 : // reporting
1687 4 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirTemp(
1688 4 : state, simpleWatertoAirHP.Name, CompType, MixTemp, state.dataSize->CurSysNum, state.dataSize->CurZoneEqNum);
1689 4 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirHumRat(state, simpleWatertoAirHP.Name, CompType, MixHumRat);
1690 4 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirTemp(state, simpleWatertoAirHP.Name, CompType, SupTemp);
1691 4 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirHumRat(state, simpleWatertoAirHP.Name, CompType, SupHumRat);
1692 : } else {
1693 0 : RatedCapCoolTotalDes = 0.0;
1694 : }
1695 : }
1696 5 : if (RatedCapCoolTotalDes < HVAC::SmallLoad) {
1697 1 : RatedCapCoolTotalDes = 0.0;
1698 : }
1699 : }
1700 : // size rated sensible cooling capacity
1701 9 : if (simpleWatertoAirHP.RatedCapCoolSens == DataSizing::AutoSize && simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
1702 4 : RatedCapCoolSensAutoSized = true;
1703 : }
1704 9 : if (SizingDesRunThisAirSys || SizingDesRunThisZone) HardSizeNoDesRun = false;
1705 9 : if (state.dataSize->CurSysNum > 0) {
1706 0 : if (!RatedCapCoolSensAutoSized && !SizingDesRunThisAirSys) { // Simulation continue
1707 0 : HardSizeNoDesRun = true;
1708 0 : if (simpleWatertoAirHP.RatedCapCoolSens > 0.0) {
1709 0 : BaseSizer::reportSizerOutput(
1710 : state,
1711 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1712 : simpleWatertoAirHP.Name,
1713 : "User-Specified Rated Sensible Cooling Capacity [W]",
1714 : simpleWatertoAirHP.RatedCapCoolSens);
1715 : }
1716 : } else {
1717 0 : CheckSysSizing(
1718 : state,
1719 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1720 0 : simpleWatertoAirHP.Name);
1721 0 : if (CoolingAirVolFlowRateDes > 0.0) {
1722 0 : VolFlowRate = CoolingAirVolFlowRateDes;
1723 : } else {
1724 0 : VolFlowRate = HeatingAirVolFlowRateDes; // system air flow
1725 : }
1726 0 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
1727 0 : auto const &finalSysSizing = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum);
1728 0 : if (state.dataSize->CurOASysNum > 0) { // coil is in the OA stream
1729 0 : MixTemp = finalSysSizing.OutTempAtCoolPeak;
1730 0 : MixHumRat = finalSysSizing.OutHumRatAtCoolPeak;
1731 0 : SupTemp = finalSysSizing.PrecoolTemp;
1732 0 : SupHumRat = finalSysSizing.PrecoolHumRat;
1733 : } else { // coil is on the main air loop
1734 0 : SupTemp = finalSysSizing.CoolSupTemp;
1735 0 : SupHumRat = finalSysSizing.CoolSupHumRat;
1736 0 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).NumOACoolCoils ==
1737 : 0) { // there is no precooling of the OA stream
1738 0 : MixTemp = finalSysSizing.MixTempAtCoolPeak;
1739 0 : MixHumRat = finalSysSizing.MixHumRatAtCoolPeak;
1740 : } else { // there is precooling of OA stream
1741 0 : if (VolFlowRate > 0.0) {
1742 0 : OutAirFrac = finalSysSizing.DesOutAirVolFlow / VolFlowRate;
1743 : } else {
1744 0 : OutAirFrac = 1.0;
1745 : }
1746 0 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
1747 0 : MixTemp = OutAirFrac * finalSysSizing.PrecoolTemp + (1.0 - OutAirFrac) * finalSysSizing.RetTempAtCoolPeak;
1748 0 : MixHumRat = OutAirFrac * finalSysSizing.PrecoolHumRat + (1.0 - OutAirFrac) * finalSysSizing.RetHumRatAtCoolPeak;
1749 : }
1750 : }
1751 : // supply air condition is capped with that of mixed air to avoid SHR > 1.0
1752 0 : SupTemp = min(MixTemp, SupTemp);
1753 0 : SupHumRat = min(MixHumRat, SupHumRat);
1754 0 : OutTemp = finalSysSizing.OutTempAtCoolPeak;
1755 0 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, MixTemp, MixHumRat, RoutineName);
1756 0 : MixEnth = Psychrometrics::PsyHFnTdbW(MixTemp, MixHumRat);
1757 0 : SupEnth = Psychrometrics::PsyHFnTdbW(SupTemp, MixHumRat);
1758 0 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid && state.dataSize->DataFanIndex > 0) { // add fan heat to coil load
1759 0 : FanCoolLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
1760 :
1761 0 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(MixHumRat);
1762 0 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace == HVAC::FanPlace::BlowThru) {
1763 0 : MixTemp += FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature entering the coil
1764 0 : } else if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace ==
1765 : HVAC::FanPlace::DrawThru) {
1766 0 : SupTemp -= FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature leaving the coil
1767 : }
1768 : }
1769 : // Sensible capacity is calculated from enthalpy difference with constant humidity ratio, i.e.,
1770 : // there is only temperature difference between entering and leaving air enthalpy. Previously
1771 : // it was calculated using m.cp.dT
1772 0 : SensCapAtPeak = (rhoair * VolFlowRate * (MixEnth - SupEnth)) +
1773 : FanCoolLoad; // load on the cooling coil which includes ventilation load and fan heat (sensible)
1774 0 : SensCapAtPeak = max(0.0, SensCapAtPeak);
1775 0 : MixWetBulb = Psychrometrics::PsyTwbFnTdbWPb(state, MixTemp, MixHumRat, state.dataEnvrn->StdBaroPress, RoutineName);
1776 0 : RatedMixWetBulb = simpleWatertoAirHP.RatedEntAirWetbulbTemp;
1777 0 : RatedMixDryBulb = simpleWatertoAirHP.RatedEntAirDrybulbTemp;
1778 : // calculate temperature ratios at design day peak conditions
1779 0 : ratioTDB = (MixTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1780 0 : ratioTWB = (MixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1781 0 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
1782 : state,
1783 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1784 : simpleWatertoAirHP.Name,
1785 : simpleWatertoAirHP.WaterInletNodeNum,
1786 : simpleWatertoAirHP.WaterOutletNodeNum,
1787 : ErrorsFound,
1788 : false);
1789 0 : if (PltSizNum > 0) {
1790 0 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
1791 0 : ratioTS = (DesignEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1792 : } else {
1793 0 : ShowSevereError(state, "Autosizing of sensible cooling capacity requires a loop Sizing:Plant object");
1794 0 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
1795 0 : ShowContinueError(state,
1796 0 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
1797 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
1798 0 : simpleWatertoAirHP.Name));
1799 0 : ErrorsFound = true;
1800 : }
1801 : // calculate temperatue ratio at rated conditions
1802 0 : RatedratioTDB = (RatedMixDryBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1803 0 : RatedratioTWB = (RatedMixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1804 0 : RatedratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1805 : // determine curve modifiers at peak and rated conditions
1806 0 : PeakSensCapTempModFac = simpleWatertoAirHP.SensCoolCapCurve->value(state, ratioTDB, ratioTWB, ratioTS, 1.0, 1.0);
1807 0 : RatedSensCapTempModFac =
1808 0 : simpleWatertoAirHP.SensCoolCapCurve->value(state, RatedratioTDB, RatedratioTWB, RatedratioTS, 1.0, 1.0);
1809 : // calculate the rated sensible capacity based on peak conditions
1810 : // note: the rated sensible capacity can be different than the sensible capacity
1811 : // at rated conditions if the capacity curve isn't normalized at the rated
1812 : // conditions
1813 0 : RatedCapCoolSensDes = (PeakSensCapTempModFac > 0.0) ? SensCapAtPeak / PeakSensCapTempModFac : SensCapAtPeak;
1814 : } else {
1815 0 : RatedCapCoolSensDes = 0.0;
1816 : }
1817 : }
1818 9 : } else if (state.dataSize->CurZoneEqNum > 0) {
1819 5 : if (!RatedCapCoolSensAutoSized && !SizingDesRunThisZone) { // Simulation continue
1820 1 : HardSizeNoDesRun = true;
1821 1 : if (simpleWatertoAirHP.RatedCapCoolSens > 0.0) {
1822 3 : BaseSizer::reportSizerOutput(
1823 : state,
1824 2 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1825 : simpleWatertoAirHP.Name,
1826 : "User-Specified Rated Sensible Cooling Capacity [W]",
1827 : simpleWatertoAirHP.RatedCapCoolSens);
1828 : }
1829 : } else {
1830 8 : CheckZoneSizing(
1831 : state,
1832 8 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1833 : simpleWatertoAirHP.Name);
1834 4 : if (CoolingAirVolFlowRateDes > 0.0) {
1835 4 : VolFlowRate = CoolingAirVolFlowRateDes;
1836 : } else {
1837 0 : VolFlowRate = HeatingAirVolFlowRateDes; // system air flow
1838 : }
1839 4 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
1840 4 : if (state.dataSize->ZoneEqDXCoil) {
1841 4 : if (state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow > 0.0) {
1842 0 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp;
1843 0 : MixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInHumRat;
1844 : } else {
1845 4 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneRetTempAtCoolPeak;
1846 4 : MixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneHumRatAtCoolPeak;
1847 : }
1848 : } else {
1849 0 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp;
1850 0 : MixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInHumRat;
1851 : }
1852 4 : SupTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDesTemp;
1853 4 : SupHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDesHumRat;
1854 : // supply air condition is capped with that of mixed air to avoid SHR > 1.0
1855 4 : SupTemp = min(MixTemp, SupTemp);
1856 4 : SupHumRat = min(MixHumRat, SupHumRat);
1857 4 : int TimeStepNumAtMax = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).TimeStepNumAtCoolMax;
1858 4 : int DDNum = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDDNum;
1859 4 : if (DDNum > 0 && TimeStepNumAtMax > 0) {
1860 4 : OutTemp = state.dataSize->DesDayWeath(DDNum).Temp(TimeStepNumAtMax);
1861 : } else {
1862 0 : OutTemp = 0.0;
1863 : }
1864 4 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, MixTemp, MixHumRat, RoutineName);
1865 4 : MixEnth = Psychrometrics::PsyHFnTdbW(MixTemp, MixHumRat);
1866 4 : SupEnth = Psychrometrics::PsyHFnTdbW(SupTemp, MixHumRat);
1867 4 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid && state.dataSize->DataFanIndex > 0) { // add fan heat to coil load
1868 1 : FanCoolLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
1869 :
1870 1 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(MixHumRat);
1871 1 : if (state.dataSize->DataFanPlacement == HVAC::FanPlace::BlowThru) {
1872 1 : MixTemp += FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature entering the coil
1873 : } else {
1874 0 : SupTemp -= FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature leaving the coil
1875 : }
1876 : }
1877 : // Sensible capacity is calculated from enthalpy difference with constant humidity ratio, i.e.,
1878 : // there is only temperature difference between entering and leaving air enthalpy. Previously
1879 : // it was calculated using m.cp.dT
1880 4 : SensCapAtPeak = (rhoair * VolFlowRate * (MixEnth - SupEnth)) +
1881 : FanCoolLoad; // load on the cooling coil which includes ventilation load and fan heat (sensible)
1882 4 : SensCapAtPeak = max(0.0, SensCapAtPeak);
1883 4 : MixWetBulb = Psychrometrics::PsyTwbFnTdbWPb(state, MixTemp, MixHumRat, state.dataEnvrn->StdBaroPress, RoutineName);
1884 4 : RatedMixWetBulb = simpleWatertoAirHP.RatedEntAirWetbulbTemp;
1885 4 : RatedMixDryBulb = simpleWatertoAirHP.RatedEntAirDrybulbTemp;
1886 : // calculate temperature ratios at design day peak conditions
1887 4 : ratioTDB = (MixTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1888 4 : ratioTWB = (MixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1889 8 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
1890 : state,
1891 8 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1892 : simpleWatertoAirHP.Name,
1893 : simpleWatertoAirHP.WaterInletNodeNum,
1894 : simpleWatertoAirHP.WaterOutletNodeNum,
1895 : ErrorsFound,
1896 : false);
1897 4 : if (PltSizNum > 0) {
1898 3 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
1899 3 : ratioTS = (DesignEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1900 : } else {
1901 2 : ShowSevereError(state, "Autosizing of sensible cooling capacity requires a loop Sizing:Plant object");
1902 2 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
1903 2 : ShowContinueError(state,
1904 2 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
1905 1 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
1906 1 : simpleWatertoAirHP.Name));
1907 1 : ErrorsFound = true;
1908 : }
1909 : // calculate temperatue ratio at rated conditions
1910 4 : RatedratioTDB = (RatedMixDryBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1911 4 : RatedratioTWB = (RatedMixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1912 4 : RatedratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1913 4 : PeakSensCapTempModFac = simpleWatertoAirHP.SensCoolCapCurve->value(state, ratioTDB, ratioTWB, ratioTS, 1.0, 1.0);
1914 4 : RatedSensCapTempModFac =
1915 4 : simpleWatertoAirHP.SensCoolCapCurve->value(state, RatedratioTDB, RatedratioTWB, RatedratioTS, 1.0, 1.0);
1916 : // Check curve output when rated mixed air wetbulb is the design mixed air wetbulb
1917 : // calculate the rated sensible capacity based on peak conditions
1918 : // note: the rated sensible capacity can be different than the sensible capacity
1919 : // at rated conditions if the capacity curve isn't normalized at the rated
1920 : // conditions
1921 4 : RatedCapCoolSensDes = (PeakSensCapTempModFac > 0.0) ? SensCapAtPeak / PeakSensCapTempModFac : SensCapAtPeak;
1922 : } else {
1923 0 : RatedCapCoolSensDes = 0.0;
1924 : }
1925 : }
1926 : }
1927 9 : if (RatedCapCoolSensDes < HVAC::SmallLoad) {
1928 5 : RatedCapCoolSensDes = 0.0;
1929 : }
1930 9 : if (RatedCapCoolTotalAutoSized && RatedCapCoolSensAutoSized) {
1931 4 : if (RatedCapCoolSensDes > RatedCapCoolTotalDes) {
1932 1 : RatedCapCoolTotalDes = RatedCapCoolSensDes;
1933 : }
1934 : }
1935 9 : if (!HardSizeNoDesRun) {
1936 4 : if (RatedCapCoolTotalAutoSized) {
1937 4 : if (simpleWatertoAirHP.CompanionHeatingCoilNum > 0) {
1938 : auto const &companionHeatingCoil =
1939 3 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum);
1940 3 : if (companionHeatingCoil.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit &&
1941 3 : companionHeatingCoil.RatedCapHeat > 0) {
1942 : // case 1: companion heating coil has a user-specified capacity
1943 : // or has already been sized
1944 0 : RatedCapCoolTotalDesCDD = RatedCapCoolTotalDes;
1945 0 : RatedCapCoolHeatDD = companionHeatingCoil.RatedCapHeatAtRatedCdts / companionHeatingCoil.RatioRatedHeatRatedTotCoolCap /
1946 : RatedTotCapTempModFac;
1947 0 : if (RatedCapCoolHeatDD > RatedCapCoolTotalDesCDD) {
1948 : // re-base the cooling capacity
1949 0 : RatedCapCoolTotalDes = RatedCapCoolHeatDD;
1950 :
1951 : // adjust for system air flow -- capacity is based on heating design day calcs
1952 : // adjust by ratio of system to heating air flow rate and temperature delta across the coil at these different airflow
1953 0 : if (HeatingAirVolFlowRateDes > 0) {
1954 0 : RatedCapCoolTotalDes *= (RatedAirVolFlowRateDes / HeatingAirVolFlowRateDes) * HeatdTratio;
1955 : }
1956 :
1957 0 : if (RatedCapCoolSensAutoSized) {
1958 : // adjust sensible capacity assuming that the SHR is constant
1959 0 : RatedCapCoolSensDes *= RatedCapCoolTotalDes / RatedCapCoolTotalDesCDD;
1960 : }
1961 :
1962 0 : simpleWatertoAirHP.RatedCapCoolTotal = RatedCapCoolTotalDes;
1963 0 : OutputReportPredefined::PreDefTableEntry(
1964 0 : state, state.dataOutRptPredefined->pdchWAHPDD, simpleWatertoAirHP.Name, "Heating");
1965 : } else {
1966 : // adjust for system air flow -- capacity is based on cooling design day calcs
1967 : // adjust by ratio of system to cooling air flow rate and enthalpy delta across the coil at these different airflow
1968 0 : RatedCapCoolTotalDes *= (RatedAirVolFlowRateDes / CoolingAirVolFlowRateDes) * dHratio;
1969 :
1970 0 : simpleWatertoAirHP.RatedCapCoolTotal = RatedCapCoolTotalDes;
1971 0 : OutputReportPredefined::PreDefTableEntry(
1972 0 : state, state.dataOutRptPredefined->pdchWAHPDD, simpleWatertoAirHP.Name, "Cooling");
1973 : }
1974 : // Set the global DX cooling coil capacity variable for use by other objects
1975 0 : state.dataSize->DXCoolCap = simpleWatertoAirHP.RatedCapCoolTotal;
1976 3 : } else if (companionHeatingCoil.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit &&
1977 3 : companionHeatingCoil.RatedCapHeat == DataSizing::AutoSize) {
1978 : // case 2: companion heating coil has not already been sized
1979 : // we only pass the rated total cooling capacity determined
1980 : // based on cooling design day which is used to decide if the
1981 : // coil needs to be sized of the heating coil size
1982 : //
1983 : // no capcity adjustment based on system flow because the capacity could change
1984 : // once the heating coil has been sized
1985 3 : state.dataSize->DXCoolCap = RatedCapCoolTotalDes;
1986 0 : } else if (companionHeatingCoil.WAHPPlantType != DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit) {
1987 : // case 3: companion heating coil is not of the "equationfit" type and hence doesn't use the rated heating to cooling
1988 : // coil capacity ratio
1989 : // adjust for system air flow -- capacity is based on cooling design day calcs
1990 : // adjust by ratio of system to cooling air flow rate and enthalpy delta across the coil at these different airflow
1991 0 : RatedCapCoolTotalDes *= (RatedAirVolFlowRateDes / CoolingAirVolFlowRateDes) * dHratio;
1992 0 : simpleWatertoAirHP.RatedCapCoolTotal = RatedCapCoolTotalDes;
1993 : // Set the global DX cooling coil capacity variable for use by other objects
1994 0 : state.dataSize->DXCoolCap = simpleWatertoAirHP.RatedCapCoolTotal;
1995 : }
1996 : } else {
1997 : // adjust for system air flow -- capacity is based on cooling design day calcs
1998 : // adjust by ratio of system to cooling air flow rate and enthalpy delta across the coil at these different airflow
1999 1 : RatedCapCoolTotalDes *= (RatedAirVolFlowRateDes / CoolingAirVolFlowRateDes) * dHratio;
2000 :
2001 1 : simpleWatertoAirHP.RatedCapCoolTotal = RatedCapCoolTotalDes;
2002 1 : state.dataSize->DXCoolCap = simpleWatertoAirHP.RatedCapCoolTotal;
2003 : }
2004 : // size power
2005 4 : simpleWatertoAirHP.RatedCapCoolAtRatedCdts = RatedCapCoolTotalDes * RatedTotCapTempModFac;
2006 4 : simpleWatertoAirHP.RatedPowerCoolAtRatedCdts =
2007 4 : simpleWatertoAirHP.RatedCapCoolAtRatedCdts / simpleWatertoAirHP.RatedCOPCoolAtRatedCdts;
2008 4 : simpleWatertoAirHP.RatedPowerCool = simpleWatertoAirHP.RatedPowerCoolAtRatedCdts / RatedCoolPowerTempModFac;
2009 4 : if (simpleWatertoAirHP.RatedCapCoolTotal != DataSizing::AutoSize) {
2010 3 : BaseSizer::reportSizerOutput(
2011 : state,
2012 2 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2013 : simpleWatertoAirHP.Name,
2014 : "Design Size Rated Total Cooling Capacity [W]",
2015 : simpleWatertoAirHP.RatedCapCoolTotal);
2016 : }
2017 8 : OutputReportPredefined::PreDefTableEntry(
2018 4 : state, state.dataOutRptPredefined->pdchWAHPRatedAirDBT, simpleWatertoAirHP.Name, RatedMixDryBulb);
2019 8 : OutputReportPredefined::PreDefTableEntry(
2020 4 : state, state.dataOutRptPredefined->pdchWAHPRatedAirWBT, simpleWatertoAirHP.Name, RatedMixWetBulb);
2021 8 : OutputReportPredefined::PreDefTableEntry(
2022 4 : state, state.dataOutRptPredefined->pdchWAHPRatedWtrT, simpleWatertoAirHP.Name, simpleWatertoAirHP.RatedEntWaterTemp);
2023 : } else { // Hardsized with sizing data
2024 0 : if (simpleWatertoAirHP.RatedCapCoolTotal > 0.0 && RatedCapCoolTotalDes > 0.0) {
2025 0 : RatedCapCoolTotalUser = simpleWatertoAirHP.RatedCapCoolTotal;
2026 0 : state.dataSize->DXCoolCap = simpleWatertoAirHP.RatedCapCoolTotal;
2027 0 : simpleWatertoAirHP.RatedPowerCool = simpleWatertoAirHP.RatedCapCoolTotal / simpleWatertoAirHP.RatedCOPCoolAtRatedCdts;
2028 0 : BaseSizer::reportSizerOutput(
2029 : state,
2030 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2031 : simpleWatertoAirHP.Name,
2032 : "Design Size Rated Total Cooling Capacity [W]",
2033 : RatedCapCoolTotalDes,
2034 : "User-Specified Rated Total Cooling Capacity [W]",
2035 : RatedCapCoolTotalUser);
2036 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2037 0 : if ((std::abs(RatedCapCoolTotalDes - RatedCapCoolTotalUser) / RatedCapCoolTotalUser) >
2038 0 : state.dataSize->AutoVsHardSizingThreshold) {
2039 0 : ShowMessage(
2040 : state,
2041 0 : format("SizeHVACWaterToAir: Potential issue with equipment sizing for coil {}:WATERTOAIRHEATPUMP:EQUATIONFIT {}",
2042 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2043 0 : simpleWatertoAirHP.Name));
2044 0 : ShowContinueError(state, format("User-Specified Rated Total Cooling Capacity of {:.2R} [W]", RatedCapCoolTotalUser));
2045 0 : ShowContinueError(
2046 0 : state, format("differs from Design Size Rated Total Cooling Capacity of {:.2R} [W]", RatedCapCoolTotalDes));
2047 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2048 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2049 : }
2050 : }
2051 : }
2052 : }
2053 : } else {
2054 5 : state.dataSize->DXCoolCap = simpleWatertoAirHP.RatedCapCoolTotal;
2055 : // user provided inputs are assumed to be at rated conditions
2056 5 : simpleWatertoAirHP.RatedPowerCool = simpleWatertoAirHP.RatedCapCoolTotal / simpleWatertoAirHP.RatedCOPCoolAtRatedCdts;
2057 5 : simpleWatertoAirHP.RatedCapCoolAtRatedCdts = 0;
2058 5 : simpleWatertoAirHP.RatedPowerCoolAtRatedCdts = 0;
2059 : }
2060 9 : if (simpleWatertoAirHP.RatedCapCoolTotal !=
2061 : DataSizing::AutoSize) { // all cases except case 2 mentioned above (when EquationFit companion heating coil has not yet been sized)
2062 12 : OutputReportPredefined::PreDefTableEntry(
2063 6 : state, state.dataOutRptPredefined->pdchCoolCoilTotCap, simpleWatertoAirHP.Name, simpleWatertoAirHP.RatedCapCoolTotal);
2064 12 : OutputReportPredefined::PreDefTableEntry(state,
2065 6 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
2066 : simpleWatertoAirHP.Name,
2067 6 : simpleWatertoAirHP.RatedCapCoolTotal - simpleWatertoAirHP.RatedCapCoolSens);
2068 6 : if (simpleWatertoAirHP.RatedCapCoolTotal > 0) {
2069 12 : OutputReportPredefined::PreDefTableEntry(state,
2070 6 : state.dataOutRptPredefined->pdchCoolCoilSHR,
2071 : simpleWatertoAirHP.Name,
2072 6 : simpleWatertoAirHP.RatedCapCoolSens / simpleWatertoAirHP.RatedCapCoolTotal);
2073 : } else {
2074 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, simpleWatertoAirHP.Name, 0.0);
2075 : }
2076 6 : if (RatedCapCoolTotalAutoSized) {
2077 2 : OutputReportPredefined::PreDefTableEntry(state,
2078 1 : state.dataOutRptPredefined->pdchWAHPRatedCapAtRatedCdts,
2079 : simpleWatertoAirHP.Name,
2080 : simpleWatertoAirHP.RatedCapCoolAtRatedCdts);
2081 1 : if (simpleWatertoAirHP.CompanionHeatingCoilNum > 0) {
2082 : auto &companionHeatingCoil(
2083 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum));
2084 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWAHPDD, companionHeatingCoil.Name, "Cooling");
2085 : }
2086 : }
2087 : } else {
2088 : // set temporarily until companion heating coil is sized
2089 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, simpleWatertoAirHP.Name, 0.0);
2090 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilLatCap, simpleWatertoAirHP.Name, 0.0);
2091 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, simpleWatertoAirHP.Name, 0.0);
2092 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, simpleWatertoAirHP.Name, 0.0);
2093 : }
2094 9 : if (simpleWatertoAirHP.RatedCapCoolTotal != DataSizing::AutoSize) {
2095 6 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilCoolingCapacity(state,
2096 6 : simpleWatertoAirHP.Name,
2097 : CompType,
2098 : simpleWatertoAirHP.RatedCapCoolTotal,
2099 : RatedCapCoolTotalAutoSized,
2100 6 : state.dataSize->CurSysNum,
2101 6 : state.dataSize->CurZoneEqNum,
2102 6 : state.dataSize->CurOASysNum,
2103 : FanCoolLoad,
2104 : PeakTotCapTempModFac,
2105 : -999.0,
2106 : -999.0);
2107 : }
2108 9 : if (!HardSizeNoDesRun) {
2109 4 : if (RatedCapCoolSensAutoSized) {
2110 4 : simpleWatertoAirHP.RatedCapCoolSens = RatedCapCoolSensDes;
2111 4 : simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts = RatedCapCoolSensDes * RatedSensCapTempModFac;
2112 4 : if (simpleWatertoAirHP.RatedCapCoolTotal != DataSizing::AutoSize) {
2113 3 : BaseSizer::reportSizerOutput(
2114 : state,
2115 2 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2116 : simpleWatertoAirHP.Name,
2117 : "Design Size Rated Sensible Cooling Capacity [W]",
2118 : RatedCapCoolSensDes);
2119 : }
2120 : } else {
2121 0 : if (simpleWatertoAirHP.RatedCapCoolSens > 0.0 && RatedCapCoolSensDes > 0.0) {
2122 0 : RatedCapCoolSensUser = simpleWatertoAirHP.RatedCapCoolSens;
2123 0 : BaseSizer::reportSizerOutput(
2124 : state,
2125 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2126 : simpleWatertoAirHP.Name,
2127 : "Design Size Rated Sensible Cooling Capacity [W]",
2128 : RatedCapCoolSensDes,
2129 : "User-Specified Rated Sensible Cooling Capacity [W]",
2130 : RatedCapCoolSensUser);
2131 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2132 0 : if ((std::abs(RatedCapCoolSensDes - RatedCapCoolSensUser) / RatedCapCoolSensUser) >
2133 0 : state.dataSize->AutoVsHardSizingThreshold) {
2134 0 : ShowMessage(
2135 : state,
2136 0 : format("SizeHVACWaterToAir: Potential issue with equipment sizing for coil {}:WATERTOAIRHEATPUMP:EQUATIONFIT {}",
2137 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2138 0 : simpleWatertoAirHP.Name));
2139 0 : ShowContinueError(state,
2140 0 : format("User-Specified Rated Sensible Cooling Capacity of {:.2R} [W]", RatedCapCoolSensUser));
2141 0 : ShowContinueError(
2142 0 : state, format("differs from Design Size Rated Sensible Cooling Capacity of {:.2R} [W]", RatedCapCoolSensDes));
2143 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2144 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2145 : }
2146 : }
2147 : }
2148 : }
2149 : }
2150 18 : OutputReportPredefined::PreDefTableEntry(
2151 9 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, simpleWatertoAirHP.Name, simpleWatertoAirHP.RatedCapCoolSens);
2152 18 : OutputReportPredefined::PreDefTableEntry(state,
2153 9 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
2154 : simpleWatertoAirHP.Name,
2155 9 : state.dataSize->DXCoolCap - simpleWatertoAirHP.RatedCapCoolSens);
2156 9 : if (RatedCapCoolSensAutoSized) {
2157 :
2158 8 : OutputReportPredefined::PreDefTableEntry(state,
2159 4 : state.dataOutRptPredefined->pdchWAHPRatedSensCapAtRatedCdts,
2160 : simpleWatertoAirHP.Name,
2161 : simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts);
2162 : }
2163 9 : if (simpleWatertoAirHP.RatedCapCoolTotal != 0.0) {
2164 18 : OutputReportPredefined::PreDefTableEntry(state,
2165 9 : state.dataOutRptPredefined->pdchCoolCoilSHR,
2166 : simpleWatertoAirHP.Name,
2167 9 : simpleWatertoAirHP.RatedCapCoolSens / state.dataSize->DXCoolCap);
2168 : } else {
2169 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, simpleWatertoAirHP.Name, 0.0);
2170 : }
2171 : // test autosized sensible and total cooling capacity for total > sensible
2172 9 : if ((RatedCapCoolSensAutoSized && RatedCapCoolTotalAutoSized) || RatedCapCoolSensAutoSized) {
2173 4 : if (simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts > simpleWatertoAirHP.RatedCapCoolAtRatedCdts) {
2174 0 : ShowWarningError(state,
2175 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT \"{}\"",
2176 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2177 0 : simpleWatertoAirHP.Name));
2178 0 : ShowContinueError(state, format("{}: Rated Sensible Cooling Capacity > Rated Total Cooling Capacity", RoutineName));
2179 0 : ShowContinueError(state, "Both of these capacity inputs have been autosized.");
2180 0 : ShowContinueError(
2181 : state,
2182 0 : format("Rated Sensible Cooling Capacity at Rated Conditions = {:.2T} W", simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts));
2183 0 : ShowContinueError(
2184 0 : state, format("Rated Total Cooling Capacity at Rated Conditions = {:.2T} W", simpleWatertoAirHP.RatedCapCoolAtRatedCdts));
2185 0 : ShowContinueError(state, "See eio file for further details.");
2186 0 : ShowContinueError(state, "Check Total and Sensible Cooling Capacity coefficients in curves to ensure they are accurate.");
2187 0 : ShowContinueError(state, "Check Zone and System Sizing objects to verify sizing inputs.");
2188 0 : ShowContinueError(state, "Sizing statistics:");
2189 0 : ShowContinueError(state, format("Rated entering Air Wet-Bulb Temperature = {:.3T} C", RatedMixWetBulb));
2190 0 : ShowContinueError(state, format("Peak entering Air Wet-Bulb Temperature = {:.3T} C", MixWetBulb));
2191 0 : ShowContinueError(state, format("Entering Water Temperature used = {:.3T} C", simpleWatertoAirHP.RatedEntWaterTemp));
2192 0 : ShowContinueError(state, "Design air and water flow rates = 1.0");
2193 0 : ShowContinueError(
2194 0 : state, format("Rated ratio of load-side air wet-bulb temperature to 283.15 C (Rated ratioTWB) = {:.3T}", RatedratioTWB));
2195 0 : ShowContinueError(
2196 0 : state, format("Rated ratio of source-side inlet water temperature to 283.15 C (Rated ratioTS) = {:.3T}", RatedratioTS));
2197 0 : ShowContinueError(state,
2198 0 : format("Peak ratio of load-side air wet-bulb temperature to 283.15 C (Peak ratioTWB) = {:.3T}", ratioTWB));
2199 0 : ShowContinueError(state,
2200 0 : format("Peak ratio of source-side inlet water temperature to 283.15 C (Peak ratioTS) = {:.3T}", ratioTS));
2201 0 : ShowContinueError(state, format("Rated Total Cooling Capacity Modifier = {:.5T}", RatedTotCapTempModFac));
2202 0 : ShowContinueError(state, format("Peak Design Total Cooling Capacity Modifier = {:.5T}", PeakTotCapTempModFac));
2203 0 : ShowContinueError(state, format("Rated Sensible Cooling Capacity Modifier = {:.5T}", RatedSensCapTempModFac));
2204 0 : ShowContinueError(state, format("Peak Design Sensible Cooling Capacity Modifier = {:.5T}", PeakSensCapTempModFac));
2205 0 : ShowContinueError(state,
2206 : "...Rated Total Cooling Capacity at Rated Conditions = Total Peak Design Load * Rated Total "
2207 : "Cooling Capacity Modifier / "
2208 : "Peak Design Total Cooling Capacity Modifier");
2209 0 : ShowContinueError(state,
2210 : "...Rated Sensible Cooling Capacity at Rated Conditions = Peak Design Sensible Load * Rated "
2211 : "Sensible Cooling "
2212 : "Capacity Modifier / Peak Design Sensible Cooling Capacity Modifier");
2213 0 : ShowContinueError(state, "Carefully review the Load Side Total, Sensible, and Latent heat transfer rates");
2214 0 : ShowContinueError(state, "... to ensure they meet the expected manufacturers performance specifications.");
2215 : }
2216 5 : } else if (RatedCapCoolTotalAutoSized) {
2217 0 : if (simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts > simpleWatertoAirHP.RatedCapCoolAtRatedCdts) {
2218 0 : ShowWarningError(state,
2219 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT \"{}\"",
2220 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2221 0 : simpleWatertoAirHP.Name));
2222 0 : ShowContinueError(state, format("{}: Rated Sensible Cooling Capacity > Rated Total Cooling Capacity", RoutineName));
2223 0 : ShowContinueError(state, "Only the Rated total capacity input is autosized, consider autosizing both inputs.");
2224 0 : ShowContinueError(state, format("Rated Sensible Cooling Capacity = {:.2T} W", simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts));
2225 0 : ShowContinueError(state, format("Rated Total Cooling Capacity = {:.2T} W", simpleWatertoAirHP.RatedCapCoolAtRatedCdts));
2226 0 : ShowContinueError(state, "See eio file for further details.");
2227 0 : ShowContinueError(state, "Check Total and Sensible Cooling Capacity coefficients in curves to ensure they are accurate.");
2228 0 : ShowContinueError(state, "Check Zone and System Sizing objects to verify sizing inputs.");
2229 0 : ShowContinueError(state, "Sizing statistics for Total Cooling Capacity:");
2230 0 : ShowContinueError(state, format("Rated entering Air Wet-Bulb Temperature = {:.3T} C", RatedMixWetBulb));
2231 0 : ShowContinueError(state, format("Peak entering Air Wet-Bulb Temperature = {:.3T} C", MixWetBulb));
2232 0 : ShowContinueError(state, format("Entering Water Temperature used = {:.3T} C", simpleWatertoAirHP.RatedEntWaterTemp));
2233 0 : ShowContinueError(state, "Design air and water flow rates = 1.0");
2234 0 : ShowContinueError(
2235 0 : state, format("Rated ratio of load-side air wet-bulb temperature to 283.15 C (Rated ratioTWB) = {:.3T}", RatedratioTWB));
2236 0 : ShowContinueError(
2237 0 : state, format("Rated ratio of source-side inlet water temperature to 283.15 C (Rated ratioTS) = {:.3T}", RatedratioTS));
2238 0 : ShowContinueError(state,
2239 0 : format("Peak ratio of load-side air wet-bulb temperature to 283.15 C (Peak ratioTWB) = {:.3T}", ratioTWB));
2240 0 : ShowContinueError(state,
2241 0 : format("Peak ratio of source-side inlet water temperature to 283.15 C (Peak ratioTS) = {:.3T}", ratioTS));
2242 0 : ShowContinueError(state, format("Rated Total Cooling Capacity Modifier = {:.5T}", RatedTotCapTempModFac));
2243 0 : ShowContinueError(state, format("Peak Design Total Cooling Capacity Modifier = {:.5T}", PeakTotCapTempModFac));
2244 0 : ShowContinueError(state,
2245 : "...Rated Total Cooling Capacity at Rated Conditions = Total Peak Design Load * Rated Total "
2246 : "Cooling Capacity Modifier / "
2247 : "Peak Design Total Cooling Capacity Modifier");
2248 0 : ShowContinueError(state,
2249 : "...Rated Sensible Cooling Capacity at Rated Conditions = Peak Design Sensible Load * Rated "
2250 : "Sensible Cooling "
2251 : "Capacity Modifier / Peak Design Sensible Cooling Capacity Modifier");
2252 0 : ShowContinueError(state, "Carefully review the Load Side Total, Sensible, and Latent heat transfer rates");
2253 0 : ShowContinueError(state, "... to ensure they meet the expected manufacturers performance specifications.");
2254 : }
2255 : }
2256 :
2257 : } // Cooling Coil
2258 :
2259 16 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating) {
2260 : // size rated heating capacity
2261 7 : IsAutoSize = false;
2262 7 : if (simpleWatertoAirHP.RatedCapHeat == DataSizing::AutoSize) {
2263 3 : IsAutoSize = true;
2264 : }
2265 7 : if (SizingDesRunThisAirSys || SizingDesRunThisZone) HardSizeNoDesRun = false;
2266 7 : if (IsAutoSize) {
2267 3 : if (state.dataSize->CurSysNum > 0) {
2268 0 : CheckSysSizing(
2269 : state,
2270 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2271 0 : simpleWatertoAirHP.Name);
2272 0 : if (HeatingAirVolFlowRateDes > 0.0) {
2273 0 : VolFlowRate = HeatingAirVolFlowRateDes;
2274 : } else {
2275 0 : VolFlowRate = CoolingAirVolFlowRateDes; // system air flow
2276 : }
2277 : // heating design day calculations
2278 0 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
2279 0 : auto const &finalSysSizing = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum);
2280 0 : if (state.dataSize->CurOASysNum > 0) { // coil is in the OA stream
2281 0 : HeatMixTemp = finalSysSizing.HeatOutTemp;
2282 0 : HeatMixHumRat = finalSysSizing.HeatOutHumRat;
2283 0 : HeatSupTemp = finalSysSizing.PreheatTemp;
2284 : } else { // coil is on the main air loop
2285 0 : if (VolFlowRate > 0.0) {
2286 0 : HeatOutAirFrac = finalSysSizing.DesOutAirVolFlow / VolFlowRate;
2287 0 : HeatOutAirFracSys = finalSysSizing.DesOutAirVolFlow / RatedAirVolFlowRateDes;
2288 : } else {
2289 0 : HeatOutAirFrac = 1.0;
2290 0 : HeatOutAirFracSys = HeatOutAirFrac;
2291 : }
2292 0 : HeatOutAirFrac = min(1.0, max(0.0, HeatOutAirFrac));
2293 0 : HeatOutAirFracSys = min(1.0, max(0.0, HeatOutAirFracSys));
2294 0 : HeatSupTemp = finalSysSizing.HeatSupTemp;
2295 0 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).NumOAHeatCoils ==
2296 : 0) { // there is no preheating of the OA stream
2297 0 : HeatMixTemp = HeatOutAirFrac * finalSysSizing.HeatOutTemp + (1.0 - HeatOutAirFrac) * finalSysSizing.HeatRetTemp;
2298 0 : HeatMixHumRat = HeatOutAirFrac * finalSysSizing.HeatOutHumRat + (1.0 - HeatOutAirFrac) * finalSysSizing.HeatRetHumRat;
2299 : // calculate mixed air temperature with system airflow
2300 0 : HeatMixTempSys =
2301 0 : HeatOutAirFracSys * finalSysSizing.HeatOutTemp + (1.0 - HeatOutAirFracSys) * finalSysSizing.HeatRetTemp;
2302 0 : HeatMixHumRatSys =
2303 0 : HeatOutAirFracSys * finalSysSizing.HeatOutHumRat + (1.0 - HeatOutAirFracSys) * finalSysSizing.HeatRetHumRat;
2304 : } else { // there is preheating of OA stream
2305 0 : HeatOutAirFrac = min(1.0, max(0.0, HeatOutAirFrac));
2306 0 : HeatMixTemp = HeatOutAirFrac * finalSysSizing.PreheatTemp + (1.0 - HeatOutAirFrac) * finalSysSizing.HeatRetTemp;
2307 0 : HeatMixHumRat = HeatOutAirFrac * finalSysSizing.PreheatHumRat + (1.0 - HeatOutAirFrac) * finalSysSizing.HeatRetHumRat;
2308 : // calculate mixed air temperature with system airflow
2309 0 : HeatMixTempSys =
2310 0 : HeatOutAirFracSys * finalSysSizing.PreheatTemp + (1.0 - HeatOutAirFracSys) * finalSysSizing.HeatRetTemp;
2311 0 : HeatMixHumRatSys =
2312 0 : HeatOutAirFracSys * finalSysSizing.PreheatHumRat + (1.0 - HeatOutAirFracSys) * finalSysSizing.HeatRetHumRat;
2313 : }
2314 : // determine the coil ratio of coil dT with system air flow to design heating air flow
2315 0 : HeatdTratio = (HeatSupTemp - HeatMixTempSys) / (HeatSupTemp - HeatMixTemp);
2316 : }
2317 0 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, HeatMixTemp, HeatMixHumRat, RoutineName);
2318 0 : HeatCapAtPeak = rhoair * VolFlowRate * Psychrometrics::PsyCpAirFnW(DataPrecisionGlobals::constant_zero) *
2319 0 : (HeatSupTemp - HeatMixTemp); // heating coil load
2320 0 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid &&
2321 0 : state.dataSize->DataFanIndex > 0) { // remove fan heat to coil load
2322 0 : FanHeatLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
2323 :
2324 0 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(HeatMixHumRat);
2325 0 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace == HVAC::FanPlace::BlowThru) {
2326 0 : HeatMixTemp += FanHeatLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature entering the coil
2327 0 : } else if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace ==
2328 : HVAC::FanPlace::DrawThru) {
2329 0 : HeatSupTemp -= FanHeatLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature leaving the coil
2330 : }
2331 : }
2332 0 : HeatCapAtPeak -= FanHeatLoad; // remove fan heat from heating coil load
2333 0 : HeatCapAtPeak = max(0.0, HeatCapAtPeak);
2334 0 : RatedHeatMixDryBulb = simpleWatertoAirHP.RatedEntAirDrybulbTemp;
2335 : // calculate temperatue ratio at design day peak conditions
2336 0 : HeatratioTDB = (HeatMixTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2337 0 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
2338 : state,
2339 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2340 : simpleWatertoAirHP.Name,
2341 : simpleWatertoAirHP.WaterInletNodeNum,
2342 : simpleWatertoAirHP.WaterOutletNodeNum,
2343 : ErrorsFound,
2344 : false);
2345 0 : if (PltSizNum > 0) {
2346 0 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
2347 0 : HeatratioTS = (DesignEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2348 : } else {
2349 0 : ShowSevereError(state, "Autosizing of heating capacity requires a loop Sizing:Plant object");
2350 0 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
2351 0 : ShowContinueError(state,
2352 0 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
2353 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2354 0 : simpleWatertoAirHP.Name));
2355 0 : HeatratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
2356 0 : ErrorsFound = true;
2357 : }
2358 : // calculate temperatue ratio at refrence conditions
2359 0 : RatedHeatratioTDB = (RatedHeatMixDryBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2360 0 : RatedHeatratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2361 : // determine curve modifiers at peak and rated conditions
2362 0 : PeakHeatCapTempModFac = simpleWatertoAirHP.HeatCapCurve->value(state, HeatratioTDB, HeatratioTS, 1.0, 1.0);
2363 0 : RatedHeatCapTempModFac = simpleWatertoAirHP.HeatCapCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
2364 : // Check curve output when rated mixed air wetbulb is the design mixed air wetbulb
2365 0 : if (RatedHeatMixDryBulb == HeatMixTemp) {
2366 0 : if (RatedHeatCapTempModFac > 1.02 || RatedHeatCapTempModFac < 0.98) {
2367 0 : ShowWarningError(state,
2368 0 : format("{} Coil:Heating:WaterToAirHeatPump:EquationFit={}", RoutineName, simpleWatertoAirHP.Name));
2369 0 : ShowContinueError(state,
2370 : "Heating capacity as a function of temperature curve output is not equal to 1.0 (+ or - 2%) "
2371 : "at rated conditions.");
2372 0 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedHeatCapTempModFac));
2373 : }
2374 : }
2375 : // calculate the rated capacity based on peak conditions
2376 : // note: the rated capacity can be different than the capacity at
2377 : // rated conditions if the capacity curve isn't normalized at the
2378 : // rated conditions
2379 0 : RatedCapHeatDes = (PeakHeatCapTempModFac > 0.0) ? HeatCapAtPeak / PeakHeatCapTempModFac : HeatCapAtPeak;
2380 : } else {
2381 0 : RatedCapHeatDes = 0.0;
2382 0 : RatedHeatratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
2383 : }
2384 3 : } else if (state.dataSize->CurZoneEqNum > 0) {
2385 6 : CheckZoneSizing(
2386 : state,
2387 6 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2388 : simpleWatertoAirHP.Name);
2389 3 : if (HeatingAirVolFlowRateDes > 0.0) {
2390 3 : VolFlowRate = HeatingAirVolFlowRateDes;
2391 : } else {
2392 0 : VolFlowRate = CoolingAirVolFlowRateDes; // system air flow
2393 : }
2394 3 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
2395 2 : if (state.dataSize->ZoneEqDXCoil) {
2396 2 : if (state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow > 0.0) {
2397 0 : HeatMixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInTemp;
2398 0 : HeatMixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInHumRat;
2399 : // calculate mixed air temperature with system airflow
2400 0 : HeatOAFrac = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA / HeatingAirVolFlowRateDes;
2401 0 : HeatOAFracSys = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA / RatedAirVolFlowRateDes;
2402 0 : HeatOAFrac = min(1.0, max(0.0, HeatOAFrac));
2403 0 : HeatOAFracSys = min(1.0, max(0.0, HeatOAFracSys));
2404 0 : HeatOATemp = (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInTemp -
2405 0 : (1.0 - HeatOAFrac) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneTempAtHeatPeak) /
2406 : HeatOAFrac;
2407 0 : HeatMixTempSys =
2408 0 : HeatOAFracSys * HeatOATemp +
2409 0 : (1.0 - HeatOAFracSys) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneTempAtHeatPeak;
2410 : } else {
2411 2 : HeatMixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneRetTempAtHeatPeak;
2412 2 : HeatMixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneHumRatAtHeatPeak;
2413 2 : HeatMixTempSys = HeatMixTemp;
2414 : }
2415 : } else {
2416 0 : HeatMixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInTemp;
2417 0 : HeatMixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInHumRat;
2418 0 : HeatMixTempSys = HeatMixTemp;
2419 : }
2420 2 : HeatSupTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).HeatDesTemp;
2421 : // determine the coil ratio of coil dT with system air flow to design heating air flow
2422 2 : HeatdTratio = (HeatSupTemp - HeatMixTempSys) / (HeatSupTemp - HeatMixTemp);
2423 2 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, HeatMixTemp, HeatMixHumRat, RoutineName);
2424 2 : HeatCapAtPeak = rhoair * VolFlowRate * Psychrometrics::PsyCpAirFnW(DataPrecisionGlobals::constant_zero) *
2425 2 : (HeatSupTemp - HeatMixTemp); // heating coil load
2426 2 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid && state.dataSize->DataFanIndex > 0) { // add fan heat to coil load
2427 1 : FanHeatLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
2428 :
2429 1 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(HeatMixHumRat);
2430 1 : if (state.dataSize->DataFanPlacement == HVAC::FanPlace::BlowThru) {
2431 1 : HeatMixTemp += FanHeatLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature entering the coil
2432 : } else {
2433 0 : HeatSupTemp -= FanHeatLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature leaving the coil
2434 : }
2435 : }
2436 2 : HeatCapAtPeak -= FanHeatLoad; // remove fan heat from heating coil load
2437 2 : HeatCapAtPeak = max(0.0, HeatCapAtPeak);
2438 2 : RatedHeatMixDryBulb = simpleWatertoAirHP.RatedEntAirDrybulbTemp;
2439 : // calculate temperatue ratio at design day peak conditions
2440 2 : HeatratioTDB = (HeatMixTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2441 4 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
2442 : state,
2443 4 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2444 : simpleWatertoAirHP.Name,
2445 : simpleWatertoAirHP.WaterInletNodeNum,
2446 : simpleWatertoAirHP.WaterOutletNodeNum,
2447 : ErrorsFound,
2448 : false);
2449 2 : if (PltSizNum > 0) {
2450 2 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
2451 2 : HeatratioTS = (DesignEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2452 : } else {
2453 0 : ShowSevereError(state, "Autosizing of heating capacity requires a loop Sizing:Plant object");
2454 0 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
2455 0 : ShowContinueError(state,
2456 0 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
2457 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2458 0 : simpleWatertoAirHP.Name));
2459 0 : HeatratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
2460 0 : ErrorsFound = true;
2461 : }
2462 : // calculate temperatue ratio at refrence conditions
2463 2 : RatedHeatratioTDB = (RatedHeatMixDryBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2464 2 : RatedHeatratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2465 : // determine curve modifiers at peak and rated conditions
2466 2 : PeakHeatCapTempModFac = simpleWatertoAirHP.HeatCapCurve->value(state, HeatratioTDB, HeatratioTS, 1.0, 1.0);
2467 2 : RatedHeatCapTempModFac = simpleWatertoAirHP.HeatCapCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
2468 2 : RatedHeatPowerTempModFac = simpleWatertoAirHP.HeatPowCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
2469 : // Check curve output when rated mixed air wetbulb is the design mixed air wetbulb
2470 2 : if (RatedHeatMixDryBulb == HeatMixTemp) {
2471 0 : if (RatedHeatCapTempModFac > 1.02 || RatedHeatCapTempModFac < 0.98) {
2472 0 : ShowWarningError(state,
2473 0 : format("{} Coil:Heating:WaterToAirHeatPump:EquationFit={}", RoutineName, simpleWatertoAirHP.Name));
2474 0 : ShowContinueError(state,
2475 : "Heating capacity as a function of temperature curve output is not equal to 1.0 (+ or - 2%) "
2476 : "at rated conditions.");
2477 0 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedHeatCapTempModFac));
2478 : }
2479 0 : if (RatedHeatPowerTempModFac > 1.02 || RatedHeatPowerTempModFac < 0.98) {
2480 0 : ShowWarningError(state,
2481 0 : format("{} Coil:Heating:WaterToAirHeatPump:EquationFit={}", RoutineName, simpleWatertoAirHP.Name));
2482 0 : ShowContinueError(state,
2483 : "Heating power consumption as a function of temperature curve output is not equal to "
2484 : "1.0 (+ or - 2%) at rated conditions.");
2485 0 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedHeatPowerTempModFac));
2486 : }
2487 : }
2488 : // calculate the rated capacity based on peak conditions
2489 : // note: the rated capacity can be different than the capacity at
2490 : // rated conditions if the capacity curve isn't normalized at the
2491 : // rated conditions
2492 2 : RatedCapHeatDes = (PeakHeatCapTempModFac > 0.0) ? HeatCapAtPeak / PeakHeatCapTempModFac : HeatCapAtPeak;
2493 : } else {
2494 1 : RatedHeatratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
2495 1 : RatedCapHeatDes = 0.0;
2496 : }
2497 : } else {
2498 0 : RatedHeatratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
2499 : }
2500 :
2501 : // determine adjusted cooling and heating coil capacity
2502 3 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts = RatedCapHeatDes * RatedHeatCapTempModFac;
2503 3 : if (simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
2504 3 : auto &companionCoolingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum));
2505 3 : if (companionCoolingCoil.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit &&
2506 3 : companionCoolingCoil.RatedCapCoolTotal == DataSizing::AutoSize) {
2507 : // case 1: companion coil is also of EquationFit type and is being autosized
2508 3 : RatedCapCoolTotalDes = state.dataSize->DXCoolCap;
2509 3 : RatedTotCapTempModFac = companionCoolingCoil.RatedCapCoolAtRatedCdts / RatedCapCoolTotalDes;
2510 3 : RatedCapCoolHeatDD =
2511 3 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts / simpleWatertoAirHP.RatioRatedHeatRatedTotCoolCap / RatedTotCapTempModFac;
2512 3 : RatedCoolPowerTempModFac = companionCoolingCoil.RatedPowerCoolAtRatedCdts / companionCoolingCoil.RatedPowerCool;
2513 3 : if (RatedCapCoolHeatDD > RatedCapCoolTotalDes) {
2514 : // total cooling capacity
2515 1 : RatedCapCoolTotalDes = RatedCapCoolHeatDD;
2516 : // adjust for system air flow -- capacity is based on heating design day calcs
2517 : // adjust by ratio of system to heating air flow rate and temperature delta across the coil at these different airflow
2518 1 : if (HeatingAirVolFlowRateDes > 0) {
2519 1 : RatedCapCoolTotalDes *= (RatedAirVolFlowRateDes / HeatingAirVolFlowRateDes) * HeatdTratio;
2520 : }
2521 : // calculate ajustment factor over previous capacity for sensible capacity adjustment
2522 1 : Real64 CapCoolAdjFac = RatedCapCoolTotalDes / state.dataSize->DXCoolCap;
2523 : // update cooling coil rated capacity after adjustments based on heating coil size
2524 1 : state.dataSize->DXCoolCap = RatedCapCoolTotalDes;
2525 : // sensible cooling capacity
2526 1 : RatedCapCoolSensDes = companionCoolingCoil.RatedCapCoolSens * CapCoolAdjFac; // Assume that SHR stays the same
2527 1 : companionCoolingCoil.RatedCapCoolSensDesAtRatedCdts *= CapCoolAdjFac;
2528 1 : companionCoolingCoil.RatedCapCoolSens = RatedCapCoolSensDes;
2529 : // update Water-to-Air Heat Pumps output reports
2530 2 : OutputReportPredefined::PreDefTableEntry(state,
2531 1 : state.dataOutRptPredefined->pdchWAHPRatedSensCapAtRatedCdts,
2532 : companionCoolingCoil.Name,
2533 : companionCoolingCoil.RatedCapCoolSensDesAtRatedCdts);
2534 2 : OutputReportPredefined::PreDefTableEntry(
2535 1 : state, state.dataOutRptPredefined->pdchWAHPDD, companionCoolingCoil.Name, "Heating");
2536 2 : OutputReportPredefined::PreDefTableEntry(
2537 1 : state, state.dataOutRptPredefined->pdchWAHPDD, simpleWatertoAirHP.Name, "Heating");
2538 : // update Cooling Coils output reports
2539 2 : OutputReportPredefined::PreDefTableEntry(state,
2540 1 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
2541 : companionCoolingCoil.Name,
2542 : RatedCapCoolTotalDes - RatedCapCoolSensDes);
2543 2 : OutputReportPredefined::PreDefTableEntry(state,
2544 1 : state.dataOutRptPredefined->pdchCoolCoilSHR,
2545 : companionCoolingCoil.Name,
2546 : RatedCapCoolSensDes / RatedCapCoolTotalDes);
2547 2 : OutputReportPredefined::PreDefTableEntry(
2548 1 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, companionCoolingCoil.Name, RatedCapCoolSensDes);
2549 : } else {
2550 4 : OutputReportPredefined::PreDefTableEntry(
2551 2 : state, state.dataOutRptPredefined->pdchWAHPDD, companionCoolingCoil.Name, "Cooling");
2552 4 : OutputReportPredefined::PreDefTableEntry(
2553 2 : state, state.dataOutRptPredefined->pdchWAHPDD, simpleWatertoAirHP.Name, "Cooling");
2554 : }
2555 3 : RatedCapHeatDes =
2556 3 : RatedCapCoolTotalDes * RatedTotCapTempModFac * simpleWatertoAirHP.RatioRatedHeatRatedTotCoolCap / RatedHeatCapTempModFac;
2557 3 : companionCoolingCoil.RatedCapCoolTotal = RatedCapCoolTotalDes;
2558 3 : companionCoolingCoil.RatedCapCoolAtRatedCdts = RatedCapCoolTotalDes * RatedTotCapTempModFac;
2559 3 : companionCoolingCoil.RatedPowerCoolAtRatedCdts =
2560 3 : companionCoolingCoil.RatedCapCoolAtRatedCdts / companionCoolingCoil.RatedCOPCoolAtRatedCdts;
2561 3 : companionCoolingCoil.RatedPowerCool = companionCoolingCoil.RatedPowerCoolAtRatedCdts / RatedCoolPowerTempModFac;
2562 : // update Water-to-Air Heat Pumps output reports
2563 6 : OutputReportPredefined::PreDefTableEntry(state,
2564 3 : state.dataOutRptPredefined->pdchWAHPRatedCapAtRatedCdts,
2565 : companionCoolingCoil.Name,
2566 : companionCoolingCoil.RatedCapCoolAtRatedCdts);
2567 : // update Cooling Coils output reports
2568 6 : OutputReportPredefined::PreDefTableEntry(
2569 3 : state, state.dataOutRptPredefined->pdchCoolCoilTotCap, companionCoolingCoil.Name, RatedCapCoolTotalDes);
2570 9 : BaseSizer::reportSizerOutput(
2571 : state,
2572 6 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(companionCoolingCoil.WAHPType)]),
2573 : companionCoolingCoil.Name,
2574 : "Design Size Rated Total Cooling Capacity [W]",
2575 : companionCoolingCoil.RatedCapCoolTotal);
2576 9 : BaseSizer::reportSizerOutput(
2577 : state,
2578 6 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(companionCoolingCoil.WAHPType)]),
2579 : companionCoolingCoil.Name,
2580 : "Design Size Rated Sensible Cooling Capacity [W]",
2581 : companionCoolingCoil.RatedCapCoolSens);
2582 3 : } else if (companionCoolingCoil.WAHPPlantType ==
2583 : DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit) { // case 2: companion coil is of EquationFit type but is
2584 : // not autosized
2585 0 : RatedCapHeatDes = companionCoolingCoil.RatedCapCoolTotal * simpleWatertoAirHP.RatioRatedHeatRatedTotCoolCap;
2586 : } else { // case 3: companion type is different than EquationFit
2587 0 : RatedCapHeatDes = state.dataSize->DXCoolCap;
2588 : }
2589 : }
2590 : // heating capacity final determination
2591 3 : simpleWatertoAirHP.RatedCapHeat = RatedCapHeatDes;
2592 3 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts = RatedCapHeatDes * RatedHeatCapTempModFac;
2593 :
2594 : // heating power calculations
2595 3 : RatedHeatPowerTempModFac = simpleWatertoAirHP.HeatPowCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
2596 3 : simpleWatertoAirHP.RatedPowerHeat =
2597 3 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts / (simpleWatertoAirHP.RatedCOPHeatAtRatedCdts * RatedHeatPowerTempModFac);
2598 :
2599 : // update reports
2600 6 : OutputReportPredefined::PreDefTableEntry(state,
2601 3 : state.dataOutRptPredefined->pdchWAHPRatedCapAtRatedCdts,
2602 : simpleWatertoAirHP.Name,
2603 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts);
2604 6 : OutputReportPredefined::PreDefTableEntry(
2605 3 : state, state.dataOutRptPredefined->pdchWAHPRatedAirDBT, simpleWatertoAirHP.Name, RatedHeatMixDryBulb);
2606 6 : OutputReportPredefined::PreDefTableEntry(
2607 3 : state, state.dataOutRptPredefined->pdchWAHPRatedWtrT, simpleWatertoAirHP.Name, simpleWatertoAirHP.RatedEntWaterTemp);
2608 9 : BaseSizer::reportSizerOutput(
2609 : state,
2610 6 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2611 : simpleWatertoAirHP.Name,
2612 : "Design Size Rated Heating Capacity [W]",
2613 : simpleWatertoAirHP.RatedCapHeat);
2614 6 : OutputReportPredefined::PreDefTableEntry(
2615 3 : state, state.dataOutRptPredefined->pdchHeatCoilNomCap, simpleWatertoAirHP.Name, simpleWatertoAirHP.RatedCapHeat);
2616 3 : if (simpleWatertoAirHP.RatedCapHeat != 0.0) {
2617 6 : OutputReportPredefined::PreDefTableEntry(state,
2618 3 : state.dataOutRptPredefined->pdchHeatCoilNomEff,
2619 : simpleWatertoAirHP.Name,
2620 3 : simpleWatertoAirHP.RatedPowerHeat / simpleWatertoAirHP.RatedCapHeat);
2621 : } else {
2622 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, simpleWatertoAirHP.Name, 0.0);
2623 : }
2624 : } else {
2625 4 : if (simpleWatertoAirHP.RatedCapHeat > 0.0 && RatedCapHeatDes > 0.0 && !HardSizeNoDesRun) {
2626 0 : RatedCapHeatUser = simpleWatertoAirHP.RatedCapHeat;
2627 0 : BaseSizer::reportSizerOutput(
2628 : state,
2629 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2630 : simpleWatertoAirHP.Name,
2631 : "Design Size Rated Heating Capacity [W]",
2632 : RatedCapHeatDes,
2633 : "User-Specified Rated Heating Capacity [W]",
2634 : RatedCapHeatUser);
2635 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2636 0 : if ((std::abs(RatedCapHeatDes - RatedCapHeatUser) / RatedCapHeatUser) > state.dataSize->AutoVsHardSizingThreshold) {
2637 0 : ShowMessage(
2638 : state,
2639 0 : format("SizeHVACWaterToAir: Potential issue with equipment sizing for coil {}:WATERTOAIRHEATPUMP:EQUATIONFIT {}",
2640 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2641 0 : simpleWatertoAirHP.Name));
2642 0 : ShowContinueError(state, format("User-Specified Rated Heating Capacity of {:.2R} [W]", RatedCapHeatUser));
2643 0 : ShowContinueError(state, format("differs from Design Size Rated Heating Capacity of {:.2R} [W]", RatedCapHeatDes));
2644 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2645 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2646 : }
2647 : }
2648 : } else {
2649 4 : if (simpleWatertoAirHP.RatedCapHeat > 0.0) {
2650 4 : RatedCapHeatUser = simpleWatertoAirHP.RatedCapHeat;
2651 12 : BaseSizer::reportSizerOutput(
2652 : state,
2653 8 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2654 : simpleWatertoAirHP.Name,
2655 : "User-Specified Rated Heating Capacity [W]",
2656 : RatedCapHeatUser);
2657 : }
2658 : }
2659 :
2660 : // user provided inputs are assumed to be at rated conditions
2661 4 : simpleWatertoAirHP.RatedPowerHeat = simpleWatertoAirHP.RatedCapHeat / simpleWatertoAirHP.RatedCOPHeatAtRatedCdts;
2662 4 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts = 0; // not sure why these are set = 0, should be RatedCapHeat?
2663 4 : simpleWatertoAirHP.RatedPowerHeatAtRatedCdts = 0; // should be RatedPowerHeat?
2664 : }
2665 : // Check that heat pump heating capacity is within 20% of cooling capacity. Check only for heating coil and report both.
2666 7 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating && simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
2667 4 : auto &companionCoolingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum));
2668 4 : if (companionCoolingCoil.RatedCapCoolTotal > 0.0) {
2669 :
2670 4 : if (std::abs(companionCoolingCoil.RatedCapCoolTotal - simpleWatertoAirHP.RatedCapHeat) / companionCoolingCoil.RatedCapCoolTotal >
2671 : 0.2) {
2672 :
2673 4 : ShowWarningError(state,
2674 4 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT {}",
2675 2 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2676 2 : simpleWatertoAirHP.Name));
2677 4 : ShowContinueError(state,
2678 4 : format("...used with COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT {}",
2679 2 : companionCoolingCoil.WAHPType,
2680 2 : companionCoolingCoil.Name));
2681 4 : ShowContinueError(state, "...heating capacity is disproportionate (> 20% different) to total cooling capacity");
2682 2 : ShowContinueError(state, format("...heating capacity = {:.3T} W", simpleWatertoAirHP.RatedCapHeat));
2683 2 : ShowContinueError(state, format("...cooling capacity = {:.3T} W", companionCoolingCoil.RatedCapCoolTotal));
2684 : }
2685 : }
2686 : }
2687 :
2688 7 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilHeatingCapacity(
2689 : state,
2690 7 : simpleWatertoAirHP.Name,
2691 14 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2692 : RatedCapHeatDes,
2693 : IsAutoSize,
2694 7 : state.dataSize->CurSysNum,
2695 7 : state.dataSize->CurZoneEqNum,
2696 7 : state.dataSize->CurOASysNum,
2697 : FanCoolLoad,
2698 : 1.0, // RatedHeatCapTempModFac,
2699 : -999.0,
2700 : -999.0);
2701 :
2702 : } // Heating
2703 :
2704 : // size/report rated efficiency and power
2705 16 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
2706 9 : if (simpleWatertoAirHP.RatedPowerCool > 0) {
2707 18 : OutputReportPredefined::PreDefTableEntry(state,
2708 9 : state.dataOutRptPredefined->pdchCoolCoilNomEff,
2709 : simpleWatertoAirHP.Name,
2710 9 : simpleWatertoAirHP.RatedCapCoolTotal / simpleWatertoAirHP.RatedPowerCool);
2711 : }
2712 9 : if (IsAutoSize) {
2713 8 : OutputReportPredefined::PreDefTableEntry(state,
2714 4 : state.dataOutRptPredefined->pdchWAHPRatedPowerAtRatedCdts,
2715 : simpleWatertoAirHP.Name,
2716 : simpleWatertoAirHP.RatedPowerCoolAtRatedCdts);
2717 4 : if (simpleWatertoAirHP.RatedPowerCoolAtRatedCdts > 0) {
2718 8 : OutputReportPredefined::PreDefTableEntry(state,
2719 4 : state.dataOutRptPredefined->pdchWAHPRatedCOPAtRatedCdts,
2720 : simpleWatertoAirHP.Name,
2721 4 : simpleWatertoAirHP.RatedCapCoolAtRatedCdts /
2722 4 : simpleWatertoAirHP.RatedPowerCoolAtRatedCdts);
2723 : }
2724 : }
2725 7 : } else if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating) {
2726 : // heating coil power
2727 7 : simpleWatertoAirHP.RatedPowerHeatAtRatedCdts = simpleWatertoAirHP.RatedCapHeatAtRatedCdts / simpleWatertoAirHP.RatedCOPHeatAtRatedCdts;
2728 7 : if (simpleWatertoAirHP.RatedPowerHeat > 0) {
2729 12 : OutputReportPredefined::PreDefTableEntry(state,
2730 6 : state.dataOutRptPredefined->pdchHeatCoilNomEff,
2731 : simpleWatertoAirHP.Name,
2732 6 : simpleWatertoAirHP.RatedCapHeat / simpleWatertoAirHP.RatedPowerHeat);
2733 : }
2734 7 : if (IsAutoSize) {
2735 6 : OutputReportPredefined::PreDefTableEntry(state,
2736 3 : state.dataOutRptPredefined->pdchWAHPRatedPowerAtRatedCdts,
2737 : simpleWatertoAirHP.Name,
2738 : simpleWatertoAirHP.RatedPowerHeatAtRatedCdts);
2739 3 : if (simpleWatertoAirHP.RatedPowerHeatAtRatedCdts > 0) {
2740 6 : OutputReportPredefined::PreDefTableEntry(state,
2741 3 : state.dataOutRptPredefined->pdchWAHPRatedCOPAtRatedCdts,
2742 : simpleWatertoAirHP.Name,
2743 3 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts /
2744 3 : simpleWatertoAirHP.RatedPowerHeatAtRatedCdts);
2745 : }
2746 : }
2747 : // re-calculate companion coil power
2748 7 : if (simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
2749 4 : auto &companionCoolingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum));
2750 4 : companionCoolingCoil.RatedPowerCoolAtRatedCdts =
2751 4 : companionCoolingCoil.RatedCapCoolAtRatedCdts / companionCoolingCoil.RatedCOPCoolAtRatedCdts;
2752 4 : if (companionCoolingCoil.RatedCapCoolTotal > 0) {
2753 8 : OutputReportPredefined::PreDefTableEntry(state,
2754 4 : state.dataOutRptPredefined->pdchCoolCoilNomEff,
2755 : companionCoolingCoil.Name,
2756 4 : companionCoolingCoil.RatedCapCoolTotal / companionCoolingCoil.RatedPowerCool);
2757 4 : if (IsAutoSize) {
2758 6 : OutputReportPredefined::PreDefTableEntry(state,
2759 3 : state.dataOutRptPredefined->pdchWAHPRatedPowerAtRatedCdts,
2760 : companionCoolingCoil.Name,
2761 : companionCoolingCoil.RatedPowerCoolAtRatedCdts);
2762 3 : if (companionCoolingCoil.RatedPowerCoolAtRatedCdts > 0) {
2763 6 : OutputReportPredefined::PreDefTableEntry(state,
2764 3 : state.dataOutRptPredefined->pdchWAHPRatedCOPAtRatedCdts,
2765 : companionCoolingCoil.Name,
2766 3 : companionCoolingCoil.RatedCapCoolAtRatedCdts /
2767 3 : companionCoolingCoil.RatedPowerCoolAtRatedCdts);
2768 : }
2769 : }
2770 : }
2771 : }
2772 : }
2773 :
2774 : // Size water volumetric flow rate
2775 16 : IsAutoSize = false;
2776 16 : if (simpleWatertoAirHP.RatedWaterVolFlowRate == DataSizing::AutoSize) {
2777 2 : IsAutoSize = true;
2778 : }
2779 :
2780 : // WSHP condenser can be on either a plant loop or condenser loop. Test each to find plant sizing number.
2781 : // first check to see if coil is connected to a plant loop, no warning on this CALL
2782 16 : if (IsAutoSize) {
2783 4 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
2784 : state,
2785 4 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2786 : simpleWatertoAirHP.Name,
2787 : simpleWatertoAirHP.WaterInletNodeNum,
2788 : simpleWatertoAirHP.WaterOutletNodeNum,
2789 : ErrorsFound,
2790 : false);
2791 :
2792 2 : if (PltSizNum > 0) {
2793 2 : rho = state.dataPlnt->PlantLoop(simpleWatertoAirHP.plantLoc.loopNum)
2794 2 : .glycol->getDensity(state, state.dataSize->PlantSizData(PltSizNum).ExitTemp, RoutineNameAlt);
2795 2 : Cp = state.dataPlnt->PlantLoop(simpleWatertoAirHP.plantLoc.loopNum)
2796 2 : .glycol->getSpecificHeat(state, state.dataSize->PlantSizData(PltSizNum).ExitTemp, RoutineNameAlt);
2797 :
2798 2 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating) {
2799 1 : RatedWaterVolFlowRateDes = simpleWatertoAirHP.RatedCapHeat / (state.dataSize->PlantSizData(PltSizNum).DeltaT * Cp * rho);
2800 1 : } else if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
2801 : // use companion heating coil capacity to calculate volumetric flow rate
2802 1 : if (simpleWatertoAirHP.CompanionHeatingCoilNum > 0) {
2803 : auto const &companionHeatingCoil =
2804 1 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum);
2805 1 : if (companionHeatingCoil.RatedCapHeat == DataSizing::AutoSize) {
2806 1 : SystemCapacity = simpleWatertoAirHP.RatedCapCoolTotal; // but you should use condenser capacity?
2807 : } else {
2808 0 : SystemCapacity = companionHeatingCoil.RatedCapHeat;
2809 : }
2810 : } else {
2811 0 : SystemCapacity = simpleWatertoAirHP.RatedCapCoolAtRatedCdts; // RatedCapCoolTotal ? * (1 + 1/COP) ?
2812 : }
2813 :
2814 1 : RatedWaterVolFlowRateDes = SystemCapacity / (state.dataSize->PlantSizData(PltSizNum).DeltaT * Cp * rho);
2815 : }
2816 : } else {
2817 0 : ShowSevereError(state, "Autosizing of water flow requires a loop Sizing:Plant object");
2818 0 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
2819 0 : ShowContinueError(state,
2820 0 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
2821 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2822 0 : simpleWatertoAirHP.Name));
2823 : }
2824 :
2825 2 : if (SystemCapacity != DataSizing::AutoSize) {
2826 1 : simpleWatertoAirHP.RatedWaterVolFlowRate = RatedWaterVolFlowRateDes;
2827 3 : BaseSizer::reportSizerOutput(
2828 : state,
2829 2 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2830 : simpleWatertoAirHP.Name,
2831 : "Design Size Rated Water Flow Rate [m3/s]",
2832 : RatedWaterVolFlowRateDes);
2833 1 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating && simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
2834 1 : auto &companionCoolingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum));
2835 1 : companionCoolingCoil.RatedWaterVolFlowRate = RatedWaterVolFlowRateDes;
2836 3 : BaseSizer::reportSizerOutput(
2837 : state,
2838 2 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(companionCoolingCoil.WAHPType)]),
2839 : companionCoolingCoil.Name,
2840 : "Design Size Rated Water Flow Rate [m3/s]",
2841 : RatedWaterVolFlowRateDes);
2842 1 : } else if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling && simpleWatertoAirHP.CompanionHeatingCoilNum > 0) {
2843 0 : auto &companionHeatingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum));
2844 0 : companionHeatingCoil.RatedWaterVolFlowRate = RatedWaterVolFlowRateDes;
2845 0 : BaseSizer::reportSizerOutput(
2846 : state,
2847 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(companionHeatingCoil.WAHPType)]),
2848 : companionHeatingCoil.Name,
2849 : "Design Size Rated Water Flow Rate [m3/s]",
2850 : RatedWaterVolFlowRateDes);
2851 : }
2852 : }
2853 : } else {
2854 14 : if (simpleWatertoAirHP.RatedWaterVolFlowRate > 0.0 && RatedWaterVolFlowRateDes > 0.0) {
2855 0 : RatedWaterVolFlowRateUser = simpleWatertoAirHP.RatedWaterVolFlowRate;
2856 0 : BaseSizer::reportSizerOutput(
2857 : state,
2858 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2859 : simpleWatertoAirHP.Name,
2860 : "Design Size Rated Water Flow Rate [m3/s]",
2861 : RatedWaterVolFlowRateDes,
2862 : "User-Specified Rated Water Flow Rate [m3/s]",
2863 : RatedWaterVolFlowRateUser);
2864 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2865 0 : if ((std::abs(RatedWaterVolFlowRateDes - RatedWaterVolFlowRateUser) / RatedWaterVolFlowRateUser) >
2866 0 : state.dataSize->AutoVsHardSizingThreshold) {
2867 0 : ShowMessage(state,
2868 0 : format("SizeHVACWaterToAir: Potential issue with equipment sizing for coil {}:WATERTOAIRHEATPUMP:EQUATIONFIT {}",
2869 0 : simpleWatertoAirHP.WAHPType,
2870 0 : simpleWatertoAirHP.Name));
2871 0 : ShowContinueError(state, format("User-Specified Rated Water Flow Rate of {:.5R} [m3/s]", RatedWaterVolFlowRateUser));
2872 0 : ShowContinueError(state, format("differs from Design Size Rated Water Flow Rate of {:.5R} [m3/s]", RatedWaterVolFlowRateDes));
2873 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2874 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2875 : }
2876 : }
2877 : }
2878 : }
2879 :
2880 : // Save component design water volumetric flow rate.
2881 : // Use 1/2 flow since both cooling and heating coil will save flow yet only 1 will operate at a time
2882 16 : if (simpleWatertoAirHP.RatedWaterVolFlowRate > 0.0) {
2883 8 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating) {
2884 4 : PlantUtilities::RegisterPlantCompDesignFlow(
2885 4 : state, simpleWatertoAirHP.WaterInletNodeNum, 0.5 * simpleWatertoAirHP.RatedWaterVolFlowRate);
2886 4 : if (simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
2887 2 : auto &companionCoolingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum));
2888 2 : PlantUtilities::RegisterPlantCompDesignFlow(
2889 2 : state, companionCoolingCoil.WaterInletNodeNum, 0.5 * simpleWatertoAirHP.RatedWaterVolFlowRate);
2890 : }
2891 4 : } else if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
2892 4 : PlantUtilities::RegisterPlantCompDesignFlow(
2893 4 : state, simpleWatertoAirHP.WaterInletNodeNum, 0.5 * simpleWatertoAirHP.RatedWaterVolFlowRate);
2894 : }
2895 : }
2896 16 : }
2897 :
2898 49906 : void CalcHPCoolingSimple(EnergyPlusData &state,
2899 : int const HPNum, // Heat Pump Number
2900 : HVAC::FanOp const fanOp, // Fan/Compressor cycling scheme indicator
2901 : [[maybe_unused]] Real64 const SensDemand, // Cooling Sensible Demand [W] !unused1208
2902 : [[maybe_unused]] Real64 const LatentDemand, // Cooling Latent Demand [W]
2903 : HVAC::CompressorOp const compressorOp, // compressor operation flag
2904 : Real64 const PartLoadRatio, // compressor part load ratio
2905 : [[maybe_unused]] Real64 const OnOffAirFlowRatio // ratio of compressor on flow to average flow over time step
2906 : )
2907 : {
2908 :
2909 : // AUTHOR Arun Shenoy
2910 : // DATE WRITTEN Jan 2004
2911 : // RE-ENGINEERED Kenneth Tang (Jan 2005)
2912 :
2913 : // PURPOSE OF THIS SUBROUTINE:
2914 : // This subroutine is for simulating the cooling mode of the Water to Air HP Simple
2915 :
2916 : // METHODOLOGY EMPLOYED:
2917 : // Simulate the heat pump performance using the coefficients in quadlinear and quintlinear curves and rated conditions
2918 : // If the LatDegradModelSimFlag is enabled, the coil will be simulated twice:
2919 : // (1)first simulation at the rated conditions (2) second simulation at the
2920 : // actual operating conditions. Then call CalcEffectiveSHR and the effective SHR
2921 : // is adjusted.
2922 : // If the LatDegradModelSimFlag is disabled, the cooling coil is only simulated
2923 : // once at the actual operating conditions.
2924 : // Finally, adjust the heat pump outlet conditions based on the PartLoadRatio
2925 : // and RuntimeFrac.
2926 :
2927 : // REFERENCES:
2928 : // (1) Lash.T.A.,1992.Simulation and Analysis of a Water Loop Heat Pump System.
2929 : // M.S. Thesis, University of Illinois at Urbana Champaign.
2930 : // (2) Shenoy, Arun. 2004. Simulation, Modeling and Analysis of Water to Air Heat Pump.
2931 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
2932 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
2933 : // (3) Tang,C.C.. 2005. Modeling Packaged Heat Pumps in a Quasi-Steady
2934 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
2935 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
2936 : // (4) Henderson, H.I., K. Rengarajan.1996. A Model to Predict the Latent
2937 : // Capacity of Air Conditioners and Heat Pumps at Part-Load Conditions
2938 : // with Constant Fan Operation ASHRAE Transactions 102 (1), pp. 266-274.
2939 :
2940 49906 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
2941 :
2942 : // SUBROUTINE PARAMETER DEFINITIONS:
2943 49906 : constexpr Real64 Tref(283.15); // Reference Temperature for performance curves,10C [K]
2944 : static constexpr std::string_view RoutineName("CalcHPCoolingSimple");
2945 : static constexpr std::string_view RoutineNameSourceSideInletTemp("CalcHPCoolingSimple:SourceSideInletTemp");
2946 :
2947 : Real64 TotalCapRated; // Rated Total Cooling Capacity [W]
2948 : Real64 SensCapRated; // Rated Sensible Cooling Capacity [W]
2949 : Real64 CoolPowerRated; // Rated Cooling Power Input[W]
2950 : Real64 AirVolFlowRateRated; // Rated Air Volumetric Flow Rate [m3/s]
2951 : Real64 WaterVolFlowRateRated; // Rated Water Volumetric Flow Rate [m3/s]
2952 : Real64 Twet_Rated; // Twet at rated conditions (coil air flow rate and air temperatures), sec
2953 : Real64 Gamma_Rated; // Gamma at rated conditions (coil air flow rate and air temperatures)
2954 : Real64 SHRss; // Sensible heat ratio at steady state
2955 : Real64 SHReff; // Effective sensible heat ratio at part-load condition
2956 : Real64 ratioTDB; // Ratio of the inlet air dry bulb temperature to the rated conditions
2957 : Real64 ratioTWB; // Ratio of the inlet air wet bulb temperature to the rated conditions
2958 : Real64 ratioTS; // Ratio of the source side(water) inlet temperature to the rated conditions
2959 : Real64 ratioVL; // Ratio of the air flow rate to the rated conditions
2960 : Real64 ratioVS; // Ratio of the water flow rate to the rated conditions
2961 : Real64 CpWater; // Specific heat of water [J/kg_C]
2962 : Real64 CpAir; // Specific heat of air [J/kg_C]
2963 : Real64 LoadSideFullMassFlowRate; // Load Side Full Load Mass Flow Rate [kg/s]
2964 : Real64 LoadSideFullOutletEnthalpy; // Load Side Full Load Outlet Air Enthalpy [J/kg]
2965 :
2966 : bool LatDegradModelSimFlag; // Latent degradation model simulation flag
2967 : int NumIteration; // Iteration Counter
2968 : Real64 LoadSideInletDBTemp_Unit; // calc conditions for unit
2969 : Real64 LoadSideInletWBTemp_Unit; // calc conditions for unit
2970 : Real64 LoadSideInletHumRat_Unit; // calc conditions for unit
2971 : Real64 LoadSideInletEnth_Unit; // calc conditions for unit
2972 : Real64 CpAir_Unit; // calc conditions for unit
2973 :
2974 49906 : if (state.dataWaterToAirHeatPumpSimple->firstTime) {
2975 : // Set indoor air conditions to the rated condition
2976 6 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp_Init = 26.7;
2977 6 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat_Init = 0.0111;
2978 6 : state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth_Init = Psychrometrics::PsyHFnTdbW(
2979 6 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp_Init, state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat_Init);
2980 6 : state.dataWaterToAirHeatPumpSimple->CpAir_Init =
2981 6 : Psychrometrics::PsyCpAirFnW(state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat_Init);
2982 6 : state.dataWaterToAirHeatPumpSimple->firstTime = false;
2983 : }
2984 99812 : state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp_Init =
2985 49906 : Psychrometrics::PsyTwbFnTdbWPb(state,
2986 49906 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp_Init,
2987 49906 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat_Init,
2988 49906 : state.dataEnvrn->OutBaroPress,
2989 : RoutineName);
2990 :
2991 : // LOAD LOCAL VARIABLES FROM DATA STRUCTURE (for code readability)
2992 :
2993 49906 : auto &simpleWatertoAirHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
2994 :
2995 49906 : TotalCapRated = simpleWatertoAirHP.RatedCapCoolTotal;
2996 49906 : SensCapRated = simpleWatertoAirHP.RatedCapCoolSens;
2997 49906 : CoolPowerRated = simpleWatertoAirHP.RatedPowerCool;
2998 49906 : AirVolFlowRateRated = simpleWatertoAirHP.RatedAirVolFlowRate;
2999 49906 : WaterVolFlowRateRated = simpleWatertoAirHP.RatedWaterVolFlowRate;
3000 :
3001 49906 : Twet_Rated = simpleWatertoAirHP.Twet_Rated;
3002 49906 : Gamma_Rated = simpleWatertoAirHP.Gamma_Rated;
3003 :
3004 49906 : if (fanOp == HVAC::FanOp::Continuous) {
3005 6 : LoadSideFullMassFlowRate = simpleWatertoAirHP.AirMassFlowRate;
3006 : } else {
3007 : // default to cycling fan, cycling compressor, full load air flow
3008 49900 : if (PartLoadRatio > 0.0) {
3009 10169 : LoadSideFullMassFlowRate = simpleWatertoAirHP.AirMassFlowRate / PartLoadRatio;
3010 : } else {
3011 39731 : LoadSideFullMassFlowRate = 0.0;
3012 : }
3013 : }
3014 49906 : state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate = simpleWatertoAirHP.WaterMassFlowRate;
3015 49906 : state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp = simpleWatertoAirHP.InletWaterTemp;
3016 49906 : state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth = simpleWatertoAirHP.InletWaterEnthalpy;
3017 49906 : CpWater = state.dataPlnt->PlantLoop(simpleWatertoAirHP.plantLoc.loopNum)
3018 49906 : .glycol->getSpecificHeat(state, state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp, RoutineNameSourceSideInletTemp);
3019 :
3020 : // Check for flows, do not perform simulation if no flow in load side or source side.
3021 49906 : if (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate <= 0.0 || LoadSideFullMassFlowRate <= 0.0) {
3022 39735 : simpleWatertoAirHP.SimFlag = false;
3023 39735 : return;
3024 : } else {
3025 10171 : simpleWatertoAirHP.SimFlag = true;
3026 : }
3027 :
3028 10171 : if (compressorOp == HVAC::CompressorOp::Off) {
3029 0 : simpleWatertoAirHP.SimFlag = false;
3030 0 : return;
3031 : }
3032 :
3033 : // Calculate Part Load Factor and Runtime Fraction
3034 10171 : Real64 PLF = 1.0; // part load factor as a function of PLR, RTF = PLR / PLF
3035 10171 : if (simpleWatertoAirHP.PLFCurve != nullptr) {
3036 10171 : PLF = simpleWatertoAirHP.PLFCurve->value(state, PartLoadRatio); // Calculate part-load factor
3037 : }
3038 10171 : if (fanOp == HVAC::FanOp::Cycling) {
3039 10169 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
3040 : }
3041 10171 : simpleWatertoAirHP.RunFrac = PartLoadRatio / PLF;
3042 :
3043 : // Loop the calculation at least once depending whether the latent degradation model
3044 : // is enabled. 1st iteration to calculate the QLatent(rated) at (TDB,TWB)indoorair=(26.7C,19.4C)
3045 : // and 2nd iteration to calculate the QLatent(actual)
3046 10171 : if ((simpleWatertoAirHP.RunFrac >= 1.0) || (Twet_Rated <= 0.0) || (Gamma_Rated <= 0.0)) {
3047 10169 : LatDegradModelSimFlag = false;
3048 : // Set NumIteration=1 so that latent model would quit after 1 simulation with the actual condition
3049 10169 : NumIteration = 1;
3050 : } else {
3051 2 : LatDegradModelSimFlag = true;
3052 : // Set NumIteration=0 so that latent model would simulate twice with rated and actual condition
3053 2 : NumIteration = 0;
3054 : }
3055 :
3056 : // Set indoor air conditions to the actual condition
3057 10171 : LoadSideInletDBTemp_Unit = simpleWatertoAirHP.InletAirDBTemp;
3058 10171 : LoadSideInletHumRat_Unit = simpleWatertoAirHP.InletAirHumRat;
3059 : LoadSideInletWBTemp_Unit =
3060 10171 : Psychrometrics::PsyTwbFnTdbWPb(state, LoadSideInletDBTemp_Unit, LoadSideInletHumRat_Unit, state.dataEnvrn->OutBaroPress, RoutineName);
3061 10171 : LoadSideInletEnth_Unit = simpleWatertoAirHP.InletAirEnthalpy;
3062 10171 : CpAir_Unit = Psychrometrics::PsyCpAirFnW(LoadSideInletHumRat_Unit);
3063 :
3064 : while (true) {
3065 10173 : ++NumIteration;
3066 10173 : if (NumIteration == 1) {
3067 : // Set indoor air conditions to the rated conditions
3068 2 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp = state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp_Init;
3069 2 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat = state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat_Init;
3070 2 : state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp = state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp_Init;
3071 2 : state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth = state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth_Init;
3072 2 : CpAir = state.dataWaterToAirHeatPumpSimple->CpAir_Init;
3073 : } else {
3074 : // Set indoor air conditions to the actual condition
3075 10171 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp = LoadSideInletDBTemp_Unit;
3076 10171 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat = LoadSideInletHumRat_Unit;
3077 10171 : state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp = LoadSideInletWBTemp_Unit;
3078 10171 : state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth = LoadSideInletEnth_Unit;
3079 10171 : CpAir = CpAir_Unit;
3080 : }
3081 :
3082 10173 : ratioTDB = ((state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref);
3083 10173 : ratioTWB = ((state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref);
3084 10173 : ratioTS = ((state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref);
3085 10173 : ratioVL = (LoadSideFullMassFlowRate /
3086 10173 : (AirVolFlowRateRated * Psychrometrics::PsyRhoAirFnPbTdbW(state,
3087 10173 : state.dataEnvrn->StdBaroPress,
3088 10173 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp,
3089 10173 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat,
3090 : RoutineName)));
3091 :
3092 10173 : if (simpleWatertoAirHP.DesignWaterMassFlowRate > 0.0) {
3093 10173 : ratioVS = (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate) / (simpleWatertoAirHP.DesignWaterMassFlowRate);
3094 : } else {
3095 0 : ratioVS = 0.0;
3096 : }
3097 :
3098 10173 : simpleWatertoAirHP.QLoadTotal = TotalCapRated * simpleWatertoAirHP.TotalCoolCapCurve->value(state, ratioTWB, ratioTS, ratioVL, ratioVS);
3099 10173 : simpleWatertoAirHP.QSensible =
3100 10173 : SensCapRated * simpleWatertoAirHP.SensCoolCapCurve->value(state, ratioTDB, ratioTWB, ratioTS, ratioVL, ratioVS);
3101 20346 : state.dataWaterToAirHeatPumpSimple->Winput =
3102 10173 : CoolPowerRated * simpleWatertoAirHP.CoolPowCurve->value(state, ratioTWB, ratioTS, ratioVL, ratioVS);
3103 :
3104 : // Check if the Sensible Load is greater than the Total Cooling Load
3105 10173 : if (simpleWatertoAirHP.QSensible > simpleWatertoAirHP.QLoadTotal) {
3106 5 : simpleWatertoAirHP.QSensible = simpleWatertoAirHP.QLoadTotal;
3107 : }
3108 :
3109 10173 : if (LatDegradModelSimFlag) {
3110 : // Calculate for SHReff using the Latent Degradation Model
3111 4 : if (NumIteration == 1) {
3112 2 : state.dataWaterToAirHeatPumpSimple->QLatRated = simpleWatertoAirHP.QLoadTotal - simpleWatertoAirHP.QSensible;
3113 2 : } else if (NumIteration == 2) {
3114 2 : state.dataWaterToAirHeatPumpSimple->QLatActual = simpleWatertoAirHP.QLoadTotal - simpleWatertoAirHP.QSensible;
3115 2 : SHRss = simpleWatertoAirHP.QSensible / simpleWatertoAirHP.QLoadTotal;
3116 2 : SHReff = CalcEffectiveSHR(state,
3117 : HPNum,
3118 : SHRss,
3119 : fanOp,
3120 : simpleWatertoAirHP.RunFrac,
3121 2 : state.dataWaterToAirHeatPumpSimple->QLatRated,
3122 2 : state.dataWaterToAirHeatPumpSimple->QLatActual,
3123 2 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp,
3124 2 : state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp);
3125 : // Update sensible capacity based on effective SHR
3126 2 : simpleWatertoAirHP.QSensible = simpleWatertoAirHP.QLoadTotal * SHReff;
3127 2 : break;
3128 : }
3129 : } else {
3130 : // Assume SHReff=SHRss
3131 10169 : SHReff = simpleWatertoAirHP.QSensible / simpleWatertoAirHP.QLoadTotal;
3132 10169 : break;
3133 : }
3134 : }
3135 :
3136 : // calculate coil outlet state variables
3137 10171 : LoadSideFullOutletEnthalpy = state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth - simpleWatertoAirHP.QLoadTotal / LoadSideFullMassFlowRate;
3138 20342 : state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp =
3139 10171 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp - simpleWatertoAirHP.QSensible / (LoadSideFullMassFlowRate * CpAir);
3140 20342 : state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat =
3141 10171 : Psychrometrics::PsyWFnTdbH(state, state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp, LoadSideFullOutletEnthalpy, RoutineName);
3142 : // Actual outlet conditions are "average" for time step
3143 10171 : if (fanOp == HVAC::FanOp::Continuous) {
3144 : // continuous fan, cycling compressor
3145 2 : simpleWatertoAirHP.OutletAirEnthalpy =
3146 2 : PartLoadRatio * LoadSideFullOutletEnthalpy + (1.0 - PartLoadRatio) * state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth;
3147 2 : simpleWatertoAirHP.OutletAirHumRat = PartLoadRatio * state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat +
3148 2 : (1.0 - PartLoadRatio) * state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat;
3149 2 : simpleWatertoAirHP.OutletAirDBTemp = Psychrometrics::PsyTdbFnHW(simpleWatertoAirHP.OutletAirEnthalpy, simpleWatertoAirHP.OutletAirHumRat);
3150 : } else {
3151 : // default to cycling fan, cycling compressor
3152 10169 : simpleWatertoAirHP.OutletAirEnthalpy = LoadSideFullOutletEnthalpy;
3153 10169 : simpleWatertoAirHP.OutletAirHumRat = state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat;
3154 10169 : simpleWatertoAirHP.OutletAirDBTemp = state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp;
3155 : }
3156 :
3157 : // scale heat transfer rates to PLR and power to RTF
3158 10171 : simpleWatertoAirHP.QLoadTotal *= PartLoadRatio;
3159 20342 : simpleWatertoAirHP.QLoadTotalReport = simpleWatertoAirHP.AirMassFlowRate *
3160 10171 : (state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth -
3161 10171 : Psychrometrics::PsyHFnTdbW(simpleWatertoAirHP.OutletAirDBTemp,
3162 : simpleWatertoAirHP.OutletAirHumRat)); // Why doesn't this match QLoadTotal?
3163 10171 : simpleWatertoAirHP.QSensible *= PartLoadRatio;
3164 10171 : state.dataWaterToAirHeatPumpSimple->Winput *= simpleWatertoAirHP.RunFrac;
3165 10171 : simpleWatertoAirHP.QSource = simpleWatertoAirHP.QLoadTotalReport + state.dataWaterToAirHeatPumpSimple->Winput;
3166 10171 : state.dataHeatBal->HeatReclaimSimple_WAHPCoil(HPNum).AvailCapacity = simpleWatertoAirHP.QSource;
3167 :
3168 : // Add power to global variable so power can be summed by parent object
3169 10171 : state.dataHVACGlobal->DXElecCoolingPower = state.dataWaterToAirHeatPumpSimple->Winput;
3170 :
3171 10171 : DataHeatBalance::HeatReclaimDataBase &HeatReclaim = state.dataHeatBal->HeatReclaimSimple_WAHPCoil(HPNum);
3172 10171 : HeatReclaim.WaterHeatingDesuperheaterReclaimedHeatTotal = 0.0;
3173 10171 : if (allocated(HeatReclaim.WaterHeatingDesuperheaterReclaimedHeat)) {
3174 4 : for (auto const &num : HeatReclaim.WaterHeatingDesuperheaterReclaimedHeat)
3175 2 : HeatReclaim.WaterHeatingDesuperheaterReclaimedHeatTotal += num;
3176 : }
3177 10171 : simpleWatertoAirHP.QSource -= HeatReclaim.WaterHeatingDesuperheaterReclaimedHeatTotal;
3178 :
3179 : // Update heat pump data structure
3180 10171 : simpleWatertoAirHP.Power = state.dataWaterToAirHeatPumpSimple->Winput;
3181 10171 : simpleWatertoAirHP.QLoadTotal = simpleWatertoAirHP.QLoadTotalReport;
3182 10171 : simpleWatertoAirHP.QLatent = simpleWatertoAirHP.QLoadTotalReport - simpleWatertoAirHP.QSensible;
3183 10171 : simpleWatertoAirHP.Energy = state.dataWaterToAirHeatPumpSimple->Winput * TimeStepSysSec;
3184 10171 : simpleWatertoAirHP.EnergyLoadTotal = simpleWatertoAirHP.QLoadTotalReport * TimeStepSysSec;
3185 10171 : simpleWatertoAirHP.EnergySensible = simpleWatertoAirHP.QSensible * TimeStepSysSec;
3186 10171 : simpleWatertoAirHP.EnergyLatent = (simpleWatertoAirHP.QLoadTotalReport - simpleWatertoAirHP.QSensible) * TimeStepSysSec;
3187 10171 : simpleWatertoAirHP.EnergySource = simpleWatertoAirHP.QSource * TimeStepSysSec;
3188 10171 : if (simpleWatertoAirHP.RunFrac == 0.0) {
3189 0 : simpleWatertoAirHP.COP = 0.0;
3190 : } else {
3191 10171 : simpleWatertoAirHP.COP = simpleWatertoAirHP.QLoadTotalReport / state.dataWaterToAirHeatPumpSimple->Winput;
3192 : }
3193 10171 : simpleWatertoAirHP.PartLoadRatio = PartLoadRatio;
3194 :
3195 10171 : if ((simpleWatertoAirHP.WaterCyclingMode) == HVAC::WaterFlow::Cycling) {
3196 : // plant can lock flow at coil water inlet node, use design flow multiplied by PLR to calculate water mass flow rate
3197 10163 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate * PartLoadRatio;
3198 10163 : PlantUtilities::SetComponentFlowRate(state,
3199 10163 : simpleWatertoAirHP.WaterMassFlowRate,
3200 : simpleWatertoAirHP.WaterInletNodeNum,
3201 : simpleWatertoAirHP.WaterOutletNodeNum,
3202 10163 : simpleWatertoAirHP.plantLoc);
3203 10163 : if (simpleWatertoAirHP.WaterMassFlowRate > 0.0) {
3204 10163 : simpleWatertoAirHP.OutletWaterTemp = state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp +
3205 10163 : simpleWatertoAirHP.QSource / (simpleWatertoAirHP.WaterMassFlowRate * CpWater);
3206 10163 : simpleWatertoAirHP.OutletWaterEnthalpy =
3207 10163 : state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth + simpleWatertoAirHP.QSource / simpleWatertoAirHP.WaterMassFlowRate;
3208 : }
3209 : } else {
3210 8 : if ((simpleWatertoAirHP.WaterCyclingMode) == HVAC::WaterFlow::Constant) {
3211 0 : if (simpleWatertoAirHP.WaterFlowMode) {
3212 0 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate;
3213 0 : PlantUtilities::SetComponentFlowRate(state,
3214 0 : simpleWatertoAirHP.WaterMassFlowRate,
3215 : simpleWatertoAirHP.WaterInletNodeNum,
3216 : simpleWatertoAirHP.WaterOutletNodeNum,
3217 0 : simpleWatertoAirHP.plantLoc);
3218 : } else {
3219 0 : simpleWatertoAirHP.WaterMassFlowRate = state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3220 : }
3221 : } else {
3222 8 : simpleWatertoAirHP.WaterMassFlowRate = state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3223 : }
3224 8 : simpleWatertoAirHP.OutletWaterTemp = state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp +
3225 8 : simpleWatertoAirHP.QSource / (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate * CpWater);
3226 8 : simpleWatertoAirHP.OutletWaterEnthalpy = state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth +
3227 8 : simpleWatertoAirHP.QSource / state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3228 : }
3229 : }
3230 :
3231 49902 : void CalcHPHeatingSimple(EnergyPlusData &state,
3232 : int const HPNum, // Heat Pump Number
3233 : HVAC::FanOp const fanOp, // Fan/Compressor cycling scheme indicator
3234 : [[maybe_unused]] Real64 const SensDemand, // Sensible Demand [W] !unused1208
3235 : HVAC::CompressorOp const compressorOp, // compressor operation flag
3236 : Real64 const PartLoadRatio, // compressor part load ratio
3237 : [[maybe_unused]] Real64 const OnOffAirFlowRatio // ratio of compressor on flow to average flow over time step
3238 : )
3239 : {
3240 :
3241 : // AUTHOR Arun Shenoy
3242 : // DATE WRITTEN Jan 2004
3243 : // RE-ENGINEERED Kenneth Tang (Jan 2005)
3244 :
3245 : // PURPOSE OF THIS SUBROUTINE:
3246 : // This subroutine is for simulating the heating mode of the Water to Air HP Simple
3247 :
3248 : // METHODOLOGY EMPLOYED:
3249 : // Simulate the heat pump performance using the coefficients in quadlinear and quintlinear curves and rated conditions
3250 : // Finally, adjust the heat pump outlet conditions based on the PartLoadRatio
3251 : // and RuntimeFrac.
3252 :
3253 : // REFERENCES:
3254 : // (1) Lash.T.A.,1992.Simulation and Analysis of a Water Loop Heat Pump System.
3255 : // M.S. Thesis, University of Illinois at Urbana Champaign.
3256 : // (2) Shenoy, Arun. 2004. Simulation, Modeling and Analysis of Water to Air Heat Pump.
3257 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
3258 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
3259 : // (3) Tang,C.C.. 2005. Modeling Packaged Heat Pumps in a Quasi-Steady
3260 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
3261 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
3262 :
3263 49902 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
3264 :
3265 : // SUBROUTINE PARAMETER DEFINITIONS:
3266 49902 : Real64 constexpr Tref(283.15); // Reference Temperature for performance curves,10C [K]
3267 : static constexpr std::string_view RoutineName("CalcHPHeatingSimple");
3268 : static constexpr std::string_view RoutineNameSourceSideInletTemp("CalcHPHeatingSimple:SourceSideInletTemp");
3269 :
3270 : Real64 HeatCapRated; // Rated Heating Capacity [W]
3271 : Real64 HeatPowerRated; // Rated Heating Power Input[W]
3272 : Real64 AirVolFlowRateRated; // Rated Air Volumetric Flow Rate [m3/s]
3273 : Real64 WaterVolFlowRateRated; // Rated Water Volumetric Flow Rate [m3/s]
3274 : Real64 ratioTDB; // Ratio of the inlet air dry bulb temperature to the rated conditions
3275 : Real64 ratioTS; // Ratio of the source side (water) inlet temperature to the rated conditions
3276 : Real64 ratioVL; // Ratio of the load side flow rate to the rated conditions
3277 : Real64 ratioVS; // Ratio of the source side flow rate to the rated conditions
3278 : Real64 CpWater; // Specific heat of water [J/kg_C]
3279 : Real64 CpAir; // Specific heat of air [J/kg_C]
3280 : Real64 LoadSideFullMassFlowRate; // Load Side Full Load Mass Flow Rate [kg/s]
3281 : Real64 LoadSideFullOutletEnthalpy; // Load Side Full Load Outlet Air Enthalpy [J/kg]
3282 :
3283 : // LOAD LOCAL VARIABLES FROM DATA STRUCTURE (for code readability)
3284 :
3285 49902 : auto &simpleWatertoAirHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
3286 :
3287 49902 : HeatCapRated = simpleWatertoAirHP.RatedCapHeat;
3288 49902 : HeatPowerRated = simpleWatertoAirHP.RatedPowerHeat;
3289 49902 : AirVolFlowRateRated = simpleWatertoAirHP.RatedAirVolFlowRate;
3290 49902 : WaterVolFlowRateRated = simpleWatertoAirHP.RatedWaterVolFlowRate;
3291 49902 : if (fanOp == HVAC::FanOp::Continuous) {
3292 6 : LoadSideFullMassFlowRate = simpleWatertoAirHP.AirMassFlowRate;
3293 : } else {
3294 : // default to cycling fan, cycling compressor, full load air flow
3295 49896 : if (PartLoadRatio > 0.0) {
3296 32275 : LoadSideFullMassFlowRate = simpleWatertoAirHP.AirMassFlowRate / PartLoadRatio;
3297 : } else {
3298 17621 : LoadSideFullMassFlowRate = 0.0;
3299 : }
3300 : }
3301 49902 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp = simpleWatertoAirHP.InletAirDBTemp;
3302 49902 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat = simpleWatertoAirHP.InletAirHumRat;
3303 :
3304 99804 : state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp =
3305 49902 : Psychrometrics::PsyTwbFnTdbWPb(state,
3306 49902 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp,
3307 49902 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat,
3308 49902 : state.dataEnvrn->OutBaroPress,
3309 : RoutineName);
3310 49902 : state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth = simpleWatertoAirHP.InletAirEnthalpy;
3311 49902 : CpAir = Psychrometrics::PsyCpAirFnW(state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat);
3312 49902 : state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate = simpleWatertoAirHP.WaterMassFlowRate;
3313 49902 : state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp = simpleWatertoAirHP.InletWaterTemp;
3314 49902 : state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth = simpleWatertoAirHP.InletWaterEnthalpy;
3315 49902 : CpWater = state.dataPlnt->PlantLoop(simpleWatertoAirHP.plantLoc.loopNum)
3316 49902 : .glycol->getSpecificHeat(state, state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp, RoutineNameSourceSideInletTemp);
3317 :
3318 : // Check for flows, do not perform simulation if no flow in load side or source side.
3319 49902 : if (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate <= 0.0 || LoadSideFullMassFlowRate <= 0.0) {
3320 17643 : simpleWatertoAirHP.SimFlag = false;
3321 17643 : return;
3322 : } else {
3323 32259 : simpleWatertoAirHP.SimFlag = true;
3324 : }
3325 :
3326 32259 : if (compressorOp == HVAC::CompressorOp::Off) {
3327 0 : simpleWatertoAirHP.SimFlag = false;
3328 0 : return;
3329 : }
3330 :
3331 : // Calculate Part Load Factor and Runtime Fraction
3332 32259 : Real64 PLF = 1.0; // part load factor as a function of PLR, RTF = PLR / PLF
3333 32259 : if (simpleWatertoAirHP.PLFCurve != nullptr) {
3334 32259 : PLF = simpleWatertoAirHP.PLFCurve->value(state, PartLoadRatio); // Calculate part-load factor
3335 : }
3336 32259 : if (fanOp == HVAC::FanOp::Cycling) {
3337 32257 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
3338 : }
3339 32259 : simpleWatertoAirHP.RunFrac = PartLoadRatio / PLF;
3340 :
3341 32259 : ratioTDB = ((state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref);
3342 32259 : ratioTS = ((state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref);
3343 32259 : ratioVL = (LoadSideFullMassFlowRate /
3344 32259 : (AirVolFlowRateRated * Psychrometrics::PsyRhoAirFnPbTdbW(state,
3345 32259 : state.dataEnvrn->StdBaroPress,
3346 32259 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp,
3347 32259 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat,
3348 : RoutineName)));
3349 32259 : if (simpleWatertoAirHP.DesignWaterMassFlowRate > 0.0) {
3350 32259 : ratioVS = (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate) / (simpleWatertoAirHP.DesignWaterMassFlowRate);
3351 : } else {
3352 0 : ratioVS = 0.0;
3353 : }
3354 :
3355 32259 : simpleWatertoAirHP.QLoadTotal = HeatCapRated * simpleWatertoAirHP.HeatCapCurve->value(state, ratioTDB, ratioTS, ratioVL, ratioVS);
3356 32259 : simpleWatertoAirHP.QSensible = simpleWatertoAirHP.QLoadTotal;
3357 64518 : state.dataWaterToAirHeatPumpSimple->Winput =
3358 32259 : HeatPowerRated * simpleWatertoAirHP.HeatPowCurve->value(state, ratioTDB, ratioTS, ratioVL, ratioVS);
3359 :
3360 : // calculate coil outlet state variables
3361 32259 : LoadSideFullOutletEnthalpy = state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth + simpleWatertoAirHP.QLoadTotal / LoadSideFullMassFlowRate;
3362 64518 : state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp =
3363 32259 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp + simpleWatertoAirHP.QSensible / (LoadSideFullMassFlowRate * CpAir);
3364 64518 : state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat =
3365 32259 : Psychrometrics::PsyWFnTdbH(state, state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp, LoadSideFullOutletEnthalpy, RoutineName);
3366 :
3367 : // Actual outlet conditions are "average" for time step
3368 32259 : if (fanOp == HVAC::FanOp::Continuous) {
3369 : // continuous fan, cycling compressor
3370 2 : simpleWatertoAirHP.OutletAirEnthalpy =
3371 2 : PartLoadRatio * LoadSideFullOutletEnthalpy + (1.0 - PartLoadRatio) * state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth;
3372 2 : simpleWatertoAirHP.OutletAirHumRat = PartLoadRatio * state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat +
3373 2 : (1.0 - PartLoadRatio) * state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat;
3374 2 : simpleWatertoAirHP.OutletAirDBTemp = Psychrometrics::PsyTdbFnHW(simpleWatertoAirHP.OutletAirEnthalpy, simpleWatertoAirHP.OutletAirHumRat);
3375 : } else {
3376 : // default to cycling fan, cycling compressor
3377 32257 : simpleWatertoAirHP.OutletAirEnthalpy = LoadSideFullOutletEnthalpy;
3378 32257 : simpleWatertoAirHP.OutletAirHumRat = state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat;
3379 32257 : simpleWatertoAirHP.OutletAirDBTemp = state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp;
3380 : }
3381 :
3382 : // scale heat transfer rates to PLR and power to RTF
3383 32259 : simpleWatertoAirHP.QLoadTotal *= PartLoadRatio;
3384 32259 : simpleWatertoAirHP.QLoadTotalReport = simpleWatertoAirHP.QLoadTotal;
3385 32259 : simpleWatertoAirHP.QSensible *= PartLoadRatio;
3386 32259 : state.dataWaterToAirHeatPumpSimple->Winput *= simpleWatertoAirHP.RunFrac;
3387 32259 : simpleWatertoAirHP.QSource = simpleWatertoAirHP.QLoadTotalReport - state.dataWaterToAirHeatPumpSimple->Winput;
3388 :
3389 : // Add power to global variable so power can be summed by parent object
3390 32259 : state.dataHVACGlobal->DXElecHeatingPower = state.dataWaterToAirHeatPumpSimple->Winput;
3391 :
3392 : // Update heat pump data structure
3393 32259 : simpleWatertoAirHP.Power = state.dataWaterToAirHeatPumpSimple->Winput;
3394 32259 : simpleWatertoAirHP.QLoadTotal = simpleWatertoAirHP.QLoadTotalReport;
3395 32259 : simpleWatertoAirHP.QSensible = simpleWatertoAirHP.QSensible;
3396 32259 : simpleWatertoAirHP.Energy = state.dataWaterToAirHeatPumpSimple->Winput * TimeStepSysSec;
3397 32259 : simpleWatertoAirHP.EnergyLoadTotal = simpleWatertoAirHP.QLoadTotalReport * TimeStepSysSec;
3398 32259 : simpleWatertoAirHP.EnergySensible = simpleWatertoAirHP.QSensible * TimeStepSysSec;
3399 32259 : simpleWatertoAirHP.EnergyLatent = 0.0;
3400 32259 : simpleWatertoAirHP.EnergySource = simpleWatertoAirHP.QSource * TimeStepSysSec;
3401 32259 : if (simpleWatertoAirHP.RunFrac == 0.0) {
3402 0 : simpleWatertoAirHP.COP = 0.0;
3403 : } else {
3404 32259 : simpleWatertoAirHP.COP = simpleWatertoAirHP.QLoadTotalReport / state.dataWaterToAirHeatPumpSimple->Winput;
3405 : }
3406 32259 : simpleWatertoAirHP.PartLoadRatio = PartLoadRatio;
3407 :
3408 32259 : if ((simpleWatertoAirHP.WaterCyclingMode) == HVAC::WaterFlow::Cycling) {
3409 : // plant can lock flow at coil water inlet node, use design flow multiplied by PLR to calculate water mass flow rate
3410 32253 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate * PartLoadRatio;
3411 32253 : PlantUtilities::SetComponentFlowRate(state,
3412 32253 : simpleWatertoAirHP.WaterMassFlowRate,
3413 : simpleWatertoAirHP.WaterInletNodeNum,
3414 : simpleWatertoAirHP.WaterOutletNodeNum,
3415 32253 : simpleWatertoAirHP.plantLoc);
3416 32253 : if (simpleWatertoAirHP.WaterMassFlowRate > 0.0) {
3417 32253 : simpleWatertoAirHP.OutletWaterTemp = state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp -
3418 32253 : simpleWatertoAirHP.QSource / (simpleWatertoAirHP.WaterMassFlowRate * CpWater);
3419 32253 : simpleWatertoAirHP.OutletWaterEnthalpy =
3420 32253 : state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth - simpleWatertoAirHP.QSource / simpleWatertoAirHP.WaterMassFlowRate;
3421 : }
3422 : } else {
3423 6 : if ((simpleWatertoAirHP.WaterCyclingMode) == HVAC::WaterFlow::Constant) {
3424 0 : if (simpleWatertoAirHP.WaterFlowMode) {
3425 0 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate;
3426 0 : PlantUtilities::SetComponentFlowRate(state,
3427 0 : simpleWatertoAirHP.WaterMassFlowRate,
3428 : simpleWatertoAirHP.WaterInletNodeNum,
3429 : simpleWatertoAirHP.WaterOutletNodeNum,
3430 0 : simpleWatertoAirHP.plantLoc);
3431 : } else {
3432 0 : simpleWatertoAirHP.WaterMassFlowRate = state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3433 : }
3434 : } else {
3435 6 : simpleWatertoAirHP.WaterMassFlowRate = state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3436 : }
3437 6 : simpleWatertoAirHP.OutletWaterTemp = state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp -
3438 6 : simpleWatertoAirHP.QSource / (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate * CpWater);
3439 6 : simpleWatertoAirHP.OutletWaterEnthalpy = state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth -
3440 6 : simpleWatertoAirHP.QSource / state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3441 : }
3442 : }
3443 :
3444 99790 : void UpdateSimpleWatertoAirHP(EnergyPlusData &state, int const HPNum)
3445 : {
3446 : // SUBROUTINE INFORMATION:
3447 : // AUTHOR Arun Shenoy
3448 : // DATE WRITTEN Jan 2004
3449 : // RE-ENGINEERED Kenneth Tang (Jan 2005)
3450 :
3451 : // PURPOSE OF THIS SUBROUTINE:
3452 : // This subroutine updates the Water to Air Heat Pump outlet nodes.
3453 :
3454 : // METHODOLOGY EMPLOYED:
3455 : // Data is moved from the HP data structure to the HP outlet nodes.
3456 :
3457 99790 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
3458 :
3459 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3460 : int AirInletNode;
3461 : int WaterInletNode;
3462 : int AirOutletNode;
3463 : int WaterOutletNode;
3464 :
3465 99790 : auto &simpleWatertoAirHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
3466 :
3467 99790 : if (!simpleWatertoAirHP.SimFlag) {
3468 : // Heatpump is off; just pass through conditions
3469 57378 : simpleWatertoAirHP.Power = 0.0;
3470 57378 : simpleWatertoAirHP.QLoadTotal = 0.0;
3471 57378 : simpleWatertoAirHP.QLoadTotalReport = 0.0;
3472 57378 : simpleWatertoAirHP.QSensible = 0.0;
3473 57378 : simpleWatertoAirHP.QLatent = 0.0;
3474 57378 : simpleWatertoAirHP.QSource = 0.0;
3475 57378 : simpleWatertoAirHP.Energy = 0.0;
3476 57378 : simpleWatertoAirHP.EnergyLoadTotal = 0.0;
3477 57378 : simpleWatertoAirHP.EnergySensible = 0.0;
3478 57378 : simpleWatertoAirHP.EnergyLatent = 0.0;
3479 57378 : simpleWatertoAirHP.EnergySource = 0.0;
3480 57378 : simpleWatertoAirHP.COP = 0.0;
3481 57378 : simpleWatertoAirHP.RunFrac = 0.0;
3482 57378 : simpleWatertoAirHP.PartLoadRatio = 0.0;
3483 :
3484 57378 : simpleWatertoAirHP.OutletAirDBTemp = simpleWatertoAirHP.InletAirDBTemp;
3485 57378 : simpleWatertoAirHP.OutletAirHumRat = simpleWatertoAirHP.InletAirHumRat;
3486 57378 : simpleWatertoAirHP.OutletAirEnthalpy = simpleWatertoAirHP.InletAirEnthalpy;
3487 57378 : simpleWatertoAirHP.OutletWaterTemp = simpleWatertoAirHP.InletWaterTemp;
3488 57378 : simpleWatertoAirHP.OutletWaterEnthalpy = simpleWatertoAirHP.InletWaterEnthalpy;
3489 : }
3490 :
3491 99790 : AirInletNode = simpleWatertoAirHP.AirInletNodeNum;
3492 99790 : WaterInletNode = simpleWatertoAirHP.WaterInletNodeNum;
3493 99790 : AirOutletNode = simpleWatertoAirHP.AirOutletNodeNum;
3494 99790 : WaterOutletNode = simpleWatertoAirHP.WaterOutletNodeNum;
3495 :
3496 : // Set the air outlet nodes of the WatertoAirHPSimple
3497 99790 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRate = state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
3498 99790 : state.dataLoopNodes->Node(AirOutletNode).Temp = simpleWatertoAirHP.OutletAirDBTemp;
3499 99790 : state.dataLoopNodes->Node(AirOutletNode).HumRat = simpleWatertoAirHP.OutletAirHumRat;
3500 99790 : state.dataLoopNodes->Node(AirOutletNode).Enthalpy = simpleWatertoAirHP.OutletAirEnthalpy;
3501 :
3502 : // Set the air outlet nodes for properties that just pass through & not used
3503 99790 : state.dataLoopNodes->Node(AirOutletNode).Quality = state.dataLoopNodes->Node(AirInletNode).Quality;
3504 99790 : state.dataLoopNodes->Node(AirOutletNode).Press = state.dataLoopNodes->Node(AirInletNode).Press;
3505 99790 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMin = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMin;
3506 99790 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMax = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax;
3507 99790 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMinAvail;
3508 99790 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMaxAvail;
3509 :
3510 : // Set the water outlet node of the WatertoAirHPSimple
3511 : // Set the water outlet nodes for properties that just pass through & not used
3512 99790 : PlantUtilities::SafeCopyPlantNode(state, WaterInletNode, WaterOutletNode);
3513 :
3514 99790 : state.dataLoopNodes->Node(WaterOutletNode).Temp = simpleWatertoAirHP.OutletWaterTemp;
3515 99790 : state.dataLoopNodes->Node(WaterOutletNode).Enthalpy = simpleWatertoAirHP.OutletWaterEnthalpy;
3516 :
3517 99790 : simpleWatertoAirHP.Energy = simpleWatertoAirHP.Power * TimeStepSysSec;
3518 99790 : simpleWatertoAirHP.EnergyLoadTotal = simpleWatertoAirHP.QLoadTotal * TimeStepSysSec;
3519 99790 : simpleWatertoAirHP.EnergySensible = simpleWatertoAirHP.QSensible * TimeStepSysSec;
3520 99790 : simpleWatertoAirHP.EnergyLatent = simpleWatertoAirHP.QLatent * TimeStepSysSec;
3521 99790 : simpleWatertoAirHP.EnergySource = simpleWatertoAirHP.QSource * TimeStepSysSec;
3522 :
3523 99790 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
3524 0 : state.dataLoopNodes->Node(AirOutletNode).CO2 = state.dataLoopNodes->Node(AirInletNode).CO2;
3525 : }
3526 99790 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
3527 0 : state.dataLoopNodes->Node(AirOutletNode).GenContam = state.dataLoopNodes->Node(AirInletNode).GenContam;
3528 : }
3529 :
3530 99790 : if (simpleWatertoAirHP.reportCoilFinalSizes) {
3531 10 : if (!state.dataGlobal->WarmupFlag && !state.dataGlobal->DoingHVACSizingSimulations && !state.dataGlobal->DoingSizing) {
3532 :
3533 8 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
3534 4 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(
3535 : state,
3536 4 : simpleWatertoAirHP.Name,
3537 8 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
3538 : simpleWatertoAirHP.RatedCapCoolTotal,
3539 : simpleWatertoAirHP.RatedCapCoolSens,
3540 : simpleWatertoAirHP.RatedAirVolFlowRate,
3541 : simpleWatertoAirHP.RatedWaterVolFlowRate);
3542 4 : } else if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating) {
3543 4 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(
3544 : state,
3545 4 : simpleWatertoAirHP.Name,
3546 8 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
3547 : simpleWatertoAirHP.RatedCapHeat,
3548 : simpleWatertoAirHP.RatedCapHeat,
3549 : simpleWatertoAirHP.RatedAirVolFlowRate,
3550 : simpleWatertoAirHP.RatedWaterVolFlowRate);
3551 : }
3552 8 : simpleWatertoAirHP.reportCoilFinalSizes = false;
3553 : }
3554 : }
3555 99790 : }
3556 :
3557 : // End of Update subroutines for the WatertoAirHP Module
3558 : // *****************************************************************************
3559 :
3560 2 : Real64 CalcEffectiveSHR(EnergyPlusData &state,
3561 : int const HPNum, // Index number for cooling coil
3562 : Real64 const SHRss, // Steady-state sensible heat ratio
3563 : HVAC::FanOp const fanOp, // Fan/compressor cycling scheme indicator
3564 : Real64 const RTF, // Compressor run-time fraction
3565 : Real64 const QLatRated, // Rated latent capacity
3566 : Real64 const QLatActual, // Actual latent capacity
3567 : Real64 const EnteringDB, // Entering air dry-bulb temperature
3568 : Real64 const EnteringWB // Entering air wet-bulb temperature
3569 : )
3570 : {
3571 :
3572 : // FUNCTION INFORMATION:
3573 : // AUTHOR Richard Raustad, FSEC
3574 : // DATE WRITTEN September 2003
3575 : // MODIFIED Kenneth Tang (Aug 2004) Added capability for simulating FanOp::Cycling
3576 :
3577 : // PURPOSE OF THIS FUNCTION:
3578 : // Adjust sensible heat ratio to account for degradation of DX coil latent
3579 : // capacity at part-load (cycling) conditions.
3580 :
3581 : // METHODOLOGY EMPLOYED:
3582 : // With model parameters entered by the user, the part-load latent performance
3583 : // of a DX cooling coil is determined for a constant air flow system with
3584 : // a cooling coil that cycles on/off. The model calculates the time
3585 : // required for condensate to begin falling from the cooling coil.
3586 : // Runtimes greater than this are integrated to a "part-load" latent
3587 : // capacity which is used to determine the "part-load" sensible heat ratio.
3588 : // See reference below for additional details (linear decay model, Eq. 8b).
3589 :
3590 : // For cycling fan operation, a modified version of Henderson and Rengarajan (1996)
3591 : // model is used by ultilizing the fan delay time as the time-off (or time duration
3592 : // for the re-evaporation of moisture from time coil). Refer to Tang, C.C. (2005)
3593 :
3594 : // REFERENCES:
3595 : // (1) Henderson, H.I., K. Rengarajan.1996. A Model to Predict the Latent
3596 : // Capacity of Air Conditioners and Heat Pumps at Part-Load Conditions
3597 : // with Constant Fan Operation ASHRAE Transactions 102 (1), pp. 266-274.
3598 : // (2) Tang,C.C.. 2005. Modeling Packaged Heat Pumps in a Quasi-Steady
3599 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
3600 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
3601 :
3602 : // Return value
3603 : Real64 SHReff; // Effective sensible heat ratio, includes degradation due to cycling effects
3604 :
3605 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3606 : Real64 Twet; // Nominal time for condensate to begin leaving the coil's condensate drain line
3607 : // at the current operating conditions (sec)
3608 : Real64 Gamma; // Initial moisture evaporation rate divided by steady-state AC latent capacity
3609 : // at the current operating conditions
3610 : Real64 Twet_Rated; // Twet at rated conditions (coil air flow rate and air temperatures), sec
3611 : Real64 Gamma_Rated; // Gamma at rated conditions (coil air flow rate and air temperatures)
3612 : Real64 Twet_max; // Maximum allowed value for Twet
3613 : Real64 MaxONOFFCyclesperHour; // Maximum cycling rate of heat pump [cycles/hr]
3614 : Real64 LatentCapacityTimeConstant; // Latent capacity time constant [s]
3615 : Real64 FanDelayTime; // Fan delay time, time delay for the HP's fan to
3616 : // shut off after compressor cycle off [s]
3617 : Real64 Ton; // Coil on time (sec)
3618 : Real64 Toff; // Coil off time (sec)
3619 : Real64 Toffa; // Actual coil off time (sec). Equations valid for Toff <= (2.0 * Twet/Gamma)
3620 : Real64 aa; // Intermediate variable
3621 : Real64 To1; // Intermediate variable (first guess at To). To = time to the start of moisture removal
3622 : Real64 To2; // Intermediate variable (second guess at To). To = time to the start of moisture removal
3623 : Real64 Error; // Error for iteration (DO) loop
3624 : Real64 LHRmult; // Latent Heat Ratio (LHR) multiplier. The effective latent heat ratio LHR = (1-SHRss)*LHRmult
3625 :
3626 2 : auto const &simpleWatertoAirHP = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum);
3627 :
3628 2 : Twet_Rated = simpleWatertoAirHP.Twet_Rated;
3629 2 : Gamma_Rated = simpleWatertoAirHP.Gamma_Rated;
3630 2 : MaxONOFFCyclesperHour = simpleWatertoAirHP.MaxONOFFCyclesperHour;
3631 2 : LatentCapacityTimeConstant = simpleWatertoAirHP.LatentCapacityTimeConstant;
3632 2 : FanDelayTime = simpleWatertoAirHP.FanDelayTime;
3633 :
3634 : // No moisture evaporation (latent degradation) occurs for runtime fraction of 1.0
3635 : // All latent degradation model parameters cause divide by 0.0 if not greater than 0.0
3636 : // Latent degradation model parameters initialize to 0.0 meaning no evaporation model used.
3637 2 : if ((RTF >= 1.0) || (QLatRated == 0.0) || (QLatActual == 0.0) || (Twet_Rated <= 0.0) || (Gamma_Rated <= 0.0) ||
3638 0 : (MaxONOFFCyclesperHour <= 0.0) || (LatentCapacityTimeConstant <= 0.0) || (RTF <= 0.0)) {
3639 2 : SHReff = SHRss;
3640 2 : return SHReff;
3641 : }
3642 :
3643 0 : Twet_max = 9999.0; // high limit for Twet
3644 :
3645 : // Calculate the model parameters at the actual operating conditions
3646 0 : Twet = min(Twet_Rated * QLatRated / (QLatActual + 1.e-10), Twet_max);
3647 0 : Gamma = Gamma_Rated * QLatRated * (EnteringDB - EnteringWB) / ((26.7 - 19.4) * QLatActual + 1.e-10);
3648 :
3649 : // Calculate the compressor on and off times using a converntional thermostat curve
3650 0 : Ton = 3600.0 / (4.0 * MaxONOFFCyclesperHour * (1.0 - RTF)); // duration of cooling coil on-cycle (sec)
3651 :
3652 0 : if ((fanOp == HVAC::FanOp::Cycling) && (FanDelayTime != 0.0)) {
3653 : // For FanOp::Cycling, moisture is evaporated from the cooling coil back to the air stream
3654 : // until the fan cycle off. Assume no evaporation from the coil after the fan shuts off.
3655 0 : Toff = FanDelayTime;
3656 : } else {
3657 : // For FanOp::Continuous, moisture is evaporated from the cooling coil back to the air stream
3658 : // for the entire heat pump off-cycle.
3659 0 : Toff = 3600.0 / (4.0 * MaxONOFFCyclesperHour * RTF); // duration of cooling coil off-cycle (sec)
3660 : }
3661 :
3662 : // Cap Toff to meet the equation restriction
3663 0 : if (Gamma > 0.0) {
3664 0 : Toffa = min(Toff, 2.0 * Twet / Gamma);
3665 : } else {
3666 0 : Toffa = Toff;
3667 : }
3668 :
3669 : // Use sucessive substitution to solve for To
3670 0 : aa = (Gamma * Toffa) - (0.25 / Twet) * pow_2(Gamma) * pow_2(Toffa);
3671 :
3672 0 : To1 = aa + LatentCapacityTimeConstant;
3673 0 : Error = 1.0;
3674 0 : while (Error > 0.001) {
3675 0 : To2 = aa - LatentCapacityTimeConstant * std::expm1(-To1 / LatentCapacityTimeConstant);
3676 0 : Error = std::abs((To2 - To1) / To1);
3677 0 : To1 = To2;
3678 : }
3679 :
3680 : // Adjust Sensible Heat Ratio (SHR) using Latent Heat Ratio (LHR) multiplier
3681 : // Floating underflow errors occur when -Ton/LatentCapacityTimeConstant is a large negative number.
3682 : // Cap lower limit at -700 to avoid the underflow errors.
3683 0 : aa = std::exp(max(-700.0, -Ton / LatentCapacityTimeConstant));
3684 : // Calculate latent heat ratio multiplier
3685 0 : LHRmult = max(((Ton - To2) / (Ton + LatentCapacityTimeConstant * (aa - 1.0))), 0.0);
3686 :
3687 : // Calculate part-load or "effective" sensible heat ratio
3688 0 : SHReff = 1.0 - (1.0 - SHRss) * LHRmult;
3689 :
3690 0 : if (SHReff < SHRss) SHReff = SHRss; // Effective SHR can be less than the steady-state SHR
3691 0 : if (SHReff > 1.0) SHReff = 1.0; // Effective sensible heat ratio can't be greater than 1.0
3692 :
3693 0 : return SHReff;
3694 : }
3695 :
3696 5 : int GetCoilIndex(EnergyPlusData &state,
3697 : std::string const &CoilType, // must match coil types in this module
3698 : std::string const &CoilName, // must match coil names for the coil type
3699 : bool &ErrorsFound // set to true if problem
3700 : )
3701 : {
3702 :
3703 : // FUNCTION INFORMATION:
3704 : // AUTHOR R. Raustad
3705 : // DATE WRITTEN August 2007
3706 :
3707 : // PURPOSE OF THIS FUNCTION:
3708 : // This function looks up the coil capacity for the given coil and returns it. If
3709 : // incorrect coil type or name is given, ErrorsFound is returned as true and index is returned
3710 : // as zero.
3711 :
3712 : // Return value
3713 : int IndexNum; // returned index of matched coil
3714 :
3715 : // Obtains and Allocates WatertoAirHP related parameters from input file
3716 5 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3717 3 : GetSimpleWatertoAirHPInput(state);
3718 3 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3719 : }
3720 :
3721 5 : IndexNum = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3722 :
3723 5 : if (IndexNum == 0) {
3724 0 : ShowSevereError(state, format(R"(Could not find CoilType="{}" with Name="{}")", CoilType, CoilName));
3725 0 : ErrorsFound = true;
3726 : }
3727 :
3728 5 : return IndexNum;
3729 : }
3730 :
3731 6 : Real64 GetCoilCapacity(EnergyPlusData &state,
3732 : std::string const &CoilType, // must match coil types in this module
3733 : std::string const &CoilName, // must match coil names for the coil type
3734 : bool &ErrorsFound // set to true if problem
3735 : )
3736 : {
3737 :
3738 : // FUNCTION INFORMATION:
3739 : // AUTHOR Linda Lawrie
3740 : // DATE WRITTEN February 2006
3741 :
3742 : // PURPOSE OF THIS FUNCTION:
3743 : // This function looks up the coil capacity for the given coil and returns it. If
3744 : // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
3745 : // as negative.
3746 :
3747 : // Return value
3748 : Real64 CoilCapacity; // returned capacity of matched coil
3749 :
3750 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3751 : int WhichCoil;
3752 :
3753 : // Obtains and Allocates WatertoAirHP related parameters from input file
3754 6 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3755 0 : GetSimpleWatertoAirHPInput(state);
3756 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3757 : }
3758 :
3759 8 : if (Util::SameString(CoilType, "COIL:COOLING:WATERTOAIRHEATPUMP:EQUATIONFIT") ||
3760 8 : Util::SameString(CoilType, "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT")) {
3761 6 : WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3762 6 : if (WhichCoil != 0) {
3763 6 : if (Util::SameString(CoilType, "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT")) {
3764 2 : CoilCapacity = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).RatedCapHeat;
3765 : } else {
3766 4 : CoilCapacity = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).RatedCapCoolTotal;
3767 :
3768 4 : int companionHeatingCoil = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).CompanionHeatingCoilNum;
3769 4 : if (companionHeatingCoil > 0) {
3770 5 : if (CoilCapacity == DataSizing::AutoSize &&
3771 1 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(companionHeatingCoil).WAHPPlantType ==
3772 1 : DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit &&
3773 6 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(companionHeatingCoil).RatedCapHeat == DataSizing::AutoSize &&
3774 1 : state.dataSize->DXCoolCap > 0) {
3775 : // Heating coil has not yet been sized, returning the temporary cooling capacity
3776 1 : CoilCapacity = state.dataSize->DXCoolCap;
3777 : }
3778 : }
3779 : }
3780 : }
3781 : } else {
3782 0 : WhichCoil = 0;
3783 : }
3784 :
3785 6 : if (WhichCoil == 0) {
3786 0 : ShowSevereError(state, format(R"(Could not find CoilType="{}" with Name="{}")", CoilType, CoilName));
3787 0 : ErrorsFound = true;
3788 0 : CoilCapacity = -1000.0;
3789 : }
3790 :
3791 6 : return CoilCapacity;
3792 : }
3793 :
3794 4 : Real64 GetCoilAirFlowRate(EnergyPlusData &state,
3795 : std::string const &CoilType, // must match coil types in this module
3796 : std::string const &CoilName, // must match coil names for the coil type
3797 : bool &ErrorsFound // set to true if problem
3798 : )
3799 : {
3800 :
3801 : // FUNCTION INFORMATION:
3802 : // AUTHOR Richard Raustad, FSEC
3803 : // DATE WRITTEN October 2011
3804 :
3805 : // PURPOSE OF THIS FUNCTION:
3806 : // This function looks up the coil air flow rate for the given coil and returns it. If
3807 : // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
3808 : // as negative.
3809 :
3810 : // Return value
3811 : Real64 CoilAirFlowRate; // returned air volume flow rate of matched coil
3812 :
3813 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3814 : int WhichCoil;
3815 :
3816 : // Obtains and Allocates WatertoAirHP related parameters from input file
3817 4 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3818 0 : GetSimpleWatertoAirHPInput(state);
3819 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3820 : }
3821 :
3822 6 : if (Util::SameString(CoilType, "COIL:COOLING:WATERTOAIRHEATPUMP:EQUATIONFIT") ||
3823 6 : Util::SameString(CoilType, "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT")) {
3824 4 : WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3825 4 : if (WhichCoil != 0) {
3826 4 : CoilAirFlowRate = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).RatedAirVolFlowRate;
3827 : }
3828 : } else {
3829 0 : WhichCoil = 0;
3830 : }
3831 :
3832 4 : if (WhichCoil == 0) {
3833 0 : ShowSevereError(state, format(R"(Could not find CoilType="{}" with Name="{}")", CoilType, CoilName));
3834 0 : ErrorsFound = true;
3835 0 : CoilAirFlowRate = -1000.0;
3836 : }
3837 :
3838 4 : return CoilAirFlowRate;
3839 : }
3840 :
3841 0 : int GetCoilInletNode(EnergyPlusData &state,
3842 : std::string const &CoilType, // must match coil types in this module
3843 : std::string const &CoilName, // must match coil names for the coil type
3844 : bool &ErrorsFound // set to true if problem
3845 : )
3846 : {
3847 :
3848 : // FUNCTION INFORMATION:
3849 : // AUTHOR Linda Lawrie
3850 : // DATE WRITTEN February 2006
3851 :
3852 : // PURPOSE OF THIS FUNCTION:
3853 : // This function looks up the given coil and returns the inlet node. If
3854 : // incorrect coil type or name is given, ErrorsFound is returned as true and value is returned
3855 : // as zero.
3856 :
3857 : // Return value
3858 : int NodeNumber; // returned outlet node of matched coil
3859 :
3860 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3861 : int WhichCoil;
3862 :
3863 : // Obtains and Allocates WatertoAirHP related parameters from input file
3864 0 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3865 0 : GetSimpleWatertoAirHPInput(state);
3866 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3867 : }
3868 :
3869 0 : WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3870 0 : if (WhichCoil != 0) {
3871 0 : NodeNumber = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).AirInletNodeNum;
3872 : }
3873 :
3874 0 : if (WhichCoil == 0) {
3875 0 : ShowSevereError(state, format(R"(Could not find CoilType="{}" with Name="{}")", CoilType, CoilName));
3876 0 : ErrorsFound = true;
3877 0 : NodeNumber = 0;
3878 : }
3879 :
3880 0 : return NodeNumber;
3881 : }
3882 :
3883 0 : int GetCoilOutletNode(EnergyPlusData &state,
3884 : std::string const &CoilType, // must match coil types in this module
3885 : std::string const &CoilName, // must match coil names for the coil type
3886 : bool &ErrorsFound // set to true if problem
3887 : )
3888 : {
3889 :
3890 : // FUNCTION INFORMATION:
3891 : // AUTHOR R. Raustad
3892 : // DATE WRITTEN July 2007
3893 :
3894 : // PURPOSE OF THIS FUNCTION:
3895 : // This function looks up the given coil and returns the outlet node. If
3896 : // incorrect coil type or name is given, ErrorsFound is returned as true and value is returned
3897 : // as zero.
3898 :
3899 : // Return value
3900 : int NodeNumber; // returned outlet node of matched coil
3901 :
3902 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3903 : int WhichCoil;
3904 :
3905 : // Obtains and Allocates WatertoAirHP related parameters from input file
3906 0 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3907 0 : GetSimpleWatertoAirHPInput(state);
3908 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3909 : }
3910 :
3911 0 : WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3912 0 : if (WhichCoil != 0) {
3913 0 : NodeNumber = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).AirOutletNodeNum;
3914 : }
3915 :
3916 0 : if (WhichCoil == 0) {
3917 0 : ShowSevereError(state, format(R"(Could not find CoilType="{}" with Name="{}")", CoilType, CoilName));
3918 0 : ErrorsFound = true;
3919 0 : NodeNumber = 0;
3920 : }
3921 :
3922 0 : return NodeNumber;
3923 : }
3924 :
3925 2 : void SetSimpleWSHPData(EnergyPlusData &state,
3926 : int const SimpleWSHPNum, // Number of OA Controller
3927 : bool &ErrorsFound, // Set to true if certain errors found
3928 : HVAC::WaterFlow const WaterCyclingMode, // the coil water flow mode (cycling, constant or constantondemand)
3929 : ObjexxFCL::Optional_int CompanionCoolingCoilNum, // Index to cooling coil for heating coil = SimpleWSHPNum
3930 : ObjexxFCL::Optional_int CompanionHeatingCoilNum // Index to heating coil for cooling coil = SimpleWSHPNum
3931 : )
3932 : {
3933 :
3934 : // SUBROUTINE INFORMATION:
3935 : // AUTHOR Richard Raustad
3936 : // DATE WRITTEN June 2009
3937 :
3938 : // PURPOSE OF THIS SUBROUTINE:
3939 : // This routine was designed to "push" information from a parent object to
3940 : // this WSHP coil object.
3941 :
3942 : // Obtains and Allocates WatertoAirHP related parameters from input file
3943 2 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3944 0 : GetSimpleWatertoAirHPInput(state);
3945 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3946 : }
3947 :
3948 2 : if (SimpleWSHPNum <= 0 || SimpleWSHPNum > state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs) {
3949 0 : ShowSevereError(state,
3950 0 : format("SetSimpleWSHPData: called with WSHP Coil Number out of range={} should be >0 and <{}",
3951 : SimpleWSHPNum,
3952 0 : state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs));
3953 0 : ErrorsFound = true;
3954 0 : return;
3955 : }
3956 :
3957 2 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(SimpleWSHPNum).WaterCyclingMode = WaterCyclingMode;
3958 2 : if (present(CompanionCoolingCoilNum)) {
3959 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(SimpleWSHPNum).CompanionCoolingCoilNum = CompanionCoolingCoilNum;
3960 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionCoolingCoilNum).CompanionHeatingCoilNum = SimpleWSHPNum;
3961 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionCoolingCoilNum).WaterCyclingMode = WaterCyclingMode;
3962 : }
3963 :
3964 2 : if (present(CompanionHeatingCoilNum)) {
3965 2 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(SimpleWSHPNum).CompanionHeatingCoilNum = CompanionHeatingCoilNum;
3966 2 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoilNum).CompanionCoolingCoilNum = SimpleWSHPNum;
3967 2 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoilNum).WaterCyclingMode = WaterCyclingMode;
3968 : }
3969 : }
3970 :
3971 15 : void CheckSimpleWAHPRatedCurvesOutputs(EnergyPlusData &state, std::string const &CoilName)
3972 : {
3973 15 : constexpr Real64 Tref(283.15); // Refrence Temperature for performance curves,10C [K]
3974 : static constexpr std::string_view RoutineName("CheckSimpleWAHPRatedCurvesOutputs");
3975 :
3976 15 : int WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3977 :
3978 15 : if (WhichCoil == 0) return;
3979 :
3980 15 : auto &wahp = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil);
3981 15 : if (wahp.WAHPType == WatertoAirHP::Cooling) {
3982 10 : if (wahp.RatedEntAirWetbulbTemp != DataSizing::AutoSize && wahp.TotalCoolCapCurve != nullptr && wahp.CoolPowCurve != nullptr) {
3983 9 : Real64 RatedratioTWB = (wahp.RatedEntAirWetbulbTemp + Constant::Kelvin) / Tref;
3984 9 : Real64 RatedratioTS = (wahp.RatedEntWaterTemp + Constant::Kelvin) / Tref;
3985 9 : Real64 RatedTotCapTempModFac = wahp.TotalCoolCapCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
3986 9 : Real64 RatedCoolPowerTempModFac = wahp.CoolPowCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
3987 9 : if (RatedTotCapTempModFac > 1.02 || RatedTotCapTempModFac < 0.98) {
3988 7 : ShowWarningError(state, format("{}: Coil:Cooling:WaterToAirHeatPump:EquationFit=\"{}\"", RoutineName, wahp.Name));
3989 14 : ShowContinueError(state,
3990 : "Total cooling capacity as a function of temperature curve output is not equal to 1.0 (+ or - 2%) "
3991 : "at rated conditions.");
3992 7 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedTotCapTempModFac));
3993 : }
3994 9 : if (RatedCoolPowerTempModFac > 1.02 || RatedCoolPowerTempModFac < 0.98) {
3995 7 : ShowWarningError(state, format("{}: Coil:Cooling:WaterToAirHeatPump:EquationFit=\"{}\"", RoutineName, wahp.Name));
3996 14 : ShowContinueError(state,
3997 : "Cooling power consumption as a function of temperature curve output is not equal to 1.0 (+ or - 2%) "
3998 : "at rated conditions.");
3999 7 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedCoolPowerTempModFac));
4000 : }
4001 : }
4002 :
4003 10 : if (wahp.RatedEntAirDrybulbTemp != DataSizing::AutoSize && wahp.SensCoolCapCurve != nullptr) {
4004 8 : Real64 RatedratioTDB = (wahp.RatedEntAirDrybulbTemp + Constant::Kelvin) / Tref;
4005 8 : Real64 RatedratioTWB = (wahp.RatedEntAirWetbulbTemp + Constant::Kelvin) / Tref;
4006 8 : Real64 RatedratioTS = (wahp.RatedEntWaterTemp + Constant::Kelvin) / Tref;
4007 :
4008 8 : Real64 RatedSensCapTempModFac = wahp.SensCoolCapCurve->value(state, RatedratioTDB, RatedratioTWB, RatedratioTS, 1.0, 1.0);
4009 8 : if (RatedSensCapTempModFac > 1.02 || RatedSensCapTempModFac < 0.98) {
4010 5 : ShowWarningError(state, format("{}: Coil:Cooling:WaterToAirHeatPump:EquationFit=\"{}\"", RoutineName, wahp.Name));
4011 10 : ShowContinueError(state,
4012 : "Sensible cooling capacity as a function of temperature curve output is not equal to 1.0 (+ or - 2%) "
4013 : "at rated conditions.");
4014 5 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedSensCapTempModFac));
4015 : }
4016 : }
4017 :
4018 5 : } else if (wahp.WAHPType == WatertoAirHP::Heating) {
4019 5 : if (wahp.RatedEntAirDrybulbTemp != DataSizing::AutoSize && wahp.HeatCapCurve != nullptr && wahp.HeatPowCurve != nullptr) {
4020 4 : Real64 RatedHeatratioTDB = (wahp.RatedEntAirDrybulbTemp + Constant::Kelvin) / Tref;
4021 4 : Real64 RatedHeatratioTS = (wahp.RatedEntWaterTemp + Constant::Kelvin) / Tref;
4022 4 : Real64 RatedHeatCapTempModFac = wahp.HeatCapCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
4023 4 : Real64 RatedHeatPowerTempModFac = wahp.HeatPowCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
4024 4 : if (RatedHeatCapTempModFac > 1.02 || RatedHeatCapTempModFac < 0.98) {
4025 2 : ShowWarningError(state, format("{}: Coil:Heating:WaterToAirHeatPump:EquationFit=\"{}\"", RoutineName, wahp.Name));
4026 4 : ShowContinueError(
4027 : state, "Heating capacity as a function of temperature curve output is not equal to 1.0 (+ or - 2%) at rated conditions.");
4028 2 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedHeatCapTempModFac));
4029 : }
4030 4 : if (RatedHeatPowerTempModFac > 1.02 || RatedHeatPowerTempModFac < 0.98) {
4031 2 : ShowWarningError(state, format("{}: Coil:Heating:WaterToAirHeatPump:EquationFit=\"{}\"", RoutineName, wahp.Name));
4032 4 : ShowContinueError(state,
4033 : "Heating power consumption as a function of temperature curve output is not equal to 1.0 (+ or - 2%) at "
4034 : "rated conditions.");
4035 2 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedHeatPowerTempModFac));
4036 : }
4037 : }
4038 : }
4039 : }
4040 : } // namespace WaterToAirHeatPumpSimple
4041 :
4042 : } // namespace EnergyPlus
|