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 : }
1030 : } else {
1031 25128 : if (simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
1032 25124 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(simpleWatertoAirHP.CompanionCoolingCoilNum) = true;
1033 : }
1034 : }
1035 : }
1036 :
1037 : // Do the Begin Environment initializations
1038 99809 : if (state.dataGlobal->BeginEnvrnFlag) {
1039 :
1040 385 : if (state.dataWaterToAirHeatPumpSimple->MyEnvrnFlag(HPNum) && !state.dataWaterToAirHeatPumpSimple->MyPlantScanFlag(HPNum)) {
1041 :
1042 : // Initialize all report variables to a known state at beginning of simulation
1043 11 : simpleWatertoAirHP.AirVolFlowRate = 0.0;
1044 11 : simpleWatertoAirHP.InletAirDBTemp = 0.0;
1045 11 : simpleWatertoAirHP.InletAirHumRat = 0.0;
1046 11 : simpleWatertoAirHP.OutletAirDBTemp = 0.0;
1047 11 : simpleWatertoAirHP.OutletAirHumRat = 0.0;
1048 11 : simpleWatertoAirHP.WaterVolFlowRate = 0.0;
1049 11 : simpleWatertoAirHP.WaterMassFlowRate = 0.0;
1050 11 : simpleWatertoAirHP.InletWaterTemp = 0.0;
1051 11 : simpleWatertoAirHP.InletWaterEnthalpy = 0.0;
1052 11 : simpleWatertoAirHP.OutletWaterEnthalpy = 0.0;
1053 11 : simpleWatertoAirHP.OutletWaterTemp = 0.0;
1054 11 : simpleWatertoAirHP.Power = 0.0;
1055 11 : simpleWatertoAirHP.QLoadTotal = 0.0;
1056 11 : simpleWatertoAirHP.QLoadTotalReport = 0.0;
1057 11 : simpleWatertoAirHP.QSensible = 0.0;
1058 11 : simpleWatertoAirHP.QLatent = 0.0;
1059 11 : simpleWatertoAirHP.QSource = 0.0;
1060 11 : simpleWatertoAirHP.Energy = 0.0;
1061 11 : simpleWatertoAirHP.EnergyLoadTotal = 0.0;
1062 11 : simpleWatertoAirHP.EnergySensible = 0.0;
1063 11 : simpleWatertoAirHP.EnergyLatent = 0.0;
1064 11 : simpleWatertoAirHP.EnergySource = 0.0;
1065 11 : simpleWatertoAirHP.COP = 0.0;
1066 11 : simpleWatertoAirHP.RunFrac = 0.0;
1067 11 : simpleWatertoAirHP.PartLoadRatio = 0.0;
1068 :
1069 11 : if (simpleWatertoAirHP.RatedWaterVolFlowRate != DataSizing::AutoSize) {
1070 : rho =
1071 10 : state.dataPlnt->PlantLoop(simpleWatertoAirHP.plantLoc.loopNum).glycol->getDensity(state, Constant::InitConvTemp, RoutineName);
1072 :
1073 10 : simpleWatertoAirHP.DesignWaterMassFlowRate = rho * simpleWatertoAirHP.RatedWaterVolFlowRate;
1074 10 : PlantUtilities::InitComponentNodes(state,
1075 : 0.0,
1076 : simpleWatertoAirHP.DesignWaterMassFlowRate,
1077 : simpleWatertoAirHP.WaterInletNodeNum,
1078 : simpleWatertoAirHP.WaterOutletNodeNum);
1079 :
1080 10 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating && simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
1081 5 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).DesignWaterMassFlowRate =
1082 5 : rho *
1083 5 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).RatedWaterVolFlowRate;
1084 15 : PlantUtilities::InitComponentNodes(
1085 : state,
1086 : 0.0,
1087 5 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum)
1088 : .DesignWaterMassFlowRate,
1089 5 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).WaterInletNodeNum,
1090 5 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).WaterOutletNodeNum);
1091 : }
1092 : }
1093 :
1094 11 : simpleWatertoAirHP.SimFlag = true;
1095 :
1096 11 : state.dataWaterToAirHeatPumpSimple->MyEnvrnFlag(HPNum) = false;
1097 : }
1098 :
1099 : } // End If for the Begin Environment initializations
1100 :
1101 99809 : if (!state.dataGlobal->BeginEnvrnFlag) {
1102 99424 : state.dataWaterToAirHeatPumpSimple->MyEnvrnFlag(HPNum) = true;
1103 : }
1104 :
1105 : // Do the following initializations (every time step): This should be the info from
1106 : // the previous components outlets or the node data in this section.
1107 : // First set the conditions for the air into the heat pump model
1108 :
1109 : // Set water and air inlet nodes
1110 :
1111 99809 : int AirInletNode = simpleWatertoAirHP.AirInletNodeNum;
1112 99809 : int WaterInletNode = simpleWatertoAirHP.WaterInletNodeNum;
1113 :
1114 99809 : if ((SensLoad != 0.0 || LatentLoad != 0.0) && (state.dataLoopNodes->Node(AirInletNode).MassFlowRate > 0.0)) {
1115 44035 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate;
1116 :
1117 44035 : simpleWatertoAirHP.AirMassFlowRate = state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
1118 : // If air flow is less than 25% rated flow. Then throw warning
1119 44035 : RatedAirMassFlowRate =
1120 44035 : simpleWatertoAirHP.RatedAirVolFlowRate * Psychrometrics::PsyRhoAirFnPbTdbW(state,
1121 44035 : state.dataEnvrn->StdBaroPress,
1122 44035 : state.dataLoopNodes->Node(AirInletNode).Temp,
1123 44035 : state.dataLoopNodes->Node(AirInletNode).HumRat,
1124 : RoutineName);
1125 44035 : if (simpleWatertoAirHP.AirMassFlowRate < 0.25 * RatedAirMassFlowRate) {
1126 9184 : ShowRecurringWarningErrorAtEnd(state,
1127 : "Actual air mass flow rate is smaller than 25% of water-to-air heat pump coil rated air flow rate.",
1128 1148 : state.dataWaterToAirHeatPumpSimple->AirflowErrPointer,
1129 1148 : simpleWatertoAirHP.AirMassFlowRate,
1130 1148 : simpleWatertoAirHP.AirMassFlowRate);
1131 : }
1132 44035 : simpleWatertoAirHP.WaterFlowMode = true;
1133 : } else { // heat pump is off
1134 55774 : simpleWatertoAirHP.WaterFlowMode = false;
1135 55774 : simpleWatertoAirHP.WaterMassFlowRate = 0.0;
1136 55774 : simpleWatertoAirHP.AirMassFlowRate = 0.0;
1137 55774 : if ((simpleWatertoAirHP.WaterCyclingMode) == HVAC::WaterFlow::Constant) {
1138 0 : if (simpleWatertoAirHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit) {
1139 0 : if (simpleWatertoAirHP.CompanionHeatingCoilNum > 0) {
1140 0 : if (state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum).QLoadTotal > 0.0) {
1141 : // do nothing, there will be flow through this coil
1142 0 : } else if (simpleWatertoAirHP.LastOperatingMode == HVAC::Cooling) {
1143 : // set the flow rate to full design flow
1144 0 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate;
1145 : }
1146 : } else {
1147 0 : if (simpleWatertoAirHP.LastOperatingMode == HVAC::Cooling) {
1148 : // set the flow rate to full design flow
1149 0 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate;
1150 : }
1151 : }
1152 0 : } else if (simpleWatertoAirHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit) {
1153 : // It's a heating coil
1154 0 : if (simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
1155 0 : if (state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).QLoadTotal > 0.0) {
1156 : // do nothing, there will be flow through this coil
1157 0 : } else if (simpleWatertoAirHP.LastOperatingMode == HVAC::Heating) {
1158 : // set the flow rate to full design flow
1159 0 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate;
1160 : }
1161 : } else {
1162 0 : if (simpleWatertoAirHP.LastOperatingMode == HVAC::Heating) {
1163 : // set the flow rate to full design flow
1164 0 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate;
1165 : }
1166 : }
1167 : }
1168 : }
1169 : }
1170 :
1171 99809 : PlantUtilities::SetComponentFlowRate(state,
1172 99809 : simpleWatertoAirHP.WaterMassFlowRate,
1173 : simpleWatertoAirHP.WaterInletNodeNum,
1174 : simpleWatertoAirHP.WaterOutletNodeNum,
1175 99809 : simpleWatertoAirHP.plantLoc);
1176 :
1177 99809 : simpleWatertoAirHP.InletAirDBTemp = state.dataLoopNodes->Node(AirInletNode).Temp;
1178 99809 : simpleWatertoAirHP.InletAirHumRat = state.dataLoopNodes->Node(AirInletNode).HumRat;
1179 99809 : simpleWatertoAirHP.InletAirEnthalpy = state.dataLoopNodes->Node(AirInletNode).Enthalpy;
1180 99809 : simpleWatertoAirHP.InletWaterTemp = state.dataLoopNodes->Node(WaterInletNode).Temp;
1181 99809 : simpleWatertoAirHP.InletWaterEnthalpy = state.dataLoopNodes->Node(WaterInletNode).Enthalpy;
1182 99809 : simpleWatertoAirHP.OutletWaterTemp = simpleWatertoAirHP.InletWaterTemp;
1183 99809 : simpleWatertoAirHP.OutletWaterEnthalpy = simpleWatertoAirHP.InletWaterEnthalpy;
1184 :
1185 : // Outlet variables
1186 99809 : simpleWatertoAirHP.Power = 0.0;
1187 99809 : simpleWatertoAirHP.QLoadTotal = 0.0;
1188 99809 : simpleWatertoAirHP.QLoadTotalReport = 0.0;
1189 99809 : simpleWatertoAirHP.QSensible = 0.0;
1190 99809 : simpleWatertoAirHP.QLatent = 0.0;
1191 99809 : simpleWatertoAirHP.QSource = 0.0;
1192 99809 : simpleWatertoAirHP.Energy = 0.0;
1193 99809 : simpleWatertoAirHP.EnergyLoadTotal = 0.0;
1194 99809 : simpleWatertoAirHP.EnergySensible = 0.0;
1195 99809 : simpleWatertoAirHP.EnergyLatent = 0.0;
1196 99809 : simpleWatertoAirHP.EnergySource = 0.0;
1197 99809 : simpleWatertoAirHP.COP = 0.0;
1198 99809 : state.dataHeatBal->HeatReclaimSimple_WAHPCoil(HPNum).AvailCapacity = 0.0;
1199 99809 : }
1200 :
1201 16 : void SizeHVACWaterToAir(EnergyPlusData &state, int const HPNum)
1202 : {
1203 :
1204 : // SUBROUTINE INFORMATION:
1205 : // AUTHOR Richard Raustad, FSEC
1206 : // DATE WRITTEN June 2009
1207 : // MODIFIED August 2013 Daeho Kang, add component sizing table entries
1208 :
1209 : // PURPOSE OF THIS SUBROUTINE:
1210 : // This subroutine is for sizing WSHP Components for which nominal capacities
1211 : // and flow rates have not been specified in the input
1212 :
1213 : // METHODOLOGY EMPLOYED:
1214 : // Obtains heating capacities and flow rates from the zone or system sizing arrays.
1215 :
1216 16 : auto &simpleWatertoAirHP = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum);
1217 :
1218 : // SUBROUTINE PARAMETER DEFINITIONS:
1219 : static constexpr std::string_view RoutineName("SizeWaterToAirCoil");
1220 : static constexpr std::string_view RoutineNameAlt("SizeHVACWaterToAir");
1221 :
1222 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
1223 : Real64 rhoair;
1224 : Real64 MixTemp; // Mixed air temperature at cooling design conditions
1225 : Real64 MixTempSys; // Mixed air temperature at cooling design conditions at system air flow
1226 : Real64 HeatMixTemp; // Mixed air temperature at heating design conditions
1227 : Real64 HeatMixTempSys; // Mixed air temperature at heating design conditions at system air flow
1228 : Real64 MixHumRat; // Mixed air humidity ratio at cooling design conditions
1229 : Real64 MixHumRatSys; // Mixed air humidity ratio at cooling design conditions at system air flow
1230 : Real64 HeatMixHumRat; // Mixed air humidity ratio at heating design conditions
1231 : Real64 HeatMixHumRatSys; // Mixed air humidity ratio at heating design conditions at system air flow
1232 : Real64 MixEnth; // Mixed air enthalpy at cooling design conditions
1233 : Real64 MixEnthSys; // Mixed air enthalpy at cooling design conditions at system air flow
1234 : Real64 MixWetBulb; // Mixed air wet-bulb temperature at cooling design conditions
1235 16 : Real64 RatedMixWetBulb = 0.0; // Rated mixed air wetbulb temperature
1236 16 : Real64 RatedMixDryBulb = 0.0; // Rated mixed air drybulb temperature
1237 16 : Real64 RatedHeatMixDryBulb = 0.0; // Rated mixed air drybulb temperature at heating design conditions
1238 : Real64 SupTemp; // Supply air temperature at cooling design conditions
1239 : Real64 HeatSupTemp; // Supply air temperature at heating design conditions
1240 : Real64 SupHumRat; // Supply air humidity ratio at cooling design conditions
1241 : Real64 SupEnth; // Supply air enthalpy at cooling design conditions
1242 : Real64 OutTemp; // Outdoor aur dry-bulb temperature at cooling design conditions
1243 : Real64 ratioTDB; // Load-side dry-bulb temperature ratio at cooling design conditions
1244 : Real64 HeatratioTDB; // Load-side dry-bulb temperature ratio at heating design conditions
1245 : Real64 ratioTWB; // Load-side wet-bulb temperature ratio at cooling design conditions
1246 : Real64 ratioTS; // Source-side temperature ratio at cooling design conditions
1247 : Real64 HeatratioTS; // Source-side temperature ratio at heating design conditions
1248 : Real64 RatedratioTDB; // Rated cooling load-side dry-bulb temperature ratio
1249 16 : Real64 RatedHeatratioTDB = 0.0; // Rated cooling load-side dry-bulb temperature ratio
1250 : Real64 RatedratioTWB; // Rated cooling load-side wet-bulb temperature ratio
1251 : Real64 RatedratioTS; // Rated cooling source-side temperature ratio
1252 : Real64 RatedHeatratioTS; // Rated heating source-side temperature ratio
1253 : Real64 OutAirFrac; // Outdoor air fraction at cooling design conditions
1254 : Real64 OutAirFracSys; // Outdoor air fraction at cooling design conditions at system air flow
1255 : Real64 HeatOutAirFrac; // Outdoor air fraction at heating design conditions
1256 : Real64 HeatOutAirFracSys; // Outdoor air fraction at heating design conditions at system air flow
1257 : Real64 VolFlowRate;
1258 : Real64 CoolCapAtPeak; // Load on the cooling coil at cooling design conditions
1259 : Real64 HeatCapAtPeak; // Load on the heating coil at heating design conditions
1260 16 : Real64 PeakTotCapTempModFac = 1.0; // Peak total cooling capacity curve modifier
1261 16 : Real64 RatedTotCapTempModFac = 1.0; // Rated total cooling capacity curve modifier
1262 16 : Real64 PeakHeatCapTempModFac = 1.0; // Peak heating capacity curve modifier
1263 : Real64 DesignEntWaterTemp; // Design entering coil water temperature
1264 : Real64 SensCapAtPeak; // Sensible load on the cooling coil at cooling design conditions
1265 16 : Real64 PeakSensCapTempModFac = 1.0; // Peak sensible cooling capacity curve modifier
1266 16 : Real64 RatedSensCapTempModFac = 1.0; // Rated sensible cooling capacity curve modifier
1267 16 : Real64 RatedHeatCapTempModFac = 1.0; // Rated heating capacity curve modifier
1268 16 : Real64 RatedCoolPowerTempModFac = 1.0; // Rated cooling power curve modifier
1269 16 : Real64 RatedHeatPowerTempModFac = 1.0; // Rated heating power curve modifier
1270 : Real64 RatedCapCoolTotalDesCDD; // Rated total cooling coil capacity determined at cooling design conditions
1271 16 : constexpr Real64 Tref(283.15); // Refrence Temperature for performance curves,10C [K]
1272 : int PltSizNum;
1273 : bool RatedCapCoolTotalAutoSized;
1274 : bool RatedCapCoolSensAutoSized;
1275 : bool ErrorsFound;
1276 16 : Real64 SystemCapacity = 0.0;
1277 : Real64 rho;
1278 : Real64 Cp;
1279 : bool IsAutoSize; // Indicator to autosize
1280 : bool HardSizeNoDesRun; // Indicator to hardsize and no sizing run
1281 : Real64 RatedAirVolFlowRateDes; // Autosized rated air flow for reporting
1282 : Real64 CoolingAirVolFlowRateDes; // Cooling desing day air flow
1283 : Real64 HeatingAirVolFlowRateDes; // Heating design day air flow
1284 : Real64 RatedAirVolFlowRateUser; // Hardsized rated air flow for reporting
1285 : Real64 RatedCapCoolTotalDes; // Autosized rated cooling capacity for reporting
1286 : Real64 RatedCapCoolTotalUser; // Hardsized rated cooling capacity for reporting
1287 : Real64 RatedCapCoolSensDes; // Autosized rated sensible cooling capacity for reporting
1288 : Real64 RatedCapCoolSensUser; // Hardsized rated sensible cooling capacity for reporting
1289 : Real64 RatedCapHeatDes; // Autosized rated heating capacity for reporting
1290 : Real64 RatedCapHeatUser; // Hardsized rated heating capacity for reporting
1291 : Real64 RatedWaterVolFlowRateDes; // Autosized rated water flow rate for reporting
1292 : Real64 RatedWaterVolFlowRateUser; // Hardsized rated water flow rate for reporting
1293 : Real64 RatedCapCoolHeatDD; // Rated cooling coil capacity based on heating design conditions
1294 : bool SizingDesRunThisAirSys; // true if a particular air system had a Sizing:System object and system sizing done
1295 : bool SizingDesRunThisZone; // true if a particular zone had a Sizing:Zone object and zone sizing was done
1296 16 : Real64 HeatdTratio = 1.0; // Temperature difference across coil adjustment factor
1297 16 : Real64 dHratio = 1.0; // Enthalpy difference across coil adjustment factor
1298 : Real64 HeatOAFrac; // Outdoor air fraction at heating design conditions
1299 : Real64 HeatOAFracSys; // Outdoor air fraction at heating design conditions at system air flow
1300 : Real64 HeatOATemp; // Outdoor air temperature at heating design conditions
1301 : Real64 OAFrac; // Outdooor air fraction
1302 : Real64 OAFracSys; // Outdoor air fraction at system air flow
1303 : Real64 OATemp; // Outdoor air temperature at cooling design conditions
1304 : Real64 OAHumRat; // Humidity ratio at cooling design conditions
1305 :
1306 16 : ErrorsFound = false;
1307 16 : IsAutoSize = false;
1308 16 : if (state.dataSize->SysSizingRunDone || state.dataSize->ZoneSizingRunDone) {
1309 7 : HardSizeNoDesRun = false;
1310 : } else {
1311 9 : HardSizeNoDesRun = true;
1312 : }
1313 16 : if (state.dataSize->CurSysNum > 0) {
1314 0 : CheckThisAirSystemForSizing(state, state.dataSize->CurSysNum, SizingDesRunThisAirSys);
1315 : } else {
1316 16 : SizingDesRunThisAirSys = false;
1317 : }
1318 16 : if (state.dataSize->CurZoneEqNum > 0) {
1319 9 : CheckThisZoneForSizing(state, state.dataSize->CurZoneEqNum, SizingDesRunThisZone);
1320 : } else {
1321 7 : SizingDesRunThisZone = false;
1322 : }
1323 16 : RatedAirVolFlowRateDes = 0.0;
1324 16 : RatedAirVolFlowRateUser = 0.0;
1325 16 : CoolingAirVolFlowRateDes = 0.0;
1326 16 : HeatingAirVolFlowRateDes = 0.0;
1327 16 : RatedCapCoolTotalDes = 0.0;
1328 16 : RatedCapCoolTotalUser = 0.0;
1329 16 : RatedCapCoolSensDes = 0.0;
1330 16 : RatedCapCoolSensUser = 0.0;
1331 16 : RatedCapHeatDes = 0.0;
1332 16 : RatedCapHeatUser = 0.0;
1333 16 : RatedWaterVolFlowRateDes = 0.0;
1334 16 : RatedWaterVolFlowRateUser = 0.0;
1335 16 : std::string CompType = format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]);
1336 :
1337 16 : if (simpleWatertoAirHP.RatedAirVolFlowRate == DataSizing::AutoSize) {
1338 7 : IsAutoSize = true;
1339 : }
1340 16 : if (state.dataSize->CurSysNum > 0) {
1341 0 : if (!IsAutoSize && !SizingDesRunThisAirSys) { // Simulation continue
1342 0 : HardSizeNoDesRun = true;
1343 0 : if (simpleWatertoAirHP.RatedAirVolFlowRate > 0.0) {
1344 0 : BaseSizer::reportSizerOutput(
1345 : state,
1346 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1347 : simpleWatertoAirHP.Name,
1348 : "User-Specified Rated Air Flow Rate [m3/s]",
1349 : simpleWatertoAirHP.RatedAirVolFlowRate);
1350 : }
1351 : } else {
1352 0 : CheckSysSizing(state,
1353 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1354 0 : simpleWatertoAirHP.Name);
1355 0 : if (state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow >= HVAC::SmallAirVolFlow) {
1356 0 : RatedAirVolFlowRateDes = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow;
1357 0 : CoolingAirVolFlowRateDes = state.dataSize->CalcSysSizing(state.dataSize->CurSysNum).DesCoolVolFlow;
1358 0 : HeatingAirVolFlowRateDes = state.dataSize->CalcSysSizing(state.dataSize->CurSysNum).DesHeatVolFlow;
1359 : } else {
1360 0 : RatedAirVolFlowRateDes = 0.0;
1361 : }
1362 : }
1363 16 : } else if (state.dataSize->CurZoneEqNum > 0) {
1364 9 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
1365 2 : HardSizeNoDesRun = true;
1366 2 : if (simpleWatertoAirHP.RatedAirVolFlowRate > 0.0) {
1367 6 : BaseSizer::reportSizerOutput(
1368 : state,
1369 4 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1370 : simpleWatertoAirHP.Name,
1371 : "User-Specified Rated Air Flow Rate [m3/s]",
1372 : simpleWatertoAirHP.RatedAirVolFlowRate);
1373 : }
1374 : } else {
1375 14 : CheckZoneSizing(state,
1376 14 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1377 : simpleWatertoAirHP.Name);
1378 7 : RatedAirVolFlowRateDes = max(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow,
1379 7 : state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatVolFlow);
1380 7 : CoolingAirVolFlowRateDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow;
1381 7 : HeatingAirVolFlowRateDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatVolFlow;
1382 7 : if (RatedAirVolFlowRateDes < HVAC::SmallAirVolFlow) {
1383 0 : RatedAirVolFlowRateDes = 0.0;
1384 : }
1385 : }
1386 : }
1387 16 : if (!HardSizeNoDesRun) {
1388 7 : if (IsAutoSize) {
1389 7 : simpleWatertoAirHP.RatedAirVolFlowRate = RatedAirVolFlowRateDes;
1390 21 : BaseSizer::reportSizerOutput(
1391 : state,
1392 14 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1393 : simpleWatertoAirHP.Name,
1394 : "Design Size Rated Air Flow Rate [m3/s]",
1395 : RatedAirVolFlowRateDes);
1396 : } else {
1397 0 : if (simpleWatertoAirHP.RatedAirVolFlowRate > 0.0 && RatedAirVolFlowRateDes > 0.0) {
1398 0 : RatedAirVolFlowRateUser = simpleWatertoAirHP.RatedAirVolFlowRate;
1399 0 : BaseSizer::reportSizerOutput(
1400 : state,
1401 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1402 : simpleWatertoAirHP.Name,
1403 : "Design Size Rated Air Flow Rate [m3/s]",
1404 : RatedAirVolFlowRateDes,
1405 : "User-Specified Rated Air Flow Rate [m3/s]",
1406 : RatedAirVolFlowRateUser);
1407 0 : if (state.dataGlobal->DisplayExtraWarnings) {
1408 0 : if ((std::abs(RatedAirVolFlowRateDes - RatedAirVolFlowRateUser) / RatedAirVolFlowRateUser) >
1409 0 : state.dataSize->AutoVsHardSizingThreshold) {
1410 0 : ShowMessage(
1411 : state,
1412 0 : format("SizeHVACWaterToAir: Potential issue with equipment sizing for coil {}:WATERTOAIRHEATPUMP:EQUATIONFIT \"{}\"",
1413 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
1414 0 : simpleWatertoAirHP.Name));
1415 0 : ShowContinueError(state, format("User-Specified Rated Air Volume Flow Rate of {:.5R} [m3/s]", RatedAirVolFlowRateUser));
1416 0 : ShowContinueError(state,
1417 0 : format("differs from Design Size Rated Air Volume Flow Rate of {:.5R} [m3/s]", RatedAirVolFlowRateDes));
1418 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
1419 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
1420 : }
1421 : }
1422 : }
1423 : }
1424 : }
1425 :
1426 16 : RatedCapCoolTotalAutoSized = false;
1427 16 : RatedCapCoolSensAutoSized = false;
1428 :
1429 16 : Real64 FanCoolLoad = 0.0;
1430 16 : Real64 FanHeatLoad = FanCoolLoad;
1431 16 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
1432 : // size rated total cooling capacity
1433 9 : if (simpleWatertoAirHP.RatedCapCoolTotal == DataSizing::AutoSize) {
1434 4 : RatedCapCoolTotalAutoSized = true;
1435 : }
1436 9 : if (SizingDesRunThisAirSys || SizingDesRunThisZone) {
1437 1 : HardSizeNoDesRun = false;
1438 : }
1439 9 : if (state.dataSize->CurSysNum > 0) {
1440 0 : if (!RatedCapCoolTotalAutoSized && !SizingDesRunThisAirSys) { // Simulation continue
1441 0 : HardSizeNoDesRun = true;
1442 0 : if (simpleWatertoAirHP.RatedCapCoolTotal > 0.0) {
1443 0 : BaseSizer::reportSizerOutput(
1444 : state,
1445 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1446 : simpleWatertoAirHP.Name,
1447 : "User-Specified Rated Total Cooling Capacity [W]",
1448 : simpleWatertoAirHP.RatedCapCoolTotal);
1449 : }
1450 : } else {
1451 0 : CheckSysSizing(
1452 : state,
1453 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1454 0 : simpleWatertoAirHP.Name);
1455 0 : if (CoolingAirVolFlowRateDes > 0.0) {
1456 0 : VolFlowRate = CoolingAirVolFlowRateDes;
1457 : } else {
1458 0 : VolFlowRate = HeatingAirVolFlowRateDes; // system air flow
1459 : }
1460 : // cooling design day calculations
1461 0 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
1462 0 : auto const &finalSysSizing = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum);
1463 0 : if (state.dataSize->CurOASysNum > 0) { // coil is in the OA stream
1464 0 : MixTemp = finalSysSizing.OutTempAtCoolPeak;
1465 0 : MixHumRat = finalSysSizing.OutHumRatAtCoolPeak;
1466 0 : SupTemp = finalSysSizing.PrecoolTemp;
1467 0 : SupHumRat = finalSysSizing.PrecoolHumRat;
1468 0 : MixTempSys = MixTemp;
1469 0 : MixHumRatSys = MixHumRat;
1470 : } else { // coil is on the main air loop
1471 0 : SupTemp = finalSysSizing.CoolSupTemp;
1472 0 : SupHumRat = finalSysSizing.CoolSupHumRat;
1473 0 : if (VolFlowRate > 0.0) {
1474 0 : OutAirFrac = finalSysSizing.DesOutAirVolFlow / VolFlowRate;
1475 0 : OutAirFracSys = finalSysSizing.DesOutAirVolFlow / RatedAirVolFlowRateDes;
1476 : } else {
1477 0 : OutAirFrac = 1.0;
1478 0 : OutAirFracSys = OutAirFrac;
1479 : }
1480 0 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
1481 0 : OutAirFracSys = min(1.0, max(0.0, OutAirFracSys));
1482 0 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).NumOACoolCoils ==
1483 : 0) { // there is no precooling of the OA stream
1484 0 : MixTemp = finalSysSizing.MixTempAtCoolPeak;
1485 0 : MixHumRat = finalSysSizing.MixHumRatAtCoolPeak;
1486 : // calculate mixed air temperature with system airflow
1487 0 : MixTempSys =
1488 0 : OutAirFracSys * finalSysSizing.OutTempAtCoolPeak + (1.0 - OutAirFracSys) * finalSysSizing.RetTempAtCoolPeak;
1489 0 : MixHumRatSys =
1490 0 : OutAirFracSys * finalSysSizing.OutHumRatAtCoolPeak + (1.0 - OutAirFracSys) * finalSysSizing.RetHumRatAtCoolPeak;
1491 : } else { // there is precooling of OA stream
1492 0 : MixTemp = OutAirFrac * finalSysSizing.PrecoolTemp + (1.0 - OutAirFrac) * finalSysSizing.RetTempAtCoolPeak;
1493 0 : MixHumRat = OutAirFrac * finalSysSizing.PrecoolHumRat + (1.0 - OutAirFrac) * finalSysSizing.RetHumRatAtCoolPeak;
1494 : // calculate mixed air temperature with system airflow
1495 0 : MixTempSys = OutAirFracSys * finalSysSizing.PrecoolTemp + (1.0 - OutAirFracSys) * finalSysSizing.RetTempAtCoolPeak;
1496 0 : MixHumRatSys =
1497 0 : OutAirFracSys * finalSysSizing.PrecoolHumRat + (1.0 - OutAirFracSys) * finalSysSizing.RetHumRatAtCoolPeak;
1498 : }
1499 : }
1500 : // supply air condition is capped with that of mixed air to avoid SHR > 1.0
1501 0 : SupTemp = min(MixTemp, SupTemp);
1502 0 : SupHumRat = min(MixHumRat, SupHumRat);
1503 0 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, MixTemp, MixHumRat, RoutineName);
1504 0 : MixEnth = Psychrometrics::PsyHFnTdbW(MixTemp, MixHumRat);
1505 0 : MixEnthSys = Psychrometrics::PsyHFnTdbW(MixTempSys, MixHumRatSys);
1506 0 : SupEnth = Psychrometrics::PsyHFnTdbW(SupTemp, SupHumRat);
1507 : // determine the coil ratio of coil dT with system air flow to design heating air flow
1508 0 : dHratio = (SupEnth - MixEnthSys) / (SupEnth - MixEnth);
1509 0 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid && state.dataSize->DataFanIndex > 0) { // add fan heat to coil load
1510 0 : FanCoolLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
1511 :
1512 0 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(MixHumRat);
1513 0 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace == HVAC::FanPlace::BlowThru) {
1514 0 : MixTemp += FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature entering the coil
1515 0 : } else if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace ==
1516 : HVAC::FanPlace::DrawThru) {
1517 0 : SupTemp -= FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature leaving the coil
1518 : }
1519 : }
1520 0 : CoolCapAtPeak = (rhoair * VolFlowRate * (MixEnth - SupEnth)) +
1521 : FanCoolLoad; // load on the cooling coil which includes ventilation load and fan heat
1522 0 : CoolCapAtPeak = max(0.0, CoolCapAtPeak);
1523 0 : MixWetBulb = Psychrometrics::PsyTwbFnTdbWPb(state, MixTemp, MixHumRat, state.dataEnvrn->StdBaroPress, RoutineName);
1524 0 : RatedMixWetBulb = simpleWatertoAirHP.RatedEntAirWetbulbTemp;
1525 : // calculate temperatue ratio at design day peak conditions
1526 0 : ratioTWB = (MixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1527 0 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
1528 : state,
1529 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1530 : simpleWatertoAirHP.Name,
1531 : simpleWatertoAirHP.WaterInletNodeNum,
1532 : simpleWatertoAirHP.WaterOutletNodeNum,
1533 : ErrorsFound,
1534 : false);
1535 0 : if (PltSizNum > 0) {
1536 0 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
1537 0 : ratioTS = (DesignEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1538 : } else {
1539 0 : ShowSevereError(state, "Autosizing of total cooling capacity requires a loop Sizing:Plant object");
1540 0 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
1541 0 : ShowContinueError(state,
1542 0 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
1543 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
1544 0 : simpleWatertoAirHP.Name));
1545 0 : ratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
1546 0 : ErrorsFound = true;
1547 : }
1548 : // calculate temperatue ratio at rated conditions
1549 0 : RatedratioTWB = (RatedMixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1550 0 : RatedratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1551 : // determine curve modifiers at peak and rated conditions
1552 0 : PeakTotCapTempModFac = simpleWatertoAirHP.TotalCoolCapCurve->value(state, ratioTWB, ratioTS, 1.0, 1.0);
1553 0 : RatedTotCapTempModFac = simpleWatertoAirHP.TotalCoolCapCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
1554 0 : RatedCoolPowerTempModFac = simpleWatertoAirHP.CoolPowCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
1555 : // calculate the rated total capacity based on peak conditions
1556 : // note: the rated total capacity can be different than the total capacity at
1557 : // rated conditions if the capacity curve isn't normalized at the rated
1558 : // conditions
1559 0 : RatedCapCoolTotalDes = (PeakTotCapTempModFac > 0.0) ? CoolCapAtPeak / PeakTotCapTempModFac : CoolCapAtPeak;
1560 : // reporting
1561 0 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirTemp(
1562 0 : state, simpleWatertoAirHP.Name, CompType, MixTemp, state.dataSize->CurSysNum, state.dataSize->CurZoneEqNum);
1563 0 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirHumRat(state, simpleWatertoAirHP.Name, CompType, MixHumRat);
1564 0 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirTemp(state, simpleWatertoAirHP.Name, CompType, SupTemp);
1565 0 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirHumRat(state, simpleWatertoAirHP.Name, CompType, SupHumRat);
1566 : } else {
1567 0 : RatedCapCoolTotalDes = 0.0;
1568 : }
1569 : }
1570 9 : } else if (state.dataSize->CurZoneEqNum > 0) {
1571 5 : if (!RatedCapCoolTotalAutoSized && !SizingDesRunThisZone) { // Simulation continue
1572 1 : HardSizeNoDesRun = true;
1573 1 : if (simpleWatertoAirHP.RatedCapCoolTotal > 0.0) {
1574 3 : BaseSizer::reportSizerOutput(
1575 : state,
1576 2 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1577 : simpleWatertoAirHP.Name,
1578 : "User-Specified Rated Total Cooling Capacity [W]",
1579 : simpleWatertoAirHP.RatedCapCoolTotal);
1580 : }
1581 : } else {
1582 8 : CheckZoneSizing(
1583 : state,
1584 8 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1585 : simpleWatertoAirHP.Name);
1586 4 : if (CoolingAirVolFlowRateDes > 0.0) {
1587 4 : VolFlowRate = CoolingAirVolFlowRateDes;
1588 : } else {
1589 0 : VolFlowRate = HeatingAirVolFlowRateDes; // system air flow
1590 : }
1591 4 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
1592 : // cooling design calculations
1593 4 : if (state.dataSize->ZoneEqDXCoil) {
1594 4 : if (state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow > 0.0) {
1595 0 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp;
1596 0 : MixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInHumRat;
1597 : // calculate mixed air temperature and humidity with system airflow
1598 0 : OAFrac = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA / CoolingAirVolFlowRateDes;
1599 0 : OAFracSys = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA / RatedAirVolFlowRateDes;
1600 0 : OATemp = (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp -
1601 0 : (1.0 - OAFrac) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneTempAtCoolPeak) /
1602 : OAFrac;
1603 0 : OAHumRat = (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInHumRat -
1604 0 : (1.0 - OAFrac) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneHumRatAtHeatPeak) /
1605 : OAFrac;
1606 0 : MixTempSys = OAFracSys * OATemp +
1607 0 : (1.0 - OAFracSys) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneTempAtCoolPeak;
1608 0 : MixHumRatSys = OAFracSys * OAHumRat +
1609 0 : (1.0 - OAFracSys) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneHumRatAtHeatPeak;
1610 : } else {
1611 4 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneRetTempAtCoolPeak;
1612 4 : MixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneHumRatAtCoolPeak;
1613 4 : MixTempSys = MixTemp;
1614 4 : MixHumRatSys = MixHumRat;
1615 : }
1616 : } else {
1617 0 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp;
1618 0 : MixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInHumRat;
1619 0 : MixTempSys = MixTemp;
1620 0 : MixHumRatSys = MixHumRat;
1621 : }
1622 4 : SupTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDesTemp;
1623 4 : SupHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDesHumRat;
1624 : // supply air condition is capped with that of mixed air to avoid SHR > 1.0
1625 4 : SupTemp = min(MixTemp, SupTemp);
1626 4 : SupHumRat = min(MixHumRat, SupHumRat);
1627 4 : int TimeStepNumAtMax = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).TimeStepNumAtCoolMax;
1628 4 : int DDNum = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDDNum;
1629 4 : if (DDNum > 0 && TimeStepNumAtMax > 0) {
1630 4 : OutTemp = state.dataSize->DesDayWeath(DDNum).Temp(TimeStepNumAtMax);
1631 : } else {
1632 0 : OutTemp = 0.0;
1633 : }
1634 4 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, MixTemp, MixHumRat, RoutineName);
1635 4 : MixEnth = Psychrometrics::PsyHFnTdbW(MixTemp, MixHumRat);
1636 4 : MixEnthSys = Psychrometrics::PsyHFnTdbW(MixTempSys, MixHumRatSys);
1637 4 : SupEnth = Psychrometrics::PsyHFnTdbW(SupTemp, SupHumRat);
1638 : // determine the coil ratio of coil dH with system air flow to design heating air flow
1639 4 : dHratio = (SupEnth - MixEnthSys) / (SupEnth - MixEnth);
1640 4 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid && state.dataSize->DataFanIndex > 0) { // add fan heat to coil load
1641 1 : FanCoolLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
1642 :
1643 1 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(MixHumRat);
1644 1 : if (state.dataSize->DataFanPlacement == HVAC::FanPlace::BlowThru) {
1645 1 : MixTemp += FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature entering the coil
1646 : } else {
1647 0 : SupTemp -= FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature leaving the coil
1648 : }
1649 : }
1650 4 : CoolCapAtPeak = (rhoair * VolFlowRate * (MixEnth - SupEnth)) +
1651 : FanCoolLoad; // load on the cooling coil which includes ventilation load and fan heat
1652 4 : CoolCapAtPeak = max(0.0, CoolCapAtPeak);
1653 4 : MixWetBulb = Psychrometrics::PsyTwbFnTdbWPb(state, MixTemp, MixHumRat, state.dataEnvrn->StdBaroPress, RoutineName);
1654 4 : RatedMixWetBulb = simpleWatertoAirHP.RatedEntAirWetbulbTemp;
1655 : // calculate temperatue ratio at design day peak conditions
1656 4 : ratioTWB = (MixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1657 8 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
1658 : state,
1659 8 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1660 : simpleWatertoAirHP.Name,
1661 : simpleWatertoAirHP.WaterInletNodeNum,
1662 : simpleWatertoAirHP.WaterOutletNodeNum,
1663 : ErrorsFound,
1664 : false);
1665 4 : if (PltSizNum > 0) {
1666 3 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
1667 3 : ratioTS = (DesignEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1668 : } else {
1669 2 : ShowSevereError(state, "Autosizing of total cooling capacity requires a loop Sizing:Plant object");
1670 2 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
1671 2 : ShowContinueError(state,
1672 2 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
1673 1 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
1674 1 : simpleWatertoAirHP.Name));
1675 1 : ratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
1676 1 : ErrorsFound = true;
1677 : }
1678 : // calculate temperatue ratio at rated conditions
1679 4 : RatedratioTWB = (RatedMixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1680 4 : RatedratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1681 : // determine curve modifiers at peak and rated conditions
1682 4 : PeakTotCapTempModFac = simpleWatertoAirHP.TotalCoolCapCurve->value(state, ratioTWB, ratioTS, 1.0, 1.0);
1683 4 : RatedTotCapTempModFac = simpleWatertoAirHP.TotalCoolCapCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
1684 4 : RatedCoolPowerTempModFac = simpleWatertoAirHP.CoolPowCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
1685 : // calculate the rated total capacity based on peak conditions
1686 : // note: the rated total capacity can be different than the total capacity at
1687 : // rated conditions if the capacity curve isn't normalized at the rated
1688 : // conditions
1689 4 : RatedCapCoolTotalDes = (PeakTotCapTempModFac > 0.0) ? CoolCapAtPeak / PeakTotCapTempModFac : CoolCapAtPeak;
1690 : // reporting
1691 4 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirTemp(
1692 4 : state, simpleWatertoAirHP.Name, CompType, MixTemp, state.dataSize->CurSysNum, state.dataSize->CurZoneEqNum);
1693 4 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirHumRat(state, simpleWatertoAirHP.Name, CompType, MixHumRat);
1694 4 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirTemp(state, simpleWatertoAirHP.Name, CompType, SupTemp);
1695 4 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirHumRat(state, simpleWatertoAirHP.Name, CompType, SupHumRat);
1696 : } else {
1697 0 : RatedCapCoolTotalDes = 0.0;
1698 : }
1699 : }
1700 5 : if (RatedCapCoolTotalDes < HVAC::SmallLoad) {
1701 1 : RatedCapCoolTotalDes = 0.0;
1702 : }
1703 : }
1704 : // size rated sensible cooling capacity
1705 9 : if (simpleWatertoAirHP.RatedCapCoolSens == DataSizing::AutoSize && simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
1706 4 : RatedCapCoolSensAutoSized = true;
1707 : }
1708 9 : if (SizingDesRunThisAirSys || SizingDesRunThisZone) {
1709 1 : HardSizeNoDesRun = false;
1710 : }
1711 9 : if (state.dataSize->CurSysNum > 0) {
1712 0 : if (!RatedCapCoolSensAutoSized && !SizingDesRunThisAirSys) { // Simulation continue
1713 0 : HardSizeNoDesRun = true;
1714 0 : if (simpleWatertoAirHP.RatedCapCoolSens > 0.0) {
1715 0 : BaseSizer::reportSizerOutput(
1716 : state,
1717 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1718 : simpleWatertoAirHP.Name,
1719 : "User-Specified Rated Sensible Cooling Capacity [W]",
1720 : simpleWatertoAirHP.RatedCapCoolSens);
1721 : }
1722 : } else {
1723 0 : CheckSysSizing(
1724 : state,
1725 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1726 0 : simpleWatertoAirHP.Name);
1727 0 : if (CoolingAirVolFlowRateDes > 0.0) {
1728 0 : VolFlowRate = CoolingAirVolFlowRateDes;
1729 : } else {
1730 0 : VolFlowRate = HeatingAirVolFlowRateDes; // system air flow
1731 : }
1732 0 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
1733 0 : auto const &finalSysSizing = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum);
1734 0 : if (state.dataSize->CurOASysNum > 0) { // coil is in the OA stream
1735 0 : MixTemp = finalSysSizing.OutTempAtCoolPeak;
1736 0 : MixHumRat = finalSysSizing.OutHumRatAtCoolPeak;
1737 0 : SupTemp = finalSysSizing.PrecoolTemp;
1738 0 : SupHumRat = finalSysSizing.PrecoolHumRat;
1739 : } else { // coil is on the main air loop
1740 0 : SupTemp = finalSysSizing.CoolSupTemp;
1741 0 : SupHumRat = finalSysSizing.CoolSupHumRat;
1742 0 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).NumOACoolCoils ==
1743 : 0) { // there is no precooling of the OA stream
1744 0 : MixTemp = finalSysSizing.MixTempAtCoolPeak;
1745 0 : MixHumRat = finalSysSizing.MixHumRatAtCoolPeak;
1746 : } else { // there is precooling of OA stream
1747 0 : if (VolFlowRate > 0.0) {
1748 0 : OutAirFrac = finalSysSizing.DesOutAirVolFlow / VolFlowRate;
1749 : } else {
1750 0 : OutAirFrac = 1.0;
1751 : }
1752 0 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
1753 0 : MixTemp = OutAirFrac * finalSysSizing.PrecoolTemp + (1.0 - OutAirFrac) * finalSysSizing.RetTempAtCoolPeak;
1754 0 : MixHumRat = OutAirFrac * finalSysSizing.PrecoolHumRat + (1.0 - OutAirFrac) * finalSysSizing.RetHumRatAtCoolPeak;
1755 : }
1756 : }
1757 : // supply air condition is capped with that of mixed air to avoid SHR > 1.0
1758 0 : SupTemp = min(MixTemp, SupTemp);
1759 0 : SupHumRat = min(MixHumRat, SupHumRat);
1760 0 : OutTemp = finalSysSizing.OutTempAtCoolPeak;
1761 0 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, MixTemp, MixHumRat, RoutineName);
1762 0 : MixEnth = Psychrometrics::PsyHFnTdbW(MixTemp, MixHumRat);
1763 0 : SupEnth = Psychrometrics::PsyHFnTdbW(SupTemp, MixHumRat);
1764 0 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid && state.dataSize->DataFanIndex > 0) { // add fan heat to coil load
1765 0 : FanCoolLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
1766 :
1767 0 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(MixHumRat);
1768 0 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace == HVAC::FanPlace::BlowThru) {
1769 0 : MixTemp += FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature entering the coil
1770 0 : } else if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace ==
1771 : HVAC::FanPlace::DrawThru) {
1772 0 : SupTemp -= FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature leaving the coil
1773 : }
1774 : }
1775 : // Sensible capacity is calculated from enthalpy difference with constant humidity ratio, i.e.,
1776 : // there is only temperature difference between entering and leaving air enthalpy. Previously
1777 : // it was calculated using m.cp.dT
1778 0 : SensCapAtPeak = (rhoair * VolFlowRate * (MixEnth - SupEnth)) +
1779 : FanCoolLoad; // load on the cooling coil which includes ventilation load and fan heat (sensible)
1780 0 : SensCapAtPeak = max(0.0, SensCapAtPeak);
1781 0 : MixWetBulb = Psychrometrics::PsyTwbFnTdbWPb(state, MixTemp, MixHumRat, state.dataEnvrn->StdBaroPress, RoutineName);
1782 0 : RatedMixWetBulb = simpleWatertoAirHP.RatedEntAirWetbulbTemp;
1783 0 : RatedMixDryBulb = simpleWatertoAirHP.RatedEntAirDrybulbTemp;
1784 : // calculate temperature ratios at design day peak conditions
1785 0 : ratioTDB = (MixTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1786 0 : ratioTWB = (MixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1787 0 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
1788 : state,
1789 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1790 : simpleWatertoAirHP.Name,
1791 : simpleWatertoAirHP.WaterInletNodeNum,
1792 : simpleWatertoAirHP.WaterOutletNodeNum,
1793 : ErrorsFound,
1794 : false);
1795 0 : if (PltSizNum > 0) {
1796 0 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
1797 0 : ratioTS = (DesignEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1798 : } else {
1799 0 : ShowSevereError(state, "Autosizing of sensible cooling capacity requires a loop Sizing:Plant object");
1800 0 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
1801 0 : ShowContinueError(state,
1802 0 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
1803 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
1804 0 : simpleWatertoAirHP.Name));
1805 0 : ErrorsFound = true;
1806 : }
1807 : // calculate temperatue ratio at rated conditions
1808 0 : RatedratioTDB = (RatedMixDryBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1809 0 : RatedratioTWB = (RatedMixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1810 0 : RatedratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1811 : // determine curve modifiers at peak and rated conditions
1812 0 : PeakSensCapTempModFac = simpleWatertoAirHP.SensCoolCapCurve->value(state, ratioTDB, ratioTWB, ratioTS, 1.0, 1.0);
1813 0 : RatedSensCapTempModFac =
1814 0 : simpleWatertoAirHP.SensCoolCapCurve->value(state, RatedratioTDB, RatedratioTWB, RatedratioTS, 1.0, 1.0);
1815 : // calculate the rated sensible capacity based on peak conditions
1816 : // note: the rated sensible capacity can be different than the sensible capacity
1817 : // at rated conditions if the capacity curve isn't normalized at the rated
1818 : // conditions
1819 0 : RatedCapCoolSensDes = (PeakSensCapTempModFac > 0.0) ? SensCapAtPeak / PeakSensCapTempModFac : SensCapAtPeak;
1820 : } else {
1821 0 : RatedCapCoolSensDes = 0.0;
1822 : }
1823 : }
1824 9 : } else if (state.dataSize->CurZoneEqNum > 0) {
1825 5 : if (!RatedCapCoolSensAutoSized && !SizingDesRunThisZone) { // Simulation continue
1826 1 : HardSizeNoDesRun = true;
1827 1 : if (simpleWatertoAirHP.RatedCapCoolSens > 0.0) {
1828 3 : BaseSizer::reportSizerOutput(
1829 : state,
1830 2 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1831 : simpleWatertoAirHP.Name,
1832 : "User-Specified Rated Sensible Cooling Capacity [W]",
1833 : simpleWatertoAirHP.RatedCapCoolSens);
1834 : }
1835 : } else {
1836 8 : CheckZoneSizing(
1837 : state,
1838 8 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1839 : simpleWatertoAirHP.Name);
1840 4 : if (CoolingAirVolFlowRateDes > 0.0) {
1841 4 : VolFlowRate = CoolingAirVolFlowRateDes;
1842 : } else {
1843 0 : VolFlowRate = HeatingAirVolFlowRateDes; // system air flow
1844 : }
1845 4 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
1846 4 : if (state.dataSize->ZoneEqDXCoil) {
1847 4 : if (state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow > 0.0) {
1848 0 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp;
1849 0 : MixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInHumRat;
1850 : } else {
1851 4 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneRetTempAtCoolPeak;
1852 4 : MixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneHumRatAtCoolPeak;
1853 : }
1854 : } else {
1855 0 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp;
1856 0 : MixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInHumRat;
1857 : }
1858 4 : SupTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDesTemp;
1859 4 : SupHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDesHumRat;
1860 : // supply air condition is capped with that of mixed air to avoid SHR > 1.0
1861 4 : SupTemp = min(MixTemp, SupTemp);
1862 4 : SupHumRat = min(MixHumRat, SupHumRat);
1863 4 : int TimeStepNumAtMax = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).TimeStepNumAtCoolMax;
1864 4 : int DDNum = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDDNum;
1865 4 : if (DDNum > 0 && TimeStepNumAtMax > 0) {
1866 4 : OutTemp = state.dataSize->DesDayWeath(DDNum).Temp(TimeStepNumAtMax);
1867 : } else {
1868 0 : OutTemp = 0.0;
1869 : }
1870 4 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, MixTemp, MixHumRat, RoutineName);
1871 4 : MixEnth = Psychrometrics::PsyHFnTdbW(MixTemp, MixHumRat);
1872 4 : SupEnth = Psychrometrics::PsyHFnTdbW(SupTemp, MixHumRat);
1873 4 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid && state.dataSize->DataFanIndex > 0) { // add fan heat to coil load
1874 1 : FanCoolLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
1875 :
1876 1 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(MixHumRat);
1877 1 : if (state.dataSize->DataFanPlacement == HVAC::FanPlace::BlowThru) {
1878 1 : MixTemp += FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature entering the coil
1879 : } else {
1880 0 : SupTemp -= FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature leaving the coil
1881 : }
1882 : }
1883 : // Sensible capacity is calculated from enthalpy difference with constant humidity ratio, i.e.,
1884 : // there is only temperature difference between entering and leaving air enthalpy. Previously
1885 : // it was calculated using m.cp.dT
1886 4 : SensCapAtPeak = (rhoair * VolFlowRate * (MixEnth - SupEnth)) +
1887 : FanCoolLoad; // load on the cooling coil which includes ventilation load and fan heat (sensible)
1888 4 : SensCapAtPeak = max(0.0, SensCapAtPeak);
1889 4 : MixWetBulb = Psychrometrics::PsyTwbFnTdbWPb(state, MixTemp, MixHumRat, state.dataEnvrn->StdBaroPress, RoutineName);
1890 4 : RatedMixWetBulb = simpleWatertoAirHP.RatedEntAirWetbulbTemp;
1891 4 : RatedMixDryBulb = simpleWatertoAirHP.RatedEntAirDrybulbTemp;
1892 : // calculate temperature ratios at design day peak conditions
1893 4 : ratioTDB = (MixTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1894 4 : ratioTWB = (MixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1895 8 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
1896 : state,
1897 8 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1898 : simpleWatertoAirHP.Name,
1899 : simpleWatertoAirHP.WaterInletNodeNum,
1900 : simpleWatertoAirHP.WaterOutletNodeNum,
1901 : ErrorsFound,
1902 : false);
1903 4 : if (PltSizNum > 0) {
1904 3 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
1905 3 : ratioTS = (DesignEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1906 : } else {
1907 2 : ShowSevereError(state, "Autosizing of sensible cooling capacity requires a loop Sizing:Plant object");
1908 2 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
1909 2 : ShowContinueError(state,
1910 2 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
1911 1 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
1912 1 : simpleWatertoAirHP.Name));
1913 1 : ErrorsFound = true;
1914 : }
1915 : // calculate temperatue ratio at rated conditions
1916 4 : RatedratioTDB = (RatedMixDryBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1917 4 : RatedratioTWB = (RatedMixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1918 4 : RatedratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1919 4 : PeakSensCapTempModFac = simpleWatertoAirHP.SensCoolCapCurve->value(state, ratioTDB, ratioTWB, ratioTS, 1.0, 1.0);
1920 4 : RatedSensCapTempModFac =
1921 4 : simpleWatertoAirHP.SensCoolCapCurve->value(state, RatedratioTDB, RatedratioTWB, RatedratioTS, 1.0, 1.0);
1922 : // Check curve output when rated mixed air wetbulb is the design mixed air wetbulb
1923 : // calculate the rated sensible capacity based on peak conditions
1924 : // note: the rated sensible capacity can be different than the sensible capacity
1925 : // at rated conditions if the capacity curve isn't normalized at the rated
1926 : // conditions
1927 4 : RatedCapCoolSensDes = (PeakSensCapTempModFac > 0.0) ? SensCapAtPeak / PeakSensCapTempModFac : SensCapAtPeak;
1928 : } else {
1929 0 : RatedCapCoolSensDes = 0.0;
1930 : }
1931 : }
1932 : }
1933 9 : if (RatedCapCoolSensDes < HVAC::SmallLoad) {
1934 5 : RatedCapCoolSensDes = 0.0;
1935 : }
1936 9 : if (RatedCapCoolTotalAutoSized && RatedCapCoolSensAutoSized) {
1937 4 : if (RatedCapCoolSensDes > RatedCapCoolTotalDes) {
1938 1 : RatedCapCoolTotalDes = RatedCapCoolSensDes;
1939 : }
1940 : }
1941 9 : if (!HardSizeNoDesRun) {
1942 4 : if (RatedCapCoolTotalAutoSized) {
1943 4 : if (simpleWatertoAirHP.CompanionHeatingCoilNum > 0) {
1944 : auto const &companionHeatingCoil =
1945 3 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum);
1946 3 : if (companionHeatingCoil.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit &&
1947 3 : companionHeatingCoil.RatedCapHeat > 0) {
1948 : // case 1: companion heating coil has a user-specified capacity
1949 : // or has already been sized
1950 0 : RatedCapCoolTotalDesCDD = RatedCapCoolTotalDes;
1951 0 : RatedCapCoolHeatDD = companionHeatingCoil.RatedCapHeatAtRatedCdts / companionHeatingCoil.RatioRatedHeatRatedTotCoolCap /
1952 : RatedTotCapTempModFac;
1953 0 : if (RatedCapCoolHeatDD > RatedCapCoolTotalDesCDD) {
1954 : // re-base the cooling capacity
1955 0 : RatedCapCoolTotalDes = RatedCapCoolHeatDD;
1956 :
1957 : // adjust for system air flow -- capacity is based on heating design day calcs
1958 : // adjust by ratio of system to heating air flow rate and temperature delta across the coil at these different airflow
1959 0 : if (HeatingAirVolFlowRateDes > 0) {
1960 0 : RatedCapCoolTotalDes *= (RatedAirVolFlowRateDes / HeatingAirVolFlowRateDes) * HeatdTratio;
1961 : }
1962 :
1963 0 : if (RatedCapCoolSensAutoSized) {
1964 : // adjust sensible capacity assuming that the SHR is constant
1965 0 : RatedCapCoolSensDes *= RatedCapCoolTotalDes / RatedCapCoolTotalDesCDD;
1966 : }
1967 :
1968 0 : simpleWatertoAirHP.RatedCapCoolTotal = RatedCapCoolTotalDes;
1969 0 : OutputReportPredefined::PreDefTableEntry(
1970 0 : state, state.dataOutRptPredefined->pdchWAHPDD, simpleWatertoAirHP.Name, "Heating");
1971 : } else {
1972 : // adjust for system air flow -- capacity is based on cooling design day calcs
1973 : // adjust by ratio of system to cooling air flow rate and enthalpy delta across the coil at these different airflow
1974 0 : RatedCapCoolTotalDes *= (RatedAirVolFlowRateDes / CoolingAirVolFlowRateDes) * dHratio;
1975 :
1976 0 : simpleWatertoAirHP.RatedCapCoolTotal = RatedCapCoolTotalDes;
1977 0 : OutputReportPredefined::PreDefTableEntry(
1978 0 : state, state.dataOutRptPredefined->pdchWAHPDD, simpleWatertoAirHP.Name, "Cooling");
1979 : }
1980 : // Set the global DX cooling coil capacity variable for use by other objects
1981 0 : state.dataSize->DXCoolCap = simpleWatertoAirHP.RatedCapCoolTotal;
1982 3 : } else if (companionHeatingCoil.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit &&
1983 3 : companionHeatingCoil.RatedCapHeat == DataSizing::AutoSize) {
1984 : // case 2: companion heating coil has not already been sized
1985 : // we only pass the rated total cooling capacity determined
1986 : // based on cooling design day which is used to decide if the
1987 : // coil needs to be sized of the heating coil size
1988 : //
1989 : // no capcity adjustment based on system flow because the capacity could change
1990 : // once the heating coil has been sized
1991 3 : state.dataSize->DXCoolCap = RatedCapCoolTotalDes;
1992 0 : } else if (companionHeatingCoil.WAHPPlantType != DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit) {
1993 : // case 3: companion heating coil is not of the "equationfit" type and hence doesn't use the rated heating to cooling
1994 : // coil capacity ratio
1995 : // adjust for system air flow -- capacity is based on cooling design day calcs
1996 : // adjust by ratio of system to cooling air flow rate and enthalpy delta across the coil at these different airflow
1997 0 : RatedCapCoolTotalDes *= (RatedAirVolFlowRateDes / CoolingAirVolFlowRateDes) * dHratio;
1998 0 : simpleWatertoAirHP.RatedCapCoolTotal = RatedCapCoolTotalDes;
1999 : // Set the global DX cooling coil capacity variable for use by other objects
2000 0 : state.dataSize->DXCoolCap = simpleWatertoAirHP.RatedCapCoolTotal;
2001 : }
2002 : } else {
2003 : // adjust for system air flow -- capacity is based on cooling design day calcs
2004 : // adjust by ratio of system to cooling air flow rate and enthalpy delta across the coil at these different airflow
2005 1 : RatedCapCoolTotalDes *= (RatedAirVolFlowRateDes / CoolingAirVolFlowRateDes) * dHratio;
2006 :
2007 1 : simpleWatertoAirHP.RatedCapCoolTotal = RatedCapCoolTotalDes;
2008 1 : state.dataSize->DXCoolCap = simpleWatertoAirHP.RatedCapCoolTotal;
2009 : }
2010 : // size power
2011 4 : simpleWatertoAirHP.RatedCapCoolAtRatedCdts = RatedCapCoolTotalDes * RatedTotCapTempModFac;
2012 4 : simpleWatertoAirHP.RatedPowerCoolAtRatedCdts =
2013 4 : simpleWatertoAirHP.RatedCapCoolAtRatedCdts / simpleWatertoAirHP.RatedCOPCoolAtRatedCdts;
2014 4 : simpleWatertoAirHP.RatedPowerCool = simpleWatertoAirHP.RatedPowerCoolAtRatedCdts / RatedCoolPowerTempModFac;
2015 4 : if (simpleWatertoAirHP.RatedCapCoolTotal != DataSizing::AutoSize) {
2016 3 : BaseSizer::reportSizerOutput(
2017 : state,
2018 2 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2019 : simpleWatertoAirHP.Name,
2020 : "Design Size Rated Total Cooling Capacity [W]",
2021 : simpleWatertoAirHP.RatedCapCoolTotal);
2022 : }
2023 8 : OutputReportPredefined::PreDefTableEntry(
2024 4 : state, state.dataOutRptPredefined->pdchWAHPRatedAirDBT, simpleWatertoAirHP.Name, RatedMixDryBulb);
2025 8 : OutputReportPredefined::PreDefTableEntry(
2026 4 : state, state.dataOutRptPredefined->pdchWAHPRatedAirWBT, simpleWatertoAirHP.Name, RatedMixWetBulb);
2027 8 : OutputReportPredefined::PreDefTableEntry(
2028 4 : state, state.dataOutRptPredefined->pdchWAHPRatedWtrT, simpleWatertoAirHP.Name, simpleWatertoAirHP.RatedEntWaterTemp);
2029 : } else { // Hardsized with sizing data
2030 0 : if (simpleWatertoAirHP.RatedCapCoolTotal > 0.0 && RatedCapCoolTotalDes > 0.0) {
2031 0 : RatedCapCoolTotalUser = simpleWatertoAirHP.RatedCapCoolTotal;
2032 0 : state.dataSize->DXCoolCap = simpleWatertoAirHP.RatedCapCoolTotal;
2033 0 : simpleWatertoAirHP.RatedPowerCool = simpleWatertoAirHP.RatedCapCoolTotal / simpleWatertoAirHP.RatedCOPCoolAtRatedCdts;
2034 0 : BaseSizer::reportSizerOutput(
2035 : state,
2036 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2037 : simpleWatertoAirHP.Name,
2038 : "Design Size Rated Total Cooling Capacity [W]",
2039 : RatedCapCoolTotalDes,
2040 : "User-Specified Rated Total Cooling Capacity [W]",
2041 : RatedCapCoolTotalUser);
2042 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2043 0 : if ((std::abs(RatedCapCoolTotalDes - RatedCapCoolTotalUser) / RatedCapCoolTotalUser) >
2044 0 : state.dataSize->AutoVsHardSizingThreshold) {
2045 0 : ShowMessage(
2046 : state,
2047 0 : format("SizeHVACWaterToAir: Potential issue with equipment sizing for coil {}:WATERTOAIRHEATPUMP:EQUATIONFIT {}",
2048 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2049 0 : simpleWatertoAirHP.Name));
2050 0 : ShowContinueError(state, format("User-Specified Rated Total Cooling Capacity of {:.2R} [W]", RatedCapCoolTotalUser));
2051 0 : ShowContinueError(
2052 0 : state, format("differs from Design Size Rated Total Cooling Capacity of {:.2R} [W]", RatedCapCoolTotalDes));
2053 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2054 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2055 : }
2056 : }
2057 : }
2058 : }
2059 : } else {
2060 5 : state.dataSize->DXCoolCap = simpleWatertoAirHP.RatedCapCoolTotal;
2061 : // user provided inputs are assumed to be at rated conditions
2062 5 : simpleWatertoAirHP.RatedPowerCool = simpleWatertoAirHP.RatedCapCoolTotal / simpleWatertoAirHP.RatedCOPCoolAtRatedCdts;
2063 5 : simpleWatertoAirHP.RatedCapCoolAtRatedCdts = 0;
2064 5 : simpleWatertoAirHP.RatedPowerCoolAtRatedCdts = 0;
2065 : }
2066 9 : if (simpleWatertoAirHP.RatedCapCoolTotal !=
2067 : DataSizing::AutoSize) { // all cases except case 2 mentioned above (when EquationFit companion heating coil has not yet been sized)
2068 12 : OutputReportPredefined::PreDefTableEntry(
2069 6 : state, state.dataOutRptPredefined->pdchCoolCoilTotCap, simpleWatertoAirHP.Name, simpleWatertoAirHP.RatedCapCoolTotal);
2070 12 : OutputReportPredefined::PreDefTableEntry(state,
2071 6 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
2072 : simpleWatertoAirHP.Name,
2073 6 : simpleWatertoAirHP.RatedCapCoolTotal - simpleWatertoAirHP.RatedCapCoolSens);
2074 6 : if (simpleWatertoAirHP.RatedCapCoolTotal > 0) {
2075 12 : OutputReportPredefined::PreDefTableEntry(state,
2076 6 : state.dataOutRptPredefined->pdchCoolCoilSHR,
2077 : simpleWatertoAirHP.Name,
2078 6 : simpleWatertoAirHP.RatedCapCoolSens / simpleWatertoAirHP.RatedCapCoolTotal);
2079 : } else {
2080 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, simpleWatertoAirHP.Name, 0.0);
2081 : }
2082 6 : if (RatedCapCoolTotalAutoSized) {
2083 2 : OutputReportPredefined::PreDefTableEntry(state,
2084 1 : state.dataOutRptPredefined->pdchWAHPRatedCapAtRatedCdts,
2085 : simpleWatertoAirHP.Name,
2086 : simpleWatertoAirHP.RatedCapCoolAtRatedCdts);
2087 1 : if (simpleWatertoAirHP.CompanionHeatingCoilNum > 0) {
2088 : auto &companionHeatingCoil(
2089 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum));
2090 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWAHPDD, companionHeatingCoil.Name, "Cooling");
2091 : }
2092 : }
2093 : } else {
2094 : // set temporarily until companion heating coil is sized
2095 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, simpleWatertoAirHP.Name, 0.0);
2096 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilLatCap, simpleWatertoAirHP.Name, 0.0);
2097 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, simpleWatertoAirHP.Name, 0.0);
2098 3 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, simpleWatertoAirHP.Name, 0.0);
2099 : }
2100 9 : if (simpleWatertoAirHP.RatedCapCoolTotal != DataSizing::AutoSize) {
2101 6 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilCoolingCapacity(state,
2102 6 : simpleWatertoAirHP.Name,
2103 : CompType,
2104 : simpleWatertoAirHP.RatedCapCoolTotal,
2105 : RatedCapCoolTotalAutoSized,
2106 6 : state.dataSize->CurSysNum,
2107 6 : state.dataSize->CurZoneEqNum,
2108 6 : state.dataSize->CurOASysNum,
2109 : FanCoolLoad,
2110 : PeakTotCapTempModFac,
2111 : -999.0,
2112 : -999.0);
2113 : }
2114 9 : if (!HardSizeNoDesRun) {
2115 4 : if (RatedCapCoolSensAutoSized) {
2116 4 : simpleWatertoAirHP.RatedCapCoolSens = RatedCapCoolSensDes;
2117 4 : simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts = RatedCapCoolSensDes * RatedSensCapTempModFac;
2118 4 : if (simpleWatertoAirHP.RatedCapCoolTotal != DataSizing::AutoSize) {
2119 3 : BaseSizer::reportSizerOutput(
2120 : state,
2121 2 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2122 : simpleWatertoAirHP.Name,
2123 : "Design Size Rated Sensible Cooling Capacity [W]",
2124 : RatedCapCoolSensDes);
2125 : }
2126 : } else {
2127 0 : if (simpleWatertoAirHP.RatedCapCoolSens > 0.0 && RatedCapCoolSensDes > 0.0) {
2128 0 : RatedCapCoolSensUser = simpleWatertoAirHP.RatedCapCoolSens;
2129 0 : BaseSizer::reportSizerOutput(
2130 : state,
2131 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2132 : simpleWatertoAirHP.Name,
2133 : "Design Size Rated Sensible Cooling Capacity [W]",
2134 : RatedCapCoolSensDes,
2135 : "User-Specified Rated Sensible Cooling Capacity [W]",
2136 : RatedCapCoolSensUser);
2137 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2138 0 : if ((std::abs(RatedCapCoolSensDes - RatedCapCoolSensUser) / RatedCapCoolSensUser) >
2139 0 : state.dataSize->AutoVsHardSizingThreshold) {
2140 0 : ShowMessage(
2141 : state,
2142 0 : format("SizeHVACWaterToAir: Potential issue with equipment sizing for coil {}:WATERTOAIRHEATPUMP:EQUATIONFIT {}",
2143 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2144 0 : simpleWatertoAirHP.Name));
2145 0 : ShowContinueError(state,
2146 0 : format("User-Specified Rated Sensible Cooling Capacity of {:.2R} [W]", RatedCapCoolSensUser));
2147 0 : ShowContinueError(
2148 0 : state, format("differs from Design Size Rated Sensible Cooling Capacity of {:.2R} [W]", RatedCapCoolSensDes));
2149 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2150 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2151 : }
2152 : }
2153 : }
2154 : }
2155 : }
2156 18 : OutputReportPredefined::PreDefTableEntry(
2157 9 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, simpleWatertoAirHP.Name, simpleWatertoAirHP.RatedCapCoolSens);
2158 18 : OutputReportPredefined::PreDefTableEntry(state,
2159 9 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
2160 : simpleWatertoAirHP.Name,
2161 9 : state.dataSize->DXCoolCap - simpleWatertoAirHP.RatedCapCoolSens);
2162 9 : if (RatedCapCoolSensAutoSized) {
2163 :
2164 8 : OutputReportPredefined::PreDefTableEntry(state,
2165 4 : state.dataOutRptPredefined->pdchWAHPRatedSensCapAtRatedCdts,
2166 : simpleWatertoAirHP.Name,
2167 : simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts);
2168 : }
2169 9 : if (simpleWatertoAirHP.RatedCapCoolTotal != 0.0) {
2170 18 : OutputReportPredefined::PreDefTableEntry(state,
2171 9 : state.dataOutRptPredefined->pdchCoolCoilSHR,
2172 : simpleWatertoAirHP.Name,
2173 9 : simpleWatertoAirHP.RatedCapCoolSens / state.dataSize->DXCoolCap);
2174 : } else {
2175 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, simpleWatertoAirHP.Name, 0.0);
2176 : }
2177 : // test autosized sensible and total cooling capacity for total > sensible
2178 9 : if ((RatedCapCoolSensAutoSized && RatedCapCoolTotalAutoSized) || RatedCapCoolSensAutoSized) {
2179 4 : if (simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts > simpleWatertoAirHP.RatedCapCoolAtRatedCdts) {
2180 0 : ShowWarningError(state,
2181 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT \"{}\"",
2182 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2183 0 : simpleWatertoAirHP.Name));
2184 0 : ShowContinueError(state, format("{}: Rated Sensible Cooling Capacity > Rated Total Cooling Capacity", RoutineName));
2185 0 : ShowContinueError(state, "Both of these capacity inputs have been autosized.");
2186 0 : ShowContinueError(
2187 : state,
2188 0 : format("Rated Sensible Cooling Capacity at Rated Conditions = {:.2T} W", simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts));
2189 0 : ShowContinueError(
2190 0 : state, format("Rated Total Cooling Capacity at Rated Conditions = {:.2T} W", simpleWatertoAirHP.RatedCapCoolAtRatedCdts));
2191 0 : ShowContinueError(state, "See eio file for further details.");
2192 0 : ShowContinueError(state, "Check Total and Sensible Cooling Capacity coefficients in curves to ensure they are accurate.");
2193 0 : ShowContinueError(state, "Check Zone and System Sizing objects to verify sizing inputs.");
2194 0 : ShowContinueError(state, "Sizing statistics:");
2195 0 : ShowContinueError(state, format("Rated entering Air Wet-Bulb Temperature = {:.3T} C", RatedMixWetBulb));
2196 0 : ShowContinueError(state, format("Peak entering Air Wet-Bulb Temperature = {:.3T} C", MixWetBulb));
2197 0 : ShowContinueError(state, format("Entering Water Temperature used = {:.3T} C", simpleWatertoAirHP.RatedEntWaterTemp));
2198 0 : ShowContinueError(state, "Design air and water flow rates = 1.0");
2199 0 : ShowContinueError(
2200 0 : state, format("Rated ratio of load-side air wet-bulb temperature to 283.15 C (Rated ratioTWB) = {:.3T}", RatedratioTWB));
2201 0 : ShowContinueError(
2202 0 : state, format("Rated ratio of source-side inlet water temperature to 283.15 C (Rated ratioTS) = {:.3T}", RatedratioTS));
2203 0 : ShowContinueError(state,
2204 0 : format("Peak ratio of load-side air wet-bulb temperature to 283.15 C (Peak ratioTWB) = {:.3T}", ratioTWB));
2205 0 : ShowContinueError(state,
2206 0 : format("Peak ratio of source-side inlet water temperature to 283.15 C (Peak ratioTS) = {:.3T}", ratioTS));
2207 0 : ShowContinueError(state, format("Rated Total Cooling Capacity Modifier = {:.5T}", RatedTotCapTempModFac));
2208 0 : ShowContinueError(state, format("Peak Design Total Cooling Capacity Modifier = {:.5T}", PeakTotCapTempModFac));
2209 0 : ShowContinueError(state, format("Rated Sensible Cooling Capacity Modifier = {:.5T}", RatedSensCapTempModFac));
2210 0 : ShowContinueError(state, format("Peak Design Sensible Cooling Capacity Modifier = {:.5T}", PeakSensCapTempModFac));
2211 0 : ShowContinueError(state,
2212 : "...Rated Total Cooling Capacity at Rated Conditions = Total Peak Design Load * Rated Total "
2213 : "Cooling Capacity Modifier / "
2214 : "Peak Design Total Cooling Capacity Modifier");
2215 0 : ShowContinueError(state,
2216 : "...Rated Sensible Cooling Capacity at Rated Conditions = Peak Design Sensible Load * Rated "
2217 : "Sensible Cooling "
2218 : "Capacity Modifier / Peak Design Sensible Cooling Capacity Modifier");
2219 0 : ShowContinueError(state, "Carefully review the Load Side Total, Sensible, and Latent heat transfer rates");
2220 0 : ShowContinueError(state, "... to ensure they meet the expected manufacturers performance specifications.");
2221 : }
2222 5 : } else if (RatedCapCoolTotalAutoSized) {
2223 0 : if (simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts > simpleWatertoAirHP.RatedCapCoolAtRatedCdts) {
2224 0 : ShowWarningError(state,
2225 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT \"{}\"",
2226 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2227 0 : simpleWatertoAirHP.Name));
2228 0 : ShowContinueError(state, format("{}: Rated Sensible Cooling Capacity > Rated Total Cooling Capacity", RoutineName));
2229 0 : ShowContinueError(state, "Only the Rated total capacity input is autosized, consider autosizing both inputs.");
2230 0 : ShowContinueError(state, format("Rated Sensible Cooling Capacity = {:.2T} W", simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts));
2231 0 : ShowContinueError(state, format("Rated Total Cooling Capacity = {:.2T} W", simpleWatertoAirHP.RatedCapCoolAtRatedCdts));
2232 0 : ShowContinueError(state, "See eio file for further details.");
2233 0 : ShowContinueError(state, "Check Total and Sensible Cooling Capacity coefficients in curves to ensure they are accurate.");
2234 0 : ShowContinueError(state, "Check Zone and System Sizing objects to verify sizing inputs.");
2235 0 : ShowContinueError(state, "Sizing statistics for Total Cooling Capacity:");
2236 0 : ShowContinueError(state, format("Rated entering Air Wet-Bulb Temperature = {:.3T} C", RatedMixWetBulb));
2237 0 : ShowContinueError(state, format("Peak entering Air Wet-Bulb Temperature = {:.3T} C", MixWetBulb));
2238 0 : ShowContinueError(state, format("Entering Water Temperature used = {:.3T} C", simpleWatertoAirHP.RatedEntWaterTemp));
2239 0 : ShowContinueError(state, "Design air and water flow rates = 1.0");
2240 0 : ShowContinueError(
2241 0 : state, format("Rated ratio of load-side air wet-bulb temperature to 283.15 C (Rated ratioTWB) = {:.3T}", RatedratioTWB));
2242 0 : ShowContinueError(
2243 0 : state, format("Rated ratio of source-side inlet water temperature to 283.15 C (Rated ratioTS) = {:.3T}", RatedratioTS));
2244 0 : ShowContinueError(state,
2245 0 : format("Peak ratio of load-side air wet-bulb temperature to 283.15 C (Peak ratioTWB) = {:.3T}", ratioTWB));
2246 0 : ShowContinueError(state,
2247 0 : format("Peak ratio of source-side inlet water temperature to 283.15 C (Peak ratioTS) = {:.3T}", ratioTS));
2248 0 : ShowContinueError(state, format("Rated Total Cooling Capacity Modifier = {:.5T}", RatedTotCapTempModFac));
2249 0 : ShowContinueError(state, format("Peak Design Total Cooling Capacity Modifier = {:.5T}", PeakTotCapTempModFac));
2250 0 : ShowContinueError(state,
2251 : "...Rated Total Cooling Capacity at Rated Conditions = Total Peak Design Load * Rated Total "
2252 : "Cooling Capacity Modifier / "
2253 : "Peak Design Total Cooling Capacity Modifier");
2254 0 : ShowContinueError(state,
2255 : "...Rated Sensible Cooling Capacity at Rated Conditions = Peak Design Sensible Load * Rated "
2256 : "Sensible Cooling "
2257 : "Capacity Modifier / Peak Design Sensible Cooling Capacity Modifier");
2258 0 : ShowContinueError(state, "Carefully review the Load Side Total, Sensible, and Latent heat transfer rates");
2259 0 : ShowContinueError(state, "... to ensure they meet the expected manufacturers performance specifications.");
2260 : }
2261 : }
2262 :
2263 : } // Cooling Coil
2264 :
2265 16 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating) {
2266 : // size rated heating capacity
2267 7 : IsAutoSize = false;
2268 7 : if (simpleWatertoAirHP.RatedCapHeat == DataSizing::AutoSize) {
2269 3 : IsAutoSize = true;
2270 : }
2271 7 : if (SizingDesRunThisAirSys || SizingDesRunThisZone) {
2272 1 : HardSizeNoDesRun = false;
2273 : }
2274 7 : if (IsAutoSize) {
2275 3 : if (state.dataSize->CurSysNum > 0) {
2276 0 : CheckSysSizing(
2277 : state,
2278 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2279 0 : simpleWatertoAirHP.Name);
2280 0 : if (HeatingAirVolFlowRateDes > 0.0) {
2281 0 : VolFlowRate = HeatingAirVolFlowRateDes;
2282 : } else {
2283 0 : VolFlowRate = CoolingAirVolFlowRateDes; // system air flow
2284 : }
2285 : // heating design day calculations
2286 0 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
2287 0 : auto const &finalSysSizing = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum);
2288 0 : if (state.dataSize->CurOASysNum > 0) { // coil is in the OA stream
2289 0 : HeatMixTemp = finalSysSizing.HeatOutTemp;
2290 0 : HeatMixHumRat = finalSysSizing.HeatOutHumRat;
2291 0 : HeatSupTemp = finalSysSizing.PreheatTemp;
2292 : } else { // coil is on the main air loop
2293 0 : if (VolFlowRate > 0.0) {
2294 0 : HeatOutAirFrac = finalSysSizing.DesOutAirVolFlow / VolFlowRate;
2295 0 : HeatOutAirFracSys = finalSysSizing.DesOutAirVolFlow / RatedAirVolFlowRateDes;
2296 : } else {
2297 0 : HeatOutAirFrac = 1.0;
2298 0 : HeatOutAirFracSys = HeatOutAirFrac;
2299 : }
2300 0 : HeatOutAirFrac = min(1.0, max(0.0, HeatOutAirFrac));
2301 0 : HeatOutAirFracSys = min(1.0, max(0.0, HeatOutAirFracSys));
2302 0 : HeatSupTemp = finalSysSizing.HeatSupTemp;
2303 0 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).NumOAHeatCoils ==
2304 : 0) { // there is no preheating of the OA stream
2305 0 : HeatMixTemp = HeatOutAirFrac * finalSysSizing.HeatOutTemp + (1.0 - HeatOutAirFrac) * finalSysSizing.HeatRetTemp;
2306 0 : HeatMixHumRat = HeatOutAirFrac * finalSysSizing.HeatOutHumRat + (1.0 - HeatOutAirFrac) * finalSysSizing.HeatRetHumRat;
2307 : // calculate mixed air temperature with system airflow
2308 0 : HeatMixTempSys =
2309 0 : HeatOutAirFracSys * finalSysSizing.HeatOutTemp + (1.0 - HeatOutAirFracSys) * finalSysSizing.HeatRetTemp;
2310 0 : HeatMixHumRatSys =
2311 0 : HeatOutAirFracSys * finalSysSizing.HeatOutHumRat + (1.0 - HeatOutAirFracSys) * finalSysSizing.HeatRetHumRat;
2312 : } else { // there is preheating of OA stream
2313 0 : HeatOutAirFrac = min(1.0, max(0.0, HeatOutAirFrac));
2314 0 : HeatMixTemp = HeatOutAirFrac * finalSysSizing.PreheatTemp + (1.0 - HeatOutAirFrac) * finalSysSizing.HeatRetTemp;
2315 0 : HeatMixHumRat = HeatOutAirFrac * finalSysSizing.PreheatHumRat + (1.0 - HeatOutAirFrac) * finalSysSizing.HeatRetHumRat;
2316 : // calculate mixed air temperature with system airflow
2317 0 : HeatMixTempSys =
2318 0 : HeatOutAirFracSys * finalSysSizing.PreheatTemp + (1.0 - HeatOutAirFracSys) * finalSysSizing.HeatRetTemp;
2319 0 : HeatMixHumRatSys =
2320 0 : HeatOutAirFracSys * finalSysSizing.PreheatHumRat + (1.0 - HeatOutAirFracSys) * finalSysSizing.HeatRetHumRat;
2321 : }
2322 : // determine the coil ratio of coil dT with system air flow to design heating air flow
2323 0 : HeatdTratio = (HeatSupTemp - HeatMixTempSys) / (HeatSupTemp - HeatMixTemp);
2324 : }
2325 0 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, HeatMixTemp, HeatMixHumRat, RoutineName);
2326 0 : HeatCapAtPeak = rhoair * VolFlowRate * Psychrometrics::PsyCpAirFnW(DataPrecisionGlobals::constant_zero) *
2327 0 : (HeatSupTemp - HeatMixTemp); // heating coil load
2328 0 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid &&
2329 0 : state.dataSize->DataFanIndex > 0) { // remove fan heat to coil load
2330 0 : FanHeatLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
2331 :
2332 0 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(HeatMixHumRat);
2333 0 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace == HVAC::FanPlace::BlowThru) {
2334 0 : HeatMixTemp += FanHeatLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature entering the coil
2335 0 : } else if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace ==
2336 : HVAC::FanPlace::DrawThru) {
2337 0 : HeatSupTemp -= FanHeatLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature leaving the coil
2338 : }
2339 : }
2340 0 : HeatCapAtPeak -= FanHeatLoad; // remove fan heat from heating coil load
2341 0 : HeatCapAtPeak = max(0.0, HeatCapAtPeak);
2342 0 : RatedHeatMixDryBulb = simpleWatertoAirHP.RatedEntAirDrybulbTemp;
2343 : // calculate temperatue ratio at design day peak conditions
2344 0 : HeatratioTDB = (HeatMixTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2345 0 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
2346 : state,
2347 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2348 : simpleWatertoAirHP.Name,
2349 : simpleWatertoAirHP.WaterInletNodeNum,
2350 : simpleWatertoAirHP.WaterOutletNodeNum,
2351 : ErrorsFound,
2352 : false);
2353 0 : if (PltSizNum > 0) {
2354 0 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
2355 0 : HeatratioTS = (DesignEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2356 : } else {
2357 0 : ShowSevereError(state, "Autosizing of heating capacity requires a loop Sizing:Plant object");
2358 0 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
2359 0 : ShowContinueError(state,
2360 0 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
2361 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2362 0 : simpleWatertoAirHP.Name));
2363 0 : HeatratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
2364 0 : ErrorsFound = true;
2365 : }
2366 : // calculate temperatue ratio at refrence conditions
2367 0 : RatedHeatratioTDB = (RatedHeatMixDryBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2368 0 : RatedHeatratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2369 : // determine curve modifiers at peak and rated conditions
2370 0 : PeakHeatCapTempModFac = simpleWatertoAirHP.HeatCapCurve->value(state, HeatratioTDB, HeatratioTS, 1.0, 1.0);
2371 0 : RatedHeatCapTempModFac = simpleWatertoAirHP.HeatCapCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
2372 : // Check curve output when rated mixed air wetbulb is the design mixed air wetbulb
2373 0 : if (RatedHeatMixDryBulb == HeatMixTemp) {
2374 0 : if (RatedHeatCapTempModFac > 1.02 || RatedHeatCapTempModFac < 0.98) {
2375 0 : ShowWarningError(state,
2376 0 : format("{} Coil:Heating:WaterToAirHeatPump:EquationFit={}", RoutineName, simpleWatertoAirHP.Name));
2377 0 : ShowContinueError(state,
2378 : "Heating capacity as a function of temperature curve output is not equal to 1.0 (+ or - 2%) "
2379 : "at rated conditions.");
2380 0 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedHeatCapTempModFac));
2381 : }
2382 : }
2383 : // calculate the rated capacity based on peak conditions
2384 : // note: the rated capacity can be different than the capacity at
2385 : // rated conditions if the capacity curve isn't normalized at the
2386 : // rated conditions
2387 0 : RatedCapHeatDes = (PeakHeatCapTempModFac > 0.0) ? HeatCapAtPeak / PeakHeatCapTempModFac : HeatCapAtPeak;
2388 : } else {
2389 0 : RatedCapHeatDes = 0.0;
2390 0 : RatedHeatratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
2391 : }
2392 3 : } else if (state.dataSize->CurZoneEqNum > 0) {
2393 6 : CheckZoneSizing(
2394 : state,
2395 6 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2396 : simpleWatertoAirHP.Name);
2397 3 : if (HeatingAirVolFlowRateDes > 0.0) {
2398 3 : VolFlowRate = HeatingAirVolFlowRateDes;
2399 : } else {
2400 0 : VolFlowRate = CoolingAirVolFlowRateDes; // system air flow
2401 : }
2402 3 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
2403 2 : if (state.dataSize->ZoneEqDXCoil) {
2404 2 : if (state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow > 0.0) {
2405 0 : HeatMixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInTemp;
2406 0 : HeatMixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInHumRat;
2407 : // calculate mixed air temperature with system airflow
2408 0 : HeatOAFrac = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA / HeatingAirVolFlowRateDes;
2409 0 : HeatOAFracSys = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA / RatedAirVolFlowRateDes;
2410 0 : HeatOAFrac = min(1.0, max(0.0, HeatOAFrac));
2411 0 : HeatOAFracSys = min(1.0, max(0.0, HeatOAFracSys));
2412 0 : HeatOATemp = (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInTemp -
2413 0 : (1.0 - HeatOAFrac) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneTempAtHeatPeak) /
2414 : HeatOAFrac;
2415 0 : HeatMixTempSys =
2416 0 : HeatOAFracSys * HeatOATemp +
2417 0 : (1.0 - HeatOAFracSys) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneTempAtHeatPeak;
2418 : } else {
2419 2 : HeatMixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneRetTempAtHeatPeak;
2420 2 : HeatMixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneHumRatAtHeatPeak;
2421 2 : HeatMixTempSys = HeatMixTemp;
2422 : }
2423 : } else {
2424 0 : HeatMixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInTemp;
2425 0 : HeatMixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInHumRat;
2426 0 : HeatMixTempSys = HeatMixTemp;
2427 : }
2428 2 : HeatSupTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).HeatDesTemp;
2429 : // determine the coil ratio of coil dT with system air flow to design heating air flow
2430 2 : HeatdTratio = (HeatSupTemp - HeatMixTempSys) / (HeatSupTemp - HeatMixTemp);
2431 2 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, HeatMixTemp, HeatMixHumRat, RoutineName);
2432 2 : HeatCapAtPeak = rhoair * VolFlowRate * Psychrometrics::PsyCpAirFnW(DataPrecisionGlobals::constant_zero) *
2433 2 : (HeatSupTemp - HeatMixTemp); // heating coil load
2434 2 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid && state.dataSize->DataFanIndex > 0) { // add fan heat to coil load
2435 1 : FanHeatLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
2436 :
2437 1 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(HeatMixHumRat);
2438 1 : if (state.dataSize->DataFanPlacement == HVAC::FanPlace::BlowThru) {
2439 1 : HeatMixTemp += FanHeatLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature entering the coil
2440 : } else {
2441 0 : HeatSupTemp -= FanHeatLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature leaving the coil
2442 : }
2443 : }
2444 2 : HeatCapAtPeak -= FanHeatLoad; // remove fan heat from heating coil load
2445 2 : HeatCapAtPeak = max(0.0, HeatCapAtPeak);
2446 2 : RatedHeatMixDryBulb = simpleWatertoAirHP.RatedEntAirDrybulbTemp;
2447 : // calculate temperatue ratio at design day peak conditions
2448 2 : HeatratioTDB = (HeatMixTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2449 4 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
2450 : state,
2451 4 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2452 : simpleWatertoAirHP.Name,
2453 : simpleWatertoAirHP.WaterInletNodeNum,
2454 : simpleWatertoAirHP.WaterOutletNodeNum,
2455 : ErrorsFound,
2456 : false);
2457 2 : if (PltSizNum > 0) {
2458 2 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
2459 2 : HeatratioTS = (DesignEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2460 : } else {
2461 0 : ShowSevereError(state, "Autosizing of heating capacity requires a loop Sizing:Plant object");
2462 0 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
2463 0 : ShowContinueError(state,
2464 0 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
2465 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2466 0 : simpleWatertoAirHP.Name));
2467 0 : HeatratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
2468 0 : ErrorsFound = true;
2469 : }
2470 : // calculate temperatue ratio at refrence conditions
2471 2 : RatedHeatratioTDB = (RatedHeatMixDryBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2472 2 : RatedHeatratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2473 : // determine curve modifiers at peak and rated conditions
2474 2 : PeakHeatCapTempModFac = simpleWatertoAirHP.HeatCapCurve->value(state, HeatratioTDB, HeatratioTS, 1.0, 1.0);
2475 2 : RatedHeatCapTempModFac = simpleWatertoAirHP.HeatCapCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
2476 2 : RatedHeatPowerTempModFac = simpleWatertoAirHP.HeatPowCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
2477 : // Check curve output when rated mixed air wetbulb is the design mixed air wetbulb
2478 2 : if (RatedHeatMixDryBulb == HeatMixTemp) {
2479 0 : if (RatedHeatCapTempModFac > 1.02 || RatedHeatCapTempModFac < 0.98) {
2480 0 : ShowWarningError(state,
2481 0 : format("{} Coil:Heating:WaterToAirHeatPump:EquationFit={}", RoutineName, simpleWatertoAirHP.Name));
2482 0 : ShowContinueError(state,
2483 : "Heating capacity as a function of temperature curve output is not equal to 1.0 (+ or - 2%) "
2484 : "at rated conditions.");
2485 0 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedHeatCapTempModFac));
2486 : }
2487 0 : if (RatedHeatPowerTempModFac > 1.02 || RatedHeatPowerTempModFac < 0.98) {
2488 0 : ShowWarningError(state,
2489 0 : format("{} Coil:Heating:WaterToAirHeatPump:EquationFit={}", RoutineName, simpleWatertoAirHP.Name));
2490 0 : ShowContinueError(state,
2491 : "Heating power consumption as a function of temperature curve output is not equal to "
2492 : "1.0 (+ or - 2%) at rated conditions.");
2493 0 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedHeatPowerTempModFac));
2494 : }
2495 : }
2496 : // calculate the rated capacity based on peak conditions
2497 : // note: the rated capacity can be different than the capacity at
2498 : // rated conditions if the capacity curve isn't normalized at the
2499 : // rated conditions
2500 2 : RatedCapHeatDes = (PeakHeatCapTempModFac > 0.0) ? HeatCapAtPeak / PeakHeatCapTempModFac : HeatCapAtPeak;
2501 : } else {
2502 1 : RatedHeatratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
2503 1 : RatedCapHeatDes = 0.0;
2504 : }
2505 : } else {
2506 0 : RatedHeatratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
2507 : }
2508 :
2509 : // determine adjusted cooling and heating coil capacity
2510 3 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts = RatedCapHeatDes * RatedHeatCapTempModFac;
2511 3 : if (simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
2512 3 : auto &companionCoolingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum));
2513 3 : if (companionCoolingCoil.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit &&
2514 3 : companionCoolingCoil.RatedCapCoolTotal == DataSizing::AutoSize) {
2515 : // case 1: companion coil is also of EquationFit type and is being autosized
2516 3 : RatedCapCoolTotalDes = state.dataSize->DXCoolCap;
2517 3 : RatedTotCapTempModFac = companionCoolingCoil.RatedCapCoolAtRatedCdts / RatedCapCoolTotalDes;
2518 3 : RatedCapCoolHeatDD =
2519 3 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts / simpleWatertoAirHP.RatioRatedHeatRatedTotCoolCap / RatedTotCapTempModFac;
2520 3 : RatedCoolPowerTempModFac = companionCoolingCoil.RatedPowerCoolAtRatedCdts / companionCoolingCoil.RatedPowerCool;
2521 3 : if (RatedCapCoolHeatDD > RatedCapCoolTotalDes) {
2522 : // total cooling capacity
2523 1 : RatedCapCoolTotalDes = RatedCapCoolHeatDD;
2524 : // adjust for system air flow -- capacity is based on heating design day calcs
2525 : // adjust by ratio of system to heating air flow rate and temperature delta across the coil at these different airflow
2526 1 : if (HeatingAirVolFlowRateDes > 0) {
2527 1 : RatedCapCoolTotalDes *= (RatedAirVolFlowRateDes / HeatingAirVolFlowRateDes) * HeatdTratio;
2528 : }
2529 : // calculate ajustment factor over previous capacity for sensible capacity adjustment
2530 1 : Real64 CapCoolAdjFac = RatedCapCoolTotalDes / state.dataSize->DXCoolCap;
2531 : // update cooling coil rated capacity after adjustments based on heating coil size
2532 1 : state.dataSize->DXCoolCap = RatedCapCoolTotalDes;
2533 : // sensible cooling capacity
2534 1 : RatedCapCoolSensDes = companionCoolingCoil.RatedCapCoolSens * CapCoolAdjFac; // Assume that SHR stays the same
2535 1 : companionCoolingCoil.RatedCapCoolSensDesAtRatedCdts *= CapCoolAdjFac;
2536 1 : companionCoolingCoil.RatedCapCoolSens = RatedCapCoolSensDes;
2537 : // update Water-to-Air Heat Pumps output reports
2538 2 : OutputReportPredefined::PreDefTableEntry(state,
2539 1 : state.dataOutRptPredefined->pdchWAHPRatedSensCapAtRatedCdts,
2540 : companionCoolingCoil.Name,
2541 : companionCoolingCoil.RatedCapCoolSensDesAtRatedCdts);
2542 2 : OutputReportPredefined::PreDefTableEntry(
2543 1 : state, state.dataOutRptPredefined->pdchWAHPDD, companionCoolingCoil.Name, "Heating");
2544 2 : OutputReportPredefined::PreDefTableEntry(
2545 1 : state, state.dataOutRptPredefined->pdchWAHPDD, simpleWatertoAirHP.Name, "Heating");
2546 : // update Cooling Coils output reports
2547 2 : OutputReportPredefined::PreDefTableEntry(state,
2548 1 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
2549 : companionCoolingCoil.Name,
2550 : RatedCapCoolTotalDes - RatedCapCoolSensDes);
2551 2 : OutputReportPredefined::PreDefTableEntry(state,
2552 1 : state.dataOutRptPredefined->pdchCoolCoilSHR,
2553 : companionCoolingCoil.Name,
2554 : RatedCapCoolSensDes / RatedCapCoolTotalDes);
2555 2 : OutputReportPredefined::PreDefTableEntry(
2556 1 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, companionCoolingCoil.Name, RatedCapCoolSensDes);
2557 : } else {
2558 4 : OutputReportPredefined::PreDefTableEntry(
2559 2 : state, state.dataOutRptPredefined->pdchWAHPDD, companionCoolingCoil.Name, "Cooling");
2560 4 : OutputReportPredefined::PreDefTableEntry(
2561 2 : state, state.dataOutRptPredefined->pdchWAHPDD, simpleWatertoAirHP.Name, "Cooling");
2562 : }
2563 3 : RatedCapHeatDes =
2564 3 : RatedCapCoolTotalDes * RatedTotCapTempModFac * simpleWatertoAirHP.RatioRatedHeatRatedTotCoolCap / RatedHeatCapTempModFac;
2565 3 : companionCoolingCoil.RatedCapCoolTotal = RatedCapCoolTotalDes;
2566 3 : companionCoolingCoil.RatedCapCoolAtRatedCdts = RatedCapCoolTotalDes * RatedTotCapTempModFac;
2567 3 : companionCoolingCoil.RatedPowerCoolAtRatedCdts =
2568 3 : companionCoolingCoil.RatedCapCoolAtRatedCdts / companionCoolingCoil.RatedCOPCoolAtRatedCdts;
2569 3 : companionCoolingCoil.RatedPowerCool = companionCoolingCoil.RatedPowerCoolAtRatedCdts / RatedCoolPowerTempModFac;
2570 : // update Water-to-Air Heat Pumps output reports
2571 6 : OutputReportPredefined::PreDefTableEntry(state,
2572 3 : state.dataOutRptPredefined->pdchWAHPRatedCapAtRatedCdts,
2573 : companionCoolingCoil.Name,
2574 : companionCoolingCoil.RatedCapCoolAtRatedCdts);
2575 : // update Cooling Coils output reports
2576 6 : OutputReportPredefined::PreDefTableEntry(
2577 3 : state, state.dataOutRptPredefined->pdchCoolCoilTotCap, companionCoolingCoil.Name, RatedCapCoolTotalDes);
2578 9 : BaseSizer::reportSizerOutput(
2579 : state,
2580 6 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(companionCoolingCoil.WAHPType)]),
2581 : companionCoolingCoil.Name,
2582 : "Design Size Rated Total Cooling Capacity [W]",
2583 : companionCoolingCoil.RatedCapCoolTotal);
2584 9 : BaseSizer::reportSizerOutput(
2585 : state,
2586 6 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(companionCoolingCoil.WAHPType)]),
2587 : companionCoolingCoil.Name,
2588 : "Design Size Rated Sensible Cooling Capacity [W]",
2589 : companionCoolingCoil.RatedCapCoolSens);
2590 3 : } else if (companionCoolingCoil.WAHPPlantType ==
2591 : DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit) { // case 2: companion coil is of EquationFit type but is
2592 : // not autosized
2593 0 : RatedCapHeatDes = companionCoolingCoil.RatedCapCoolTotal * simpleWatertoAirHP.RatioRatedHeatRatedTotCoolCap;
2594 : } else { // case 3: companion type is different than EquationFit
2595 0 : RatedCapHeatDes = state.dataSize->DXCoolCap;
2596 : }
2597 : }
2598 : // heating capacity final determination
2599 3 : simpleWatertoAirHP.RatedCapHeat = RatedCapHeatDes;
2600 3 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts = RatedCapHeatDes * RatedHeatCapTempModFac;
2601 :
2602 : // heating power calculations
2603 3 : RatedHeatPowerTempModFac = simpleWatertoAirHP.HeatPowCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
2604 3 : simpleWatertoAirHP.RatedPowerHeat =
2605 3 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts / (simpleWatertoAirHP.RatedCOPHeatAtRatedCdts * RatedHeatPowerTempModFac);
2606 :
2607 : // update reports
2608 6 : OutputReportPredefined::PreDefTableEntry(state,
2609 3 : state.dataOutRptPredefined->pdchWAHPRatedCapAtRatedCdts,
2610 : simpleWatertoAirHP.Name,
2611 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts);
2612 6 : OutputReportPredefined::PreDefTableEntry(
2613 3 : state, state.dataOutRptPredefined->pdchWAHPRatedAirDBT, simpleWatertoAirHP.Name, RatedHeatMixDryBulb);
2614 6 : OutputReportPredefined::PreDefTableEntry(
2615 3 : state, state.dataOutRptPredefined->pdchWAHPRatedWtrT, simpleWatertoAirHP.Name, simpleWatertoAirHP.RatedEntWaterTemp);
2616 9 : BaseSizer::reportSizerOutput(
2617 : state,
2618 6 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2619 : simpleWatertoAirHP.Name,
2620 : "Design Size Rated Heating Capacity [W]",
2621 : simpleWatertoAirHP.RatedCapHeat);
2622 6 : OutputReportPredefined::PreDefTableEntry(
2623 3 : state, state.dataOutRptPredefined->pdchHeatCoilNomCap, simpleWatertoAirHP.Name, simpleWatertoAirHP.RatedCapHeat);
2624 3 : if (simpleWatertoAirHP.RatedCapHeat != 0.0) {
2625 6 : OutputReportPredefined::PreDefTableEntry(state,
2626 3 : state.dataOutRptPredefined->pdchHeatCoilNomEff,
2627 : simpleWatertoAirHP.Name,
2628 3 : simpleWatertoAirHP.RatedPowerHeat / simpleWatertoAirHP.RatedCapHeat);
2629 : } else {
2630 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, simpleWatertoAirHP.Name, 0.0);
2631 : }
2632 : } else {
2633 4 : if (simpleWatertoAirHP.RatedCapHeat > 0.0 && RatedCapHeatDes > 0.0 && !HardSizeNoDesRun) {
2634 0 : RatedCapHeatUser = simpleWatertoAirHP.RatedCapHeat;
2635 0 : BaseSizer::reportSizerOutput(
2636 : state,
2637 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2638 : simpleWatertoAirHP.Name,
2639 : "Design Size Rated Heating Capacity [W]",
2640 : RatedCapHeatDes,
2641 : "User-Specified Rated Heating Capacity [W]",
2642 : RatedCapHeatUser);
2643 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2644 0 : if ((std::abs(RatedCapHeatDes - RatedCapHeatUser) / RatedCapHeatUser) > state.dataSize->AutoVsHardSizingThreshold) {
2645 0 : ShowMessage(
2646 : state,
2647 0 : format("SizeHVACWaterToAir: Potential issue with equipment sizing for coil {}:WATERTOAIRHEATPUMP:EQUATIONFIT {}",
2648 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2649 0 : simpleWatertoAirHP.Name));
2650 0 : ShowContinueError(state, format("User-Specified Rated Heating Capacity of {:.2R} [W]", RatedCapHeatUser));
2651 0 : ShowContinueError(state, format("differs from Design Size Rated Heating Capacity of {:.2R} [W]", RatedCapHeatDes));
2652 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2653 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2654 : }
2655 : }
2656 : } else {
2657 4 : if (simpleWatertoAirHP.RatedCapHeat > 0.0) {
2658 4 : RatedCapHeatUser = simpleWatertoAirHP.RatedCapHeat;
2659 12 : BaseSizer::reportSizerOutput(
2660 : state,
2661 8 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2662 : simpleWatertoAirHP.Name,
2663 : "User-Specified Rated Heating Capacity [W]",
2664 : RatedCapHeatUser);
2665 : }
2666 : }
2667 :
2668 : // user provided inputs are assumed to be at rated conditions
2669 4 : simpleWatertoAirHP.RatedPowerHeat = simpleWatertoAirHP.RatedCapHeat / simpleWatertoAirHP.RatedCOPHeatAtRatedCdts;
2670 4 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts = 0; // not sure why these are set = 0, should be RatedCapHeat?
2671 4 : simpleWatertoAirHP.RatedPowerHeatAtRatedCdts = 0; // should be RatedPowerHeat?
2672 : }
2673 : // Check that heat pump heating capacity is within 20% of cooling capacity. Check only for heating coil and report both.
2674 7 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating && simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
2675 4 : auto &companionCoolingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum));
2676 4 : if (companionCoolingCoil.RatedCapCoolTotal > 0.0) {
2677 :
2678 4 : if (std::abs(companionCoolingCoil.RatedCapCoolTotal - simpleWatertoAirHP.RatedCapHeat) / companionCoolingCoil.RatedCapCoolTotal >
2679 : 0.2) {
2680 :
2681 4 : ShowWarningError(state,
2682 4 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT {}",
2683 2 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2684 2 : simpleWatertoAirHP.Name));
2685 4 : ShowContinueError(state,
2686 4 : format("...used with COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT {}",
2687 2 : companionCoolingCoil.WAHPType,
2688 2 : companionCoolingCoil.Name));
2689 4 : ShowContinueError(state, "...heating capacity is disproportionate (> 20% different) to total cooling capacity");
2690 2 : ShowContinueError(state, format("...heating capacity = {:.3T} W", simpleWatertoAirHP.RatedCapHeat));
2691 2 : ShowContinueError(state, format("...cooling capacity = {:.3T} W", companionCoolingCoil.RatedCapCoolTotal));
2692 : }
2693 : }
2694 : }
2695 :
2696 7 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilHeatingCapacity(
2697 : state,
2698 7 : simpleWatertoAirHP.Name,
2699 14 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2700 : RatedCapHeatDes,
2701 : IsAutoSize,
2702 7 : state.dataSize->CurSysNum,
2703 7 : state.dataSize->CurZoneEqNum,
2704 7 : state.dataSize->CurOASysNum,
2705 : FanCoolLoad,
2706 : 1.0, // RatedHeatCapTempModFac,
2707 : -999.0,
2708 : -999.0);
2709 :
2710 : } // Heating
2711 :
2712 : // size/report rated efficiency and power
2713 16 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
2714 9 : if (simpleWatertoAirHP.RatedPowerCool > 0) {
2715 18 : OutputReportPredefined::PreDefTableEntry(state,
2716 9 : state.dataOutRptPredefined->pdchCoolCoilNomEff,
2717 : simpleWatertoAirHP.Name,
2718 9 : simpleWatertoAirHP.RatedCapCoolTotal / simpleWatertoAirHP.RatedPowerCool);
2719 : }
2720 9 : if (IsAutoSize) {
2721 8 : OutputReportPredefined::PreDefTableEntry(state,
2722 4 : state.dataOutRptPredefined->pdchWAHPRatedPowerAtRatedCdts,
2723 : simpleWatertoAirHP.Name,
2724 : simpleWatertoAirHP.RatedPowerCoolAtRatedCdts);
2725 4 : if (simpleWatertoAirHP.RatedPowerCoolAtRatedCdts > 0) {
2726 8 : OutputReportPredefined::PreDefTableEntry(state,
2727 4 : state.dataOutRptPredefined->pdchWAHPRatedCOPAtRatedCdts,
2728 : simpleWatertoAirHP.Name,
2729 4 : simpleWatertoAirHP.RatedCapCoolAtRatedCdts /
2730 4 : simpleWatertoAirHP.RatedPowerCoolAtRatedCdts);
2731 : }
2732 : }
2733 7 : } else if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating) {
2734 : // heating coil power
2735 7 : simpleWatertoAirHP.RatedPowerHeatAtRatedCdts = simpleWatertoAirHP.RatedCapHeatAtRatedCdts / simpleWatertoAirHP.RatedCOPHeatAtRatedCdts;
2736 7 : if (simpleWatertoAirHP.RatedPowerHeat > 0) {
2737 12 : OutputReportPredefined::PreDefTableEntry(state,
2738 6 : state.dataOutRptPredefined->pdchHeatCoilNomEff,
2739 : simpleWatertoAirHP.Name,
2740 6 : simpleWatertoAirHP.RatedCapHeat / simpleWatertoAirHP.RatedPowerHeat);
2741 : }
2742 7 : if (IsAutoSize) {
2743 6 : OutputReportPredefined::PreDefTableEntry(state,
2744 3 : state.dataOutRptPredefined->pdchWAHPRatedPowerAtRatedCdts,
2745 : simpleWatertoAirHP.Name,
2746 : simpleWatertoAirHP.RatedPowerHeatAtRatedCdts);
2747 3 : if (simpleWatertoAirHP.RatedPowerHeatAtRatedCdts > 0) {
2748 6 : OutputReportPredefined::PreDefTableEntry(state,
2749 3 : state.dataOutRptPredefined->pdchWAHPRatedCOPAtRatedCdts,
2750 : simpleWatertoAirHP.Name,
2751 3 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts /
2752 3 : simpleWatertoAirHP.RatedPowerHeatAtRatedCdts);
2753 : }
2754 : }
2755 : // re-calculate companion coil power
2756 7 : if (simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
2757 4 : auto &companionCoolingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum));
2758 4 : companionCoolingCoil.RatedPowerCoolAtRatedCdts =
2759 4 : companionCoolingCoil.RatedCapCoolAtRatedCdts / companionCoolingCoil.RatedCOPCoolAtRatedCdts;
2760 4 : if (companionCoolingCoil.RatedCapCoolTotal > 0) {
2761 8 : OutputReportPredefined::PreDefTableEntry(state,
2762 4 : state.dataOutRptPredefined->pdchCoolCoilNomEff,
2763 : companionCoolingCoil.Name,
2764 4 : companionCoolingCoil.RatedCapCoolTotal / companionCoolingCoil.RatedPowerCool);
2765 4 : if (IsAutoSize) {
2766 6 : OutputReportPredefined::PreDefTableEntry(state,
2767 3 : state.dataOutRptPredefined->pdchWAHPRatedPowerAtRatedCdts,
2768 : companionCoolingCoil.Name,
2769 : companionCoolingCoil.RatedPowerCoolAtRatedCdts);
2770 3 : if (companionCoolingCoil.RatedPowerCoolAtRatedCdts > 0) {
2771 6 : OutputReportPredefined::PreDefTableEntry(state,
2772 3 : state.dataOutRptPredefined->pdchWAHPRatedCOPAtRatedCdts,
2773 : companionCoolingCoil.Name,
2774 3 : companionCoolingCoil.RatedCapCoolAtRatedCdts /
2775 3 : companionCoolingCoil.RatedPowerCoolAtRatedCdts);
2776 : }
2777 : }
2778 : }
2779 : }
2780 : }
2781 :
2782 : // Size water volumetric flow rate
2783 16 : IsAutoSize = false;
2784 16 : if (simpleWatertoAirHP.RatedWaterVolFlowRate == DataSizing::AutoSize) {
2785 2 : IsAutoSize = true;
2786 : }
2787 :
2788 : // WSHP condenser can be on either a plant loop or condenser loop. Test each to find plant sizing number.
2789 : // first check to see if coil is connected to a plant loop, no warning on this CALL
2790 16 : if (IsAutoSize) {
2791 4 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
2792 : state,
2793 4 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2794 : simpleWatertoAirHP.Name,
2795 : simpleWatertoAirHP.WaterInletNodeNum,
2796 : simpleWatertoAirHP.WaterOutletNodeNum,
2797 : ErrorsFound,
2798 : false);
2799 :
2800 2 : if (PltSizNum > 0) {
2801 2 : rho = state.dataPlnt->PlantLoop(simpleWatertoAirHP.plantLoc.loopNum)
2802 2 : .glycol->getDensity(state, state.dataSize->PlantSizData(PltSizNum).ExitTemp, RoutineNameAlt);
2803 2 : Cp = state.dataPlnt->PlantLoop(simpleWatertoAirHP.plantLoc.loopNum)
2804 2 : .glycol->getSpecificHeat(state, state.dataSize->PlantSizData(PltSizNum).ExitTemp, RoutineNameAlt);
2805 :
2806 2 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating) {
2807 1 : RatedWaterVolFlowRateDes = simpleWatertoAirHP.RatedCapHeat / (state.dataSize->PlantSizData(PltSizNum).DeltaT * Cp * rho);
2808 1 : } else if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
2809 : // use companion heating coil capacity to calculate volumetric flow rate
2810 1 : if (simpleWatertoAirHP.CompanionHeatingCoilNum > 0) {
2811 : auto const &companionHeatingCoil =
2812 1 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum);
2813 1 : if (companionHeatingCoil.RatedCapHeat == DataSizing::AutoSize) {
2814 1 : SystemCapacity = simpleWatertoAirHP.RatedCapCoolTotal; // but you should use condenser capacity?
2815 : } else {
2816 0 : SystemCapacity = companionHeatingCoil.RatedCapHeat;
2817 : }
2818 : } else {
2819 0 : SystemCapacity = simpleWatertoAirHP.RatedCapCoolAtRatedCdts; // RatedCapCoolTotal ? * (1 + 1/COP) ?
2820 : }
2821 :
2822 1 : RatedWaterVolFlowRateDes = SystemCapacity / (state.dataSize->PlantSizData(PltSizNum).DeltaT * Cp * rho);
2823 : }
2824 : } else {
2825 0 : ShowSevereError(state, "Autosizing of water flow requires a loop Sizing:Plant object");
2826 0 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
2827 0 : ShowContinueError(state,
2828 0 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
2829 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2830 0 : simpleWatertoAirHP.Name));
2831 : }
2832 :
2833 2 : if (SystemCapacity != DataSizing::AutoSize) {
2834 1 : simpleWatertoAirHP.RatedWaterVolFlowRate = RatedWaterVolFlowRateDes;
2835 3 : BaseSizer::reportSizerOutput(
2836 : state,
2837 2 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2838 : simpleWatertoAirHP.Name,
2839 : "Design Size Rated Water Flow Rate [m3/s]",
2840 : RatedWaterVolFlowRateDes);
2841 1 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating && simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
2842 1 : auto &companionCoolingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum));
2843 1 : companionCoolingCoil.RatedWaterVolFlowRate = RatedWaterVolFlowRateDes;
2844 3 : BaseSizer::reportSizerOutput(
2845 : state,
2846 2 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(companionCoolingCoil.WAHPType)]),
2847 : companionCoolingCoil.Name,
2848 : "Design Size Rated Water Flow Rate [m3/s]",
2849 : RatedWaterVolFlowRateDes);
2850 1 : } else if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling && simpleWatertoAirHP.CompanionHeatingCoilNum > 0) {
2851 0 : auto &companionHeatingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum));
2852 0 : companionHeatingCoil.RatedWaterVolFlowRate = RatedWaterVolFlowRateDes;
2853 0 : BaseSizer::reportSizerOutput(
2854 : state,
2855 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(companionHeatingCoil.WAHPType)]),
2856 : companionHeatingCoil.Name,
2857 : "Design Size Rated Water Flow Rate [m3/s]",
2858 : RatedWaterVolFlowRateDes);
2859 : }
2860 : }
2861 : } else {
2862 14 : if (simpleWatertoAirHP.RatedWaterVolFlowRate > 0.0 && RatedWaterVolFlowRateDes > 0.0) {
2863 0 : RatedWaterVolFlowRateUser = simpleWatertoAirHP.RatedWaterVolFlowRate;
2864 0 : BaseSizer::reportSizerOutput(
2865 : state,
2866 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2867 : simpleWatertoAirHP.Name,
2868 : "Design Size Rated Water Flow Rate [m3/s]",
2869 : RatedWaterVolFlowRateDes,
2870 : "User-Specified Rated Water Flow Rate [m3/s]",
2871 : RatedWaterVolFlowRateUser);
2872 0 : if (state.dataGlobal->DisplayExtraWarnings) {
2873 0 : if ((std::abs(RatedWaterVolFlowRateDes - RatedWaterVolFlowRateUser) / RatedWaterVolFlowRateUser) >
2874 0 : state.dataSize->AutoVsHardSizingThreshold) {
2875 0 : ShowMessage(state,
2876 0 : format("SizeHVACWaterToAir: Potential issue with equipment sizing for coil {}:WATERTOAIRHEATPUMP:EQUATIONFIT {}",
2877 0 : simpleWatertoAirHP.WAHPType,
2878 0 : simpleWatertoAirHP.Name));
2879 0 : ShowContinueError(state, format("User-Specified Rated Water Flow Rate of {:.5R} [m3/s]", RatedWaterVolFlowRateUser));
2880 0 : ShowContinueError(state, format("differs from Design Size Rated Water Flow Rate of {:.5R} [m3/s]", RatedWaterVolFlowRateDes));
2881 0 : ShowContinueError(state, "This may, or may not, indicate mismatched component sizes.");
2882 0 : ShowContinueError(state, "Verify that the value entered is intended and is consistent with other components.");
2883 : }
2884 : }
2885 : }
2886 : }
2887 :
2888 : // Save component design water volumetric flow rate.
2889 : // Use 1/2 flow since both cooling and heating coil will save flow yet only 1 will operate at a time
2890 16 : if (simpleWatertoAirHP.RatedWaterVolFlowRate > 0.0) {
2891 8 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating) {
2892 4 : PlantUtilities::RegisterPlantCompDesignFlow(
2893 4 : state, simpleWatertoAirHP.WaterInletNodeNum, 0.5 * simpleWatertoAirHP.RatedWaterVolFlowRate);
2894 4 : if (simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
2895 2 : auto &companionCoolingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum));
2896 2 : PlantUtilities::RegisterPlantCompDesignFlow(
2897 2 : state, companionCoolingCoil.WaterInletNodeNum, 0.5 * simpleWatertoAirHP.RatedWaterVolFlowRate);
2898 : }
2899 4 : } else if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
2900 4 : PlantUtilities::RegisterPlantCompDesignFlow(
2901 4 : state, simpleWatertoAirHP.WaterInletNodeNum, 0.5 * simpleWatertoAirHP.RatedWaterVolFlowRate);
2902 : }
2903 : }
2904 16 : }
2905 :
2906 49906 : void CalcHPCoolingSimple(EnergyPlusData &state,
2907 : int const HPNum, // Heat Pump Number
2908 : HVAC::FanOp const fanOp, // Fan/Compressor cycling scheme indicator
2909 : [[maybe_unused]] Real64 const SensDemand, // Cooling Sensible Demand [W] !unused1208
2910 : [[maybe_unused]] Real64 const LatentDemand, // Cooling Latent Demand [W]
2911 : HVAC::CompressorOp const compressorOp, // compressor operation flag
2912 : Real64 const PartLoadRatio, // compressor part load ratio
2913 : [[maybe_unused]] Real64 const OnOffAirFlowRatio // ratio of compressor on flow to average flow over time step
2914 : )
2915 : {
2916 :
2917 : // AUTHOR Arun Shenoy
2918 : // DATE WRITTEN Jan 2004
2919 : // RE-ENGINEERED Kenneth Tang (Jan 2005)
2920 :
2921 : // PURPOSE OF THIS SUBROUTINE:
2922 : // This subroutine is for simulating the cooling mode of the Water to Air HP Simple
2923 :
2924 : // METHODOLOGY EMPLOYED:
2925 : // Simulate the heat pump performance using the coefficients in quadlinear and quintlinear curves and rated conditions
2926 : // If the LatDegradModelSimFlag is enabled, the coil will be simulated twice:
2927 : // (1)first simulation at the rated conditions (2) second simulation at the
2928 : // actual operating conditions. Then call CalcEffectiveSHR and the effective SHR
2929 : // is adjusted.
2930 : // If the LatDegradModelSimFlag is disabled, the cooling coil is only simulated
2931 : // once at the actual operating conditions.
2932 : // Finally, adjust the heat pump outlet conditions based on the PartLoadRatio
2933 : // and RuntimeFrac.
2934 :
2935 : // REFERENCES:
2936 : // (1) Lash.T.A.,1992.Simulation and Analysis of a Water Loop Heat Pump System.
2937 : // M.S. Thesis, University of Illinois at Urbana Champaign.
2938 : // (2) Shenoy, Arun. 2004. Simulation, Modeling and Analysis of Water to Air Heat Pump.
2939 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
2940 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
2941 : // (3) Tang,C.C.. 2005. Modeling Packaged Heat Pumps in a Quasi-Steady
2942 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
2943 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
2944 : // (4) Henderson, H.I., K. Rengarajan.1996. A Model to Predict the Latent
2945 : // Capacity of Air Conditioners and Heat Pumps at Part-Load Conditions
2946 : // with Constant Fan Operation ASHRAE Transactions 102 (1), pp. 266-274.
2947 :
2948 49906 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
2949 :
2950 : // SUBROUTINE PARAMETER DEFINITIONS:
2951 49906 : constexpr Real64 Tref(283.15); // Reference Temperature for performance curves,10C [K]
2952 : static constexpr std::string_view RoutineName("CalcHPCoolingSimple");
2953 : static constexpr std::string_view RoutineNameSourceSideInletTemp("CalcHPCoolingSimple:SourceSideInletTemp");
2954 :
2955 : Real64 TotalCapRated; // Rated Total Cooling Capacity [W]
2956 : Real64 SensCapRated; // Rated Sensible Cooling Capacity [W]
2957 : Real64 CoolPowerRated; // Rated Cooling Power Input[W]
2958 : Real64 AirVolFlowRateRated; // Rated Air Volumetric Flow Rate [m3/s]
2959 : Real64 WaterVolFlowRateRated; // Rated Water Volumetric Flow Rate [m3/s]
2960 : Real64 Twet_Rated; // Twet at rated conditions (coil air flow rate and air temperatures), sec
2961 : Real64 Gamma_Rated; // Gamma at rated conditions (coil air flow rate and air temperatures)
2962 : Real64 SHRss; // Sensible heat ratio at steady state
2963 : Real64 SHReff; // Effective sensible heat ratio at part-load condition
2964 : Real64 ratioTDB; // Ratio of the inlet air dry bulb temperature to the rated conditions
2965 : Real64 ratioTWB; // Ratio of the inlet air wet bulb temperature to the rated conditions
2966 : Real64 ratioTS; // Ratio of the source side(water) inlet temperature to the rated conditions
2967 : Real64 ratioVL; // Ratio of the air flow rate to the rated conditions
2968 : Real64 ratioVS; // Ratio of the water flow rate to the rated conditions
2969 : Real64 CpWater; // Specific heat of water [J/kg_C]
2970 : Real64 CpAir; // Specific heat of air [J/kg_C]
2971 : Real64 LoadSideFullMassFlowRate; // Load Side Full Load Mass Flow Rate [kg/s]
2972 : Real64 LoadSideFullOutletEnthalpy; // Load Side Full Load Outlet Air Enthalpy [J/kg]
2973 :
2974 : bool LatDegradModelSimFlag; // Latent degradation model simulation flag
2975 : int NumIteration; // Iteration Counter
2976 : Real64 LoadSideInletDBTemp_Unit; // calc conditions for unit
2977 : Real64 LoadSideInletWBTemp_Unit; // calc conditions for unit
2978 : Real64 LoadSideInletHumRat_Unit; // calc conditions for unit
2979 : Real64 LoadSideInletEnth_Unit; // calc conditions for unit
2980 : Real64 CpAir_Unit; // calc conditions for unit
2981 :
2982 49906 : if (state.dataWaterToAirHeatPumpSimple->firstTime) {
2983 : // Set indoor air conditions to the rated condition
2984 6 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp_Init = 26.7;
2985 6 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat_Init = 0.0111;
2986 6 : state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth_Init = Psychrometrics::PsyHFnTdbW(
2987 6 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp_Init, state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat_Init);
2988 6 : state.dataWaterToAirHeatPumpSimple->CpAir_Init =
2989 6 : Psychrometrics::PsyCpAirFnW(state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat_Init);
2990 6 : state.dataWaterToAirHeatPumpSimple->firstTime = false;
2991 : }
2992 99812 : state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp_Init =
2993 49906 : Psychrometrics::PsyTwbFnTdbWPb(state,
2994 49906 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp_Init,
2995 49906 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat_Init,
2996 49906 : state.dataEnvrn->OutBaroPress,
2997 : RoutineName);
2998 :
2999 : // LOAD LOCAL VARIABLES FROM DATA STRUCTURE (for code readability)
3000 :
3001 49906 : auto &simpleWatertoAirHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
3002 :
3003 49906 : TotalCapRated = simpleWatertoAirHP.RatedCapCoolTotal;
3004 49906 : SensCapRated = simpleWatertoAirHP.RatedCapCoolSens;
3005 49906 : CoolPowerRated = simpleWatertoAirHP.RatedPowerCool;
3006 49906 : AirVolFlowRateRated = simpleWatertoAirHP.RatedAirVolFlowRate;
3007 49906 : WaterVolFlowRateRated = simpleWatertoAirHP.RatedWaterVolFlowRate;
3008 :
3009 49906 : Twet_Rated = simpleWatertoAirHP.Twet_Rated;
3010 49906 : Gamma_Rated = simpleWatertoAirHP.Gamma_Rated;
3011 :
3012 49906 : if (fanOp == HVAC::FanOp::Continuous) {
3013 6 : LoadSideFullMassFlowRate = simpleWatertoAirHP.AirMassFlowRate;
3014 : } else {
3015 : // default to cycling fan, cycling compressor, full load air flow
3016 49900 : if (PartLoadRatio > 0.0) {
3017 10169 : LoadSideFullMassFlowRate = simpleWatertoAirHP.AirMassFlowRate / PartLoadRatio;
3018 : } else {
3019 39731 : LoadSideFullMassFlowRate = 0.0;
3020 : }
3021 : }
3022 49906 : state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate = simpleWatertoAirHP.WaterMassFlowRate;
3023 49906 : state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp = simpleWatertoAirHP.InletWaterTemp;
3024 49906 : state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth = simpleWatertoAirHP.InletWaterEnthalpy;
3025 49906 : CpWater = state.dataPlnt->PlantLoop(simpleWatertoAirHP.plantLoc.loopNum)
3026 49906 : .glycol->getSpecificHeat(state, state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp, RoutineNameSourceSideInletTemp);
3027 :
3028 : // Check for flows, do not perform simulation if no flow in load side or source side.
3029 49906 : if (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate <= 0.0 || LoadSideFullMassFlowRate <= 0.0) {
3030 39735 : simpleWatertoAirHP.SimFlag = false;
3031 39735 : return;
3032 : } else {
3033 10171 : simpleWatertoAirHP.SimFlag = true;
3034 : }
3035 :
3036 10171 : if (compressorOp == HVAC::CompressorOp::Off) {
3037 0 : simpleWatertoAirHP.SimFlag = false;
3038 0 : return;
3039 : }
3040 :
3041 : // Calculate Part Load Factor and Runtime Fraction
3042 10171 : Real64 PLF = 1.0; // part load factor as a function of PLR, RTF = PLR / PLF
3043 10171 : if (simpleWatertoAirHP.PLFCurve != nullptr) {
3044 10171 : PLF = simpleWatertoAirHP.PLFCurve->value(state, PartLoadRatio); // Calculate part-load factor
3045 : }
3046 10171 : if (fanOp == HVAC::FanOp::Cycling) {
3047 10169 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
3048 : }
3049 10171 : simpleWatertoAirHP.RunFrac = PartLoadRatio / PLF;
3050 :
3051 : // Loop the calculation at least once depending whether the latent degradation model
3052 : // is enabled. 1st iteration to calculate the QLatent(rated) at (TDB,TWB)indoorair=(26.7C,19.4C)
3053 : // and 2nd iteration to calculate the QLatent(actual)
3054 10171 : if ((simpleWatertoAirHP.RunFrac >= 1.0) || (Twet_Rated <= 0.0) || (Gamma_Rated <= 0.0)) {
3055 10169 : LatDegradModelSimFlag = false;
3056 : // Set NumIteration=1 so that latent model would quit after 1 simulation with the actual condition
3057 10169 : NumIteration = 1;
3058 : } else {
3059 2 : LatDegradModelSimFlag = true;
3060 : // Set NumIteration=0 so that latent model would simulate twice with rated and actual condition
3061 2 : NumIteration = 0;
3062 : }
3063 :
3064 : // Set indoor air conditions to the actual condition
3065 10171 : LoadSideInletDBTemp_Unit = simpleWatertoAirHP.InletAirDBTemp;
3066 10171 : LoadSideInletHumRat_Unit = simpleWatertoAirHP.InletAirHumRat;
3067 : LoadSideInletWBTemp_Unit =
3068 10171 : Psychrometrics::PsyTwbFnTdbWPb(state, LoadSideInletDBTemp_Unit, LoadSideInletHumRat_Unit, state.dataEnvrn->OutBaroPress, RoutineName);
3069 10171 : LoadSideInletEnth_Unit = simpleWatertoAirHP.InletAirEnthalpy;
3070 10171 : CpAir_Unit = Psychrometrics::PsyCpAirFnW(LoadSideInletHumRat_Unit);
3071 :
3072 : while (true) {
3073 10173 : ++NumIteration;
3074 10173 : if (NumIteration == 1) {
3075 : // Set indoor air conditions to the rated conditions
3076 2 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp = state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp_Init;
3077 2 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat = state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat_Init;
3078 2 : state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp = state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp_Init;
3079 2 : state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth = state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth_Init;
3080 2 : CpAir = state.dataWaterToAirHeatPumpSimple->CpAir_Init;
3081 : } else {
3082 : // Set indoor air conditions to the actual condition
3083 10171 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp = LoadSideInletDBTemp_Unit;
3084 10171 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat = LoadSideInletHumRat_Unit;
3085 10171 : state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp = LoadSideInletWBTemp_Unit;
3086 10171 : state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth = LoadSideInletEnth_Unit;
3087 10171 : CpAir = CpAir_Unit;
3088 : }
3089 :
3090 10173 : ratioTDB = ((state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref);
3091 10173 : ratioTWB = ((state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref);
3092 10173 : ratioTS = ((state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref);
3093 10173 : ratioVL = (LoadSideFullMassFlowRate /
3094 10173 : (AirVolFlowRateRated * Psychrometrics::PsyRhoAirFnPbTdbW(state,
3095 10173 : state.dataEnvrn->StdBaroPress,
3096 10173 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp,
3097 10173 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat,
3098 : RoutineName)));
3099 :
3100 10173 : if (simpleWatertoAirHP.DesignWaterMassFlowRate > 0.0) {
3101 10173 : ratioVS = (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate) / (simpleWatertoAirHP.DesignWaterMassFlowRate);
3102 : } else {
3103 0 : ratioVS = 0.0;
3104 : }
3105 :
3106 10173 : simpleWatertoAirHP.QLoadTotal = TotalCapRated * simpleWatertoAirHP.TotalCoolCapCurve->value(state, ratioTWB, ratioTS, ratioVL, ratioVS);
3107 10173 : simpleWatertoAirHP.QSensible =
3108 10173 : SensCapRated * simpleWatertoAirHP.SensCoolCapCurve->value(state, ratioTDB, ratioTWB, ratioTS, ratioVL, ratioVS);
3109 20346 : state.dataWaterToAirHeatPumpSimple->Winput =
3110 10173 : CoolPowerRated * simpleWatertoAirHP.CoolPowCurve->value(state, ratioTWB, ratioTS, ratioVL, ratioVS);
3111 :
3112 : // Check if the Sensible Load is greater than the Total Cooling Load
3113 10173 : if (simpleWatertoAirHP.QSensible > simpleWatertoAirHP.QLoadTotal) {
3114 5 : simpleWatertoAirHP.QSensible = simpleWatertoAirHP.QLoadTotal;
3115 : }
3116 :
3117 10173 : if (LatDegradModelSimFlag) {
3118 : // Calculate for SHReff using the Latent Degradation Model
3119 4 : if (NumIteration == 1) {
3120 2 : state.dataWaterToAirHeatPumpSimple->QLatRated = simpleWatertoAirHP.QLoadTotal - simpleWatertoAirHP.QSensible;
3121 2 : } else if (NumIteration == 2) {
3122 2 : state.dataWaterToAirHeatPumpSimple->QLatActual = simpleWatertoAirHP.QLoadTotal - simpleWatertoAirHP.QSensible;
3123 2 : SHRss = simpleWatertoAirHP.QSensible / simpleWatertoAirHP.QLoadTotal;
3124 2 : SHReff = CalcEffectiveSHR(state,
3125 : HPNum,
3126 : SHRss,
3127 : fanOp,
3128 : simpleWatertoAirHP.RunFrac,
3129 2 : state.dataWaterToAirHeatPumpSimple->QLatRated,
3130 2 : state.dataWaterToAirHeatPumpSimple->QLatActual,
3131 2 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp,
3132 2 : state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp);
3133 : // Update sensible capacity based on effective SHR
3134 2 : simpleWatertoAirHP.QSensible = simpleWatertoAirHP.QLoadTotal * SHReff;
3135 2 : break;
3136 : }
3137 : } else {
3138 : // Assume SHReff=SHRss
3139 10169 : SHReff = simpleWatertoAirHP.QSensible / simpleWatertoAirHP.QLoadTotal;
3140 10169 : break;
3141 : }
3142 : }
3143 :
3144 : // calculate coil outlet state variables
3145 10171 : LoadSideFullOutletEnthalpy = state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth - simpleWatertoAirHP.QLoadTotal / LoadSideFullMassFlowRate;
3146 20342 : state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp =
3147 10171 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp - simpleWatertoAirHP.QSensible / (LoadSideFullMassFlowRate * CpAir);
3148 20342 : state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat =
3149 10171 : Psychrometrics::PsyWFnTdbH(state, state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp, LoadSideFullOutletEnthalpy, RoutineName);
3150 : // Actual outlet conditions are "average" for time step
3151 10171 : if (fanOp == HVAC::FanOp::Continuous) {
3152 : // continuous fan, cycling compressor
3153 2 : simpleWatertoAirHP.OutletAirEnthalpy =
3154 2 : PartLoadRatio * LoadSideFullOutletEnthalpy + (1.0 - PartLoadRatio) * state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth;
3155 2 : simpleWatertoAirHP.OutletAirHumRat = PartLoadRatio * state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat +
3156 2 : (1.0 - PartLoadRatio) * state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat;
3157 2 : simpleWatertoAirHP.OutletAirDBTemp = Psychrometrics::PsyTdbFnHW(simpleWatertoAirHP.OutletAirEnthalpy, simpleWatertoAirHP.OutletAirHumRat);
3158 : } else {
3159 : // default to cycling fan, cycling compressor
3160 10169 : simpleWatertoAirHP.OutletAirEnthalpy = LoadSideFullOutletEnthalpy;
3161 10169 : simpleWatertoAirHP.OutletAirHumRat = state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat;
3162 10169 : simpleWatertoAirHP.OutletAirDBTemp = state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp;
3163 : }
3164 :
3165 : // scale heat transfer rates to PLR and power to RTF
3166 10171 : simpleWatertoAirHP.QLoadTotal *= PartLoadRatio;
3167 20342 : simpleWatertoAirHP.QLoadTotalReport = simpleWatertoAirHP.AirMassFlowRate *
3168 10171 : (state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth -
3169 10171 : Psychrometrics::PsyHFnTdbW(simpleWatertoAirHP.OutletAirDBTemp,
3170 : simpleWatertoAirHP.OutletAirHumRat)); // Why doesn't this match QLoadTotal?
3171 10171 : simpleWatertoAirHP.QSensible *= PartLoadRatio;
3172 10171 : state.dataWaterToAirHeatPumpSimple->Winput *= simpleWatertoAirHP.RunFrac;
3173 10171 : simpleWatertoAirHP.QSource = simpleWatertoAirHP.QLoadTotalReport + state.dataWaterToAirHeatPumpSimple->Winput;
3174 10171 : state.dataHeatBal->HeatReclaimSimple_WAHPCoil(HPNum).AvailCapacity = simpleWatertoAirHP.QSource;
3175 :
3176 : // Add power to global variable so power can be summed by parent object
3177 10171 : state.dataHVACGlobal->DXElecCoolingPower = state.dataWaterToAirHeatPumpSimple->Winput;
3178 :
3179 10171 : DataHeatBalance::HeatReclaimDataBase &HeatReclaim = state.dataHeatBal->HeatReclaimSimple_WAHPCoil(HPNum);
3180 10171 : HeatReclaim.WaterHeatingDesuperheaterReclaimedHeatTotal = 0.0;
3181 10171 : if (allocated(HeatReclaim.WaterHeatingDesuperheaterReclaimedHeat)) {
3182 4 : for (auto const &num : HeatReclaim.WaterHeatingDesuperheaterReclaimedHeat) {
3183 2 : HeatReclaim.WaterHeatingDesuperheaterReclaimedHeatTotal += num;
3184 : }
3185 : }
3186 10171 : simpleWatertoAirHP.QSource -= HeatReclaim.WaterHeatingDesuperheaterReclaimedHeatTotal;
3187 :
3188 : // Update heat pump data structure
3189 10171 : simpleWatertoAirHP.Power = state.dataWaterToAirHeatPumpSimple->Winput;
3190 10171 : simpleWatertoAirHP.QLoadTotal = simpleWatertoAirHP.QLoadTotalReport;
3191 10171 : simpleWatertoAirHP.QLatent = simpleWatertoAirHP.QLoadTotalReport - simpleWatertoAirHP.QSensible;
3192 10171 : simpleWatertoAirHP.Energy = state.dataWaterToAirHeatPumpSimple->Winput * TimeStepSysSec;
3193 10171 : simpleWatertoAirHP.EnergyLoadTotal = simpleWatertoAirHP.QLoadTotalReport * TimeStepSysSec;
3194 10171 : simpleWatertoAirHP.EnergySensible = simpleWatertoAirHP.QSensible * TimeStepSysSec;
3195 10171 : simpleWatertoAirHP.EnergyLatent = (simpleWatertoAirHP.QLoadTotalReport - simpleWatertoAirHP.QSensible) * TimeStepSysSec;
3196 10171 : simpleWatertoAirHP.EnergySource = simpleWatertoAirHP.QSource * TimeStepSysSec;
3197 10171 : if (simpleWatertoAirHP.RunFrac == 0.0) {
3198 0 : simpleWatertoAirHP.COP = 0.0;
3199 : } else {
3200 10171 : simpleWatertoAirHP.COP = simpleWatertoAirHP.QLoadTotalReport / state.dataWaterToAirHeatPumpSimple->Winput;
3201 : }
3202 10171 : simpleWatertoAirHP.PartLoadRatio = PartLoadRatio;
3203 :
3204 10171 : if ((simpleWatertoAirHP.WaterCyclingMode) == HVAC::WaterFlow::Cycling) {
3205 : // plant can lock flow at coil water inlet node, use design flow multiplied by PLR to calculate water mass flow rate
3206 10163 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate * PartLoadRatio;
3207 10163 : PlantUtilities::SetComponentFlowRate(state,
3208 10163 : simpleWatertoAirHP.WaterMassFlowRate,
3209 : simpleWatertoAirHP.WaterInletNodeNum,
3210 : simpleWatertoAirHP.WaterOutletNodeNum,
3211 10163 : simpleWatertoAirHP.plantLoc);
3212 10163 : if (simpleWatertoAirHP.WaterMassFlowRate > 0.0) {
3213 10163 : simpleWatertoAirHP.OutletWaterTemp = state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp +
3214 10163 : simpleWatertoAirHP.QSource / (simpleWatertoAirHP.WaterMassFlowRate * CpWater);
3215 10163 : simpleWatertoAirHP.OutletWaterEnthalpy =
3216 10163 : state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth + simpleWatertoAirHP.QSource / simpleWatertoAirHP.WaterMassFlowRate;
3217 : }
3218 : } else {
3219 8 : if ((simpleWatertoAirHP.WaterCyclingMode) == HVAC::WaterFlow::Constant) {
3220 0 : if (simpleWatertoAirHP.WaterFlowMode) {
3221 0 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate;
3222 0 : PlantUtilities::SetComponentFlowRate(state,
3223 0 : simpleWatertoAirHP.WaterMassFlowRate,
3224 : simpleWatertoAirHP.WaterInletNodeNum,
3225 : simpleWatertoAirHP.WaterOutletNodeNum,
3226 0 : simpleWatertoAirHP.plantLoc);
3227 : } else {
3228 0 : simpleWatertoAirHP.WaterMassFlowRate = state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3229 : }
3230 : } else {
3231 8 : simpleWatertoAirHP.WaterMassFlowRate = state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3232 : }
3233 8 : simpleWatertoAirHP.OutletWaterTemp = state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp +
3234 8 : simpleWatertoAirHP.QSource / (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate * CpWater);
3235 8 : simpleWatertoAirHP.OutletWaterEnthalpy = state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth +
3236 8 : simpleWatertoAirHP.QSource / state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3237 : }
3238 : }
3239 :
3240 49902 : void CalcHPHeatingSimple(EnergyPlusData &state,
3241 : int const HPNum, // Heat Pump Number
3242 : HVAC::FanOp const fanOp, // Fan/Compressor cycling scheme indicator
3243 : [[maybe_unused]] Real64 const SensDemand, // Sensible Demand [W] !unused1208
3244 : HVAC::CompressorOp const compressorOp, // compressor operation flag
3245 : Real64 const PartLoadRatio, // compressor part load ratio
3246 : [[maybe_unused]] Real64 const OnOffAirFlowRatio // ratio of compressor on flow to average flow over time step
3247 : )
3248 : {
3249 :
3250 : // AUTHOR Arun Shenoy
3251 : // DATE WRITTEN Jan 2004
3252 : // RE-ENGINEERED Kenneth Tang (Jan 2005)
3253 :
3254 : // PURPOSE OF THIS SUBROUTINE:
3255 : // This subroutine is for simulating the heating mode of the Water to Air HP Simple
3256 :
3257 : // METHODOLOGY EMPLOYED:
3258 : // Simulate the heat pump performance using the coefficients in quadlinear and quintlinear curves and rated conditions
3259 : // Finally, adjust the heat pump outlet conditions based on the PartLoadRatio
3260 : // and RuntimeFrac.
3261 :
3262 : // REFERENCES:
3263 : // (1) Lash.T.A.,1992.Simulation and Analysis of a Water Loop Heat Pump System.
3264 : // M.S. Thesis, University of Illinois at Urbana Champaign.
3265 : // (2) Shenoy, Arun. 2004. Simulation, Modeling and Analysis of Water to Air Heat Pump.
3266 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
3267 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
3268 : // (3) Tang,C.C.. 2005. Modeling Packaged Heat Pumps in a Quasi-Steady
3269 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
3270 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
3271 :
3272 49902 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
3273 :
3274 : // SUBROUTINE PARAMETER DEFINITIONS:
3275 49902 : Real64 constexpr Tref(283.15); // Reference Temperature for performance curves,10C [K]
3276 : static constexpr std::string_view RoutineName("CalcHPHeatingSimple");
3277 : static constexpr std::string_view RoutineNameSourceSideInletTemp("CalcHPHeatingSimple:SourceSideInletTemp");
3278 :
3279 : Real64 HeatCapRated; // Rated Heating Capacity [W]
3280 : Real64 HeatPowerRated; // Rated Heating Power Input[W]
3281 : Real64 AirVolFlowRateRated; // Rated Air Volumetric Flow Rate [m3/s]
3282 : Real64 WaterVolFlowRateRated; // Rated Water Volumetric Flow Rate [m3/s]
3283 : Real64 ratioTDB; // Ratio of the inlet air dry bulb temperature to the rated conditions
3284 : Real64 ratioTS; // Ratio of the source side (water) inlet temperature to the rated conditions
3285 : Real64 ratioVL; // Ratio of the load side flow rate to the rated conditions
3286 : Real64 ratioVS; // Ratio of the source side flow rate to the rated conditions
3287 : Real64 CpWater; // Specific heat of water [J/kg_C]
3288 : Real64 CpAir; // Specific heat of air [J/kg_C]
3289 : Real64 LoadSideFullMassFlowRate; // Load Side Full Load Mass Flow Rate [kg/s]
3290 : Real64 LoadSideFullOutletEnthalpy; // Load Side Full Load Outlet Air Enthalpy [J/kg]
3291 :
3292 : // LOAD LOCAL VARIABLES FROM DATA STRUCTURE (for code readability)
3293 :
3294 49902 : auto &simpleWatertoAirHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
3295 :
3296 49902 : HeatCapRated = simpleWatertoAirHP.RatedCapHeat;
3297 49902 : HeatPowerRated = simpleWatertoAirHP.RatedPowerHeat;
3298 49902 : AirVolFlowRateRated = simpleWatertoAirHP.RatedAirVolFlowRate;
3299 49902 : WaterVolFlowRateRated = simpleWatertoAirHP.RatedWaterVolFlowRate;
3300 49902 : if (fanOp == HVAC::FanOp::Continuous) {
3301 6 : LoadSideFullMassFlowRate = simpleWatertoAirHP.AirMassFlowRate;
3302 : } else {
3303 : // default to cycling fan, cycling compressor, full load air flow
3304 49896 : if (PartLoadRatio > 0.0) {
3305 32275 : LoadSideFullMassFlowRate = simpleWatertoAirHP.AirMassFlowRate / PartLoadRatio;
3306 : } else {
3307 17621 : LoadSideFullMassFlowRate = 0.0;
3308 : }
3309 : }
3310 49902 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp = simpleWatertoAirHP.InletAirDBTemp;
3311 49902 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat = simpleWatertoAirHP.InletAirHumRat;
3312 :
3313 99804 : state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp =
3314 49902 : Psychrometrics::PsyTwbFnTdbWPb(state,
3315 49902 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp,
3316 49902 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat,
3317 49902 : state.dataEnvrn->OutBaroPress,
3318 : RoutineName);
3319 49902 : state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth = simpleWatertoAirHP.InletAirEnthalpy;
3320 49902 : CpAir = Psychrometrics::PsyCpAirFnW(state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat);
3321 49902 : state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate = simpleWatertoAirHP.WaterMassFlowRate;
3322 49902 : state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp = simpleWatertoAirHP.InletWaterTemp;
3323 49902 : state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth = simpleWatertoAirHP.InletWaterEnthalpy;
3324 49902 : CpWater = state.dataPlnt->PlantLoop(simpleWatertoAirHP.plantLoc.loopNum)
3325 49902 : .glycol->getSpecificHeat(state, state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp, RoutineNameSourceSideInletTemp);
3326 :
3327 : // Check for flows, do not perform simulation if no flow in load side or source side.
3328 49902 : if (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate <= 0.0 || LoadSideFullMassFlowRate <= 0.0) {
3329 17643 : simpleWatertoAirHP.SimFlag = false;
3330 17643 : return;
3331 : } else {
3332 32259 : simpleWatertoAirHP.SimFlag = true;
3333 : }
3334 :
3335 32259 : if (compressorOp == HVAC::CompressorOp::Off) {
3336 0 : simpleWatertoAirHP.SimFlag = false;
3337 0 : return;
3338 : }
3339 :
3340 : // Calculate Part Load Factor and Runtime Fraction
3341 32259 : Real64 PLF = 1.0; // part load factor as a function of PLR, RTF = PLR / PLF
3342 32259 : if (simpleWatertoAirHP.PLFCurve != nullptr) {
3343 32259 : PLF = simpleWatertoAirHP.PLFCurve->value(state, PartLoadRatio); // Calculate part-load factor
3344 : }
3345 32259 : if (fanOp == HVAC::FanOp::Cycling) {
3346 32257 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
3347 : }
3348 32259 : simpleWatertoAirHP.RunFrac = PartLoadRatio / PLF;
3349 :
3350 32259 : ratioTDB = ((state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref);
3351 32259 : ratioTS = ((state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref);
3352 32259 : ratioVL = (LoadSideFullMassFlowRate /
3353 32259 : (AirVolFlowRateRated * Psychrometrics::PsyRhoAirFnPbTdbW(state,
3354 32259 : state.dataEnvrn->StdBaroPress,
3355 32259 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp,
3356 32259 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat,
3357 : RoutineName)));
3358 32259 : if (simpleWatertoAirHP.DesignWaterMassFlowRate > 0.0) {
3359 32259 : ratioVS = (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate) / (simpleWatertoAirHP.DesignWaterMassFlowRate);
3360 : } else {
3361 0 : ratioVS = 0.0;
3362 : }
3363 :
3364 32259 : simpleWatertoAirHP.QLoadTotal = HeatCapRated * simpleWatertoAirHP.HeatCapCurve->value(state, ratioTDB, ratioTS, ratioVL, ratioVS);
3365 32259 : simpleWatertoAirHP.QSensible = simpleWatertoAirHP.QLoadTotal;
3366 64518 : state.dataWaterToAirHeatPumpSimple->Winput =
3367 32259 : HeatPowerRated * simpleWatertoAirHP.HeatPowCurve->value(state, ratioTDB, ratioTS, ratioVL, ratioVS);
3368 :
3369 : // calculate coil outlet state variables
3370 32259 : LoadSideFullOutletEnthalpy = state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth + simpleWatertoAirHP.QLoadTotal / LoadSideFullMassFlowRate;
3371 64518 : state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp =
3372 32259 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp + simpleWatertoAirHP.QSensible / (LoadSideFullMassFlowRate * CpAir);
3373 64518 : state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat =
3374 32259 : Psychrometrics::PsyWFnTdbH(state, state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp, LoadSideFullOutletEnthalpy, RoutineName);
3375 :
3376 : // Actual outlet conditions are "average" for time step
3377 32259 : if (fanOp == HVAC::FanOp::Continuous) {
3378 : // continuous fan, cycling compressor
3379 2 : simpleWatertoAirHP.OutletAirEnthalpy =
3380 2 : PartLoadRatio * LoadSideFullOutletEnthalpy + (1.0 - PartLoadRatio) * state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth;
3381 2 : simpleWatertoAirHP.OutletAirHumRat = PartLoadRatio * state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat +
3382 2 : (1.0 - PartLoadRatio) * state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat;
3383 2 : simpleWatertoAirHP.OutletAirDBTemp = Psychrometrics::PsyTdbFnHW(simpleWatertoAirHP.OutletAirEnthalpy, simpleWatertoAirHP.OutletAirHumRat);
3384 : } else {
3385 : // default to cycling fan, cycling compressor
3386 32257 : simpleWatertoAirHP.OutletAirEnthalpy = LoadSideFullOutletEnthalpy;
3387 32257 : simpleWatertoAirHP.OutletAirHumRat = state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat;
3388 32257 : simpleWatertoAirHP.OutletAirDBTemp = state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp;
3389 : }
3390 :
3391 : // scale heat transfer rates to PLR and power to RTF
3392 32259 : simpleWatertoAirHP.QLoadTotal *= PartLoadRatio;
3393 32259 : simpleWatertoAirHP.QLoadTotalReport = simpleWatertoAirHP.QLoadTotal;
3394 32259 : simpleWatertoAirHP.QSensible *= PartLoadRatio;
3395 32259 : state.dataWaterToAirHeatPumpSimple->Winput *= simpleWatertoAirHP.RunFrac;
3396 32259 : simpleWatertoAirHP.QSource = simpleWatertoAirHP.QLoadTotalReport - state.dataWaterToAirHeatPumpSimple->Winput;
3397 :
3398 : // Add power to global variable so power can be summed by parent object
3399 32259 : state.dataHVACGlobal->DXElecHeatingPower = state.dataWaterToAirHeatPumpSimple->Winput;
3400 :
3401 : // Update heat pump data structure
3402 32259 : simpleWatertoAirHP.Power = state.dataWaterToAirHeatPumpSimple->Winput;
3403 32259 : simpleWatertoAirHP.QLoadTotal = simpleWatertoAirHP.QLoadTotalReport;
3404 32259 : simpleWatertoAirHP.QSensible = simpleWatertoAirHP.QSensible;
3405 32259 : simpleWatertoAirHP.Energy = state.dataWaterToAirHeatPumpSimple->Winput * TimeStepSysSec;
3406 32259 : simpleWatertoAirHP.EnergyLoadTotal = simpleWatertoAirHP.QLoadTotalReport * TimeStepSysSec;
3407 32259 : simpleWatertoAirHP.EnergySensible = simpleWatertoAirHP.QSensible * TimeStepSysSec;
3408 32259 : simpleWatertoAirHP.EnergyLatent = 0.0;
3409 32259 : simpleWatertoAirHP.EnergySource = simpleWatertoAirHP.QSource * TimeStepSysSec;
3410 32259 : if (simpleWatertoAirHP.RunFrac == 0.0) {
3411 0 : simpleWatertoAirHP.COP = 0.0;
3412 : } else {
3413 32259 : simpleWatertoAirHP.COP = simpleWatertoAirHP.QLoadTotalReport / state.dataWaterToAirHeatPumpSimple->Winput;
3414 : }
3415 32259 : simpleWatertoAirHP.PartLoadRatio = PartLoadRatio;
3416 :
3417 32259 : if ((simpleWatertoAirHP.WaterCyclingMode) == HVAC::WaterFlow::Cycling) {
3418 : // plant can lock flow at coil water inlet node, use design flow multiplied by PLR to calculate water mass flow rate
3419 32253 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate * PartLoadRatio;
3420 32253 : PlantUtilities::SetComponentFlowRate(state,
3421 32253 : simpleWatertoAirHP.WaterMassFlowRate,
3422 : simpleWatertoAirHP.WaterInletNodeNum,
3423 : simpleWatertoAirHP.WaterOutletNodeNum,
3424 32253 : simpleWatertoAirHP.plantLoc);
3425 32253 : if (simpleWatertoAirHP.WaterMassFlowRate > 0.0) {
3426 32253 : simpleWatertoAirHP.OutletWaterTemp = state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp -
3427 32253 : simpleWatertoAirHP.QSource / (simpleWatertoAirHP.WaterMassFlowRate * CpWater);
3428 32253 : simpleWatertoAirHP.OutletWaterEnthalpy =
3429 32253 : state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth - simpleWatertoAirHP.QSource / simpleWatertoAirHP.WaterMassFlowRate;
3430 : }
3431 : } else {
3432 6 : if ((simpleWatertoAirHP.WaterCyclingMode) == HVAC::WaterFlow::Constant) {
3433 0 : if (simpleWatertoAirHP.WaterFlowMode) {
3434 0 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate;
3435 0 : PlantUtilities::SetComponentFlowRate(state,
3436 0 : simpleWatertoAirHP.WaterMassFlowRate,
3437 : simpleWatertoAirHP.WaterInletNodeNum,
3438 : simpleWatertoAirHP.WaterOutletNodeNum,
3439 0 : simpleWatertoAirHP.plantLoc);
3440 : } else {
3441 0 : simpleWatertoAirHP.WaterMassFlowRate = state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3442 : }
3443 : } else {
3444 6 : simpleWatertoAirHP.WaterMassFlowRate = state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3445 : }
3446 6 : simpleWatertoAirHP.OutletWaterTemp = state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp -
3447 6 : simpleWatertoAirHP.QSource / (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate * CpWater);
3448 6 : simpleWatertoAirHP.OutletWaterEnthalpy = state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth -
3449 6 : simpleWatertoAirHP.QSource / state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3450 : }
3451 : }
3452 :
3453 99790 : void UpdateSimpleWatertoAirHP(EnergyPlusData &state, int const HPNum)
3454 : {
3455 : // SUBROUTINE INFORMATION:
3456 : // AUTHOR Arun Shenoy
3457 : // DATE WRITTEN Jan 2004
3458 : // RE-ENGINEERED Kenneth Tang (Jan 2005)
3459 :
3460 : // PURPOSE OF THIS SUBROUTINE:
3461 : // This subroutine updates the Water to Air Heat Pump outlet nodes.
3462 :
3463 : // METHODOLOGY EMPLOYED:
3464 : // Data is moved from the HP data structure to the HP outlet nodes.
3465 :
3466 99790 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
3467 :
3468 : // SUBROUTINE LOCAL VARIABLE DECLARATIONS:
3469 : int AirInletNode;
3470 : int WaterInletNode;
3471 : int AirOutletNode;
3472 : int WaterOutletNode;
3473 :
3474 99790 : auto &simpleWatertoAirHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
3475 :
3476 99790 : if (!simpleWatertoAirHP.SimFlag) {
3477 : // Heatpump is off; just pass through conditions
3478 57378 : simpleWatertoAirHP.Power = 0.0;
3479 57378 : simpleWatertoAirHP.QLoadTotal = 0.0;
3480 57378 : simpleWatertoAirHP.QLoadTotalReport = 0.0;
3481 57378 : simpleWatertoAirHP.QSensible = 0.0;
3482 57378 : simpleWatertoAirHP.QLatent = 0.0;
3483 57378 : simpleWatertoAirHP.QSource = 0.0;
3484 57378 : simpleWatertoAirHP.Energy = 0.0;
3485 57378 : simpleWatertoAirHP.EnergyLoadTotal = 0.0;
3486 57378 : simpleWatertoAirHP.EnergySensible = 0.0;
3487 57378 : simpleWatertoAirHP.EnergyLatent = 0.0;
3488 57378 : simpleWatertoAirHP.EnergySource = 0.0;
3489 57378 : simpleWatertoAirHP.COP = 0.0;
3490 57378 : simpleWatertoAirHP.RunFrac = 0.0;
3491 57378 : simpleWatertoAirHP.PartLoadRatio = 0.0;
3492 :
3493 57378 : simpleWatertoAirHP.OutletAirDBTemp = simpleWatertoAirHP.InletAirDBTemp;
3494 57378 : simpleWatertoAirHP.OutletAirHumRat = simpleWatertoAirHP.InletAirHumRat;
3495 57378 : simpleWatertoAirHP.OutletAirEnthalpy = simpleWatertoAirHP.InletAirEnthalpy;
3496 57378 : simpleWatertoAirHP.OutletWaterTemp = simpleWatertoAirHP.InletWaterTemp;
3497 57378 : simpleWatertoAirHP.OutletWaterEnthalpy = simpleWatertoAirHP.InletWaterEnthalpy;
3498 : }
3499 :
3500 99790 : AirInletNode = simpleWatertoAirHP.AirInletNodeNum;
3501 99790 : WaterInletNode = simpleWatertoAirHP.WaterInletNodeNum;
3502 99790 : AirOutletNode = simpleWatertoAirHP.AirOutletNodeNum;
3503 99790 : WaterOutletNode = simpleWatertoAirHP.WaterOutletNodeNum;
3504 :
3505 : // Set the air outlet nodes of the WatertoAirHPSimple
3506 99790 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRate = state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
3507 99790 : state.dataLoopNodes->Node(AirOutletNode).Temp = simpleWatertoAirHP.OutletAirDBTemp;
3508 99790 : state.dataLoopNodes->Node(AirOutletNode).HumRat = simpleWatertoAirHP.OutletAirHumRat;
3509 99790 : state.dataLoopNodes->Node(AirOutletNode).Enthalpy = simpleWatertoAirHP.OutletAirEnthalpy;
3510 :
3511 : // Set the air outlet nodes for properties that just pass through & not used
3512 99790 : state.dataLoopNodes->Node(AirOutletNode).Quality = state.dataLoopNodes->Node(AirInletNode).Quality;
3513 99790 : state.dataLoopNodes->Node(AirOutletNode).Press = state.dataLoopNodes->Node(AirInletNode).Press;
3514 99790 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMin = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMin;
3515 99790 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMax = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax;
3516 99790 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMinAvail;
3517 99790 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMaxAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMaxAvail;
3518 :
3519 : // Set the water outlet node of the WatertoAirHPSimple
3520 : // Set the water outlet nodes for properties that just pass through & not used
3521 99790 : PlantUtilities::SafeCopyPlantNode(state, WaterInletNode, WaterOutletNode);
3522 :
3523 99790 : state.dataLoopNodes->Node(WaterOutletNode).Temp = simpleWatertoAirHP.OutletWaterTemp;
3524 99790 : state.dataLoopNodes->Node(WaterOutletNode).Enthalpy = simpleWatertoAirHP.OutletWaterEnthalpy;
3525 :
3526 99790 : simpleWatertoAirHP.Energy = simpleWatertoAirHP.Power * TimeStepSysSec;
3527 99790 : simpleWatertoAirHP.EnergyLoadTotal = simpleWatertoAirHP.QLoadTotal * TimeStepSysSec;
3528 99790 : simpleWatertoAirHP.EnergySensible = simpleWatertoAirHP.QSensible * TimeStepSysSec;
3529 99790 : simpleWatertoAirHP.EnergyLatent = simpleWatertoAirHP.QLatent * TimeStepSysSec;
3530 99790 : simpleWatertoAirHP.EnergySource = simpleWatertoAirHP.QSource * TimeStepSysSec;
3531 :
3532 99790 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
3533 0 : state.dataLoopNodes->Node(AirOutletNode).CO2 = state.dataLoopNodes->Node(AirInletNode).CO2;
3534 : }
3535 99790 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
3536 0 : state.dataLoopNodes->Node(AirOutletNode).GenContam = state.dataLoopNodes->Node(AirInletNode).GenContam;
3537 : }
3538 :
3539 99790 : if (simpleWatertoAirHP.reportCoilFinalSizes) {
3540 10 : if (!state.dataGlobal->WarmupFlag && !state.dataGlobal->DoingHVACSizingSimulations && !state.dataGlobal->DoingSizing) {
3541 :
3542 8 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
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.RatedCapCoolTotal,
3548 : simpleWatertoAirHP.RatedCapCoolSens,
3549 : simpleWatertoAirHP.RatedAirVolFlowRate,
3550 : simpleWatertoAirHP.RatedWaterVolFlowRate);
3551 4 : } else if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating) {
3552 4 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(
3553 : state,
3554 4 : simpleWatertoAirHP.Name,
3555 8 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
3556 : simpleWatertoAirHP.RatedCapHeat,
3557 : simpleWatertoAirHP.RatedCapHeat,
3558 : simpleWatertoAirHP.RatedAirVolFlowRate,
3559 : simpleWatertoAirHP.RatedWaterVolFlowRate);
3560 : }
3561 8 : simpleWatertoAirHP.reportCoilFinalSizes = false;
3562 : }
3563 : }
3564 99790 : }
3565 :
3566 : // End of Update subroutines for the WatertoAirHP Module
3567 : // *****************************************************************************
3568 :
3569 2 : Real64 CalcEffectiveSHR(EnergyPlusData &state,
3570 : int const HPNum, // Index number for cooling coil
3571 : Real64 const SHRss, // Steady-state sensible heat ratio
3572 : HVAC::FanOp const fanOp, // Fan/compressor cycling scheme indicator
3573 : Real64 const RTF, // Compressor run-time fraction
3574 : Real64 const QLatRated, // Rated latent capacity
3575 : Real64 const QLatActual, // Actual latent capacity
3576 : Real64 const EnteringDB, // Entering air dry-bulb temperature
3577 : Real64 const EnteringWB // Entering air wet-bulb temperature
3578 : )
3579 : {
3580 :
3581 : // FUNCTION INFORMATION:
3582 : // AUTHOR Richard Raustad, FSEC
3583 : // DATE WRITTEN September 2003
3584 : // MODIFIED Kenneth Tang (Aug 2004) Added capability for simulating FanOp::Cycling
3585 :
3586 : // PURPOSE OF THIS FUNCTION:
3587 : // Adjust sensible heat ratio to account for degradation of DX coil latent
3588 : // capacity at part-load (cycling) conditions.
3589 :
3590 : // METHODOLOGY EMPLOYED:
3591 : // With model parameters entered by the user, the part-load latent performance
3592 : // of a DX cooling coil is determined for a constant air flow system with
3593 : // a cooling coil that cycles on/off. The model calculates the time
3594 : // required for condensate to begin falling from the cooling coil.
3595 : // Runtimes greater than this are integrated to a "part-load" latent
3596 : // capacity which is used to determine the "part-load" sensible heat ratio.
3597 : // See reference below for additional details (linear decay model, Eq. 8b).
3598 :
3599 : // For cycling fan operation, a modified version of Henderson and Rengarajan (1996)
3600 : // model is used by ultilizing the fan delay time as the time-off (or time duration
3601 : // for the re-evaporation of moisture from time coil). Refer to Tang, C.C. (2005)
3602 :
3603 : // REFERENCES:
3604 : // (1) Henderson, H.I., K. Rengarajan.1996. A Model to Predict the Latent
3605 : // Capacity of Air Conditioners and Heat Pumps at Part-Load Conditions
3606 : // with Constant Fan Operation ASHRAE Transactions 102 (1), pp. 266-274.
3607 : // (2) Tang,C.C.. 2005. Modeling Packaged Heat Pumps in a Quasi-Steady
3608 : // State Energy Simulation Program. M.S. Thesis, Department of Mechanical and Aerospace Engineering,
3609 : // Oklahoma State University. (downloadable from www.hvac.okstate.edu)
3610 :
3611 : // Return value
3612 : Real64 SHReff; // Effective sensible heat ratio, includes degradation due to cycling effects
3613 :
3614 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3615 : Real64 Twet; // Nominal time for condensate to begin leaving the coil's condensate drain line
3616 : // at the current operating conditions (sec)
3617 : Real64 Gamma; // Initial moisture evaporation rate divided by steady-state AC latent capacity
3618 : // at the current operating conditions
3619 : Real64 Twet_Rated; // Twet at rated conditions (coil air flow rate and air temperatures), sec
3620 : Real64 Gamma_Rated; // Gamma at rated conditions (coil air flow rate and air temperatures)
3621 : Real64 Twet_max; // Maximum allowed value for Twet
3622 : Real64 MaxONOFFCyclesperHour; // Maximum cycling rate of heat pump [cycles/hr]
3623 : Real64 LatentCapacityTimeConstant; // Latent capacity time constant [s]
3624 : Real64 FanDelayTime; // Fan delay time, time delay for the HP's fan to
3625 : // shut off after compressor cycle off [s]
3626 : Real64 Ton; // Coil on time (sec)
3627 : Real64 Toff; // Coil off time (sec)
3628 : Real64 Toffa; // Actual coil off time (sec). Equations valid for Toff <= (2.0 * Twet/Gamma)
3629 : Real64 aa; // Intermediate variable
3630 : Real64 To1; // Intermediate variable (first guess at To). To = time to the start of moisture removal
3631 : Real64 To2; // Intermediate variable (second guess at To). To = time to the start of moisture removal
3632 : Real64 Error; // Error for iteration (DO) loop
3633 : Real64 LHRmult; // Latent Heat Ratio (LHR) multiplier. The effective latent heat ratio LHR = (1-SHRss)*LHRmult
3634 :
3635 2 : auto const &simpleWatertoAirHP = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum);
3636 :
3637 2 : Twet_Rated = simpleWatertoAirHP.Twet_Rated;
3638 2 : Gamma_Rated = simpleWatertoAirHP.Gamma_Rated;
3639 2 : MaxONOFFCyclesperHour = simpleWatertoAirHP.MaxONOFFCyclesperHour;
3640 2 : LatentCapacityTimeConstant = simpleWatertoAirHP.LatentCapacityTimeConstant;
3641 2 : FanDelayTime = simpleWatertoAirHP.FanDelayTime;
3642 :
3643 : // No moisture evaporation (latent degradation) occurs for runtime fraction of 1.0
3644 : // All latent degradation model parameters cause divide by 0.0 if not greater than 0.0
3645 : // Latent degradation model parameters initialize to 0.0 meaning no evaporation model used.
3646 2 : if ((RTF >= 1.0) || (QLatRated == 0.0) || (QLatActual == 0.0) || (Twet_Rated <= 0.0) || (Gamma_Rated <= 0.0) ||
3647 0 : (MaxONOFFCyclesperHour <= 0.0) || (LatentCapacityTimeConstant <= 0.0) || (RTF <= 0.0)) {
3648 2 : SHReff = SHRss;
3649 2 : return SHReff;
3650 : }
3651 :
3652 0 : Twet_max = 9999.0; // high limit for Twet
3653 :
3654 : // Calculate the model parameters at the actual operating conditions
3655 0 : Twet = min(Twet_Rated * QLatRated / (QLatActual + 1.e-10), Twet_max);
3656 0 : Gamma = Gamma_Rated * QLatRated * (EnteringDB - EnteringWB) / ((26.7 - 19.4) * QLatActual + 1.e-10);
3657 :
3658 : // Calculate the compressor on and off times using a converntional thermostat curve
3659 0 : Ton = 3600.0 / (4.0 * MaxONOFFCyclesperHour * (1.0 - RTF)); // duration of cooling coil on-cycle (sec)
3660 :
3661 0 : if ((fanOp == HVAC::FanOp::Cycling) && (FanDelayTime != 0.0)) {
3662 : // For FanOp::Cycling, moisture is evaporated from the cooling coil back to the air stream
3663 : // until the fan cycle off. Assume no evaporation from the coil after the fan shuts off.
3664 0 : Toff = FanDelayTime;
3665 : } else {
3666 : // For FanOp::Continuous, moisture is evaporated from the cooling coil back to the air stream
3667 : // for the entire heat pump off-cycle.
3668 0 : Toff = 3600.0 / (4.0 * MaxONOFFCyclesperHour * RTF); // duration of cooling coil off-cycle (sec)
3669 : }
3670 :
3671 : // Cap Toff to meet the equation restriction
3672 0 : if (Gamma > 0.0) {
3673 0 : Toffa = min(Toff, 2.0 * Twet / Gamma);
3674 : } else {
3675 0 : Toffa = Toff;
3676 : }
3677 :
3678 : // Use sucessive substitution to solve for To
3679 0 : aa = (Gamma * Toffa) - (0.25 / Twet) * pow_2(Gamma) * pow_2(Toffa);
3680 :
3681 0 : To1 = aa + LatentCapacityTimeConstant;
3682 0 : Error = 1.0;
3683 0 : while (Error > 0.001) {
3684 0 : To2 = aa - LatentCapacityTimeConstant * std::expm1(-To1 / LatentCapacityTimeConstant);
3685 0 : Error = std::abs((To2 - To1) / To1);
3686 0 : To1 = To2;
3687 : }
3688 :
3689 : // Adjust Sensible Heat Ratio (SHR) using Latent Heat Ratio (LHR) multiplier
3690 : // Floating underflow errors occur when -Ton/LatentCapacityTimeConstant is a large negative number.
3691 : // Cap lower limit at -700 to avoid the underflow errors.
3692 0 : aa = std::exp(max(-700.0, -Ton / LatentCapacityTimeConstant));
3693 : // Calculate latent heat ratio multiplier
3694 0 : LHRmult = max(((Ton - To2) / (Ton + LatentCapacityTimeConstant * (aa - 1.0))), 0.0);
3695 :
3696 : // Calculate part-load or "effective" sensible heat ratio
3697 0 : SHReff = 1.0 - (1.0 - SHRss) * LHRmult;
3698 :
3699 0 : if (SHReff < SHRss) {
3700 0 : SHReff = SHRss; // Effective SHR can be less than the steady-state SHR
3701 : }
3702 0 : if (SHReff > 1.0) {
3703 0 : SHReff = 1.0; // Effective sensible heat ratio can't be greater than 1.0
3704 : }
3705 :
3706 0 : return SHReff;
3707 : }
3708 :
3709 5 : int GetCoilIndex(EnergyPlusData &state,
3710 : std::string const &CoilType, // must match coil types in this module
3711 : std::string const &CoilName, // must match coil names for the coil type
3712 : bool &ErrorsFound // set to true if problem
3713 : )
3714 : {
3715 :
3716 : // FUNCTION INFORMATION:
3717 : // AUTHOR R. Raustad
3718 : // DATE WRITTEN August 2007
3719 :
3720 : // PURPOSE OF THIS FUNCTION:
3721 : // This function looks up the coil capacity for the given coil and returns it. If
3722 : // incorrect coil type or name is given, ErrorsFound is returned as true and index is returned
3723 : // as zero.
3724 :
3725 : // Return value
3726 : int IndexNum; // returned index of matched coil
3727 :
3728 : // Obtains and Allocates WatertoAirHP related parameters from input file
3729 5 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3730 3 : GetSimpleWatertoAirHPInput(state);
3731 3 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3732 : }
3733 :
3734 5 : IndexNum = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3735 :
3736 5 : if (IndexNum == 0) {
3737 0 : ShowSevereError(state, format(R"(Could not find CoilType="{}" with Name="{}")", CoilType, CoilName));
3738 0 : ErrorsFound = true;
3739 : }
3740 :
3741 5 : return IndexNum;
3742 : }
3743 :
3744 6 : Real64 GetCoilCapacity(EnergyPlusData &state,
3745 : std::string const &CoilType, // must match coil types in this module
3746 : std::string const &CoilName, // must match coil names for the coil type
3747 : bool &ErrorsFound // set to true if problem
3748 : )
3749 : {
3750 :
3751 : // FUNCTION INFORMATION:
3752 : // AUTHOR Linda Lawrie
3753 : // DATE WRITTEN February 2006
3754 :
3755 : // PURPOSE OF THIS FUNCTION:
3756 : // This function looks up the coil capacity for the given coil and returns it. If
3757 : // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
3758 : // as negative.
3759 :
3760 : // Return value
3761 : Real64 CoilCapacity; // returned capacity of matched coil
3762 :
3763 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3764 : int WhichCoil;
3765 :
3766 : // Obtains and Allocates WatertoAirHP related parameters from input file
3767 6 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3768 0 : GetSimpleWatertoAirHPInput(state);
3769 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3770 : }
3771 :
3772 8 : if (Util::SameString(CoilType, "COIL:COOLING:WATERTOAIRHEATPUMP:EQUATIONFIT") ||
3773 8 : Util::SameString(CoilType, "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT")) {
3774 6 : WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3775 6 : if (WhichCoil != 0) {
3776 6 : if (Util::SameString(CoilType, "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT")) {
3777 2 : CoilCapacity = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).RatedCapHeat;
3778 : } else {
3779 4 : CoilCapacity = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).RatedCapCoolTotal;
3780 :
3781 4 : int companionHeatingCoil = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).CompanionHeatingCoilNum;
3782 4 : if (companionHeatingCoil > 0) {
3783 5 : if (CoilCapacity == DataSizing::AutoSize &&
3784 1 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(companionHeatingCoil).WAHPPlantType ==
3785 1 : DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit &&
3786 6 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(companionHeatingCoil).RatedCapHeat == DataSizing::AutoSize &&
3787 1 : state.dataSize->DXCoolCap > 0) {
3788 : // Heating coil has not yet been sized, returning the temporary cooling capacity
3789 1 : CoilCapacity = state.dataSize->DXCoolCap;
3790 : }
3791 : }
3792 : }
3793 : }
3794 : } else {
3795 0 : WhichCoil = 0;
3796 : }
3797 :
3798 6 : if (WhichCoil == 0) {
3799 0 : ShowSevereError(state, format(R"(Could not find CoilType="{}" with Name="{}")", CoilType, CoilName));
3800 0 : ErrorsFound = true;
3801 0 : CoilCapacity = -1000.0;
3802 : }
3803 :
3804 6 : return CoilCapacity;
3805 : }
3806 :
3807 4 : Real64 GetCoilAirFlowRate(EnergyPlusData &state,
3808 : std::string const &CoilType, // must match coil types in this module
3809 : std::string const &CoilName, // must match coil names for the coil type
3810 : bool &ErrorsFound // set to true if problem
3811 : )
3812 : {
3813 :
3814 : // FUNCTION INFORMATION:
3815 : // AUTHOR Richard Raustad, FSEC
3816 : // DATE WRITTEN October 2011
3817 :
3818 : // PURPOSE OF THIS FUNCTION:
3819 : // This function looks up the coil air flow rate for the given coil and returns it. If
3820 : // incorrect coil type or name is given, ErrorsFound is returned as true and capacity is returned
3821 : // as negative.
3822 :
3823 : // Return value
3824 : Real64 CoilAirFlowRate; // returned air volume flow rate of matched coil
3825 :
3826 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3827 : int WhichCoil;
3828 :
3829 : // Obtains and Allocates WatertoAirHP related parameters from input file
3830 4 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3831 0 : GetSimpleWatertoAirHPInput(state);
3832 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3833 : }
3834 :
3835 6 : if (Util::SameString(CoilType, "COIL:COOLING:WATERTOAIRHEATPUMP:EQUATIONFIT") ||
3836 6 : Util::SameString(CoilType, "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT")) {
3837 4 : WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3838 4 : if (WhichCoil != 0) {
3839 4 : CoilAirFlowRate = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).RatedAirVolFlowRate;
3840 : }
3841 : } else {
3842 0 : WhichCoil = 0;
3843 : }
3844 :
3845 4 : if (WhichCoil == 0) {
3846 0 : ShowSevereError(state, format(R"(Could not find CoilType="{}" with Name="{}")", CoilType, CoilName));
3847 0 : ErrorsFound = true;
3848 0 : CoilAirFlowRate = -1000.0;
3849 : }
3850 :
3851 4 : return CoilAirFlowRate;
3852 : }
3853 :
3854 0 : int GetCoilInletNode(EnergyPlusData &state,
3855 : std::string const &CoilType, // must match coil types in this module
3856 : std::string const &CoilName, // must match coil names for the coil type
3857 : bool &ErrorsFound // set to true if problem
3858 : )
3859 : {
3860 :
3861 : // FUNCTION INFORMATION:
3862 : // AUTHOR Linda Lawrie
3863 : // DATE WRITTEN February 2006
3864 :
3865 : // PURPOSE OF THIS FUNCTION:
3866 : // This function looks up the given coil and returns the inlet node. If
3867 : // incorrect coil type or name is given, ErrorsFound is returned as true and value is returned
3868 : // as zero.
3869 :
3870 : // Return value
3871 : int NodeNumber; // returned outlet node of matched coil
3872 :
3873 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3874 : int WhichCoil;
3875 :
3876 : // Obtains and Allocates WatertoAirHP related parameters from input file
3877 0 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3878 0 : GetSimpleWatertoAirHPInput(state);
3879 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3880 : }
3881 :
3882 0 : WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3883 0 : if (WhichCoil != 0) {
3884 0 : NodeNumber = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).AirInletNodeNum;
3885 : }
3886 :
3887 0 : if (WhichCoil == 0) {
3888 0 : ShowSevereError(state, format(R"(Could not find CoilType="{}" with Name="{}")", CoilType, CoilName));
3889 0 : ErrorsFound = true;
3890 0 : NodeNumber = 0;
3891 : }
3892 :
3893 0 : return NodeNumber;
3894 : }
3895 :
3896 0 : int GetCoilOutletNode(EnergyPlusData &state,
3897 : std::string const &CoilType, // must match coil types in this module
3898 : std::string const &CoilName, // must match coil names for the coil type
3899 : bool &ErrorsFound // set to true if problem
3900 : )
3901 : {
3902 :
3903 : // FUNCTION INFORMATION:
3904 : // AUTHOR R. Raustad
3905 : // DATE WRITTEN July 2007
3906 :
3907 : // PURPOSE OF THIS FUNCTION:
3908 : // This function looks up the given coil and returns the outlet node. If
3909 : // incorrect coil type or name is given, ErrorsFound is returned as true and value is returned
3910 : // as zero.
3911 :
3912 : // Return value
3913 : int NodeNumber; // returned outlet node of matched coil
3914 :
3915 : // FUNCTION LOCAL VARIABLE DECLARATIONS:
3916 : int WhichCoil;
3917 :
3918 : // Obtains and Allocates WatertoAirHP related parameters from input file
3919 0 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3920 0 : GetSimpleWatertoAirHPInput(state);
3921 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3922 : }
3923 :
3924 0 : WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3925 0 : if (WhichCoil != 0) {
3926 0 : NodeNumber = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).AirOutletNodeNum;
3927 : }
3928 :
3929 0 : if (WhichCoil == 0) {
3930 0 : ShowSevereError(state, format(R"(Could not find CoilType="{}" with Name="{}")", CoilType, CoilName));
3931 0 : ErrorsFound = true;
3932 0 : NodeNumber = 0;
3933 : }
3934 :
3935 0 : return NodeNumber;
3936 : }
3937 :
3938 2 : void SetSimpleWSHPData(EnergyPlusData &state,
3939 : int const SimpleWSHPNum, // Number of OA Controller
3940 : bool &ErrorsFound, // Set to true if certain errors found
3941 : HVAC::WaterFlow const WaterCyclingMode, // the coil water flow mode (cycling, constant or constantondemand)
3942 : ObjexxFCL::Optional_int CompanionCoolingCoilNum, // Index to cooling coil for heating coil = SimpleWSHPNum
3943 : ObjexxFCL::Optional_int CompanionHeatingCoilNum // Index to heating coil for cooling coil = SimpleWSHPNum
3944 : )
3945 : {
3946 :
3947 : // SUBROUTINE INFORMATION:
3948 : // AUTHOR Richard Raustad
3949 : // DATE WRITTEN June 2009
3950 :
3951 : // PURPOSE OF THIS SUBROUTINE:
3952 : // This routine was designed to "push" information from a parent object to
3953 : // this WSHP coil object.
3954 :
3955 : // Obtains and Allocates WatertoAirHP related parameters from input file
3956 2 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3957 0 : GetSimpleWatertoAirHPInput(state);
3958 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3959 : }
3960 :
3961 2 : if (SimpleWSHPNum <= 0 || SimpleWSHPNum > state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs) {
3962 0 : ShowSevereError(state,
3963 0 : format("SetSimpleWSHPData: called with WSHP Coil Number out of range={} should be >0 and <{}",
3964 : SimpleWSHPNum,
3965 0 : state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs));
3966 0 : ErrorsFound = true;
3967 0 : return;
3968 : }
3969 :
3970 2 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(SimpleWSHPNum).WaterCyclingMode = WaterCyclingMode;
3971 2 : if (present(CompanionCoolingCoilNum)) {
3972 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(SimpleWSHPNum).CompanionCoolingCoilNum = CompanionCoolingCoilNum;
3973 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionCoolingCoilNum).CompanionHeatingCoilNum = SimpleWSHPNum;
3974 0 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionCoolingCoilNum).WaterCyclingMode = WaterCyclingMode;
3975 : }
3976 :
3977 2 : if (present(CompanionHeatingCoilNum)) {
3978 2 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(SimpleWSHPNum).CompanionHeatingCoilNum = CompanionHeatingCoilNum;
3979 2 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoilNum).CompanionCoolingCoilNum = SimpleWSHPNum;
3980 2 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoilNum).WaterCyclingMode = WaterCyclingMode;
3981 : }
3982 : }
3983 :
3984 15 : void CheckSimpleWAHPRatedCurvesOutputs(EnergyPlusData &state, std::string const &CoilName)
3985 : {
3986 15 : constexpr Real64 Tref(283.15); // Refrence Temperature for performance curves,10C [K]
3987 : static constexpr std::string_view RoutineName("CheckSimpleWAHPRatedCurvesOutputs");
3988 :
3989 15 : int WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3990 :
3991 15 : if (WhichCoil == 0) {
3992 0 : return;
3993 : }
3994 :
3995 15 : auto &wahp = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil);
3996 15 : if (wahp.WAHPType == WatertoAirHP::Cooling) {
3997 10 : if (wahp.RatedEntAirWetbulbTemp != DataSizing::AutoSize && wahp.TotalCoolCapCurve != nullptr && wahp.CoolPowCurve != nullptr) {
3998 9 : Real64 RatedratioTWB = (wahp.RatedEntAirWetbulbTemp + Constant::Kelvin) / Tref;
3999 9 : Real64 RatedratioTS = (wahp.RatedEntWaterTemp + Constant::Kelvin) / Tref;
4000 9 : Real64 RatedTotCapTempModFac = wahp.TotalCoolCapCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
4001 9 : Real64 RatedCoolPowerTempModFac = wahp.CoolPowCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
4002 9 : if (RatedTotCapTempModFac > 1.02 || RatedTotCapTempModFac < 0.98) {
4003 7 : ShowWarningError(state, format("{}: Coil:Cooling:WaterToAirHeatPump:EquationFit=\"{}\"", RoutineName, wahp.Name));
4004 14 : ShowContinueError(state,
4005 : "Total cooling capacity as a function of temperature curve output is not equal to 1.0 (+ or - 2%) "
4006 : "at rated conditions.");
4007 7 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedTotCapTempModFac));
4008 : }
4009 9 : if (RatedCoolPowerTempModFac > 1.02 || RatedCoolPowerTempModFac < 0.98) {
4010 7 : ShowWarningError(state, format("{}: Coil:Cooling:WaterToAirHeatPump:EquationFit=\"{}\"", RoutineName, wahp.Name));
4011 14 : ShowContinueError(state,
4012 : "Cooling power consumption as a function of temperature curve output is not equal to 1.0 (+ or - 2%) "
4013 : "at rated conditions.");
4014 7 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedCoolPowerTempModFac));
4015 : }
4016 : }
4017 :
4018 10 : if (wahp.RatedEntAirDrybulbTemp != DataSizing::AutoSize && wahp.SensCoolCapCurve != nullptr) {
4019 8 : Real64 RatedratioTDB = (wahp.RatedEntAirDrybulbTemp + Constant::Kelvin) / Tref;
4020 8 : Real64 RatedratioTWB = (wahp.RatedEntAirWetbulbTemp + Constant::Kelvin) / Tref;
4021 8 : Real64 RatedratioTS = (wahp.RatedEntWaterTemp + Constant::Kelvin) / Tref;
4022 :
4023 8 : Real64 RatedSensCapTempModFac = wahp.SensCoolCapCurve->value(state, RatedratioTDB, RatedratioTWB, RatedratioTS, 1.0, 1.0);
4024 8 : if (RatedSensCapTempModFac > 1.02 || RatedSensCapTempModFac < 0.98) {
4025 5 : ShowWarningError(state, format("{}: Coil:Cooling:WaterToAirHeatPump:EquationFit=\"{}\"", RoutineName, wahp.Name));
4026 10 : ShowContinueError(state,
4027 : "Sensible cooling capacity as a function of temperature curve output is not equal to 1.0 (+ or - 2%) "
4028 : "at rated conditions.");
4029 5 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedSensCapTempModFac));
4030 : }
4031 : }
4032 :
4033 5 : } else if (wahp.WAHPType == WatertoAirHP::Heating) {
4034 5 : if (wahp.RatedEntAirDrybulbTemp != DataSizing::AutoSize && wahp.HeatCapCurve != nullptr && wahp.HeatPowCurve != nullptr) {
4035 4 : Real64 RatedHeatratioTDB = (wahp.RatedEntAirDrybulbTemp + Constant::Kelvin) / Tref;
4036 4 : Real64 RatedHeatratioTS = (wahp.RatedEntWaterTemp + Constant::Kelvin) / Tref;
4037 4 : Real64 RatedHeatCapTempModFac = wahp.HeatCapCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
4038 4 : Real64 RatedHeatPowerTempModFac = wahp.HeatPowCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
4039 4 : if (RatedHeatCapTempModFac > 1.02 || RatedHeatCapTempModFac < 0.98) {
4040 2 : ShowWarningError(state, format("{}: Coil:Heating:WaterToAirHeatPump:EquationFit=\"{}\"", RoutineName, wahp.Name));
4041 4 : ShowContinueError(
4042 : state, "Heating capacity as a function of temperature curve output is not equal to 1.0 (+ or - 2%) at rated conditions.");
4043 2 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedHeatCapTempModFac));
4044 : }
4045 4 : if (RatedHeatPowerTempModFac > 1.02 || RatedHeatPowerTempModFac < 0.98) {
4046 2 : ShowWarningError(state, format("{}: Coil:Heating:WaterToAirHeatPump:EquationFit=\"{}\"", RoutineName, wahp.Name));
4047 4 : ShowContinueError(state,
4048 : "Heating power consumption as a function of temperature curve output is not equal to 1.0 (+ or - 2%) at "
4049 : "rated conditions.");
4050 2 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedHeatPowerTempModFac));
4051 : }
4052 : }
4053 : }
4054 : }
4055 : } // namespace WaterToAirHeatPumpSimple
4056 :
4057 : } // namespace EnergyPlus
|