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 76196727 : 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 76196727 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
149 0 : GetSimpleWatertoAirHPInput(state);
150 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
151 : }
152 :
153 76196727 : 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 76196727 : HPNum = CompIndex;
161 76196727 : 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 76196727 : 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 76196727 : auto const &simpleWAHP = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum);
179 :
180 76196727 : if (simpleWAHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit) {
181 : // Cooling mode
182 38098181 : InitSimpleWatertoAirHP(state, HPNum, SensLoad, LatentLoad, fanOp, OnOffAirFlowRatio, FirstHVACIteration);
183 38098181 : CalcHPCoolingSimple(state, HPNum, fanOp, SensLoad, LatentLoad, compressorOp, PartLoadRatio, OnOffAirFlowRatio);
184 38098181 : UpdateSimpleWatertoAirHP(state, HPNum);
185 38098546 : } else if (simpleWAHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit) {
186 : // Heating mode
187 38098546 : InitSimpleWatertoAirHP(state, HPNum, SensLoad, DataPrecisionGlobals::constant_zero, fanOp, OnOffAirFlowRatio, FirstHVACIteration);
188 38098546 : CalcHPHeatingSimple(state, HPNum, fanOp, SensLoad, compressorOp, PartLoadRatio, OnOffAirFlowRatio);
189 38098546 : UpdateSimpleWatertoAirHP(state, HPNum);
190 : } else {
191 0 : ShowFatalError(state, "SimWatertoAirHPSimple: WatertoAir heatpump not in either HEATING or COOLING mode");
192 : }
193 76196727 : }
194 :
195 19 : 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 19 : int MaxNums(0); // Maximum number of numeric input fields
232 19 : int MaxAlphas(0); // Maximum number of alpha input fields
233 : int IOStat;
234 19 : bool ErrorsFound(false); // If errors detected in input
235 19 : std::string CurrentModuleObject; // for ease in getting objects
236 19 : Array1D_string AlphArray; // Alpha input items for object
237 19 : Array1D_string cAlphaFields; // Alpha field names
238 19 : Array1D_string cNumericFields; // Numeric field names
239 19 : Array1D<Real64> NumArray; // Numeric input items for object
240 19 : Array1D_bool lAlphaBlanks; // Logical array, alpha field input BLANK = .TRUE.
241 19 : Array1D_bool lNumericBlanks; // Logical array, numeric field input BLANK = .TRUE.
242 :
243 19 : NumCool = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Cooling:WaterToAirHeatPump:EquationFit");
244 19 : NumHeat = state.dataInputProcessing->inputProcessor->getNumObjectsFound(state, "Coil:Heating:WaterToAirHeatPump:EquationFit");
245 19 : state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs = NumCool + NumHeat;
246 19 : HPNum = 0;
247 :
248 19 : if (state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs <= 0) {
249 0 : ShowSevereError(state, "No Equipment found in SimWatertoAirHPSimple");
250 0 : ErrorsFound = true;
251 : }
252 :
253 : // Allocate Arrays
254 19 : if (state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs > 0) {
255 19 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP.allocate(state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs);
256 19 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag.dimension(state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs, true);
257 19 : state.dataHeatBal->HeatReclaimSimple_WAHPCoil.allocate(state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs);
258 : }
259 :
260 19 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
261 : state, "Coil:Cooling:WaterToAirHeatPump:EquationFit", NumParams, NumAlphas, NumNums);
262 19 : MaxNums = max(MaxNums, NumNums);
263 19 : MaxAlphas = max(MaxAlphas, NumAlphas);
264 19 : state.dataInputProcessing->inputProcessor->getObjectDefMaxArgs(
265 : state, "Coil:Heating:WaterToAirHeatPump:EquationFit", NumParams, NumAlphas, NumNums);
266 19 : MaxNums = max(MaxNums, NumNums);
267 19 : MaxAlphas = max(MaxAlphas, NumAlphas);
268 19 : AlphArray.allocate(MaxAlphas);
269 19 : cAlphaFields.allocate(MaxAlphas);
270 19 : lAlphaBlanks.dimension(MaxAlphas, true);
271 19 : cNumericFields.allocate(MaxNums);
272 19 : lNumericBlanks.dimension(MaxNums, true);
273 19 : NumArray.dimension(MaxNums, 0.0);
274 :
275 : // Get the data for cooling coil
276 19 : CurrentModuleObject = "Coil:Cooling:WaterToAirHeatPump:EquationFit";
277 :
278 284 : for (WatertoAirHPNum = 1; WatertoAirHPNum <= NumCool; ++WatertoAirHPNum) {
279 :
280 265 : ++HPNum;
281 265 : auto &simpleWAHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
282 265 : 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 265 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, AlphArray(1)};
296 :
297 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
298 265 : GlobalNames::VerifyUniqueCoilName(state, CurrentModuleObject, AlphArray(1), ErrorsFound, format("{} Name", CurrentModuleObject));
299 265 : simpleWAHP.Name = AlphArray(1);
300 265 : simpleWAHP.WAHPType = WatertoAirHP::Cooling;
301 265 : simpleWAHP.WAHPPlantType = DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit;
302 265 : simpleWAHP.RatedAirVolFlowRate = NumArray(1);
303 265 : simpleWAHP.RatedWaterVolFlowRate = NumArray(2);
304 265 : simpleWAHP.RatedCapCoolTotal = NumArray(3);
305 265 : simpleWAHP.RatedCapCoolSens = NumArray(4);
306 265 : simpleWAHP.RatedCOPCoolAtRatedCdts = NumArray(5);
307 265 : simpleWAHP.RatedEntWaterTemp = NumArray(6);
308 265 : simpleWAHP.RatedEntAirDrybulbTemp = NumArray(7);
309 265 : simpleWAHP.RatedEntAirWetbulbTemp = NumArray(8);
310 :
311 265 : if (lAlphaBlanks(6)) {
312 0 : ShowSevereEmptyField(state, eoh, cAlphaFields(6));
313 0 : ErrorsFound = true;
314 265 : } else if ((simpleWAHP.TotalCoolCapCurve = Curve::GetCurve(state, AlphArray(6))) == nullptr) {
315 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(6), AlphArray(6));
316 0 : ErrorsFound = true;
317 265 : } 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 265 : if (lAlphaBlanks(7)) {
323 0 : ShowSevereEmptyField(state, eoh, cAlphaFields(7));
324 0 : ErrorsFound = true;
325 265 : } else if ((simpleWAHP.SensCoolCapCurve = Curve::GetCurve(state, AlphArray(7))) == nullptr) {
326 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(7), AlphArray(7));
327 0 : ErrorsFound = true;
328 265 : } 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 265 : if (lAlphaBlanks(8)) {
334 0 : ShowSevereEmptyField(state, eoh, cAlphaFields(8));
335 0 : ErrorsFound = true;
336 265 : } else if ((simpleWAHP.CoolPowCurve = Curve::GetCurve(state, AlphArray(8))) == nullptr) {
337 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(8), AlphArray(8));
338 0 : ErrorsFound = true;
339 265 : } 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 265 : if (lAlphaBlanks(9)) {
345 0 : ShowSevereEmptyField(state, eoh, cAlphaFields(9));
346 0 : ErrorsFound = true;
347 265 : } else if ((simpleWAHP.PLFCurve = Curve::GetCurve(state, AlphArray(9))) == nullptr) {
348 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(9), AlphArray(9));
349 0 : ErrorsFound = true;
350 265 : } 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 265 : Real64 MinCurveVal = 999.0;
357 265 : Real64 MaxCurveVal = -999.0;
358 265 : Real64 CurveInput = 0.0;
359 265 : Real64 MinCurvePLR{0.0};
360 265 : Real64 MaxCurvePLR{0.0};
361 :
362 26765 : while (CurveInput <= 1.0) {
363 26500 : Real64 CurveVal = simpleWAHP.PLFCurve->value(state, CurveInput);
364 26500 : if (CurveVal < MinCurveVal) {
365 265 : MinCurveVal = CurveVal;
366 265 : MinCurvePLR = CurveInput;
367 : }
368 26500 : if (CurveVal > MaxCurveVal) {
369 26500 : MaxCurveVal = CurveVal;
370 26500 : MaxCurvePLR = CurveInput;
371 : }
372 26500 : CurveInput += 0.01;
373 : }
374 265 : 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 265 : 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 265 : CheckSimpleWAHPRatedCurvesOutputs(state, simpleWAHP.Name);
394 265 : simpleWAHP.Twet_Rated = NumArray(9);
395 265 : simpleWAHP.Gamma_Rated = NumArray(10);
396 265 : simpleWAHP.MaxONOFFCyclesperHour = NumArray(11);
397 265 : simpleWAHP.LatentCapacityTimeConstant = NumArray(12);
398 265 : simpleWAHP.FanDelayTime = NumArray(13);
399 :
400 265 : state.dataHeatBal->HeatReclaimSimple_WAHPCoil(WatertoAirHPNum).Name = simpleWAHP.Name;
401 265 : state.dataHeatBal->HeatReclaimSimple_WAHPCoil(WatertoAirHPNum).SourceType = CurrentModuleObject;
402 :
403 265 : simpleWAHP.WaterInletNodeNum = GetOnlySingleNode(state,
404 265 : AlphArray(2),
405 : ErrorsFound,
406 : DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpEquationFit,
407 265 : simpleWAHP.Name,
408 : DataLoopNode::NodeFluidType::Water,
409 : DataLoopNode::ConnectionType::Inlet,
410 : NodeInputManager::CompFluidStream::Secondary,
411 : DataLoopNode::ObjectIsNotParent);
412 265 : simpleWAHP.WaterOutletNodeNum = GetOnlySingleNode(state,
413 265 : AlphArray(3),
414 : ErrorsFound,
415 : DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpEquationFit,
416 265 : simpleWAHP.Name,
417 : DataLoopNode::NodeFluidType::Water,
418 : DataLoopNode::ConnectionType::Outlet,
419 : NodeInputManager::CompFluidStream::Secondary,
420 : DataLoopNode::ObjectIsNotParent);
421 265 : simpleWAHP.AirInletNodeNum = GetOnlySingleNode(state,
422 265 : AlphArray(4),
423 : ErrorsFound,
424 : DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpEquationFit,
425 265 : simpleWAHP.Name,
426 : DataLoopNode::NodeFluidType::Air,
427 : DataLoopNode::ConnectionType::Inlet,
428 : NodeInputManager::CompFluidStream::Primary,
429 : DataLoopNode::ObjectIsNotParent);
430 530 : simpleWAHP.AirOutletNodeNum = GetOnlySingleNode(state,
431 265 : AlphArray(5),
432 : ErrorsFound,
433 : DataLoopNode::ConnectionObjectType::CoilCoolingWaterToAirHeatPumpEquationFit,
434 265 : simpleWAHP.Name,
435 : DataLoopNode::NodeFluidType::Air,
436 : DataLoopNode::ConnectionType::Outlet,
437 : NodeInputManager::CompFluidStream::Primary,
438 : DataLoopNode::ObjectIsNotParent);
439 :
440 530 : BranchNodeConnections::TestCompSet(state, CurrentModuleObject, simpleWAHP.Name, AlphArray(2), AlphArray(3), "Water Nodes");
441 265 : 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 530 : SetupOutputVariable(state,
446 : "Cooling Coil Electricity Energy",
447 : Constant::Units::J,
448 265 : simpleWAHP.Energy,
449 : OutputProcessor::TimeStepType::System,
450 : OutputProcessor::StoreType::Sum,
451 265 : simpleWAHP.Name,
452 : Constant::eResource::Electricity,
453 : OutputProcessor::Group::HVAC,
454 : OutputProcessor::EndUseCat::Cooling);
455 530 : SetupOutputVariable(state,
456 : "Cooling Coil Total Cooling Energy",
457 : Constant::Units::J,
458 265 : simpleWAHP.EnergyLoadTotal,
459 : OutputProcessor::TimeStepType::System,
460 : OutputProcessor::StoreType::Sum,
461 265 : simpleWAHP.Name,
462 : Constant::eResource::EnergyTransfer,
463 : OutputProcessor::Group::HVAC,
464 : OutputProcessor::EndUseCat::CoolingCoils);
465 530 : SetupOutputVariable(state,
466 : "Cooling Coil Sensible Cooling Energy",
467 : Constant::Units::J,
468 265 : simpleWAHP.EnergySensible,
469 : OutputProcessor::TimeStepType::System,
470 : OutputProcessor::StoreType::Sum,
471 265 : simpleWAHP.Name);
472 530 : SetupOutputVariable(state,
473 : "Cooling Coil Latent Cooling Energy",
474 : Constant::Units::J,
475 265 : simpleWAHP.EnergyLatent,
476 : OutputProcessor::TimeStepType::System,
477 : OutputProcessor::StoreType::Sum,
478 265 : simpleWAHP.Name);
479 530 : SetupOutputVariable(state,
480 : "Cooling Coil Source Side Heat Transfer Energy",
481 : Constant::Units::J,
482 265 : simpleWAHP.EnergySource,
483 : OutputProcessor::TimeStepType::System,
484 : OutputProcessor::StoreType::Sum,
485 265 : simpleWAHP.Name,
486 : Constant::eResource::PlantLoopCoolingDemand,
487 : OutputProcessor::Group::HVAC,
488 : OutputProcessor::EndUseCat::CoolingCoils);
489 :
490 : // create predefined report entries
491 265 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilType, simpleWAHP.Name, CurrentModuleObject);
492 530 : OutputReportPredefined::PreDefTableEntry(
493 265 : state, state.dataOutRptPredefined->pdchCoolCoilTotCap, simpleWAHP.Name, simpleWAHP.RatedCapCoolTotal);
494 530 : OutputReportPredefined::PreDefTableEntry(
495 265 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, simpleWAHP.Name, simpleWAHP.RatedCapCoolSens);
496 530 : OutputReportPredefined::PreDefTableEntry(
497 265 : state, state.dataOutRptPredefined->pdchCoolCoilLatCap, simpleWAHP.Name, simpleWAHP.RatedCapCoolTotal - simpleWAHP.RatedCapCoolSens);
498 530 : OutputReportPredefined::PreDefTableEntry(
499 265 : state, state.dataOutRptPredefined->pdchCoolCoilSHR, simpleWAHP.Name, simpleWAHP.RatedCapCoolSens / simpleWAHP.RatedCapCoolTotal);
500 530 : OutputReportPredefined::PreDefTableEntry(
501 265 : state, state.dataOutRptPredefined->pdchCoolCoilNomEff, simpleWAHP.Name, simpleWAHP.RatedPowerCool / simpleWAHP.RatedCapCoolTotal);
502 :
503 265 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWAHPType, simpleWAHP.Name, CurrentModuleObject);
504 : }
505 :
506 : // Get the data for heating coil
507 19 : CurrentModuleObject = "Coil:Heating:WaterToAirHeatPump:EquationFit";
508 :
509 284 : for (WatertoAirHPNum = 1; WatertoAirHPNum <= NumHeat; ++WatertoAirHPNum) {
510 :
511 265 : ++HPNum;
512 265 : auto &simpleWAHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
513 265 : 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 265 : ErrorObjectHeader eoh{routineName, CurrentModuleObject, AlphArray(1)};
527 :
528 : // ErrorsFound will be set to True if problem was found, left untouched otherwise
529 265 : GlobalNames::VerifyUniqueCoilName(state, CurrentModuleObject, AlphArray(1), ErrorsFound, format("{} Name", CurrentModuleObject));
530 265 : simpleWAHP.Name = AlphArray(1);
531 265 : simpleWAHP.WAHPType = WatertoAirHP::Heating;
532 265 : simpleWAHP.WAHPPlantType = DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit;
533 265 : simpleWAHP.RatedAirVolFlowRate = NumArray(1);
534 265 : simpleWAHP.RatedWaterVolFlowRate = NumArray(2);
535 265 : simpleWAHP.RatedCapHeat = NumArray(3);
536 265 : simpleWAHP.RatedCOPHeatAtRatedCdts = NumArray(4);
537 265 : simpleWAHP.RatedEntWaterTemp = NumArray(5);
538 265 : simpleWAHP.RatedEntAirDrybulbTemp = NumArray(6);
539 265 : simpleWAHP.RatioRatedHeatRatedTotCoolCap = NumArray(7);
540 :
541 265 : if (lAlphaBlanks(6)) {
542 0 : ShowSevereEmptyField(state, eoh, cAlphaFields(6));
543 0 : ErrorsFound = true;
544 265 : } else if ((simpleWAHP.HeatCapCurve = Curve::GetCurve(state, AlphArray(6))) == nullptr) {
545 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(6), AlphArray(6));
546 0 : ErrorsFound = true;
547 265 : } 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 265 : if (lAlphaBlanks(7)) {
553 0 : ShowSevereEmptyField(state, eoh, cAlphaFields(7));
554 0 : ErrorsFound = true;
555 265 : } else if ((simpleWAHP.HeatPowCurve = Curve::GetCurve(state, AlphArray(7))) == nullptr) {
556 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(7), AlphArray(7));
557 0 : ErrorsFound = true;
558 265 : } 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 265 : if (lAlphaBlanks(8)) {
564 0 : ShowSevereEmptyField(state, eoh, cAlphaFields(8));
565 0 : ErrorsFound = true;
566 265 : } else if ((simpleWAHP.PLFCurve = Curve::GetCurve(state, AlphArray(8))) == nullptr) {
567 0 : ShowSevereItemNotFound(state, eoh, cAlphaFields(8), AlphArray(8));
568 0 : ErrorsFound = true;
569 265 : } 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 265 : Real64 MinCurveVal = 999.0;
575 265 : Real64 MaxCurveVal = -999.0;
576 265 : Real64 CurveInput = 0.0;
577 265 : Real64 MinCurvePLR{0.0};
578 265 : Real64 MaxCurvePLR{0.0};
579 :
580 26765 : while (CurveInput <= 1.0) {
581 26500 : Real64 CurveVal = simpleWAHP.PLFCurve->value(state, CurveInput);
582 26500 : if (CurveVal < MinCurveVal) {
583 265 : MinCurveVal = CurveVal;
584 265 : MinCurvePLR = CurveInput;
585 26235 : } else if (CurveVal > MaxCurveVal) {
586 26235 : MaxCurveVal = CurveVal;
587 26235 : MaxCurvePLR = CurveInput;
588 : }
589 26500 : CurveInput += 0.01;
590 : }
591 :
592 265 : 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 265 : 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 265 : CheckSimpleWAHPRatedCurvesOutputs(state, simpleWAHP.Name);
612 265 : simpleWAHP.WaterInletNodeNum = GetOnlySingleNode(state,
613 265 : AlphArray(2),
614 : ErrorsFound,
615 : DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpEquationFit,
616 265 : simpleWAHP.Name,
617 : DataLoopNode::NodeFluidType::Water,
618 : DataLoopNode::ConnectionType::Inlet,
619 : NodeInputManager::CompFluidStream::Secondary,
620 : DataLoopNode::ObjectIsNotParent);
621 265 : simpleWAHP.WaterOutletNodeNum = GetOnlySingleNode(state,
622 265 : AlphArray(3),
623 : ErrorsFound,
624 : DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpEquationFit,
625 265 : simpleWAHP.Name,
626 : DataLoopNode::NodeFluidType::Water,
627 : DataLoopNode::ConnectionType::Outlet,
628 : NodeInputManager::CompFluidStream::Secondary,
629 : DataLoopNode::ObjectIsNotParent);
630 265 : simpleWAHP.AirInletNodeNum = GetOnlySingleNode(state,
631 265 : AlphArray(4),
632 : ErrorsFound,
633 : DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpEquationFit,
634 265 : simpleWAHP.Name,
635 : DataLoopNode::NodeFluidType::Air,
636 : DataLoopNode::ConnectionType::Inlet,
637 : NodeInputManager::CompFluidStream::Primary,
638 : DataLoopNode::ObjectIsNotParent);
639 530 : simpleWAHP.AirOutletNodeNum = GetOnlySingleNode(state,
640 265 : AlphArray(5),
641 : ErrorsFound,
642 : DataLoopNode::ConnectionObjectType::CoilHeatingWaterToAirHeatPumpEquationFit,
643 265 : simpleWAHP.Name,
644 : DataLoopNode::NodeFluidType::Air,
645 : DataLoopNode::ConnectionType::Outlet,
646 : NodeInputManager::CompFluidStream::Primary,
647 : DataLoopNode::ObjectIsNotParent);
648 :
649 530 : BranchNodeConnections::TestCompSet(state, CurrentModuleObject, simpleWAHP.Name, AlphArray(2), AlphArray(3), "Water Nodes");
650 265 : BranchNodeConnections::TestCompSet(state, CurrentModuleObject, simpleWAHP.Name, AlphArray(4), AlphArray(5), "Air Nodes");
651 :
652 : // CurrentModuleObject = "Coil:Cooling:WaterToAirHeatPump:EquationFit"
653 530 : SetupOutputVariable(state,
654 : "Heating Coil Electricity Energy",
655 : Constant::Units::J,
656 265 : simpleWAHP.Energy,
657 : OutputProcessor::TimeStepType::System,
658 : OutputProcessor::StoreType::Sum,
659 265 : simpleWAHP.Name,
660 : Constant::eResource::Electricity,
661 : OutputProcessor::Group::HVAC,
662 : OutputProcessor::EndUseCat::Heating);
663 530 : SetupOutputVariable(state,
664 : "Heating Coil Heating Energy",
665 : Constant::Units::J,
666 265 : simpleWAHP.EnergyLoadTotal,
667 : OutputProcessor::TimeStepType::System,
668 : OutputProcessor::StoreType::Sum,
669 265 : simpleWAHP.Name,
670 : Constant::eResource::EnergyTransfer,
671 : OutputProcessor::Group::HVAC,
672 : OutputProcessor::EndUseCat::HeatingCoils);
673 530 : SetupOutputVariable(state,
674 : "Heating Coil Source Side Heat Transfer Energy",
675 : Constant::Units::J,
676 265 : simpleWAHP.EnergySource,
677 : OutputProcessor::TimeStepType::System,
678 : OutputProcessor::StoreType::Sum,
679 265 : simpleWAHP.Name,
680 : Constant::eResource::PlantLoopHeatingDemand,
681 : OutputProcessor::Group::HVAC,
682 : OutputProcessor::EndUseCat::HeatingCoils);
683 :
684 : // create predefined report entries
685 265 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilType, simpleWAHP.Name, CurrentModuleObject);
686 265 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomCap, simpleWAHP.Name, simpleWAHP.RatedCapHeat);
687 530 : OutputReportPredefined::PreDefTableEntry(
688 265 : state, state.dataOutRptPredefined->pdchHeatCoilNomEff, simpleWAHP.Name, simpleWAHP.RatedPowerHeat / simpleWAHP.RatedCapHeat);
689 :
690 265 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchWAHPType, simpleWAHP.Name, CurrentModuleObject);
691 : }
692 :
693 19 : AlphArray.deallocate();
694 19 : cAlphaFields.deallocate();
695 19 : lAlphaBlanks.deallocate();
696 19 : cNumericFields.deallocate();
697 19 : lNumericBlanks.deallocate();
698 19 : NumArray.deallocate();
699 :
700 19 : if (ErrorsFound) {
701 0 : ShowFatalError(state, format("{} Errors found getting input. Program terminates.", RoutineName));
702 : }
703 :
704 549 : for (HPNum = 1; HPNum <= state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs; ++HPNum) {
705 530 : auto &simpleWAHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
706 530 : if (simpleWAHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit) {
707 : // COOLING COIL Setup Report variables for the Heat Pump
708 530 : SetupOutputVariable(state,
709 : "Cooling Coil Electricity Rate",
710 : Constant::Units::W,
711 265 : simpleWAHP.Power,
712 : OutputProcessor::TimeStepType::System,
713 : OutputProcessor::StoreType::Average,
714 265 : simpleWAHP.Name);
715 530 : SetupOutputVariable(state,
716 : "Cooling Coil Total Cooling Rate",
717 : Constant::Units::W,
718 265 : simpleWAHP.QLoadTotal,
719 : OutputProcessor::TimeStepType::System,
720 : OutputProcessor::StoreType::Average,
721 265 : simpleWAHP.Name);
722 530 : SetupOutputVariable(state,
723 : "Cooling Coil Sensible Cooling Rate",
724 : Constant::Units::W,
725 265 : simpleWAHP.QSensible,
726 : OutputProcessor::TimeStepType::System,
727 : OutputProcessor::StoreType::Average,
728 265 : simpleWAHP.Name);
729 530 : SetupOutputVariable(state,
730 : "Cooling Coil Latent Cooling Rate",
731 : Constant::Units::W,
732 265 : simpleWAHP.QLatent,
733 : OutputProcessor::TimeStepType::System,
734 : OutputProcessor::StoreType::Average,
735 265 : simpleWAHP.Name);
736 530 : SetupOutputVariable(state,
737 : "Cooling Coil Source Side Heat Transfer Rate",
738 : Constant::Units::W,
739 265 : simpleWAHP.QSource,
740 : OutputProcessor::TimeStepType::System,
741 : OutputProcessor::StoreType::Average,
742 265 : simpleWAHP.Name);
743 530 : SetupOutputVariable(state,
744 : "Cooling Coil Part Load Ratio",
745 : Constant::Units::None,
746 265 : simpleWAHP.PartLoadRatio,
747 : OutputProcessor::TimeStepType::System,
748 : OutputProcessor::StoreType::Average,
749 265 : simpleWAHP.Name);
750 530 : SetupOutputVariable(state,
751 : "Cooling Coil Runtime Fraction",
752 : Constant::Units::None,
753 265 : simpleWAHP.RunFrac,
754 : OutputProcessor::TimeStepType::System,
755 : OutputProcessor::StoreType::Average,
756 265 : simpleWAHP.Name);
757 :
758 530 : SetupOutputVariable(state,
759 : "Cooling Coil Air Mass Flow Rate",
760 : Constant::Units::kg_s,
761 265 : simpleWAHP.AirMassFlowRate,
762 : OutputProcessor::TimeStepType::System,
763 : OutputProcessor::StoreType::Average,
764 265 : simpleWAHP.Name);
765 530 : SetupOutputVariable(state,
766 : "Cooling Coil Air Inlet Temperature",
767 : Constant::Units::C,
768 265 : simpleWAHP.InletAirDBTemp,
769 : OutputProcessor::TimeStepType::System,
770 : OutputProcessor::StoreType::Average,
771 265 : simpleWAHP.Name);
772 530 : SetupOutputVariable(state,
773 : "Cooling Coil Air Inlet Humidity Ratio",
774 : Constant::Units::kgWater_kgDryAir,
775 265 : simpleWAHP.InletAirHumRat,
776 : OutputProcessor::TimeStepType::System,
777 : OutputProcessor::StoreType::Average,
778 265 : simpleWAHP.Name);
779 530 : SetupOutputVariable(state,
780 : "Cooling Coil Air Outlet Temperature",
781 : Constant::Units::C,
782 265 : simpleWAHP.OutletAirDBTemp,
783 : OutputProcessor::TimeStepType::System,
784 : OutputProcessor::StoreType::Average,
785 265 : simpleWAHP.Name);
786 530 : SetupOutputVariable(state,
787 : "Cooling Coil Air Outlet Humidity Ratio",
788 : Constant::Units::kgWater_kgDryAir,
789 265 : simpleWAHP.OutletAirHumRat,
790 : OutputProcessor::TimeStepType::System,
791 : OutputProcessor::StoreType::Average,
792 265 : simpleWAHP.Name);
793 530 : SetupOutputVariable(state,
794 : "Cooling Coil Source Side Mass Flow Rate",
795 : Constant::Units::kg_s,
796 265 : simpleWAHP.WaterMassFlowRate,
797 : OutputProcessor::TimeStepType::System,
798 : OutputProcessor::StoreType::Average,
799 265 : simpleWAHP.Name);
800 530 : SetupOutputVariable(state,
801 : "Cooling Coil Source Side Inlet Temperature",
802 : Constant::Units::C,
803 265 : simpleWAHP.InletWaterTemp,
804 : OutputProcessor::TimeStepType::System,
805 : OutputProcessor::StoreType::Average,
806 265 : simpleWAHP.Name);
807 530 : SetupOutputVariable(state,
808 : "Cooling Coil Source Side Outlet Temperature",
809 : Constant::Units::C,
810 265 : simpleWAHP.OutletWaterTemp,
811 : OutputProcessor::TimeStepType::System,
812 : OutputProcessor::StoreType::Average,
813 265 : simpleWAHP.Name);
814 :
815 265 : } else if (simpleWAHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit) {
816 : // HEATING COIL Setup Report variables for the Heat Pump
817 530 : SetupOutputVariable(state,
818 : "Heating Coil Electricity Rate",
819 : Constant::Units::W,
820 265 : simpleWAHP.Power,
821 : OutputProcessor::TimeStepType::System,
822 : OutputProcessor::StoreType::Average,
823 265 : simpleWAHP.Name);
824 530 : SetupOutputVariable(state,
825 : "Heating Coil Heating Rate",
826 : Constant::Units::W,
827 265 : simpleWAHP.QLoadTotal,
828 : OutputProcessor::TimeStepType::System,
829 : OutputProcessor::StoreType::Average,
830 265 : simpleWAHP.Name);
831 530 : SetupOutputVariable(state,
832 : "Heating Coil Sensible Heating Rate",
833 : Constant::Units::W,
834 265 : simpleWAHP.QSensible,
835 : OutputProcessor::TimeStepType::System,
836 : OutputProcessor::StoreType::Average,
837 265 : simpleWAHP.Name);
838 :
839 530 : SetupOutputVariable(state,
840 : "Heating Coil Source Side Heat Transfer Rate",
841 : Constant::Units::W,
842 265 : simpleWAHP.QSource,
843 : OutputProcessor::TimeStepType::System,
844 : OutputProcessor::StoreType::Average,
845 265 : simpleWAHP.Name);
846 530 : SetupOutputVariable(state,
847 : "Heating Coil Part Load Ratio",
848 : Constant::Units::None,
849 265 : simpleWAHP.PartLoadRatio,
850 : OutputProcessor::TimeStepType::System,
851 : OutputProcessor::StoreType::Average,
852 265 : simpleWAHP.Name);
853 530 : SetupOutputVariable(state,
854 : "Heating Coil Runtime Fraction",
855 : Constant::Units::None,
856 265 : simpleWAHP.RunFrac,
857 : OutputProcessor::TimeStepType::System,
858 : OutputProcessor::StoreType::Average,
859 265 : simpleWAHP.Name);
860 :
861 530 : SetupOutputVariable(state,
862 : "Heating Coil Air Mass Flow Rate",
863 : Constant::Units::kg_s,
864 265 : simpleWAHP.AirMassFlowRate,
865 : OutputProcessor::TimeStepType::System,
866 : OutputProcessor::StoreType::Average,
867 265 : simpleWAHP.Name);
868 530 : SetupOutputVariable(state,
869 : "Heating Coil Air Inlet Temperature",
870 : Constant::Units::C,
871 265 : simpleWAHP.InletAirDBTemp,
872 : OutputProcessor::TimeStepType::System,
873 : OutputProcessor::StoreType::Average,
874 265 : simpleWAHP.Name);
875 530 : SetupOutputVariable(state,
876 : "Heating Coil Air Inlet Humidity Ratio",
877 : Constant::Units::kgWater_kgDryAir,
878 265 : simpleWAHP.InletAirHumRat,
879 : OutputProcessor::TimeStepType::System,
880 : OutputProcessor::StoreType::Average,
881 265 : simpleWAHP.Name);
882 530 : SetupOutputVariable(state,
883 : "Heating Coil Air Outlet Temperature",
884 : Constant::Units::C,
885 265 : simpleWAHP.OutletAirDBTemp,
886 : OutputProcessor::TimeStepType::System,
887 : OutputProcessor::StoreType::Average,
888 265 : simpleWAHP.Name);
889 530 : SetupOutputVariable(state,
890 : "Heating Coil Air Outlet Humidity Ratio",
891 : Constant::Units::kgWater_kgDryAir,
892 265 : simpleWAHP.OutletAirHumRat,
893 : OutputProcessor::TimeStepType::System,
894 : OutputProcessor::StoreType::Average,
895 265 : simpleWAHP.Name);
896 530 : SetupOutputVariable(state,
897 : "Heating Coil Source Side Mass Flow Rate",
898 : Constant::Units::kg_s,
899 265 : simpleWAHP.WaterMassFlowRate,
900 : OutputProcessor::TimeStepType::System,
901 : OutputProcessor::StoreType::Average,
902 265 : simpleWAHP.Name);
903 530 : SetupOutputVariable(state,
904 : "Heating Coil Source Side Inlet Temperature",
905 : Constant::Units::C,
906 265 : simpleWAHP.InletWaterTemp,
907 : OutputProcessor::TimeStepType::System,
908 : OutputProcessor::StoreType::Average,
909 265 : simpleWAHP.Name);
910 530 : SetupOutputVariable(state,
911 : "Heating Coil Source Side Outlet Temperature",
912 : Constant::Units::C,
913 265 : simpleWAHP.OutletWaterTemp,
914 : OutputProcessor::TimeStepType::System,
915 : OutputProcessor::StoreType::Average,
916 265 : simpleWAHP.Name);
917 : }
918 : }
919 19 : }
920 :
921 : // Beginning Initialization Section of the Module
922 : //******************************************************************************
923 :
924 76196727 : 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 76196727 : if (state.dataWaterToAirHeatPumpSimple->MyOneTimeFlag) {
953 : // initialize the environment and sizing flags
954 19 : state.dataWaterToAirHeatPumpSimple->MySizeFlag.allocate(state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs);
955 19 : state.dataWaterToAirHeatPumpSimple->MyEnvrnFlag.allocate(state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs);
956 19 : state.dataWaterToAirHeatPumpSimple->MyPlantScanFlag.allocate(state.dataWaterToAirHeatPumpSimple->NumWatertoAirHPs);
957 19 : state.dataWaterToAirHeatPumpSimple->MySizeFlag = true;
958 19 : state.dataWaterToAirHeatPumpSimple->MyEnvrnFlag = true;
959 19 : state.dataWaterToAirHeatPumpSimple->MyPlantScanFlag = true;
960 19 : state.dataWaterToAirHeatPumpSimple->MyOneTimeFlag = false;
961 : }
962 :
963 76196727 : auto &simpleWatertoAirHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
964 :
965 76196727 : if (state.dataWaterToAirHeatPumpSimple->MyPlantScanFlag(HPNum) && allocated(state.dataPlnt->PlantLoop)) {
966 530 : bool errFlag = false;
967 1060 : PlantUtilities::ScanPlantLoopsForObject(
968 530 : state, simpleWatertoAirHP.Name, simpleWatertoAirHP.WAHPPlantType, simpleWatertoAirHP.plantLoc, errFlag, _, _, _, _, _);
969 530 : if (errFlag) {
970 0 : ShowFatalError(state, "InitSimpleWatertoAirHP: Program terminated for previous conditions.");
971 : }
972 530 : state.dataWaterToAirHeatPumpSimple->MyPlantScanFlag(HPNum) = false;
973 : }
974 :
975 76196727 : if (state.dataWaterToAirHeatPumpSimple->MySizeFlag(HPNum)) {
976 1947 : if (!state.dataGlobal->SysSizingCalc && !state.dataWaterToAirHeatPumpSimple->MyPlantScanFlag(HPNum)) {
977 : // do the sizing once.
978 530 : SizeHVACWaterToAir(state, HPNum);
979 530 : state.dataWaterToAirHeatPumpSimple->MySizeFlag(HPNum) = false;
980 : }
981 : }
982 :
983 76196727 : if (FirstHVACIteration) {
984 17881143 : if (state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(HPNum)) {
985 1243318 : if (simpleWatertoAirHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit) {
986 1243318 : if (simpleWatertoAirHP.CompanionHeatingCoilNum > 0) {
987 1243318 : if (simpleWatertoAirHP.WaterFlowMode) {
988 650261 : simpleWatertoAirHP.LastOperatingMode = HVAC::Cooling;
989 650261 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum).LastOperatingMode =
990 : HVAC::Cooling;
991 593057 : } else if (state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum).WaterFlowMode) {
992 443544 : simpleWatertoAirHP.LastOperatingMode = HVAC::Heating;
993 443544 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum).LastOperatingMode =
994 : HVAC::Heating;
995 : }
996 1243318 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(simpleWatertoAirHP.CompanionHeatingCoilNum) = false;
997 : } else {
998 0 : if (simpleWatertoAirHP.WaterFlowMode) {
999 0 : simpleWatertoAirHP.LastOperatingMode = HVAC::Cooling;
1000 : }
1001 : }
1002 1243318 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(HPNum) = false;
1003 : } else {
1004 : // it is a heating coil
1005 0 : 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 0 : if (simpleWatertoAirHP.WaterFlowMode) {
1018 0 : simpleWatertoAirHP.LastOperatingMode = HVAC::Heating;
1019 : }
1020 : }
1021 0 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(HPNum) = false;
1022 : }
1023 : }
1024 : } else {
1025 58315584 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(HPNum) = true;
1026 58315584 : if (simpleWatertoAirHP.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit) {
1027 29157792 : if (simpleWatertoAirHP.CompanionHeatingCoilNum > 0) {
1028 29157792 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(simpleWatertoAirHP.CompanionHeatingCoilNum) = true;
1029 : }
1030 : } else {
1031 29157792 : if (simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
1032 29157792 : state.dataWaterToAirHeatPumpSimple->SimpleHPTimeStepFlag(simpleWatertoAirHP.CompanionCoolingCoilNum) = true;
1033 : }
1034 : }
1035 : }
1036 :
1037 : // Do the Begin Environment initializations
1038 76196727 : if (state.dataGlobal->BeginEnvrnFlag) {
1039 :
1040 150174 : if (state.dataWaterToAirHeatPumpSimple->MyEnvrnFlag(HPNum) && !state.dataWaterToAirHeatPumpSimple->MyPlantScanFlag(HPNum)) {
1041 :
1042 : // Initialize all report variables to a known state at beginning of simulation
1043 3616 : simpleWatertoAirHP.AirVolFlowRate = 0.0;
1044 3616 : simpleWatertoAirHP.InletAirDBTemp = 0.0;
1045 3616 : simpleWatertoAirHP.InletAirHumRat = 0.0;
1046 3616 : simpleWatertoAirHP.OutletAirDBTemp = 0.0;
1047 3616 : simpleWatertoAirHP.OutletAirHumRat = 0.0;
1048 3616 : simpleWatertoAirHP.WaterVolFlowRate = 0.0;
1049 3616 : simpleWatertoAirHP.WaterMassFlowRate = 0.0;
1050 3616 : simpleWatertoAirHP.InletWaterTemp = 0.0;
1051 3616 : simpleWatertoAirHP.InletWaterEnthalpy = 0.0;
1052 3616 : simpleWatertoAirHP.OutletWaterEnthalpy = 0.0;
1053 3616 : simpleWatertoAirHP.OutletWaterTemp = 0.0;
1054 3616 : simpleWatertoAirHP.Power = 0.0;
1055 3616 : simpleWatertoAirHP.QLoadTotal = 0.0;
1056 3616 : simpleWatertoAirHP.QLoadTotalReport = 0.0;
1057 3616 : simpleWatertoAirHP.QSensible = 0.0;
1058 3616 : simpleWatertoAirHP.QLatent = 0.0;
1059 3616 : simpleWatertoAirHP.QSource = 0.0;
1060 3616 : simpleWatertoAirHP.Energy = 0.0;
1061 3616 : simpleWatertoAirHP.EnergyLoadTotal = 0.0;
1062 3616 : simpleWatertoAirHP.EnergySensible = 0.0;
1063 3616 : simpleWatertoAirHP.EnergyLatent = 0.0;
1064 3616 : simpleWatertoAirHP.EnergySource = 0.0;
1065 3616 : simpleWatertoAirHP.COP = 0.0;
1066 3616 : simpleWatertoAirHP.RunFrac = 0.0;
1067 3616 : simpleWatertoAirHP.PartLoadRatio = 0.0;
1068 :
1069 3616 : if (simpleWatertoAirHP.RatedWaterVolFlowRate != DataSizing::AutoSize) {
1070 : rho =
1071 3366 : state.dataPlnt->PlantLoop(simpleWatertoAirHP.plantLoc.loopNum).glycol->getDensity(state, Constant::InitConvTemp, RoutineName);
1072 :
1073 3366 : simpleWatertoAirHP.DesignWaterMassFlowRate = rho * simpleWatertoAirHP.RatedWaterVolFlowRate;
1074 3366 : PlantUtilities::InitComponentNodes(state,
1075 : 0.0,
1076 : simpleWatertoAirHP.DesignWaterMassFlowRate,
1077 : simpleWatertoAirHP.WaterInletNodeNum,
1078 : simpleWatertoAirHP.WaterOutletNodeNum);
1079 :
1080 3366 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating && simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
1081 1808 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).DesignWaterMassFlowRate =
1082 1808 : rho *
1083 1808 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).RatedWaterVolFlowRate;
1084 5424 : PlantUtilities::InitComponentNodes(
1085 : state,
1086 : 0.0,
1087 1808 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum)
1088 : .DesignWaterMassFlowRate,
1089 1808 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).WaterInletNodeNum,
1090 1808 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum).WaterOutletNodeNum);
1091 : }
1092 : }
1093 :
1094 3616 : simpleWatertoAirHP.SimFlag = true;
1095 :
1096 3616 : state.dataWaterToAirHeatPumpSimple->MyEnvrnFlag(HPNum) = false;
1097 : }
1098 :
1099 : } // End If for the Begin Environment initializations
1100 :
1101 76196727 : if (!state.dataGlobal->BeginEnvrnFlag) {
1102 76046553 : 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 76196727 : int AirInletNode = simpleWatertoAirHP.AirInletNodeNum;
1112 76196727 : int WaterInletNode = simpleWatertoAirHP.WaterInletNodeNum;
1113 :
1114 76196727 : if ((SensLoad != 0.0 || LatentLoad != 0.0) && (state.dataLoopNodes->Node(AirInletNode).MassFlowRate > 0.0)) {
1115 28811072 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate;
1116 :
1117 28811072 : simpleWatertoAirHP.AirMassFlowRate = state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
1118 : // If air flow is less than 25% rated flow. Then throw warning
1119 28811072 : RatedAirMassFlowRate =
1120 28811072 : simpleWatertoAirHP.RatedAirVolFlowRate * Psychrometrics::PsyRhoAirFnPbTdbW(state,
1121 28811072 : state.dataEnvrn->StdBaroPress,
1122 28811072 : state.dataLoopNodes->Node(AirInletNode).Temp,
1123 28811072 : state.dataLoopNodes->Node(AirInletNode).HumRat,
1124 : RoutineName);
1125 28811072 : if (simpleWatertoAirHP.AirMassFlowRate < 0.25 * RatedAirMassFlowRate) {
1126 13665816 : ShowRecurringWarningErrorAtEnd(state,
1127 : "Actual air mass flow rate is smaller than 25% of water-to-air heat pump coil rated air flow rate.",
1128 1708227 : state.dataWaterToAirHeatPumpSimple->AirflowErrPointer,
1129 1708227 : simpleWatertoAirHP.AirMassFlowRate,
1130 1708227 : simpleWatertoAirHP.AirMassFlowRate);
1131 : }
1132 28811072 : simpleWatertoAirHP.WaterFlowMode = true;
1133 : } else { // heat pump is off
1134 47385655 : simpleWatertoAirHP.WaterFlowMode = false;
1135 47385655 : simpleWatertoAirHP.WaterMassFlowRate = 0.0;
1136 47385655 : simpleWatertoAirHP.AirMassFlowRate = 0.0;
1137 47385655 : 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 76196727 : PlantUtilities::SetComponentFlowRate(state,
1172 76196727 : simpleWatertoAirHP.WaterMassFlowRate,
1173 : simpleWatertoAirHP.WaterInletNodeNum,
1174 : simpleWatertoAirHP.WaterOutletNodeNum,
1175 76196727 : simpleWatertoAirHP.plantLoc);
1176 :
1177 76196727 : simpleWatertoAirHP.InletAirDBTemp = state.dataLoopNodes->Node(AirInletNode).Temp;
1178 76196727 : simpleWatertoAirHP.InletAirHumRat = state.dataLoopNodes->Node(AirInletNode).HumRat;
1179 76196727 : simpleWatertoAirHP.InletAirEnthalpy = state.dataLoopNodes->Node(AirInletNode).Enthalpy;
1180 76196727 : simpleWatertoAirHP.InletWaterTemp = state.dataLoopNodes->Node(WaterInletNode).Temp;
1181 76196727 : simpleWatertoAirHP.InletWaterEnthalpy = state.dataLoopNodes->Node(WaterInletNode).Enthalpy;
1182 76196727 : simpleWatertoAirHP.OutletWaterTemp = simpleWatertoAirHP.InletWaterTemp;
1183 76196727 : simpleWatertoAirHP.OutletWaterEnthalpy = simpleWatertoAirHP.InletWaterEnthalpy;
1184 :
1185 : // Outlet variables
1186 76196727 : simpleWatertoAirHP.Power = 0.0;
1187 76196727 : simpleWatertoAirHP.QLoadTotal = 0.0;
1188 76196727 : simpleWatertoAirHP.QLoadTotalReport = 0.0;
1189 76196727 : simpleWatertoAirHP.QSensible = 0.0;
1190 76196727 : simpleWatertoAirHP.QLatent = 0.0;
1191 76196727 : simpleWatertoAirHP.QSource = 0.0;
1192 76196727 : simpleWatertoAirHP.Energy = 0.0;
1193 76196727 : simpleWatertoAirHP.EnergyLoadTotal = 0.0;
1194 76196727 : simpleWatertoAirHP.EnergySensible = 0.0;
1195 76196727 : simpleWatertoAirHP.EnergyLatent = 0.0;
1196 76196727 : simpleWatertoAirHP.EnergySource = 0.0;
1197 76196727 : simpleWatertoAirHP.COP = 0.0;
1198 76196727 : state.dataHeatBal->HeatReclaimSimple_WAHPCoil(HPNum).AvailCapacity = 0.0;
1199 76196727 : }
1200 :
1201 530 : 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 530 : 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 530 : Real64 RatedMixWetBulb = 0.0; // Rated mixed air wetbulb temperature
1236 530 : Real64 RatedMixDryBulb = 0.0; // Rated mixed air drybulb temperature
1237 530 : 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 530 : 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 530 : Real64 PeakTotCapTempModFac = 1.0; // Peak total cooling capacity curve modifier
1261 530 : Real64 RatedTotCapTempModFac = 1.0; // Rated total cooling capacity curve modifier
1262 530 : 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 530 : Real64 PeakSensCapTempModFac = 1.0; // Peak sensible cooling capacity curve modifier
1266 530 : Real64 RatedSensCapTempModFac = 1.0; // Rated sensible cooling capacity curve modifier
1267 530 : Real64 RatedHeatCapTempModFac = 1.0; // Rated heating capacity curve modifier
1268 530 : Real64 RatedCoolPowerTempModFac = 1.0; // Rated cooling power curve modifier
1269 530 : Real64 RatedHeatPowerTempModFac = 1.0; // Rated heating power curve modifier
1270 : Real64 RatedCapCoolTotalDesCDD; // Rated total cooling coil capacity determined at cooling design conditions
1271 530 : 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 530 : 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 530 : Real64 HeatdTratio = 1.0; // Temperature difference across coil adjustment factor
1297 530 : 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 530 : ErrorsFound = false;
1307 530 : IsAutoSize = false;
1308 530 : if (state.dataSize->SysSizingRunDone || state.dataSize->ZoneSizingRunDone) {
1309 500 : HardSizeNoDesRun = false;
1310 : } else {
1311 30 : HardSizeNoDesRun = true;
1312 : }
1313 530 : if (state.dataSize->CurSysNum > 0) {
1314 224 : CheckThisAirSystemForSizing(state, state.dataSize->CurSysNum, SizingDesRunThisAirSys);
1315 : } else {
1316 306 : SizingDesRunThisAirSys = false;
1317 : }
1318 530 : if (state.dataSize->CurZoneEqNum > 0) {
1319 306 : CheckThisZoneForSizing(state, state.dataSize->CurZoneEqNum, SizingDesRunThisZone);
1320 : } else {
1321 224 : SizingDesRunThisZone = false;
1322 : }
1323 530 : RatedAirVolFlowRateDes = 0.0;
1324 530 : RatedAirVolFlowRateUser = 0.0;
1325 530 : CoolingAirVolFlowRateDes = 0.0;
1326 530 : HeatingAirVolFlowRateDes = 0.0;
1327 530 : RatedCapCoolTotalDes = 0.0;
1328 530 : RatedCapCoolTotalUser = 0.0;
1329 530 : RatedCapCoolSensDes = 0.0;
1330 530 : RatedCapCoolSensUser = 0.0;
1331 530 : RatedCapHeatDes = 0.0;
1332 530 : RatedCapHeatUser = 0.0;
1333 530 : RatedWaterVolFlowRateDes = 0.0;
1334 530 : RatedWaterVolFlowRateUser = 0.0;
1335 530 : std::string CompType = format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]);
1336 :
1337 530 : if (simpleWatertoAirHP.RatedAirVolFlowRate == DataSizing::AutoSize) {
1338 500 : IsAutoSize = true;
1339 : }
1340 530 : if (state.dataSize->CurSysNum > 0) {
1341 224 : if (!IsAutoSize && !SizingDesRunThisAirSys) { // Simulation continue
1342 30 : HardSizeNoDesRun = true;
1343 30 : if (simpleWatertoAirHP.RatedAirVolFlowRate > 0.0) {
1344 90 : BaseSizer::reportSizerOutput(
1345 : state,
1346 60 : 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 194 : CheckSysSizing(state,
1353 388 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1354 194 : simpleWatertoAirHP.Name);
1355 194 : if (state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow >= HVAC::SmallAirVolFlow) {
1356 194 : RatedAirVolFlowRateDes = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum).DesMainVolFlow;
1357 194 : CoolingAirVolFlowRateDes = state.dataSize->CalcSysSizing(state.dataSize->CurSysNum).DesCoolVolFlow;
1358 194 : HeatingAirVolFlowRateDes = state.dataSize->CalcSysSizing(state.dataSize->CurSysNum).DesHeatVolFlow;
1359 : } else {
1360 0 : RatedAirVolFlowRateDes = 0.0;
1361 : }
1362 : }
1363 306 : } else if (state.dataSize->CurZoneEqNum > 0) {
1364 306 : if (!IsAutoSize && !SizingDesRunThisZone) { // Simulation continue
1365 0 : HardSizeNoDesRun = true;
1366 0 : if (simpleWatertoAirHP.RatedAirVolFlowRate > 0.0) {
1367 0 : BaseSizer::reportSizerOutput(
1368 : state,
1369 0 : 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 612 : CheckZoneSizing(state,
1376 612 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1377 : simpleWatertoAirHP.Name);
1378 306 : RatedAirVolFlowRateDes = max(state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow,
1379 306 : state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatVolFlow);
1380 306 : CoolingAirVolFlowRateDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolVolFlow;
1381 306 : HeatingAirVolFlowRateDes = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatVolFlow;
1382 306 : if (RatedAirVolFlowRateDes < HVAC::SmallAirVolFlow) {
1383 0 : RatedAirVolFlowRateDes = 0.0;
1384 : }
1385 : }
1386 : }
1387 530 : if (!HardSizeNoDesRun) {
1388 500 : if (IsAutoSize) {
1389 500 : simpleWatertoAirHP.RatedAirVolFlowRate = RatedAirVolFlowRateDes;
1390 1500 : BaseSizer::reportSizerOutput(
1391 : state,
1392 1000 : 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 530 : RatedCapCoolTotalAutoSized = false;
1427 530 : RatedCapCoolSensAutoSized = false;
1428 :
1429 530 : Real64 FanCoolLoad = 0.0;
1430 530 : Real64 FanHeatLoad = FanCoolLoad;
1431 530 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
1432 : // size rated total cooling capacity
1433 265 : if (simpleWatertoAirHP.RatedCapCoolTotal == DataSizing::AutoSize) {
1434 250 : RatedCapCoolTotalAutoSized = true;
1435 : }
1436 265 : if (SizingDesRunThisAirSys || SizingDesRunThisZone) {
1437 250 : HardSizeNoDesRun = false;
1438 : }
1439 265 : if (state.dataSize->CurSysNum > 0) {
1440 112 : if (!RatedCapCoolTotalAutoSized && !SizingDesRunThisAirSys) { // Simulation continue
1441 15 : HardSizeNoDesRun = true;
1442 15 : if (simpleWatertoAirHP.RatedCapCoolTotal > 0.0) {
1443 45 : BaseSizer::reportSizerOutput(
1444 : state,
1445 30 : 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 97 : CheckSysSizing(
1452 : state,
1453 194 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1454 97 : simpleWatertoAirHP.Name);
1455 97 : if (CoolingAirVolFlowRateDes > 0.0) {
1456 97 : VolFlowRate = CoolingAirVolFlowRateDes;
1457 : } else {
1458 0 : VolFlowRate = HeatingAirVolFlowRateDes; // system air flow
1459 : }
1460 : // cooling design day calculations
1461 97 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
1462 97 : auto const &finalSysSizing = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum);
1463 97 : 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 97 : SupTemp = finalSysSizing.CoolSupTemp;
1472 97 : SupHumRat = finalSysSizing.CoolSupHumRat;
1473 97 : if (VolFlowRate > 0.0) {
1474 97 : OutAirFrac = finalSysSizing.DesOutAirVolFlow / VolFlowRate;
1475 97 : OutAirFracSys = finalSysSizing.DesOutAirVolFlow / RatedAirVolFlowRateDes;
1476 : } else {
1477 0 : OutAirFrac = 1.0;
1478 0 : OutAirFracSys = OutAirFrac;
1479 : }
1480 97 : OutAirFrac = min(1.0, max(0.0, OutAirFrac));
1481 97 : OutAirFracSys = min(1.0, max(0.0, OutAirFracSys));
1482 97 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).NumOACoolCoils ==
1483 : 0) { // there is no precooling of the OA stream
1484 97 : MixTemp = finalSysSizing.MixTempAtCoolPeak;
1485 97 : MixHumRat = finalSysSizing.MixHumRatAtCoolPeak;
1486 : // calculate mixed air temperature with system airflow
1487 97 : MixTempSys =
1488 97 : OutAirFracSys * finalSysSizing.OutTempAtCoolPeak + (1.0 - OutAirFracSys) * finalSysSizing.RetTempAtCoolPeak;
1489 97 : MixHumRatSys =
1490 97 : 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 97 : SupTemp = min(MixTemp, SupTemp);
1502 97 : SupHumRat = min(MixHumRat, SupHumRat);
1503 97 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, MixTemp, MixHumRat, RoutineName);
1504 97 : MixEnth = Psychrometrics::PsyHFnTdbW(MixTemp, MixHumRat);
1505 97 : MixEnthSys = Psychrometrics::PsyHFnTdbW(MixTempSys, MixHumRatSys);
1506 97 : SupEnth = Psychrometrics::PsyHFnTdbW(SupTemp, SupHumRat);
1507 : // determine the coil ratio of coil dT with system air flow to design heating air flow
1508 97 : dHratio = (SupEnth - MixEnthSys) / (SupEnth - MixEnth);
1509 97 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid && state.dataSize->DataFanIndex > 0) { // add fan heat to coil load
1510 97 : FanCoolLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
1511 :
1512 97 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(MixHumRat);
1513 97 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace == HVAC::FanPlace::BlowThru) {
1514 97 : 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 97 : CoolCapAtPeak = (rhoair * VolFlowRate * (MixEnth - SupEnth)) +
1521 : FanCoolLoad; // load on the cooling coil which includes ventilation load and fan heat
1522 97 : CoolCapAtPeak = max(0.0, CoolCapAtPeak);
1523 97 : MixWetBulb = Psychrometrics::PsyTwbFnTdbWPb(state, MixTemp, MixHumRat, state.dataEnvrn->StdBaroPress, RoutineName);
1524 97 : RatedMixWetBulb = simpleWatertoAirHP.RatedEntAirWetbulbTemp;
1525 : // calculate temperatue ratio at design day peak conditions
1526 97 : ratioTWB = (MixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1527 194 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
1528 : state,
1529 194 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1530 : simpleWatertoAirHP.Name,
1531 : simpleWatertoAirHP.WaterInletNodeNum,
1532 : simpleWatertoAirHP.WaterOutletNodeNum,
1533 : ErrorsFound,
1534 : false);
1535 97 : if (PltSizNum > 0) {
1536 97 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
1537 97 : 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 97 : RatedratioTWB = (RatedMixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1550 97 : RatedratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1551 : // determine curve modifiers at peak and rated conditions
1552 97 : PeakTotCapTempModFac = simpleWatertoAirHP.TotalCoolCapCurve->value(state, ratioTWB, ratioTS, 1.0, 1.0);
1553 97 : RatedTotCapTempModFac = simpleWatertoAirHP.TotalCoolCapCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
1554 97 : 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 97 : RatedCapCoolTotalDes = (PeakTotCapTempModFac > 0.0) ? CoolCapAtPeak / PeakTotCapTempModFac : CoolCapAtPeak;
1560 : // reporting
1561 97 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirTemp(
1562 97 : state, simpleWatertoAirHP.Name, CompType, MixTemp, state.dataSize->CurSysNum, state.dataSize->CurZoneEqNum);
1563 97 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirHumRat(state, simpleWatertoAirHP.Name, CompType, MixHumRat);
1564 97 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirTemp(state, simpleWatertoAirHP.Name, CompType, SupTemp);
1565 97 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirHumRat(state, simpleWatertoAirHP.Name, CompType, SupHumRat);
1566 : } else {
1567 0 : RatedCapCoolTotalDes = 0.0;
1568 : }
1569 : }
1570 153 : } else if (state.dataSize->CurZoneEqNum > 0) {
1571 153 : if (!RatedCapCoolTotalAutoSized && !SizingDesRunThisZone) { // Simulation continue
1572 0 : HardSizeNoDesRun = true;
1573 0 : if (simpleWatertoAirHP.RatedCapCoolTotal > 0.0) {
1574 0 : BaseSizer::reportSizerOutput(
1575 : state,
1576 0 : 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 306 : CheckZoneSizing(
1583 : state,
1584 306 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1585 : simpleWatertoAirHP.Name);
1586 153 : if (CoolingAirVolFlowRateDes > 0.0) {
1587 151 : VolFlowRate = CoolingAirVolFlowRateDes;
1588 : } else {
1589 2 : VolFlowRate = HeatingAirVolFlowRateDes; // system air flow
1590 : }
1591 153 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
1592 : // cooling design calculations
1593 153 : if (state.dataSize->ZoneEqDXCoil) {
1594 153 : if (state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow > 0.0) {
1595 7 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp;
1596 7 : MixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInHumRat;
1597 : // calculate mixed air temperature and humidity with system airflow
1598 7 : OAFrac = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA / CoolingAirVolFlowRateDes;
1599 7 : OAFracSys = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA / RatedAirVolFlowRateDes;
1600 7 : OATemp = (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp -
1601 7 : (1.0 - OAFrac) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneTempAtCoolPeak) /
1602 : OAFrac;
1603 7 : OAHumRat = (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInHumRat -
1604 7 : (1.0 - OAFrac) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneHumRatAtHeatPeak) /
1605 : OAFrac;
1606 14 : MixTempSys = OAFracSys * OATemp +
1607 7 : (1.0 - OAFracSys) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneTempAtCoolPeak;
1608 14 : MixHumRatSys = OAFracSys * OAHumRat +
1609 7 : (1.0 - OAFracSys) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneHumRatAtHeatPeak;
1610 : } else {
1611 146 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneRetTempAtCoolPeak;
1612 146 : MixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneHumRatAtCoolPeak;
1613 146 : MixTempSys = MixTemp;
1614 146 : 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 153 : SupTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDesTemp;
1623 153 : 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 153 : SupTemp = min(MixTemp, SupTemp);
1626 153 : SupHumRat = min(MixHumRat, SupHumRat);
1627 153 : int TimeStepNumAtMax = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).TimeStepNumAtCoolMax;
1628 153 : int DDNum = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDDNum;
1629 153 : if (DDNum > 0 && TimeStepNumAtMax > 0) {
1630 153 : OutTemp = state.dataSize->DesDayWeath(DDNum).Temp(TimeStepNumAtMax);
1631 : } else {
1632 0 : OutTemp = 0.0;
1633 : }
1634 153 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, MixTemp, MixHumRat, RoutineName);
1635 153 : MixEnth = Psychrometrics::PsyHFnTdbW(MixTemp, MixHumRat);
1636 153 : MixEnthSys = Psychrometrics::PsyHFnTdbW(MixTempSys, MixHumRatSys);
1637 153 : SupEnth = Psychrometrics::PsyHFnTdbW(SupTemp, SupHumRat);
1638 : // determine the coil ratio of coil dH with system air flow to design heating air flow
1639 153 : dHratio = (SupEnth - MixEnthSys) / (SupEnth - MixEnth);
1640 153 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid && state.dataSize->DataFanIndex > 0) { // add fan heat to coil load
1641 153 : FanCoolLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
1642 :
1643 153 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(MixHumRat);
1644 153 : if (state.dataSize->DataFanPlacement == HVAC::FanPlace::BlowThru) {
1645 146 : MixTemp += FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature entering the coil
1646 : } else {
1647 7 : SupTemp -= FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature leaving the coil
1648 : }
1649 : }
1650 153 : CoolCapAtPeak = (rhoair * VolFlowRate * (MixEnth - SupEnth)) +
1651 : FanCoolLoad; // load on the cooling coil which includes ventilation load and fan heat
1652 153 : CoolCapAtPeak = max(0.0, CoolCapAtPeak);
1653 153 : MixWetBulb = Psychrometrics::PsyTwbFnTdbWPb(state, MixTemp, MixHumRat, state.dataEnvrn->StdBaroPress, RoutineName);
1654 153 : RatedMixWetBulb = simpleWatertoAirHP.RatedEntAirWetbulbTemp;
1655 : // calculate temperatue ratio at design day peak conditions
1656 153 : ratioTWB = (MixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1657 306 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
1658 : state,
1659 306 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1660 : simpleWatertoAirHP.Name,
1661 : simpleWatertoAirHP.WaterInletNodeNum,
1662 : simpleWatertoAirHP.WaterOutletNodeNum,
1663 : ErrorsFound,
1664 : false);
1665 153 : if (PltSizNum > 0) {
1666 153 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
1667 153 : ratioTS = (DesignEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1668 : } else {
1669 0 : ShowSevereError(state, "Autosizing of total cooling capacity requires a loop Sizing:Plant object");
1670 0 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
1671 0 : ShowContinueError(state,
1672 0 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
1673 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
1674 0 : simpleWatertoAirHP.Name));
1675 0 : ratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
1676 0 : ErrorsFound = true;
1677 : }
1678 : // calculate temperatue ratio at rated conditions
1679 153 : RatedratioTWB = (RatedMixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1680 153 : RatedratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1681 : // determine curve modifiers at peak and rated conditions
1682 153 : PeakTotCapTempModFac = simpleWatertoAirHP.TotalCoolCapCurve->value(state, ratioTWB, ratioTS, 1.0, 1.0);
1683 153 : RatedTotCapTempModFac = simpleWatertoAirHP.TotalCoolCapCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
1684 153 : 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 153 : RatedCapCoolTotalDes = (PeakTotCapTempModFac > 0.0) ? CoolCapAtPeak / PeakTotCapTempModFac : CoolCapAtPeak;
1690 : // reporting
1691 153 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirTemp(
1692 153 : state, simpleWatertoAirHP.Name, CompType, MixTemp, state.dataSize->CurSysNum, state.dataSize->CurZoneEqNum);
1693 153 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilEntAirHumRat(state, simpleWatertoAirHP.Name, CompType, MixHumRat);
1694 153 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirTemp(state, simpleWatertoAirHP.Name, CompType, SupTemp);
1695 153 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilLvgAirHumRat(state, simpleWatertoAirHP.Name, CompType, SupHumRat);
1696 : } else {
1697 0 : RatedCapCoolTotalDes = 0.0;
1698 : }
1699 : }
1700 153 : if (RatedCapCoolTotalDes < HVAC::SmallLoad) {
1701 0 : RatedCapCoolTotalDes = 0.0;
1702 : }
1703 : }
1704 : // size rated sensible cooling capacity
1705 265 : if (simpleWatertoAirHP.RatedCapCoolSens == DataSizing::AutoSize && simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
1706 250 : RatedCapCoolSensAutoSized = true;
1707 : }
1708 265 : if (SizingDesRunThisAirSys || SizingDesRunThisZone) {
1709 250 : HardSizeNoDesRun = false;
1710 : }
1711 265 : if (state.dataSize->CurSysNum > 0) {
1712 112 : if (!RatedCapCoolSensAutoSized && !SizingDesRunThisAirSys) { // Simulation continue
1713 15 : HardSizeNoDesRun = true;
1714 15 : if (simpleWatertoAirHP.RatedCapCoolSens > 0.0) {
1715 45 : BaseSizer::reportSizerOutput(
1716 : state,
1717 30 : 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 97 : CheckSysSizing(
1724 : state,
1725 194 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1726 97 : simpleWatertoAirHP.Name);
1727 97 : if (CoolingAirVolFlowRateDes > 0.0) {
1728 97 : VolFlowRate = CoolingAirVolFlowRateDes;
1729 : } else {
1730 0 : VolFlowRate = HeatingAirVolFlowRateDes; // system air flow
1731 : }
1732 97 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
1733 97 : auto const &finalSysSizing = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum);
1734 97 : 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 97 : SupTemp = finalSysSizing.CoolSupTemp;
1741 97 : SupHumRat = finalSysSizing.CoolSupHumRat;
1742 97 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).NumOACoolCoils ==
1743 : 0) { // there is no precooling of the OA stream
1744 97 : MixTemp = finalSysSizing.MixTempAtCoolPeak;
1745 97 : 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 97 : SupTemp = min(MixTemp, SupTemp);
1759 97 : SupHumRat = min(MixHumRat, SupHumRat);
1760 97 : OutTemp = finalSysSizing.OutTempAtCoolPeak;
1761 97 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, MixTemp, MixHumRat, RoutineName);
1762 97 : MixEnth = Psychrometrics::PsyHFnTdbW(MixTemp, MixHumRat);
1763 97 : SupEnth = Psychrometrics::PsyHFnTdbW(SupTemp, MixHumRat);
1764 97 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid && state.dataSize->DataFanIndex > 0) { // add fan heat to coil load
1765 97 : FanCoolLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
1766 :
1767 97 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(MixHumRat);
1768 97 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace == HVAC::FanPlace::BlowThru) {
1769 97 : 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 97 : SensCapAtPeak = (rhoair * VolFlowRate * (MixEnth - SupEnth)) +
1779 : FanCoolLoad; // load on the cooling coil which includes ventilation load and fan heat (sensible)
1780 97 : SensCapAtPeak = max(0.0, SensCapAtPeak);
1781 97 : MixWetBulb = Psychrometrics::PsyTwbFnTdbWPb(state, MixTemp, MixHumRat, state.dataEnvrn->StdBaroPress, RoutineName);
1782 97 : RatedMixWetBulb = simpleWatertoAirHP.RatedEntAirWetbulbTemp;
1783 97 : RatedMixDryBulb = simpleWatertoAirHP.RatedEntAirDrybulbTemp;
1784 : // calculate temperature ratios at design day peak conditions
1785 97 : ratioTDB = (MixTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1786 97 : ratioTWB = (MixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1787 194 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
1788 : state,
1789 194 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1790 : simpleWatertoAirHP.Name,
1791 : simpleWatertoAirHP.WaterInletNodeNum,
1792 : simpleWatertoAirHP.WaterOutletNodeNum,
1793 : ErrorsFound,
1794 : false);
1795 97 : if (PltSizNum > 0) {
1796 97 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
1797 97 : 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 97 : RatedratioTDB = (RatedMixDryBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1809 97 : RatedratioTWB = (RatedMixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1810 97 : RatedratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1811 : // determine curve modifiers at peak and rated conditions
1812 97 : PeakSensCapTempModFac = simpleWatertoAirHP.SensCoolCapCurve->value(state, ratioTDB, ratioTWB, ratioTS, 1.0, 1.0);
1813 97 : RatedSensCapTempModFac =
1814 97 : 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 97 : RatedCapCoolSensDes = (PeakSensCapTempModFac > 0.0) ? SensCapAtPeak / PeakSensCapTempModFac : SensCapAtPeak;
1820 : } else {
1821 0 : RatedCapCoolSensDes = 0.0;
1822 : }
1823 : }
1824 153 : } else if (state.dataSize->CurZoneEqNum > 0) {
1825 153 : if (!RatedCapCoolSensAutoSized && !SizingDesRunThisZone) { // Simulation continue
1826 0 : HardSizeNoDesRun = true;
1827 0 : if (simpleWatertoAirHP.RatedCapCoolSens > 0.0) {
1828 0 : BaseSizer::reportSizerOutput(
1829 : state,
1830 0 : 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 306 : CheckZoneSizing(
1837 : state,
1838 306 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1839 : simpleWatertoAirHP.Name);
1840 153 : if (CoolingAirVolFlowRateDes > 0.0) {
1841 151 : VolFlowRate = CoolingAirVolFlowRateDes;
1842 : } else {
1843 2 : VolFlowRate = HeatingAirVolFlowRateDes; // system air flow
1844 : }
1845 153 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
1846 153 : if (state.dataSize->ZoneEqDXCoil) {
1847 153 : if (state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow > 0.0) {
1848 7 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInTemp;
1849 7 : MixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesCoolCoilInHumRat;
1850 : } else {
1851 146 : MixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneRetTempAtCoolPeak;
1852 146 : 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 153 : SupTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDesTemp;
1859 153 : 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 153 : SupTemp = min(MixTemp, SupTemp);
1862 153 : SupHumRat = min(MixHumRat, SupHumRat);
1863 153 : int TimeStepNumAtMax = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).TimeStepNumAtCoolMax;
1864 153 : int DDNum = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).CoolDDNum;
1865 153 : if (DDNum > 0 && TimeStepNumAtMax > 0) {
1866 153 : OutTemp = state.dataSize->DesDayWeath(DDNum).Temp(TimeStepNumAtMax);
1867 : } else {
1868 0 : OutTemp = 0.0;
1869 : }
1870 153 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, MixTemp, MixHumRat, RoutineName);
1871 153 : MixEnth = Psychrometrics::PsyHFnTdbW(MixTemp, MixHumRat);
1872 153 : SupEnth = Psychrometrics::PsyHFnTdbW(SupTemp, MixHumRat);
1873 153 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid && state.dataSize->DataFanIndex > 0) { // add fan heat to coil load
1874 153 : FanCoolLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
1875 :
1876 153 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(MixHumRat);
1877 153 : if (state.dataSize->DataFanPlacement == HVAC::FanPlace::BlowThru) {
1878 146 : MixTemp += FanCoolLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature entering the coil
1879 : } else {
1880 7 : 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 153 : SensCapAtPeak = (rhoair * VolFlowRate * (MixEnth - SupEnth)) +
1887 : FanCoolLoad; // load on the cooling coil which includes ventilation load and fan heat (sensible)
1888 153 : SensCapAtPeak = max(0.0, SensCapAtPeak);
1889 153 : MixWetBulb = Psychrometrics::PsyTwbFnTdbWPb(state, MixTemp, MixHumRat, state.dataEnvrn->StdBaroPress, RoutineName);
1890 153 : RatedMixWetBulb = simpleWatertoAirHP.RatedEntAirWetbulbTemp;
1891 153 : RatedMixDryBulb = simpleWatertoAirHP.RatedEntAirDrybulbTemp;
1892 : // calculate temperature ratios at design day peak conditions
1893 153 : ratioTDB = (MixTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1894 153 : ratioTWB = (MixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1895 306 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
1896 : state,
1897 306 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
1898 : simpleWatertoAirHP.Name,
1899 : simpleWatertoAirHP.WaterInletNodeNum,
1900 : simpleWatertoAirHP.WaterOutletNodeNum,
1901 : ErrorsFound,
1902 : false);
1903 153 : if (PltSizNum > 0) {
1904 153 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
1905 153 : ratioTS = (DesignEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1906 : } else {
1907 0 : ShowSevereError(state, "Autosizing of sensible cooling capacity requires a loop Sizing:Plant object");
1908 0 : ShowContinueError(state, "Autosizing also requires physical connection to a plant or condenser loop.");
1909 0 : ShowContinueError(state,
1910 0 : format("Occurs in COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT Object={}",
1911 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
1912 0 : simpleWatertoAirHP.Name));
1913 0 : ErrorsFound = true;
1914 : }
1915 : // calculate temperatue ratio at rated conditions
1916 153 : RatedratioTDB = (RatedMixDryBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1917 153 : RatedratioTWB = (RatedMixWetBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1918 153 : RatedratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
1919 153 : PeakSensCapTempModFac = simpleWatertoAirHP.SensCoolCapCurve->value(state, ratioTDB, ratioTWB, ratioTS, 1.0, 1.0);
1920 153 : RatedSensCapTempModFac =
1921 153 : 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 153 : RatedCapCoolSensDes = (PeakSensCapTempModFac > 0.0) ? SensCapAtPeak / PeakSensCapTempModFac : SensCapAtPeak;
1928 : } else {
1929 0 : RatedCapCoolSensDes = 0.0;
1930 : }
1931 : }
1932 : }
1933 265 : if (RatedCapCoolSensDes < HVAC::SmallLoad) {
1934 15 : RatedCapCoolSensDes = 0.0;
1935 : }
1936 265 : if (RatedCapCoolTotalAutoSized && RatedCapCoolSensAutoSized) {
1937 250 : if (RatedCapCoolSensDes > RatedCapCoolTotalDes) {
1938 18 : RatedCapCoolTotalDes = RatedCapCoolSensDes;
1939 : }
1940 : }
1941 265 : if (!HardSizeNoDesRun) {
1942 250 : if (RatedCapCoolTotalAutoSized) {
1943 250 : if (simpleWatertoAirHP.CompanionHeatingCoilNum > 0) {
1944 : auto const &companionHeatingCoil =
1945 250 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum);
1946 250 : if (companionHeatingCoil.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit &&
1947 250 : 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 250 : } else if (companionHeatingCoil.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit &&
1983 250 : 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 250 : 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 0 : RatedCapCoolTotalDes *= (RatedAirVolFlowRateDes / CoolingAirVolFlowRateDes) * dHratio;
2006 :
2007 0 : simpleWatertoAirHP.RatedCapCoolTotal = RatedCapCoolTotalDes;
2008 0 : state.dataSize->DXCoolCap = simpleWatertoAirHP.RatedCapCoolTotal;
2009 : }
2010 : // size power
2011 250 : simpleWatertoAirHP.RatedCapCoolAtRatedCdts = RatedCapCoolTotalDes * RatedTotCapTempModFac;
2012 250 : simpleWatertoAirHP.RatedPowerCoolAtRatedCdts =
2013 250 : simpleWatertoAirHP.RatedCapCoolAtRatedCdts / simpleWatertoAirHP.RatedCOPCoolAtRatedCdts;
2014 250 : simpleWatertoAirHP.RatedPowerCool = simpleWatertoAirHP.RatedPowerCoolAtRatedCdts / RatedCoolPowerTempModFac;
2015 250 : if (simpleWatertoAirHP.RatedCapCoolTotal != DataSizing::AutoSize) {
2016 0 : BaseSizer::reportSizerOutput(
2017 : state,
2018 0 : 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 500 : OutputReportPredefined::PreDefTableEntry(
2024 250 : state, state.dataOutRptPredefined->pdchWAHPRatedAirDBT, simpleWatertoAirHP.Name, RatedMixDryBulb);
2025 500 : OutputReportPredefined::PreDefTableEntry(
2026 250 : state, state.dataOutRptPredefined->pdchWAHPRatedAirWBT, simpleWatertoAirHP.Name, RatedMixWetBulb);
2027 500 : OutputReportPredefined::PreDefTableEntry(
2028 250 : 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 15 : state.dataSize->DXCoolCap = simpleWatertoAirHP.RatedCapCoolTotal;
2061 : // user provided inputs are assumed to be at rated conditions
2062 15 : simpleWatertoAirHP.RatedPowerCool = simpleWatertoAirHP.RatedCapCoolTotal / simpleWatertoAirHP.RatedCOPCoolAtRatedCdts;
2063 15 : simpleWatertoAirHP.RatedCapCoolAtRatedCdts = 0;
2064 15 : simpleWatertoAirHP.RatedPowerCoolAtRatedCdts = 0;
2065 : }
2066 265 : if (simpleWatertoAirHP.RatedCapCoolTotal !=
2067 : DataSizing::AutoSize) { // all cases except case 2 mentioned above (when EquationFit companion heating coil has not yet been sized)
2068 30 : OutputReportPredefined::PreDefTableEntry(
2069 15 : state, state.dataOutRptPredefined->pdchCoolCoilTotCap, simpleWatertoAirHP.Name, simpleWatertoAirHP.RatedCapCoolTotal);
2070 30 : OutputReportPredefined::PreDefTableEntry(state,
2071 15 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
2072 : simpleWatertoAirHP.Name,
2073 15 : simpleWatertoAirHP.RatedCapCoolTotal - simpleWatertoAirHP.RatedCapCoolSens);
2074 15 : if (simpleWatertoAirHP.RatedCapCoolTotal > 0) {
2075 30 : OutputReportPredefined::PreDefTableEntry(state,
2076 15 : state.dataOutRptPredefined->pdchCoolCoilSHR,
2077 : simpleWatertoAirHP.Name,
2078 15 : simpleWatertoAirHP.RatedCapCoolSens / simpleWatertoAirHP.RatedCapCoolTotal);
2079 : } else {
2080 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, simpleWatertoAirHP.Name, 0.0);
2081 : }
2082 15 : if (RatedCapCoolTotalAutoSized) {
2083 0 : OutputReportPredefined::PreDefTableEntry(state,
2084 0 : state.dataOutRptPredefined->pdchWAHPRatedCapAtRatedCdts,
2085 : simpleWatertoAirHP.Name,
2086 : simpleWatertoAirHP.RatedCapCoolAtRatedCdts);
2087 0 : 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 250 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilTotCap, simpleWatertoAirHP.Name, 0.0);
2096 250 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilLatCap, simpleWatertoAirHP.Name, 0.0);
2097 250 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilSHR, simpleWatertoAirHP.Name, 0.0);
2098 250 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchCoolCoilNomEff, simpleWatertoAirHP.Name, 0.0);
2099 : }
2100 265 : if (simpleWatertoAirHP.RatedCapCoolTotal != DataSizing::AutoSize) {
2101 15 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilCoolingCapacity(state,
2102 15 : simpleWatertoAirHP.Name,
2103 : CompType,
2104 : simpleWatertoAirHP.RatedCapCoolTotal,
2105 : RatedCapCoolTotalAutoSized,
2106 15 : state.dataSize->CurSysNum,
2107 15 : state.dataSize->CurZoneEqNum,
2108 15 : state.dataSize->CurOASysNum,
2109 : FanCoolLoad,
2110 : PeakTotCapTempModFac,
2111 : -999.0,
2112 : -999.0);
2113 : }
2114 265 : if (!HardSizeNoDesRun) {
2115 250 : if (RatedCapCoolSensAutoSized) {
2116 250 : simpleWatertoAirHP.RatedCapCoolSens = RatedCapCoolSensDes;
2117 250 : simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts = RatedCapCoolSensDes * RatedSensCapTempModFac;
2118 250 : if (simpleWatertoAirHP.RatedCapCoolTotal != DataSizing::AutoSize) {
2119 0 : BaseSizer::reportSizerOutput(
2120 : state,
2121 0 : 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 530 : OutputReportPredefined::PreDefTableEntry(
2157 265 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, simpleWatertoAirHP.Name, simpleWatertoAirHP.RatedCapCoolSens);
2158 530 : OutputReportPredefined::PreDefTableEntry(state,
2159 265 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
2160 : simpleWatertoAirHP.Name,
2161 265 : state.dataSize->DXCoolCap - simpleWatertoAirHP.RatedCapCoolSens);
2162 265 : if (RatedCapCoolSensAutoSized) {
2163 :
2164 500 : OutputReportPredefined::PreDefTableEntry(state,
2165 250 : state.dataOutRptPredefined->pdchWAHPRatedSensCapAtRatedCdts,
2166 : simpleWatertoAirHP.Name,
2167 : simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts);
2168 : }
2169 265 : if (simpleWatertoAirHP.RatedCapCoolTotal != 0.0) {
2170 530 : OutputReportPredefined::PreDefTableEntry(state,
2171 265 : state.dataOutRptPredefined->pdchCoolCoilSHR,
2172 : simpleWatertoAirHP.Name,
2173 265 : 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 265 : if ((RatedCapCoolSensAutoSized && RatedCapCoolTotalAutoSized) || RatedCapCoolSensAutoSized) {
2179 250 : if (simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts > simpleWatertoAirHP.RatedCapCoolAtRatedCdts) {
2180 36 : ShowWarningError(state,
2181 36 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT \"{}\"",
2182 18 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2183 18 : simpleWatertoAirHP.Name));
2184 18 : ShowContinueError(state, format("{}: Rated Sensible Cooling Capacity > Rated Total Cooling Capacity", RoutineName));
2185 36 : ShowContinueError(state, "Both of these capacity inputs have been autosized.");
2186 36 : ShowContinueError(
2187 : state,
2188 36 : format("Rated Sensible Cooling Capacity at Rated Conditions = {:.2T} W", simpleWatertoAirHP.RatedCapCoolSensDesAtRatedCdts));
2189 36 : ShowContinueError(
2190 36 : state, format("Rated Total Cooling Capacity at Rated Conditions = {:.2T} W", simpleWatertoAirHP.RatedCapCoolAtRatedCdts));
2191 36 : ShowContinueError(state, "See eio file for further details.");
2192 36 : ShowContinueError(state, "Check Total and Sensible Cooling Capacity coefficients in curves to ensure they are accurate.");
2193 36 : ShowContinueError(state, "Check Zone and System Sizing objects to verify sizing inputs.");
2194 36 : ShowContinueError(state, "Sizing statistics:");
2195 18 : ShowContinueError(state, format("Rated entering Air Wet-Bulb Temperature = {:.3T} C", RatedMixWetBulb));
2196 18 : ShowContinueError(state, format("Peak entering Air Wet-Bulb Temperature = {:.3T} C", MixWetBulb));
2197 18 : ShowContinueError(state, format("Entering Water Temperature used = {:.3T} C", simpleWatertoAirHP.RatedEntWaterTemp));
2198 36 : ShowContinueError(state, "Design air and water flow rates = 1.0");
2199 36 : ShowContinueError(
2200 36 : state, format("Rated ratio of load-side air wet-bulb temperature to 283.15 C (Rated ratioTWB) = {:.3T}", RatedratioTWB));
2201 36 : ShowContinueError(
2202 36 : state, format("Rated ratio of source-side inlet water temperature to 283.15 C (Rated ratioTS) = {:.3T}", RatedratioTS));
2203 36 : ShowContinueError(state,
2204 36 : format("Peak ratio of load-side air wet-bulb temperature to 283.15 C (Peak ratioTWB) = {:.3T}", ratioTWB));
2205 36 : ShowContinueError(state,
2206 36 : format("Peak ratio of source-side inlet water temperature to 283.15 C (Peak ratioTS) = {:.3T}", ratioTS));
2207 18 : ShowContinueError(state, format("Rated Total Cooling Capacity Modifier = {:.5T}", RatedTotCapTempModFac));
2208 18 : ShowContinueError(state, format("Peak Design Total Cooling Capacity Modifier = {:.5T}", PeakTotCapTempModFac));
2209 18 : ShowContinueError(state, format("Rated Sensible Cooling Capacity Modifier = {:.5T}", RatedSensCapTempModFac));
2210 18 : ShowContinueError(state, format("Peak Design Sensible Cooling Capacity Modifier = {:.5T}", PeakSensCapTempModFac));
2211 36 : 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 36 : 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 36 : ShowContinueError(state, "Carefully review the Load Side Total, Sensible, and Latent heat transfer rates");
2220 54 : ShowContinueError(state, "... to ensure they meet the expected manufacturers performance specifications.");
2221 : }
2222 15 : } 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 530 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating) {
2266 : // size rated heating capacity
2267 265 : IsAutoSize = false;
2268 265 : if (simpleWatertoAirHP.RatedCapHeat == DataSizing::AutoSize) {
2269 250 : IsAutoSize = true;
2270 : }
2271 265 : if (SizingDesRunThisAirSys || SizingDesRunThisZone) {
2272 250 : HardSizeNoDesRun = false;
2273 : }
2274 265 : if (IsAutoSize) {
2275 250 : if (state.dataSize->CurSysNum > 0) {
2276 97 : CheckSysSizing(
2277 : state,
2278 194 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2279 97 : simpleWatertoAirHP.Name);
2280 97 : if (HeatingAirVolFlowRateDes > 0.0) {
2281 97 : VolFlowRate = HeatingAirVolFlowRateDes;
2282 : } else {
2283 0 : VolFlowRate = CoolingAirVolFlowRateDes; // system air flow
2284 : }
2285 : // heating design day calculations
2286 97 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
2287 97 : auto const &finalSysSizing = state.dataSize->FinalSysSizing(state.dataSize->CurSysNum);
2288 97 : 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 97 : if (VolFlowRate > 0.0) {
2294 97 : HeatOutAirFrac = finalSysSizing.DesOutAirVolFlow / VolFlowRate;
2295 97 : HeatOutAirFracSys = finalSysSizing.DesOutAirVolFlow / RatedAirVolFlowRateDes;
2296 : } else {
2297 0 : HeatOutAirFrac = 1.0;
2298 0 : HeatOutAirFracSys = HeatOutAirFrac;
2299 : }
2300 97 : HeatOutAirFrac = min(1.0, max(0.0, HeatOutAirFrac));
2301 97 : HeatOutAirFracSys = min(1.0, max(0.0, HeatOutAirFracSys));
2302 97 : HeatSupTemp = finalSysSizing.HeatSupTemp;
2303 97 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).NumOAHeatCoils ==
2304 : 0) { // there is no preheating of the OA stream
2305 97 : HeatMixTemp = HeatOutAirFrac * finalSysSizing.HeatOutTemp + (1.0 - HeatOutAirFrac) * finalSysSizing.HeatRetTemp;
2306 97 : HeatMixHumRat = HeatOutAirFrac * finalSysSizing.HeatOutHumRat + (1.0 - HeatOutAirFrac) * finalSysSizing.HeatRetHumRat;
2307 : // calculate mixed air temperature with system airflow
2308 97 : HeatMixTempSys =
2309 97 : HeatOutAirFracSys * finalSysSizing.HeatOutTemp + (1.0 - HeatOutAirFracSys) * finalSysSizing.HeatRetTemp;
2310 97 : HeatMixHumRatSys =
2311 97 : 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 97 : HeatdTratio = (HeatSupTemp - HeatMixTempSys) / (HeatSupTemp - HeatMixTemp);
2324 : }
2325 97 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, HeatMixTemp, HeatMixHumRat, RoutineName);
2326 97 : HeatCapAtPeak = rhoair * VolFlowRate * Psychrometrics::PsyCpAirFnW(DataPrecisionGlobals::constant_zero) *
2327 97 : (HeatSupTemp - HeatMixTemp); // heating coil load
2328 194 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid &&
2329 97 : state.dataSize->DataFanIndex > 0) { // remove fan heat to coil load
2330 97 : FanHeatLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
2331 :
2332 97 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(HeatMixHumRat);
2333 97 : if (state.dataAirSystemsData->PrimaryAirSystems(state.dataSize->CurSysNum).supFanPlace == HVAC::FanPlace::BlowThru) {
2334 97 : 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 97 : HeatCapAtPeak -= FanHeatLoad; // remove fan heat from heating coil load
2341 97 : HeatCapAtPeak = max(0.0, HeatCapAtPeak);
2342 97 : RatedHeatMixDryBulb = simpleWatertoAirHP.RatedEntAirDrybulbTemp;
2343 : // calculate temperatue ratio at design day peak conditions
2344 97 : HeatratioTDB = (HeatMixTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2345 194 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
2346 : state,
2347 194 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2348 : simpleWatertoAirHP.Name,
2349 : simpleWatertoAirHP.WaterInletNodeNum,
2350 : simpleWatertoAirHP.WaterOutletNodeNum,
2351 : ErrorsFound,
2352 : false);
2353 97 : if (PltSizNum > 0) {
2354 97 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
2355 97 : 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 97 : RatedHeatratioTDB = (RatedHeatMixDryBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2368 97 : RatedHeatratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2369 : // determine curve modifiers at peak and rated conditions
2370 97 : PeakHeatCapTempModFac = simpleWatertoAirHP.HeatCapCurve->value(state, HeatratioTDB, HeatratioTS, 1.0, 1.0);
2371 97 : 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 97 : 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 97 : 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 153 : } else if (state.dataSize->CurZoneEqNum > 0) {
2393 306 : CheckZoneSizing(
2394 : state,
2395 306 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2396 : simpleWatertoAirHP.Name);
2397 153 : if (HeatingAirVolFlowRateDes > 0.0) {
2398 153 : VolFlowRate = HeatingAirVolFlowRateDes;
2399 : } else {
2400 0 : VolFlowRate = CoolingAirVolFlowRateDes; // system air flow
2401 : }
2402 153 : if (VolFlowRate >= HVAC::SmallAirVolFlow) {
2403 153 : if (state.dataSize->ZoneEqDXCoil) {
2404 153 : if (state.dataSize->ZoneEqSizing(state.dataSize->CurZoneEqNum).OAVolFlow > 0.0) {
2405 7 : HeatMixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInTemp;
2406 7 : HeatMixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInHumRat;
2407 : // calculate mixed air temperature with system airflow
2408 7 : HeatOAFrac = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA / HeatingAirVolFlowRateDes;
2409 7 : HeatOAFracSys = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).MinOA / RatedAirVolFlowRateDes;
2410 7 : HeatOAFrac = min(1.0, max(0.0, HeatOAFrac));
2411 7 : HeatOAFracSys = min(1.0, max(0.0, HeatOAFracSys));
2412 7 : HeatOATemp = (state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).DesHeatCoilInTemp -
2413 7 : (1.0 - HeatOAFrac) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneTempAtHeatPeak) /
2414 : HeatOAFrac;
2415 7 : HeatMixTempSys =
2416 7 : HeatOAFracSys * HeatOATemp +
2417 7 : (1.0 - HeatOAFracSys) * state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneTempAtHeatPeak;
2418 : } else {
2419 146 : HeatMixTemp = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneRetTempAtHeatPeak;
2420 146 : HeatMixHumRat = state.dataSize->FinalZoneSizing(state.dataSize->CurZoneEqNum).ZoneHumRatAtHeatPeak;
2421 146 : 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 153 : 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 153 : HeatdTratio = (HeatSupTemp - HeatMixTempSys) / (HeatSupTemp - HeatMixTemp);
2431 153 : rhoair = Psychrometrics::PsyRhoAirFnPbTdbW(state, state.dataEnvrn->StdBaroPress, HeatMixTemp, HeatMixHumRat, RoutineName);
2432 153 : HeatCapAtPeak = rhoair * VolFlowRate * Psychrometrics::PsyCpAirFnW(DataPrecisionGlobals::constant_zero) *
2433 153 : (HeatSupTemp - HeatMixTemp); // heating coil load
2434 153 : if (state.dataSize->DataFanType != HVAC::FanType::Invalid && state.dataSize->DataFanIndex > 0) { // add fan heat to coil load
2435 153 : FanHeatLoad = state.dataFans->fans(state.dataSize->DataFanIndex)->getDesignHeatGain(state, VolFlowRate);
2436 :
2437 153 : Real64 CpAir = Psychrometrics::PsyCpAirFnW(HeatMixHumRat);
2438 153 : if (state.dataSize->DataFanPlacement == HVAC::FanPlace::BlowThru) {
2439 146 : HeatMixTemp += FanHeatLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature entering the coil
2440 : } else {
2441 7 : HeatSupTemp -= FanHeatLoad / (CpAir * rhoair * VolFlowRate); // this is now the temperature leaving the coil
2442 : }
2443 : }
2444 153 : HeatCapAtPeak -= FanHeatLoad; // remove fan heat from heating coil load
2445 153 : HeatCapAtPeak = max(0.0, HeatCapAtPeak);
2446 153 : RatedHeatMixDryBulb = simpleWatertoAirHP.RatedEntAirDrybulbTemp;
2447 : // calculate temperatue ratio at design day peak conditions
2448 153 : HeatratioTDB = (HeatMixTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2449 306 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
2450 : state,
2451 306 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2452 : simpleWatertoAirHP.Name,
2453 : simpleWatertoAirHP.WaterInletNodeNum,
2454 : simpleWatertoAirHP.WaterOutletNodeNum,
2455 : ErrorsFound,
2456 : false);
2457 153 : if (PltSizNum > 0) {
2458 153 : DesignEntWaterTemp = state.dataSize->PlantSizData(PltSizNum).ExitTemp;
2459 153 : 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 153 : RatedHeatratioTDB = (RatedHeatMixDryBulb + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2472 153 : RatedHeatratioTS = (simpleWatertoAirHP.RatedEntWaterTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref;
2473 : // determine curve modifiers at peak and rated conditions
2474 153 : PeakHeatCapTempModFac = simpleWatertoAirHP.HeatCapCurve->value(state, HeatratioTDB, HeatratioTS, 1.0, 1.0);
2475 153 : RatedHeatCapTempModFac = simpleWatertoAirHP.HeatCapCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
2476 153 : 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 153 : 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 153 : RatedCapHeatDes = (PeakHeatCapTempModFac > 0.0) ? HeatCapAtPeak / PeakHeatCapTempModFac : HeatCapAtPeak;
2501 : } else {
2502 0 : RatedHeatratioTS = 0.0; // Clang complains it is used uninitialized if you don't give it a value
2503 0 : 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 250 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts = RatedCapHeatDes * RatedHeatCapTempModFac;
2511 250 : if (simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
2512 250 : auto &companionCoolingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum));
2513 250 : if (companionCoolingCoil.WAHPPlantType == DataPlant::PlantEquipmentType::CoilWAHPCoolingEquationFit &&
2514 250 : companionCoolingCoil.RatedCapCoolTotal == DataSizing::AutoSize) {
2515 : // case 1: companion coil is also of EquationFit type and is being autosized
2516 250 : RatedCapCoolTotalDes = state.dataSize->DXCoolCap;
2517 250 : RatedTotCapTempModFac = companionCoolingCoil.RatedCapCoolAtRatedCdts / RatedCapCoolTotalDes;
2518 250 : RatedCapCoolHeatDD =
2519 250 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts / simpleWatertoAirHP.RatioRatedHeatRatedTotCoolCap / RatedTotCapTempModFac;
2520 250 : RatedCoolPowerTempModFac = companionCoolingCoil.RatedPowerCoolAtRatedCdts / companionCoolingCoil.RatedPowerCool;
2521 250 : if (RatedCapCoolHeatDD > RatedCapCoolTotalDes) {
2522 : // total cooling capacity
2523 19 : 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 19 : if (HeatingAirVolFlowRateDes > 0) {
2527 19 : RatedCapCoolTotalDes *= (RatedAirVolFlowRateDes / HeatingAirVolFlowRateDes) * HeatdTratio;
2528 : }
2529 : // calculate ajustment factor over previous capacity for sensible capacity adjustment
2530 19 : Real64 CapCoolAdjFac = RatedCapCoolTotalDes / state.dataSize->DXCoolCap;
2531 : // update cooling coil rated capacity after adjustments based on heating coil size
2532 19 : state.dataSize->DXCoolCap = RatedCapCoolTotalDes;
2533 : // sensible cooling capacity
2534 19 : RatedCapCoolSensDes = companionCoolingCoil.RatedCapCoolSens * CapCoolAdjFac; // Assume that SHR stays the same
2535 19 : companionCoolingCoil.RatedCapCoolSensDesAtRatedCdts *= CapCoolAdjFac;
2536 19 : companionCoolingCoil.RatedCapCoolSens = RatedCapCoolSensDes;
2537 : // update Water-to-Air Heat Pumps output reports
2538 38 : OutputReportPredefined::PreDefTableEntry(state,
2539 19 : state.dataOutRptPredefined->pdchWAHPRatedSensCapAtRatedCdts,
2540 : companionCoolingCoil.Name,
2541 : companionCoolingCoil.RatedCapCoolSensDesAtRatedCdts);
2542 38 : OutputReportPredefined::PreDefTableEntry(
2543 19 : state, state.dataOutRptPredefined->pdchWAHPDD, companionCoolingCoil.Name, "Heating");
2544 38 : OutputReportPredefined::PreDefTableEntry(
2545 19 : state, state.dataOutRptPredefined->pdchWAHPDD, simpleWatertoAirHP.Name, "Heating");
2546 : // update Cooling Coils output reports
2547 38 : OutputReportPredefined::PreDefTableEntry(state,
2548 19 : state.dataOutRptPredefined->pdchCoolCoilLatCap,
2549 : companionCoolingCoil.Name,
2550 : RatedCapCoolTotalDes - RatedCapCoolSensDes);
2551 38 : OutputReportPredefined::PreDefTableEntry(state,
2552 19 : state.dataOutRptPredefined->pdchCoolCoilSHR,
2553 : companionCoolingCoil.Name,
2554 : RatedCapCoolSensDes / RatedCapCoolTotalDes);
2555 38 : OutputReportPredefined::PreDefTableEntry(
2556 19 : state, state.dataOutRptPredefined->pdchCoolCoilSensCap, companionCoolingCoil.Name, RatedCapCoolSensDes);
2557 : } else {
2558 462 : OutputReportPredefined::PreDefTableEntry(
2559 231 : state, state.dataOutRptPredefined->pdchWAHPDD, companionCoolingCoil.Name, "Cooling");
2560 462 : OutputReportPredefined::PreDefTableEntry(
2561 231 : state, state.dataOutRptPredefined->pdchWAHPDD, simpleWatertoAirHP.Name, "Cooling");
2562 : }
2563 250 : RatedCapHeatDes =
2564 250 : RatedCapCoolTotalDes * RatedTotCapTempModFac * simpleWatertoAirHP.RatioRatedHeatRatedTotCoolCap / RatedHeatCapTempModFac;
2565 250 : companionCoolingCoil.RatedCapCoolTotal = RatedCapCoolTotalDes;
2566 250 : companionCoolingCoil.RatedCapCoolAtRatedCdts = RatedCapCoolTotalDes * RatedTotCapTempModFac;
2567 250 : companionCoolingCoil.RatedPowerCoolAtRatedCdts =
2568 250 : companionCoolingCoil.RatedCapCoolAtRatedCdts / companionCoolingCoil.RatedCOPCoolAtRatedCdts;
2569 250 : companionCoolingCoil.RatedPowerCool = companionCoolingCoil.RatedPowerCoolAtRatedCdts / RatedCoolPowerTempModFac;
2570 : // update Water-to-Air Heat Pumps output reports
2571 500 : OutputReportPredefined::PreDefTableEntry(state,
2572 250 : state.dataOutRptPredefined->pdchWAHPRatedCapAtRatedCdts,
2573 : companionCoolingCoil.Name,
2574 : companionCoolingCoil.RatedCapCoolAtRatedCdts);
2575 : // update Cooling Coils output reports
2576 500 : OutputReportPredefined::PreDefTableEntry(
2577 250 : state, state.dataOutRptPredefined->pdchCoolCoilTotCap, companionCoolingCoil.Name, RatedCapCoolTotalDes);
2578 750 : BaseSizer::reportSizerOutput(
2579 : state,
2580 500 : 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 750 : BaseSizer::reportSizerOutput(
2585 : state,
2586 500 : 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 250 : } 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 250 : simpleWatertoAirHP.RatedCapHeat = RatedCapHeatDes;
2600 250 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts = RatedCapHeatDes * RatedHeatCapTempModFac;
2601 :
2602 : // heating power calculations
2603 250 : RatedHeatPowerTempModFac = simpleWatertoAirHP.HeatPowCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
2604 250 : simpleWatertoAirHP.RatedPowerHeat =
2605 250 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts / (simpleWatertoAirHP.RatedCOPHeatAtRatedCdts * RatedHeatPowerTempModFac);
2606 :
2607 : // update reports
2608 500 : OutputReportPredefined::PreDefTableEntry(state,
2609 250 : state.dataOutRptPredefined->pdchWAHPRatedCapAtRatedCdts,
2610 : simpleWatertoAirHP.Name,
2611 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts);
2612 500 : OutputReportPredefined::PreDefTableEntry(
2613 250 : state, state.dataOutRptPredefined->pdchWAHPRatedAirDBT, simpleWatertoAirHP.Name, RatedHeatMixDryBulb);
2614 500 : OutputReportPredefined::PreDefTableEntry(
2615 250 : state, state.dataOutRptPredefined->pdchWAHPRatedWtrT, simpleWatertoAirHP.Name, simpleWatertoAirHP.RatedEntWaterTemp);
2616 750 : BaseSizer::reportSizerOutput(
2617 : state,
2618 500 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2619 : simpleWatertoAirHP.Name,
2620 : "Design Size Rated Heating Capacity [W]",
2621 : simpleWatertoAirHP.RatedCapHeat);
2622 500 : OutputReportPredefined::PreDefTableEntry(
2623 250 : state, state.dataOutRptPredefined->pdchHeatCoilNomCap, simpleWatertoAirHP.Name, simpleWatertoAirHP.RatedCapHeat);
2624 250 : if (simpleWatertoAirHP.RatedCapHeat != 0.0) {
2625 500 : OutputReportPredefined::PreDefTableEntry(state,
2626 250 : state.dataOutRptPredefined->pdchHeatCoilNomEff,
2627 : simpleWatertoAirHP.Name,
2628 250 : simpleWatertoAirHP.RatedPowerHeat / simpleWatertoAirHP.RatedCapHeat);
2629 : } else {
2630 0 : OutputReportPredefined::PreDefTableEntry(state, state.dataOutRptPredefined->pdchHeatCoilNomEff, simpleWatertoAirHP.Name, 0.0);
2631 : }
2632 : } else {
2633 15 : 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 15 : if (simpleWatertoAirHP.RatedCapHeat > 0.0) {
2658 15 : RatedCapHeatUser = simpleWatertoAirHP.RatedCapHeat;
2659 45 : BaseSizer::reportSizerOutput(
2660 : state,
2661 30 : 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 15 : simpleWatertoAirHP.RatedPowerHeat = simpleWatertoAirHP.RatedCapHeat / simpleWatertoAirHP.RatedCOPHeatAtRatedCdts;
2670 15 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts = 0; // not sure why these are set = 0, should be RatedCapHeat?
2671 15 : 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 265 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating && simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
2675 265 : auto &companionCoolingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum));
2676 265 : if (companionCoolingCoil.RatedCapCoolTotal > 0.0) {
2677 :
2678 265 : if (std::abs(companionCoolingCoil.RatedCapCoolTotal - simpleWatertoAirHP.RatedCapHeat) / companionCoolingCoil.RatedCapCoolTotal >
2679 : 0.2) {
2680 :
2681 0 : ShowWarningError(state,
2682 0 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT {}",
2683 0 : WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)],
2684 0 : simpleWatertoAirHP.Name));
2685 0 : ShowContinueError(state,
2686 0 : format("...used with COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT {}",
2687 0 : companionCoolingCoil.WAHPType,
2688 0 : companionCoolingCoil.Name));
2689 0 : ShowContinueError(state, "...heating capacity is disproportionate (> 20% different) to total cooling capacity");
2690 0 : ShowContinueError(state, format("...heating capacity = {:.3T} W", simpleWatertoAirHP.RatedCapHeat));
2691 0 : ShowContinueError(state, format("...cooling capacity = {:.3T} W", companionCoolingCoil.RatedCapCoolTotal));
2692 : }
2693 : }
2694 : }
2695 :
2696 265 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilHeatingCapacity(
2697 : state,
2698 265 : simpleWatertoAirHP.Name,
2699 530 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
2700 : RatedCapHeatDes,
2701 : IsAutoSize,
2702 265 : state.dataSize->CurSysNum,
2703 265 : state.dataSize->CurZoneEqNum,
2704 265 : 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 530 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
2714 265 : if (simpleWatertoAirHP.RatedPowerCool > 0) {
2715 530 : OutputReportPredefined::PreDefTableEntry(state,
2716 265 : state.dataOutRptPredefined->pdchCoolCoilNomEff,
2717 : simpleWatertoAirHP.Name,
2718 265 : simpleWatertoAirHP.RatedCapCoolTotal / simpleWatertoAirHP.RatedPowerCool);
2719 : }
2720 265 : if (IsAutoSize) {
2721 500 : OutputReportPredefined::PreDefTableEntry(state,
2722 250 : state.dataOutRptPredefined->pdchWAHPRatedPowerAtRatedCdts,
2723 : simpleWatertoAirHP.Name,
2724 : simpleWatertoAirHP.RatedPowerCoolAtRatedCdts);
2725 250 : if (simpleWatertoAirHP.RatedPowerCoolAtRatedCdts > 0) {
2726 500 : OutputReportPredefined::PreDefTableEntry(state,
2727 250 : state.dataOutRptPredefined->pdchWAHPRatedCOPAtRatedCdts,
2728 : simpleWatertoAirHP.Name,
2729 250 : simpleWatertoAirHP.RatedCapCoolAtRatedCdts /
2730 250 : simpleWatertoAirHP.RatedPowerCoolAtRatedCdts);
2731 : }
2732 : }
2733 265 : } else if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating) {
2734 : // heating coil power
2735 265 : simpleWatertoAirHP.RatedPowerHeatAtRatedCdts = simpleWatertoAirHP.RatedCapHeatAtRatedCdts / simpleWatertoAirHP.RatedCOPHeatAtRatedCdts;
2736 265 : if (simpleWatertoAirHP.RatedPowerHeat > 0) {
2737 530 : OutputReportPredefined::PreDefTableEntry(state,
2738 265 : state.dataOutRptPredefined->pdchHeatCoilNomEff,
2739 : simpleWatertoAirHP.Name,
2740 265 : simpleWatertoAirHP.RatedCapHeat / simpleWatertoAirHP.RatedPowerHeat);
2741 : }
2742 265 : if (IsAutoSize) {
2743 500 : OutputReportPredefined::PreDefTableEntry(state,
2744 250 : state.dataOutRptPredefined->pdchWAHPRatedPowerAtRatedCdts,
2745 : simpleWatertoAirHP.Name,
2746 : simpleWatertoAirHP.RatedPowerHeatAtRatedCdts);
2747 250 : if (simpleWatertoAirHP.RatedPowerHeatAtRatedCdts > 0) {
2748 500 : OutputReportPredefined::PreDefTableEntry(state,
2749 250 : state.dataOutRptPredefined->pdchWAHPRatedCOPAtRatedCdts,
2750 : simpleWatertoAirHP.Name,
2751 250 : simpleWatertoAirHP.RatedCapHeatAtRatedCdts /
2752 250 : simpleWatertoAirHP.RatedPowerHeatAtRatedCdts);
2753 : }
2754 : }
2755 : // re-calculate companion coil power
2756 265 : if (simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
2757 265 : auto &companionCoolingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum));
2758 265 : companionCoolingCoil.RatedPowerCoolAtRatedCdts =
2759 265 : companionCoolingCoil.RatedCapCoolAtRatedCdts / companionCoolingCoil.RatedCOPCoolAtRatedCdts;
2760 265 : if (companionCoolingCoil.RatedCapCoolTotal > 0) {
2761 530 : OutputReportPredefined::PreDefTableEntry(state,
2762 265 : state.dataOutRptPredefined->pdchCoolCoilNomEff,
2763 : companionCoolingCoil.Name,
2764 265 : companionCoolingCoil.RatedCapCoolTotal / companionCoolingCoil.RatedPowerCool);
2765 265 : if (IsAutoSize) {
2766 500 : OutputReportPredefined::PreDefTableEntry(state,
2767 250 : state.dataOutRptPredefined->pdchWAHPRatedPowerAtRatedCdts,
2768 : companionCoolingCoil.Name,
2769 : companionCoolingCoil.RatedPowerCoolAtRatedCdts);
2770 250 : if (companionCoolingCoil.RatedPowerCoolAtRatedCdts > 0) {
2771 500 : OutputReportPredefined::PreDefTableEntry(state,
2772 250 : state.dataOutRptPredefined->pdchWAHPRatedCOPAtRatedCdts,
2773 : companionCoolingCoil.Name,
2774 250 : companionCoolingCoil.RatedCapCoolAtRatedCdts /
2775 250 : companionCoolingCoil.RatedPowerCoolAtRatedCdts);
2776 : }
2777 : }
2778 : }
2779 : }
2780 : }
2781 :
2782 : // Size water volumetric flow rate
2783 530 : IsAutoSize = false;
2784 530 : if (simpleWatertoAirHP.RatedWaterVolFlowRate == DataSizing::AutoSize) {
2785 500 : 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 530 : if (IsAutoSize) {
2791 1000 : PltSizNum = PlantUtilities::MyPlantSizingIndex(
2792 : state,
2793 1000 : 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 500 : if (PltSizNum > 0) {
2801 500 : rho = state.dataPlnt->PlantLoop(simpleWatertoAirHP.plantLoc.loopNum)
2802 500 : .glycol->getDensity(state, state.dataSize->PlantSizData(PltSizNum).ExitTemp, RoutineNameAlt);
2803 500 : Cp = state.dataPlnt->PlantLoop(simpleWatertoAirHP.plantLoc.loopNum)
2804 500 : .glycol->getSpecificHeat(state, state.dataSize->PlantSizData(PltSizNum).ExitTemp, RoutineNameAlt);
2805 :
2806 500 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating) {
2807 250 : RatedWaterVolFlowRateDes = simpleWatertoAirHP.RatedCapHeat / (state.dataSize->PlantSizData(PltSizNum).DeltaT * Cp * rho);
2808 250 : } else if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
2809 : // use companion heating coil capacity to calculate volumetric flow rate
2810 250 : if (simpleWatertoAirHP.CompanionHeatingCoilNum > 0) {
2811 : auto const &companionHeatingCoil =
2812 250 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionHeatingCoilNum);
2813 250 : if (companionHeatingCoil.RatedCapHeat == DataSizing::AutoSize) {
2814 250 : 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 250 : 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 500 : if (SystemCapacity != DataSizing::AutoSize) {
2834 250 : simpleWatertoAirHP.RatedWaterVolFlowRate = RatedWaterVolFlowRateDes;
2835 750 : BaseSizer::reportSizerOutput(
2836 : state,
2837 500 : 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 250 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating && simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
2842 250 : auto &companionCoolingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum));
2843 250 : companionCoolingCoil.RatedWaterVolFlowRate = RatedWaterVolFlowRateDes;
2844 750 : BaseSizer::reportSizerOutput(
2845 : state,
2846 500 : 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 250 : } 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 30 : 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 530 : if (simpleWatertoAirHP.RatedWaterVolFlowRate > 0.0) {
2891 280 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating) {
2892 265 : PlantUtilities::RegisterPlantCompDesignFlow(
2893 265 : state, simpleWatertoAirHP.WaterInletNodeNum, 0.5 * simpleWatertoAirHP.RatedWaterVolFlowRate);
2894 265 : if (simpleWatertoAirHP.CompanionCoolingCoilNum > 0) {
2895 265 : auto &companionCoolingCoil(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(simpleWatertoAirHP.CompanionCoolingCoilNum));
2896 265 : PlantUtilities::RegisterPlantCompDesignFlow(
2897 265 : state, companionCoolingCoil.WaterInletNodeNum, 0.5 * simpleWatertoAirHP.RatedWaterVolFlowRate);
2898 : }
2899 15 : } else if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
2900 15 : PlantUtilities::RegisterPlantCompDesignFlow(
2901 15 : state, simpleWatertoAirHP.WaterInletNodeNum, 0.5 * simpleWatertoAirHP.RatedWaterVolFlowRate);
2902 : }
2903 : }
2904 530 : }
2905 :
2906 38098181 : 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 38098181 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
2949 :
2950 : // SUBROUTINE PARAMETER DEFINITIONS:
2951 38098181 : 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 38098181 : if (state.dataWaterToAirHeatPumpSimple->firstTime) {
2983 : // Set indoor air conditions to the rated condition
2984 19 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp_Init = 26.7;
2985 19 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat_Init = 0.0111;
2986 19 : state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth_Init = Psychrometrics::PsyHFnTdbW(
2987 19 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp_Init, state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat_Init);
2988 19 : state.dataWaterToAirHeatPumpSimple->CpAir_Init =
2989 19 : Psychrometrics::PsyCpAirFnW(state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat_Init);
2990 19 : state.dataWaterToAirHeatPumpSimple->firstTime = false;
2991 : }
2992 76196362 : state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp_Init =
2993 38098181 : Psychrometrics::PsyTwbFnTdbWPb(state,
2994 38098181 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp_Init,
2995 38098181 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat_Init,
2996 38098181 : state.dataEnvrn->OutBaroPress,
2997 : RoutineName);
2998 :
2999 : // LOAD LOCAL VARIABLES FROM DATA STRUCTURE (for code readability)
3000 :
3001 38098181 : auto &simpleWatertoAirHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
3002 :
3003 38098181 : TotalCapRated = simpleWatertoAirHP.RatedCapCoolTotal;
3004 38098181 : SensCapRated = simpleWatertoAirHP.RatedCapCoolSens;
3005 38098181 : CoolPowerRated = simpleWatertoAirHP.RatedPowerCool;
3006 38098181 : AirVolFlowRateRated = simpleWatertoAirHP.RatedAirVolFlowRate;
3007 38098181 : WaterVolFlowRateRated = simpleWatertoAirHP.RatedWaterVolFlowRate;
3008 :
3009 38098181 : Twet_Rated = simpleWatertoAirHP.Twet_Rated;
3010 38098181 : Gamma_Rated = simpleWatertoAirHP.Gamma_Rated;
3011 :
3012 38098181 : if (fanOp == HVAC::FanOp::Continuous) {
3013 12501802 : LoadSideFullMassFlowRate = simpleWatertoAirHP.AirMassFlowRate;
3014 : } else {
3015 : // default to cycling fan, cycling compressor, full load air flow
3016 25596379 : if (PartLoadRatio > 0.0) {
3017 8760395 : LoadSideFullMassFlowRate = simpleWatertoAirHP.AirMassFlowRate / PartLoadRatio;
3018 : } else {
3019 16835984 : LoadSideFullMassFlowRate = 0.0;
3020 : }
3021 : }
3022 38098181 : state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate = simpleWatertoAirHP.WaterMassFlowRate;
3023 38098181 : state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp = simpleWatertoAirHP.InletWaterTemp;
3024 38098181 : state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth = simpleWatertoAirHP.InletWaterEnthalpy;
3025 38098181 : CpWater = state.dataPlnt->PlantLoop(simpleWatertoAirHP.plantLoc.loopNum)
3026 38098181 : .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 38098181 : if (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate <= 0.0 || LoadSideFullMassFlowRate <= 0.0) {
3030 21957547 : simpleWatertoAirHP.SimFlag = false;
3031 21957547 : return;
3032 : } else {
3033 16140634 : simpleWatertoAirHP.SimFlag = true;
3034 : }
3035 :
3036 16140634 : if (compressorOp == HVAC::CompressorOp::Off) {
3037 565518 : simpleWatertoAirHP.SimFlag = false;
3038 565518 : return;
3039 : }
3040 :
3041 : // Calculate Part Load Factor and Runtime Fraction
3042 15575116 : Real64 PLF = 1.0; // part load factor as a function of PLR, RTF = PLR / PLF
3043 15575116 : if (simpleWatertoAirHP.PLFCurve != nullptr) {
3044 15575116 : PLF = simpleWatertoAirHP.PLFCurve->value(state, PartLoadRatio); // Calculate part-load factor
3045 : }
3046 15575116 : if (fanOp == HVAC::FanOp::Cycling) {
3047 8760073 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
3048 : }
3049 15575116 : 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 15575116 : if ((simpleWatertoAirHP.RunFrac >= 1.0) || (Twet_Rated <= 0.0) || (Gamma_Rated <= 0.0)) {
3055 15575116 : LatDegradModelSimFlag = false;
3056 : // Set NumIteration=1 so that latent model would quit after 1 simulation with the actual condition
3057 15575116 : NumIteration = 1;
3058 : } else {
3059 0 : LatDegradModelSimFlag = true;
3060 : // Set NumIteration=0 so that latent model would simulate twice with rated and actual condition
3061 0 : NumIteration = 0;
3062 : }
3063 :
3064 : // Set indoor air conditions to the actual condition
3065 15575116 : LoadSideInletDBTemp_Unit = simpleWatertoAirHP.InletAirDBTemp;
3066 15575116 : LoadSideInletHumRat_Unit = simpleWatertoAirHP.InletAirHumRat;
3067 : LoadSideInletWBTemp_Unit =
3068 15575116 : Psychrometrics::PsyTwbFnTdbWPb(state, LoadSideInletDBTemp_Unit, LoadSideInletHumRat_Unit, state.dataEnvrn->OutBaroPress, RoutineName);
3069 15575116 : LoadSideInletEnth_Unit = simpleWatertoAirHP.InletAirEnthalpy;
3070 15575116 : CpAir_Unit = Psychrometrics::PsyCpAirFnW(LoadSideInletHumRat_Unit);
3071 :
3072 : while (true) {
3073 15575116 : ++NumIteration;
3074 15575116 : if (NumIteration == 1) {
3075 : // Set indoor air conditions to the rated conditions
3076 0 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp = state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp_Init;
3077 0 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat = state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat_Init;
3078 0 : state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp = state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp_Init;
3079 0 : state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth = state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth_Init;
3080 0 : CpAir = state.dataWaterToAirHeatPumpSimple->CpAir_Init;
3081 : } else {
3082 : // Set indoor air conditions to the actual condition
3083 15575116 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp = LoadSideInletDBTemp_Unit;
3084 15575116 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat = LoadSideInletHumRat_Unit;
3085 15575116 : state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp = LoadSideInletWBTemp_Unit;
3086 15575116 : state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth = LoadSideInletEnth_Unit;
3087 15575116 : CpAir = CpAir_Unit;
3088 : }
3089 :
3090 15575116 : ratioTDB = ((state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref);
3091 15575116 : ratioTWB = ((state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref);
3092 15575116 : ratioTS = ((state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref);
3093 15575116 : ratioVL = (LoadSideFullMassFlowRate /
3094 15575116 : (AirVolFlowRateRated * Psychrometrics::PsyRhoAirFnPbTdbW(state,
3095 15575116 : state.dataEnvrn->StdBaroPress,
3096 15575116 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp,
3097 15575116 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat,
3098 : RoutineName)));
3099 :
3100 15575116 : if (simpleWatertoAirHP.DesignWaterMassFlowRate > 0.0) {
3101 15575116 : ratioVS = (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate) / (simpleWatertoAirHP.DesignWaterMassFlowRate);
3102 : } else {
3103 0 : ratioVS = 0.0;
3104 : }
3105 :
3106 15575116 : simpleWatertoAirHP.QLoadTotal = TotalCapRated * simpleWatertoAirHP.TotalCoolCapCurve->value(state, ratioTWB, ratioTS, ratioVL, ratioVS);
3107 15575116 : simpleWatertoAirHP.QSensible =
3108 15575116 : SensCapRated * simpleWatertoAirHP.SensCoolCapCurve->value(state, ratioTDB, ratioTWB, ratioTS, ratioVL, ratioVS);
3109 31150232 : state.dataWaterToAirHeatPumpSimple->Winput =
3110 15575116 : CoolPowerRated * simpleWatertoAirHP.CoolPowCurve->value(state, ratioTWB, ratioTS, ratioVL, ratioVS);
3111 :
3112 : // Check if the Sensible Load is greater than the Total Cooling Load
3113 15575116 : if (simpleWatertoAirHP.QSensible > simpleWatertoAirHP.QLoadTotal) {
3114 3610702 : simpleWatertoAirHP.QSensible = simpleWatertoAirHP.QLoadTotal;
3115 : }
3116 :
3117 15575116 : if (LatDegradModelSimFlag) {
3118 : // Calculate for SHReff using the Latent Degradation Model
3119 0 : if (NumIteration == 1) {
3120 0 : state.dataWaterToAirHeatPumpSimple->QLatRated = simpleWatertoAirHP.QLoadTotal - simpleWatertoAirHP.QSensible;
3121 0 : } else if (NumIteration == 2) {
3122 0 : state.dataWaterToAirHeatPumpSimple->QLatActual = simpleWatertoAirHP.QLoadTotal - simpleWatertoAirHP.QSensible;
3123 0 : SHRss = simpleWatertoAirHP.QSensible / simpleWatertoAirHP.QLoadTotal;
3124 0 : SHReff = CalcEffectiveSHR(state,
3125 : HPNum,
3126 : SHRss,
3127 : fanOp,
3128 : simpleWatertoAirHP.RunFrac,
3129 0 : state.dataWaterToAirHeatPumpSimple->QLatRated,
3130 0 : state.dataWaterToAirHeatPumpSimple->QLatActual,
3131 0 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp,
3132 0 : state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp);
3133 : // Update sensible capacity based on effective SHR
3134 0 : simpleWatertoAirHP.QSensible = simpleWatertoAirHP.QLoadTotal * SHReff;
3135 0 : break;
3136 : }
3137 : } else {
3138 : // Assume SHReff=SHRss
3139 15575116 : SHReff = simpleWatertoAirHP.QSensible / simpleWatertoAirHP.QLoadTotal;
3140 15575116 : break;
3141 : }
3142 : }
3143 :
3144 : // calculate coil outlet state variables
3145 15575116 : LoadSideFullOutletEnthalpy = state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth - simpleWatertoAirHP.QLoadTotal / LoadSideFullMassFlowRate;
3146 31150232 : state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp =
3147 15575116 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp - simpleWatertoAirHP.QSensible / (LoadSideFullMassFlowRate * CpAir);
3148 31150232 : state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat =
3149 15575116 : Psychrometrics::PsyWFnTdbH(state, state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp, LoadSideFullOutletEnthalpy, RoutineName);
3150 : // Actual outlet conditions are "average" for time step
3151 15575116 : if (fanOp == HVAC::FanOp::Continuous) {
3152 : // continuous fan, cycling compressor
3153 6815043 : simpleWatertoAirHP.OutletAirEnthalpy =
3154 6815043 : PartLoadRatio * LoadSideFullOutletEnthalpy + (1.0 - PartLoadRatio) * state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth;
3155 6815043 : simpleWatertoAirHP.OutletAirHumRat = PartLoadRatio * state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat +
3156 6815043 : (1.0 - PartLoadRatio) * state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat;
3157 6815043 : simpleWatertoAirHP.OutletAirDBTemp = Psychrometrics::PsyTdbFnHW(simpleWatertoAirHP.OutletAirEnthalpy, simpleWatertoAirHP.OutletAirHumRat);
3158 : } else {
3159 : // default to cycling fan, cycling compressor
3160 8760073 : simpleWatertoAirHP.OutletAirEnthalpy = LoadSideFullOutletEnthalpy;
3161 8760073 : simpleWatertoAirHP.OutletAirHumRat = state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat;
3162 8760073 : simpleWatertoAirHP.OutletAirDBTemp = state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp;
3163 : }
3164 :
3165 : // scale heat transfer rates to PLR and power to RTF
3166 15575116 : simpleWatertoAirHP.QLoadTotal *= PartLoadRatio;
3167 31150232 : simpleWatertoAirHP.QLoadTotalReport = simpleWatertoAirHP.AirMassFlowRate *
3168 15575116 : (state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth -
3169 15575116 : Psychrometrics::PsyHFnTdbW(simpleWatertoAirHP.OutletAirDBTemp,
3170 : simpleWatertoAirHP.OutletAirHumRat)); // Why doesn't this match QLoadTotal?
3171 15575116 : simpleWatertoAirHP.QSensible *= PartLoadRatio;
3172 15575116 : state.dataWaterToAirHeatPumpSimple->Winput *= simpleWatertoAirHP.RunFrac;
3173 15575116 : simpleWatertoAirHP.QSource = simpleWatertoAirHP.QLoadTotalReport + state.dataWaterToAirHeatPumpSimple->Winput;
3174 15575116 : state.dataHeatBal->HeatReclaimSimple_WAHPCoil(HPNum).AvailCapacity = simpleWatertoAirHP.QSource;
3175 :
3176 : // Add power to global variable so power can be summed by parent object
3177 15575116 : state.dataHVACGlobal->DXElecCoolingPower = state.dataWaterToAirHeatPumpSimple->Winput;
3178 :
3179 15575116 : DataHeatBalance::HeatReclaimDataBase &HeatReclaim = state.dataHeatBal->HeatReclaimSimple_WAHPCoil(HPNum);
3180 15575116 : HeatReclaim.WaterHeatingDesuperheaterReclaimedHeatTotal = 0.0;
3181 15575116 : if (allocated(HeatReclaim.WaterHeatingDesuperheaterReclaimedHeat)) {
3182 34404 : for (auto const &num : HeatReclaim.WaterHeatingDesuperheaterReclaimedHeat) {
3183 17202 : HeatReclaim.WaterHeatingDesuperheaterReclaimedHeatTotal += num;
3184 : }
3185 : }
3186 15575116 : simpleWatertoAirHP.QSource -= HeatReclaim.WaterHeatingDesuperheaterReclaimedHeatTotal;
3187 :
3188 : // Update heat pump data structure
3189 15575116 : simpleWatertoAirHP.Power = state.dataWaterToAirHeatPumpSimple->Winput;
3190 15575116 : simpleWatertoAirHP.QLoadTotal = simpleWatertoAirHP.QLoadTotalReport;
3191 15575116 : simpleWatertoAirHP.QLatent = simpleWatertoAirHP.QLoadTotalReport - simpleWatertoAirHP.QSensible;
3192 15575116 : simpleWatertoAirHP.Energy = state.dataWaterToAirHeatPumpSimple->Winput * TimeStepSysSec;
3193 15575116 : simpleWatertoAirHP.EnergyLoadTotal = simpleWatertoAirHP.QLoadTotalReport * TimeStepSysSec;
3194 15575116 : simpleWatertoAirHP.EnergySensible = simpleWatertoAirHP.QSensible * TimeStepSysSec;
3195 15575116 : simpleWatertoAirHP.EnergyLatent = (simpleWatertoAirHP.QLoadTotalReport - simpleWatertoAirHP.QSensible) * TimeStepSysSec;
3196 15575116 : simpleWatertoAirHP.EnergySource = simpleWatertoAirHP.QSource * TimeStepSysSec;
3197 15575116 : if (simpleWatertoAirHP.RunFrac == 0.0) {
3198 1480406 : simpleWatertoAirHP.COP = 0.0;
3199 : } else {
3200 14094710 : simpleWatertoAirHP.COP = simpleWatertoAirHP.QLoadTotalReport / state.dataWaterToAirHeatPumpSimple->Winput;
3201 : }
3202 15575116 : simpleWatertoAirHP.PartLoadRatio = PartLoadRatio;
3203 :
3204 15575116 : 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 15575116 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate * PartLoadRatio;
3207 15575116 : PlantUtilities::SetComponentFlowRate(state,
3208 15575116 : simpleWatertoAirHP.WaterMassFlowRate,
3209 : simpleWatertoAirHP.WaterInletNodeNum,
3210 : simpleWatertoAirHP.WaterOutletNodeNum,
3211 15575116 : simpleWatertoAirHP.plantLoc);
3212 15575116 : if (simpleWatertoAirHP.WaterMassFlowRate > 0.0) {
3213 14094710 : simpleWatertoAirHP.OutletWaterTemp = state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp +
3214 14094710 : simpleWatertoAirHP.QSource / (simpleWatertoAirHP.WaterMassFlowRate * CpWater);
3215 14094710 : simpleWatertoAirHP.OutletWaterEnthalpy =
3216 14094710 : state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth + simpleWatertoAirHP.QSource / simpleWatertoAirHP.WaterMassFlowRate;
3217 : }
3218 : } else {
3219 0 : 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 0 : simpleWatertoAirHP.WaterMassFlowRate = state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3232 : }
3233 0 : simpleWatertoAirHP.OutletWaterTemp = state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp +
3234 0 : simpleWatertoAirHP.QSource / (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate * CpWater);
3235 0 : simpleWatertoAirHP.OutletWaterEnthalpy = state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth +
3236 0 : simpleWatertoAirHP.QSource / state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3237 : }
3238 : }
3239 :
3240 38098546 : 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 38098546 : Real64 TimeStepSysSec = state.dataHVACGlobal->TimeStepSysSec;
3273 :
3274 : // SUBROUTINE PARAMETER DEFINITIONS:
3275 38098546 : 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 38098546 : auto &simpleWatertoAirHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
3295 :
3296 38098546 : HeatCapRated = simpleWatertoAirHP.RatedCapHeat;
3297 38098546 : HeatPowerRated = simpleWatertoAirHP.RatedPowerHeat;
3298 38098546 : AirVolFlowRateRated = simpleWatertoAirHP.RatedAirVolFlowRate;
3299 38098546 : WaterVolFlowRateRated = simpleWatertoAirHP.RatedWaterVolFlowRate;
3300 38098546 : if (fanOp == HVAC::FanOp::Continuous) {
3301 12502082 : LoadSideFullMassFlowRate = simpleWatertoAirHP.AirMassFlowRate;
3302 : } else {
3303 : // default to cycling fan, cycling compressor, full load air flow
3304 25596464 : if (PartLoadRatio > 0.0) {
3305 9248355 : LoadSideFullMassFlowRate = simpleWatertoAirHP.AirMassFlowRate / PartLoadRatio;
3306 : } else {
3307 16348109 : LoadSideFullMassFlowRate = 0.0;
3308 : }
3309 : }
3310 38098546 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp = simpleWatertoAirHP.InletAirDBTemp;
3311 38098546 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat = simpleWatertoAirHP.InletAirHumRat;
3312 :
3313 76197092 : state.dataWaterToAirHeatPumpSimple->LoadSideInletWBTemp =
3314 38098546 : Psychrometrics::PsyTwbFnTdbWPb(state,
3315 38098546 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp,
3316 38098546 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat,
3317 38098546 : state.dataEnvrn->OutBaroPress,
3318 : RoutineName);
3319 38098546 : state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth = simpleWatertoAirHP.InletAirEnthalpy;
3320 38098546 : CpAir = Psychrometrics::PsyCpAirFnW(state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat);
3321 38098546 : state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate = simpleWatertoAirHP.WaterMassFlowRate;
3322 38098546 : state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp = simpleWatertoAirHP.InletWaterTemp;
3323 38098546 : state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth = simpleWatertoAirHP.InletWaterEnthalpy;
3324 38098546 : CpWater = state.dataPlnt->PlantLoop(simpleWatertoAirHP.plantLoc.loopNum)
3325 38098546 : .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 38098546 : if (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate <= 0.0 || LoadSideFullMassFlowRate <= 0.0) {
3329 26251833 : simpleWatertoAirHP.SimFlag = false;
3330 26251833 : return;
3331 : } else {
3332 11846713 : simpleWatertoAirHP.SimFlag = true;
3333 : }
3334 :
3335 11846713 : if (compressorOp == HVAC::CompressorOp::Off) {
3336 418573 : simpleWatertoAirHP.SimFlag = false;
3337 418573 : return;
3338 : }
3339 :
3340 : // Calculate Part Load Factor and Runtime Fraction
3341 11428140 : Real64 PLF = 1.0; // part load factor as a function of PLR, RTF = PLR / PLF
3342 11428140 : if (simpleWatertoAirHP.PLFCurve != nullptr) {
3343 11428140 : PLF = simpleWatertoAirHP.PLFCurve->value(state, PartLoadRatio); // Calculate part-load factor
3344 : }
3345 11428140 : if (fanOp == HVAC::FanOp::Cycling) {
3346 9138037 : state.dataHVACGlobal->OnOffFanPartLoadFraction = PLF;
3347 : }
3348 11428140 : simpleWatertoAirHP.RunFrac = PartLoadRatio / PLF;
3349 :
3350 11428140 : ratioTDB = ((state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref);
3351 11428140 : ratioTS = ((state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp + state.dataWaterToAirHeatPumpSimple->CelsiustoKelvin) / Tref);
3352 11428140 : ratioVL = (LoadSideFullMassFlowRate /
3353 11428140 : (AirVolFlowRateRated * Psychrometrics::PsyRhoAirFnPbTdbW(state,
3354 11428140 : state.dataEnvrn->StdBaroPress,
3355 11428140 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp,
3356 11428140 : state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat,
3357 : RoutineName)));
3358 11428140 : if (simpleWatertoAirHP.DesignWaterMassFlowRate > 0.0) {
3359 11428140 : ratioVS = (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate) / (simpleWatertoAirHP.DesignWaterMassFlowRate);
3360 : } else {
3361 0 : ratioVS = 0.0;
3362 : }
3363 :
3364 11428140 : simpleWatertoAirHP.QLoadTotal = HeatCapRated * simpleWatertoAirHP.HeatCapCurve->value(state, ratioTDB, ratioTS, ratioVL, ratioVS);
3365 11428140 : simpleWatertoAirHP.QSensible = simpleWatertoAirHP.QLoadTotal;
3366 22856280 : state.dataWaterToAirHeatPumpSimple->Winput =
3367 11428140 : HeatPowerRated * simpleWatertoAirHP.HeatPowCurve->value(state, ratioTDB, ratioTS, ratioVL, ratioVS);
3368 :
3369 : // calculate coil outlet state variables
3370 11428140 : LoadSideFullOutletEnthalpy = state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth + simpleWatertoAirHP.QLoadTotal / LoadSideFullMassFlowRate;
3371 22856280 : state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp =
3372 11428140 : state.dataWaterToAirHeatPumpSimple->LoadSideInletDBTemp + simpleWatertoAirHP.QSensible / (LoadSideFullMassFlowRate * CpAir);
3373 22856280 : state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat =
3374 11428140 : Psychrometrics::PsyWFnTdbH(state, state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp, LoadSideFullOutletEnthalpy, RoutineName);
3375 :
3376 : // Actual outlet conditions are "average" for time step
3377 11428140 : if (fanOp == HVAC::FanOp::Continuous) {
3378 : // continuous fan, cycling compressor
3379 2290103 : simpleWatertoAirHP.OutletAirEnthalpy =
3380 2290103 : PartLoadRatio * LoadSideFullOutletEnthalpy + (1.0 - PartLoadRatio) * state.dataWaterToAirHeatPumpSimple->LoadSideInletEnth;
3381 2290103 : simpleWatertoAirHP.OutletAirHumRat = PartLoadRatio * state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat +
3382 2290103 : (1.0 - PartLoadRatio) * state.dataWaterToAirHeatPumpSimple->LoadSideInletHumRat;
3383 2290103 : simpleWatertoAirHP.OutletAirDBTemp = Psychrometrics::PsyTdbFnHW(simpleWatertoAirHP.OutletAirEnthalpy, simpleWatertoAirHP.OutletAirHumRat);
3384 : } else {
3385 : // default to cycling fan, cycling compressor
3386 9138037 : simpleWatertoAirHP.OutletAirEnthalpy = LoadSideFullOutletEnthalpy;
3387 9138037 : simpleWatertoAirHP.OutletAirHumRat = state.dataWaterToAirHeatPumpSimple->LoadSideOutletHumRat;
3388 9138037 : simpleWatertoAirHP.OutletAirDBTemp = state.dataWaterToAirHeatPumpSimple->LoadSideOutletDBTemp;
3389 : }
3390 :
3391 : // scale heat transfer rates to PLR and power to RTF
3392 11428140 : simpleWatertoAirHP.QLoadTotal *= PartLoadRatio;
3393 11428140 : simpleWatertoAirHP.QLoadTotalReport = simpleWatertoAirHP.QLoadTotal;
3394 11428140 : simpleWatertoAirHP.QSensible *= PartLoadRatio;
3395 11428140 : state.dataWaterToAirHeatPumpSimple->Winput *= simpleWatertoAirHP.RunFrac;
3396 11428140 : simpleWatertoAirHP.QSource = simpleWatertoAirHP.QLoadTotalReport - state.dataWaterToAirHeatPumpSimple->Winput;
3397 :
3398 : // Add power to global variable so power can be summed by parent object
3399 11428140 : state.dataHVACGlobal->DXElecHeatingPower = state.dataWaterToAirHeatPumpSimple->Winput;
3400 :
3401 : // Update heat pump data structure
3402 11428140 : simpleWatertoAirHP.Power = state.dataWaterToAirHeatPumpSimple->Winput;
3403 11428140 : simpleWatertoAirHP.QLoadTotal = simpleWatertoAirHP.QLoadTotalReport;
3404 11428140 : simpleWatertoAirHP.QSensible = simpleWatertoAirHP.QSensible;
3405 11428140 : simpleWatertoAirHP.Energy = state.dataWaterToAirHeatPumpSimple->Winput * TimeStepSysSec;
3406 11428140 : simpleWatertoAirHP.EnergyLoadTotal = simpleWatertoAirHP.QLoadTotalReport * TimeStepSysSec;
3407 11428140 : simpleWatertoAirHP.EnergySensible = simpleWatertoAirHP.QSensible * TimeStepSysSec;
3408 11428140 : simpleWatertoAirHP.EnergyLatent = 0.0;
3409 11428140 : simpleWatertoAirHP.EnergySource = simpleWatertoAirHP.QSource * TimeStepSysSec;
3410 11428140 : if (simpleWatertoAirHP.RunFrac == 0.0) {
3411 60632 : simpleWatertoAirHP.COP = 0.0;
3412 : } else {
3413 11367508 : simpleWatertoAirHP.COP = simpleWatertoAirHP.QLoadTotalReport / state.dataWaterToAirHeatPumpSimple->Winput;
3414 : }
3415 11428140 : simpleWatertoAirHP.PartLoadRatio = PartLoadRatio;
3416 :
3417 11428140 : 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 11428140 : simpleWatertoAirHP.WaterMassFlowRate = simpleWatertoAirHP.DesignWaterMassFlowRate * PartLoadRatio;
3420 11428140 : PlantUtilities::SetComponentFlowRate(state,
3421 11428140 : simpleWatertoAirHP.WaterMassFlowRate,
3422 : simpleWatertoAirHP.WaterInletNodeNum,
3423 : simpleWatertoAirHP.WaterOutletNodeNum,
3424 11428140 : simpleWatertoAirHP.plantLoc);
3425 11428140 : if (simpleWatertoAirHP.WaterMassFlowRate > 0.0) {
3426 11367524 : simpleWatertoAirHP.OutletWaterTemp = state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp -
3427 11367524 : simpleWatertoAirHP.QSource / (simpleWatertoAirHP.WaterMassFlowRate * CpWater);
3428 11367524 : simpleWatertoAirHP.OutletWaterEnthalpy =
3429 11367524 : state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth - simpleWatertoAirHP.QSource / simpleWatertoAirHP.WaterMassFlowRate;
3430 : }
3431 : } else {
3432 0 : 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 0 : simpleWatertoAirHP.WaterMassFlowRate = state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3445 : }
3446 0 : simpleWatertoAirHP.OutletWaterTemp = state.dataWaterToAirHeatPumpSimple->SourceSideInletTemp -
3447 0 : simpleWatertoAirHP.QSource / (state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate * CpWater);
3448 0 : simpleWatertoAirHP.OutletWaterEnthalpy = state.dataWaterToAirHeatPumpSimple->SourceSideInletEnth -
3449 0 : simpleWatertoAirHP.QSource / state.dataWaterToAirHeatPumpSimple->SourceSideMassFlowRate;
3450 : }
3451 : }
3452 :
3453 76196727 : 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 76196727 : 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 76196727 : auto &simpleWatertoAirHP(state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum));
3475 :
3476 76196727 : if (!simpleWatertoAirHP.SimFlag) {
3477 : // Heatpump is off; just pass through conditions
3478 49193471 : simpleWatertoAirHP.Power = 0.0;
3479 49193471 : simpleWatertoAirHP.QLoadTotal = 0.0;
3480 49193471 : simpleWatertoAirHP.QLoadTotalReport = 0.0;
3481 49193471 : simpleWatertoAirHP.QSensible = 0.0;
3482 49193471 : simpleWatertoAirHP.QLatent = 0.0;
3483 49193471 : simpleWatertoAirHP.QSource = 0.0;
3484 49193471 : simpleWatertoAirHP.Energy = 0.0;
3485 49193471 : simpleWatertoAirHP.EnergyLoadTotal = 0.0;
3486 49193471 : simpleWatertoAirHP.EnergySensible = 0.0;
3487 49193471 : simpleWatertoAirHP.EnergyLatent = 0.0;
3488 49193471 : simpleWatertoAirHP.EnergySource = 0.0;
3489 49193471 : simpleWatertoAirHP.COP = 0.0;
3490 49193471 : simpleWatertoAirHP.RunFrac = 0.0;
3491 49193471 : simpleWatertoAirHP.PartLoadRatio = 0.0;
3492 :
3493 49193471 : simpleWatertoAirHP.OutletAirDBTemp = simpleWatertoAirHP.InletAirDBTemp;
3494 49193471 : simpleWatertoAirHP.OutletAirHumRat = simpleWatertoAirHP.InletAirHumRat;
3495 49193471 : simpleWatertoAirHP.OutletAirEnthalpy = simpleWatertoAirHP.InletAirEnthalpy;
3496 49193471 : simpleWatertoAirHP.OutletWaterTemp = simpleWatertoAirHP.InletWaterTemp;
3497 49193471 : simpleWatertoAirHP.OutletWaterEnthalpy = simpleWatertoAirHP.InletWaterEnthalpy;
3498 : }
3499 :
3500 76196727 : AirInletNode = simpleWatertoAirHP.AirInletNodeNum;
3501 76196727 : WaterInletNode = simpleWatertoAirHP.WaterInletNodeNum;
3502 76196727 : AirOutletNode = simpleWatertoAirHP.AirOutletNodeNum;
3503 76196727 : WaterOutletNode = simpleWatertoAirHP.WaterOutletNodeNum;
3504 :
3505 : // Set the air outlet nodes of the WatertoAirHPSimple
3506 76196727 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRate = state.dataLoopNodes->Node(AirInletNode).MassFlowRate;
3507 76196727 : state.dataLoopNodes->Node(AirOutletNode).Temp = simpleWatertoAirHP.OutletAirDBTemp;
3508 76196727 : state.dataLoopNodes->Node(AirOutletNode).HumRat = simpleWatertoAirHP.OutletAirHumRat;
3509 76196727 : state.dataLoopNodes->Node(AirOutletNode).Enthalpy = simpleWatertoAirHP.OutletAirEnthalpy;
3510 :
3511 : // Set the air outlet nodes for properties that just pass through & not used
3512 76196727 : state.dataLoopNodes->Node(AirOutletNode).Quality = state.dataLoopNodes->Node(AirInletNode).Quality;
3513 76196727 : state.dataLoopNodes->Node(AirOutletNode).Press = state.dataLoopNodes->Node(AirInletNode).Press;
3514 76196727 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMin = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMin;
3515 76196727 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMax = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMax;
3516 76196727 : state.dataLoopNodes->Node(AirOutletNode).MassFlowRateMinAvail = state.dataLoopNodes->Node(AirInletNode).MassFlowRateMinAvail;
3517 76196727 : 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 76196727 : PlantUtilities::SafeCopyPlantNode(state, WaterInletNode, WaterOutletNode);
3522 :
3523 76196727 : state.dataLoopNodes->Node(WaterOutletNode).Temp = simpleWatertoAirHP.OutletWaterTemp;
3524 76196727 : state.dataLoopNodes->Node(WaterOutletNode).Enthalpy = simpleWatertoAirHP.OutletWaterEnthalpy;
3525 :
3526 76196727 : simpleWatertoAirHP.Energy = simpleWatertoAirHP.Power * TimeStepSysSec;
3527 76196727 : simpleWatertoAirHP.EnergyLoadTotal = simpleWatertoAirHP.QLoadTotal * TimeStepSysSec;
3528 76196727 : simpleWatertoAirHP.EnergySensible = simpleWatertoAirHP.QSensible * TimeStepSysSec;
3529 76196727 : simpleWatertoAirHP.EnergyLatent = simpleWatertoAirHP.QLatent * TimeStepSysSec;
3530 76196727 : simpleWatertoAirHP.EnergySource = simpleWatertoAirHP.QSource * TimeStepSysSec;
3531 :
3532 76196727 : if (state.dataContaminantBalance->Contaminant.CO2Simulation) {
3533 0 : state.dataLoopNodes->Node(AirOutletNode).CO2 = state.dataLoopNodes->Node(AirInletNode).CO2;
3534 : }
3535 76196727 : if (state.dataContaminantBalance->Contaminant.GenericContamSimulation) {
3536 0 : state.dataLoopNodes->Node(AirOutletNode).GenContam = state.dataLoopNodes->Node(AirInletNode).GenContam;
3537 : }
3538 :
3539 76196727 : if (simpleWatertoAirHP.reportCoilFinalSizes) {
3540 17658159 : if (!state.dataGlobal->WarmupFlag && !state.dataGlobal->DoingHVACSizingSimulations && !state.dataGlobal->DoingSizing) {
3541 :
3542 530 : if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Cooling) {
3543 265 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(
3544 : state,
3545 265 : simpleWatertoAirHP.Name,
3546 530 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
3547 : simpleWatertoAirHP.RatedCapCoolTotal,
3548 : simpleWatertoAirHP.RatedCapCoolSens,
3549 : simpleWatertoAirHP.RatedAirVolFlowRate,
3550 : simpleWatertoAirHP.RatedWaterVolFlowRate);
3551 265 : } else if (simpleWatertoAirHP.WAHPType == WatertoAirHP::Heating) {
3552 265 : state.dataRptCoilSelection->coilSelectionReportObj->setCoilFinalSizes(
3553 : state,
3554 265 : simpleWatertoAirHP.Name,
3555 530 : format("COIL:{}:WATERTOAIRHEATPUMP:EQUATIONFIT", WatertoAirHPNamesUC[static_cast<int>(simpleWatertoAirHP.WAHPType)]),
3556 : simpleWatertoAirHP.RatedCapHeat,
3557 : simpleWatertoAirHP.RatedCapHeat,
3558 : simpleWatertoAirHP.RatedAirVolFlowRate,
3559 : simpleWatertoAirHP.RatedWaterVolFlowRate);
3560 : }
3561 530 : simpleWatertoAirHP.reportCoilFinalSizes = false;
3562 : }
3563 : }
3564 76196727 : }
3565 :
3566 : // End of Update subroutines for the WatertoAirHP Module
3567 : // *****************************************************************************
3568 :
3569 0 : 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 0 : auto const &simpleWatertoAirHP = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(HPNum);
3636 :
3637 0 : Twet_Rated = simpleWatertoAirHP.Twet_Rated;
3638 0 : Gamma_Rated = simpleWatertoAirHP.Gamma_Rated;
3639 0 : MaxONOFFCyclesperHour = simpleWatertoAirHP.MaxONOFFCyclesperHour;
3640 0 : LatentCapacityTimeConstant = simpleWatertoAirHP.LatentCapacityTimeConstant;
3641 0 : 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 0 : 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 0 : SHReff = SHRss;
3649 0 : 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 531 : 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 531 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3730 19 : GetSimpleWatertoAirHPInput(state);
3731 19 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3732 : }
3733 :
3734 531 : IndexNum = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3735 :
3736 531 : if (IndexNum == 0) {
3737 0 : ShowSevereError(state, format(R"(Could not find CoilType="{}" with Name="{}")", CoilType, CoilName));
3738 0 : ErrorsFound = true;
3739 : }
3740 :
3741 531 : return IndexNum;
3742 : }
3743 :
3744 684 : 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 684 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3768 0 : GetSimpleWatertoAirHPInput(state);
3769 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3770 : }
3771 :
3772 949 : if (Util::SameString(CoilType, "COIL:COOLING:WATERTOAIRHEATPUMP:EQUATIONFIT") ||
3773 949 : Util::SameString(CoilType, "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT")) {
3774 684 : WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3775 684 : if (WhichCoil != 0) {
3776 684 : if (Util::SameString(CoilType, "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT")) {
3777 265 : CoilCapacity = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).RatedCapHeat;
3778 : } else {
3779 419 : CoilCapacity = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).RatedCapCoolTotal;
3780 :
3781 419 : int companionHeatingCoil = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).CompanionHeatingCoilNum;
3782 419 : if (companionHeatingCoil > 0) {
3783 669 : if (CoilCapacity == DataSizing::AutoSize &&
3784 250 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(companionHeatingCoil).WAHPPlantType ==
3785 250 : DataPlant::PlantEquipmentType::CoilWAHPHeatingEquationFit &&
3786 919 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(companionHeatingCoil).RatedCapHeat == DataSizing::AutoSize &&
3787 250 : state.dataSize->DXCoolCap > 0) {
3788 : // Heating coil has not yet been sized, returning the temporary cooling capacity
3789 154 : CoilCapacity = state.dataSize->DXCoolCap;
3790 : }
3791 : }
3792 : }
3793 : }
3794 : } else {
3795 0 : WhichCoil = 0;
3796 : }
3797 :
3798 684 : 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 684 : return CoilCapacity;
3805 : }
3806 :
3807 530 : 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 530 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3831 0 : GetSimpleWatertoAirHPInput(state);
3832 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3833 : }
3834 :
3835 795 : if (Util::SameString(CoilType, "COIL:COOLING:WATERTOAIRHEATPUMP:EQUATIONFIT") ||
3836 795 : Util::SameString(CoilType, "COIL:HEATING:WATERTOAIRHEATPUMP:EQUATIONFIT")) {
3837 530 : WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3838 530 : if (WhichCoil != 0) {
3839 530 : CoilAirFlowRate = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).RatedAirVolFlowRate;
3840 : }
3841 : } else {
3842 0 : WhichCoil = 0;
3843 : }
3844 :
3845 530 : 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 530 : return CoilAirFlowRate;
3852 : }
3853 :
3854 222 : 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 222 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3878 0 : GetSimpleWatertoAirHPInput(state);
3879 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3880 : }
3881 :
3882 222 : WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3883 222 : if (WhichCoil != 0) {
3884 222 : NodeNumber = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).AirInletNodeNum;
3885 : }
3886 :
3887 222 : 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 222 : return NodeNumber;
3894 : }
3895 :
3896 222 : 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 222 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3920 0 : GetSimpleWatertoAirHPInput(state);
3921 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3922 : }
3923 :
3924 222 : WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3925 222 : if (WhichCoil != 0) {
3926 222 : NodeNumber = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil).AirOutletNodeNum;
3927 : }
3928 :
3929 222 : 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 222 : return NodeNumber;
3936 : }
3937 :
3938 265 : 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 265 : if (state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag) { // First time subroutine has been entered
3957 0 : GetSimpleWatertoAirHPInput(state);
3958 0 : state.dataWaterToAirHeatPumpSimple->GetCoilsInputFlag = false;
3959 : }
3960 :
3961 265 : 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 265 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(SimpleWSHPNum).WaterCyclingMode = WaterCyclingMode;
3971 265 : 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 265 : if (present(CompanionHeatingCoilNum)) {
3978 265 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(SimpleWSHPNum).CompanionHeatingCoilNum = CompanionHeatingCoilNum;
3979 265 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoilNum).CompanionCoolingCoilNum = SimpleWSHPNum;
3980 265 : state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(CompanionHeatingCoilNum).WaterCyclingMode = WaterCyclingMode;
3981 : }
3982 : }
3983 :
3984 530 : void CheckSimpleWAHPRatedCurvesOutputs(EnergyPlusData &state, std::string const &CoilName)
3985 : {
3986 530 : constexpr Real64 Tref(283.15); // Refrence Temperature for performance curves,10C [K]
3987 : static constexpr std::string_view RoutineName("CheckSimpleWAHPRatedCurvesOutputs");
3988 :
3989 530 : int WhichCoil = Util::FindItemInList(CoilName, state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP);
3990 :
3991 530 : if (WhichCoil == 0) {
3992 0 : return;
3993 : }
3994 :
3995 530 : auto &wahp = state.dataWaterToAirHeatPumpSimple->SimpleWatertoAirHP(WhichCoil);
3996 530 : if (wahp.WAHPType == WatertoAirHP::Cooling) {
3997 265 : if (wahp.RatedEntAirWetbulbTemp != DataSizing::AutoSize && wahp.TotalCoolCapCurve != nullptr && wahp.CoolPowCurve != nullptr) {
3998 265 : Real64 RatedratioTWB = (wahp.RatedEntAirWetbulbTemp + Constant::Kelvin) / Tref;
3999 265 : Real64 RatedratioTS = (wahp.RatedEntWaterTemp + Constant::Kelvin) / Tref;
4000 265 : Real64 RatedTotCapTempModFac = wahp.TotalCoolCapCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
4001 265 : Real64 RatedCoolPowerTempModFac = wahp.CoolPowCurve->value(state, RatedratioTWB, RatedratioTS, 1.0, 1.0);
4002 265 : if (RatedTotCapTempModFac > 1.02 || RatedTotCapTempModFac < 0.98) {
4003 0 : ShowWarningError(state, format("{}: Coil:Cooling:WaterToAirHeatPump:EquationFit=\"{}\"", RoutineName, wahp.Name));
4004 0 : 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 0 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedTotCapTempModFac));
4008 : }
4009 265 : if (RatedCoolPowerTempModFac > 1.02 || RatedCoolPowerTempModFac < 0.98) {
4010 0 : ShowWarningError(state, format("{}: Coil:Cooling:WaterToAirHeatPump:EquationFit=\"{}\"", RoutineName, wahp.Name));
4011 0 : 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 0 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedCoolPowerTempModFac));
4015 : }
4016 : }
4017 :
4018 265 : if (wahp.RatedEntAirDrybulbTemp != DataSizing::AutoSize && wahp.SensCoolCapCurve != nullptr) {
4019 265 : Real64 RatedratioTDB = (wahp.RatedEntAirDrybulbTemp + Constant::Kelvin) / Tref;
4020 265 : Real64 RatedratioTWB = (wahp.RatedEntAirWetbulbTemp + Constant::Kelvin) / Tref;
4021 265 : Real64 RatedratioTS = (wahp.RatedEntWaterTemp + Constant::Kelvin) / Tref;
4022 :
4023 265 : Real64 RatedSensCapTempModFac = wahp.SensCoolCapCurve->value(state, RatedratioTDB, RatedratioTWB, RatedratioTS, 1.0, 1.0);
4024 265 : if (RatedSensCapTempModFac > 1.02 || RatedSensCapTempModFac < 0.98) {
4025 0 : ShowWarningError(state, format("{}: Coil:Cooling:WaterToAirHeatPump:EquationFit=\"{}\"", RoutineName, wahp.Name));
4026 0 : 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 0 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedSensCapTempModFac));
4030 : }
4031 : }
4032 :
4033 265 : } else if (wahp.WAHPType == WatertoAirHP::Heating) {
4034 265 : if (wahp.RatedEntAirDrybulbTemp != DataSizing::AutoSize && wahp.HeatCapCurve != nullptr && wahp.HeatPowCurve != nullptr) {
4035 265 : Real64 RatedHeatratioTDB = (wahp.RatedEntAirDrybulbTemp + Constant::Kelvin) / Tref;
4036 265 : Real64 RatedHeatratioTS = (wahp.RatedEntWaterTemp + Constant::Kelvin) / Tref;
4037 265 : Real64 RatedHeatCapTempModFac = wahp.HeatCapCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
4038 265 : Real64 RatedHeatPowerTempModFac = wahp.HeatPowCurve->value(state, RatedHeatratioTDB, RatedHeatratioTS, 1.0, 1.0);
4039 265 : if (RatedHeatCapTempModFac > 1.02 || RatedHeatCapTempModFac < 0.98) {
4040 0 : ShowWarningError(state, format("{}: Coil:Heating:WaterToAirHeatPump:EquationFit=\"{}\"", RoutineName, wahp.Name));
4041 0 : ShowContinueError(
4042 : state, "Heating capacity as a function of temperature curve output is not equal to 1.0 (+ or - 2%) at rated conditions.");
4043 0 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedHeatCapTempModFac));
4044 : }
4045 265 : if (RatedHeatPowerTempModFac > 1.02 || RatedHeatPowerTempModFac < 0.98) {
4046 0 : ShowWarningError(state, format("{}: Coil:Heating:WaterToAirHeatPump:EquationFit=\"{}\"", RoutineName, wahp.Name));
4047 0 : 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 0 : ShowContinueError(state, format("Curve output at rated conditions = {:.3T}", RatedHeatPowerTempModFac));
4051 : }
4052 : }
4053 : }
4054 : }
4055 : } // namespace WaterToAirHeatPumpSimple
4056 :
4057 : } // namespace EnergyPlus
|